March 17, 2011
by abd445
|
Hello,
I am trying to build on to the weight scale project proposed in nerd kits, but instead of using python i am using C and I want to display the weight on the LCD that I got from nerdkits instead of the LCD of the weight scale. I tried this code but I am unable to display the weight. It just displays a constant number 01 and it doesnt change no matter how much pressure i put on the scale. Please give me any suggestions and help me.
Here's the code:
// seniordesign.c
// using NerdKits with ATmega168
// ****taken from example temperature sensor code
// and changed to apply to distance sensor EZ-4
// and then added weight scale to project *******
#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 -- height sensor analog input
// PC1 -- weight scale analog in
//
// PB4 - bridge excite
// PB3 - bridge excite
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() {
// set ADSC bit to get the conversion started
ADCSRA |= (1<<ADSC);
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);
return result;
}
double sampleToInches(uint16_t sample) {
// conversion ratio in INCHES/STEP:
// (5000 mV / 1024 steps) * (1 cm / 4.8828125 mV) * (0.3937 in / 1 cm)
// ^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^
// from ADC from EZ4 in/cm conversion
return (sample * (4937.5 / 1024.0 / 4.8828125 * 0.3937));
}
int main() {
// start up the LCD
lcd_init();
FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
lcd_home();
// set PB3, PB4 as outputs
DDRD |= (1<<PB3) | (1<<PB4);
// 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 distance data
uint16_t last_sample = 0;
double this_dist;
double dist_avg;
int8_t rounded;
uint8_t i;
// holder variables for weight scale
int16_t reading;
while(1) {
// ***********************DISTANCE SENSOR PART*********************
// take 100 samples and average them!
ADMUX = 0;
dist_avg = 0.0;
for(i=0; i<100; i++) {
last_sample = adc_read();
this_dist = sampleToInches(last_sample);
// add this contribution to the average
dist_avg = dist_avg + this_dist/100.0;
rounded = dist_avg;
}
// *************************WEIGHT SCALE PART**********************
ADMUX = 1;
// set polarity +-
PORTD |= (1<<PB3);
PORTD &= ~(1<<PB4);
// wait 5 time constants (bw=12kHz, T=13.2us)
delay_us(66);
// take reading
reading = adc_read();
//printf_P(PSTR("%d "), adc_read());
// set polarity -+
PORTD |= (1<<PB4);
PORTD &= ~(1<<PB3);
// wait 5 time constants (bw=12kHz, T=13.2us)
delay_us(66);
// take reading
reading = reading - adc_read();
//printf_P(PSTR("%d\r\n"), adc_read());
// send over serial port
//printf_P(PSTR("%d\r\n"), reading);
// 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("Distance: %.2f"), dist_avg);
lcd_write_string(PSTR("in. "));
lcd_line_three();
lcd_write_string(PSTR("Weight: "));
lcd_write_int16(reading);
// write message to serial port
//printf_P(PSTR("%.2f degrees F\r\n"), dist_avg);
}
return 0;
}
|