How to manage dynamic number of sensors?
-
Hello
I build mqtt mysensors gateway with DS2482-100 to handle many (currently 15 DS18B20) 1wire sensors.
My idea was that the gateway will dynamically start to report each attached 1wire sensors 1wire address and value automatically without necessity to change the sketch before attaching new sensor. But from what I see I need to set MyMessage(uint8_t childSensorId, uint8_t variableType); first.
Is there some best practice pattern how to do it?
Thanks
Tomas
-
@tssk have you tried the temperature example sketch? It supports a dynamic number of sensors.
-
@mfalkvidd I did not see it - thanks for mentioning it.
I think this is what I was looking for - the sketch uses one MyMessage msg(0,V_TEMP); for values from all DS18B20 with such code construction
// Read temperatures and send them to controller for (int i=0; i<numSensors && i<MAX_ATTACHED_DS18B20; i++) { ... // Send in the new temperature send(msg.setSensor(i).set(temperature,1)); ... }
I thought I will need to set up MyMessage msg(0,V_TEMP) x number_of_sensors which would be terrible.
I guess if I extend the code with MyMessage msg(0,V_ID) to send also the 1wire address it will be what I am looking for.
Thanks!
-
@tssk I hope I've not misunderstood what you intend, but possibly a further consideration ?
I have 14 sensors defined in an array with their digital addresses.During presentation a similar "for" loop to the above ties each sensor digital address with a dedicated "i" to the Controller as in your sketch. That way the sensor location is fixed - if one goes faulty it only requires that specific address edited in the array for the replacement device and reprogram the Node.
In reality the last 2 devices in the array (Boiler) are on a separate data line to the first 12 (Spaces), but it is relatively simple to call each defined data line and address them by altering the "i" and "MAX_ATTACHED..." for each instance.
-
@zboblamont Thanks for the tip. I am trying to avoid hardcoding any addresses - maybe I find out that it will be necessary at some point. But so far it looks fine:
23:08:43.873 -> 0 MCO:BGN:INIT GW,CP=R-NGA---,FQ=8,REL=255,VER=2.3.2 23:08:44.438 -> 585 GWT:TPC:IP=192.168.1.113 23:08:45.468 -> 1589 MCO:BGN:STP 23:08:45.468 -> 1591 MCO:REG:NOT NEEDED 23:08:45.468 -> 1595 MCO:BGN:INIT OK,TSP=NA 23:08:45.468 -> 1597 GWT:TPC:IP=192.168.1.113 23:08:46.464 -> 2600 GWT:RMQ:CONNECTING... 23:08:46.464 -> 2611 GWT:RMQ:OK 23:08:46.464 -> 2613 GWT:TPS:TOPIC=1wire-out/0/255/0/0/17,MSG SENT 23:08:46.497 -> 2619 GWT:TPS:TOPIC=1wire-out/0/255/3/0/11,MSG SENT 23:08:46.497 -> 2625 GWT:TPS:TOPIC=1wire-out/0/255/3/0/12,MSG SENT 23:08:46.497 -> DBG: loop start 23:08:47.559 -> 0 : 280838211713012D 23:08:47.559 -> 3704 GWT:TPS:TOPIC=1wire-out/0/0/1/0/42,MSG SENT 23:08:47.592 -> 0 : 5A014B467FFF0C1044 : 21.62 23:08:47.626 -> 3753 GWT:TPS:TOPIC=1wire-out/0/0/1/0/0,MSG SENT 23:08:47.692 -> 1 : 28A82B7D17130189 23:08:47.692 -> 3825 GWT:TPS:TOPIC=1wire-out/0/1/1/0/42,MSG SENT 23:08:47.692 -> 1 : 53014B467FFF0C102D : 21.19 23:08:47.758 -> 3876 GWT:TPS:TOPIC=1wire-out/0/1/1/0/0,MSG SENT 23:08:47.824 -> 2 : 28949D2816130138 23:08:47.824 -> 3948 GWT:TPS:TOPIC=1wire-out/0/2/1/0/42,MSG SENT 23:08:47.824 -> 2 : 5F014B467FFF0C1012 : 21.94 23:08:47.858 -> 3999 GWT:TPS:TOPIC=1wire-out/0/2/1/0/0,MSG SENT 23:08:47.924 -> 3 : 282C3C2A16130167 23:08:47.924 -> 4071 GWT:TPS:TOPIC=1wire-out/0/3/1/0/42,MSG SENT 23:08:47.957 -> 3 : 56014B467FFF0C107B : 21.37 23:08:47.990 -> 4122 GWT:TPS:TOPIC=1wire-out/0/3/1/0/0,MSG SENT 23:08:48.057 -> 4 : 28FC801F16130104 23:08:48.057 -> 4194 GWT:TPS:TOPIC=1wire-out/0/4/1/0/42,MSG SENT 23:08:48.057 -> 4 : 5C014B467FFF0C10D7 : 21.75 23:08:48.123 -> 4245 GWT:TPS:TOPIC=1wire-out/0/4/1/0/0,MSG SENT 23:08:48.190 -> 5 : 2832312A161301C3 23:08:48.190 -> 4317 GWT:TPS:TOPIC=1wire-out/0/5/1/0/42,MSG SENT 23:08:48.190 -> 5 : 58014B467FFF0C10C2 : 21.50 23:08:48.223 -> 4368 GWT:TPS:TOPIC=1wire-out/0/5/1/0/0,MSG SENT 23:08:48.322 -> 6 : 28CAD31F16130180 23:08:48.322 -> 4440 GWT:TPS:TOPIC=1wire-out/0/6/1/0/42,MSG SENT 23:08:48.322 -> 6 : 57014B467FFF0C1038 : 21.44 23:08:48.356 -> 4489 GWT:TPS:TOPIC=1wire-out/0/6/1/0/0,MSG SENT 23:08:48.422 -> 7 : 28FFE4493118014F 23:08:48.422 -> 4560 GWT:TPS:TOPIC=1wire-out/0/7/1/0/42,MSG SENT 23:08:48.422 -> 7 : 58014B467FFF0C10C2 : 21.50 23:08:48.488 -> 4612 GWT:TPS:TOPIC=1wire-out/0/7/1/0/0,MSG SENT 23:08:48.555 -> 8 : 28FF345E311801AF 23:08:48.555 -> 4683 GWT:TPS:TOPIC=1wire-out/0/8/1/0/42,MSG SENT 23:08:48.555 -> 8 : 5B014B467FFF0C1007 : 21.69 23:08:48.621 -> 4734 GWT:TPS:TOPIC=1wire-out/0/8/1/0/0,MSG SENT 23:08:48.687 -> 9 : 28FF094131180165 23:08:48.687 -> 4806 GWT:TPS:TOPIC=1wire-out/0/9/1/0/42,MSG SENT 23:08:48.687 -> 9 : 55014B467FFF0C10BE : 21.31 23:08:48.721 -> 4855 GWT:TPS:TOPIC=1wire-out/0/9/1/0/0,MSG SENT 23:08:48.787 -> 10 : 28FFE513311802A3 23:08:48.787 -> 4927 GWT:TPS:TOPIC=1wire-out/0/10/1/0/42,MSG SENT 23:08:48.820 -> 10 : 51014B467FFF0C10AB : 21.06 23:08:48.853 -> 4980 GWT:TPS:TOPIC=1wire-out/0/10/1/0/0,MSG SENT 23:08:48.920 -> 11 : 28FF2B1F31180231 23:08:48.920 -> 5052 GWT:TPS:TOPIC=1wire-out/0/11/1/0/42,MSG SENT 23:08:48.920 -> 11 : 56014B467FFF0C107B : 21.37 23:08:48.986 -> 5103 GWT:TPS:TOPIC=1wire-out/0/11/1/0/0,MSG SENT 23:08:48.986 -> DBG: loop end
-
In case someone is interested in the code for mysensors mqtt gateway using the DS2482.h library from https://github.com/paeaetech/paeae. The temperature conversion code is from example. I am omitting the mysensors setup.
... #include <DS2482.h> #include <Ethernet.h> #include <MySensors.h> #include <Wire.h> DS2482 ds( 0 ); //channels ds2482-800 is 0 to 7, DS2482-100 is just set 0 byte dsData[8]; //holding for onewire capture byte dsAddr[8]; //1wire wire address and CRC MyMessage msgAddr( 0, V_ID ); MyMessage msgTemp( 0, V_TEMP ); void setup() { //Uses Wire library to communicate with DS2482 so be sure to call Wire.begin() before using the library. Wire.begin(); ds.reset(); } void presentation() { // Send the sketch version information to the gateway and Controller sendSketchInfo( SKETCH_NAME, SKETCH_MAJOR_VER "." SKETCH_MINOR_VER ); } void loop() { #ifdef MY_DEBUG Serial.println( "DBG: loop start" ); #endif ds.wireResetSearch(); ds.wireReset(); ds.wireSkip(); //need to send high power to bus?? Adding 5 volts to devices makes it work. ds.wireWriteByte( 0x44 ); //convert temperature on all devices delay( 1000 ); byte sensorId = 0; while( ds.wireSearch( dsAddr ) ) { #ifdef MY_DEBUG Serial.print( sensorId ); Serial.print( " : " ); #endif char sensorAddr[17]; //eg. 280838211713012D for( int i = 0; i < 8; i++ ) { sensorAddr[i*2] = ( dsAddr[i] >> 4 ) + 0x30; if ( sensorAddr[i*2] > 0x39 ) { sensorAddr[i*2] += 7; } sensorAddr[i*2+1] = ( dsAddr[i] & 0x0f ) + 0x30; if ( sensorAddr[i*2+1] > 0x39 ) { sensorAddr[i*2+1] += 7; } } sensorAddr[16] = '\0'; //always zero terminate string #ifdef MY_DEBUG Serial.print( sensorAddr ); Serial.print( "\n" ); #endif send( msgAddr.setSensor( sensorId ).set( sensorAddr ) ); #ifdef MY_DEBUG Serial.print( sensorId ); Serial.print( " : " ); #endif if ( ds.crc8( dsAddr, 7 ) != dsAddr[7] ) { Serial.print( "CRC is not valid!" ); return; } /* //test if device code DS18B20 if ( dsAddr[0]==0x28 ) { //test if device code MAX31850 if ( dsAddr[0]==0x3B ) { */ //read temperature data. ds.wireReset(); //ds.reset(); ds.selectChannel( 0 ); //necessary on -800 ds.wireSelect( dsAddr ); ds.wireWriteByte( 0xbe ); // Read Scratchpad command //display hex values of scratchpad for ( int i = 0; i < 9; i++ ) { // we need 9 bytes dsData[i] = ds.wireReadByte(); #ifdef MY_DEBUG if ( dsData[i] < 16 ) { Serial.print( "0" ); } Serial.print( dsData[i], HEX ); #endif } //convert to decimal temperature int LowByte = dsData[0]; int HighByte = dsData[1]; int TReading = ( HighByte << 8 ) + LowByte; int SignBit = TReading & 0x8000; // test most sig bit if ( SignBit ) // negative { TReading = ( TReading ^ 0xffff ) + 1; // 2's comp } float Tc_100 = (double) TReading * 0.0625; if ( SignBit ) { // If its negative Tc_100 = 0 - Tc_100; } //print temp for each device #ifdef MY_DEBUG Serial.print( " : " ); Serial.println( Tc_100 ); #endif send ( msgTemp.setSensor( sensorId ).set( Tc_100, 2 ) ); sensorId++; } #ifdef MY_DEBUG Serial.println( "DBG: loop end" ); #endif delay( 60000 ); }
I am of course happy for any feedback. Especially if I am doing anything stupid as I am no programmer