Hello all! My apologies if I am not posting in the correct place, or if this thread is a repeat.
My problem is garbage data on tera term.
I'm working on an arduino uno r3 (atmega328p). I have been working my way back through the arduino starter kit doing the projects in atmel studio with true embedded c, after having done most of the projects in the arduino IDE. I am on project 3, the 'Love-O-Meter.' This project is an external temperature sensor, from which it calculates the temperature in degrees celsius, updates serial output with the temperature and makes 0-3 LEDs light up depending on the temperature.
The part that's giving me trouble is the serial output. The trickiness stems from the fact that the degrees celcius is a signed 32 bit number (float), but the serial line is designed to transmit 8 bit numbers. After a fair amount of looking around, I came across a solution for transmitting the data by using the union keyword so that there is an array of 4 1 byte chars occupying the same space in memory as the 32 bit floating point number, and then transmitting each of the chars one at a time. Without further ado, my code:
#include <avr/io.h> #define F_CPU 8000000UL #define FOSC 16000000UL #define USART_BAUDRATE 9600 #define BAUD_PRESCALE FOSC/16/USART_BAUDRATE - 1 int main(void) { // Set up analog input... ADMUX |= (1 << REFS0); ADCSRA |= ((1 << ADATE) | (1 << ADSC) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0) | (1 << ADEN)); // Set up timer... TCCR1B |= ((1 << CS10) | (1 << CS02)); // Set up Serial communication... UBRR0H = ((BAUD_PRESCALE) >> 8); UBRR0L = BAUD_PRESCALE; UCSR0B |= ((1 << TXEN0) | (1 << RXEN0)); UCSR0C |= ((1 << UCSZ01) | (1 << UCSZ00)); // Configure GPI/O pins 2, 3, and 4 as OUTPUT. DDRD |= ((1 << DDD4) | (1 << DDD3) | (1 << DDD2)); // Declare some variables uint16_t tempReading; float volts; union temperature_t { float degreesCelcius_f; char degreeesCelcius_c[4]; } temperature; // Main While Loop /* Once per second... * ... Calculate the temperature. * ... Update Serial communication * ... Control 3 LEDs */ while (1) { // Check to see if one second has passed. if (TCNT1 >= 31249) { // Reset the timer to 0. TCNT1 = 0; // Calculate the temperature in celcius. -50 <= degreesCelcius <= 450 tempReading = ((ADCH << 8) | ADCL); volts = (tempReading * 5.0) / 1024; temperature.degreesCelcius_f = (volts - 0.5) * 100; // Update Serial communications with the degreesCelcius... for (int i = 0; i < 4; i++) { while ( !(UCSR0A & (1 << UDRE0)) ) { } UDR0 = temperature.degreeesCelcius_c[i]; } // Turn LEDs ON/OFF to visually represent degreesCelcius. if (temperature.degreesCelcius_f < 15) { PORTD = 0x00; } else if (temperature.degreesCelcius_f < 25) { PORTD = ((1 << PORTD3) | (1 << PORTD2)); } else { PORTD = ((1 << PORTD4) | (1 << PORTD3) | (1 << PORTD2)); } } } }
I think the problem is on the receiving end. I am plugging the arduino board into my laptop via a USB cable and monitoring the serial data via tera term. Tera term setting are correct: 9600BAUD, 8 bit data, 1 stop bit and no parity... I must admit that after doing a few searches for combining the four bytes into a 32 bit number, I still have no real idea of how to do it...? Any help would be much appreciated.
By the way, I am aware that there is a internal temperature sensor on the atmega328p and my next project will be to reimplement the 'Love-O-Meter' with this internal sensor.