is it possible to go up to 15 sensors?? i'd like to control the temperature in several fish tanks. Someone told me i could use a mosfet but i have no idea how i could do that. (would a sensor shield do the job?)
I think it is. There are examples around where a large quantity is distributed over several pins. But I believe that was for convenience.
I have two installation with 20+ sensors each, on a Mega for memory size reason.
Pay attention to the cable you use (a CAT6 id fine and a cable like those used for HI FI systems too) and to the topoly (avoid star network) and you'll get your result with no issue.
If you want more detailed information look here https://www.maximintegrated.com/en/app-notes/index.mvp/id/148 in the Maxim site.
aldozan:
I have two installation with 20+ sensors each, on a Mega for memory size reason.Pay attention to the cable you use (a CAT6 id fine and a cable like those used for HI FI systems too) and to the topoly (avoid star network) and you'll get your result with no issue.
If you want more detailed information look here Guidelines for Reliable Long Line 1-Wire Networks | Analog Devices in the Maxim site.
could you please show me your installation ? i'd love to see it as i'm a noob just opening my eyes in arduino world
aldozan:
I have two installation with 20+ sensors each, on a Mega for memory size reason.Pay attention to the cable you use (a CAT6 id fine and a cable like those used for HI FI systems too) and to the topoly (avoid star network) and you'll get your result with no issue.
If you want more detailed information look here Guidelines for Reliable Long Line 1-Wire Networks | Analog Devices in the Maxim site.
what resistances did you use? i saw something about using 1.9k instead of 4.7k but let me know how you've done please
About resistance, i've always used the 4.7k and it works fine.
Below you find the list of an old version of a remote temperature contol system I developed some times ago.
You can see the sensor control section for DS18B20 reference.
The system uses an RTC for time logging and a two row LCD for temperature display. A two button strip is used to scroll up and down between the temparatures.
The 10 sensors in this system are connected in parasite mode (two wires) and the code runs on an UNO R3.
#include <OneWire.h>
OneWire ow(14);
#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
#include <SPI.h>
const int switchPinUp = 16;
const int switchPinDown = 17;
int switchUpState = 0;
int prevSwitchUpState = 0;
int switchDownState = 0;
int prevSwitchDownState = 0;
int tempSelected = 1;
const int lightSetPin = 9;
const int lightPinUp = 8;
const int lightPinDown = 12;
int lightUpState = 0;
int prevLightUpState = 0;
int lightDownState = 0;
int prevLightDownState = 0;
int lightSetValue = 90;
byte G_addr[10][8];
byte G_Devices;
float GetTemp(OneWire *,byte *);
void PrintAddress(byte *);
void lookUpSensors();
int CheckSensor(byte *);
const int nSens = 10;
int n;
float temperatureArray[nSens];
float temperatureDisplayArray[nSens];
char* nameSensWebArray[nSens]={
"Temperatura acqua pozzo: ", "Temperatura acqua calda: ", "Temperatura parte alta boilerone: ",
"Temperatura ingresso solare: ", "Temperatura ingresso termocamino: ", "Temperatura uscita termocamino: ", "Temperatura ingresso caldaia: ",
"Temperatura mandata termo: ","Temperatura ritorno termo: ","Temperatura esterna: "};
char* nameSensLCDArray[nSens]={
"T.H2O: ","T.H2O cal.: ","T.boil.: ","T.solare: ","T.cam in: ","T.cam out: ","T.gas in: ","T.termo M: ","T.termo R: ","T.estern:"};
void setup(){
Serial.begin(9600);
Wire.begin();
setRTCTime();
lightInit();
switchInit();
lookUpSensors();
pinMode(4, OUTPUT);
digitalWrite(4, HIGH);
}
void loop(){
tempRead1Wire();
lightLCDSet();
rowViewSelect();
tempLCDShow();
switchSelect();
lightSelect();
}
// FUNZIONE di allineamento ora RTC con PC
void setRTCTime(){
setSyncProvider(RTC.get); // the function to get the time from the RTC
if(timeStatus()!= timeSet)
Serial.println("Impossibile sincronizzare l' RTC. Controllare l'hardware");
else
Serial.println("L'RTC ha sincronizzato data e ora: ");
}
// FUNZIONE di ricerca sensori 1-wire
void lookUpSensors(){
G_Devices=0;
byte address[8];
Serial.print("Inizio ricerca sensori 1-wire");
while (ow.search(address))
{
if (address[0] == 0x10 || address[0] == 0x28 )
{
if(CheckSensor(address)==1) //crc ok
{
Serial.println("");
Serial.print("Sensore nr. ");
Serial.print(G_Devices+1);
if (address[0] == 0x10) Serial.print(", tipo DS18S20, id: ");
else if (address[0] == 0x28) Serial.print(", tipo DS18B20, id: ");
PrintAddress(address);
for(int aa=0;aa<8;aa++) G_addr[G_Devices][aa]=address[aa];
G_Devices++;
}
}
}
}
// FUNZIONE di lettura delle temperature dai sensori 1-wire
void tempRead1Wire(){
float temperatura;
for(int num=0;num<G_Devices;num++)
{
temperatura=GetTemp(&G_addr[num][0]);
temperatureArray[num] =temperatura;
}
}
// FUNZIONE di recupero dei dati dai sensori 1-wire
float GetTemp(byte * addr) {
byte present = 0;
byte data[12];
int i;
byte address[8];
for(i=0;i<8;i++) address[i]=*(addr+i);
ow.reset();
ow.select(addr);
ow.write(0x44,1); // start conversion, with parasite power on at the end
delay(800);
present = ow.reset();
ow.select(addr);
ow.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++) data[i] = ow.read(); // we need 9 bytes //Serial.print(data[i], HEX);
int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract;
double result;
LowByte = data[0];
HighByte = data[1];
TReading = (HighByte << 8) + LowByte;
SignBit = TReading & 0x8000; // test most sig bit
if (SignBit) TReading = (TReading ^ 0xffff) + 1; // 2's comp // negative
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;
result = Whole;
result += ((double)Fract/100);
if(SignBit) result *= -1;
return result;
}
// FUNZIONE di stampa degli indirizzi dei sensori 1-wire
void PrintAddress(byte * address) {
int i;
for (i=0;i<8;i++) {
if (address[i] < 9) Serial.print("0");
Serial.print(address[i],HEX);
if (i<7) Serial.print("-");
}
}
// FUNZIONE di controllo CRC
int CheckSensor(byte * address) {
if (OneWire::crc8(address, 7) != *(address+7)) return(-1);
else return(1);
}
//FUNZIONE di inizializzazione pulsanti di controllo luminosità LCD
void lightInit(){
pinMode(lightPinUp, INPUT);
pinMode(lightPinDown, INPUT);
pinMode(lightSetPin, OUTPUT);
analogWrite(lightSetPin, lightSetValue);
}
//FUNZIONE di inizializzazione pulsanti di selezione dei sensori da cui leggere la temperatura
void switchInit(){
pinMode(switchPinUp, INPUT);
pinMode(switchPinDown, INPUT);
}
// FUNZIONE di scrittura intestazioni del display LCD
void tempLCDTitle(){
lcd.begin(16, 2);
lcd.setCursor(0, 0);
lcd.print("Temp.");
lcd.setCursor(0, 1);
lcd.print("Temp.");
}
// FUNZIONE di controllo della luminosità LCD
void lightLCDSet(){
lightUpState = digitalRead(lightPinUp);
if(lightUpState != prevLightUpState) {
if (lightUpState == LOW){
lightSetValue = lightSetValue - 10;
if (lightSetValue <255){
analogWrite(lightSetPin, lightSetValue);
delay(10);
}
else {
lightSetValue = 0;
}
}
}
lightDownState = digitalRead(lightPinDown);
if(lightDownState != prevLightDownState) {
if (lightDownState == LOW){
lightSetValue = lightSetValue + 10;
if (lightSetValue >=0){
analogWrite(lightSetPin, lightSetValue);
delay(10);
}
else {
lightSetValue = 240;
}
}
}
}
// FUNZIONE di scelta della visualizzazione su LCD
void rowViewSelect(){
switchUpState = digitalRead(switchPinUp);
if(switchUpState != prevSwitchUpState) {
if (switchUpState == LOW){
tempSelected = tempSelected + 2;
if (tempSelected > nSens){
tempSelected = 1;
}
}
}
switchDownState = digitalRead(switchPinDown);
if(switchDownState != prevSwitchDownState) {
if (switchDownState == LOW){
tempSelected = tempSelected - 2;
if (tempSelected < 1){
if ((nSens % 2) == 0){
tempSelected = nSens - 1;
}
else {
tempSelected = nSens;
}
}
}
}
}
// FUNZIONE di visualizzazione temperature su LCD
void tempLCDShow(){
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(nameSensLCDArray[tempSelected-1]);
lcd.setCursor(11, 0);
lcd.print(temperatureDisplayArray[tempSelected -1]);
if (((nSens % 2) != 0) && (tempSelected == nSens)){
lcd.setCursor(0, 1);
lcd.print(" NOT AVAIL ");
}
else {
lcd.setCursor(0,1);
lcd.print(nameSensLCDArray[tempSelected]);
lcd.setCursor(11, 1);
lcd.print(temperatureDisplayArray[tempSelected]);
}
}
// FUNZIONE di controllo pulsanti di scorrimento visualizzazione
void switchSelect(){
prevSwitchUpState = switchUpState;
prevSwitchDownState = switchDownState;
}
// FUNZIONE di controllo pulsanti di regolazione intensità LCD
void lightSelect(){
prevLightUpState = lightUpState;
prevLightDownState = lightDownState;
}
discusshrimp:
what resistances did you use? i saw something about using 1.9k instead of 4.7k
This was probably for use when things get critical with very long cables. The standard 4.7k is good for at least 5m.
Hi everyone,
I'm trying to aquire temperature from two of these DS18B20, through the same bus. I had already ran the sketch to aquire its adresses and no problems with that. Now, trying to read the temps, it recognizes that there are two sensor attached, but seems to ignore one of the devices. Can anyone see any possible reason? Follows my sketch.
#include <OneWire.h>
#include <DallasTemperature.h>
// Porta do pino de sinal do DS18B20
#define ONE_WIRE_BUS 3
void check_sensors();
// Define uma instancia do oneWire para comunicacao com o sensor
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
DeviceAddress sensor1 = { 0x28, 0xFF, 0x1C, 0xFB, 0x71, 0x16, 0x05, 0xCD };
DeviceAddress sensor2 = { 0x28, 0xFF, 0xCE, 0x15, 0x72, 0x16, 0x05, 0xA8 };
int checkt = 0;
bool checkf = false;
float temps;
bool s1f = false;
float temps1;
bool s2f = false;
float temps2;
void setup(void)
{
Serial.begin(9600);
sensors.begin();
sensors.setResolution(sensor1, 10);
sensors.setResolution(sensor2, 10);
// Localiza e mostra enderecos dos sensores
check_sensors();
}
void loop()
{
if (checkf){check_sensors();}
if(!sensors.getAddress(sensor1, 0)){Serial.println("Sensor 1 nao encontrado!"); s1f = false;}
else{
sensors.requestTemperatures();
temps1 = getTemp(sensor1);
Serial.print("Temp S1: ");
Serial.print(temps1);
Serial.print(" C");
Serial.println();
delay(1000);
}
if(!sensors.getAddress(sensor2, 0)){Serial.println("Sensor 2 nao encontrado!"); s2f = false;}
else{
sensors.requestTemperatures();
temps2 = getTemp(sensor2);
Serial.print("Temp S2: ");
Serial.print(temps2);
Serial.print(" C");
Serial.println();
Serial.println();
delay(500);
}
delay(500);
checkt = ++checkt;
if (checkt >= 10){checkf = true;}
}
void check_sensors() {
Serial.println("Localizando sensores DS18B20...");
Serial.print("Foram encontrados ");
Serial.print(sensors.getDeviceCount(), DEC);
Serial.println(" sensor(es).");
if (!sensors.getAddress(sensor1, 0)){
Serial.println("Sensor 1 nao encontrado!");
s1f = false;
}
if (!sensors.getAddress(sensor2, 0)){
Serial.println("Sensor 2 nao encontrado!");
s2f = false;}
// Mostra o endereco do sensor encontrado no barramento
Serial.print("Endereco sensor 1: ");
mostra_endereco_sensor(sensor1);
Serial.println();
Serial.print("Endereco sensor 2: ");
mostra_endereco_sensor(sensor2);
Serial.println();
Serial.println();
checkt = 0;
checkf = false;
}
void mostra_endereco_sensor(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
// Adiciona zeros se necessário
if (deviceAddress < 16) Serial.print("0");
_ Serial.print(deviceAddress*, HEX);_
_ }_
_}_
float getTemp (DeviceAddress deviceAddress){
_ sensors.requestTemperatures();_
_ temps = sensors.getTempC(deviceAddress);_
_ return temps;*_
}
Solved! The reason was that I was using the function getAddress with different devices, but same index.
getAddress(sensor1,0) and getAddress(sensor2,0) the correct should be getAddress(sensor2,1).
@discusshrimp, do not crosspost. Thread locked.