Hello everyone, I guess this question is quite dumb but I have the head in that since days and I think I need help from a third party person
I am using 4 temperature sensors (ds18b20) with onewire library and DallasTemperature library. These are connected to an Arduino Mega board. The data collected are send via serial port in JSON format to an other Arduino Uno with a W5100 module in order to store the data on a server online.
All is working fine, except the fact that I am not able to correctly bind a sensor to its geographical position (like external temperature, room temperature, etc...)
When I initialize the connection I use the ds18b20.begin() statement, and when I want to get the values I use:
ds18b20.requestTemperatures();
for (int i = 0; i < 4; i++) { sensor_value[i] = ds18b20.getTempCByIndex(i); }
So it's okay, I have my array with all the values but I am not able to know if index 1 of the array is the external sensor or not. So when I send the JSON I would be able to send the corresponding I2C address too.
So my question is, how to get the I2C address of the sensor i ?
Something like that:
ds18b20.requestTemperatures();
for (int i = 0; i < 4; i++) {
sensor_value[i] = ds18b20.getTempCByIndex(i);
sensor_address[i] = ds18b20.getAddressByIndex(i); // This method doesn't exists XD
}
You want to read the sensors by the address each has encoded permanent within it.
See
and look for
Reading DS18B20s By Address
The following sketch reads the temperature from DS18B20s by their addresses. Before you head for uploading the sketch, you need to change the addresses of DS18B20s with the one you’ve found in previous sketch.
So... interview your devices, determine their unique addresses and use those to differentiate.
Which means that an alternate would be to use multiple 1-wire buses, which might be easier but sorta kills the beauty of how the DS comms have been engineered.
OneWire oneWire(ONE_WIRE_BUS);
// Pass oneWire reference to DallasTemperature library
DallasTemperature sensors(&oneWire);
int deviceCount = 0;
float tempC;
void setup(void)
{
sensors.begin(); // Start up the library
that would disallow use of multiple one wire buses, with as few as one DS18B20 per.
Like
const byte oneWireAPin = 2;
const byte oneWireBPin = 3;
// Data wires are plugged into digital pin 2 and 3 on the Arduino
OneWire oneWireA (oneWireAPin) ;
OneWire oneWireB (oneWireBPin) ;
// Pass oneWire reference to DallasTemperature library
DallasTemperature sensorsA (&oneWireA) ;
DallasTemperature sensorsB (&oneWireB) ;
void setup(void)
{
sensorsA.begin();
sensorsB.begin();
I did imply that it is dumb\b\m\u\d inelegant. And if I was to use multiple anyhting, I'd do it with an array of whatever they were. Nevertheless, it might be easier for the OP to use multiple buses, then a physical mapping between which pin has which sensor could be made, no messing with the unique addresses the sensors afford.
#include<OneWire.h>
OneWire ds(5); //Signal in is DPin-5.
//--declare arrays to hold addresses of the sensors
byte ds1Add[8]; //to hold 64-bit ROM Codes/Address of DS1
//-------------
byte ds4Add[8];
void setup()
{
Serial.begin(9600);
//--reset all addresses at the same time----
ds.reset();
//-collect addresses of the sensors----
ds.search(ds1Add); //lower byte is saved first.
//----------------
ds.search(ds4Add);
}
void loop(){}
The OneWire address never changes and is globally unique. So once you know which device is in which location, it will never change. Only problem happens when a device must be replaced. Then you must determine it's address.
A little feedback about my problem above, I've managed the link @alto777 provided and also the advices you guys gave to me and it have solved the problem.
I used the following to get the adresses:
for (int i = 0; i < NB_TEMP_SENSORS; i++) {
sensor_value[temp_index[i]] = ds18b20.getTempCByIndex(i);
ds18b20.getAddress(temp_address[i],i);
// Affichage des adresses de capteurs
Serial.print(sensors_id[temp_index[i]]);
Serial.print(" (");
char* const charAddress = convertAddress(temp_address[i]);
Serial.print(charAddress);
Serial.print(")");
Serial.print(" = ");
Serial.println(sensor_value[temp_index[i]]);
}
And converted them with the following function to put it in the serial monitor and also in the JSON file I send to the W5100:
char* convertAddress(DeviceAddress deviceAddress){
static char charAddress[39];
memset(charAddress, '\0',39+1);
char segment[3];
byte index = 0;
for (byte i = 0; i < 8; i++) {
snprintf(segment,3,"%02x",deviceAddress[i]); //convert a byte to character string, and save 2 characters (+null) to charArr;
charAddress[index] = segment[0];
index++;
charAddress[index] = segment[1];
index++;
}
return charAddress;
}
The reconciliation is done by the online program who receive the data and the match is working perfectly. Many thanks to you all !!!