Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #121 from foogod/ds18b20-updates
DS18B20 API Improvements
  • Loading branch information
projectgus committed Apr 6, 2016
2 parents 4adddc2 + 494c2d9 commit 83c5f91
Show file tree
Hide file tree
Showing 6 changed files with 862 additions and 515 deletions.
20 changes: 8 additions & 12 deletions examples/ds18b20_broadcaster/ds18b20_broadcaster.c
Expand Up @@ -19,15 +19,14 @@

// DS18B20 driver
#include "ds18b20/ds18b20.h"
// Onewire init
#include "onewire/onewire.h"

void broadcast_temperature(void *pvParameters)
{

uint8_t amount = 0;
uint8_t sensors = 2;
ds_sensor_t t[sensors];
uint8_t sensors = 1;
ds18b20_addr_t addrs[sensors];
float results[sensors];

// Use GPIO 13 as one wire pin.
uint8_t GPIO_FOR_ONE_WIRE = 13;
Expand All @@ -36,8 +35,6 @@ void broadcast_temperature(void *pvParameters)

// Broadcaster part
err_t err;
// Initialize one wire bus.
onewire_init(GPIO_FOR_ONE_WIRE);

while(1) {

Expand Down Expand Up @@ -66,18 +63,17 @@ void broadcast_temperature(void *pvParameters)

for(;;) {
// Search all DS18B20, return its amount and feed 't' structure with result data.
amount = ds18b20_read_all(GPIO_FOR_ONE_WIRE, t);
amount = ds18b20_scan_devices(GPIO_FOR_ONE_WIRE, addrs, sensors);

if (amount < sensors){
printf("Something is wrong, I expect to see %d sensors \nbut just %d was detected!\n", sensors, amount);
}

for (int i = 0; i < amount; ++i)
ds18b20_measure_and_read_multi(GPIO_FOR_ONE_WIRE, addrs, sensors, results);
for (int i = 0; i < sensors; ++i)
{
int intpart = (int)t[i].value;
int fraction = (int)((t[i].value - intpart) * 100);
// Multiple "" here is just to satisfy compiler and don`t raise 'hex escape sequence out of range' warning.
sprintf(msg, "Sensor %d report: %d.%02d ""\xC2""\xB0""C\n",t[i].id, intpart, fraction);
// ("\xC2\xB0" is the degree character (U+00B0) in UTF-8)
sprintf(msg, "Sensor %08x%08x reports: %f \xC2\xB0""C\n", (uint32_t)(addrs[i] >> 32), (uint32_t)addrs[i], results[i]);
printf("%s", msg);

struct netbuf* buf = netbuf_new();
Expand Down
93 changes: 56 additions & 37 deletions examples/ds18b20_onewire/ds18b20_onewire.c
@@ -1,59 +1,78 @@
/* ds18b20 - Retrieves temperature from ds18b20 sensors and print it out.
/* ds18b20_onewire.c - Retrieves readings from one or more DS18B20 temperature
* sensors, and prints the results to stdout.
*
* This sample code is in the public domain.,
*/
#include "espressif/esp_common.h"
#include "esp/uart.h"

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "queue.h"
#include "esp/uart.h"

// DS18B20 driver
#include "ds18b20/ds18b20.h"
// Onewire init
#include "onewire/onewire.h"

void print_temperature(void *pvParameters)
{
int delay = 500;
uint8_t amount = 0;
// Declare amount of sensors
uint8_t sensors = 2;
ds_sensor_t t[sensors];

// Use GPIO 13 as one wire pin.
uint8_t GPIO_FOR_ONE_WIRE = 13;

onewire_init(GPIO_FOR_ONE_WIRE);
#define SENSOR_GPIO 13
#define MAX_SENSORS 8
#define RESCAN_INTERVAL 8
#define LOOP_DELAY_MS 250

void print_temperature(void *pvParameters) {
ds18b20_addr_t addrs[MAX_SENSORS];
float temps[MAX_SENSORS];
int sensor_count;

// There is no special initialization required before using the ds18b20
// routines. However, we make sure that the internal pull-up resistor is
// enabled on the GPIO pin so that one can connect up a sensor without
// needing an external pull-up (Note: The internal (~47k) pull-ups of the
// ESP8266 do appear to work, at least for simple setups (one or two sensors
// connected with short leads), but do not technically meet the pull-up
// requirements from the DS18B20 datasheet and may not always be reliable.
// For a real application, a proper 4.7k external pull-up resistor is
// recommended instead!)

gpio_set_pullup(SENSOR_GPIO, true, true);

while(1) {
// Search all DS18B20, return its amount and feed 't' structure with result data.
amount = ds18b20_read_all(GPIO_FOR_ONE_WIRE, t);
// Every RESCAN_INTERVAL samples, check to see if the sensors connected
// to our bus have changed.
sensor_count = ds18b20_scan_devices(SENSOR_GPIO, addrs, MAX_SENSORS);

if (amount < sensors){
printf("Something is wrong, I expect to see %d sensors \nbut just %d was detected!\n", sensors, amount);
}
if (sensor_count < 1) {
printf("\nNo sensors detected!\n");
} else {
printf("\n%d sensors detected:\n", sensor_count);
// If there were more sensors found than we have space to handle,
// just report the first MAX_SENSORS..
if (sensor_count > MAX_SENSORS) sensor_count = MAX_SENSORS;

for (int i = 0; i < amount; ++i)
{
int intpart = (int)t[i].value;
int fraction = (int)((t[i].value - intpart) * 100);
// Multiple "" here is just to satisfy compiler and don`t raise 'hex escape sequence out of range' warning.
printf("Sensor %d report: %d.%02d ""\xC2""\xB0""C\n",t[i].id, intpart, fraction);
// Do a number of temperature samples, and print the results.
for (int i = 0; i < RESCAN_INTERVAL; i++) {
ds18b20_measure_and_read_multi(SENSOR_GPIO, addrs, sensor_count, temps);
for (int j = 0; j < sensor_count; j++) {
// The DS18B20 address is a 64-bit integer, but newlib-nano
// printf does not support printing 64-bit values, so we
// split it up into two 32-bit integers and print them
// back-to-back to make it look like one big hex number.
uint32_t addr0 = addrs[j] >> 32;
uint32_t addr1 = addrs[j];
float temp_c = temps[j];
float temp_f = (temp_c * 1.8) + 32;
printf(" Sensor %08x%08x reports %f deg C (%f deg F)\n", addr0, addr1, temp_c, temp_f);
}
printf("\n");

// Wait for a little bit between each sample (note that the
// ds18b20_measure_and_read_multi operation already takes at
// least 750ms to run, so this is on top of that delay).
vTaskDelay(LOOP_DELAY_MS / portTICK_RATE_MS);
}
}
printf("\n");
vTaskDelay(delay / portTICK_RATE_MS);
}
}

void user_init(void)
{
void user_init(void) {
uart_set_baud(0, 115200);

printf("SDK version:%s\n", sdk_system_get_sdk_version());

xTaskCreate(&print_temperature, (signed char *)"print_temperature", 256, NULL, 2, NULL);
}

167 changes: 141 additions & 26 deletions extras/ds18b20/ds18b20.c
@@ -1,43 +1,47 @@
#include "FreeRTOS.h"
#include "task.h"
#include "math.h"

#include "onewire/onewire.h"
#include "ds18b20.h"

#define DS1820_WRITE_SCRATCHPAD 0x4E
#define DS1820_READ_SCRATCHPAD 0xBE
#define DS1820_COPY_SCRATCHPAD 0x48
#define DS1820_READ_EEPROM 0xB8
#define DS1820_READ_PWRSUPPLY 0xB4
#define DS1820_SEARCHROM 0xF0
#define DS1820_SKIP_ROM 0xCC
#define DS1820_READROM 0x33
#define DS1820_MATCHROM 0x55
#define DS1820_ALARMSEARCH 0xEC
#define DS1820_CONVERT_T 0x44
#define DS18B20_WRITE_SCRATCHPAD 0x4E
#define DS18B20_READ_SCRATCHPAD 0xBE
#define DS18B20_COPY_SCRATCHPAD 0x48
#define DS18B20_READ_EEPROM 0xB8
#define DS18B20_READ_PWRSUPPLY 0xB4
#define DS18B20_SEARCHROM 0xF0
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_READROM 0x33
#define DS18B20_MATCHROM 0x55
#define DS18B20_ALARMSEARCH 0xEC
#define DS18B20_CONVERT_T 0x44

#define os_sleep_ms(x) vTaskDelay(((x) + portTICK_RATE_MS - 1) / portTICK_RATE_MS)

uint8_t ds18b20_read_all(uint8_t pin, ds_sensor_t *result) {

uint8_t addr[8];
onewire_addr_t addr;
onewire_search_t search;
uint8_t sensor_id = 0;
onewire_reset_search(pin);

onewire_search_start(&search);

while(onewire_search(pin, addr)){
uint8_t crc = onewire_crc8(addr, 7);
if (crc != addr[7]){
printf("CRC check failed: %02X %02X\n", addr[7], crc);
while ((addr = onewire_search_next(&search, pin)) != ONEWIRE_NONE) {
uint8_t crc = onewire_crc8((uint8_t *)&addr, 7);
if (crc != (addr >> 56)){
printf("CRC check failed: %02X %02X\n", (unsigned)(addr >> 56), crc);
return 0;
}

onewire_reset(pin);
onewire_select(pin, addr);
onewire_write(pin, DS1820_CONVERT_T, ONEWIRE_DEFAULT_POWER);
onewire_write(pin, DS18B20_CONVERT_T);

onewire_power(pin);
vTaskDelay(750 / portTICK_RATE_MS);

onewire_reset(pin);
onewire_select(pin, addr);
onewire_write(pin, DS1820_READ_SCRATCHPAD, ONEWIRE_DEFAULT_POWER);
onewire_write(pin, DS18B20_READ_SCRATCHPAD);

uint8_t get[10];

Expand Down Expand Up @@ -71,15 +75,15 @@ uint8_t ds18b20_read_all(uint8_t pin, ds_sensor_t *result) {
float ds18b20_read_single(uint8_t pin) {

onewire_reset(pin);
onewire_skip_rom(pin);
onewire_write(pin, DS18B20_CONVERT_T);

onewire_write(pin, DS1820_SKIP_ROM, ONEWIRE_DEFAULT_POWER);
onewire_write(pin, DS1820_CONVERT_T, ONEWIRE_DEFAULT_POWER);

onewire_power(pin);
vTaskDelay(750 / portTICK_RATE_MS);

onewire_reset(pin);
onewire_write(pin, DS1820_SKIP_ROM, ONEWIRE_DEFAULT_POWER);
onewire_write(pin, DS1820_READ_SCRATCHPAD, ONEWIRE_DEFAULT_POWER);
onewire_skip_rom(pin);
onewire_write(pin, DS18B20_READ_SCRATCHPAD);

uint8_t get[10];

Expand All @@ -106,3 +110,114 @@ float ds18b20_read_single(uint8_t pin) {
return temperature;
//printf("Got a DS18B20 Reading: %d.%02d\n", (int)temperature, (int)(temperature - (int)temperature) * 100);
}

bool ds18b20_measure(int pin, ds18b20_addr_t addr, bool wait) {
if (!onewire_reset(pin)) {
return false;
}
if (addr == DS18B20_ANY) {
onewire_skip_rom(pin);
} else {
onewire_select(pin, addr);
}
taskENTER_CRITICAL();
onewire_write(pin, DS18B20_CONVERT_T);
// For parasitic devices, power must be applied within 10us after issuing
// the convert command.
onewire_power(pin);
taskEXIT_CRITICAL();

if (wait) {
os_sleep_ms(750);
onewire_depower(pin);
}

return true;
}

bool ds18b20_read_scratchpad(int pin, ds18b20_addr_t addr, uint8_t *buffer) {
uint8_t crc;
uint8_t expected_crc;

if (!onewire_reset(pin)) {
return false;
}
if (addr == DS18B20_ANY) {
onewire_skip_rom(pin);
} else {
onewire_select(pin, addr);
}
onewire_write(pin, DS18B20_READ_SCRATCHPAD);

for (int i = 0; i < 8; i++) {
buffer[i] = onewire_read(pin);
}
crc = onewire_read(pin);

expected_crc = onewire_crc8(buffer, 8);
if (crc != expected_crc) {
printf("CRC check failed reading scratchpad: %02x %02x %02x %02x %02x %02x %02x %02x : %02x (expected %02x)\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5], buffer[6], buffer[7], crc, expected_crc);
return false;
}

return true;
}

float ds18b20_read_temperature(int pin, ds18b20_addr_t addr) {
uint8_t scratchpad[8];
int temp;

if (!ds18b20_read_scratchpad(pin, addr, scratchpad)) {
return NAN;
}

temp = scratchpad[1] << 8 | scratchpad[0];

return ((float)temp * 625.0)/10000;
}

float ds18b20_measure_and_read(int pin, ds18b20_addr_t addr) {
if (!ds18b20_measure(pin, addr, true)) {
return NAN;
}
return ds18b20_read_temperature(pin, addr);
}

bool ds18b20_measure_and_read_multi(int pin, ds18b20_addr_t *addr_list, int addr_count, float *result_list) {
if (!ds18b20_measure(pin, DS18B20_ANY, true)) {
for (int i=0; i < addr_count; i++) {
result_list[i] = NAN;
}
return false;
}
return ds18b20_read_temp_multi(pin, addr_list, addr_count, result_list);
}

int ds18b20_scan_devices(int pin, ds18b20_addr_t *addr_list, int addr_count) {
onewire_search_t search;
onewire_addr_t addr;
int found = 0;

onewire_search_start(&search);
while ((addr = onewire_search_next(&search, pin)) != ONEWIRE_NONE) {
if (found < addr_count) {
addr_list[found] = addr;
}
found++;
}
return found;
}

bool ds18b20_read_temp_multi(int pin, ds18b20_addr_t *addr_list, int addr_count, float *result_list) {
bool result = true;

for (int i = 0; i < addr_count; i++) {
result_list[i] = ds18b20_read_temperature(pin, addr_list[i]);
if (isnan(result_list[i])) {
result = false;
}
}
return result;
}


0 comments on commit 83c5f91

Please sign in to comment.