// https://wokwi.com/projects/411353543794137089
// modified from https://wokwi.com/projects/395145162627749889
// Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/DS18B20.pdf
// Comparison: https://www.analog.com/en/resources/design-notes/1wire-protocol-pdf-of-ds18s20-vs-ds18b20-digital-themormeters.html
// DallasTemperature.h https://github.com/milesburton/Arduino-Temperature-Control-Library
// WokwiChip: https://github.com/bonnyr/wokwi-ds1820-custom-chip
/*
PROGRAM:
Name Add_tempsensor.ino
Version: 02d
Author: C.W.A. Baltus
Created: 8-12-2021
Edited by: C.W.A. Baltus
Modified: 22-12-2021
WHAT DOES THIS PROGRAM:
Stores the adresses of 4 pieces of temperaturesensors DS18b20 in an EEPROM (on board of Arduino) in the same order as the sensors step by step are added.
It takes 4 * 8 bytes = 32 bytes; the Nano can contain 512 bytes.
Afterwords the addresses can be read out and assigned to byte arrays:
adrTcvForth[8] (uint8_t)
adrTcvBack[8]
adrTvvForth[8]
adrTvvBack[8]
HARDWARE:
- Arduino Nano V3
- LCD 2004 with I2C-interface (SDA pin A4, SCL pin A5)
- 4 pieces 1 wire temperature sensors Dallas DS1620b20 (pin D12, with pullup resistor 4k7)
TESTED ON:
IDE 1.8.16 and Arduino Nano
Tutorials:
http://www.hacktronics.com/Tutorials/arduino-1-wire-address-finder.html
https://www.pjrc.com/teensy/td_libs_OneWire.html
*/
//========================================================================
//Libraries
#include <DallasTemperature.h> // https://github.com/milesburton/Arduino-Temperature-Control-Library
#include <EEPROM.h>
//#include <LCD.h>
//#include <LiquidCrystal_I2C.h> // Source: LiquidCrystal_V1.2.1.zip
#include <OneWire.h>
#include <Wire.h>
#include <hd44780.h> // #include <hd44780ioClass/hd44780_I2Cexp.h> // i2c LCD i/o class header
#include <hd44780ioClass/hd44780_I2Cexp.h> // i2c LCD i/o class header
hd44780_I2Cexp lcd;
// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 2
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
// variable to hold device addresses
DeviceAddress Thermometer;
int deviceCount = 0;
//Define global parameters
byte i; //position within arraybye
byte j = 0; //Number of ds passed
uint8_t adrTcvForward[8];
uint8_t adrTcvBack[8];
uint8_t adrTvvForward[8];
uint8_t adrTvvBack[8];
String myString;
const byte invordering[] = {7, 3, 1, 5, 0, 4, 2, 6};
const byte ordering[] = {4, 2, 6, 1, 5, 3, 7, 0};
int status;
//========================================================================
void setup(void) {
Serial.begin(11520);
status = lcd.begin(20, 4);
if (status) // non zero status means it was unsuccesful
{
// hd44780 has a fatalError() routine that blinks an led if possible
// begin() failed so blink error code using the onboard LED if possible
hd44780::fatalError(status); // does not return
}
setupDallas(); // from https://lastminuteengineers.com/multiple-ds18b20-arduino-tutorial/
} //End setup
//========================================================================
void loop(void) {
//Nothing to do
uint32_t t0 = micros();
if(loopDallasRead()){
uint32_t t1 = micros();
Serial.println(t1-t0);
}
} //End loop
// void setupOtherDS() {
// //This call has to be moved to a control menu (so it will be executed once)
// Identify_1WireDevices();
// delay (1000);
// //Assign a bytearray once to adrTcvForth
// for (int i = 0; i < 8; i++) {
// adrTcvForward[i] = EEPROM.read(100 + i);
// }
// for (int i = 0; i < 8; i++) {
// adrTcvBack[i] = EEPROM.read(108 + i);
// }
// for (int i = 0; i < 8; i++) {
// adrTvvForward[i] = EEPROM.read(116 + i);
// }
// for (int i = 0; i < 8; i++) {
// adrTvvBack[i] = EEPROM.read(124 + i);
// }
// //Check addresses on serial monitor
// Serial.println("");
// Serial.print("Adres sensor1 = "); printAddress(adrTcvForward);
// Serial.print("Adres sensor2 = "); printAddress(adrTcvBack);
// Serial.print("Adres sensor3 = "); printAddress(adrTvvForward);
// Serial.print("Adres sensor4 = "); printAddress(adrTvvBack);
// }
// //========================================================================
// void Identify_1WireDevices(void) {
// boolean blnExists;
// byte addr[8];
// byte addr1[8];
// byte addr2[8];
// byte addr3[8];
// byte addr4[8];
// int intSensorsPassed = 0;
// Serial.print("Looking for 1-Wire devices...\n\r");
// lcd.clear(); lcd.print ("Connect sensor 1");
// do { //Should be done 4 times
// while (ds.search(addr))
// {
// //printAddress(addr);
// if ( OneWire::crc8( addr, 7) != addr[7]) {
// Serial.print("CRC is not valid!\n");
// delay (100);
// break;
// }
// if (addr[0] != 0x10) {
// Serial.print(addr[0], HEX);
// Serial.println (" Not a DS18b20"); //The least significant byte of the DS18b20 should be 0x28
// break;
// }
// switch (intSensorsPassed) {
// case 0:
// memcpy (addr1, addr, 8); //Store the first addres in addr1
// intSensorsPassed++;
// Serial.print ("Assigned to " + String(intSensorsPassed) + ": "); printAddress(addr1); cr();
// Serial.println ("Sensors passed = " + String(intSensorsPassed) + "\n");
// lcd.setCursor(0, intSensorsPassed); lcd.print ("Add sensor " + String(intSensorsPassed + 1));
// break;
// case 1:
// //check if the address was earlier identified
// //Serial.println("\nIncoming address = "); printAddress(addr);
// if (memcmp(addr1, addr, 8) != 0) {
// //Serial.println("Unknown sensor found"); //Seems to be another (new) address
// memcpy (addr2, addr, 8); //Store the addess in addr2
// intSensorsPassed++;
// Serial.print ("Assigned to " + String(intSensorsPassed) + ": "); printAddress(addr2); cr();
// Serial.println ("Sensors passed = " + String(intSensorsPassed) + "\n");
// lcd.setCursor(0, intSensorsPassed); lcd.print ("Add sensor " + String(intSensorsPassed + 1));
// } //End if
// break;
// case 2:
// //check if the address was earlier identified
// if ((memcmp(addr, addr1, 8) != 0) && (memcmp(addr, addr2, 8) != 0)) {
// //Serial.println("Unknown sensor found"); //Seems to be another (new) address
// memcpy (addr3, addr, 8); //Copy the addess to addr3
// intSensorsPassed++;
// Serial.print ("Assigned to " + String(intSensorsPassed) + ": "); printAddress(addr3); cr();
// Serial.println ("Sensors passed = " + String(intSensorsPassed) + "\n");
// lcd.setCursor(0, intSensorsPassed); lcd.print ("Add sensor " + String(intSensorsPassed + 1));
// } //End if
// break;
// case 3:
// //check if the address was earlier identified
// if ((memcmp(addr, addr1, 8) != 0) && (memcmp(addr, addr2, 8) != 0) && (memcmp(addr, addr3, 8) != 0) ) {
// //Serial.println("Unknown sensor found"); //Seems to be another (new) address
// memcpy (addr4, addr, 8); //Copy the addess to addr4
// //printAddress(addr); Serial.print("\n");
// intSensorsPassed++;
// Serial.print ("Assigned to " + String(intSensorsPassed) + ": "); printAddress(addr4); cr();
// Serial.println ("Sensors passed = " + String(intSensorsPassed) + "\n");
// } //End if
// break;
// } //End switch
// } //End while sensors Passed
// delay (500);
// } while (intSensorsPassed < 4);
// //Store the detected addresses in EEPROM
// for ( i = 0; i < 8; i++)
// {
// EEPROM.write( (100 + i), addr1[i] );
// EEPROM.write( (108 + i), addr2[i] );
// EEPROM.write( (116 + i), addr3[i] );
// EEPROM.write( (124 + i), addr4[i] );
// }
// Serial.print("\n\nThat's it.");
// } //End function
// //================================================================================================================
// void printAddress(uint8_t temp2[]) {
// int i;
// for ( i = 0; i < 8; i++) {
// Serial.print("0x"); //Starting with the least significant byte
// if (temp2[i] < 16) {
// Serial.print('0'); //print a prevealing zero if necessary
// }
// Serial.print(temp2[i], HEX); ;
// if (i < 7)
// {
// Serial.print(", "); //print a separator between all bytes
// }
// } //End for loop
// Serial.print("\n");
// } //End subroutine
// //================================================================================================================
// void cr()
// {
// Serial.println("\n");
// }
void setupDallas(void)
{
// from https://lastminuteengineers.com/multiple-ds18b20-arduino-tutorial/
// Start up the library
sensors.begin();
// locate devices on the bus
Serial.println("Locating devices...");
Serial.print("Found ");
deviceCount = sensors.getDeviceCount();
Serial.print(deviceCount, DEC);
Serial.println(" devices.");
Serial.println("");
Serial.println("Printing addresses...");
for (int i = 0; i < deviceCount; i++)
{
Serial.print("Sensor ");
Serial.print(i + 1);
Serial.print(" : ");
sensors.getAddress(Thermometer, i);
printAddress(Thermometer);
}
}
// void loop(void)
// {}
void printAddress(DeviceAddress deviceAddress)
{
for (uint8_t i = 0; i < 8; i++)
{
Serial.print("0x");
if (deviceAddress[i] < 0x10) Serial.print("0");
Serial.print(deviceAddress[i], HEX);
if (i < 7) Serial.print(", ");
}
Serial.println("");
}
bool loopDallasRead(void)
{
bool retval = false;
const uint32_t interval = 1000;
static uint32_t last = -interval;
uint32_t now = millis();
if (now - last >= interval) {
last+= interval;
// Send command to all the sensors for temperature conversion
sensors.requestTemperatures();
// Display temperature from each sensor
for (int i = 0; i < deviceCount/4; i++)
{
byte jj = ordering[i]; // lookup logical sensor(physpos)
float tempC;
Serial.print("S");
Serial.print(i + 1);
Serial.print(":");
tempC = sensors.getTempCByIndex(jj);
Serial.print(tempC);
Serial.print(" ");
//lcd.setCursor(10 * (i & 1 ), i / 2);
//lcd.print(i + 1); lcd.print(':'); lcd.print(tempC, 3);
//lcd.print(" ");
}
Serial.println();
retval = true;
}
return retval;
}
1-5 are diagram.json waveForm controlled || 6-8 click-to-adjust.