@nca78 well, after 2 nights of intense trying and failing I've got code to work as expected. And yes, it works with PORT interrupt, its kinda more code for you to write in compare to simply using attachInterrupt function, but I'm okay with that. For me double the price of 52832 compared to 51822 is significant. And for now, for a simple sensor stuff as we do with mysensors I don't really see any advantages except that interrupt bug fixed.
Also I've found that Mysensors sleep function for nrf5 is missing one very important command, I don't know why, maybe it is nrf51822 specific and thus @d00616 missed it but in current version of Mysensors library it doesn't disable UART before sleep, that's why I was getting 120-200uA current during sleep. I still don't really know how to make pull requests on github, so I guess I will just post it here:
line 290 of MyHwNRF5.cpp should contain: NRF_UART0->ENABLE=0;
and line 327: NRF_UART0->ENABLE=1;
respectively. That completely disables UART on nrf51822.
I will post my complete sketch later, when I will finish it, maybe someone who strugles as I did will find it useful. Also I think we need to somehow combine all examples that were posted in this thread or at least put a list of them with links, because looking through 1654 posts is not an easy task, especially if you not sure what you are looking for exactly.

monte
@monte
Best posts made by monte
-
RE: nRF5 action!
-
RE: What did you build today (Pictures) ?
Made a prototype board for writing a software for one of my projects. Goal was to have everything needed on a board no bigger then a 1.54" eink display, and to make it doable at home by my own.
I was gladly surprised that everything worked (after a sleepless night of fighting through-layer connections, and soldering/desoldering FPC connectors)The only I've messed up is order of connector pins, so the display is connected the wrong way...
It also has pads for SHT30 sensor so it may be somehow useful after development is done.
-
RE: Where did everyone go?
I guess the main reason is that mysensors is very stand-alone framework. And it locked itself in purely hobbyist territory. So when there are vast amount of iot devices from various manufacturers that you can combine with your own diy solutions in zigbee-ikea-hue or esp-tasmota-mqtt ecosystem in mysesnsors you have to make all devices yourself if you want some kind of ecosystem, or rely on HA/openhab/nodered/domoticz with its script system to make something connected. Also strict requirement of arduino framework and outdated hardware as the core of the framework alienates the big chunk of iot developers out there. It feels like people come to mysensors, make relay node, temperature sensor and then go forward for more complex solutions to never come back.
@NeverDie said in Where did everyone go?:
not all that long ago Google bought a thermostat company (Nest)
And pretty much broke it for opensource or third-party integrations.
-
RE: What did you build today (Pictures) ?
Build myself a simple temperature sensor with a clock. No RTC, just pulling time from controller and updating every 10 minutes to avoid drift. Also requesting outdoor temperature from controller. Build from what was lying around - DHT22, pro mini clone, nokia screen. I can share the code if someone needs it
-
RE: What did you build today (Pictures) ?
Offtopic in terms of mysensors platform, but somehow tangent to a home automation. I've made a batch of concrete switches/push buttons which are in this case simple buttons with led backlight and all the logic is located centrally in distribution box, based on KNX ABB module. But I am planning on making smarter and more complex version which could use Mysensors as its transport.
and a photo of insides of one of the prototypes at first stages of development
-
RE: What did you build today (Pictures) ?
Today I've finally swapped my outdoor relay node with something descent.
This was my very first mysensors node that I've built when I was only starting to mess with arduino, probably around four years ago.
This board uses cheap 5v power supply and an amplified version of NRF24 module from Ebyte. It supposed to be poured with silicone ore resin, but I am yet to find suitable box, the size of this board appeared to be bigger then most of such cases designed for compound pouring. But I'm planning on making next version, with non-isolated power supply, which will help to achieve smaller size. -
Direct pairing of two nodes implementation
I've been looking for some time for implementation of pairing two nodes to each other to be able to send messages directly omitting controller. I've seen some other posts suggesting to add this functionality to mysensors core, and proposing base scheme of how it should look like. After some reading I realized that it is not hard to write such code by myself. So I tried my best and now I have what seems to be a working code for two test nodes and a gateway. One of the nodes is modified sketch for binary button the other one is simple one channel relay. I'm not a professional programmer, so code can be optimized more, I guess, and maybe rewritten in better manner.
It's primarily useful for direct communication between a button node (a light switch, or motion sensor) and some relay or other actuator. The key feature is the ability to avoid necessity of controller presence for some simple usage like light switching. Also it provides better reliability in case of controller failure.
Both nodes must have specific pairing button which also serves as "Clear EEPROM" button if pressed before node is powered on. So basically when pairing button is pressed node enters pairing mode for required amount of time (in my case 10 seconds) and sends special message to controller which collects its node and children id's and then waits for 10 seconds for another node to send request in which case it then sends id's vice versa. My code is written only for single button/relay nodes, but it can be made to pair specific child sensors on every node.
Let me know what do you think of it, and if it's useful to anybody.
Binary button code:
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 #include <MySensors.h> #define CHILD_ID 3 #define SET_BUTTON_PIN 5// Arduino Digital I/O pin for button/reed switch #define BUTTON_PIN 3 MyMessage msg(CHILD_ID, V_TRIPPED); bool firstLoop = 1; bool pairing = 0; int node_pair=-1; int sensor_pair=-1; bool paired=0; bool lastButState=0; unsigned long timer1 = 0; int debounceTime = 1000; unsigned long timer2 = 0; int pairWaitTime = 10000; unsigned long timer3; int holdTime = 3000; //Time counter function instead of delay boolean isTime(unsigned long *timeMark, unsigned long timeInterval) { if (millis() - *timeMark >= timeInterval) { *timeMark = millis(); return true; } return false; } void before() { Serial.begin(115200); Serial.println("Starting node..."); pinMode(SET_BUTTON_PIN, INPUT_PULLUP); //Eneble button pin for detect request for resetting node's EEPROM bool clr = digitalRead(SET_BUTTON_PIN); if (!clr) { Serial.println("Clearing EEPROM"); for (int i=0; i<EEPROM_LOCAL_CONFIG_ADDRESS; i++) { hwWriteConfig(i,0xFF); } //Clearing paired nodes address and paired state for (int i=245; i<=255; i++) { hwWriteConfig(i,0xFF); } Serial.println("EEPROM is clean"); } //Reading pairing state from EEPROM and then reading paired nodes id's if paired paired = loadState(255); Serial.print("Paired state: "); Serial.println(paired); if (paired) { node_pair = loadState(245); sensor_pair = loadState(246); Serial.print("Paired node: "); Serial.print(node_pair); Serial.print("-"); Serial.println(sensor_pair); } } void setup() { // Setup the buttons pinMode(BUTTON_PIN, INPUT_PULLUP); } void presentation() { // Send the sketch version information to the Controller in case node is'nt paired if (!paired) { sendSketchInfo("Binary paired button", "1.0"); present(CHILD_ID, S_MOTION); } } // Loop will iterate on changes on the BUTTON_PINs void loop() { bool butState = !digitalRead(BUTTON_PIN); if (!paired) { if (firstLoop) { timer3 = millis(); //Starting delay for pairing button on first loop } //If pairing button hold for required amount of seconds initiate pairing process if (!digitalRead(SET_BUTTON_PIN)) { if(isTime(&timer3, holdTime)){ Serial.println("Pair button pressed"); pair(); if (!paired) { Serial.println("Pairing timeout"); } } } else { timer3 = millis(); } } //Processing main button press if (butState != lastButState) { if (butState) { lastButState = butState; if (isTime(&timer1, debounceTime)) { Serial.println("Button pressed"); //If node is paired to other node send message directly to paired node omitting controller if (paired) { MyMessage msg(sensor_pair, V_TRIPPED); msg.setDestination(node_pair); Serial.println("Sent message to paired node"); int retry = 0; while(!send(msg.set(1)) || retry == 10) { wait(100); send(msg.set(1)); retry++; } } else { //If not, send message to controller send(msg.set(1)); Serial.println("Sent message to controller"); } } } else { if (!paired) { send(msg.set(0)); } lastButState = butState; } } firstLoop = 0; //Counter for first loop just to know from where to start timer for pairing button hold } //Pairing function void pair() { Serial.println("Entering pairing mode"); pairing = 1; MyMessage pairMsg(244, V_VAR1); //I'm using specific CHILD_ID to be able to filter out pairing requests send(pairMsg.set("Pair me."), true); //Send any message to gateway Serial.println("Pair request sent"); //Then we wait some time to recieve paired node id (in my case 10 seconds) timer2 = millis(); while (!isTime(&timer2, pairWaitTime)) { wait(1); if (paired) { Serial.println("Successfully paired"); break; } } pairing = 0; } void receive(const MyMessage &message) { //While in pairing mode we'll only process pairing messages if (pairing) { if (!message.sender) { if (message.type == V_VAR2) { node_pair = atoi(strtok(message.getString(), ";")); //Deconstructing string from gateway, wich must contain id of paired node Serial.println(node_pair); sensor_pair = atoi(strtok(NULL, ";")); //...and id of specific sensor on that node, in case there are more than one Serial.print("Paired with: "); Serial.println(node_pair); Serial.println(sensor_pair); paired=1; saveState(255, 1); } } } }
Relay actuator code:
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 // Enable repeater functionality for this node //#define MY_REPEATER_FEATURE #include <MySensors.h> #define CHILD_ID 1 #define RELAY_PIN 5 // Arduino Digital I/O pin number for relay #define RELAY_ON 1 // GPIO value to write to turn on attached relay #define RELAY_OFF 0 // GPIO value to write to turn off attached relay #define SET_BUTTON_PIN 3 bool relayState; bool firstLoop = 1; bool pairing = 0; int node_pair=-1; int sensor_pair=-1; bool paired=0; bool lastButState=0; unsigned long timer1 = 0; int debounceTime = 100; unsigned long timer2 = 0; int pairWaitTime = 10000; unsigned long timer3; int holdTime = 3000; unsigned long timer4; int resendTime = 1500; MyMessage msg(CHILD_ID,V_LIGHT); //Time counter function instead delay boolean isTime(unsigned long *timeMark, unsigned long timeInterval) { if (millis() - *timeMark >= timeInterval) { *timeMark = millis(); return true; } return false; } void before () { Serial.begin(115200); Serial.println("Starting..."); pinMode(SET_BUTTON_PIN, INPUT_PULLUP); bool clr = digitalRead(SET_BUTTON_PIN); if (!clr) { Serial.println("Clearing EEPROM"); for (int i=0; i<EEPROM_LOCAL_CONFIG_ADDRESS; i++) { hwWriteConfig(i,0xFF); } //Clearing paired nodes address and paired state for (int i=245; i<=255; i++) { hwWriteConfig(i,0xFF); } Serial.println("EEPROM is clean"); } //Reading pairing state from EEPROM and then reading paired nodes id's if paired paired = loadState(255); Serial.print("Paired state: "); Serial.println(paired); if (paired) { node_pair = loadState(245); sensor_pair = loadState(246); Serial.print("Paired node: "); Serial.print(node_pair); Serial.print("-"); Serial.println(sensor_pair); } pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, 1); delay(1000); digitalWrite(RELAY_PIN, 0); // Set relay to last known state (using eeprom storage) relayState = loadState(CHILD_ID); digitalWrite(RELAY_PIN, relayState ? RELAY_ON : RELAY_OFF); } void setup() { } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Relay", "1.0"); present(CHILD_ID, S_LIGHT, "Test light", true); // Send saved state to gateway (using eeprom storage) send(msg.set(relayState),true); } void loop() { if (!paired) { if (firstLoop) { timer3 = millis(); //Starting delay for pairing button on first loop } //If pairing button hold for required amount of seconds initiate pairing process if (!digitalRead(SET_BUTTON_PIN)) { if(isTime(&timer3, holdTime)){ Serial.println("Pair button pressed"); pair(); } } else { timer3 = millis(); } } firstLoop = 0; //Counter for first loop just to know from where to start timer for pairing button hold } void pair() { Serial.println("Entering pairing mode"); pairing = 1; MyMessage pairMsg(244, V_VAR1); //I'm using specific CHILD_ID to be able to filter out pairing requests send(pairMsg.set("Pair me."), true); //Send any message to gateway Serial.println("Pair request sent"); //Then we wait some time to recieve paired node id (in my case 10 seconds) timer2 = millis(); while (!isTime(&timer2, pairWaitTime)) { wait(1); if (paired) { Serial.println("Successfully paired"); break; } } pairing = 0; Serial.println("Pairing timeout"); } void receive(const MyMessage &message) { //While in pairing mode we'll only process pairing messages if (pairing) { if (!message.sender) { if (message.type == V_VAR2) { node_pair = atoi(strtok(message.getString(), ";")); //Deconstructing string from gateway, wich must contain id of paired node Serial.println(node_pair); sensor_pair = atoi(strtok(NULL, ";")); //...and id of specific sensor on that node, in case there are more than one Serial.print("Paired with: "); Serial.println(node_pair); Serial.println(sensor_pair); paired=1; saveState(255, 1); } } } else { //Process mesage from gateway if (message.type == V_LIGHT && !message.sender) { // Change relay state relayState = message.getBool(); digitalWrite(RELAY_PIN, relayState ? RELAY_ON : RELAY_OFF); // Store state in eeprom saveState(CHILD_ID, relayState); // Write some debug info Serial.print("Incoming change. New status:"); Serial.println(relayState); } else if (message.type == V_TRIPPED && message.sender == node_pair) { //Process message sent directly from paired node if(isTime(&timer4, resendTime)) { digitalWrite(RELAY_PIN, relayState ? RELAY_OFF : RELAY_ON); relayState = relayState ? 0 : 1; saveState(CHILD_ID, relayState); send(msg.set(relayState)); //Send changed state to controller, because paired button won't do it } } } }
Gateway code:
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 //#define MY_RADIO_RFM69 // Set LOW transmit power level as default, if you have an amplified NRF-module and // power your radio separately with a good regulator you can turn up PA level. #define MY_RF24_PA_LEVEL RF24_PA_MAX // Enable serial gateway #define MY_GATEWAY_SERIAL // Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender) #if F_CPU == 8000000L #define MY_BAUD_RATE 38400 #endif // Set blinking period #define MY_DEFAULT_LED_BLINK_PERIOD 300 #include <MySensors.h> unsigned long currentTime = 0; int waitTime = 10000; int node1_addr = 0; bool node1_addr_present = 0; int sensor1_addr = 0; char str1[8]; char str2[8]; bool pairing = 0; //Messages for answering pairing requests MyMessage msg(254,V_VAR2); MyMessage msg2(254,V_VAR2); //Time counter function instead delay boolean isTime(unsigned long *timeMark, unsigned long timeInterval) { if (millis() - *timeMark >= timeInterval) { *timeMark = millis(); return true; } return false; } void setup() { // Setup locally attached sensors } void loop() { //We are keeping ids of pairing nodes only for 10 seconds while pairing if(isTime(¤tTime, waitTime)) { node1_addr = 0; node1_addr_present = 0; } } void receive(const MyMessage &message) { //I used specific message type for filtering out pairing request if (message.type == V_VAR1) { Serial.print("Incoming message. Node - "); Serial.print(message.sender); Serial.print(message.sensor); Serial.println(message.getString()); //Check if there was any pairing requests for last 10 seconds, if no begin pairing process if (!node1_addr_present) { currentTime = millis(); node1_addr = message.sender; sensor1_addr = message.sensor; node1_addr_present = 1; } //If there is request from another node send back pairing node ids to each other else if (message.sender != node1_addr && message.sensor != sensor1_addr) { snprintf(str2, 7, "%d;%d", message.sender, message.sensor); //Construct message string with node and sensor ids of second node snprintf(str1, 7, "%d;%d", node1_addr, sensor1_addr); //...and the first one //print some debug info Serial.print("First address: "); Serial.print(str1); Serial.print("Second address: "); Serial.print(str2); //Send answer to nodes msg.setDestination(message.sender); send(msg.set(str1), true); wait(500); Serial.println("Sent message to second address"); msg2.setDestination(node1_addr); send(msg2.set(str2), true); wait(500); Serial.println("Sent message to first address"); node1_addr = 0; sensor1_addr = 0; node1_addr_present = 0; Serial.println("Pairing finished"); } } }
-
RE: Favorite hand solderable radio chip?
@NeverDie stencil would help, for sure. But I am talking bare minimum. You tin the pads a little, so they are like bumps, then apply gel flux, put the IC aligned to the pins and reflow it with hot-air gun. That may be not the best practice, but it works, if you need to solder few IC's.
-
RE: nRF5 action!
I wanted to write that Softdevice and ESB are not compatible for use at the same time, but then decided to fact check myself. Seems like now you can use Softdevice and ESB simultaneously. You can either disable softdevice in program, or use Timeslot API to manage access to radio of different protocols.
https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsds_s140%2FSDS%2Fs1xx%2Fconcurrent_multiprotocol_tsl_api%2Ftsl_usage_examples.html&cp=4_5_3_0_8_2
https://devzone.nordicsemi.com/f/nordic-q-a/55847/priority-level-overlap-between-softdevice-and-esb
https://jimmywongiot.com/2020/06/22/radio-timeslot-api-for-the-multiple-protocols/
If this is doable I can't think of a reason, why mysensors shouldn't use softdevice. -
RE: What did you build today (Pictures) ?
@sundberg84 I've bought these 5032 crystals: https://www.aliexpress.com/item/Free-shipping-20pcs-16-000MHZ-16mhz-20pF-2Pin-5032-smd-quartz-resonator-Crystal/32821974003.html but there are plentiful other offers on aliexspress and/or ebay. This 5032 package seems to be the most common. There is another package with the same size but with 4 pins 2 of which are not connected, I bought them from my local distributor, while was waiting a package from aliexpress. But those with 4 pins are harder to solder (obviously) and I don't see any pros of using them.
The most suitable for hand soldering and easiest to find are these:
According to this image the ones I have are TX5 and TG5.
Latest posts made by monte
-
RE: HassOS + Serial Gateway OR Docker + RPI Ethernet Gateway
@se-O-matic said in HassOS + Serial Gateway OR Docker + RPI Ethernet Gateway:
Can I use the UART Port "/dev/ttyAMA0" in HassOS?
Yes.
@se-O-matic said in HassOS + Serial Gateway OR Docker + RPI Ethernet Gateway:
Are there any limitations in Option2, when HA running in Docker?
Not that I can think of. Supervisor might be unhappy about "unsupported" setup, but it will work. They invented very strict guidelines for supervisor setup, apparently to lift any "responsibility" in terms of support for what people may come up with in their setups. But everything usually works anyway.
-
RE: How to drill 1mm diameter holes? My drills won't even hold the bit!
@NeverDie https://www.aliexpress.com/item/32738503593.html special bits, that has the same diameter of the tail side, and will fit the standard drill. Or you can buy a drill with small jaws, or just another chuck, that will fit your drill.
I am using dremel tool with a drill chuck bought separately https://www.dremel.com/us/en/p/4486-2615004486 -
RE: GUIDE - NRF5 / NRF51 / NRF52 for beginners
@NeverDie I contacted alibaba sellers a few times for quotes, but never got to buy anything:) The process and shipping costs kills any wish to try and buy if anything less then 20-50...
-
RE: GUIDE - NRF5 / NRF51 / NRF52 for beginners
@NeverDie yep, you're lucky:) Mouser says "Expected 09-Dec-22"
-
RE: GUIDE - NRF5 / NRF51 / NRF52 for beginners
@NeverDie sorry, where did you buy them? I don't see them anywhere
-
RE: GUIDE - NRF5 / NRF51 / NRF52 for beginners
@NeverDie are you saying it is only programmable with j-link? Won't stlink/blackmagic work?
-
RE: GUIDE - NRF5 / NRF51 / NRF52 for beginners
@NeverDie have you checked the radio already? How much work is needed to make it work with mysensors?
-
RE: TEMT6000 Breakout board
@Daniel-Brunod said in TEMT6000 Breakout board:
First of all, when trying to figure out something about electronic component, read the datasheet first. https://www.vishay.com/docs/81579/temt6000.pdf says that maximum "Collector emitter voltage" is 6V. So, of course you won't damage the sensor by wiring it like that.
BUT! You're right that it is a voltage divider scheme, so you need a resistor to take a reading. -
RE: 💬 Building a Raspberry Pi Gateway
@badisensors try ethernet gateway instead of serial. You won't need to pass anything to docker and it works just fine.
-
RE: Zigbee gateway with support for multiple vendors?
@NeverDie I think this is what you are looking for:
https://tasmota.github.io/docs/Zigbee/#hardware
https://github.com/esphome/feature-requests/issues/1111
Also look at "Network" category: https://www.zigbee2mqtt.io/guide/adapters/
If you want to make something yourself, you need to make UART to LAN adapter basically. Home Assistant can use network socket as serial address https://www.home-assistant.io/integrations/zha/#zigate-or-sonoff-zbbridge-devices. So basically you think in the right direction, just skip MQTT part:)