I have a project hooked up with a single dallas ds18b20 temp sensor. As of now I stored the unique address in the code and accessed the devices which is supposed to be faster than accessing them by index and my project is taking up a lot of overhead as is.
I am now banging my head trying to figure out how to make it so I can plug ANY ds18b20 into the device as my project is to be completely modular and has all replaceable parts.
I need to read the address which gets stored into an array containing 8 bytes as per the generic example then I need to store that in a variable of type DeviceAddress (which is an array of 8 uint8 elements from the DallasTemperature library) that I would name myTempSensorAddress.
Im pretty new to having to use all these data types and it is making my head hurt. Any help?
This is from DallasTemperature.h
typedef uint8_t DeviceAddress[8];
It gets called in my code like this above void setup()
PaulS:
You need to make the array named myThermalSensorAddress equal WHAT 8 byte array?
the addr array down below. the function search(addr) returns the address of the onewire device. I need to store that in the DeviceAddress from DallasTemperature library from my example above.
I know this is very old but it contains very helpful posts and I needed to say thank you to all that participated!
I've been searching hours to find this perfect example for a newbie like me.
The key message was "Do you understand that DeviceAddress is not a real type? The name is an alias for a byte array with 8 elements"
I can now read all my sensors (20 of them) and store them in my two dimensional byte array for later use.
byte DS18B20_DeviceByteAddresses[20][8];
...
// as you read the device addresses with one of the many examples call this procdure
// to store the Device Address in the DS18B20_DeviceByteAddresses array.
void Temperature_storeDeviceAddress(int position, DeviceAddress deviceAddress) {
// function to convert a device address in a printable string
for (uint8_t i = 0; i < 8; i++) {
DS18B20_DeviceByteAddresses[position][i] = deviceAddress[i];
}
}
void Temperature_printAllDS18B20() {
sensors.requestTemperatures();
byte addr[8]; // temp storage as we put the serial number back together
delay(1000);
for (int i = 0; i < 20; i++) {
Serial.print("Device: "); Serial.println(i);
// put the address back together
for (int f = 0; f < 8; f++) {
addr[f] = DS18B20_DeviceByteAddresses[i][f];
}
Serial.print("Serial: "); Temperature_printAddressDS18B20(addr); Serial.println("");
float tempC = sensors.getTempCByIndex(i); // call by index number
Serial.println(tempC);
float tempC = sensors.getTempC(addr); // call by stored device address
Serial.println(tempC);
}
}
void Temperature_printAddressDS18B20(DeviceAddress deviceAddress) {
// function to print a device address
for (uint8_t i = 0; i < 8; i++) {
if (deviceAddress[i] < 16) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
}
}
I'm curious if there is a better way but after hours of playing and reading different examples most of which required me to hard code the Device Address into variables I'm really quite happy with this.
@bionicbone
I believe your code is exactly what I have been searching for going on two days now. I haven't started working with it quite yet, but is there anyway you can post more of the code/setup you are using?
The Arduino I have setup will have a handful of sensors that I want outputted by Serial for processing with a Raspberry Pi. Your code will give me the ability to have multiple temperature sensors without already knowing their device address.
Thank you VERY MUCH for posting what you have so far! My code looks like this (I'm still in the process of testing and trying to figure out how to output my data and addresses in the correct format):
#include <OneWire.h>
#include <DallasTemperature.h>
int tp = 5; // temperature power
int ti = 7; // temperature input
int loopDelay = 2000; // loop delay
OneWire ow(ti);
DallasTemperature sensors(&ow);
DeviceAddress device;
uint8_t* devices;
int deviceCount;
void setup(void)
{
pinMode(ti,INPUT); // setup temp pin
digitalWrite(ti,LOW); // turn down temp input
pinMode(tp,OUTPUT); // setup temp power pin
Serial.begin(9600);
// Setup oneWire sensors for initial read
digitalWrite(tp,HIGH); // turn on power to temp
sensors.begin();
sensors.begin();
if (!sensors.getAddress(device, 0)) Serial.println("Unable to find address for Device 0");
//Serial.print(device[2],HEX);
Serial.print(sensors.getAddress(device[1], 0));
deviceCount = sensors.getDeviceCount();
for (int i = 0; i < deviceCount; i++) {// Create w1 device index array
DeviceAddress devices[i];
if (sensors.getAddress(devices[i],i));
}
Serial.print(sizeof(devices[0]));
Serial.print(deviceCount);
//devices = sensors.getDeviceCount();
//if (digitalRead(tp)) digitalWrite(tp,LOW); // turn off power to temp
}
void loop()
{
Serial.print("[");
get1w();
Serial.println("]");
delay(loopDelay);
}
void get1w()
{
//if (!digitalRead(tp)) digitalWrite(tp,HIGH); // turn on power to temp
uint8_t address[8];
int* count = 0;
for (int i = 0; i < deviceCount; i++) {
sensors.setResolution(&devices[i],9);
Serial.print(sensors.requestTemperaturesByAddress(&devices[i]));
if (count>0) Serial.print(",");
Serial.print("'");
for (int j = 0; j < 8; j++) {
Serial.print(sizeof(&devices[i]));
if (j < 1) Serial.print("-");
count++;
}
}
//Serial.print(devices);
//ow.reset_search();
/*if (ow.search(address)) {
do {
// Print Sensor ID
if (count>0) Serial.print(",");
Serial.print("'");
for (uint8_t i = 0; i < 8; i++) {
//addr += address[i].toChar();
//if (i<1) addr += "-";
//if (address[i] < 16) Serial.print("0");
Serial.print(address[i]);
if (i < 1) Serial.print("-");
}
Serial.print("':");
// Print Sensor Data
sensors.setResolution(address,9);
float tempC = sensors.getTempC(address);
Serial.print(tempC);
count++;
}
while (ow.search(address));
}*/
//if (digitalRead(tp)) digitalWrite(tp,LOW); // turn off power to temp
}
Thanks for the quick reply. I'll be honest though, I'm new to Arduino programming and the wrapper you posted is way over my head. I wish I had the time to devote to learning more about the language but I'm behind as it is.
I was hoping to get bionicbone's code as a launch pad to make mine work.
Here is my completed code if anyone is interested in the future. I set it up for debugging, which I'll remove for production.
#include <OneWire.h>
#include <DallasTemperature.h>
bool DEBUG = false; // for outputting debugging information
bool stopFlag = false; // stopFlag: when true, loop will stop processing
int serialByte; // variable for receiving commands from serial
boolean newData = false; // does new data exist?
int tp = 5; // digital pin number for temperature sensor power (4.7v)
int ti = 7; // digital pin number for temperature sensor input
int loopDelay = 2000; // loop delay in milliseconds
byte tempDevices[5][8]; // Up to five temperature sensors
int tempDeviceCount; // temperature sensor count
OneWire ow(ti);
DallasTemperature sensors(&ow);
void setup(void)
{
pinMode(ti,INPUT); // setup temp pin
digitalWrite(ti,LOW); // turn down temp input
pinMode(tp,OUTPUT); // setup temp power pin
Serial.begin(9600); // Start serial port
// Setup oneWire sensors for initial read
digitalWrite(tp,HIGH); // turn on power to temp
sensors.begin(); // initialize sensors
sensors.begin(); // sensors need to be initialized twice or all sensors won't be detected
//ow.reset_search();
tempDeviceCount = sensors.getDeviceCount(); // temperature devices
if (!tempDeviceCount) { // if can't find temperature sensors, turn on debugging and trouble shoot
tempTroubleshoot();
}
if (DEBUG) {
Serial.print("Device Count: ");
Serial.print(tempDeviceCount);
Serial.println();
}
for (int i = 0; i < tempDeviceCount; i++) {// Create w1 device index array
if (sensors.getAddress(tempDevices[i],i)) ;
}
//if (digitalRead(tp)) digitalWrite(tp,LOW); // turn off power to temp after setup is complete
Serial.flush();
}
void serialEvent() { // Get Serial Data and Process
if (Serial.available()) {
serialByte = Serial.read();
newData = true;
processNewData();
}
}
void processNewData() { // process new data received from serial port
if (newData) {
if (serialByte == 84) { // Byte: 84 ("T")
// Do something with Temperature setting
}
else if (serialByte == 43) { //Byte: 43 ("+")
// Increase coeffecient value by 0.1
}
else if (serialByte == 45) { //Byte: 45 ("-")
// decrease coeffecient value by 0.1
}
else if (serialByte == 68) { // Byte: 68 ("D") - Turn on debugging
DEBUG = true;
}
else if (serialByte == 100) { // Byte: 100 ("d") - Turn off debugging
DEBUG = false;
}
else if (serialByte == 108) { // Byte: 108 ("l" or lowercase L) - Turn off Loop
stopFlag = true;
Serial.print("\n************************\nSTOPPING MAIN FUNCTION\n************************\n\n");
}
if (DEBUG) { // output serial data if DEBUG is true
Serial.print("/nNew Serial Data: ");
Serial.println(serialByte);
}
newData = false;
}
}
//void stopLoop () if (!stopFlag) return;
void loop()
{
if (!DEBUG) Serial.print("[");
else Serial.println("DEBUG MODE");
getTemps();
if (!DEBUG) Serial.println("]");
delay(loopDelay);
while (stopFlag) { } // stop main function
}
void getTemps() {
sensors.requestTemperatures(); // Instructions to get temps
delay(250);
if (DEBUG) {
Serial.print("Devices: ");
Serial.println(tempDeviceCount);
}
for (uint8_t i=0;i<tempDeviceCount;i++) { // loop through devices
if (i>0) Serial.print(",");
Serial.print(getTempByDevice(tempDevices[i])); // print temperature
if (DEBUG) {
Serial.print("\nLoop Counter: ");
Serial.println(i);
}
}
}
float getTempByDevice(DeviceAddress deviceAddress) {
byte addr[8];
if (DEBUG) Serial.print("addr: ");
Serial.print("'");
for (int f = 0; f < 8; f++) {
addr[f] = deviceAddress[f];
Serial.print(addr[f],HEX);
if (f < 1) Serial.print("-");
}
if (DEBUG) {
Serial.print(" addr sizeof: ");
Serial.print(sizeof(addr));
}
Serial.print("':");
if (DEBUG) {
Serial.print("\nTemperature sensor reading: ");
}
float tempC = sensors.getTempC(addr); // call by stored device address
return tempC;
}
void tempTroubleshoot() {
if (!tempDeviceCount) { // if can't find temperature sensors, turn on debugging and trouble shoot
DEBUG = true;
// trouble shooting
if (!digitalRead(tp)) { // Step 1: Check power on sensor pin
Serial.print("No power to temperature sensor pin ");
Serial.println(tp);
}
// other trouble shooting options
}
}
I have a question as this is something I've been searching for as the onewire bus reindexes the sensors if one goes down, the question I have is, trying to understand the multi array.
in the code you have declared.
byte tempDevices[5][8]; // Up to five temperature sensors
int tempDeviceCount; // temperature sensor count
and later you have this
for (int i = 0; i < tempDeviceCount; i++) {// Create w1 device index array
if (sensors.getAddress(tempDevices[i],i)) ;
}
even though you have been given a declared size, if the tempDevices is less would it only account for less and leave the rest empty, and what happens if you don't know how many sensor devices you are going to use is there a correct method to leave the size open e.g something like.
byte tempDevices[][8]; // Up to five temperature sensors
int tempDeviceCount; // temperature sensor count
I'm still new at this and my job doen't allow me to use this everyday its every now and again. thanks in advance. fingers crossed.