having trouble with water flow sensor + relay + moisture
-
Hi, I've build my own node with mqtt to send waterflow sensor and DHT22 and moisture data to Domoticz and have one Relay to control. but both relay and waterflow sketches has receive function and when I write both of them in one function, relay doesn't show up in domoticz devices or hardware(child node);
here is my code:#include <DHT.h> #include <SPI.h> #define DHT_DATA_PIN 6 #define SENSOR_TEMP_OFFSET 0 static const uint8_t FORCE_UPDATE_N_READS = 10; static const uint64_t UPDATE_INTERVAL = 5000; #define MY_RADIO_NRF24 #define MY_RF24_PA_LEVEL RF24_PA_MAX #define MY_REPEATER_FEATURE #define MY_NODE_ID 1 #include <MySensors.h> #define RELAY_PIN 4 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) #define NUMBER_OF_RELAYS 1 // Total number of attached relays #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 #define CHILD_ID_MOISTURE 2 #define CHILD_ID_HUM 3 #define CHILD_ID_TEMP 4 float lastTemp; float lastHum; uint8_t nNoUpdatesTemp; uint8_t nNoUpdatesHum; bool metric = true; MyMessage msgMoisture(CHILD_ID_MOISTURE, V_HUM); MyMessage msgHum(CHILD_ID_HUM, V_HUM); MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP); DHT dht; static int sensorValue; int soilPin = A0; int soilPower = 5; #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your sensor. (Only 2 and 3 generates interrupt!) #define PULSE_FACTOR 450000 // Nummber of blinks per m3 of your meter (One rotation/liter) #define SLEEP_MODE false // flowvalue can only be reported when sleep mode is false. #define MAX_FLOW 30 // Max flow (l/min) value to report. This filters outliers. #define CHILD_ID_WATER 1 uint32_t SEND_FREQUENCY = 5000; // Minimum time between send (in milliseconds). We don't want to spam the gateway. MyMessage flowMsg(CHILD_ID_WATER,V_FLOW); MyMessage volumeMsg(CHILD_ID_WATER,V_VOLUME); MyMessage lastCounterMsg(CHILD_ID_WATER,V_VAR1); double ppl = ((double)PULSE_FACTOR)/1000; // Pulses per liter volatile uint32_t pulseCount = 0; volatile uint32_t lastBlink = 0; volatile double flow = 0; bool pcReceived = false; uint32_t oldPulseCount = 0; uint32_t newBlink = 0; double oldflow = 0; double volume =0; double oldvolume =0; uint32_t lastSend =0; uint32_t lastPulse =0; void before() { for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) { // Then set relay pins in output mode pinMode(pin, OUTPUT); // Set relay to last known state (using eeprom storage) digitalWrite(pin, loadState(sensor)?RELAY_ON:RELAY_OFF); } } void presentation() { sendSketchInfo("Smart Irrigation System", "1.0"); present(CHILD_ID_MOISTURE, S_MOISTURE); present(CHILD_ID_WATER, S_WATER); present(CHILD_ID_HUM, S_HUM); present(CHILD_ID_TEMP, S_TEMP); metric = getControllerConfig().isMetric; for (int sensor=1, pin=RELAY_PIN; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) { present(sensor, S_BINARY); } } void setup() { pinMode(soilPower, OUTPUT);//Set D6 as an OUTPUT // initialize our digital pins internal pullup resistor so one pulse switches from high to low (less distortion) pinMode(DIGITAL_INPUT_SENSOR, INPUT_PULLUP); pulseCount = oldPulseCount = 0; // Fetch last known pulse count value from gw request(CHILD_ID_WATER, V_VAR1); lastSend = lastPulse = millis(); attachInterrupt(digitalPinToInterrupt(DIGITAL_INPUT_SENSOR), onPulse, FALLING); dht.setup(DHT_DATA_PIN); // set data pin of DHT sensor if (UPDATE_INTERVAL <= dht.getMinimumSamplingPeriod()) { Serial.println("Warning: UPDATE_INTERVAL is smaller than supported by the sensor!"); } // Sleep for the time of the minimum sampling period to give the sensor time to power up // (otherwise, timeout errors might occure for the first reading) sleep(dht.getMinimumSamplingPeriod()); } void loop() { // Force reading sensor, so it works also after sleep() dht.readSensor(true); // Get temperature from DHT library float temperature = dht.getTemperature(); if (isnan(temperature)) { Serial.println("Failed reading temperature from DHT!"); } else if (temperature != lastTemp || nNoUpdatesTemp == FORCE_UPDATE_N_READS) { // Only send temperature if it changed since the last measurement or if we didn't send an update for n times lastTemp = temperature; if (!metric) { temperature = dht.toFahrenheit(temperature); } // Reset no updates counter nNoUpdatesTemp = 0; temperature += SENSOR_TEMP_OFFSET; send(msgTemp.set(temperature, 1)); #ifdef MY_DEBUG Serial.print("T: "); Serial.println(temperature); #endif } else { // Increase no update counter if the temperature stayed the same nNoUpdatesTemp++; } // Get humidity from DHT library float humidity = dht.getHumidity(); if (isnan(humidity)) { Serial.println("Failed reading humidity from DHT"); } else if (humidity != lastHum || nNoUpdatesHum == FORCE_UPDATE_N_READS) { // Only send humidity if it changed since the last measurement or if we didn't send an update for n times lastHum = humidity; // Reset no updates counter nNoUpdatesHum = 0; send(msgHum.set(humidity, 1)); #ifdef MY_DEBUG Serial.print("H: "); Serial.println(humidity); #endif } else { // Increase no update counter if the humidity stayed the same nNoUpdatesHum++; } // Sleep for a while to save energy sleep(UPDATE_INTERVAL); //...................................................... uint32_t currentTime = millis(); // Only send values at a maximum frequency or woken up from sleep if (SLEEP_MODE || (currentTime - lastSend > SEND_FREQUENCY)) { lastSend=currentTime; if (!pcReceived) { //Last Pulsecount not yet received from controller, request it again request(CHILD_ID_WATER, V_VAR1); return; } if (!SLEEP_MODE && flow != oldflow) { oldflow = flow; Serial.print("l/min:"); Serial.println(flow); // Check that we dont get unresonable large flow value. // could hapen when long wraps or false interrupt triggered if (flow<((uint32_t)MAX_FLOW)) { send(flowMsg.set(flow, 2)); // Send flow value to gw } } // No Pulse count received in 2min if(currentTime - lastPulse > 120000) { flow = 0; } // Pulse count has changed if ((pulseCount != oldPulseCount)||(!SLEEP_MODE)) { oldPulseCount = pulseCount; Serial.print("pulsecount:"); Serial.println(pulseCount); send(lastCounterMsg.set(pulseCount)); // Send pulsecount value to gw in VAR1 double volume = ((double)pulseCount/((double)PULSE_FACTOR)); if ((volume != oldvolume)||(!SLEEP_MODE)) { oldvolume = volume; Serial.print("volume:"); Serial.println(volume, 3); send(volumeMsg.set(volume, 3)); // Send volume value to gw } } } if (SLEEP_MODE) { sleep(SEND_FREQUENCY); } soilmoisture(); } void soilmoisture() { digitalWrite(soilPower, HIGH); delay(10);//wait 10 milliseconds sensorValue = analogRead(soilPin); digitalWrite(soilPower, LOW); sensorValue = map(sensorValue, 0, 680, 0, 100); send(msgMoisture.set(sensorValue)); sleep(SEND_FREQUENCY); } void receive(const MyMessage &message) { if (message.type==V_VAR1) { uint32_t gwPulseCount=message.getULong(); pulseCount += gwPulseCount; flow=oldflow=0; Serial.print("Received last pulse count from gw:"); Serial.println(pulseCount); pcReceived = true; } if (message.type==V_STATUS) { // Change relay state digitalWrite(message.sensor-1+RELAY_PIN, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(message.sensor, message.getBool()); } } void onPulse() { if (!SLEEP_MODE) { uint32_t newBlink = micros(); uint32_t interval = newBlink-lastBlink; if (interval!=0) { lastPulse = millis(); if (interval<500000L) { // Sometimes we get interrupt on RISING, 500000 = 0.5sek debounce ( max 120 l/min) return; } flow = (60000000.0 /interval) / ppl; } lastBlink = newBlink; } pulseCount++; }
anyone can help me?
and any suggestion to clean up my code?
thanks in advanced.
-
@tsunami if you look at the debug output, you will probably see that the presentation presents the relay and the water sensor with the same child id.
You'll need to use a higher number for one of the IDs.
-
@mfalkvidd I've changed CHILD_ID for nodes but nothing changed and moisture data show up in DHT22's humidity!
-
@tsunami said in having trouble with water flow sensor + relay + moisture:
#define CHILD_ID_MOISTURE 2
#define CHILD_ID_HUM 3
#define CHILD_ID_TEMP 4try
#define CHILD_ID_MOISTURE 12
#define CHILD_ID_HUM 13
#define CHILD_ID_TEMP 14Also delete node from controller if you still see the ID mixed up