changeset 318:31199b2941f6

Add simple_ds18b20.c etc
author Matt Johnston <matt@ucc.asn.au>
date Sat, 19 May 2012 21:47:09 +0800
parents 4ef5ce596ec6
children 9621436cfa07
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_