Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: ATParser DHT22 SerialGPS Sigfox mbed
Fork of Nucleo_SerialGPS_to_PC by
DS1820.cpp
00001 #include "DS1820.h" 00002 #include "mbed.h" 00003 00004 // Global variables shared between all DS1820 objects 00005 bool DS1820_done_flag; 00006 int DS1820_last_descrepancy; 00007 char DS1820_search_ROM[8]; 00008 00009 00010 DS1820::DS1820 (PinName data_pin, PinName power_pin) : _datapin(data_pin), _parasitepin(power_pin) { 00011 int byte_counter; 00012 00013 _parasite_power = true; 00014 for(byte_counter=0;byte_counter<8;byte_counter++) 00015 ROM[byte_counter] = 0xFF; 00016 for(byte_counter=0;byte_counter<9;byte_counter++) 00017 RAM[byte_counter] = 0x00; 00018 } 00019 DS1820::DS1820 (PinName data_pin) : _datapin(data_pin), _parasitepin(NC) { 00020 int byte_counter; 00021 _parasite_power = false; 00022 for(byte_counter=0;byte_counter<8;byte_counter++) 00023 ROM[byte_counter] = 0xFF; 00024 for(byte_counter=0;byte_counter<9;byte_counter++) 00025 RAM[byte_counter] = 0x00; 00026 } 00027 00028 bool DS1820::onewire_reset() { 00029 // This will return false if no devices are present on the data bus 00030 bool presence=false; 00031 _datapin.output(); 00032 _datapin.mode(PullUp); 00033 _datapin = 0; // bring low for 500 us 00034 wait_us(500); 00035 _datapin.input(); // let the data line float high 00036 _datapin.mode(PullUp); 00037 wait_us(90); // wait 90us 00038 if (_datapin.read()==0) // see if any devices are pulling the data line low 00039 presence=true; 00040 wait_us(410); 00041 return presence; 00042 } 00043 00044 void DS1820::onewire_bit_out (bool bit_data) { 00045 _datapin.output(); 00046 _datapin = 0; 00047 wait_us(5); 00048 if (bit_data) { 00049 _datapin.input(); // bring data line high 00050 _datapin.mode(PullUp); 00051 wait_us(55); 00052 } else { 00053 wait_us(55); // keep data line low 00054 _datapin.input(); 00055 _datapin.mode(PullUp); 00056 } 00057 } 00058 00059 void DS1820::onewire_byte_out(char data) { // output data character (least sig bit first). 00060 int n; 00061 for (n=0; n<8; n++) { 00062 onewire_bit_out(data & 0x01); 00063 data = data >> 1; // now the next bit is in the least sig bit position. 00064 } 00065 } 00066 00067 bool DS1820::onewire_bit_in() { 00068 bool answer; 00069 _datapin.output(); 00070 _datapin = 0; 00071 wait_us(5); 00072 _datapin.input(); 00073 _datapin.mode(PullUp); 00074 wait_us(5); 00075 answer = _datapin.read(); 00076 wait_us(50); 00077 return answer; 00078 } 00079 00080 char DS1820::onewire_byte_in() { // read byte, least sig byte first 00081 char answer = 0x00; 00082 int i; 00083 for (i=0; i<8; i++) { 00084 answer = answer >> 1; // shift over to make room for the next bit 00085 if (onewire_bit_in()) 00086 answer = answer | 0x80; // if the data port is high, make this bit a 1 00087 } 00088 return answer; 00089 } 00090 00091 bool DS1820::search_ROM() { 00092 return search_ROM_routine(0xF0); // Search ROM command 00093 } 00094 00095 bool DS1820::search_alarm() { 00096 return search_ROM_routine(0xEC); // Search Alarm command 00097 } 00098 00099 bool DS1820::search_ROM_routine(char command) { 00100 extern bool DS1820_done_flag; 00101 extern int DS1820_last_descrepancy; 00102 extern char DS1820_search_ROM[8]; 00103 int descrepancy_marker, ROM_bit_index; 00104 bool return_value, Bit_A, Bit_B; 00105 char byte_counter, bit_mask; 00106 00107 return_value=false; 00108 if (!DS1820_done_flag) { 00109 if (!onewire_reset()) { 00110 DS1820_last_descrepancy = 0; // no devices present 00111 } else { 00112 ROM_bit_index=1; 00113 descrepancy_marker=0; 00114 onewire_byte_out(command); // Search ROM command or Search Alarm command 00115 byte_counter = 0; 00116 bit_mask = 0x01; 00117 while (ROM_bit_index<=64) { 00118 Bit_A = onewire_bit_in(); 00119 Bit_B = onewire_bit_in(); 00120 if (Bit_A & Bit_B) { 00121 descrepancy_marker = 0; // data read error, this should never happen 00122 ROM_bit_index = 0xFF; 00123 } else { 00124 if (Bit_A | Bit_B) { 00125 // Set ROM bit to Bit_A 00126 if (Bit_A) { 00127 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] | bit_mask; // Set ROM bit to one 00128 } else { 00129 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] & ~bit_mask; // Set ROM bit to zero 00130 } 00131 } else { 00132 // both bits A and B are low, so there are two or more devices present 00133 if ( ROM_bit_index == DS1820_last_descrepancy ) { 00134 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] | bit_mask; // Set ROM bit to one 00135 } else { 00136 if ( ROM_bit_index > DS1820_last_descrepancy ) { 00137 DS1820_search_ROM[byte_counter] = DS1820_search_ROM[byte_counter] & ~bit_mask; // Set ROM bit to zero 00138 descrepancy_marker = ROM_bit_index; 00139 } else { 00140 if (( DS1820_search_ROM[byte_counter] & bit_mask) == 0x00 ) 00141 descrepancy_marker = ROM_bit_index; 00142 } 00143 } 00144 } 00145 onewire_bit_out (DS1820_search_ROM[byte_counter] & bit_mask); 00146 ROM_bit_index++; 00147 if (bit_mask & 0x80) { 00148 byte_counter++; 00149 bit_mask = 0x01; 00150 } else { 00151 bit_mask = bit_mask << 1; 00152 } 00153 } 00154 } 00155 DS1820_last_descrepancy = descrepancy_marker; 00156 if (ROM_bit_index != 0xFF) { 00157 for(byte_counter=0;byte_counter<8;byte_counter++) 00158 ROM[byte_counter] = DS1820_search_ROM[byte_counter]; 00159 return_value = true; 00160 } 00161 } 00162 if (DS1820_last_descrepancy == 0) 00163 DS1820_done_flag = true; 00164 } 00165 return return_value; 00166 } 00167 00168 void DS1820::search_ROM_setup() { 00169 extern bool DS1820_done_flag; 00170 extern int DS1820_last_descrepancy; 00171 extern char DS1820_search_ROM[8]; 00172 DS1820_done_flag = false; 00173 DS1820_last_descrepancy = 0; 00174 int i; 00175 for (i=0; i<8; i++) 00176 DS1820_search_ROM[i]=0x00; 00177 } 00178 00179 void DS1820::read_ROM() { 00180 // NOTE: This command can only be used when there is one DS1820 on the bus. If this command 00181 // is used when there is more than one slave present on the bus, a data collision will occur 00182 // when all the DS1820s attempt to respond at the same time. 00183 int i; 00184 onewire_reset(); 00185 onewire_byte_out(0x33); // Read ROM id 00186 for (i=0; i<8; i++) 00187 ROM[i]=onewire_byte_in(); 00188 } 00189 00190 void DS1820::match_ROM() { 00191 // Used to select a specific device 00192 int i; 00193 onewire_reset(); 00194 onewire_byte_out( 0x55); //Match ROM command 00195 for (i=0;i<8;i++) 00196 onewire_byte_out(ROM[i]); 00197 } 00198 00199 void DS1820::skip_ROM() { 00200 onewire_reset(); 00201 onewire_byte_out(0xCC); // Skip ROM command 00202 } 00203 00204 bool DS1820::ROM_checksum_error() { 00205 char xCRC=0x00; 00206 int i; 00207 for(i=0;i<7;i++) // Only going to shift the lower 7 bytes 00208 xCRC = CRC_byte(xCRC, ROM[i]); 00209 // After 7 bytes CRC should equal the 8th byte (ROM CRC) 00210 return (xCRC!=ROM[7]); // will return true if there is a CRC checksum error 00211 } 00212 00213 bool DS1820::RAM_checksum_error() { 00214 char xCRC=0x00; 00215 int i; 00216 read_RAM(); 00217 for(i=0;i<8;i++) // Only going to shift the lower 8 bytes 00218 xCRC = CRC_byte(xCRC, RAM[i]); 00219 // After 8 bytes CRC should equal the 9th byte (RAM CRC) 00220 return (xCRC!=RAM[8]); // will return true if there is a CRC checksum error 00221 } 00222 00223 char DS1820::CRC_byte (char xCRC, char byte ) { 00224 int j; 00225 for(j=0;j<8;j++) { 00226 if ((byte & 0x01 ) ^ (xCRC & 0x01)) { 00227 // DATA ^ LSB CRC = 1 00228 xCRC = xCRC>>1; 00229 // Set the MSB to 1 00230 xCRC = xCRC | 0x80; 00231 // Check bit 3 00232 if (xCRC & 0x04) { 00233 xCRC = xCRC & 0xFB; // Bit 3 is set, so clear it 00234 } else { 00235 xCRC = xCRC | 0x04; // Bit 3 is clear, so set it 00236 } 00237 // Check bit 4 00238 if (xCRC & 0x08) { 00239 xCRC = xCRC & 0xF7; // Bit 4 is set, so clear it 00240 } else { 00241 xCRC = xCRC | 0x08; // Bit 4 is clear, so set it 00242 } 00243 } else { 00244 // DATA ^ LSB xCRC = 0 00245 xCRC = xCRC>>1; 00246 // clear MSB 00247 xCRC = xCRC & 0x7F; 00248 // No need to check bits, with DATA ^ LSB xCRC = 0, they will remain unchanged 00249 } 00250 byte = byte>>1; 00251 } 00252 return xCRC; 00253 } 00254 00255 void DS1820::convert_temperature(devices device) { 00256 // Convert temperature into scratchpad RAM for all devices at once 00257 int delay_time = 750; // Default delay time 00258 char resolution; 00259 if (device==all_devices) 00260 skip_ROM(); // Skip ROM command, will convert for ALL devices 00261 else { 00262 match_ROM(); 00263 if (FAMILY_CODE == FAMILY_CODE_DS18B20 ) { 00264 resolution = RAM[4] & 0x60; 00265 if (resolution == 0x00) // 9 bits 00266 delay_time = 94; 00267 if (resolution == 0x20) // 10 bits 00268 delay_time = 188; 00269 if (resolution == 0x40) // 11 bits. Note 12bits uses the 750ms default 00270 delay_time = 375; 00271 } 00272 } 00273 onewire_byte_out( 0x44); // perform temperature conversion 00274 if (_parasite_power) 00275 _parasitepin = 1; // Parasite power strong pullup 00276 wait_ms(delay_time); 00277 if (_parasite_power) 00278 _parasitepin = 0; 00279 } 00280 00281 void DS1820::read_RAM() { 00282 // This will copy the DS1820's 9 bytes of RAM data 00283 // into the objects RAM array. Functions that use 00284 // RAM values will automaticly call this procedure. 00285 int i; 00286 match_ROM(); // Select this device 00287 onewire_byte_out( 0xBE); //Read Scratchpad command 00288 for(i=0;i<9;i++) { 00289 RAM[i] = onewire_byte_in(); 00290 } 00291 } 00292 00293 bool DS1820::set_configuration_bits(unsigned int resolution) { 00294 bool answer = false; 00295 resolution = resolution - 9; 00296 if (resolution < 4) { 00297 resolution = resolution<<5; // align the bits 00298 RAM[4] = (RAM[4] & 0x60) | resolution; // mask out old data, insert new 00299 write_scratchpad ((RAM[2]<<8) + RAM[3]); 00300 // store_scratchpad (DS1820::this_device); // Need to test if this is required 00301 answer = true; 00302 } 00303 return answer; 00304 } 00305 00306 int DS1820::read_scratchpad() { 00307 int answer; 00308 read_RAM(); 00309 answer = (RAM[2]<<8) + RAM[3]; 00310 return answer; 00311 } 00312 00313 void DS1820::write_scratchpad(int data) { 00314 RAM[3] = data; 00315 RAM[2] = data>>8; 00316 match_ROM(); 00317 onewire_byte_out(0x4E); // Copy scratchpad into DS1820 ram memory 00318 onewire_byte_out(RAM[2]); // T(H) 00319 onewire_byte_out(RAM[3]); // T(L) 00320 if ( FAMILY_CODE == FAMILY_CODE_DS18B20 ) { 00321 onewire_byte_out(RAM[4]); // Configuration register 00322 } 00323 } 00324 00325 void DS1820::store_scratchpad(devices device) { 00326 if (device==all_devices) 00327 skip_ROM(); // Skip ROM command, will store for ALL devices 00328 else 00329 match_ROM(); 00330 onewire_byte_out(0x48); // Write scratchpad into E2 command 00331 if (_parasite_power) 00332 _parasitepin=1; 00333 wait_ms(10); // Parasite power strong pullup for 10ms 00334 if (_parasite_power) 00335 _parasitepin=0; 00336 } 00337 00338 int DS1820::recall_scratchpad(devices device) { 00339 // This copies the E2 values into the DS1820's memory. 00340 // If you specify all_devices this will return zero, otherwise 00341 // it will return the value of the scratchpad memory. 00342 int answer=0; 00343 if (device==all_devices) 00344 skip_ROM(); // Skip ROM command, will recall for ALL devices 00345 else 00346 match_ROM(); 00347 onewire_byte_out(0xB8); // Recall E2 data to scratchpad command 00348 wait_ms(10); // not sure I like polling for completion 00349 // it could cause an infinite loop 00350 if (device==DS1820::this_device) { 00351 read_RAM(); 00352 answer = read_scratchpad(); 00353 } 00354 return answer; 00355 } 00356 00357 float DS1820::temperature(char scale) { 00358 // The data specs state that count_per_degree should be 0x10 (16), I found my devices 00359 // to have a count_per_degree of 0x4B (75). With the standard resolution of 1/2 deg C 00360 // this allowed an expanded resolution of 1/150th of a deg C. I wouldn't rely on this 00361 // being super acurate, but it does allow for a smooth display in the 1/10ths of a 00362 // deg C or F scales. 00363 float answer, remaining_count, count_per_degree; 00364 int reading; 00365 read_RAM(); 00366 reading = (RAM[1] << 8) + RAM[0]; 00367 if (reading & 0x8000) { // negative degrees C 00368 reading = 0-((reading ^ 0xffff) + 1); // 2's comp then convert to signed int 00369 } 00370 answer = reading +0.0; // convert to floating point 00371 if ( FAMILY_CODE == FAMILY_CODE_DS18B20 ) { 00372 answer = answer / 8.0; 00373 } 00374 else { 00375 remaining_count = RAM[6]; 00376 count_per_degree = RAM[7]; 00377 answer = answer - 0.25 + (count_per_degree - remaining_count) / count_per_degree; 00378 } 00379 if (scale=='C' or scale=='c') 00380 answer = answer / 2.0; 00381 else 00382 // Convert to deg F 00383 answer = answer * 9.0 / 10.0 + 32.0; 00384 return answer; 00385 } 00386 00387 bool DS1820::read_power_supply(devices device) { 00388 // This will return true if the device (or all devices) are Vcc powered 00389 // This will return false if the device (or ANY device) is parasite powered 00390 if (device==all_devices) 00391 skip_ROM(); // Skip ROM command, will poll for any device using parasite power 00392 else 00393 match_ROM(); 00394 onewire_byte_out(0xB4); // Read power supply command 00395 return onewire_bit_in(); 00396 }
Generated on Wed Jul 13 2022 17:46:39 by
1.7.2
