I am in the process of creating a 4 channel temperature controller. I am wanting to use DS18B20 sensors. As sensors will be swapped out and moved around, I figure this would cause problems using a single input for them all. So I am thinking one sensor on each input would be the best route. I searched around for examples of how to implement this and was not coming up with anything. Could someone point me in the right direction?
This is the code I used, derived from the sheepdog method. Not such a great idea in principle but works fine if you have the pins to spare.
Another approach is to incorporate the address finder code. This enables you to still use the one-wire system.
/*
Reading two DS18B20s pins 14&15
display to monitor
display to LCD with pin D04 moved to pin 16 (A2)
Code uses Arduino LCD, sheepdog temp reader, SD stuff from Mellis & Igoe
*/
#define tture1 14//no ; here
#define tture2 15//no ; here
// include the library codes:
#include <LiquidCrystal.h>
#include <SD.h>
File myFile;
// initialize the library with the numbers of MY interface pins
LiquidCrystal lcd(8,9,16,5,6,7);
int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
void setup() {
//For each tture sensor: Do a pinMode and a digitalWrite
pinMode(tture1, INPUT);
pinMode(tture2, INPUT);
digitalWrite(tture1, LOW);//Disable internal pull-up.
digitalWrite(tture2, LOW);
Serial.begin(9600);
delay(300);//Wait for newly restarted system to stabilize
Serial.print("Temperature measurement, two sensors:\n\n");
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
lcd.clear();
// Print a message to the LCD.
lcd.print("temp in out");
Serial.print("Initializing SD card...");
pinMode(10, OUTPUT);
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
// open the file. note that only one file can be open at a time,
// so you have to close this one before opening another.
myFile = SD.open("test.txt", FILE_WRITE);//+++++++++++++++++++ OPEN
// if the file opened okay, write to it:
if (myFile) {
Serial.print("Writing to test.txt...");
myFile.println("testing! Did you forget the date?");
myFile.close();//++++++++++++++++++++++++++++++++++++++++++++ CLOSE
Serial.println("done.");
} else {
// if the file didn't open, print an error:
Serial.println("error opening test.txt");
}
}
void loop(){
// set the LCD cursor to column 4, line 1
// (note: line 1 is the second row, since counting begins with 0):
lcd.setCursor(4, 1);
readTture(tture1);//N.B.: Values passed back in globals
printTture();//N.B.: Takes values from globals. Also...
//no newline part of printTture;
delay(120);// Delay... must not be too short.
// set LCD cursor for second temp
lcd.setCursor(11, 1);
readTture(tture2);//Now read and report 2nd tture.
printTture();
delay(200);// Delay... must not be too short.
Serial.print("\n");//Start new line
myFile = SD.open("test.txt", FILE_WRITE);//+++++++++++++++++++++++++OPEN
myFile.println(", ");
myFile.close();//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>CLOSE
delay(880);
}
//Everything below here... just copy it into your program "as is".
//You are only likely to need to use readTture(pin) and printTture()
// directly. Others are subordinate to those.
//These routine access the following global variables...
// int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
void OneWireReset(int Pin) // reset. Should improve to act as a presence pulse
{
digitalWrite(Pin, LOW);
pinMode(Pin, OUTPUT); // bring low for 500 us
delayMicroseconds(500);
pinMode(Pin, INPUT);
delayMicroseconds(500);
}
//end OneWireReset
void OneWireOutByte(int Pin, byte d) // output byte d (least sig bit first).
{
byte n;
for(n=8; n!=0; n--)
{
if ((d & 0x01) == 1) // test least sig bit
{
digitalWrite(Pin, LOW);
pinMode(Pin, OUTPUT);
delayMicroseconds(5);
pinMode(Pin, INPUT);
delayMicroseconds(60);
}
else
{
digitalWrite(Pin, LOW);
pinMode(Pin, OUTPUT);
delayMicroseconds(60);
pinMode(Pin, INPUT);
}
d=d>>1; // now the next bit is in the least sig bit position.
}
}//end OneWireOutByte
byte OneWireInByte(int Pin) // read byte, least sig byte first
{
byte d, n, b;
for (n=0; n<8; n++)
{
digitalWrite(Pin, LOW);
pinMode(Pin, OUTPUT);
delayMicroseconds(5);
pinMode(Pin, INPUT);
delayMicroseconds(5);
b = digitalRead(Pin);
delayMicroseconds(50);
d = (d >> 1) | (b<<7); // shift d to right and insert b in most sig bit position
}
return(d);
}//end OneWireInByte
void readTture(byte Pin){
//Pass WHICH pin you want to read in "Pin"
//Returns values in... (See global declarations)
OneWireReset(Pin);
OneWireOutByte(Pin, 0xcc);
OneWireOutByte(Pin, 0x44); // perform temperature conversion, strong pullup for one sec
OneWireReset(Pin);
OneWireOutByte(Pin, 0xcc);
OneWireOutByte(Pin, 0xbe);
LowByte = OneWireInByte(Pin);
HighByte = OneWireInByte(Pin);
TReading = (HighByte << 8) + LowByte;
SignBit = TReading & 0x8000; // test most sig bit
if (SignBit) // negative
{
TReading = (TReading ^ 0xffff) + 1; // 2's comp
}
Tc_100 = (6 * TReading) + TReading / 4; // multiply by (100 * 0.0625) or 6.25
Whole = Tc_100 / 100; // separate off the whole and fractional portions
Fract = Tc_100 % 100;
};//end readTture
void printTture(){//Uses values from global variables.
//See global declarations.
//N.B.: No new line inside printTture
myFile = SD.open("test.txt", FILE_WRITE); //+++++++++++++OPEN
if (SignBit) // If it's negative
{
Serial.print("-");
lcd.print("-");
myFile.print("-");
};
Serial.print(Whole);
Serial.print(".");
lcd.print(Whole);
lcd.print(".");
myFile.print(Whole);
myFile.print(".");
if (Fract < 10)
{
Serial.print("0");
lcd.print("0");
myFile.print("0");
};
Serial.print(Fract);
lcd.print(Fract);
myFile.print(Fract);
Serial.print(" ");
myFile.print(", ");
myFile.close();//++++++++++++++++++++++++ CLOSE
};//end printTture
Thanks. I saw that way, I was trying to see if I there were any options. I was hoping that this was possible with the OneWire and Dallas functions as I have already been playing with them a bit. I am not sure if the using the address finder will work for me or not. What I am really trying to do is if a sensor from "input 4" is put into "input 2" I want that sensor to now be input 2. From my understanding if I reference these by address, it will still be reporting as input 4 correct? That is what I am really wanting to avoid.
adamfritzsche:
What I am really trying to do is if a sensor from "input 4" is put into "input 2" I want that sensor to now be input 2. From my understanding if I reference these by address, it will still be reporting as input 4 correct? That is what I am really wanting to avoid.
No. One-wire is one-wire, and Arduino neither knows nor cares which input is used by which sensor. They report according to their address code, not the terminal by which they are corrected.
I don't know why you would want to swap them around, other than you find it hard to tell which is which, a problem I solve with paper labels. I misunderstood your intent and thought you were using different sensors and different Arduinos. This situation is in fact the only instance I can think of where building in the address finder is not a pointless exercise. I guess having the sensors constantly stolen might be another.
I now understand you merely want to be secure about mixing them in the same application. I can't see a problem with that, providing you know what the sensors are sensing.
I don't know why you would want to swap them around, other than you find it hard to tell which is which, a problem I solve with paper labels. I misunderstood your intent and thought you were using different sensors and different Arduinos. This situation is in fact the only instance I can think of where building in the address finder is not a pointless exercise. I guess having the sensors constantly stolen might be another.
For now, no there would be no reason to swap them around. My thought is that with a final product, where if probes have been replaced or put on a different connection than what was labeled by the end user, you would have problems. It would not be a very user friendly replacement of probes. Just trying to prevent this sort of thing being an issue.
Im thinking out loud here, but the best of both worlds would be to put all the sensors on 1 input and have a menu function where a user can define what sensor is to be read as what "input" and these addresses/input assignment combo would be saved in eeprom. Unfortunately I would have no idea where to start with this.