I have a program that reads temperature and pressure sensors and does internal ADC conversion on them, then save data to the EEPROM, then convert back to original value and display it on the LCD. The issue is that when I debug the program in Atmel, it seems to work fine. But, the code doesn't actually on my circuit. IT seems to only write and read the first 2 bytes properly, then just writes the same byte over and over.
Here's my code for writing data. I'm using the included eeprom.h
library, and writing a 16-bit value by splitting to lower and higher bytes.
void WriteToEEPROM(uint16_t value, int address){
uint8_t low_value = value;
uint8_t high_value = (value & 0xFF00) >> 8;
if ((address == 0) || (address == 100)){}
else {address++;}
while(!eeprom_is_ready()){}
eeprom_write_byte((uint8_t*)address, low_value);
while(!eeprom_is_ready()){}
address++;
eeprom_write_byte((uint8_t*)address, high_value);
while(!eeprom_is_ready()){}
}
This is the contents of the EEPROM after finishing writing values. Note that the value should not change because I'm keeping it constant. Correct values should be 0x134
at '0x0000' and 0x0073
at 0x0064
. I'm lost on why this is not working.
Any help is appreciated!
full code
#define __DELAY_BACKWARD_COMPATIBLE__
#define F_CPU 8000000UL
#define eeprom_is_ready()
#include <avr/io.h>
#include <avr/delay.h>
#include <stdint.h>
#include <avr/eeprom.h>
#include <stdio.h>
//******************LCD PROGRAM STARTS*********************//
#define LCD_DATA PORTD // port D is selected as LCD data port
#define ctrl PORTC // port C is selected as LCD command port
#define en PC2 // enable signal is connected to port D pin 7
#define rw PC1 // read/write signal is connected to port D pin 6
#define rs PC0 // register select signal is connected to port D pin 5
void LCD_cmd(unsigned char cmd);
void init_LCD(void);
void LCD_write(unsigned char data);
void LCD_write_string(char*str);
void WriteToEEPROM(uint16_t value, int address);
void scaled_delay(int delay){
_delay_ms(delay * 1000);
}
void setup(void){
DDRA = 0x00; //PORTA is set as an input
DDRD = 0xFF; //PORTD is set as an output
DDRC = 0xFF;
}
//Temperature sensor output connected to PA0
void ReadTemp(int address){
ADCSRA = ADCSRA | 0b10000111; //enable ADC, CLK/128 conversion speed
ADMUX = ADMUX | 0b01000000; //Use internal 2.56V Vref and PA0 as input, right-hand justified
ADCSRA |= (1 << ADSC); //start conversion
while(!(ADCSRA & (1 << ADIF))) {}
WriteToEEPROM(ADC, address);
}
//Temperature sensor output connected to PA1
void ReadPressure(int address){
ADCSRA = ADCSRA | 0b10000111; //enable ADC, CLK/128 conversion speed
ADMUX = ADMUX | 0b01000001; //Use AVCC and PA0 as input, right-hand justified
ADCSRA |= (1 << ADSC); //start conversion
while(!(ADCSRA & (1 << ADIF))){} // wait until process is finished
address = address + 100;
WriteToEEPROM(ADC, address);
}
void WriteToEEPROM(uint16_t value, int address){
uint8_t low_value = value;
uint8_t high_value = (value & 0xFF00) >> 8;
if ((address == 0) || (address == 100)){}
else {address++;}
while(!eeprom_is_ready()){}
eeprom_write_byte((uint8_t*)address, low_value);
while(!eeprom_is_ready()){}
address++;
eeprom_write_byte((uint8_t*)address, high_value);
while(!eeprom_is_ready()){}
}
void ReadEEPROM_Temp(uint8_t address){
uint8_t temp_value_low;
uint8_t temp_value_high;
char value_buffer_temp[100] = "";
if(address != 0) {address++;}
temp_value_low = eeprom_read_byte((uint8_t*)address);
address++;
temp_value_high = eeprom_read_byte((uint8_t*)address);
uint16_t temp_value = (temp_value_high << 8) | temp_value_low;
int temperature = (temp_value * 4.88) / 10;
sprintf(value_buffer_temp,"%s %d %s ", "Temp ", temperature, "C");
init_LCD();
LCD_cmd(0x0C);
_delay_ms(100);
LCD_write_string(value_buffer_temp);
}
void ReadEEPROM_Pres(uint8_t address){
uint8_t pres_value_low;
uint8_t pres_value_high;
char value_buffer_pres[100] = "";
if(address != 100) {address++;}
pres_value_low = eeprom_read_byte((uint8_t*)address);
address++;
pres_value_high = eeprom_read_byte((uint8_t*)address);
uint16_t pres_value = (pres_value_high << 8) | pres_value_low;
int v_out = (pres_value * 4.88)/1000;
int pressure = ((v_out/5.1) + 0.095) / 0.009;
sprintf(value_buffer_pres,"%s %d %s ", "Pres ", pressure, "kPa");
LCD_cmd(0xC0);
_delay_ms(100);
LCD_write_string(value_buffer_pres);
}
void init_LCD(void){
LCD_cmd(0x38);
// initialization in 8bit mode of 16X2 LCD
_delay_ms(1);
LCD_cmd(0x01);
// make clear LCD
_delay_ms(1);
LCD_cmd(0x02);
// return home
_delay_ms(1);
LCD_cmd(0x06);
// make increment in cursor
_delay_ms(1);
LCD_cmd(0x80);
// “8” go to first line and “0” is for 0th position
_delay_ms(1);
return;
}
//**************sending command on LCD***************//
void LCD_cmd(unsigned char cmd){
LCD_DATA = cmd; // data lines are set to send command
PORTC &= ~(1<<rs); // RS sets 0
PORTC &= ~(1<<rw); // RW sets 0
PORTC |= (1<<en); // make enable from high to low
_delay_ms(100);
PORTC &= ~(1<<en);
return;
}
//*****************write data on LCD*****************//
void LCD_write(unsigned char data){
LCD_DATA= data; // data lines are set to send command
PORTC |= (1<<rs); // RS sets 1
PORTC &= ~(1<<rw); // RW sets 0
PORTC |= (1<<en); // make enable from high to low
_delay_ms(100);
PORTC &= ~(1<<en);
return ;
}
//store address value of the string in pointer *str
void LCD_write_string(char *str) {
int i=0;
for(i; str[i]!=0; i++){
// loop will go on till the NULL character in the string
LCD_write(str[i]); // sending data on LCD byte by byte i++;
}
return;
}
int main(void)
{
setup();
int counter = 0;
while (1)
{
scaled_delay(1); //delay 1 hour
ReadTemp(counter); //get temperature reading
ReadPressure(counter); //get pressure reading
counter++; //keep track of number of conversions
//get reading 24 times
if(counter == 23){
counter = 0;
while (counter != 24)
{
ReadEEPROM_Temp(counter);
ReadEEPROM_Pres(counter + 100);
counter++;
}
counter = 0;
}
}
}