Serial Gateway Sketch with si7021
-
Hi All,
I have biuld a Serial Gateway based on RFM69 and a ProMini. Its working great so far. But I want to implement in this Sketch also a Sensor si7021. I have currently no idea how i can implent the sensor part into the Gateway Sketch. Hope someone can help me there.Thanks
Markus
-
Just add the code of a node in presentation, setup and loop, nothing fancy
-
Well the Problem seems to be in the first step to get a working SI7021 Sketch for MySensors 2.2.0 Beta or 2.1.1.
I did Try to complie this one now:/* Sketch with Si7021 and battery monitoring. by m26872, 20151109 */ #define MY_DEBUG #define MY_RADIO_NRF24 #define MY_NODE_ID 5 // <<<<<<<<<<<<<<<<<<<<<<<<<<< Enter Node_ID #define MY_BAUD_RATE 115200 #include <MySensors.h> #include <Wire.h> #include <SI7021.h> #include <SPI.h> #include <RunningAverage.h> //#define DEBUG #ifdef DEBUG #define DEBUG_SERIAL(x) Serial.begin(x) #define DEBUG_PRINT(x) Serial.print(x) #define DEBUG_PRINTLN(x) Serial.println(x) #else #define DEBUG_SERIAL(x) #define DEBUG_PRINT(x) #define DEBUG_PRINTLN(x) #endif #define CHILD_ID_TEMP 0 #define CHILD_ID_HUM 1 // #define SLEEP_TIME 15000 // 15s for DEBUG #define SLEEP_TIME 300000 // 5 min #define FORCE_TRANSMIT_CYCLE 36 // 5min*12=1/hour, 5min*36=1/3hour #define BATTERY_REPORT_CYCLE 2880 // Once per 5min => 12*24*7 = 2016 (one report/week) #define VMIN 1900 #define VMAX 3300 #define HUMI_TRANSMIT_THRESHOLD 3.0 // THRESHOLD tells how much the value should have changed since last time it was transmitted. #define TEMP_TRANSMIT_THRESHOLD 0.5 #define AVERAGES 2 int batteryReportCounter = BATTERY_REPORT_CYCLE - 1; // to make it report the first time. int measureCount = 0; float lastTemperature = -100; int lastHumidity = -100; RunningAverage raHum(AVERAGES); SI7021 humiditySensor; MyMessage msgTemp(CHILD_ID_TEMP,V_TEMP); // Initialize temperature message MyMessage msgHum(CHILD_ID_HUM,V_HUM); void presentation() { sendSketchInfo("EgTmpHumBat5min", "1.0 151106"); present(CHILD_ID_TEMP, S_TEMP); // Present sensor to controller present(CHILD_ID_HUM, S_HUM); } void setup() { DEBUG_SERIAL(115200); // <<<<<<<<<<<<<<<<<<<<<<<<<< Note BAUD_RATE in MySensors.h DEBUG_PRINTLN("Serial started"); DEBUG_PRINT("Voltage: "); DEBUG_PRINT(readVcc()); DEBUG_PRINTLN(" mV"); /* delay(500); DEBUG_PRINT("Internal temp: "); DEBUG_PRINT(GetInternalTemp()); // Probably not calibrated. Just to print something. DEBUG_PRINTLN(" *C"); */ delay(500); // Allow time for radio if power useed as reset DEBUG_PRINT("Node and "); DEBUG_PRINTLN("2 children presented."); raHum.clear(); } void loop() { measureCount ++; batteryReportCounter ++; bool forceTransmit = false; if (measureCount > FORCE_TRANSMIT_CYCLE) { forceTransmit = true; } sendTempHumidityMeasurements(forceTransmit); /* // Read and print internal temp float temperature0 = static_cast<float>(static_cast<int>((GetInternalTemp()+0.5) * 10.)) / 10.; DEBUG_PRINT("Internal Temp: "); DEBUG_PRINT(temperature0); DEBUG_PRINTLN(" *C"); */ // Check battery if (batteryReportCounter >= BATTERY_REPORT_CYCLE) { long batteryVolt = readVcc(); DEBUG_PRINT("Battery voltage: "); DEBUG_PRINT(batteryVolt); DEBUG_PRINTLN(" mV"); uint8_t batteryPcnt = constrain(map(batteryVolt,VMIN,VMAX,0,100),0,255); DEBUG_PRINT("Battery percent: "); DEBUG_PRINT(batteryPcnt); DEBUG_PRINTLN(" %"); sendBatteryLevel(batteryPcnt); batteryReportCounter = 0; } sleep(SLEEP_TIME); } // function for reading Vcc by reading 1.1V reference against AVcc. Based from http://provideyourown.com/2012/secret-arduino-voltmeter-measure-battery-voltage/ // To calibrate reading replace 1125300L with scale_constant = internal1.1Ref * 1023 * 1000, where internal1.1Ref = 1.1 * Vcc1 (per voltmeter) / Vcc2 (per readVcc() function) long readVcc() { // set the reference to Vcc and the measurement to the internal 1.1V reference ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); delay(2); // Wait for Vref to settle ADCSRA |= _BV(ADSC); // Start conversion while (bit_is_set(ADCSRA,ADSC)); // measuring uint8_t low = ADCL; // must read ADCL first - it then locks ADCH uint8_t high = ADCH; // unlocks both long result = (high<<8) | low; result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000 return result; // Vcc in millivolts } // function for reading internal temp. From http://playground.arduino.cc/Main/InternalTemperatureSensor double GetInternalTemp(void) { // (Both double and float are 4 byte in most arduino implementation) unsigned int wADC; double t; // The internal temperature has to be used with the internal reference of 1.1V. Channel 8 can not be selected with the analogRead function yet. ADMUX = (_BV(REFS1) | _BV(REFS0) | _BV(MUX3)); // Set the internal reference and mux. ADCSRA |= _BV(ADEN); // enable the ADC delay(20); // wait for voltages to become stable. ADCSRA |= _BV(ADSC); // Start the ADC while (bit_is_set(ADCSRA,ADSC)); // Detect end-of-conversion wADC = ADCW; // Reading register "ADCW" takes care of how to read ADCL and ADCH. t = (wADC - 88.0 ) / 1.0; // The default offset is 324.31. return (t); // The returned temperature in degrees Celcius. } /********************************************* * * Sends temperature and humidity from Si7021 sensor * Parameters * - force : Forces transmission of a value (even if it's the same as previous measurement) *********************************************/ void sendTempHumidityMeasurements(bool force) { bool tx = force; si7021_env data = humiditySensor.getHumidityAndTemperature(); float temperature = data.celsiusHundredths / 100.0; DEBUG_PRINT("T: ");DEBUG_PRINTLN(temperature); float diffTemp = abs(lastTemperature - temperature); DEBUG_PRINT(F("TempDiff :"));DEBUG_PRINTLN(diffTemp); if (diffTemp > TEMP_TRANSMIT_THRESHOLD || tx) { send(msgTemp.set(temperature,1)); lastTemperature = temperature; measureCount = 0; DEBUG_PRINTLN("T sent!"); } int humidity = data.humidityPercent; DEBUG_PRINT("H: ");DEBUG_PRINTLN(humidity); raHum.addValue(humidity); humidity = raHum.getAverage(); // MA sample imply reasonable fast sample frequency float diffHum = abs(lastHumidity - humidity); DEBUG_PRINT(F("HumDiff :"));DEBUG_PRINTLN(diffHum); if (diffHum > HUMI_TRANSMIT_THRESHOLD || tx) { send(msgHum.set(humidity)); lastHumidity = humidity; measureCount = 0; DEBUG_PRINTLN("H sent!"); } }
But I get always follwoing error...
exit status 1 'si7021_env' has no member named 'humidityPercent'
So I am a bit lost at the Moment due to my limited coding Knowledge..
-
Why don't you start with a much simpler sketch? And that is for a node, it is missing all the defines for the gateway. Start with the gateway sketch and add only the code needed by the sensor. The error you get is probably a mismatch between the code and the library: check in the library examples how do you retrive humidity from the sensor
-
Did a mistake with the Libary. Used now the SI7021 from MySensorsArduinoExamples-master and this seems to be okay now
-
the Problem is I cnnaot find any simple Mysensors Sketch to read a SI7021
Only with battery Monitoring which I don't Need...
-
can it work like this?
// Enable debug prints to serial monitor #define MY_DEBUG // Enable and select radio type attached #define MY_RADIO_RFM69 #define MY_RFM69_FREQUENCY RFM69_868MHZ #include <Wire.h> #include <SI7021.h> #include <SPI.h> #include <RunningAverage.h> #ifdef MY_DEBUG #define DEBUG_SERIAL(x) Serial.begin(x) #define DEBUG_PRINT(x) Serial.print(x) #define DEBUG_PRINTLN(x) Serial.println(x) #else #define DEBUG_SERIAL(x) #define DEBUG_PRINT(x) #define DEBUG_PRINTLN(x) #endif #define CHILD_ID_TEMP 0 #define CHILD_ID_HUM 1 // #define SLEEP_TIME 15000 // 15s for DEBUG #define SLEEP_TIME 300000 // 5 min #define FORCE_TRANSMIT_CYCLE 36 // 5min*12=1/hour, 5min*36=1/3hour #define HUMI_TRANSMIT_THRESHOLD 3.0 // THRESHOLD tells how much the value should have changed since last time it was transmitted. #define TEMP_TRANSMIT_THRESHOLD 0.5 #define AVERAGES 2 int measureCount = 0; float lastTemperature = -100; int lastHumidity = -100; RunningAverage raHum(AVERAGES); SI7021 humiditySensor; // Enable serial gateway #define MY_GATEWAY_SERIAL // Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender) #if F_CPU == 8000000L #define MY_BAUD_RATE 38400 #endif // Enable inclusion mode #define MY_INCLUSION_MODE_FEATURE // Set inclusion mode duration (in seconds) #define MY_INCLUSION_MODE_DURATION 60 // Set blinking period #define MY_DEFAULT_LED_BLINK_PERIOD 300 // Inverses the behavior of leds //#define MY_WITH_LEDS_BLINKING_INVERSE // Flash leds on rx/tx/err // Uncomment to override default HW configurations //#define MY_DEFAULT_ERR_LED_PIN 4 // Error led pin //#define MY_DEFAULT_RX_LED_PIN 6 // Receive led pin //#define MY_DEFAULT_TX_LED_PIN 5 // the PCB, on board LED #include <MySensors.h> MyMessage msgTemp(CHILD_ID_TEMP,V_TEMP); // Initialize temperature message MyMessage msgHum(CHILD_ID_HUM,V_HUM); void setup() { DEBUG_SERIAL(38400); // <<<<<<<<<<<<<<<<<<<<<<<<<< Note BAUD_RATE in MySensors.h DEBUG_PRINTLN("Serial started"); delay(500); // Allow time for radio if power useed as reset DEBUG_PRINT("Node and "); DEBUG_PRINTLN("2 children presented."); raHum.clear(); } void presentation() { sendSketchInfo("Gateway_SI7021", "1.0 161017"); present(CHILD_ID_TEMP, S_TEMP); // Present sensor to controller present(CHILD_ID_HUM, S_HUM); } void loop() { measureCount ++; bool forceTransmit = false; if (measureCount > FORCE_TRANSMIT_CYCLE) { forceTransmit = true; } sendTempHumidityMeasurements(forceTransmit); /* // Read and print internal temp float temperature0 = static_cast<float>(static_cast<int>((GetInternalTemp()+0.5) * 10.)) / 10.; DEBUG_PRINT("Internal Temp: "); DEBUG_PRINT(temperature0); DEBUG_PRINTLN(" *C"); */ sleep(SLEEP_TIME); } /********************************************* * * Sends temperature and humidity from Si7021 sensor * Parameters * - force : Forces transmission of a value (even if it's the same as previous measurement) *********************************************/ void sendTempHumidityMeasurements(bool force) { bool tx = force; si7021_env data = humiditySensor.getHumidityAndTemperature(); float temperature = data.celsiusHundredths / 100.0; DEBUG_PRINT("T: ");DEBUG_PRINTLN(temperature); float diffTemp = abs(lastTemperature - temperature); DEBUG_PRINT(F("TempDiff :"));DEBUG_PRINTLN(diffTemp); if (diffTemp > TEMP_TRANSMIT_THRESHOLD || tx) { send(msgTemp.set(temperature,1)); lastTemperature = temperature; measureCount = 0; DEBUG_PRINTLN("T sent!"); } int humidity = data.humidityPercent; DEBUG_PRINT("H: ");DEBUG_PRINTLN(humidity); raHum.addValue(humidity); humidity = raHum.getAverage(); // MA sample imply reasonable fast sample frequency float diffHum = abs(lastHumidity - humidity); DEBUG_PRINT(F("HumDiff :"));DEBUG_PRINTLN(diffHum); if (diffHum > HUMI_TRANSMIT_THRESHOLD || tx) { send(msgHum.set(humidity)); lastHumidity = humidity; measureCount = 0; DEBUG_PRINTLN("H sent!"); } }
-
Did you try it?
-
not yet Will try it later....
-
tried now the Sketch... Seems that something is wrong with the sensor.
__ __ ____ | \/ |_ _/ ___| ___ _ __ ___ ___ _ __ ___ | |\/| | | | \___ \ / _ \ `_ \/ __|/ _ \| `__/ __| | | | | |_| |___| | __/ | | \__ \ _ | | \__ \ |_| |_|\__, |____/ \___|_| |_|___/\___/|_| |___/ |___/ 2.2.0-beta 0;255;3;0;9;53 MCO:BGN:INIT GW,CP=RRNGA---,VER=2.2.0-beta 0;255;3;0;9;83 TSM:INIT 0;255;3;0;9;92 TSF:WUR:MS=0 0;255;3;0;9;100 TSM:INIT:TSP OK 0;255;3;0;9;108 TSM:INIT:GW MODE 0;255;3;0;9;118 TSM:READY:ID=0,PAR=0,DIS=0 0;255;3;0;9;129 MCO:REG:NOT NEEDED 0;255;3;0;14;Gateway startup complete. 0;255;0;0;18;2.2.0-beta 0;255;3;0;11;Gateway_SI7021 0;255;3;0;12;1.0 161017 0;0;0;0;6; 0;1;0;0;7; 0;255;3;0;9;159 MCO:BGN:STP Serial started Node and 2 children presented. 0;255;3;0;9;684 MCO:BGN:INIT OK,TSP=1
Also the issue with the attached sensor blocks completly the Gateway function.Means that the Gateway didn't receive anything. Is it possible to prevent such issue? what I mean, is it possible to seperate both functions in the Sketch in that way If something is wrong with the sensor, the Gateway can still operate?
THX
Markus
-
add some more serial prints around to see where the code stops
-
@gohan how can i do this ?
-
Look at the "DEBUG_PRINTLN" you have in your code, add some of those where you see there aren't.
-
the Code stops here
si7021_env data = humiditySensor.getHumidityAndTemperature();
Anything wrong with the sensor I guess. But how can I handle such things?
-
did you try an example sketch from the library to see if you can read the values correctly?
-
the sensor conenction was the Problem at the end. Changed SCD and SCL and now it Looks good so far. At the Moment is the Gateway not connected to a Controller. Hope the sensor will be then also send the values...
__ __ ____ | \/ |_ _/ ___| ___ _ __ ___ ___ _ __ ___ | |\/| | | | \___ \ / _ \ `_ \/ __|/ _ \| `__/ __| | | | | |_| |___| | __/ | | \__ \ _ | | \__ \ |_| |_|\__, |____/ \___|_| |_|___/\___/|_| |___/ |___/ 2.2.0-beta 0;255;3;0;9;53 MCO:BGN:INIT GW,CP=RRNGA---,VER=2.2.0-beta 0;255;3;0;9;83 TSM:INIT 0;255;3;0;9;92 TSF:WUR:MS=0 0;255;3;0;9;100 TSM:INIT:TSP OK 0;255;3;0;9;108 TSM:INIT:GW MODE 0;255;3;0;9;118 TSM:READY:ID=0,PAR=0,DIS=0 0;255;3;0;9;129 MCO:REG:NOT NEEDED 0;255;3;0;14;Gateway startup complete. 0;255;0;0;18;2.2.0-beta 0;255;3;0;11;Gateway_SI7021 0;255;3;0;12;1.0 161017 0;0;0;0;6; 0;1;0;0;7; 0;255;3;0;9;159 MCO:BGN:STP Serial started Node and 2 children presented. 0;255;3;0;9;684 MCO:BGN:INIT OK,TSP=1 Loop1 started T: 21.49 TempDiff :121.49 0;0;1;0;0;21.5 T sent! H: 64 HumDiff :164.00 0;1;1;0;1;64 H sent! Before first sleep 0;255;3;0;9;733 MCO:SLP:MS=300000,SMS=0,I1=255,M1=255,I2=255,M2=255 0;255;3;0;9;768 !MCO:SLP:REP 0;255;3;0;9;124672 TSF:MSG:READ,106-106-0,s=0,c=1,t=1,pt=7,l=5,sg=0:63.3 106;0;1;0;1;63.3 0;255;3;0;9;124702 TSF:MSG:READ,106-106-0,s=255,c=3,t=0,pt=1,l=1,sg=0:90 106;255;3;0;0;90 0;255;3;0;9;124735 TSF:MSG:READ,106-106-0,s=3,c=1,t=38,pt=7,l=5,sg=0:3.71 106;3;1;0;38;3.71 After first sleep Loop1 started T: 21.64 TempDiff :0.15 H: 65 HumDiff :0.00 Before first sleep 0;255;3;0;9;300797 MCO:SLP:MS=300000,SMS=0,I1=255,M1=255,I2=255,M2=255 0;255;3;0;9;300830 !MCO:SLP:REP 0;255;3;0;9;428443 TSF:MSG:READ,106-106-0,s=255,c=3,t=0,pt=1,l=1,sg=0:90 106;255;3;0;0;90 0;255;3;0;9;428476 TSF:MSG:READ,106-106-0,s=3,c=1,t=38,pt=7,l=5,sg=0:3.72 106;3;1;0;38;3.72
But how can I prevent the Situation that a defect or missing sensor on the Gateway blocks also the Gateway function ?
Thanks
Markus
-
You need to make a check in the code that if the sensor read is fails it should keep going
-
@gohan will try it.... -> Learning leasson...