Reading from ds18b20

225 views
Skip to first unread message

Ian Henshaw

unread,
Apr 6, 2016, 4:20:50 PM4/6/16
to souliss
I'm trying to use a UNO with Ethernet Shield to read one or more ds18b20 's ,  Im not trying to do any Souliss Logic just read and report the Temperature so i can use openhab to poll Souliss,  Eventually i want also use the same board to do two outputs to drive a couple of relays, 

Does any one have any good Souliss  examples for ds18b20 ? ( i know the addresses of the devices im trying to use)

cheers

Ian

Fulvio Spelta

unread,
Apr 10, 2016, 9:03:22 AM4/10/16
to souliss
Hi, following some snippets that have to be added to your sketch:

#include <OneWire.h>
#include <DallasTemperature.h>

In setup function:

// Setup oneWire instance to handle the DS18B20 sensor
OneWire oneWire(1WIRE_BUS); //Pin that you'll use for the 1wire bus connection
DallasTemperature sensors(&oneWire);

// Define slot (remember that it requires 2 slot so the next availbale slot will be FST_TEMPERATURE_SLOT+2)
Set_Temperature(FST_TEMPERATURE_SLOT);

// Start up the DallasTemperature library
sensors.setWaitForConversion(false);
sensors.setResolution(12);
sensors.begin();



Runtime (loop function) i use a 90 sec asynchronous reading cycle: 1 cycle start temperature conversion, next cycle reading it

EXECUTESLOW() {
SLOW_90s() { 
if(ds18b20_RequestPhase) {
 sensors.requestTemperatures(); // Send the command to get temperatures
}
else {
// Read all temperatures for DS18B20
temperature = sensors.getTempCByIndex(0);
// Check for error or 85°C and skip them
if( temperature != DEVICE_DISCONNECTED && temperature != 85 ) {
// Read temperature value from sensor and convert from single-precision to half-precision
Souliss_ImportAnalog(memory_map, FST_TEMPERATURE_SLOT, &temperature);
Souliss_Logic_T52(memory_map, FST_TEMPERATURE_SLOT, 0, &data_changed);
}
}  
}  
ds18b20_RequestPhase = !ds18b20_RequestPhase;



This is just some snippet to show use how to preceed it isn't code for copy/paste/run


Juan Luis

unread,
Apr 12, 2016, 4:39:29 PM4/12/16
to souliss

Luckily I'm working in something like you need
In next Scketch are 5 Souliss Thermostat who uses 5 DS18B20 
I use Arduino Mega with Ethernet Shield working as a Gateway
As you can see I changed the number of Slots (by default 24).( Beacouse it uses 5 slots for each thermostat)





/**************************************************************************
    Souliss - Thermostat
    
    Control the heating or cooling using a temperature measure and a
    setpoint, based on the percentage distance from the setpoint runs the
    fans.
    
    The temperature measure is acquired through Souliss and available at the
    user interfaces as half-precision floating point. All calculation shall be 
    performed as standard floating point and at the end converted in half
    precision using :
        void Souliss_AnalogIn(U8 pin, U8 *memory_map, U8 slot, 
                                float scaling, float bias);
    
    Is suggested a scaling to the vRef of the AVR's ADC, using an external
    amplification circuit, in order to use the whole resolution.
    
    Run this code on one of the following boards:
      - Arduino Ethernet (W5100) 
      - Arduino with Ethernet Shield (W5100)
      
    As option you can run the same code on the following, just changing the
    relevant configuration file at begin of the sketch
      - Arduino with ENC28J60 Ethernet Shield
      - Arduino with W5200 Ethernet Shield
      - Arduino with W5500 Ethernet Shield
        
***************************************************************************/

// Let the IDE point to the Souliss framework
#include "SoulissFramework.h"


//Lets change number of nodes and slots defined in macaco.cgf 
# define MaCaco_NODESIZE_INSKETCH
# define MaCaco_NODES     30                        // Number of remote nodes
# define MaCaco_SLOT      35  



// Configure the framework
#include "bconf/StandardArduino.h"          // Use a standard Arduino
#include "conf/ethW5100.h"                  // Ethernet through Wiznet W5100
#include "conf/Gateway.h"                   // The main node is the Gateway, we have just one node
#include "conf/Webhook.h"                   // Enable DHCP and DNS

//1 wire libraries
#include <OneWire.h>
#include <DallasTemperature.h>

#include <EEPROM.h>

#define ONE_WIRE_BUS_1 8 //Data pin 1 wire

OneWire oneWire_in(ONE_WIRE_BUS_1);
DallasTemperature sensor_temp(&oneWire_in);

DeviceAddress addr_sensor1 = {0x28, 0xFF, 0x58, 0x84, 0x16, 0x14, 0x00, 0x78 };
DeviceAddress addr_sensor2=  {0x28, 0xFF, 0x5E, 0x3C, 0x17, 0x14, 0x00, 0xC2 };
DeviceAddress addr_sensor3=  {0x28, 0xFF, 0x51, 0x1B, 0x16, 0x14, 0x00, 0xF0 };
DeviceAddress addr_sensor4=  {0x28, 0xFF, 0xB9, 0x0D, 0x17, 0x14, 0x00, 0x8E };
DeviceAddress addr_sensor5=  {0x28, 0xFF, 0x17, 0x58, 0x16, 0x14, 0x00, 0xED };

// Include framework code and libraries
#include <SPI.h>

/*** All configuration includes should be above this line ***/ 
#include "Souliss.h"

#define slot_temp1               0            // This is the memory slot used for the execution of the logic sensor1
#define slot_temp2               5            // This is the memory slot used for the execution of the logic sensor2
#define slot_temp3               10           // This is the memory slot used for the execution of the logic sensor3
#define slot_temp4               15           // This is the memory slot used for the execution of the logic sensor4
#define slot_temp5               20           // This is the memory slot used for the execution of the logic sensor5

//Possition in EEPROM for save setpoint
#define setpoint1_EEPROM 0
#define setpoint2_EEPROM 4
#define setpoint3_EEPROM 8
#define setpoint4_EEPROM 12
#define setpoint5_EEPROM 16



#define DEADBAND                0.05        // Deadband value 5%  


            // Define the network configuration according to your router settings
            uint8_t ip_address[4]  = {192, 168, 1, 176};
            uint8_t subnet_mask[4] = {255, 255, 255, 0};
            uint8_t ip_gateway[4]  = {192, 168, 1, 1};
            #define myvNet_address  ip_address[3]       // The last byte of the IP address (176) is also th

void setup()
{   
    Initialize();

    // Get the IP address from DHCP
    //GetIPAddress();                   
    //SetAsGateway(myvNet_dhcp);          // Set this node as gateway for SoulissApp  
    
                  SetIPAddress(ip_address, subnet_mask, ip_gateway);
                  SetAsGateway(myvNet_address);
                     

   sensor_temp.begin(); //initialize library DS18B20

   sensor_temp.setResolution(addr_sensor1, 10); // DS18B20 resolution 10 bits
   sensor_temp.setResolution(addr_sensor2, 10); //DS18B20 resolution
   sensor_temp.setResolution(addr_sensor3, 10); //DS18B20 resolution
   sensor_temp.setResolution(addr_sensor4, 10); //DS18B20 resolution
   sensor_temp.setResolution(addr_sensor5, 10); //DS18B20 resolution
    
    Set_Thermostat(slot_temp1);          // Set a logic for the sonda1
    Set_Thermostat(slot_temp2);          // Set a logic for the sonda1
    Set_Thermostat(slot_temp3);          // Set a logic for the sonda1
    Set_Thermostat(slot_temp4);          // Set a logic for the sonda1
    Set_Thermostat(slot_temp5);          // Set a logic for the sonda1

    //TO-DO here I will recover setpoint from EEPROM   
    
    // Define output pins
    pinMode(2, OUTPUT);     // Heater (ON/OFF)
    pinMode(3, OUTPUT);     // Fan 1
    pinMode(4, OUTPUT);     // Fan 2
    pinMode(5, OUTPUT);     // Fan 3
}

void loop()
    // Here we start to play
    EXECUTEFAST() {                     
        UPDATEFAST();   
        
        // Execute the code every 11 time_base_fast       
        FAST_110ms() {  
            // The logic is executed faster than the data acquisition just to have a 
            // prompt answer to the user commands, but the real rate is defined by
            // the temperature measure rate.
        
            // Compare the setpoint from the user interface with the measured temperature
            Logic_Thermostat(slot_temp1);
            Logic_Thermostat(slot_temp2);
            Logic_Thermostat(slot_temp3);
            Logic_Thermostat(slot_temp4);
            Logic_Thermostat(slot_temp5);
            
            // Start the heater and the fans
            nDigOut(2, Souliss_T3n_HeatingOn, slot_temp1);   // Heater
            nDigOut(3, Souliss_T3n_FanOn1   , slot_temp1);   // Fan1
            nDigOut(4, Souliss_T3n_FanOn2   , slot_temp1);   // Fan2
            nDigOut(5, Souliss_T3n_FanOn3   , slot_temp1);   // Fan3

            //TO-DO here I will work with the rest of slot_temp's
            
            
            // We are not handling the cooling mode, if enabled by the user, force it back
            // to disable
            if(mOutput(slot_temp1) & Souliss_T3n_CoolingOn)
                mOutput(slot_temp1) &= ~Souliss_T3n_CoolingOn;
        }
        
        // Execute the code every 101 time_base_fast          
        FAST_910ms()    {
            sensor_temp.requestTemperatures(); // Send the command to get temperatures
                                                         //float read_temp = sensor_temp.getTempCByIndex(0);//lee temperatura desde el sensor
            float read_temp = sensor_temp.getTempC(addr_sensor1);//lee temperatura desde el sensor1
            ImportAnalog(slot_temp1+1, &read_temp);//convierte temperatura de doble precision a simple precision

            read_temp = sensor_temp.getTempC(addr_sensor2);//lee temperatura desde el sensor1
            ImportAnalog(slot_temp2+1, &read_temp);//convierte temperatura de doble precision a simple precision

            read_temp = sensor_temp.getTempC(addr_sensor3);//lee temperatura desde el sensor1
            ImportAnalog(slot_temp3+1, &read_temp);//convierte temperatura de doble precision a simple precision

            read_temp = sensor_temp.getTempC(addr_sensor4);//lee temperatura desde el sensor1
            ImportAnalog(slot_temp4+1, &read_temp);//convierte temperatura de doble precision a simple precision

            read_temp = sensor_temp.getTempC(addr_sensor5);//lee temperatura desde el sensor1
            ImportAnalog(slot_temp5+1, &read_temp);//convierte temperatura de doble precision a simple precision
        
            // Acquire temperature from the microcontroller ADC
           // AnalogIn(A0, slot_temp1+1, 0.04, -10); // The raw data is 0-1024, scaled as -10 to +30 Celsius
        
        
        
        }   

          //if changed save to eeprom setpoint
        FAST_9110ms()
        {
          //here I will save setpoint to EEPROM

          
        }
        
        // Process data communication
        FAST_GatewayComms();
    }       
}

Fulvio Spelta

unread,
Apr 26, 2016, 4:17:12 AM4/26/16
to souliss
Hi, just 2 comments.

First: Reading temperatures values every 910ms i think it's a too high frequency (temperatures usually don't change so rapidly). I suggest to read them once a minute or less.

Second: I suggest to check the return value for communications errors (sometimes I find this kind of errors especially using long wiring)
The test that (in my experience) has canceled bad values is this:
if( temperature != DEVICE_DISCONNECTED && temperature != 85 )
(first test comes from documentation and the second from direct experience)
Reply all
Reply to author
Forward
0 new messages