Mercurial > templog
changeset 12:3c27bfbd7f3a
Add simple_ds18b20.c etc
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 19 May 2012 21:47:09 +0800 |
parents | 06bedbe8540d |
children | 4838bfcb3504 |
files | Makefile main.c simple_ds18b20.c simple_ds18b20.h |
diffstat | 4 files changed, 257 insertions(+), 27 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Sat May 19 17:15:50 2012 +0800 +++ b/Makefile Sat May 19 21:47:09 2012 +0800 @@ -22,7 +22,7 @@ CLOCK = 2000000 PROGRAMMER = #-c stk500v2 -P avrdoper PROGRAMMER = -c stk500 -P ~/dev/stk500 -p $(PROGDEVICE) -B 2 -SOURCE_1WIRE = onewire.c ds18x20.c uart_addon.c crc8.c uart.c +SOURCE_1WIRE = onewire.c simple_ds18b20.c crc8.c SOURCE_SD = ff.c mmc.c SOURCE = main.c SOURCE += $(SOURCE_1WIRE) @@ -83,7 +83,7 @@ $(AVRDUDE) $(FUSES) # Xcode uses the Makefile targets "", "clean" and "install" -install: flash fuse +install: flash # if you use a bootloader, change the command below appropriately: load: all
--- a/main.c Sat May 19 17:15:50 2012 +0800 +++ b/main.c Sat May 19 21:47:09 2012 +0800 @@ -13,9 +13,10 @@ #include <avr/pgmspace.h> #include <util/crc16.h> +// for DWORD of get_fattime() #include "integer.h" -#include "onewire.h" -#include "ds18x20.h" + +#include "simple_ds18b20.h" // configuration params // - measurement interval @@ -137,6 +138,22 @@ } static void +cmd_measure() +{ + printf_P(PSTR("Measuring\n")); + need_measurement = 1; +} + +static void +cmd_sensors() +{ + uint8_t ret = simple_ds18b20_start_meas(NULL); + printf("All sensors, ret %d, waiting...\n", ret); + _delay_ms(DS18B20_TCONV_12BIT); + simple_ds18b20_read_all(); +} + +static void read_handler() { if (strcmp_P(readbuf, PSTR("fetch")) == 0) @@ -151,6 +168,14 @@ { cmd_btoff(); } + else if (strcmp_P(readbuf, PSTR("measure")) == 0) + { + cmd_measure(); + } + else if (strcmp_P(readbuf, PSTR("sensors")) == 0) + { + cmd_sensors(); + } else { printf_P(PSTR("Bad command\n")); @@ -160,7 +185,8 @@ ISR(USART_RX_vect) { char c = UDR0; - if (c == '\n') + uart_putchar(c, NULL); + if (c == '\r') { readbuf[readpos] = '\0'; read_handler(); @@ -181,9 +207,11 @@ { measure_count ++; comms_count ++; + printf("measure_count %d\n", measure_count); if (measure_count == MEASURE_WAKE) { measure_count = 0; + printf("need_measurement = 1\n"); need_measurement = 1; } @@ -273,9 +301,10 @@ static void do_measurement() { + printf("do_measurement\n"); need_measurement = 0; - do_adc_335(); + //do_adc_335(); } static void @@ -288,6 +317,8 @@ // write sd card here? same 3.3v regulator... + printf("ready> \n"); + comms_done = 0; for (;;) { @@ -345,14 +376,8 @@ } static void -test1wire() +dump_ds18x20() { - //ow_reset(); - - uint8_t ret = DS18X20_start_meas( DS18X20_POWER_PARASITE, NULL); - printf("ret %d\n", ret); - _delay_ms(DS18B20_TCONV_12BIT); - DS18X20_read_meas_all_verbose(); } int main(void) @@ -374,14 +399,9 @@ // for testing uart_on(); - //sei(); + sei(); - for (;;) - { - test1wire(); - long_delay(2000); - } - +#if 0 // set up counter2. // COM21 COM20 Set OC2 on Compare Match (p116) // WGM21 Clear counter on compare @@ -392,17 +412,14 @@ ASSR |= _BV(AS2); // interrupt TIMSK2 = _BV(OCIE2A); +#endif -#ifdef TEST_MODE for (;;) { - do_comms() + do_comms(); } -#else + for(;;){ - - test1wire(); - /* insert your main loop code here */ if (need_measurement) { @@ -420,6 +437,6 @@ blink(); printf("."); } -#endif + return 0; /* never reached */ }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simple_ds18b20.c Sat May 19 21:47:09 2012 +0800 @@ -0,0 +1,200 @@ +// Matt Johnston 2012 +// Based on ds18x20.c by Martin Thomas, in turn based on code by +// Peter // Dannegger and others. +// +#include <stdio.h> +#include <avr/pgmspace.h> + +#include "ds18x20.h" +#include "onewire.h" +#include "crc8.h" + +#include "simple_ds18b20.h" + +uint8_t +simple_ds18b20_start_meas(uint8_t id[]) +{ + uint8_t ret; + + ow_reset(); + if( ow_input_pin_state() ) { // only send if bus is "idle" = high + ow_command_with_parasite_enable(DS18X20_CONVERT_T, id); + ret = DS18X20_OK; + } + else { + ret = DS18X20_START_FAIL; + } + + return ret; +} + +static uint8_t +read_scratchpad( uint8_t id[], uint8_t sp[], uint8_t n ) +{ + uint8_t i; + uint8_t ret; + + ow_command( DS18X20_READ, id ); + for ( i = 0; i < n; i++ ) { + sp[i] = ow_byte_rd(); + } + if ( crc8( &sp[0], DS18X20_SP_SIZE ) ) { + ret = DS18X20_ERROR_CRC; + } else { + ret = DS18X20_OK; + } + + return ret; +} + +static int16_t +ds18b20_raw_to_decicelsius( uint8_t sp[] ) +{ + uint16_t measure; + uint8_t negative; + int16_t decicelsius; + uint16_t fract; + + measure = sp[0] | (sp[1] << 8); + //measure = 0xFF5E; // test -10.125 + //measure = 0xFE6F; // test -25.0625 + + // check for negative + if ( measure & 0x8000 ) { + negative = 1; // mark negative + measure ^= 0xffff; // convert to positive => (twos complement)++ + measure++; + } + else { + negative = 0; + } + + // clear undefined bits for DS18B20 != 12bit resolution + switch( sp[DS18B20_CONF_REG] & DS18B20_RES_MASK ) { + case DS18B20_9_BIT: + measure &= ~(DS18B20_9_BIT_UNDF); + break; + case DS18B20_10_BIT: + measure &= ~(DS18B20_10_BIT_UNDF); + break; + case DS18B20_11_BIT: + measure &= ~(DS18B20_11_BIT_UNDF); + break; + default: + // 12 bit - all bits valid + break; + } + + decicelsius = (measure >> 4); + decicelsius *= 10; + + // decicelsius += ((measure & 0x000F) * 640 + 512) / 1024; + // 625/1000 = 640/1024 + fract = ( measure & 0x000F ) * 640; + if ( !negative ) { + fract += 512; + } + fract /= 1024; + decicelsius += fract; + + if ( negative ) { + decicelsius = -decicelsius; + } + + if ( /* decicelsius == 850 || */ decicelsius < -550 || decicelsius > 1250 ) { + return DS18X20_INVALID_DECICELSIUS; + } else { + return decicelsius; + } +} + +uint8_t +simple_ds18b20_read_decicelsius( uint8_t id[], int16_t *decicelsius ) +{ + uint8_t sp[DS18X20_SP_SIZE]; + uint8_t ret; + + if (id) + { + ow_reset(); + } + ret = read_scratchpad( id, sp, DS18X20_SP_SIZE ); + if ( ret == DS18X20_OK ) { + *decicelsius = ds18b20_raw_to_decicelsius( sp ); + } + return ret; +} + +static void +printhex_nibble(const unsigned char b) +{ + unsigned char c = b & 0x0f; + if ( c > 9 ) { + c += 'A'-10; + } + else { + c += '0'; + } + putchar(c); +} + +void +printhex_byte( const unsigned char b ) +{ + printhex_nibble( b >> 4 ); + printhex_nibble( b ); +} + +void +printhex(uint8_t *id, uint8_t n) +{ + for (uint8_t i = 0; i < n; i++) + { + if (i > 0) + { + putchar(' '); + } + printhex_byte(id[i]); + } +} + + +uint8_t +simple_ds18b20_read_all() +{ + uint8_t id[OW_ROMCODE_SIZE]; + uint8_t sp[DS18X20_SP_SIZE]; + for( uint8_t diff = OW_SEARCH_FIRST; diff != OW_LAST_DEVICE; ) + { + diff = ow_rom_search( diff, &id[0] ); + + if( diff == OW_PRESENCE_ERR ) { + printf_P( PSTR("No Sensor found\r") ); + return OW_PRESENCE_ERR; // <--- early exit! + } + + if( diff == OW_DATA_ERR ) { + printf_P( PSTR("Bus Error\r") ); + return OW_DATA_ERR; // <--- early exit! + } + + int16_t decicelsius; + uint8_t ret = simple_ds18b20_read_decicelsius(NULL, &decicelsius); + if (ret != DS18X20_OK) + { + printf_P(PSTR("Failed reading\r")); + return OW_DATA_ERR; + } + + printf_P(PSTR("DS18B20 %d: "), diff); + if (crc8(id, OW_ROMCODE_SIZE)) + { + printf_P(PSTR("CRC fail")); + } + printhex(id, OW_ROMCODE_SIZE); + printf_P(PSTR(" %d.%d ÂșC\n"), decicelsius/10, decicelsius % 10); + } + printf_P(PSTR("Done sensors\n")); + return DS18X20_OK; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simple_ds18b20.h Sat May 19 21:47:09 2012 +0800 @@ -0,0 +1,13 @@ +#ifndef SIMPLE_DS18B20_H_ +#define SIMPLE_DS18B20_H_ +#include <stdint.h> + +#include "ds18x20.h" + +uint8_t simple_ds18b20_start_meas(uint8_t id[]); +void printhex(uint8_t *id, uint8_t n); +void printhex_byte( const unsigned char b ); +uint8_t simple_ds18b20_read_decicelsius( uint8_t id[], int16_t *decicelsius ); +uint8_t simple_ds18b20_read_all(); + +#endif // SIMPLE_DS18B20_H_