zeke 693 Posted February 3, 2011 Share Posted February 3, 2011 The DS18B20 differs from the DS1821 enough that I thought I should start a new thread for it. Since this reset function works well for me, I decided to post it up. It features presence pulse detection. It works in combination with the code Touch posted here. int OW_Reset( int Pin ) { int result, test; delayMicroseconds( 0 ); // delay for 0us digitalWrite(Pin, LOW); pinMode(Pin, OUTPUT); delayMicroseconds( 480 ); // delay for 480us pinMode(Pin, INPUT); delayMicroseconds( 70 ); // delay for 70us test = digitalRead( WIRE_PORT ); if( test == 0 ) // Mask off everything but P1.7 input { result = TRUE; // Presense pulse detected } else { result = FALSE; // ds18b20 is not there } delayMicroseconds( 410 ); // delay for 410us return ( result ); // return the sampled presence pulse result } I know that the function could be refactored to make it smaller and sleeker by removing the local variables. I left them in so that people who use this code can make those local variables into watch variables when they are debugging their hardware. Next, I have to create the master read and write time slots in the readbit and writebit functions. Quote Link to post Share on other sites
zeke 693 Posted February 3, 2011 Author Share Posted February 3, 2011 Well, after grinding through the DS18B20 datasheet and making graphs, I realize that Peter H Anderson of Baltimore, MD did a fine job back in 2007. Thanks go to Touch for that link. I now can read the ROM Code out of my DS18B20. It is 0A-00-00-02-E1-39-80-28. I know this is working because the datasheet states that the LSByte will be 0x28 for the DS18B20. 64-BIT LASERED ROM CODE Each DS18B20 contains a unique 64 Quote Link to post Share on other sites
zeke 693 Posted February 4, 2011 Author Share Posted February 4, 2011 Okay, I have my code running. Here's main.c #include #include "ds18b20.h" #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0) #define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A) #define UART_TBIT_DIV_2 (16000000 / (9600 * 2)) #define UART_TBIT (16000000 / 9600) #define delayMicroseconds(n) __delay_cycles(n<<4) // The One Wire bus is connected to this pin #define WIRE_PORT 7 //Remember you need a 4.7k pullup resistor here. #define LOW 0 #define HIGH 1 #define INPUT 0 #define OUTPUT 1 #define FALSE 0 #define TRUE 1 //Zeke's mod's int OW_Reset( int Pin ); void OW_WriteByte(int Pin, char d); char OW_ReadByte(int Pin); // Routines written by Peter H Anderson // http://www.phanderson.com/arduino/ds18b20_1.html char digitalRead( char Pin ); void pinMode( int Pin, int Out ); void digitalWrite( int Pin, int Bit ); // Software UART routines void TimerA_UART_init( void ); void TimerA_UART_tx( unsigned char byte ); unsigned int txData; // UART internal variable for TX unsigned char rxBuffer; // Received UART character void main(void) { // int temp = 0; int i; int ROMCode[8]; int ScratchPad[9]; int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; P1OUT = UART_RXD; // RXD as IN P1SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins P1DIR = UART_TXD; TimerA_UART_init(); __enable_interrupt(); while ( 1 ) { if ( 1 == OW_Reset( WIRE_PORT ) ) { OW_WriteByte( WIRE_PORT, 0x33 ); // Read ROM Code from DS18B20 for( i=0; i<8; i++ ) { // Read the values inside of the ROMCode array in the debugger window ROMCode[i] = OW_ReadByte( WIRE_PORT ); } } if ( 1 == OW_Reset( WIRE_PORT ) ) { OW_WriteByte( WIRE_PORT, SKIPROM ); // Skip ROM Code matching OW_WriteByte( WIRE_PORT, CONVERTTEMP ); // Read ROM Code from DS18B20 OW_Reset( WIRE_PORT ); OW_WriteByte( WIRE_PORT, SKIPROM ); // Skip ROM Code matching OW_WriteByte( WIRE_PORT, READSCRATCHPAD ); // Read ScratchPad from DS18B20 for( i=0; i<9; i++ ) { // Read the values inside of the ScratchPad array in the debugger window ScratchPad[i] = OW_ReadByte( WIRE_PORT ); } } OW_Reset( WIRE_PORT ); OW_WriteByte( WIRE_PORT, SKIPROM ); // Skip ROM Code matching OW_WriteByte( WIRE_PORT, CONVERTTEMP ); // Read ROM Code from DS18B20 OW_Reset( WIRE_PORT ); OW_WriteByte( WIRE_PORT, SKIPROM ); // Skip ROM Code matching OW_WriteByte( WIRE_PORT, READSCRATCHPAD ); // Read ScratchPad from DS18B20 LowByte = OW_ReadByte( WIRE_PORT ); HighByte = OW_ReadByte( WIRE_PORT ); // Thanks again "Mr. Anderson" for this code TReading = ( HighByte << 8 ) + LowByte; SignBit = TReading & 0x8000; // test most sig bit if ( 1 == SignBit ) // negative { TReading = (TReading ^ 0xffff) + 1; // 2's comp } Tc_100 = ( 6 * TReading ) + TReading / 4; // multiply by (100 * 0.0625) or 6.25 Whole = Tc_100 / 100; // separate off the whole and fractional portions Fract = Tc_100 % 100; // ********************************************************************************************************** // ***** This won't work so I am commenting it out (zeke) ***** // ***** A serial ring buffer and interrupt servicing routines is needed to make this work ***** // ***** // ***** Read the "Whole" and "Fract" values with your debugger ***** // ********************************************************************************************************** // this will print the tempature in an int8 over serial every 1 second. // TimerA_UART_tx( Whole ); // TimerA_UART_tx( Fract ); // ********************************************************************************************************** // insert a breakpoint here and observe the variables in the debugger watch window // ********************************************************************************************************** delayMicroseconds( 1000000 ); } } int OW_Reset( int Pin ) { int presence; delayMicroseconds( 0 ); // delay for 0us digitalWrite( Pin, LOW ); pinMode( Pin, OUTPUT ); delayMicroseconds( 480 ); // delay for 480us pinMode( Pin, INPUT ); delayMicroseconds( 70 ); // delay for 70us if( 0 == digitalRead( WIRE_PORT ) ) { presence = TRUE; // Presense pulse detected } else { presence = FALSE; // ds18b20 is not there } delayMicroseconds( 410 ); // delay for 410us return ( presence ); // return the sampled presence pulse result } // Peter Anderson wrote this void OW_WriteByte( int Pin, char d ) { char n; for(n=8; n!=0; n--) { if ( (d & 0x01) == 1 ) { digitalWrite( Pin, LOW ); pinMode( Pin, OUTPUT ); delayMicroseconds( 5 ); pinMode( Pin, INPUT ); delayMicroseconds( 60 ); } else { digitalWrite( Pin, LOW ); pinMode( Pin, OUTPUT ); delayMicroseconds( 60 ); pinMode( Pin, INPUT ); } d = d >> 1; } } // Peter Anderson wrote this char OW_ReadByte( int pin ) { char d, n, b; for ( n=0; n<8; n++ ) { digitalWrite( pin, LOW ); pinMode( pin, OUTPUT); delayMicroseconds( 5 ); pinMode( pin, INPUT ); delayMicroseconds( 5 ); b = digitalRead( pin ); delayMicroseconds( 50 ); d = (d >> 1) | (b << 7); // shift d to right and insert b in most sig bit position } return(d); } //------------------------------------------------------------------------------ // Arduino like digitalRead, pinMode, and digitalWrite helper functions. //------------------------------------------------------------------------------ char digitalRead( char Pin ) { // Read P1IN and mask it with the 1wPin then shift it to the LSB position return ( (P1IN & (1 << Pin) ) >> Pin ); } void pinMode( int pin, int out ) { if( 1 == out ) { P1DIR |= (1 << pin); } else { P1DIR &= (~(1 << pin)); } } void digitalWrite(int Pin, int Bit) { if ( 1 == ( Bit ) ) { P1OUT |= ( 1 << Pin ); // if the Bit is HIGH then drive the 1wBus HIGH } else { P1OUT &= ( ~(1 << Pin) ); // if the Bit is LOW then drive the 1wBus LOW } } //------------------------------------------------------------------------------ // Function configures Timer_A for full-duplex UART operation //------------------------------------------------------------------------------ void TimerA_UART_init(void) { TACCTL0 = OUT; // Set TXD Idle as Mark = '1' TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode } //------------------------------------------------------------------------------ // Outputs one byte using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_tx(unsigned char byte) { while (TACCTL0 & CCIE); // Ensure last char got TX'd TACCR0 = TAR; // Current state of TA counter TACCR0 += UART_TBIT; // One bit time till first bit TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int txData = byte; // Load global variable txData |= 0x100; // Add mark stop bit to TXData txData <<= 1; // Add space start bit } //------------------------------------------------------------------------------ // Timer_A UART - Transmit Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A0_ISR(void) { static unsigned char txBitCnt = 10; TACCR0 += UART_TBIT; // Add Offset to CCRx if (txBitCnt == 0) // All bits TXed? { TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt txBitCnt = 10; // Re-load bit counter } else { if (txData & 0x01) { TACCTL0 &= ~OUTMOD2; // TX Mark '1' } else { TACCTL0 |= OUTMOD2; // TX Space '0' } txData >>= 1; txBitCnt--; } } //------------------------------------------------------------------------------ // Timer_A UART - Receive Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch ( __even_in_range(TAIV, TAIV_TAIFG) ) // Use calculated branching { case TAIV_TACCR1: // TACCR1 CCIFG - UART RX TACCR1 += UART_TBIT; // Add Offset to CCRx if (TACCTL1 & CAP) // Capture mode = start bit edge { TACCTL1 &= ~CAP; // Switch capture to compare mode TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0 } else { rxData >>= 1; if (TACCTL1 & SCCI) // Get bit waiting in receive latch { rxData |= 0x80; } rxBitCnt--; if (rxBitCnt == 0) // All bits RXed? { rxBuffer = rxData; // Store in global variable rxBitCnt = 8; // Re-load bit counter TACCTL1 |= CAP; // Switch compare to capture mode __bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR) } } break; } } And here's ds18b20.h #ifndef DS18B20_H_ #define DS18B20_H_ // 'tick' values // Compute these from DalSemi AN126 xls worksheet //int A,B,C,D,E,F,G,H,I,J; #define tA 6 #define tB 64 #define tC 60 #define tD 10 #define tE 9 #define tF 55 #define tG 0 #define tH 480 #define tI 70 #define tJ 410 // 1-Wire ROM Command Codes #define SEARCHROM 0xF0 #define READROM 0x33 #define MATCHROM 0x55 #define SKIPROM 0xCC #define ALARMSEARCH 0xEC // DS18B20 Function Commands #define CONVERTTEMP 0x44 #define WRITESCRATCHPAD 0x4E #define READSCRATCHPAD 0xBE #define COPYSCRATCHPAD 0x48 #define RECALLEE 0xB8 #define READPOWERSUPPLY 0xB4 #endif /*DS18B20_H_*/ Again, make sure you calibrate the DCO for 16MHz if you're using a value line device. Enjoy! lvagasi, touch and bluehash 3 Quote Link to post Share on other sites
touch 34 Posted February 4, 2011 Share Posted February 4, 2011 I just gave your code a try but I'm only getting "3" printed out over my serial, any idea what this means? Quote Link to post Share on other sites
zeke 693 Posted February 4, 2011 Author Share Posted February 4, 2011 Hmmm... I guess I should have stated that I do not use the serial communications. It's not set up properly. The variables Whole and Fract are hexadecimal values and therefore need to be prepared before serial transmission. Specifically, they have to be converted into ASCII representation or else they will look like crap on your terminal program (unless it can display raw hex values). Still, if a serial terminal received 0x0d or 0x0a then your cursor would jump around. The way I'm checking the ds18b20 values is with my debugger. I stop the program at the delayMicroseconds(1000000) and then look at the value of the local variables in the watch window. In order to make the serial transmission work, a serial port TX ring buffer and supporting interrupt routines would have to be created. I will comment out the serial tx calls in my main loop so that I don't mislead people. Quote Link to post Share on other sites
touch 34 Posted February 4, 2011 Share Posted February 4, 2011 I'm using RealTerm, that lets me view the "RAW" serial data, I was outputting it as a 8bit int, but tried hex and am still getting "03". I also gave the debugger a try and here's what I'm seeing: Quote Link to post Share on other sites
zeke 693 Posted February 4, 2011 Author Share Posted February 4, 2011 I'm not sure if the program is properly reading your ds18b20. This is what I see: Look at the Tc_100 value. The value of Whole is the first two digits and Fract is the last two digits. It's important to note that the ds18b20 has to have a strong pullup during the temperature conversion process. I did this by wiring the Vdd pin to 3.6V because it was easier for me. This means the ds18b20 is not in parasitic mode. If you run it in parasitic mode then you have to apply a strong pullup during the conversion step. This is figure 4 on page 6 of the ds18b20 datasheet. How do you have your ds18b20 hooked up? Quote Link to post Share on other sites
zeke 693 Posted February 4, 2011 Author Share Posted February 4, 2011 Okay, just for you Touch, I buffed the serial port TX routines. I'm assuming that you only have RealTerm to debug stuff. If the ds18b20 gives a reading of 0x016c then: 1. Tc_100 = 0d2275 (22.75'C) 2. Whole = 0d22 = 0x16 3. Fract = 0d75 = 0x4b When RealTerm is in raw hex mode, you should be see the following repeat every one second: <0x01><0x06><0x04><0x0b><0x32><0x32><0x37><0x35><0x20> You should get sensible results as long as your ds18b20 is being read properly. #include #include "ds18b20.h" #include "types.h" #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0) #define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A) #define UART_TBIT_DIV_2 (16000000 / (9600 * 2)) #define UART_TBIT (16000000 / 9600) #define delayMicroseconds(n) __delay_cycles(n<<4) // The One Wire bus is connected to this pin #define WIRE_PORT 7 //Remember you need a 4.7k pullup resistor here. #define LOW 0 #define HIGH 1 #define INPUT 0 #define OUTPUT 1 #define FALSE 0 #define TRUE 1 //Zeke's mod's int OW_Reset( int Pin ); void OW_WriteByte(int Pin, char d); char OW_ReadByte(int Pin); // Routines written by Peter H Anderson // http://www.phanderson.com/arduino/ds18b20_1.html char digitalRead( char Pin ); void pinMode( int Pin, int Out ); void digitalWrite( int Pin, int Bit ); // Software UART routines void TimerA_UART_init( void ); UINT8 UART_putHexByte( UINT8 data); UINT8 UART_PutDec32( UINT32 data); void TimerA_UART_tx( UINT8 byte ); unsigned int txData; // UART internal variable for TX unsigned char rxBuffer; // Received UART character void main(void) { // int temp = 0; int i; int ROMCode[8]; int ScratchPad[9]; int HighByte, LowByte, TReading, SignBit, Tc_100, Whole, Fract; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; P1OUT = UART_RXD; // RXD as IN P1SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins P1DIR = UART_TXD; TimerA_UART_init(); __enable_interrupt(); while ( 1 ) { if ( 1 == OW_Reset( WIRE_PORT ) ) { OW_WriteByte( WIRE_PORT, 0x33 ); // Read ROM Code from DS18B20 for( i=0; i<8; i++ ) { // Read the values inside of the ROMCode array in the debugger window ROMCode[i] = OW_ReadByte( WIRE_PORT ); } } if ( 1 == OW_Reset( WIRE_PORT ) ) { OW_WriteByte( WIRE_PORT, SKIPROM ); // Skip ROM Code matching OW_WriteByte( WIRE_PORT, CONVERTTEMP ); // Read ROM Code from DS18B20 OW_Reset( WIRE_PORT ); OW_WriteByte( WIRE_PORT, SKIPROM ); // Skip ROM Code matching OW_WriteByte( WIRE_PORT, READSCRATCHPAD ); // Read ScratchPad from DS18B20 for( i=0; i<9; i++ ) { // Read the values inside of the ScratchPad array in the debugger window ScratchPad[i] = OW_ReadByte( WIRE_PORT ); } } OW_Reset( WIRE_PORT ); OW_WriteByte( WIRE_PORT, SKIPROM ); // Skip ROM Code matching OW_WriteByte( WIRE_PORT, CONVERTTEMP ); // Read ROM Code from DS18B20 OW_Reset( WIRE_PORT ); OW_WriteByte( WIRE_PORT, SKIPROM ); // Skip ROM Code matching OW_WriteByte( WIRE_PORT, READSCRATCHPAD ); // Read ScratchPad from DS18B20 LowByte = OW_ReadByte( WIRE_PORT ); HighByte = OW_ReadByte( WIRE_PORT ); // Thanks again "Mr. Anderson" for this code TReading = ( HighByte << 8 ) + LowByte; SignBit = TReading & 0x8000; // test most sig bit if ( 1 == SignBit ) // negative { TReading = (TReading ^ 0xffff) + 1; // 2's comp } Tc_100 = ( 6 * TReading ) + TReading / 4; // multiply by (100 * 0.0625) or 6.25 Whole = Tc_100 / 100; // separate off the whole and fractional portions Fract = Tc_100 % 100; //this will print the tempature in an int8 over serial every 1 second. UART_putHexByte( Whole ); // Transmit the hex value UART_putHexByte( Fract ); UART_PutDec32( Tc_100 ); // Transmit the decimal value TimerA_UART_tx( ' ' ); // Transmit a space character // insert a breakpoint here and observe the variables in the watch window delayMicroseconds( 1000000 ); } } int OW_Reset( int Pin ) { int presence; delayMicroseconds( 0 ); // delay for 0us digitalWrite( Pin, LOW ); pinMode( Pin, OUTPUT ); delayMicroseconds( 480 ); // delay for 480us pinMode( Pin, INPUT ); delayMicroseconds( 70 ); // delay for 70us if( 0 == digitalRead( WIRE_PORT ) ) { presence = TRUE; // Presense pulse detected } else { presence = FALSE; // ds18b20 is not there } delayMicroseconds( 410 ); // delay for 410us return ( presence ); // return the sampled presence pulse result } // Peter Anderson wrote this void OW_WriteByte( int Pin, char d ) { char n; for(n=8; n!=0; n--) { if ( (d & 0x01) == 1 ) { digitalWrite( Pin, LOW ); pinMode( Pin, OUTPUT ); delayMicroseconds( 5 ); pinMode( Pin, INPUT ); delayMicroseconds( 60 ); } else { digitalWrite( Pin, LOW ); pinMode( Pin, OUTPUT ); delayMicroseconds( 60 ); pinMode( Pin, INPUT ); } d = d >> 1; } } // Peter Anderson wrote this char OW_ReadByte( int pin ) { char d, n, b; for ( n=0; n<8; n++ ) { digitalWrite( pin, LOW ); pinMode( pin, OUTPUT); delayMicroseconds( 5 ); pinMode( pin, INPUT ); delayMicroseconds( 5 ); b = digitalRead( pin ); delayMicroseconds( 50 ); d = (d >> 1) | (b << 7); // shift d to right and insert b in most sig bit position } return(d); } //------------------------------------------------------------------------------ // Arduino like digitalRead, pinMode, and digitalWrite helper functions. //------------------------------------------------------------------------------ char digitalRead( char Pin ) { // Read P1IN and mask it with the 1wPin then shift it to the LSB position return ( (P1IN & (1 << Pin) ) >> Pin ); } void pinMode( int pin, int out ) { if( 1 == out ) { P1DIR |= (1 << pin); } else { P1DIR &= (~(1 << pin)); } } void digitalWrite(int Pin, int Bit) { if ( 1 == ( Bit ) ) { P1OUT |= ( 1 << Pin ); // if the Bit is HIGH then drive the 1wBus HIGH } else { P1OUT &= ( ~(1 << Pin) ); // if the Bit is LOW then drive the 1wBus LOW } } UINT8 UART_putHexByte(UINT8 data) { unsigned char nibble; nibble = (data>>4) & 0x0F; if (nibble<10) { nibble=nibble+'0'; } else { nibble = nibble-10+'a'; } TimerA_UART_tx( nibble ); nibble = data & 0x0F; if (nibble<10) { nibble = nibble+'0'; } else { nibble = nibble-10+'a'; } TimerA_UART_tx( nibble ); return 1; } UINT8 UART_PutDec32(UINT32 data) { UINT32 divisor, result, remainder; UINT8 leading; leading=1; remainder = data; for(divisor = 1000000000; divisor > 0; divisor /= 10) { result = remainder / divisor; remainder %= divisor; if (result) leading=0; if (!leading||(divisor==1)) TimerA_UART_tx((UINT8)(result) + '0'); } return 1; } //------------------------------------------------------------------------------ // Function configures Timer_A for full-duplex UART operation //------------------------------------------------------------------------------ void TimerA_UART_init(void) { TACCTL0 = OUT; // Set TXD Idle as Mark = '1' TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode } //------------------------------------------------------------------------------ // Outputs one byte using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_tx(unsigned char byte) { while (TACCTL0 & CCIE); // Ensure last char got TX'd TACCR0 = TAR; // Current state of TA counter TACCR0 += UART_TBIT; // One bit time till first bit TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int txData = byte; // Load global variable txData |= 0x100; // Add mark stop bit to TXData txData <<= 1; // Add space start bit } //------------------------------------------------------------------------------ // Timer_A UART - Transmit Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A0_ISR(void) { static unsigned char txBitCnt = 10; TACCR0 += UART_TBIT; // Add Offset to CCRx if (txBitCnt == 0) // All bits TXed? { TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt txBitCnt = 10; // Re-load bit counter } else { if (txData & 0x01) { TACCTL0 &= ~OUTMOD2; // TX Mark '1' } else { TACCTL0 |= OUTMOD2; // TX Space '0' } txData >>= 1; txBitCnt--; } } //------------------------------------------------------------------------------ // Timer_A UART - Receive Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch ( __even_in_range(TAIV, TAIV_TAIFG) ) // Use calculated branching { case TAIV_TACCR1: // TACCR1 CCIFG - UART RX TACCR1 += UART_TBIT; // Add Offset to CCRx if (TACCTL1 & CAP) // Capture mode = start bit edge { TACCTL1 &= ~CAP; // Switch capture to compare mode TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0 } else { rxData >>= 1; if (TACCTL1 & SCCI) // Get bit waiting in receive latch { rxData |= 0x80; } rxBitCnt--; if (rxBitCnt == 0) // All bits RXed? { rxBuffer = rxData; // Store in global variable rxBitCnt = 8; // Re-load bit counter TACCTL1 |= CAP; // Switch compare to capture mode __bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR) } } break; } } This is types.h. You'll need it. #ifndef TYPES_H_ #define TYPES_H_ //** Exportable Constants and Types ******************************************/ typedef unsigned char UINT8; /* Type for 8 bit unsigned integer */ typedef unsigned char UCHAR; /* Type for 8 bit unsigned integer */ typedef unsigned int UINT16; /* Type for 16 bit unsigned integer */ typedef unsigned long UINT32; /* Type for 32 bit unsigned integer */ typedef signed char CHAR; /* Type for 8 bit signed integer */ typedef signed char INT8; /* Type for 8 bit signed integer */ typedef signed int INT16; /* Type for 16 bit signed integer */ typedef signed long INT32; /* Type for 32 bit signed integer */ //typedef float FLOAT32; /* Type for 32 bit floating point */ //typedef double FLOAT64; /* Type for 64 bit floating point */ //typedef enum //{ // FALSE = 0, // TRUE = 1 //} BOOL, MBOOL; #endif /*TYPES_H_*/ Does it go? Quote Link to post Share on other sites
zeke 693 Posted February 5, 2011 Author Share Posted February 5, 2011 Okay, I found all my serial port gear. Here's a screen cap of realterm with the code running: I forgot that realterm does not format the raw data like I suggested above. I see ASCII encoded data in that string: 17122318 Where: 17 = 0x17 12 = 0x12 2318 = 23.18'C Do you get something like this? Quote Link to post Share on other sites
zeke 693 Posted February 5, 2011 Author Share Posted February 5, 2011 If you find realterm less than adequate then give this program a try. It looks a little more refined. GeekDoc 1 Quote Link to post Share on other sites
touch 34 Posted February 5, 2011 Share Posted February 5, 2011 Alright, I gave your newest code a try. I am hooking it up using a 4.7k pullup resistor from VCC to DQ. it's not in parasitic power mode. Heres the results I got: 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 032b343 0332350 033e362 0344368 0344368 033e362 034b375 0344368 0351381 034b375 0344368 033e362 033e362 0338356 0338356 0338356 0338356 0338356 0338356 0332350 0332350 0332350 0332350 0332350 0332350 0332350 0332350 032b343 032b343 032b343 0332350 0344368 033e362 0338356 0338356 0332350 0332350 0332350 0344368 0344368 034b375 0344368 033e362 033e362 0338356 0338356 0338356 0338356 0338356 The changes you see in the results are simply caused breathing on the sensor to change the temperature. I've tried all of my sensors to see if I had a bad one with the same results, I don't think all of my sensors could be bad. Thanks for taking your time to debug my problems! Quote Link to post Share on other sites
zeke 693 Posted February 5, 2011 Author Share Posted February 5, 2011 Touch, Let's simplify this. Modify the main loop so only these lines are transmitting out the serial port: UART_PutDec32( Tc_100 ); // Transmit the decimal value TimerA_UART_tx( 0x0A ); // Transmit a space character TimerA_UART_tx( 0x0D ); This is what I get: It's 21.75'C in my room. What's yours look like? Quote Link to post Share on other sites
touch 34 Posted February 6, 2011 Share Posted February 6, 2011 I'm getting 331~, that is obliviously incorrect because its not only missing some bits, but its not 90F~ degrees in my room! After studying the datasheets, I believe I may have been sent the wrong version of chips. I noticed that the DS1820/DS18S20 is ONLY a 9bit chip, and I'm getting a 9 bit output, the DS18B20's have a configurable resolution however. Furthermore, the DS1820/DS18S20 have longer conversion times, and that could be why I'm getting some funky readings randomly. Question, what are your chips stamped with? Mine just says DS1820. Thanks! EDIT: Yep, just confirmed based on the address of my device that it is a DS18S20, looks like I got sent the wrong ones. Oh well, time to get it working. I wonder why its reporting the temperature so far off though, looking at the datasheets there's not much difference other than the temperature resolution. Quote Link to post Share on other sites
zeke 693 Posted February 6, 2011 Author Share Posted February 6, 2011 Since you have a ds18s20, the math for the temperature conversion is different. It's different because the bit resolution is 0.5'C per bit (9 bit mode). The ds18b20 is 0.125'C per bit (12 bit mode). If we adjust the conversion math then you'll get the correct results. First, add these to the top of your file: #define DS18B20 0x28 #define DS18S20 0x10 Then adjust the temperature conversions procedure to this instead: if( ROMCode[7] == DS18B20 ) { Tc_100 = ( 6 * TReading ) + TReading / 4; // multiply by (100 * 0.0625) or 6.25 } else if ( ROMCode[7] == DS18S20 ) { Tc_100 = ( 5 * TReading ); // multiply by (100 * 0.05) or 5 } It's not the best code since I assume it's one or the other sensor (not wise). The family code is derived from the LSByte of the ROM Code. In the case of my code, ROMCode[7]. You could also do this: switch ( ROMCode[7] ) { case DS18B20: Tc_100 = ( 6 * TReading ) + TReading / 4; // multiply by (100 * 0.0625) or 6.25 break; case DS18S20: Tc_100 = ( 5 * TReading ); // multiply by (100 * 0.05) or 5 break; default: Tc_100 = 0; break; } That will take care of the condition when you pull out your temp sensor while the unit is still running. What do you get now? touch 1 Quote Link to post Share on other sites
touch 34 Posted February 6, 2011 Share Posted February 6, 2011 zeke, it works perfect now. I did need to make one change to your code: ROMCode[7] should be ROMCode[0]. Thanks again for all the help you've provided, its definitely helping me learn. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.