Hello and Meery christmas for all users
I'm working in a project based on a RS485 BUS to read one-wire temperature sensors(DALLAS DS18B20).I develop a library that handle the comunication from the master (PC) and the slaves.I develop some small boards with all I need on the slaves to read the temperature from the sensor.When I start the test the hardware I notice that each slave takes to long to deliver me the response after invoked, it take about 780ms which is to much, if I have a lot of slaves on the BUS .After reading the datasheet from the dallas DS18B20 it´s mentioned that the sensor in fact takes this time to make the convertion and put the correct value on the scrathpad.
I was thinking on implement a schedule 30 seconds in programming inside the slaves to get the current temperature and store it in a tempFloat variable, so when the slave is invoked it repply the tempFloat variable but even this soluction is far away of be perfect.
I was also thinking on interrupts but I have no clue how can I trigger the interrupt if possible.
Can someone give a opinion how can I minimize this behavior
IIRC those sensors need ~750mS to take a reading, so that's where your delay is.
The solution is simple and I think you have already found it, the slaves constantly take readings and save the last one in a variable, when asked that value is ready instantly and that's what you provide.
but even this solution is far away of be perfect.
Why. Apart from being the only solution I can see it's also a good one.
I was also thinking on interrupts
Interrupts will not help here, the problem is in the sensor delay.
EDIT: I can see no reason to use a float BTW, the sensor provides a signed int.
Graynomad:
The solution is simple and I think you have already found it, the slaves constantly take readings and save the last one in a variable, when asked that value is ready instantly and that's what you provide.
...with a timestamp or age so the master can tell if the data has become stale.
but even this solution is far away of be perfect.
Why. Apart from being the only solution I can see it's also a good one.
Well it could happen some times when the master invoke the slave the slave is doing the convertion and so the master still be delayed for the answer.
I will set the sensor to a 9 bit resolution to get a less conversion time( around 100ms) instead of 12 bits by default. Also I will create a scheduler to get the temperature every minute.
EDIT: I can see no reason to use a float BTW, the sensor provides a signed int.
I want to know the decimal parts of the temperature.
There is no reason that the slave cannot respond while waiting for conversion, unless you're using blocking or delays. The DallasTemperature library offers you options in this regard - you can have the library block for you, or you can request temperatures and manage the 750ms time taken before the temp is ready yourself.
You can do the same in your code - request conversion and keep looking for requests from the master. After conversion is done, update your temp variable. Thus you can always respond with a (fairly) up to date temp.
In my code I'm not using delays so I presume it's delayed inside the library I guess.
Here is my code:
#include "RS485.h"
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 4 //Data wire is plugged into port 4 on the microcontroller
float temperatureInCelsius; //Variable to store the current Temperature readed from DS18B20
OneWire oneWire(ONE_WIRE_BUS); //Setup a oneWire instance
DallasTemperature tempSensor(&oneWire); //Pass our oneWire reference to Dallas Temperature.
RS485 bus; //Create RS485 instance object
void setup()
{
Serial.begin(9600);
tempSensor.begin();
bus.begin(3,3); //Device address and hardware pin connected to MAX485 enable Pins 2 and 3
bus.rxMode(); //Set de Bus on receive mode
}
void loop()
{
bus.listen();
temperatureProcess();
}
void temperatureProcess(){
tempSensor.requestTemperatures(); // Request tempSensor his value
temperatureInCelsius=tempSensor.getTempCByIndex(0);
bus.passFloat(temperatureInCelsius);
}
The DallasTemperature library offers you options in this regard - you can have the library block for you, or you can request temperatures and manage the 750ms time taken before the temp is ready yourself.
I want to know the decimal parts of the temperature.
The sensor doesn't produce data in a float format, so how does converting to float help?
The data returned by the sensor is only good to .5 degree and that fraction is represented by the lowest bit. So
x = get_temp_from_sensor();
Serial.print (x >> 1); //print the degrees
Serial.print ('.');
Serial.print ((x & 1) ? '5' : '0'); //print the fraction
No need for a float.
EDIT:
I guess that getTempCByIndex() returns a float so you may as well stick with it, but I hate to see resources wasted when it's not necessary. To pull in the float library for this is silly.