January 17, 2011
by missle3944
|
Hi Ive recently completed the tempsensor project and the blinking LED project and now I want to combine them both. I want to use the if else statement to turn on a LED when the temperature reaches over a certain point. This is my code but it receives numerous errors. I just thought I'd take a stab at it but it looks like it is a tuffy.
// tempsensor.c
// for NerdKits with ATmega168
// mrobbins@mit.edu
#define F_CPU 14745600
#include <stdio.h>
#include <math.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"
// PIN DEFINITIONS:
//
// PC0 -- temperature sensor analog input
void adc_init() {
// set analog to digital converter
// for external reference (5v), single ended input ADC0
ADMUX = 0;
// set analog to digital converter
// to be enabled, with a clock prescale of 1/128
// so that the ADC clock runs at 115.2kHz.
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
// fire a conversion just to get the ADC warmed up
ADCSRA |= (1<<ADSC);
}
uint16_t adc_read() {
// read from ADC, waiting for conversion to finish
// (assumes someone else asked for a conversion.)
// wait for it to be cleared
while(ADCSRA & (1<<ADSC)) {
// do nothing... just hold your breath.
}
// bit is cleared, so we have a result.
// read from the ADCL/ADCH registers, and combine the result
// Note: ADCL must be read first (datasheet pp. 259)
uint16_t result = ADCL;
uint16_t temp = ADCH;
result = result + (temp<<8);
// set ADSC bit to get the *next* conversion started
ADCSRA |= (1<<ADSC);
return result;
}
double sampleToFahrenheit(uint16_t sample) {
// conversion ratio in DEGREES/STEP:
// (5000 mV / 1024 steps) * (1 degree / 10mV)
// ^^^^^^^^^^^ ^^^^^^^^^^
// from ADC from LM34
return sample * (5000.0 / 1024.0 / 10.0);
}
int main() {
// start up the LCD
lcd_init();
FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
lcd_home();
// start up the Analog to Digital Converter
adc_init();
// start up the serial port
uart_init();
FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
stdin = stdout = &uart_stream;
// holder variables for temperature data
uint16_t last_sample = 0;
double this_temp;
double temp_avg;
uint8_t i;
while(1) {
if ( sample %.2f < 80) {
DDRC |= (1<<PC3);
// turn on YELLOw LED
PORTC |= (1<<PC3);
//delay for 500 milliseconds to let the light stay on
delay_ms(1000);
// turn off LED
PORTC &= ~(1<<PC3);
//delay for 500 milliseconds to let the light stay off
delay_ms(600);
}
else{
DDRC |= (1<<PC4);
// turn on RED LED
PORTC |= (1<<PC4);
//delay for 500 milliseconds to let the light stay on
delay_ms(1000);
// turn off LED
PORTC &= ~(1<<PC4);
//delay for 500 milliseconds to let the light stay off
delay_ms(1200);
}
// take 100 samples and average them!
temp_avg = 0.0;
for(i=0; i<100; i++) {
last_sample = adc_read();
this_temp = sampleToFahrenheit(last_sample);
// add this contribution to the average
temp_avg = temp_avg + this_temp/100.0;
}
// write message to LCD
lcd_home();
lcd_write_string(PSTR("ADC: "));
lcd_write_int16(last_sample);
lcd_write_string(PSTR(" of 1024 "));
lcd_line_two();
fprintf_P(&lcd_stream, PSTR("The Temp is %.2f"), temp_avg);
lcd_write_data(0xdf);
lcd_write_string(PSTR("F "));
// write message to serial port
printf_P(PSTR("%.2f degrees F\r\n"), temp_avg);
}
return 0;
}
|
January 17, 2011
by Ralphxyz
|
Move your code down below line 127 an use this_temp instead of sample.
That is my best guess without trying it.
Ralph |
January 17, 2011
by missle3944
|
Thanks Ralph,
for your suggestion, I got it to work because I put in the this_temp for sample temp. Now I am trying to display a message on the LCD. I am also trying to use the if else statement along with if and else but it wont work.
// tempsensor.c
// for NerdKits with ATmega168
// mrobbins@mit.edu
#define F_CPU 14745600
#include <stdio.h>
#include <math.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"
// PIN DEFINITIONS:
//
// PC0 -- temperature sensor analog input
void adc_init() {
// set analog to digital converter
// for external reference (5v), single ended input ADC0
ADMUX = 0;
// set analog to digital converter
// to be enabled, with a clock prescale of 1/128
// so that the ADC clock runs at 115.2kHz.
ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
// fire a conversion just to get the ADC warmed up
ADCSRA |= (1<<ADSC);
}
uint16_t adc_read() {
// read from ADC, waiting for conversion to finish
// (assumes someone else asked for a conversion.)
// wait for it to be cleared
while(ADCSRA & (1<<ADSC)) {
// do nothing... just hold your breath.
}
// bit is cleared, so we have a result.
// read from the ADCL/ADCH registers, and combine the result
// Note: ADCL must be read first (datasheet pp. 259)
uint16_t result = ADCL;
uint16_t temp = ADCH;
result = result + (temp<<8);
// set ADSC bit to get the *next* conversion started
ADCSRA |= (1<<ADSC);
return result;
}
double sampleToFahrenheit(uint16_t sample) {
// conversion ratio in DEGREES/STEP:
// (5000 mV / 1024 steps) * (1 degree / 10mV)
// ^^^^^^^^^^^ ^^^^^^^^^^
// from ADC from LM34
return sample * (5000.0 / 1024.0 / 10.0);
}
int main() {
// start up the LCD
lcd_init();
FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
lcd_home();
// start up the Analog to Digital Converter
adc_init();
// start up the serial port
uart_init();
FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
stdin = stdout = &uart_stream;
// holder variables for temperature data
uint16_t last_sample = 0;
double this_temp;
double temp_avg;
uint8_t i;
while(1) {
// take 100 samples and average them!
temp_avg = 0.0;
for(i=0; i<100; i++) {
last_sample = adc_read();
this_temp = sampleToFahrenheit(last_sample);
// add this contribution to the average
temp_avg = temp_avg + this_temp/100.0;
}
if (this_temp > 80) {
DDRC |= (1<<PC3);
// turn on RED LED
PORTC |= (1<<PC3);
//delay for 500 milliseconds to let the light stay on
delay_ms(500);
// turn off LED
PORTC &= ~(1<<PC3);
//delay for 500 milliseconds to let the light stay off
delay_ms(200);
}
if else (this_temp > 75) {
DDRC |= (1<<PC5);
// turn on GREEN LED
PORTC |= (1<<PC5);
//delay for 500 milliseconds to let the light stay on
delay_ms(1000);
// turn off LED
PORTC &= ~(1<<PC5);
//delay for 500 milliseconds to let the light stay off
delay_ms(1800);
}
else{
DDRC |= (1<<PC4);
// turn on RED LED
PORTC |= (1<<PC4);
//delay for 500 milliseconds to let the light stay on
delay_ms(1000);
// turn off LED
PORTC &= ~(1<<PC4);
//delay for 500 milliseconds to let the light stay off
delay_ms(1200);
}
// write message to LCD
lcd_home();
lcd_write_string(PSTR("ADC: "));
lcd_write_int16(last_sample);
lcd_write_string(PSTR(" of 1024 "));
lcd_line_two();
fprintf_P(&lcd_stream, PSTR("The Temp is %.2f"), temp_avg);
lcd_write_data(0xdf);
lcd_write_string(PSTR("F "));
// write message to serial port
printf_P(PSTR("%.2f degrees F\r\n"), temp_avg);
}
return 0;
}
|
January 18, 2011
by Ralphxyz
|
line 120 "if else (this_temp > 75) {"
What you need is "else if" or just else!
if else
The general format for these are,
if( condition 1 )
statement1;
else if( condition 2 )
statement2;
else if( condition 3 )
statement3;
else
statement4;
The else clause allows action to be taken where the condition evaluates as false (zero).
This is from http://gd.tuwien.ac.at/languages/c/programming-bbrown/c_025.htm
Ralph |
January 18, 2011
by Jalex
|
Hi
I see the line numbers in your code. Is there a way to make the program add in the line numbers? I have had to count down from the top to find errors shown in MakeFile. |
January 18, 2011
by glidestone
|
Lower Left hand corning of the Progamer's Notepad shows the line # your cursor is on. |
January 19, 2011
by SpaceGhost
|
Jalex, when using Programmer's Notepad click on the "View" menu, then click on "Line Numbers" ("checking" it). This will show all the line numbers for the program while you are working on it.
Dave |