January 31, 2011
by Jalex
|
HI
I am just trying to count at the moment.
I have a 1K resister on PC1 to Vcc and one on PC2 to ground.
Both the counters(WindCnt, and Rain seen to count together.
Do I need to disable the pull-ups or is there something wrong with my code?
I think one should count and one should stay at 0.
Also the pin change statement on the LCD keeps toggling from high to low.
Of course the Temp works fine, that's your code.
// 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 "../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;
// MAKE PIN4 AN output
DDRC |= (1<<PC4);
// Make Pin1 pin2, and pin3 as an input
DDRC &= ~(1<<PC1);
DDRC &= ~(1<<PC2);
DDRC &= ~(1<<PC3);
DDRC &= ~(1<<PC5);
// int Result as 16 bit
// holder variables for temperature data
uint16_t last_sample = 0;
double this_temp;
double temp_avg;
uint8_t i;
// Hold Variables for Wind, Rain, and Direction
uint8_t WindCnt = 0;
uint8_t Rain = 0;
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;
}
// Write Info to LCD
lcd_home();
fprintf_P(&lcd_stream, PSTR("Temperature: %.2f"), temp_avg);
// lcd_write_data(0xdf);
lcd_write_string(PSTR("F"));
lcd_line_two();
if (PINC &= (1<<PC1)) {
fprintf_P(&lcd_stream, PSTR("Pin is High"));
}
else {
fprintf_P(&lcd_stream, PSTR("Pin is Low"));
}
lcd_line_three();
fprintf_P(&lcd_stream, PSTR("Wind Speed : %.3d"), WindCnt);
lcd_line_four();
fprintf_P(&lcd_stream, PSTR("Rain Fall: %.3d"), Rain);
if (PINC &= (1<<PC1)) {
WindCnt++;
} else { WindCnt = 0; }
if (PINC &= (1<<PC2)) {
Rain++;
} else { Rain = 0; }
// write message to serial port
// printf_P(PSTR("%.2f degrees F\r\n"), temp_avg);
delay_ms(1000);
}
return 0;
}
|