Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. My Project
  3. nRF5 action!

nRF5 action!

Scheduled Pinned Locked Moved My Project
1.9k Posts 49 Posters 630.9k Views 44 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • rmtuckerR rmtucker

    MY_HW_RTC->CC[0] = (ms / 125) + 2;

    It seems the +2 above is adding 250ms.
    Why is it done like this???

    d00616D Offline
    d00616D Offline
    d00616
    Contest Winner
    wrote on last edited by
    #699

    @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

    rmtuckerR 1 Reply Last reply
    0
    • d00616D d00616

      @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

      rmtuckerR Offline
      rmtuckerR Offline
      rmtucker
      wrote on last edited by
      #700

      @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.

      d00616D 2 Replies Last reply
      0
      • rmtuckerR Offline
        rmtuckerR Offline
        rmtucker
        wrote on last edited by
        #701

        Just wondering what the prescaler etc would have to be set to for ms accuracy and how long before overflow.(aint got my maths head on today):blush:

        1 Reply Last reply
        0
        • NeverDieN NeverDie

          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.

          d00616D Offline
          d00616D Offline
          d00616
          Contest Winner
          wrote on last edited by d00616
          #702

          @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.76mA

          Looks like the node is most time fully active.

          1 Reply Last reply
          1
          • rmtuckerR rmtucker

            @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.

            d00616D Offline
            d00616D Offline
            d00616
            Contest Winner
            wrote on last edited by
            #703

            @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.

            1 Reply Last reply
            0
            • rmtuckerR rmtucker

              @NeverDie
              Seeing Your sketch would help?

              NeverDieN Offline
              NeverDieN Offline
              NeverDie
              Hero Member
              wrote on last edited by NeverDie
              #704

              @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,0076
              

              You 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.

              d00616D rmtuckerR 2 Replies Last reply
              0
              • NeverDieN NeverDie

                @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,0076
                

                You 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.

                d00616D Offline
                d00616D Offline
                d00616
                Contest Winner
                wrote on last edited by
                #705

                @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.

                1 Reply Last reply
                2
                • NeverDieN NeverDie

                  @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,0076
                  

                  You 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.

                  rmtuckerR Offline
                  rmtuckerR Offline
                  rmtucker
                  wrote on last edited by
                  #706

                  @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.

                  NeverDieN 1 Reply Last reply
                  0
                  • rmtuckerR rmtucker

                    @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.

                    NeverDieN Offline
                    NeverDieN Offline
                    NeverDie
                    Hero Member
                    wrote on last edited by NeverDie
                    #707

                    @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?

                    d00616D 1 Reply Last reply
                    0
                    • NeverDieN NeverDie

                      @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?

                      d00616D Offline
                      d00616D Offline
                      d00616
                      Contest Winner
                      wrote on last edited by d00616
                      #708

                      @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.

                      NeverDieN 1 Reply Last reply
                      1
                      • d00616D d00616

                        @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.

                        NeverDieN Offline
                        NeverDieN Offline
                        NeverDie
                        Hero Member
                        wrote on last edited by
                        #709

                        @d00616 said in nRF5 Bluetooth action!:

                        After Sleep transportReInitialise() is called. Then you have to initialize RadioHead again.

                        So, even with RAM retention active while sleeping, each time the radio is awoken, it needs to be re-initialized?

                        d00616D 1 Reply Last reply
                        0
                        • NeverDieN NeverDie

                          @d00616 said in nRF5 Bluetooth action!:

                          After Sleep transportReInitialise() is called. Then you have to initialize RadioHead again.

                          So, even with RAM retention active while sleeping, each time the radio is awoken, it needs to be re-initialized?

                          d00616D Offline
                          d00616D Offline
                          d00616
                          Contest Winner
                          wrote on last edited by
                          #710

                          @NeverDie said in nRF5 Bluetooth action!:

                          So, even with RAM retention active while sleeping, each time the radio is awoken, it needs to be re-initialized?

                          The Radio has to be initialized after power down. This doesn't depend on RAM retention.

                          1 Reply Last reply
                          0
                          • NeverDieN Offline
                            NeverDieN Offline
                            NeverDie
                            Hero Member
                            wrote on last edited by NeverDie
                            #711

                            According to Table 39 of the mRF52832 datasheet, there is only one radio state resembling sleep, and that is the DISABLED radio state where "No operations are going on inside the radio and the power consumption is at a minimum."

                            Apparently the radio is disabled through register TASKS_DISABLE, offset 0x010, Disable RADIO, as indicated by Table 41 register overview.

                            1 Reply Last reply
                            0
                            • NeverDieN Offline
                              NeverDieN Offline
                              NeverDie
                              Hero Member
                              wrote on last edited by NeverDie
                              #712

                              But how exactly does one read or write to these registers? It looks like a quite different arrangement than writing to registers for an nRF24 or an RFM69 or a LoRa chip.

                              d00616D 1 Reply Last reply
                              0
                              • NeverDieN NeverDie

                                But how exactly does one read or write to these registers? It looks like a quite different arrangement than writing to registers for an nRF24 or an RFM69 or a LoRa chip.

                                d00616D Offline
                                d00616D Offline
                                d00616
                                Contest Winner
                                wrote on last edited by
                                #713

                                @NeverDie said in nRF5 Bluetooth action!:

                                But how exactly does one read or write to these registers? It looks like a quite different arrangement than writing to registers for an nRF24 or an RFM69 or a LoRa chip.

                                You have to include nrf.h. To disable the radio, you can do this:

                                https://github.com/mysensors/MySensors/blob/development/drivers/NRF5/Radio_ESB.cpp#L264

                                If your transmitting power is 0dbm, then "TX only run current PRF = 0dBm" with 11.6 mA is near the calculated current, when the radio stays in TX mode after sending the data.

                                NeverDieN 1 Reply Last reply
                                0
                                • d00616D d00616

                                  @NeverDie said in nRF5 Bluetooth action!:

                                  But how exactly does one read or write to these registers? It looks like a quite different arrangement than writing to registers for an nRF24 or an RFM69 or a LoRa chip.

                                  You have to include nrf.h. To disable the radio, you can do this:

                                  https://github.com/mysensors/MySensors/blob/development/drivers/NRF5/Radio_ESB.cpp#L264

                                  If your transmitting power is 0dbm, then "TX only run current PRF = 0dBm" with 11.6 mA is near the calculated current, when the radio stays in TX mode after sending the data.

                                  NeverDieN Offline
                                  NeverDieN Offline
                                  NeverDie
                                  Hero Member
                                  wrote on last edited by NeverDie
                                  #714

                                  @d00616
                                  Will this block of code guarantee that the radio is disabled?

                                    Serial.println("Testing whether radio is disabled...");
                                    Serial.print("NRF_RADIO->EVENTS_DISABLED=");
                                    Serial.println(NRF_RADIO->EVENTS_DISABLED);
                                    while (!(NRF_RADIO->EVENTS_DISABLED)) {
                                      Serial.print("NRF_RADIO->EVENTS_DISABLED=");
                                      Serial.println(NRF_RADIO->EVENTS_DISABLED);
                                      NRF_RADIO->TASKS_DISABLE = 1;  //sleep the radio
                                    }
                                    Serial.println("Radio disabled.");
                                  
                                  d00616D 1 Reply Last reply
                                  0
                                  • NeverDieN NeverDie

                                    @d00616
                                    Will this block of code guarantee that the radio is disabled?

                                      Serial.println("Testing whether radio is disabled...");
                                      Serial.print("NRF_RADIO->EVENTS_DISABLED=");
                                      Serial.println(NRF_RADIO->EVENTS_DISABLED);
                                      while (!(NRF_RADIO->EVENTS_DISABLED)) {
                                        Serial.print("NRF_RADIO->EVENTS_DISABLED=");
                                        Serial.println(NRF_RADIO->EVENTS_DISABLED);
                                        NRF_RADIO->TASKS_DISABLE = 1;  //sleep the radio
                                      }
                                      Serial.println("Radio disabled.");
                                    
                                    d00616D Offline
                                    d00616D Offline
                                    d00616
                                    Contest Winner
                                    wrote on last edited by
                                    #715

                                    @NeverDie said in nRF5 Bluetooth action!:

                                    Will this block of code guarantee that the radio is disabled?

                                    This one is better:

                                    if (NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) {
                                    	NRF_RADIO->TASKS_DISABLE = 1;
                                    }
                                    
                                    NeverDieN 1 Reply Last reply
                                    0
                                    • rmtuckerR rmtucker

                                      @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.

                                      d00616D Offline
                                      d00616D Offline
                                      d00616
                                      Contest Winner
                                      wrote on last edited by
                                      #716

                                      @rmtucker said in nRF5 Bluetooth action!:

                                      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.

                                      The sleep() function is now more precise for sleeping <512s:

                                      https://github.com/mysensors/MySensors/pull/909

                                      The PR is waiting for merge.

                                      rmtuckerR 1 Reply Last reply
                                      1
                                      • d00616D d00616

                                        @NeverDie said in nRF5 Bluetooth action!:

                                        Will this block of code guarantee that the radio is disabled?

                                        This one is better:

                                        if (NRF_RADIO->STATE != RADIO_STATE_STATE_Disabled) {
                                        	NRF_RADIO->TASKS_DISABLE = 1;
                                        }
                                        
                                        NeverDieN Offline
                                        NeverDieN Offline
                                        NeverDie
                                        Hero Member
                                        wrote on last edited by
                                        #717

                                        @d00616
                                        That works. Thanks!

                                        What's the best way to awaken the radio after sleeping it though? I've tried:

                                            NRF_RADIO->TASKS_START  = 1;  //awaken the radio
                                        

                                        and

                                            NRF_RADIO->TASKS_TXEN  = 1;  //awaken the radio
                                        

                                        and neither seems to have an effect. The radio stays disabled.

                                        d00616D 2 Replies Last reply
                                        0
                                        • NeverDieN NeverDie

                                          @d00616
                                          That works. Thanks!

                                          What's the best way to awaken the radio after sleeping it though? I've tried:

                                              NRF_RADIO->TASKS_START  = 1;  //awaken the radio
                                          

                                          and

                                              NRF_RADIO->TASKS_TXEN  = 1;  //awaken the radio
                                          

                                          and neither seems to have an effect. The radio stays disabled.

                                          d00616D Offline
                                          d00616D Offline
                                          d00616
                                          Contest Winner
                                          wrote on last edited by
                                          #718

                                          @NeverDie said in nRF5 Bluetooth action!:

                                          What's the best way to awaken the radio after sleeping it though? I've tried:

                                          This depends on the implementation. Sorry, at the moment I have not time to look into the RadioHead code in that detail. You can try to initialize the library again.

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          16

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.0k

                                          Posts


                                          Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular