Sketch problem
-
I have a sketch with some sensors. But the two that plays a part in this drama is the Temperature sensor and a Relay.
Every time when the sketch report a new temperature value I also get a SET message for the relay.If you need to see the whole sketch let me know.
This is how I report the new temperature.
MyMessage tempMsg(TEMP_ID, V_TEMP); send(tempMsg.set(tempC, 1));
And this is the output from MYSController:
688 2016-10-16 11:40:33 RX 1 - FishTank 1 - Water temperature C_SET NO V_TEMP 25.7 690 2016-10-16 11:40:35 RX 1 - FishTank 2 - Water valve C_SET YES V_LIGHT 0 691 2016-10-16 11:40:39 RX 1 - FishTank 1 - Water temperature C_SET NO V_TEMP 26.2 692 2016-10-16 11:40:39 RX 1 - FishTank 2 - Water valve C_SET YES V_LIGHT 0 694 2016-10-16 11:40:45 RX 1 - FishTank 1 - Water temperature C_SET NO V_TEMP 26.1 695 2016-10-16 11:40:45 RX 1 - FishTank 2 - Water valve C_SET YES V_LIGHT 0 697 2016-10-16 11:41:03 RX 1 - FishTank 1 - Water temperature C_SET NO V_TEMP 26.0 698 2016-10-16 11:41:03 RX 1 - FishTank 2 - Water valve C_SET YES V_LIGHT 0 700 2016-10-16 11:41:09 RX 1 - FishTank 1 - Water temperature C_SET NO V_TEMP 25.9 701 2016-10-16 11:41:09 RX 1 - FishTank 2 - Water valve C_SET YES V_LIGHT 0
-
@raptorjr Can you post the complete sketch in order to find the cause?
-
Sure.
// Enable serial gateway //#define MY_GATEWAY_SERIAL // Enable debug prints to serial monitor //#define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_NRF24 #include <SPI.h> #include <MySensors.h> #include <OneWire.h> #include <DallasTemperature.h> #define TEMP_ID 1 #define RELAY_ID 2 #define WATERFLOW_ID 3 //Temperatur sensor #define ONE_WIRE_BUS 4 #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No float lastTemperature = 0; MyMessage tempMsg(TEMP_ID, V_TEMP); // Initialize temperature message OneWire oneWire(ONE_WIRE_BUS); // Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs) DallasTemperature sensors(&oneWire); // Pass our oneWire reference to Dallas Temperature. unsigned long SLEEP_TIME = 5000; // Sleep time between reads (in milliseconds) //Relay to water valve #define RELAY_PIN 5 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) #define RELAY_ON 1 // GPIO value to write to turn on attached relay #define RELAY_OFF 0 // GPIO value to write to turn off attached relay //Waterflow meter #define WATERFLOW_PIN 3 #define WATERFLOW_INTERRUPT WATERFLOW_PIN - 2 // The hall-effect flow sensor outputs approximately 4.5 pulses per second per // litre/minute of flow. float calibrationFactor = 4.5; volatile unsigned long pulseCounter = 0; float flowRate = 0; float flowLitres = 0; float totalLitres = 0; unsigned long oldTime = 0; MyMessage flowMsg(WATERFLOW_ID, V_FLOW); MyMessage volumeMsg(WATERFLOW_ID, V_VOLUME); void setup(void) { // start serial port Serial.begin(115200); pinMode(RELAY_PIN, OUTPUT); digitalWrite(RELAY_PIN, RELAY_OFF); pinMode(WATERFLOW_PIN, INPUT); digitalWrite(WATERFLOW_PIN, HIGH); // The Hall-effect sensor is connected to pin 2 which uses interrupt 0. // Configured to trigger on a FALLING state change (transition from HIGH // state to LOW state) attachInterrupt(WATERFLOW_INTERRUPT, onPulse, FALLING); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("FishTank", "1.0"); present(TEMP_ID, S_TEMP, "Water temperature"); present(RELAY_ID, S_BINARY, "Water valve"); present(WATERFLOW_ID, S_WATER, "Water flow"); send(volumeMsg.set(totalLitres, 2)); } void loop(void) { DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device address // For testing purposes, reset the bus every loop so we can see if any devices appear or fall off sensors.begin(); sensors.requestTemperatures(); // Send the command to get temperatures // Search the wire for address if(sensors.getAddress(tempDeviceAddress, 0)) { float tempC = round(sensors.getTempC(tempDeviceAddress) * 10) / 10.0; Serial.print("Temperature="); Serial.print(tempC); Serial.print(", LastTemp="); Serial.println(lastTemperature); #if COMPARE_TEMP == 1 // Only send data if temperature has changed and no error if (lastTemperature != tempC && tempC != -127.00 && tempC != 85.00) { #else if (tempC != -127.00 && tempC != 85.00) { #endif // Send in the new temperature send(tempMsg.set(tempC, 1)); // Save new temperatures for next compare lastTemperature = tempC; } } if ((millis() - oldTime) > 1000) // Only process counters once per second { // Disable the interrupt while calculating flow rate and sending the value to // the host detachInterrupt(WATERFLOW_INTERRUPT); // Because this loop may not complete in exactly 1 second intervals we calculate // the number of milliseconds that have passed since the last execution and use // that to scale the output. We also apply the calibrationFactor to scale the output // based on the number of pulses per second per units of measure (litres/minute in // this case) coming from the sensor. flowRate = ((1000.0 / (millis() - oldTime)) * pulseCounter) / calibrationFactor; if(flowRate > 0) send(flowMsg.set(flowRate, 2)); // Note the time this processing pass was executed. Note that because we've // disabled interrupts the millis() function won't actually be incrementing right // at this point, but it will still return the value it was set to just before // interrupts went away. oldTime = millis(); // Divide the flow rate in litres/minute by 60 to determine how many litres have // passed through the sensor in this 1 second interval, then multiply by 1000 to // convert to millilitres. flowLitres = (flowRate / 60); // Add the millilitres passed in this second to the cumulative total totalLitres += flowLitres; if(totalLitres > 0) send(volumeMsg.set(totalLitres, 2)); unsigned int frac; // Print the flow rate for this second in litres / minute Serial.print("Flow rate: "); Serial.print(int(flowRate)); // Print the integer part of the variable Serial.print("."); // Print the decimal point // Determine the fractional part. The 10 multiplier gives us 1 decimal place. frac = (flowRate - int(flowRate)) * 10; Serial.print(frac, DEC); // Print the fractional part of the variable Serial.print("L/min"); // Print the number of litres flowed in this second //Serial.print(" Current Liquid Flowing: "); // Output separator //Serial.print(flowLitres); //Serial.print("L/Sec"); // Print the cumulative total of litres flowed since starting Serial.print(" Output Liquid Quantity: "); // Output separator Serial.print(totalLitres); Serial.println("L"); // Reset the pulse counter so we can start incrementing again pulseCounter = 0; // Enable the interrupt again now that we've finished sending output attachInterrupt(WATERFLOW_INTERRUPT, onPulse, FALLING); } wait(SLEEP_TIME); } void receive(const MyMessage &message) { // We only expect one type of message from controller. But we better check anyway. if (message.type == V_STATUS && message.sensor == RELAY_ID) { // Change relay state digitalWrite(RELAY_PIN, message.getBool() ? RELAY_ON : RELAY_OFF); // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); if (message.getBool() == RELAY_ON) //Reset the total litres, so we can start fresh when we open the valve { totalLitres = 0; send(volumeMsg.set(totalLitres, 2)); } } } void onPulse() { // Increment the pulse counter pulseCounter++; }
-
@raptorjr I cannot find the cause What does the serial output of the node tell you?
-
It is kind of the same thing. Every time I report a temperature, the receive function get triggered. And when temperature is not changed and reported, no message about the relay.
Temperature=25.10, LastTemp=25.10
Flow rate: 0.0L/min Output Liquid Quantity: 0.03L
Temperature=25.20, LastTemp=25.10
Flow rate: 0.0L/min Output Liquid Quantity: 0.03L
Incoming change for sensor:2, New status: 0
Temperature=25.10, LastTemp=25.20
Flow rate: 0.0L/min Output Liquid Quantity: 0.03L
Incoming change for sensor:2, New status: 0
Incoming change for sensor:2, New status: 0
Temperature=25.10, LastTemp=25.10
Flow rate: 0.0L/min Output Liquid Quantity: 0.03L
Temperature=25.10, LastTemp=25.10
Flow rate: 0.0L/min Output Liquid Quantity: 0.03L
Temperature=25.10, LastTemp=25.10
-
@raptorjr can you switch debug on?
#define MY_DEBUG
. It could be possible that the controller sends an Ack..
-
There is something about ACK that I did see in the MYSController. Every relay message has ACK = YES. Can that be a problem, and what can I do about it?
-
@raptorjr It is good practice to use "ACK" when actuating a switch. That way you the controller can check if the message arrived (if the action took place). To debug you should look at the debug log to see what kind of message's are actually sent and received.
-
This is what I get with debug turned on:
Temperature=25.10, LastTemp=25.10 Flow rate: 0.0L/min Output Liquid Quantity: 0.00L Temperature=25.00, LastTemp=25.10 TSF:MSG:SEND,1-1-0-0,s=1,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=OK:25.0 Flow rate: 0.0L/min Output Liquid Quantity: 0.00L TSF:MSG:READ,0-0-1,s=2,c=1,t=2,pt=0,l=1,sg=0:0 TSF:MSG:ACK REQ TSF:MSG:SEND,1-1-0-0,s=2,c=1,t=2,pt=0,l=1,sg=0,ft=0,st=OK:0 Incoming change for sensor:2, New status: 0 Temperature=25.10, LastTemp=25.00 !TSF:MSG:SEND,1-1-0-0,s=1,c=1,t=0,pt=7,l=5,sg=0,ft=0,st=NACK:25.1 Flow rate: 0.0L/min Output Liquid Quantity: 0.00L Temperature=25.10, LastTemp=25.10 Flow rate: 0.0L/min Output Liquid Quantity: 0.00L