In Setup I have stored the sensor addresses to a byte array using:
//<Global>
uint8_t sensor1Add[8];
//<Setup>
while (sensors1.getAddress(sensor1Add, x)) {
Serial.print(F("Temp sensor bus 1 "));
Serial.print(x + 1);
Serial.print(" : ");
sensors1.getAddress(sensor1Add, x);
for (int i = 0; i < 8; i++) {
Serial.print(sensor1Add[i], HEX);
Serial.print(" ");
}
Serial.println();
x = x + 1;
}
But I am not sure how to use that array with the requestTemperaturesByAddress command. All the examples I can find seem to use a hard-coded address which I'm trying to avoid. Do I have to loop through all of the elements of the byte array, or is it simpler than that?
I tried: temp4 = sensors1.requestTemperaturesByAddress(sensor1Add);
Does your program work properly if you use a hard coded address as a test?
Move the address from your array to a variable and use the variable as if you were using a hrd coded address.
If failure, use serial.Print() the address to see what you actually are using for an address.
Good plan, but I'm not sure what you mean by use serial.Print(). Can you just use "Serial.print(sensor1Add)" for a DeviceAddress/byte array? I'm getting compiler errors:
no matching function for call to 'print(uint8_t [8])' Serial.print(sensor1Add);
Or do you mean loop through it to show each element of the address array?
My code for showing the hex address, and then creating a CRC16 from it is:
int x = 0;
// Sensor 1
while (sensors1.getAddress(sensor1Add, x)) {
Serial.print(F("Temp sensor bus 1 "));
Serial.print(x + 1);
Serial.print(" : ");
sensors1.getAddress(sensor1Add, x);
for (int i = 0; i < 8; i++) {
Serial.print(sensor1Add[i], HEX);
Serial.print(" ");
}
Serial.println();
x = x + 1;
}
Serial.print(F("CRC 1 DEC:HEX = "));
// for (int i = 0; i < 3; i++) {
crcValue1 = calculateCRC16(sensor1Add, 8);
Serial.print(crcValue1, DEC);
Serial.print(" : ");
Serial.println(crcValue1, HEX);
Serial.println();
So I can plug sensors in and it'll work rather than having to work out which sensors are where. If I need to swap a sensor out, I don't want to have to recompile.
Sure you get errors. you have to identify WHICH one of the array you want to print. Try printing the array entry you will be using to test your temperature sensor.
An array is made up of individual entries. In your case 8. They are numbered 0 thru 7. serial.Print(array(0)); will get you the first address. Do the same for the rest of your array. PLEASE spend some time working on arrays in C.
I'm aware of that - I posted the full array at the bottom of post #3. Your reply #6 confused me though. And I am spending time working on arrays in C - hence these questions!
Here's a multi DS18B20 pgm I wrote years ago to monitor my water heater elements via HC-12 radios. I use only the OneWire library but maybe some parts might help.
#include <OneWire.h>
OneWire ds(7); // on pin 7 (a 4.7K resistor is necessary)
#include <SoftwareSerial.h>
SoftwareSerial HC12(10,11); // RX, TX
#define debug // comment this line to disable data print to serial
unsigned long start; // update timer
const int end = 15000; // update period in milliSeconds
byte data[12];
char txBuf[4];
const byte upper[8] = {0x28,0x14,0xCE,0x4D,0x05,0x00,0x00,0x51},
lower[8] = {0x28,0xFF,0x4A,0x00,0x22,0x04,0x00,0xFC};
const char header[] = {"\nupper lower"};
void setup()
{
#ifdef debug
Serial.begin(9600);
Serial.println("\n" __FILE__"\n");
Serial.println(header); // scroll break text
#endif
HC12.begin(9600);
}
void loop()
{
if(millis() - start > end) // time to update
{
start += end; // reset update timer
int upperVal, lowerVal;
static byte cntr = 0; // scroll break counter
for(byte url = 0;url < 2;url++) // url = upper or lower
{
ds.reset();
if(url == 0)
ds.select(upper); // which sensor to read
else
ds.select(lower);
ds.write(0xBE); // Read Scratchpad
for ( byte i = 0; i < 9; i++) // we need 9 bytes
data[i] = ds.read();
if(url == 0)
upperVal = data[1] << 8 | data[0];
else
lowerVal = data[1] << 8 | data[0] + 12;
}
ds.reset();
ds.skip(); // skip address read
ds.write(0x44); // start conversion for all sensors
//val = antiDither(newVal);
#ifdef debug
if(++cntr >= 12) // scroll break lines
{
cntr = 0;
Serial.println(header);
}
Serial.print(upperVal >> 4); // whole degrees
Serial.print("_");
Serial.print(upperVal >>1 & 0x0007,HEX); // 1/8 degree
Serial.print(" ");
Serial.print(lowerVal >> 4);
Serial.print("_");
Serial.println(lowerVal >>1 & 0x0007,HEX);
#endif
txBuf[0] = highByte(upperVal);
txBuf[1] = lowByte(upperVal);
txBuf[2] = highByte(lowerVal);
txBuf[3] = lowByte(lowerVal);
HC12.write(&txBuf[0],4); // transmit data
}
// do other programming here
//...
//......
//.........
}
/*
int antiDither(int newVal) // prevents +1 <-> -1 dither
{
static int val = 0, oldVal = 0;
if(newVal != val && newVal != oldVal)
{
oldVal = val;
val = newVal;
}
return val;
}
*/
The address is 8 bytes long. In the DallasTemperature library it is defined as type DeviceAddress . You will need an array of device address - one for each sensor. You will then need to scan the devices to get the addresses. This will not tell you which device has which address since they are all on the same bus. The device addresses come back in scan order (usually in low to high order as a for loop is the usual scan method). See the Multiple example in the Dallas Temperature examples for some ideas.
I scan the sensors one at a time and put an external label them. Then I can know which sensor is at which location. You don't need the whole address on the external label - usually just the last few byte will be enough for uniqueness.
Thanks oldcurmudgeon. I've got each sensor on a different bus which I understand is a bit strange for a one-wire device, but the DS18B20 is cheap and readily available in a waterproof package whereas NTCs are a bit harder to come by. I think NTCs will be a better solution for me in the long run, but I want to learn how to get this working in the mean-time.