add DS18B20 temperature sensor library from thermo-regulator project
This commit is contained in:
parent
48ac76bc02
commit
75658c2c1a
196
lib/sensor_ds18b20.c
Normal file
196
lib/sensor_ds18b20.c
Normal file
@ -0,0 +1,196 @@
|
||||
/* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
/** library for Maxim DS18B20 digital temperature sensor (using 1-Wire protocol) (code)
|
||||
* @file sensor_ds18b20.c
|
||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @date 2017
|
||||
* @note peripherals used: 1-Wire (timer @ref onewire_master_timer, GPIO @ref onewire_master_gpio)
|
||||
* @warning this library does not support parasite power mode and alarms
|
||||
*/
|
||||
/* standard libraries */
|
||||
#include <stdint.h> // standard integer types
|
||||
#include <stdbool.h> // boolean type
|
||||
#include <stdlib.h> // size_t definition
|
||||
#include <math.h> // NAN definition
|
||||
|
||||
/* own libraries */
|
||||
#include "global.h" // help macros
|
||||
#include "onewire_master.h" // 1-Wire utilities
|
||||
#include "sensor_ds18b20.h" // own definitions
|
||||
|
||||
/** remember number of DS18B20 sensors on 1-Wire bus for certain functions */
|
||||
uint64_t sensors = 0;
|
||||
/** remember if only DS18B20 sensors on 1-Wire bus for certain functions */
|
||||
bool only = false;
|
||||
/** remember code of last sensor **/
|
||||
uint64_t last = 0;
|
||||
|
||||
void sensor_ds18b20_setup(void)
|
||||
{
|
||||
onewire_master_setup(); // setup 1-Wire peripheral to communicate with sensors on bus
|
||||
sensor_ds18b20_number(); // scan for sensor (remembers sensor number and exclusivity)
|
||||
}
|
||||
|
||||
uint64_t sensor_ds18b20_number(void)
|
||||
{
|
||||
sensors = 0; // reset number
|
||||
only = true; // reset state
|
||||
uint64_t code = 0; // ROM code found (use 0 to start from scratch)
|
||||
bool more = true; // save if other additional slaves exist
|
||||
|
||||
while (more) { // scan for all 1-Wire slaves
|
||||
if (!onewire_master_reset()) { // send reset to start communication
|
||||
return 0; // no slave presence detected
|
||||
}
|
||||
more = onewire_master_rom_search(&code, false); // get next slave ROM code (without alarm)
|
||||
if (0==code) { // error occurred
|
||||
return 0;
|
||||
}
|
||||
if (0x28==(code&0xff)) { // family code (8-LSb) for DS18B20 sensors is 0x28
|
||||
last = code; // save last found code
|
||||
sensors++; // we found an additional sensor
|
||||
} else {
|
||||
only = false; // we found a slave which is not a sensor
|
||||
}
|
||||
}
|
||||
|
||||
return sensors;
|
||||
}
|
||||
|
||||
bool sensor_ds18b20_only(void)
|
||||
{
|
||||
sensor_ds18b20_number(); // this also checks for exclusivity
|
||||
return only;
|
||||
}
|
||||
|
||||
bool sensor_ds18b20_list(uint64_t* code)
|
||||
{
|
||||
if (!onewire_master_reset()) { // send reset to start communication
|
||||
return false; // no slave presence detected
|
||||
}
|
||||
onewire_master_rom_search(code, false); // get next code
|
||||
return (last!=*code); // verify if the last has been found
|
||||
}
|
||||
|
||||
bool sensor_ds18b20_convert(uint64_t code)
|
||||
{
|
||||
if (0==code && !only) { // asked for broadcast but there are different slaves on bus
|
||||
return false; // broadcast not possible when there are also different slaves on bus
|
||||
}
|
||||
|
||||
// send reset pulse
|
||||
if (!onewire_master_reset()) { // send reset to start communication
|
||||
return false; // no slave presence detected
|
||||
}
|
||||
|
||||
// send ROM command to select slave(s)
|
||||
if (0==code) { // broadcast convert
|
||||
if (!onewire_master_rom_skip()) { // select all slaves
|
||||
return false; // ROM command failed
|
||||
}
|
||||
} else {
|
||||
if (!onewire_master_rom_match(code)) { // select specific slave
|
||||
return false; // ROM command failed
|
||||
}
|
||||
}
|
||||
|
||||
// send convert T function command
|
||||
return onewire_master_function_read(0x44, NULL, 0);
|
||||
}
|
||||
|
||||
float sensor_ds18b20_temperature(uint64_t code)
|
||||
{
|
||||
if (0==code && (sensors>1 || !only)) { // broadcast read requested
|
||||
return NAN; // this function is not possible when several sensors or other devices are present
|
||||
}
|
||||
|
||||
// send reset pulse
|
||||
if (!onewire_master_reset()) { // send reset to start communication
|
||||
return NAN; // no slave presence detected
|
||||
}
|
||||
|
||||
// send ROM command to select slave
|
||||
if (!onewire_master_rom_match(code)) { // select specific slave
|
||||
return NAN; // ROM command failed
|
||||
}
|
||||
|
||||
// read scratchpad to get temperature (on byte 0 and 1)
|
||||
uint8_t scratchpad[9] = {0}; // to store read scratchpad
|
||||
if (!onewire_master_function_read(0xbe, scratchpad, sizeof(scratchpad)*8)) { // read complete scratchpad
|
||||
return NAN; // error occurred during read
|
||||
}
|
||||
|
||||
// verify if data is valid
|
||||
if (onewire_master_crc(scratchpad, sizeof(scratchpad))) { // check CRC checksum
|
||||
return NAN; // data corrupted
|
||||
}
|
||||
|
||||
// calculate temperature (stored as int16_t but on 0.125 C steps)
|
||||
return ((int16_t)(scratchpad[1]<<8)+scratchpad[0])/16.0; // get temperature (on < 16 precision the last bits are undefined, but that doesn't matter for the end result since the lower precision is still provided)
|
||||
}
|
||||
|
||||
bool sensor_ds18b20_precision(uint64_t code, uint8_t precision)
|
||||
{
|
||||
if (precision<9 || precision>12) { // check input
|
||||
return false; // wrong precision value
|
||||
}
|
||||
|
||||
if (0==code && !only) { // asked for broadcast but there are different slaves on bus
|
||||
return false; // broadcast not possible when there are also different slaves on bus
|
||||
}
|
||||
|
||||
// send reset pulse
|
||||
if (!onewire_master_reset()) { // send reset to start communication
|
||||
return false; // no slave presence detected
|
||||
}
|
||||
|
||||
// send ROM command to select slave(s)
|
||||
if (0==code) { // broadcast convert
|
||||
if (!onewire_master_rom_skip()) { // select all slaves
|
||||
return false; // ROM command failed
|
||||
}
|
||||
} else {
|
||||
if (!onewire_master_rom_match(code)) { // select specific slave
|
||||
return false; // ROM command failed
|
||||
}
|
||||
}
|
||||
|
||||
// read scratchpad to get alarm values (on byte 2 and 3)
|
||||
uint8_t scratchpad[9] = {0}; // to store read scratchpad
|
||||
if (!onewire_master_function_read(0xbe, scratchpad, sizeof(scratchpad)*8)) { // read complete scratchpad
|
||||
return false; // error occurred during read
|
||||
}
|
||||
|
||||
// verify if data is valid
|
||||
if (onewire_master_crc(scratchpad, sizeof(scratchpad))) { // check CRC checksum
|
||||
return false; // data corrupted
|
||||
}
|
||||
|
||||
// send new configuration (and keep the alarm values)
|
||||
uint8_t configuration[3] = {0}; // to store T_HIGH, T_LOW, and configuration
|
||||
configuration[0] = scratchpad[2]; // keep T_HIGH
|
||||
configuration[1] = scratchpad[3]; // keep T_LOW
|
||||
configuration[2] = 0x1f+((precision-9)<<5); // set precision bit (R1-R0 on bit 6-5)
|
||||
if (!onewire_master_function_write(0x4e, configuration, sizeof(configuration)*8)) { // write scratchpad with new configuration (all three bytes must be written)
|
||||
return false; // error occurred during write
|
||||
}
|
||||
|
||||
// store new configuration into sensor's EEPROM for retrieval on next power up
|
||||
if (!onewire_master_function_read(0x48, NULL, 0)) { // copy scratchpad (to EEPROM)
|
||||
return false; // error during copy
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
56
lib/sensor_ds18b20.h
Normal file
56
lib/sensor_ds18b20.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
/** library for Maxim DS18B20 digital temperature sensor (using 1-Wire protocol) (API)
|
||||
* @file sensor_ds18b20.h
|
||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @date 2017
|
||||
* @note peripherals used: 1-Wire (timer @ref onewire_master_timer, GPIO @ref onewire_master_gpio)
|
||||
* @warning this library does not support parasite power mode and alarms
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/** setup 1-Wire peripheral to communicate with sensors on bus */
|
||||
void sensor_ds18b20_setup(void);
|
||||
/** get number of DS18B20 sensors on bus
|
||||
* @return number of DS18B20 sensors on bus
|
||||
*/
|
||||
uint64_t sensor_ds18b20_number(void);
|
||||
/** verify if only DS18B20 sensors are on the bus
|
||||
* @return if only DS18B20 sensors are on the bus
|
||||
*/
|
||||
bool sensor_ds18b20_only(void);
|
||||
/** send all DS18B20 slaves on the bus
|
||||
* @param[out] code ROM code for sensor (0 if error occurred)
|
||||
* @return if an additional sensors have been detected
|
||||
*/
|
||||
bool sensor_ds18b20_list(uint64_t* code);
|
||||
/** start converting (e.g. measuring) temperature
|
||||
* @waning conversion time to wait before reading temperature depends on the resolution set (9 bits: 93.75ms, 10 bits: 187.5ms, 11 bits: 375ms, 12 bits: 950ms)
|
||||
* @param[in] code ROM code of sensor to start conversion on (0 for all, if only DS18B20 sensors are on the bus)
|
||||
* @return if conversion started
|
||||
*/
|
||||
bool sensor_ds18b20_convert(uint64_t code);
|
||||
/** get converted temperature
|
||||
* @note 85.0 C is the default temperature when no conversion has been performed
|
||||
* @param[in] code ROM code of sensor
|
||||
* @return temperature (NaN if error)
|
||||
*/
|
||||
float sensor_ds18b20_temperature(uint64_t code);
|
||||
/** set conversion precision
|
||||
* @param[in] code ROM code of sensor to start conversion on (0 for all, if only DS18B20 sensors are on the bus)
|
||||
* @param[in] precision precision in bits (9-12)
|
||||
* @return if operation succeeded
|
||||
*/
|
||||
bool sensor_ds18b20_precision(uint64_t code, uint8_t precision);
|
Loading…
Reference in New Issue
Block a user