|
|
View previous topic :: View next topic |
Author |
Message |
colesha
Joined: 09 Jan 2012 Posts: 45
|
Temperature setpoint input to be read from eeprom |
Posted: Fri Jan 10, 2020 10:23 am |
|
|
Hello,
I want to make a code for an automatic temperature control. I want the temperature setpoint to be entered and saved by a push button. Am able to write 2 separate functions, one that sets writes the temperature to eeprom and displays it on the LCD, while the other is to read the saved temperature reference point, compare it with the actual temperature, then switch on or off the fan.
Here is my code, but am failing to integrate it into one program. some assistance please.
Code: |
#include <16F887.h>
#device ADC= 8
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock = 4000000)
#include <flex_lcd.c>
unsigned int8 minute, minute10;
void set()
{
lcd_putc('\f'); // LCD clear
//while(TRUE){
if(input(PIN_A1) == 0)
// Convert BCD to decimal
minute = minute + minute10 * 10;
// End conversion
lcd_putc('\f'); // LCD clear
lcd_gotoxy(2, 1); // Go to column 2 row 1
lcd_putc("Temp Setpoint:");
delay_ms(200);
while(TRUE){
if(input(PIN_A2) == 0)
minute++;
if(input(PIN_A3) == 0)
minute--;
if(minute > 80)
minute = 0;
lcd_gotoxy(8, 2); // Go to column 8 row 2
printf(lcd_putc,"%02u", minute);
if(input(PIN_A1) == 0)
break;
delay_ms(200);
}
lcd_putc('\f'); // LCD clear
lcd_gotoxy(4, 1); // Go to column 4 row 1
lcd_putc("Fan On Temp:");
delay_ms(200);
while(TRUE)
{
if(input(PIN_A0) == 0)
write_eeprom(2, minute); //write_eeprom(2);
int value;
value = read_eeprom(2);
lcd_gotoxy(8, 2); // Go to column 8 row 2
printf(lcd_putc,"%02u", value);
if(input(PIN_A1) == 0)
break;
delay_ms(200);
}
}
void main()
{
lcd_init();
float refin, numin, temp;
int1 flag;
setup_adc(ADC_CLOCK_INTERNAL); // Setup ADC
setup_adc_ports(sAN4);
for(;;) // Repeat always
{
set();
delay_ms(500);
int value;
refin = value; // Read temp. reference
set_adc_channel(4);
numin = read_adc();
temp = (numin*50)/256; // Calc. temperature
delay_ms(10);
lcd_putc("\n\f");
lcd_gotoxy(2, 1);
printf(lcd_putc," Temp = %3.0g ",temp); // Display temp.
delay_ms(10);
if (numin<(refin-10)) // Temp. too low
{
output_high(PIN_D1); // Heater on
output_low(PIN_D2); // Fan off
flag = 1;
}
if (flag==1)
lcd_putc("\nHEATER ON\n");
if (numin>(refin+10)) // Temp. too high
{ output_low(PIN_D1); // Heater off
output_high(PIN_D2); // Fan on
flag = 0;
}
if (flag==0)
lcd_putc("\nFAN ON\n");
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
Re: Temperature setpoint input to be read from eeprom |
Posted: Fri Jan 10, 2020 2:27 pm |
|
|
Make the changes shown below to read the refin value from eeprom:
colesha wrote: |
for(;;) // Repeat always
{
set();
delay_ms(500);
// int value; *** Remove this line ***
// refin = value; *** Remove this line ***
refin = read_eeprom(2); // *** Add this line ***
set_adc_channel(4);
numin = read_adc();
.
.
.
|
Also, you never initialize the variables 'minute' and 'minute10' to 0.
Also, you don't have to a test to prevent the user from making the time
go negative. If the user presses the button on pin A2, the minutes will
decrement down to 0, and then go to 0xFF, 0xFE, etc. You need to
prevent the minutes from being decremented if they are already at 0. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Fri Jan 10, 2020 3:07 pm |
|
|
this...
setup_adc(ADC_CLOCK_INTERNAL); // Setup ADC
is not correct.
according to ADC info on page 101 of the datasheet...
4: When the device frequency is greater than 1 MHz, the FRC clock source is only recommended if the
conversion will be performed during Sleep.
looking at table 9-1, Fosc/8 is the only, proper choice.
Jay |
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
Re: Temperature setpoint input to be read from eeprom |
Posted: Sat Jan 11, 2020 11:09 am |
|
|
PCM programmer wrote: | Make the changes shown below to read the refin value from eeprom:
for(;;) // Repeat always
{
set();
delay_ms(500);
// int value; *** Remove this line ***
// refin = value; *** Remove this line ***
refin = read_eeprom(2); // *** Add this line ***
set_adc_channel(4);
numin = read_adc();
.
.
.
|
Thanks for the help, this has worked for me. I made some slight change on top of your recommendation by putting the set(); before the for(;;);. it worked out perfectly.
However, i still have a challenge that what i want as the refin temperature is not the one at which the fan comes on, for example, if i want 50, i write it to the eeprom, but when i ran, the fan comes on at 15. I need some help on the conversion that what is in the eeprom matches what i expect. Thanks.
Quote: |
Also, you never initialize the variables 'minute' and 'minute10' to 0. Also, you don't have to a test to prevent the user from making the time
go negative. If the user presses the button on pin A2, the minutes will
decrement down to 0, and then go to 0xFF, 0xFE, etc. You need to
prevent the minutes from being decremented if they are already at 0. |
Yes, this one i have controlled it too. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Sat Jan 11, 2020 12:29 pm |
|
|
You should tell us WHAT temperature sensor you are using. I'm assuming it's an analog sensor whose reading is stored in 'numin'. It would be better to name it 'actual_temperature' and also rename 'refin' to 'setpoint_temperature'.
While you KNOW what the variables are used for, giving them better names helps others follow what you're trying to do.
I understand English is not everyone's first language, heck It is mine , and I've fought with it for 66 years !
There's a possible problem with some numbers being floating point and other being unsigned 8bit. Depending on the sensor, you should be using 'scaled integers'. They are faster, whole numbers and easy to do 'math' with.
Jay |
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
Re: Temperature setpoint input to be read from eeprom |
Posted: Sat Jan 11, 2020 12:41 pm |
|
|
PCM programmer wrote: | Make the changes shown below to read the refin value from eeprom:
for(;;) // Repeat always
{
set();
delay_ms(500);
// int value; *** Remove this line ***
// refin = value; *** Remove this line ***
refin = read_eeprom(2); // *** Add this line ***
set_adc_channel(4);
numin = read_adc();
.
.
.
Thanks for the help, this has worked for me. I made some slight Change on top of your recommendation by putting the set(); before the for(;;);. it worked out perfectly.
However, i still have a challenge that what i want as the refin temperature is not the one at which the fan comes on, for example, if i want 50, i write it to the eeprom, but when i ran, the fan comes on at 15. I need some help on the conversion that what is in the eeprom matches what i expect. Thanks. |
Quote: |
Also, you never initialize the variables 'minute' and 'minute10' to 0.
Also, you don't have to a test to prevent the user from making the time
go negative. If the user presses the button on pin A2, the minutes will
decrement down to 0, and then go to 0xFF, 0xFE, etc. You need to
prevent the minutes from being decremented if they are already at 0.
|
Yes, this one i have controlled it too. |
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Sat Jan 11, 2020 1:27 pm |
|
|
temtronic wrote: | You should tell us WHAT temperature sensor you are using. I'm assuming it's an analog sensor whose reading is stored in 'numin'. It would be better to name it 'actual_temperature' and also rename 'refin' to 'setpoint_temperature'.
While you KNOW what the variables are used for, giving them better names helps others follow what you're trying to do.
I understand English is not everyone's first language,heck It is mine , and I've fought with it for 66 years !
There's a possible problem with some numbers being floating point and other being unsigned 8bit. Depending on the sensor, you should be using 'scaled integers'. They are faster, whole numbers and easy to do 'math' with.
|
Jay, thanks for the response, am currently still using simulation in Proteus and the sensor to use is the LM35. I have changed the variables as advised. Kindly help or give more info about the numbers and scaled integers, am still new with CCS.
Code: |
void main()
{
lcd_init();
float actual_temp, setpoint_temp, temp;
int1 flag;
setup_adc(ADC_CLOCK_INTERNAL); // Setup ADC
setup_adc_ports(sAN4);
set_temp();
for(;;) // Repeat always
{
delay_ms(500);
lcd_putc("\n\f");
setpoint_temp = read_eeprom(2); // *** Add this line ***
set_adc_channel(4);
actual_temp = read_adc();
temp = (actual_temp*50)/256; // Calc. temperature
delay_ms(10);
lcd_putc("\n\f"); // clear lcd
lcd_gotoxy(2, 1);
printf(lcd_putc," Temp = %3.0g ",temp); // Display temp.
delay_ms(10);
if (actual_temp<(setpoint_temp-10)) // Temp. too low
{
output_high(PIN_D1); // Heater on
output_low(PIN_D2); // Fan off
flag = 1;
}
if (flag==1)
lcd_putc("\nHEATER ON\n");
if (actual_temp>(setpoint_temp+10)) // Temp. too high
{ output_low(PIN_D1); // Heater off
output_high(PIN_D2); // Fan on
flag = 0;
}
if (flag==0)
lcd_putc("\nFAN ON\n");
}
while(TRUE);
}
|
|
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Sat Jan 11, 2020 1:30 pm |
|
|
temtronic wrote: | this...
setup_adc(ADC_CLOCK_INTERNAL); // Setup ADC
is not correct.
according to ADC info on page 101 of the datasheet...
4: When the device frequency is greater than 1 MHz, the FRC clock source is only recommended if the
conversion will be performed during Sleep.
looking at table 9-1, Fosc/8 is the only, proper choice.
|
Some assitance please about the FRC |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jan 11, 2020 2:00 pm |
|
|
The A/D section of the PIC data sheet suggests using this delay:
Quote: | set_adc_channel(4);
delay_us(5); // *** Add this line here ***
numin = read_adc(); |
The A/D section of the PIC data sheet suggests this clock divisor
for your clock frequency:
Quote: | void main()
{
float refin, numin, temp;
int1 flag;
lcd_init();
setup_adc(ADC_CLOCK_DIV_8 ); // *** Use this parameter ***
setup_adc_ports(sAN4); |
Put in the lines in bold below, to display the values and help you
to debug your code:
Quote: | lcd_gotoxy(1, 1);
printf(lcd_putc, "num %3.2f ref %3.2f", numin, refin);
delay_ms(1000);
if (numin<(refin-10)) // Temp. too low
{
output_high(PIN_D1); // Heater on
output_low(PIN_D2); // Fan off
flag = 1;
}
|
|
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Sun Jan 12, 2020 5:00 am |
|
|
PCM programmer wrote: |
The A/D section of the PIC data sheet suggests using this delay:
set_adc_channel(4);
delay_us(5); // *** Add this line here ***
numin = read_adc();
The A/D section of the PIC data sheet suggests this clock divisor
for your clock frequency:
void main()
{
float refin, numin, temp;
int1 flag;
lcd_init();
setup_adc(ADC_CLOCK_DIV_8 ); // *** Use this parameter ***
setup_adc_ports(sAN4);
Put in the lines in bold below, to display the values and help you
to debug your code:
lcd_gotoxy(1, 1);
printf(lcd_putc, "num %3.2f ref %3.2f", numin, refin);
delay_ms(1000);
if (numin<(refin-10)) // Temp. too low
{
output_high(PIN_D1); // Heater on
output_low(PIN_D2); // Fan off
flag = 1;
}
|
Thanks sir. I want to share an attachment of all of it including the simulation, any improvements is highly appreciated, but i have no idea how it is done on this forum. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Sun Jan 12, 2020 5:30 am |
|
|
You need to use a 3rd party website to store then upload your pictures...
You should understand that Proteus is NOT a reliable, accurate simulator. While it may appear to function OK, it fails and gives wrong results with programs that are reasonably complicated or use peripherals.
Every Proteus schematic presented here over the years will NOT work as posted. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|