Multiple Sensors on Gateway
-
Hello,
I Want to use multiple sensors (motion sensor, temperature, rain sensor etc) on one Arduino MEGA.For the moment I use a module with 4 relays, 2 Dallas temperature sensors, 1 motion sensor(I would like to change the sketch to use multiple motion sensor as the temperature example) and the problem is that I have to prioritize the sensors, for example I need update for the temperature sensors every 20-30 seconds but the motion sensor should update instantly.
Here is my code based on the MySensors examples.
// Debug #define MY_DEBUG // Partea cu Conexiunea la net #define MY_GATEWAY_ENC28J60 #define MY_IP_ADDRESS 192,168,1,66 #define MY_PORT 5003 #define MY_MAC_ADDRESS 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED #include <UIPEthernet.h> // Sfarsit parte #include <SPI.h> #include <MySensors.h> #include <DallasTemperature.h> #include <OneWire.h> //==TEMP== #define COMPARE_TEMP 1 // Send temperature only if changed? 1 = Yes 0 = No #define ONE_WIRE_BUS 2 // Pin where dallase sensor is connected unsigned long SLEEP_TIME = 20000; // Sleep time between reads (in milliseconds) #define MAX_ATTACHED_DS18B20 1 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 the oneWire reference to Dallas Temperature. float lastTemperature[MAX_ATTACHED_DS18B20]; int numSensors=0; bool receivedConfig = false; bool metric = true; // Initialize temperature message MyMessage msgtemp(0,V_TEMP); //==TEMP== //==RELAY== #define RELAY_1 8 // Arduino Digital I/O pin number for first relay (second on pin+1 etc) #define NUMBER_OF_RELAYS 4 // Total number of attached relays #define RELAY_ON 0 // GPIO value to write to turn on attached relay #define RELAY_OFF 1 // GPIO value to write to turn off attached relay //==RELAY== //==MOTION== #define DIGITAL_INPUT_SENSOR 3 // The digital input you attached your motion sensor. (Only 2 and 3 generates interrupt!) #define CHILD_ID_MISCARE 15 // Id of the sensor child unsigned long SEND_FREQUENCY = 10; // Minimum time between send (in seconds). We don't want to spam the gateway. long lastDebounce = 0; long debounceDelay = 500; unsigned long lastSend; unsigned long currentTime; unsigned int isTripped =0; // Initialize motion message MyMessage msgmiscare(CHILD_ID_MISCARE, V_TRIPPED); void before() { // Startup up the OneWire library sensors.begin(); for (int sensor=1, pin=RELAY_1; 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 setup() { // requestTemperatures() will not block current thread sensors.setWaitForConversion(false); pinMode(DIGITAL_INPUT_SENSOR, INPUT); // sets the motion sensor digital pin as input lastSend = -1; } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo("Arduino SmartHub", "1.1"); present(CHILD_ID_MISCARE, S_MOTION); for (int sensor=1, pin=RELAY_1; sensor<=NUMBER_OF_RELAYS; sensor++, pin++) { // Register all sensors to gw (they will be created as child devices) present(sensor, S_BINARY); } // Fetch the number of attached temperature sensors numSensors = sensors.getDeviceCount(); // Present all sensors to controller for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { present(i, S_TEMP); } } void loop() { //==MOTION== currentTime = millis(); // Read digital motion value boolean tripped = digitalRead(DIGITAL_INPUT_SENSOR) == HIGH; Serial.println(tripped); Serial.println(currentTime-lastSend); if ((isTripped==0) &&(tripped==1)) { Serial.println("tripped"); send(msgmiscare.set(tripped?"1":"0")); // Send tripped value to gw lastSend=currentTime; isTripped=1; } if ((tripped==0) && (isTripped==1) && (currentTime - lastSend > 1000*SEND_FREQUENCY)){ Serial.println("un-tripped"); send(msgmiscare.set(tripped?"1":"0")); // Send tripped value to gw lastSend=currentTime; isTripped=0; } // Fetch temperatures from Dallas sensors sensors.requestTemperatures(); // query conversion time and sleep until conversion completed int16_t conversionTime = sensors.millisToWaitForConversion(sensors.getResolution()); // sleep() call can be replaced by wait() call if node need to process incoming messages (or if node is repeater) //wait(conversionTime); // Read temperatures and send them to controller for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { // Fetch and round temperature to one decimal float temperature = static_cast<float>(static_cast<int>((getControllerConfig().isMetric?sensors.getTempCByIndex(i):sensors.getTempFByIndex(i)) * 10.)) / 10.; // Only send data if temperature has changed and no error #if COMPARE_TEMP == 1 if (lastTemperature[i] != temperature && temperature != -127.00 && temperature != 85.00) { #else if (temperature != -127.00 && temperature != 85.00) { #endif // Send in the new temperature send(msgtemp.setSensor(i).set(temperature,1)); // Save new temperatures for next compare lastTemperature[i]=temperature; } } wait(SLEEP_TIME); } void receive(const MyMessage &message) //Loop for receiving messages { // We only expect one type of message from controller. But we better check anyway. if (message.type==V_STATUS) { // Change relay state digitalWrite(message.sensor-1+RELAY_1, message.getBool()?RELAY_ON:RELAY_OFF); // Store state in eeprom saveState(message.sensor, message.getBool()); // Write some debug info Serial.print("Incoming change for sensor:"); Serial.print(message.sensor); Serial.print(", New status: "); Serial.println(message.getBool()); } }
-
How about using interrupts? You connect the pir sensors on the pins supporting interrupts.
-
Thank you for your reply!
The motion sensor part from the sketch works perfectly, the problem is with the temperature part.If I am using wait or sleep for temperature, arduino won't listen the motion sensor until the time elapses.
If I am commenting the wait the sensor will spam the controller until the controller stop receiving data from arduino.
-
That's my point, use interrupts that will "wake" the Arduino when pin changes status and process the pir signal
-
@gohan I understand what you are saying but if I am doing in that way I will spam the controller with the interrupts(flaps) right now it works like this
if pin=0 send the state of the pin(the next update is when pin state changes), if pin=1 send the state and wait for 10 seconds for the next update.For the moment I have found a solution with millis[if(time%frequency==0)]:
time=millis()/1000; if(time%10 ==0)
Any suggestion for improving this part?