CuVoodoo STM32F1 firmware template
sensor_ds18b20.c
Go to the documentation of this file.
1 /* This program is free software: you can redistribute it and/or modify
2  * it under the terms of the GNU General Public License as published by
3  * the Free Software Foundation, either version 3 of the License, or
4  * (at your option) any later version.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program. If not, see <http://www.gnu.org/licenses/>.
13  *
14  */
22 /* standard libraries */
23 #include <stdint.h> // standard integer types
24 #include <stdbool.h> // boolean type
25 #include <stdlib.h> // size_t definition
26 #include <math.h> // NAN definition
27 
28 /* own libraries */
29 #include "global.h" // help macros
30 #include "onewire_master.h" // 1-Wire utilities
31 #include "sensor_ds18b20.h" // own definitions
32 
34 uint64_t sensors = 0;
36 bool only = false;
38 uint64_t last = 0;
39 
41 {
42  onewire_master_setup(); // setup 1-Wire peripheral to communicate with sensors on bus
43  sensor_ds18b20_number(); // scan for sensor (remembers sensor number and exclusivity)
44 }
45 
46 uint64_t sensor_ds18b20_number(void)
47 {
48  sensors = 0; // reset number
49  only = true; // reset state
50  uint64_t code = 0; // ROM code found (use 0 to start from scratch)
51  bool more = true; // save if other additional slaves exist
52 
53  while (more) { // scan for all 1-Wire slaves
54  if (!onewire_master_reset()) { // send reset to start communication
55  return 0; // no slave presence detected
56  }
57  more = onewire_master_rom_search(&code, false); // get next slave ROM code (without alarm)
58  if (0==code) { // error occurred
59  return 0;
60  }
61  if (0x28==(code&0xff)) { // family code (8-LSb) for DS18B20 sensors is 0x28
62  last = code; // save last found code
63  sensors++; // we found an additional sensor
64  } else {
65  only = false; // we found a slave which is not a sensor
66  }
67  }
68 
69  return sensors;
70 }
71 
73 {
74  sensor_ds18b20_number(); // this also checks for exclusivity
75  return only;
76 }
77 
78 bool sensor_ds18b20_list(uint64_t* code)
79 {
80  if (!onewire_master_reset()) { // send reset to start communication
81  return false; // no slave presence detected
82  }
83  onewire_master_rom_search(code, false); // get next code
84  return (last!=*code); // verify if the last has been found
85 }
86 
87 bool sensor_ds18b20_convert(uint64_t code)
88 {
89  if (0==code && !only) { // asked for broadcast but there are different slaves on bus
90  return false; // broadcast not possible when there are also different slaves on bus
91  }
92 
93  // send reset pulse
94  if (!onewire_master_reset()) { // send reset to start communication
95  return false; // no slave presence detected
96  }
97 
98  // send ROM command to select slave(s)
99  if (0==code) { // broadcast convert
100  if (!onewire_master_rom_skip()) { // select all slaves
101  return false; // ROM command failed
102  }
103  } else {
104  if (!onewire_master_rom_match(code)) { // select specific slave
105  return false; // ROM command failed
106  }
107  }
108 
109  // send convert T function command
110  return onewire_master_function_read(0x44, NULL, 0);
111 }
112 
113 float sensor_ds18b20_temperature(uint64_t code)
114 {
115  if (0==code && (sensors>1 || !only)) { // broadcast read requested
116  return NAN; // this function is not possible when several sensors or other devices are present
117  }
118 
119  // send reset pulse
120  if (!onewire_master_reset()) { // send reset to start communication
121  return NAN; // no slave presence detected
122  }
123 
124  // send ROM command to select slave
125  if (!onewire_master_rom_match(code)) { // select specific slave
126  return NAN; // ROM command failed
127  }
128 
129  // read scratchpad to get temperature (on byte 0 and 1)
130  uint8_t scratchpad[9] = {0}; // to store read scratchpad
131  if (!onewire_master_function_read(0xbe, scratchpad, sizeof(scratchpad)*8)) { // read complete scratchpad
132  return NAN; // error occurred during read
133  }
134 
135  // verify if data is valid
136  if (onewire_master_crc(scratchpad, sizeof(scratchpad))) { // check CRC checksum
137  return NAN; // data corrupted
138  }
139 
140  // calculate temperature (stored as int16_t but on 0.125 C steps)
141  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)
142 }
143 
144 bool sensor_ds18b20_precision(uint64_t code, uint8_t precision)
145 {
146  if (precision<9 || precision>12) { // check input
147  return false; // wrong precision value
148  }
149 
150  if (0==code && !only) { // asked for broadcast but there are different slaves on bus
151  return false; // broadcast not possible when there are also different slaves on bus
152  }
153 
154  // send reset pulse
155  if (!onewire_master_reset()) { // send reset to start communication
156  return false; // no slave presence detected
157  }
158 
159  // send ROM command to select slave(s)
160  if (0==code) { // broadcast convert
161  if (!onewire_master_rom_skip()) { // select all slaves
162  return false; // ROM command failed
163  }
164  } else {
165  if (!onewire_master_rom_match(code)) { // select specific slave
166  return false; // ROM command failed
167  }
168  }
169 
170  // read scratchpad to get alarm values (on byte 2 and 3)
171  uint8_t scratchpad[9] = {0}; // to store read scratchpad
172  if (!onewire_master_function_read(0xbe, scratchpad, sizeof(scratchpad)*8)) { // read complete scratchpad
173  return false; // error occurred during read
174  }
175 
176  // verify if data is valid
177  if (onewire_master_crc(scratchpad, sizeof(scratchpad))) { // check CRC checksum
178  return false; // data corrupted
179  }
180 
181  // send new configuration (and keep the alarm values)
182  uint8_t configuration[3] = {0}; // to store T_HIGH, T_LOW, and configuration
183  configuration[0] = scratchpad[2]; // keep T_HIGH
184  configuration[1] = scratchpad[3]; // keep T_LOW
185  configuration[2] = 0x1f+((precision-9)<<5); // set precision bit (R1-R0 on bit 6-5)
186  if (!onewire_master_function_write(0x4e, configuration, sizeof(configuration)*8)) { // write scratchpad with new configuration (all three bytes must be written)
187  return false; // error occurred during write
188  }
189 
190  // store new configuration into sensor's EEPROM for retrieval on next power up
191  if (!onewire_master_function_read(0x48, NULL, 0)) { // copy scratchpad (to EEPROM)
192  return false; // error during copy
193  }
194 
195  return true;
196 }
library for Maxim DS18B20 digital temperature sensor (using 1-Wire protocol) (API) ...
bool sensor_ds18b20_list(uint64_t *code)
send all DS18B20 slaves on the bus
float sensor_ds18b20_temperature(uint64_t code)
get converted temperature
bool onewire_master_rom_search(uint64_t *code, bool alarm)
send SEARCH ROM command
uint64_t sensor_ds18b20_number(void)
get number of DS18B20 sensors on bus
bool onewire_master_function_write(uint8_t function, uint8_t *data, uint32_t bits)
issue function and write data
void onewire_master_setup(bool parasite, uint16_t recovery)
setup 1-wire peripheral
global definitions and methods (API)
library for 1-wire protocol as master (API)
bool onewire_master_function_read(uint8_t function, uint8_t *data, uint32_t bits)
issue function and read data
void sensor_ds18b20_setup(void)
setup 1-Wire peripheral to communicate with sensors on bus
bool onewire_master_rom_skip(void)
send SKIP ROM command (all slaves on the bus will be selected)
bool sensor_ds18b20_precision(uint64_t code, uint8_t precision)
set conversion precision
bool sensor_ds18b20_only(void)
verify if only DS18B20 sensors are on the bus
bool sensor_ds18b20_convert(uint64_t code)
start converting (e.g.
bool only
remember if only DS18B20 sensors on 1-Wire bus for certain functions
uint64_t sensors
remember number of DS18B20 sensors on 1-Wire bus for certain functions
bool onewire_master_rom_match(uint64_t code)
send MATCH ROM command to select a specific slave
uint8_t onewire_master_crc(uint8_t *data, uint32_t length)
compute CRC for 1-Wire
uint64_t last
remember code of last sensor
bool onewire_master_reset(void)
send reset pulse