Hard to grab time and value sent from controller


  • Hardware Contributor

    Hi!

    Im making a sketch where i ask for time and counter from the controller:

          gw.request(CHILD_ID, V_VAR1);
          Serial.println("Request pulsecount");
          gw.wait(3000);
          lastSend=currentTime;
          gw.process();
    
    void incomingMessage(const MyMessage &message) {
      if (message.type==V_VAR1) {
        hwPulseCounter = message.getULong();```
    

    What happens is that my sensor cant grab/get the answer sent out from the controller:

    send: 7-7-0-0 s=255,c=3,t=1,pt=0,l=0,sg=0,st=ok:
    send: 7-7-0-0 s=255,c=3,t=1,pt=0,l=0,sg=0,st=ok:
    send: 7-7-0-0 s=255,c=3,t=1,pt=0,l=0,sg=0,st=ok:
    send: 7-7-0-0 s=255,c=3,t=1,pt=0,l=0,sg=0,st=ok:
    send: 7-7-0-0 s=255,c=3,t=1,pt=0,l=0,sg=0,st=ok:
    send: 7-7-0-0 s=255,c=3,t=1,pt=0,l=0,sg=0,st=ok:
    
    

    sometimes it gets it right away, but sometimes it takes 50 sends before i get the recieve.

    I see in MYSController that its somewhere between the GW and the sensor. The controller is trying to send time and counter all of the times.

    Any ideas?


  • Hardware Contributor

    Anyone? (Sorry for bumping - but its really annoying!)


  • Admin

    You didn't publish the full sketch.. Can't see any time request/pickup code above.


  • Hardware Contributor

    Its a rain / tip bucket sensor. I made it since the original sketch didnt work with domoticz, but thats another problem... well the code.

    #include <SPI.h>
    #include <MySensor.h>  
    #include <Time.h>
    
    // Running this in Domoticz stable version 2.5 will not work - upgrade to beta.
    
    #define DIGITAL_INPUT_SENSOR 3                  // The reed switch you attached.  (Only 2 and 3 generates interrupt!)
    #define INTERRUPT DIGITAL_INPUT_SENSOR-2        // Usually the interrupt = pin -2 (on uno/nano anyway)
    
    #define CHILD_ID 1                              // Id of the sensor child
    #define NODE_ID 7                               // or AUTO to let controller assign
    #define SKETCH_NAME "Rain Gauge"                // Change to a fancy name you like
    #define SKETCH_VERSION "1.7"                    // Your version
    
    unsigned long SLEEP_TIME = 18*60000;            // Sleep time (in milliseconds).
    //unsigned long SLEEP_TIME = 20000;             // use this instead for debug
    
    float hwRainVolume = 0;                         // Current rainvolume calculated in hardware.
    int hwPulseCounter = 0;                         // Pulsecount recieved from GW
    float fullCounter = 0;                           // Counts when to send counter
    float bucketSize = 0.5;                           // Bucketsize mm, needs to be 1, 0.5, 0.25, 0.2 or 0.1
    boolean pcReceived = false;                     // If we have recieved the pulscount from GW or not 
    boolean reedState;                              // Current state the reedswitch is in
    boolean oldReedState;                           // Old state (last state) of the reedswitch
    unsigned long lastSend =0;                      // Time we last tried to fetch counter.
    byte lastHour;                                  // To know if we have a new hour and new day in this reading.
    byte currentHour = 0;                           // Value to store the current hour
    int maxTips = 0;                                // Int to avoid block time update due to heavy rain
    
    MySensor gw;
    MyMessage volumeMsg(CHILD_ID,V_RAIN);
    MyMessage lastCounterMsg(CHILD_ID,V_VAR1);
    
    //=========================
    // BATTERY VOLTAGE DIVIDER SETUP
    // 1M, 470K divider across battery and using internal ADC ref of 1.1V
    // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
    // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
    // 3.44/1023 = Volts per bit = 0.003363075
    #define VBAT_PER_BITS 0.003363075  
    #define VMIN 1.9                                  //  Vmin (radio Min Volt)=1.9V (564v)
    #define VMAX 3.0                                  //  Vmax = (2xAA bat)=3.0V (892v)
    int batteryPcnt = 0;                              // Calc value for battery %
    int batLoop = 0;                                  // Loop to help calc average
    int batArray[3];                                  // Array to store value for average calc.
    int BATTERY_SENSE_PIN = A0;                       // select the input pin for the battery sense point
    //=========================
    
    void setup()  
    {  
      // use the 1.1 V internal reference
      analogReference(INTERNAL);             // For battery sensing
      pinMode(DIGITAL_INPUT_SENSOR, INPUT);  // sets the reed sensor digital pin as input
    
      reedState = digitalRead(DIGITAL_INPUT_SENSOR); // Read what state the reedswitch is in
      oldReedState = reedState; // Set startup position for reedswitch
    
      delay(500); // Allow time for radio if power used as reset
    
      //Begin (Change if you dont want static node_id! (NODE_ID to AUTO)
      gw.begin(incomingMessage, NODE_ID, false, 0);
      
      // Send the Sketch Version Information to the Gateway
      gw.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
    
      // Register this device as Rain sensor (will not show in Domoticz until first value arrives)
      gw.present(CHILD_ID, S_RAIN);       
    
      // Get time from controller
      getNewTime();
     
      Serial.print("Startup - Current hour: "); Serial.println(currentHour);
      Serial.println("Startup completed");
    }
    
    void loop()     
    { 
    gw.process();
    
    unsigned long currentTime = millis();
    
        //See if we have the counter/pulse from Domoticz - and ask for it if we dont.
        if (!pcReceived && (currentTime - lastSend > 2500)) {      
          gw.process();
          gw.request(CHILD_ID, V_VAR1);
          Serial.println("Request pulsecount");
          gw.wait(3000);
          lastSend=currentTime;
          gw.process();
          return;
        }
        if (!pcReceived) {
          return;
        }
    
    //Read if the bucket tipped over
    reedState = digitalRead(DIGITAL_INPUT_SENSOR);
    boolean tipped = oldReedState != reedState; 
    
        //BUCKET TIPS!
        if (tipped==true) {
        Serial.println("The bucket has tipped over...");
        oldReedState = reedState;
        hwRainVolume = hwRainVolume + bucketSize;
        gw.send(volumeMsg.set((float)hwRainVolume,1));
        gw.wait(1000);
        fullCounter = fullCounter + bucketSize;
        maxTips++;
        Serial.println(bucketSize);
        Serial.println(fullCounter);
    
          //Count so we send the counter for every 1mm
          if(fullCounter >= 1){
          hwPulseCounter++;
          gw.send(lastCounterMsg.set(hwPulseCounter));
          gw.wait(1000);
          Serial.println(fullCounter);
          fullCounter = 0;
          }
          
            //If heavy rain, update time every X bucket tip
             if (maxTips >= 6)
             {
             currentHour = 25;
             getNewTime();
             maxTips = 0;
             }
        }
        
        if (tipped==false) {
         //No bucket tipped over last sleep-period, check battery and ask the time then...
         batM(); 
         currentHour = 25;
         getNewTime();    
        }
    
    lastSend=currentTime;
    gw.sleep(INTERRUPT, CHANGE, SLEEP_TIME); 
    //The interupt can be CHANGE or FALLING depending on how you wired the hardware.
    }
    
    //Read if we have a incoming message.
    void incomingMessage(const MyMessage &message) {
      if (message.type==V_VAR1) {
        hwPulseCounter = message.getULong();
        pcReceived = true;
        Serial.print("Received last pulse count from gw: ");
        Serial.println(hwPulseCounter);   
      }
    }
    
    //Get the time from controller.
    void getNewTime() {
      gw.process();
      while (currentHour == 25)
      {
        gw.process();
        gw.requestTime(receiveTime);
        Serial.println("Getting Time");
        gw.wait(3000); // call once per second
        gw.process();
      }
       while (timeStatus() == timeNotSet)
      {
        gw.process();
        gw.requestTime(receiveTime);
        Serial.println("Getting Time @ Startup");
        gw.wait(3000); // call once per second
        gw.process();
      }
      
      if (currentHour == 0 && lastHour == 23)
        { //means currentHour = 0 and lasthour = 23
        Serial.println("New day!");
        hwRainVolume = 0; //New day
      }  
      lastHour = currentHour;
    }
    
    
    void batM() //The battery calculations
    {
       delay(500);
       // Battery monitoring reading
       int sensorValue = analogRead(BATTERY_SENSE_PIN);    
       delay(500);
       
       // Calculate the battery in %
       float Vbat  = sensorValue * VBAT_PER_BITS;
       int batteryPcnt = static_cast<int>(((Vbat-VMIN)/(VMAX-VMIN))*100.);
       Serial.print("Battery percent: "); Serial.print(batteryPcnt); Serial.println(" %");  
       
       // Add it to array so we get an average of 3 (3x20min)
       batArray[batLoop] = batteryPcnt;
      
       if (batLoop > 1) {  
         batteryPcnt = (batArray[0] + batArray[1] + batArray[2]);
         batteryPcnt = batteryPcnt / 3;
     
       if (batteryPcnt > 100) {
         batteryPcnt=100;
     }
     
         Serial.print("Battery Average (Send): "); Serial.print(batteryPcnt); Serial.println(" %");
           gw.sendBatteryLevel(batteryPcnt);
           batLoop = 0;
           
         //Sends 1 per hour
         gw.send(volumeMsg.set((float)hwRainVolume,1));   
         gw.send(lastCounterMsg.set(hwPulseCounter));
         }
         else 
         {
         batLoop++;
         }
    }
    
    //Read if we have a incoming time reading - set this if so.
    void receiveTime(unsigned long time)
    {
    setTime(time);
    char theTime[6];
     
    currentHour = hour();
    Serial.print("Time received: ");Serial.println(hour());
    maxTips = 0;
      
    }
    
    

    If you can find why it sometimes takes 1 shot and sometimes 50 shots before recieving the time and counter it would be great.


  • Admin

    What's up with this? Does it even compile?

    while (timeStatus() == timeNotSet)


  • Hardware Contributor

    Hi!
    Yea - compiles with no problems.
    This part is "stolen" from the original raingauge sketch and not something im used to working with.
    timeNotSet is a variable in time.h

    How would you code this?

    • Ask for time/counter
    • Check if recieved
    • If not recieved - ask again

  • Admin

    Have you looked at the TimeAwareSensor example?


  • Hardware Contributor

    Yea I did, and I dont see any difference from mine.
    The thing is that I sleep my Sensor so i need a loop inside the void loop() to check if I recieved the time.

    Maybe its hardware or the position of the sensor... ill try to relocate and load the sketch to another build


  • Contest Winner

    @sundberg84 I haven't looked at your code, but do you put the Arduino to sleep after you've received the time or after you made the timeRequest to the controller? I'm not sure, but if you do the latter that might be your problem. I'm guessing that the Node is not able to receive messages from the gateway, when it's in sleep mode.


  • Hardware Contributor

    Hi.

    No i recieve the time, check if its a new day and then sleep the node.
    This is done every sleep cycle (20min),. (Im aware about the failure margin here).

    I do not sleep the sensor until i got the new time so that should not be a problem.


  • Hardware Contributor

    Looking at MysController i get this when i get into the bad loop:

    2015-10-16 16:27:20	INFO	Reply time request
    2015-10-16 16:27:20	TX	7;255;3;0;1;1445012841
    2015-10-16 16:27:20	RX	7;255;3;0;1;
    2015-10-16 16:27:24	INFO	Reply time request
    2015-10-16 16:27:24	TX	7;255;3;0;1;1445012844
    2015-10-16 16:27:24	RX	7;255;3;0;1;
    2015-10-16 16:27:28	INFO	Reply time request
    2015-10-16 16:27:28	TX	7;255;3;0;1;1445012848
    2015-10-16 16:27:28	RX	7;255;3;0;1;
    2015-10-16 16:27:28	RX	5;0;1;0;4;1020
    2015-10-16 16:27:31	INFO	Reply time request
    2015-10-16 16:27:31	TX	7;255;3;0;1;1445012852
    2015-10-16 16:27:31	RX	7;255;3;0;1;
    2015-10-16 16:27:35	INFO	Reply time request
    2015-10-16 16:27:35	TX	7;255;3;0;1;1445012855
    2015-10-16 16:27:35	RX	7;255;3;0;1;
    2015-10-16 16:27:38	INFO	Reply time request
    2015-10-16 16:27:38	TX	7;255;3;0;1;1445012859
    2015-10-16 16:27:38	RX	7;255;3;0;1;
    

    @hek
    Its like its working one way (Sensor -> Repteter -> Controller) but not the other way around. Is it not using the repeater and thats why the request with time is not getting back?


  • Hardware Contributor

    Or its a bad NRF batch i got... AGAIN 😞
    Notised its a new batch im on... have to try some other nrf in that patch. Works one way though...


  • Admin

    Also make sure you're running the latest in master branch on gw/repeater. There was a bug there earlier affecting outgoing messages through repeaters.


  • Hardware Contributor

    I run 1.4 gw and updated repeaters after bug was reporter (bad routing causing à loop). Its à bit job to update gw to 1.5. Do you think it can make any difference @hek ?


  • Admin

    I doubt it would change anything. It's the intermittent failure behaviour that is weird.


  • Hardware Contributor

    I have ordered new nrf radios. Let's hope the makey the difference.


  • Hardware Contributor

    New radio, pro mini and still the same problems 😞
    I cant get it.

    Looking at the gw leds the recieve led blinks when the node sends out the request. 1 second later the controller and gw responds accoring to MYSController and i see the transmit and error led blink.

    i have the node right beside the gw now and no repeaters.
    Any clues, anyone???


  • Admin

    And how does the node log look like?

    Did you upgrade to 1.5?


  • Hardware Contributor

    No i did not upgrade the gw since i had so much problems with the connections...

    Nod serial as before:
    (From startup)

    send: 7-7-0-0 s=255,c=0,t=17,pt=0,l=3,sg=0,st=ok:1.5
    send: 7-7-0-0 s=255,c=3,t=6,pt=1,l=1,sg=0,st=ok:0
    sensor started, id=7, parent=0, distance=1
    send: 7-7-0-0 s=255,c=3,t=11,pt=0,l=10,sg=0,st=ok:Rain Gauge
    send: 7-7-0-0 s=255,c=3,t=12,pt=0,l=3,sg=0,st=ok:1.7
    send: 7-7-0-0 s=1,c=0,t=10,pt=0,l=0,sg=0,st=ok:
    Startup completed
    send: 7-7-0-0 s=1,c=2,t=24,pt=0,l=0,sg=0,st=ok:
    Request pulsecount
    send: 7-7-0-0 s=1,c=2,t=24,pt=0,l=0,sg=0,st=ok:
    Request pulsecount
    send: 7-7-0-0 s=1,c=2,t=24,pt=0,l=0,sg=0,st=ok:
    Request pulsecount
    read: 0-0-7 s=1,c=2,t=24,pt=0,l=2,sg=0:52
    Received last pulse count from gw: 52
    send: 7-7-0-0 s=255,c=3,t=1,pt=0,l=0,sg=0,st=ok:
    Getting Time
    send: 7-7-0-0 s=255,c=3,t=1,pt=0,l=0,sg=0,st=ok:
    Getting Time
    read: 0-0-7 s=255,c=3,t=1,pt=0,l=10,sg=0:1446829805
    Time received: 17
    
    

  • Admin

    DI you have a similar serial log for the gateway? Think you should try to upgrade to be aligned with 1.5. Don't remember what problems you had earlier...


Log in to reply
 

Suggested Topics

9
Online

11.4k
Users

11.1k
Topics

112.7k
Posts