nRF5 action!
-
@NeverDie
d00616 added the support of NRF5 + ESB to MySensors.
Radiohead lib doesn't handle this mode (explained in the description of his NRF51class).Yeah, MySensors can definitely do it. Nice work @d00616 !
It turns out that with RadioHead, I am almost able to send packets from an nRF24L01 to an nRF5 module: it's just that the packets arrive as garbage. So, the packet and/or frame formatting must be different, but indeed the network ID's are matching or else I wouldn't be receiving anything at all.
-
I found the smoking gun in the radiohead documentation. Turns out RadioHead does indeed use a different packet format for the nRF5 that is "NOT compatible with the one used by RH_NRF24 and the nRF24L01 product specification, mainly because the nRF24 only supports 6 bits of message length." :(
Well, that stinks.
-
I found the smoking gun in the radiohead documentation. Turns out RadioHead does indeed use a different packet format for the nRF5 that is "NOT compatible with the one used by RH_NRF24 and the nRF24L01 product specification, mainly because the nRF24 only supports 6 bits of message length." :(
Well, that stinks.
-
Yeah, MySensors can definitely do it. Nice work @d00616 !
It turns out that with RadioHead, I am almost able to send packets from an nRF24L01 to an nRF5 module: it's just that the packets arrive as garbage. So, the packet and/or frame formatting must be different, but indeed the network ID's are matching or else I wouldn't be receiving anything at all.
@NeverDie said in nRF5 Bluetooth action!:
Yeah, MySensors can definitely do it. Nice work @d00616 !
Thanks.It turns out that with RadioHead, I am almost able to send packets from an nRF24L01 to an nRF5 module: it's just that the packets arrive as garbage. So, the packet and/or frame formatting must be different, but indeed the network ID's are matching or else I wouldn't be receiving anything at all.
The ID's are reversed between nRF5 and nRF24. Look into the code how to reverse the ID's.
@NeverDie said in nRF5 Bluetooth action!:
I found the smoking gun in the radiohead documentation. Turns out RadioHead does indeed use a different packet format for the nRF5 that is "NOT compatible with the one used by RH_NRF24 and the nRF24L01 product specification, mainly because the nRF24 only supports 6 bits of message length."
You have to choose the correct number of bits for length, S0 and S1. I have played a while to find out the correct configuration. When ACK is enabled you have to do a lot of timing work.
@Terrence said in nRF5 Bluetooth action!:
@NeverDie Ya, that really sucks. It would have been great to mix and match.
At the moment I have no opinion to the "GPL or commercial" license of Readiohead. So I have no plans to port my Code .
The Nordic SDK has an ESB library supporting the nRF24 mode. IMHO Starting with SDK 13 the license is more Open Source friendly.
-
I'm realizing I can live with it. It just means I need to add a separate nRF24 gateway if I want to use nRF24's. I'm already adding separate gateways to support RFM69's and LoRa's, so, actually, it's no big deal.
Meanwhile, I've found that the RadioHead and the MySensors libraries are at least minimally compatible. So, presently I'm using RadioHead for my low power transmissions, but I'm using the sleep(...) function from MySensors to sleep the nRF52 and wake it up. :)
The only weirdness I'm noticing is that immediately after sending the very first packet in this configuration, there's a mysterious several second delay that occurs before the code continues. However, after the initial hiccup, everything appears to run exactly as fast as it should. I have no clue as to what is causing that initial delay though. It doesn't happen if I don't #include the MySensors.h file.
-
I was playing with sleep tonight and found the following problem.
when using sleep as below it always returns a figure 252 ms bigger than the sleep figure.
ie sleep 10000 always returns 10251
ie sleep 3000 always returns 3251.
I know the nrf51822 has a 32khz rtc so why is this?oldmillis = hwMillis(); hwSleep(10000); newmillis = hwMillis(); Serial.println(newmillis - oldmillis); -
-
What more can be done to reduce current consumption on an nRF52832 when the MySensors "sleep" function is being used with RTC wakeup. I've measured a 300mv drop on a 10F capacitor over a 12 hour time period. Of that 300mv, perhaps 20mv was lost due to self-discharge of the supercap. So, that still leaves 280mv of loss due to the nRF52832 . That is too high a rate of loss.
-
What more can be done to reduce current consumption on an nRF52832 when the MySensors "sleep" function is being used with RTC wakeup. I've measured a 300mv drop on a 10F capacitor over a 12 hour time period. Of that 300mv, perhaps 20mv was lost due to self-discharge of the supercap. So, that still leaves 280mv of loss due to the nRF52832 . That is too high a rate of loss.
-
MY_HW_RTC->CC[0] = (ms / 125) + 2;
It seems the +2 above is adding 250ms.
Why is it done like this???@rmtucker said in nRF5 Bluetooth action!:
MY_HW_RTC->CC[0] = (ms / 125) + 2;
It seems the +2 above is adding 250ms.
Why is it done like this???A minimum of two ticks are required to be sure the CC[0] is triggered.
What accuracy is your requirement? I can add more code here to dynamical change the pre scaler plus a check if ms/125>=2
-
@rmtucker said in nRF5 Bluetooth action!:
MY_HW_RTC->CC[0] = (ms / 125) + 2;
It seems the +2 above is adding 250ms.
Why is it done like this???A minimum of two ticks are required to be sure the CC[0] is triggered.
What accuracy is your requirement? I can add more code here to dynamical change the pre scaler plus a check if ms/125>=2
@d00616
My initial thoughts were how the nrf51822 could be used for energy meters (counting pulses and the gap between them),But unlike the arduino's which can not run timers when in sleep mode,The nrf5 can of course do this.
So the nrf5 would be able to report watts and usage while still using sleep mode.
But seeing the inaccuracy of the timer has put the brakes on that.
Yes being able to change the prescaler dynamically would help a great deal as 125ms / 582.542 hours is not really useful for most applications with a 250ms overrun. -
What more can be done to reduce current consumption on an nRF52832 when the MySensors "sleep" function is being used with RTC wakeup. I've measured a 300mv drop on a 10F capacitor over a 12 hour time period. Of that 300mv, perhaps 20mv was lost due to self-discharge of the supercap. So, that still leaves 280mv of loss due to the nRF52832 . That is too high a rate of loss.
@NeverDie said in nRF5 Bluetooth action!:
What more can be done to reduce current consumption on an nRF52832 when the MySensors "sleep" function is being used with RTC wakeup. I've measured a 300mv drop on a 10F capacitor over a 12 hour time period. Of that 300mv, perhaps 20mv was lost due to self-discharge of the supercap. So, that still leaves 280mv of loss due to the nRF52832 . That is too high a rate of loss.
Wh = 0.5 * 10F * 280mV = 0.392 Wh = 0.0326667 W
I=0.0326667/2.56V = 12.76mALooks like the node is most time fully active.
-
@d00616
My initial thoughts were how the nrf51822 could be used for energy meters (counting pulses and the gap between them),But unlike the arduino's which can not run timers when in sleep mode,The nrf5 can of course do this.
So the nrf5 would be able to report watts and usage while still using sleep mode.
But seeing the inaccuracy of the timer has put the brakes on that.
Yes being able to change the prescaler dynamically would help a great deal as 125ms / 582.542 hours is not really useful for most applications with a 250ms overrun.@rmtucker said in nRF5 Bluetooth action!:
@d00616
My initial thoughts were how the nrf51822 could be used for energy meters (counting pulses and the gap between them),But unlike the arduino's which can not run timers when in sleep mode,The nrf5 can of course do this.
So the nrf5 would be able to report watts and usage while still using sleep mode.If you have the idea to store the results into the EEPROM like storage the nRF5, then read the hints about this: https://github.com/d00616/arduino-NVM/#nvramh
The virtual EEPROM, the radio or debugging output are adding latency to the main loop. You will see more timing errors in long term run when you trust the sleep() time.
The nRF5 can help you to count without adding latency by the cpu. You can use a timer in counter mode which TASK_COUNT and TASKS_CAPTURE[0] are triggered by PPI. Then you can compare the hwMillis() with the last seen CC[0] content and do precise calculation of events.
With nRF52 there is an unused RTC wich can trigger TASKS_CAPTURE[0] at a specific time. One RTC is used for millis() in arduino-nrf5 and one RTC is used for sleep.
But seeing the inaccuracy of the timer has put the brakes on that.
Yes being able to change the prescaler dynamically would help a great deal as 125ms / 582.542 hours is not really useful for most applications with a 250ms overrun.I will change this.
-
@rmtucker
Here it is, though it's rather messy. Nonetheless, all it does is measure the supercap and solar panel voltages, send them, then sleep for 12 hours. Then repeats:// nrf51_client.pde // -*- mode: C++ -*- // Example sketch showing how to create a simple messageing client // with the RH_NRF51 class. RH_NRF51 class does not provide for addressing or // reliability, so you should only use RH_NRF51 if you do not need the higher // level messaging abilities. // It is designed to work with the other example nrf51_server. // Tested on RedBearLabs nRF51822 and BLE Nano kit, built with Arduino 1.6.4. // See http://redbearlab.com/getting-started-nrf51822/ // for how to set up your Arduino build environment // Also tested with Sparkfun nRF52832 breakout board, witth Arduino 1.6.13 and // Sparkfun nRF52 boards manager 0.2.3 #include <RH_NRF51.h> #include <MySensors.h> unsigned long SLEEP_TIME = 43200000; // 12 hour sleep time between measurements (in milliseconds) //unsigned long SLEEP_TIME = 3600000; // 1 hour sleep time between measurements (in milliseconds) //unsigned long SLEEP_TIME = 300000; // 5 minute sleep time between measurements (in milliseconds) //unsigned long SLEEP_TIME = 1000; // 1 second sleep time between measurements (in milliseconds) #define SUPERCAP_PIN A2 //input pin for reading the supercap's voltage #define SOLAR_PANEL_PIN A4 //input pin for reading the solar panel's voltage #define LDO_ENABLE_PIN 8 //D8 (P0.19) is output pin for enabling (HIGH) or disabling (LOW) the LDO #define NUM_MEASUREMENTS_TO_AVERAGE 3 //number of measurements to collect and then average #define MAX_MEASUREMENTS 10 //Maximum number of voltage measurements before returning a result. // Singleton instance of the radio driver RH_NRF51 nrf51; uint8_t data[10]; uint16_t batteryVoltage() { uint16_t lastRawVoltage, newRawVoltage; //uint16_t counter=0; //lastRawVoltage = hwCPUVoltage(); //throw away the first voltage measurement newRawVoltage = hwCPUVoltage(); return newRawVoltage; } uint16_t readRawVoltageOnPin(uint8_t thePin) { uint16_t lastRawVoltage, newRawVoltage; uint16_t counter=0; lastRawVoltage = analogRead(thePin); newRawVoltage = analogRead(thePin); while (((newRawVoltage != lastRawVoltage)) && (counter<MAX_MEASUREMENTS)) { //measure until two consecutive measurements match lastRawVoltage=newRawVoltage; newRawVoltage=analogRead(thePin); counter++; } uint32_t sumOfMeasurements=0; for (int i=0;i<NUM_MEASUREMENTS_TO_AVERAGE;i++) { sumOfMeasurements=sumOfMeasurements+analogRead(thePin); } return (sumOfMeasurements/NUM_MEASUREMENTS_TO_AVERAGE); } void myBaro() { uint32_t superCapVoltage=0; uint32_t solarPanelVoltage=0; uint32_t superCapRawVoltage=0; uint32_t solarPanelRawVoltage=0; digitalWrite(LDO_ENABLE_PIN, LOW); //disconnect solar panel superCapRawVoltage = readRawVoltageOnPin(SUPERCAP_PIN); superCapVoltage = (3048*(((superCapRawVoltage)*3127)/4095))/1591; //Serial.print("SuperCap voltage="); //Serial.println(superCapVoltage); //send(msg1_S_BARO_P.set(superCapVoltage)); //superCap's raw voltage // wait(500); // wait(500); //delayMicroseconds(1000); //wait for voltage to adjust after LDO disabled. Necessary??? solarPanelRawVoltage=readRawVoltageOnPin(SOLAR_PANEL_PIN); digitalWrite(LDO_ENABLE_PIN, HIGH); //re-connect solar panel solarPanelVoltage=(5500*(((solarPanelRawVoltage)*3181)/4095))/1289; //Serial.print("Solar Panel Voltage="); //Serial.println(solarPanelVoltage); //superCapVoltage=1234; data[0]= (superCapVoltage/1000)+'0'; data[1]= ((superCapVoltage%1000)/100)+'0'; data[2]= ((superCapVoltage%100)/10)+'0'; data[3]= (superCapVoltage%10)+'0'; data[4]=','; data[5]= (solarPanelVoltage/1000)+'0'; data[6]= ((solarPanelVoltage%1000)/100)+'0'; data[7]= ((solarPanelVoltage%100)/10)+'0'; data[8]= (solarPanelVoltage%10)+'0'; data[9]='\0'; nrf51.send(data, sizeof(data)); nrf51.waitPacketSent(); } void setup() { pinMode(LDO_ENABLE_PIN, OUTPUT); // Enable/Disable pin for the LDO digitalWrite(LDO_ENABLE_PIN, HIGH); //enable the LDO. analogReadResolution(12); //use 12-bit ADC resolution pinMode(SUPERCAP_PIN,INPUT); //Supercap voltage measurement pin pinMode(SOLAR_PANEL_PIN,INPUT); //Solar panel voltage measurement pin //delay(1000); // Wait for serial port etc to be ready Serial.begin(250000); //while (!Serial) ; // wait for serial port to connect. if (!nrf51.init()) Serial.println("init failed"); // Defaults after init are 2.402 GHz (channel 123), 2Mbps, 0dBm if (!nrf51.setChannel(123)) Serial.println("setChannel failed"); if (!nrf51.setRF(RH_NRF51::DataRate2Mbps, RH_NRF51::TransmitPower4dBm)) Serial.println("setRF failed"); // AES encryption can be enabled by setting the same key in the sender and receiver // uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; // nrf51.setEncryptionKey(key); // nrf51.printRegisters(); Serial.println("Setup of nr51 client completed."); Serial.println("Sending to nrf51_server..."); Serial.flush(); } uint32_t sentCounter=0; uint32_t replyCounter=0; void loop() { //uint16_t theBatteryVoltage; //theBatteryVoltage=batteryVoltage(); //theBatteryVoltage=batteryVoltage(); // Serial.print("Battery voltage = "); //Serial.print(theBatteryVoltage); //Serial.println(" millivolts."); // Send a message to nrf51_server //uint8_t data[] = "Hello World!"; /* data[0]= (theBatteryVoltage/1000)+'0'; data[1]= ((theBatteryVoltage%1000)/100)+'0'; data[2]= ((theBatteryVoltage%100)/10)+'0'; data[3]= (theBatteryVoltage%10)+'0'; data[4]='\0'; nrf51.send(data, sizeof(data)); sentCounter++; nrf51.waitPacketSent(); */ myBaro(); /* // Now wait for a reply uint8_t buf[RH_NRF51_MAX_MESSAGE_LEN]; uint8_t len = sizeof(buf); if (nrf51.waitAvailableTimeout(500)) { // Should be a reply message for us now if (nrf51.recv(buf, &len)) { Serial.print("got reply: "); Serial.println((char*)buf); replyCounter++; } else { Serial.println("recv failed"); } } else { Serial.println("No reply, is nrf51_server running?"); } Serial.print("sentCounter="); Serial.print(sentCounter); Serial.print(", replyCounter="); Serial.println(replyCounter); Serial.flush(); */ sleep(SLEEP_TIME); // Sleeps for 12 hours in deep sleep }Using Termite to timestamp the output received, what I got was:
2017/08/25 17:04:13: got request: 2684,0085 2017/08/26 05:04:12: got request: 2396,0076You can ignore the solar panel measurements, because I disconnected it so as to not interfere.
On the bright side, it woke up and reported within 1 second of when it was supposed to, after a 12 hour sleep.
-
@rmtucker
Here it is, though it's rather messy. Nonetheless, all it does is measure the supercap and solar panel voltages, send them, then sleep for 12 hours. Then repeats:// nrf51_client.pde // -*- mode: C++ -*- // Example sketch showing how to create a simple messageing client // with the RH_NRF51 class. RH_NRF51 class does not provide for addressing or // reliability, so you should only use RH_NRF51 if you do not need the higher // level messaging abilities. // It is designed to work with the other example nrf51_server. // Tested on RedBearLabs nRF51822 and BLE Nano kit, built with Arduino 1.6.4. // See http://redbearlab.com/getting-started-nrf51822/ // for how to set up your Arduino build environment // Also tested with Sparkfun nRF52832 breakout board, witth Arduino 1.6.13 and // Sparkfun nRF52 boards manager 0.2.3 #include <RH_NRF51.h> #include <MySensors.h> unsigned long SLEEP_TIME = 43200000; // 12 hour sleep time between measurements (in milliseconds) //unsigned long SLEEP_TIME = 3600000; // 1 hour sleep time between measurements (in milliseconds) //unsigned long SLEEP_TIME = 300000; // 5 minute sleep time between measurements (in milliseconds) //unsigned long SLEEP_TIME = 1000; // 1 second sleep time between measurements (in milliseconds) #define SUPERCAP_PIN A2 //input pin for reading the supercap's voltage #define SOLAR_PANEL_PIN A4 //input pin for reading the solar panel's voltage #define LDO_ENABLE_PIN 8 //D8 (P0.19) is output pin for enabling (HIGH) or disabling (LOW) the LDO #define NUM_MEASUREMENTS_TO_AVERAGE 3 //number of measurements to collect and then average #define MAX_MEASUREMENTS 10 //Maximum number of voltage measurements before returning a result. // Singleton instance of the radio driver RH_NRF51 nrf51; uint8_t data[10]; uint16_t batteryVoltage() { uint16_t lastRawVoltage, newRawVoltage; //uint16_t counter=0; //lastRawVoltage = hwCPUVoltage(); //throw away the first voltage measurement newRawVoltage = hwCPUVoltage(); return newRawVoltage; } uint16_t readRawVoltageOnPin(uint8_t thePin) { uint16_t lastRawVoltage, newRawVoltage; uint16_t counter=0; lastRawVoltage = analogRead(thePin); newRawVoltage = analogRead(thePin); while (((newRawVoltage != lastRawVoltage)) && (counter<MAX_MEASUREMENTS)) { //measure until two consecutive measurements match lastRawVoltage=newRawVoltage; newRawVoltage=analogRead(thePin); counter++; } uint32_t sumOfMeasurements=0; for (int i=0;i<NUM_MEASUREMENTS_TO_AVERAGE;i++) { sumOfMeasurements=sumOfMeasurements+analogRead(thePin); } return (sumOfMeasurements/NUM_MEASUREMENTS_TO_AVERAGE); } void myBaro() { uint32_t superCapVoltage=0; uint32_t solarPanelVoltage=0; uint32_t superCapRawVoltage=0; uint32_t solarPanelRawVoltage=0; digitalWrite(LDO_ENABLE_PIN, LOW); //disconnect solar panel superCapRawVoltage = readRawVoltageOnPin(SUPERCAP_PIN); superCapVoltage = (3048*(((superCapRawVoltage)*3127)/4095))/1591; //Serial.print("SuperCap voltage="); //Serial.println(superCapVoltage); //send(msg1_S_BARO_P.set(superCapVoltage)); //superCap's raw voltage // wait(500); // wait(500); //delayMicroseconds(1000); //wait for voltage to adjust after LDO disabled. Necessary??? solarPanelRawVoltage=readRawVoltageOnPin(SOLAR_PANEL_PIN); digitalWrite(LDO_ENABLE_PIN, HIGH); //re-connect solar panel solarPanelVoltage=(5500*(((solarPanelRawVoltage)*3181)/4095))/1289; //Serial.print("Solar Panel Voltage="); //Serial.println(solarPanelVoltage); //superCapVoltage=1234; data[0]= (superCapVoltage/1000)+'0'; data[1]= ((superCapVoltage%1000)/100)+'0'; data[2]= ((superCapVoltage%100)/10)+'0'; data[3]= (superCapVoltage%10)+'0'; data[4]=','; data[5]= (solarPanelVoltage/1000)+'0'; data[6]= ((solarPanelVoltage%1000)/100)+'0'; data[7]= ((solarPanelVoltage%100)/10)+'0'; data[8]= (solarPanelVoltage%10)+'0'; data[9]='\0'; nrf51.send(data, sizeof(data)); nrf51.waitPacketSent(); } void setup() { pinMode(LDO_ENABLE_PIN, OUTPUT); // Enable/Disable pin for the LDO digitalWrite(LDO_ENABLE_PIN, HIGH); //enable the LDO. analogReadResolution(12); //use 12-bit ADC resolution pinMode(SUPERCAP_PIN,INPUT); //Supercap voltage measurement pin pinMode(SOLAR_PANEL_PIN,INPUT); //Solar panel voltage measurement pin //delay(1000); // Wait for serial port etc to be ready Serial.begin(250000); //while (!Serial) ; // wait for serial port to connect. if (!nrf51.init()) Serial.println("init failed"); // Defaults after init are 2.402 GHz (channel 123), 2Mbps, 0dBm if (!nrf51.setChannel(123)) Serial.println("setChannel failed"); if (!nrf51.setRF(RH_NRF51::DataRate2Mbps, RH_NRF51::TransmitPower4dBm)) Serial.println("setRF failed"); // AES encryption can be enabled by setting the same key in the sender and receiver // uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; // nrf51.setEncryptionKey(key); // nrf51.printRegisters(); Serial.println("Setup of nr51 client completed."); Serial.println("Sending to nrf51_server..."); Serial.flush(); } uint32_t sentCounter=0; uint32_t replyCounter=0; void loop() { //uint16_t theBatteryVoltage; //theBatteryVoltage=batteryVoltage(); //theBatteryVoltage=batteryVoltage(); // Serial.print("Battery voltage = "); //Serial.print(theBatteryVoltage); //Serial.println(" millivolts."); // Send a message to nrf51_server //uint8_t data[] = "Hello World!"; /* data[0]= (theBatteryVoltage/1000)+'0'; data[1]= ((theBatteryVoltage%1000)/100)+'0'; data[2]= ((theBatteryVoltage%100)/10)+'0'; data[3]= (theBatteryVoltage%10)+'0'; data[4]='\0'; nrf51.send(data, sizeof(data)); sentCounter++; nrf51.waitPacketSent(); */ myBaro(); /* // Now wait for a reply uint8_t buf[RH_NRF51_MAX_MESSAGE_LEN]; uint8_t len = sizeof(buf); if (nrf51.waitAvailableTimeout(500)) { // Should be a reply message for us now if (nrf51.recv(buf, &len)) { Serial.print("got reply: "); Serial.println((char*)buf); replyCounter++; } else { Serial.println("recv failed"); } } else { Serial.println("No reply, is nrf51_server running?"); } Serial.print("sentCounter="); Serial.print(sentCounter); Serial.print(", replyCounter="); Serial.println(replyCounter); Serial.flush(); */ sleep(SLEEP_TIME); // Sleeps for 12 hours in deep sleep }Using Termite to timestamp the output received, what I got was:
2017/08/25 17:04:13: got request: 2684,0085 2017/08/26 05:04:12: got request: 2396,0076You can ignore the solar panel measurements, because I disconnected it so as to not interfere.
On the bright side, it woke up and reported within 1 second of when it was supposed to, after a 12 hour sleep.
@NeverDie said in nRF5 Bluetooth action!:
Here it is, though it's rather messy. Nonetheless, all it does is measure the supercap and solar panel voltages, send them, then sleep for 12 hours. Then repeats:
RadioHead sets the radio into the Idle state. The radio isn't powered off. There is no call in RadioHead to power off the radio.
-
@rmtucker
Here it is, though it's rather messy. Nonetheless, all it does is measure the supercap and solar panel voltages, send them, then sleep for 12 hours. Then repeats:// nrf51_client.pde // -*- mode: C++ -*- // Example sketch showing how to create a simple messageing client // with the RH_NRF51 class. RH_NRF51 class does not provide for addressing or // reliability, so you should only use RH_NRF51 if you do not need the higher // level messaging abilities. // It is designed to work with the other example nrf51_server. // Tested on RedBearLabs nRF51822 and BLE Nano kit, built with Arduino 1.6.4. // See http://redbearlab.com/getting-started-nrf51822/ // for how to set up your Arduino build environment // Also tested with Sparkfun nRF52832 breakout board, witth Arduino 1.6.13 and // Sparkfun nRF52 boards manager 0.2.3 #include <RH_NRF51.h> #include <MySensors.h> unsigned long SLEEP_TIME = 43200000; // 12 hour sleep time between measurements (in milliseconds) //unsigned long SLEEP_TIME = 3600000; // 1 hour sleep time between measurements (in milliseconds) //unsigned long SLEEP_TIME = 300000; // 5 minute sleep time between measurements (in milliseconds) //unsigned long SLEEP_TIME = 1000; // 1 second sleep time between measurements (in milliseconds) #define SUPERCAP_PIN A2 //input pin for reading the supercap's voltage #define SOLAR_PANEL_PIN A4 //input pin for reading the solar panel's voltage #define LDO_ENABLE_PIN 8 //D8 (P0.19) is output pin for enabling (HIGH) or disabling (LOW) the LDO #define NUM_MEASUREMENTS_TO_AVERAGE 3 //number of measurements to collect and then average #define MAX_MEASUREMENTS 10 //Maximum number of voltage measurements before returning a result. // Singleton instance of the radio driver RH_NRF51 nrf51; uint8_t data[10]; uint16_t batteryVoltage() { uint16_t lastRawVoltage, newRawVoltage; //uint16_t counter=0; //lastRawVoltage = hwCPUVoltage(); //throw away the first voltage measurement newRawVoltage = hwCPUVoltage(); return newRawVoltage; } uint16_t readRawVoltageOnPin(uint8_t thePin) { uint16_t lastRawVoltage, newRawVoltage; uint16_t counter=0; lastRawVoltage = analogRead(thePin); newRawVoltage = analogRead(thePin); while (((newRawVoltage != lastRawVoltage)) && (counter<MAX_MEASUREMENTS)) { //measure until two consecutive measurements match lastRawVoltage=newRawVoltage; newRawVoltage=analogRead(thePin); counter++; } uint32_t sumOfMeasurements=0; for (int i=0;i<NUM_MEASUREMENTS_TO_AVERAGE;i++) { sumOfMeasurements=sumOfMeasurements+analogRead(thePin); } return (sumOfMeasurements/NUM_MEASUREMENTS_TO_AVERAGE); } void myBaro() { uint32_t superCapVoltage=0; uint32_t solarPanelVoltage=0; uint32_t superCapRawVoltage=0; uint32_t solarPanelRawVoltage=0; digitalWrite(LDO_ENABLE_PIN, LOW); //disconnect solar panel superCapRawVoltage = readRawVoltageOnPin(SUPERCAP_PIN); superCapVoltage = (3048*(((superCapRawVoltage)*3127)/4095))/1591; //Serial.print("SuperCap voltage="); //Serial.println(superCapVoltage); //send(msg1_S_BARO_P.set(superCapVoltage)); //superCap's raw voltage // wait(500); // wait(500); //delayMicroseconds(1000); //wait for voltage to adjust after LDO disabled. Necessary??? solarPanelRawVoltage=readRawVoltageOnPin(SOLAR_PANEL_PIN); digitalWrite(LDO_ENABLE_PIN, HIGH); //re-connect solar panel solarPanelVoltage=(5500*(((solarPanelRawVoltage)*3181)/4095))/1289; //Serial.print("Solar Panel Voltage="); //Serial.println(solarPanelVoltage); //superCapVoltage=1234; data[0]= (superCapVoltage/1000)+'0'; data[1]= ((superCapVoltage%1000)/100)+'0'; data[2]= ((superCapVoltage%100)/10)+'0'; data[3]= (superCapVoltage%10)+'0'; data[4]=','; data[5]= (solarPanelVoltage/1000)+'0'; data[6]= ((solarPanelVoltage%1000)/100)+'0'; data[7]= ((solarPanelVoltage%100)/10)+'0'; data[8]= (solarPanelVoltage%10)+'0'; data[9]='\0'; nrf51.send(data, sizeof(data)); nrf51.waitPacketSent(); } void setup() { pinMode(LDO_ENABLE_PIN, OUTPUT); // Enable/Disable pin for the LDO digitalWrite(LDO_ENABLE_PIN, HIGH); //enable the LDO. analogReadResolution(12); //use 12-bit ADC resolution pinMode(SUPERCAP_PIN,INPUT); //Supercap voltage measurement pin pinMode(SOLAR_PANEL_PIN,INPUT); //Solar panel voltage measurement pin //delay(1000); // Wait for serial port etc to be ready Serial.begin(250000); //while (!Serial) ; // wait for serial port to connect. if (!nrf51.init()) Serial.println("init failed"); // Defaults after init are 2.402 GHz (channel 123), 2Mbps, 0dBm if (!nrf51.setChannel(123)) Serial.println("setChannel failed"); if (!nrf51.setRF(RH_NRF51::DataRate2Mbps, RH_NRF51::TransmitPower4dBm)) Serial.println("setRF failed"); // AES encryption can be enabled by setting the same key in the sender and receiver // uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; // nrf51.setEncryptionKey(key); // nrf51.printRegisters(); Serial.println("Setup of nr51 client completed."); Serial.println("Sending to nrf51_server..."); Serial.flush(); } uint32_t sentCounter=0; uint32_t replyCounter=0; void loop() { //uint16_t theBatteryVoltage; //theBatteryVoltage=batteryVoltage(); //theBatteryVoltage=batteryVoltage(); // Serial.print("Battery voltage = "); //Serial.print(theBatteryVoltage); //Serial.println(" millivolts."); // Send a message to nrf51_server //uint8_t data[] = "Hello World!"; /* data[0]= (theBatteryVoltage/1000)+'0'; data[1]= ((theBatteryVoltage%1000)/100)+'0'; data[2]= ((theBatteryVoltage%100)/10)+'0'; data[3]= (theBatteryVoltage%10)+'0'; data[4]='\0'; nrf51.send(data, sizeof(data)); sentCounter++; nrf51.waitPacketSent(); */ myBaro(); /* // Now wait for a reply uint8_t buf[RH_NRF51_MAX_MESSAGE_LEN]; uint8_t len = sizeof(buf); if (nrf51.waitAvailableTimeout(500)) { // Should be a reply message for us now if (nrf51.recv(buf, &len)) { Serial.print("got reply: "); Serial.println((char*)buf); replyCounter++; } else { Serial.println("recv failed"); } } else { Serial.println("No reply, is nrf51_server running?"); } Serial.print("sentCounter="); Serial.print(sentCounter); Serial.print(", replyCounter="); Serial.println(replyCounter); Serial.flush(); */ sleep(SLEEP_TIME); // Sleeps for 12 hours in deep sleep }Using Termite to timestamp the output received, what I got was:
2017/08/25 17:04:13: got request: 2684,0085 2017/08/26 05:04:12: got request: 2396,0076You can ignore the solar panel measurements, because I disconnected it so as to not interfere.
On the bright side, it woke up and reported within 1 second of when it was supposed to, after a 12 hour sleep.
@NeverDie
So your sketch only wakes up every 12hours.
What current is it drawing using the radiohead library vs mysensors for an equivalent 12 hour sleep because in past discussions with you i remember you saying 5-6uA while sleeping,is this still correct?
I dont see much advantage to the radiohead library if only sending at 12hour intervals. -
@NeverDie
So your sketch only wakes up every 12hours.
What current is it drawing using the radiohead library vs mysensors for an equivalent 12 hour sleep because in past discussions with you i remember you saying 5-6uA while sleeping,is this still correct?
I dont see much advantage to the radiohead library if only sending at 12hour intervals.@rmtucker said in nRF5 Bluetooth action!:
@NeverDie
So your sketch only wakes up every 12hours.
What current is it drawing using the radiohead library vs mysensors for an equivalent 12 hour sleep because in past discussions with you i remember you saying 5-6uA while sleeping,is this still correct?
I dont see much advantage to the radiohead library if only sending at 12hour intervals.The 6ua was measured with it in deep sleep, where it relied on an external interrupt to wakeup. This measurement was intended to see what it would be if it woke-up using the RTC. So, the 12 hour interval is artificial, for measurement purposes.
@d00616
I had wrongly assumed that the "sleep(...)" command would sleep the radio. Thanks for pointing out my error. How/when is it that Mysensors puts the radio to sleep? Does it just happen automatically at the end of every sending/receiving? -
@rmtucker said in nRF5 Bluetooth action!:
@NeverDie
So your sketch only wakes up every 12hours.
What current is it drawing using the radiohead library vs mysensors for an equivalent 12 hour sleep because in past discussions with you i remember you saying 5-6uA while sleeping,is this still correct?
I dont see much advantage to the radiohead library if only sending at 12hour intervals.The 6ua was measured with it in deep sleep, where it relied on an external interrupt to wakeup. This measurement was intended to see what it would be if it woke-up using the RTC. So, the 12 hour interval is artificial, for measurement purposes.
@d00616
I had wrongly assumed that the "sleep(...)" command would sleep the radio. Thanks for pointing out my error. How/when is it that Mysensors puts the radio to sleep? Does it just happen automatically at the end of every sending/receiving?@NeverDie said in nRF5 Bluetooth action!:
I had wrongly assumed that the "sleep(...)" command would sleep the radio. Thanks for pointing out my error. How/when is it that Mysensors puts the radio to sleep? Does it just happen automatically at the end of every sending/receiving?
We are both not 100% correct ;-) The hwSleep() function doesn't disable the radio, but the sleep() function does it, when MY_SENSOR_NETWORK is defined.
After Sleep transportReInitialise() is called. Then you have to initialize RadioHead again.