Hard to grab time and value sent from controller
-
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?
-
Anyone? (Sorry for bumping - but its really annoying!)
-
You didn't publish the full sketch.. Can't see any time request/pickup code above.
-
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.
-
What's up with this? Does it even compile?
while (timeStatus() == timeNotSet)
-
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.hHow would you code this?
- Ask for time/counter
- Check if recieved
- If not recieved - ask again
-
Have you looked at the TimeAwareSensor example?
-
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
-
@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.
-
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.
-
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?
-
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...
-
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.
-
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 ?
-
I doubt it would change anything. It's the intermittent failure behaviour that is weird.
-
I have ordered new nrf radios. Let's hope the makey the difference.
-
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???
-
And how does the node log look like?
Did you upgrade to 1.5?
-
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
-
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...