bogdan.kecman Bogdan Kecman "specialist" Oracle srbistan
Član broj: 201406 Poruke: 15953 *.31.24.217.adsl2.beograd.com.
Sajt: mysql.rs
|
uh bre .. ovo je mnogo komplikovanije nego sto deluje ... elem, 18F2423 mcu je dosao umesto ovog 16F, najvise zato sto mi je zafalilo flash-a a zafalio mi je i jedan pin za jos jedan NTC a kako je ovo bio najmanji sledeci pic po fiokama ...
novosti
- dodat je output na rs232 port (ispisuje: prosecnu temperaturu ploce \t temperaturu na NTC1 *100 \t temperaturu na NTC2 *100 \t target temperatur *100 \t trenutnu vrednost PWM-a u % \t broj gresaka na RS232 portu
- RS232 izlaz moze da se iskljuci (zakomentarisati define __rs232__)
- LCD (2x16) moze da se iskljuci (zakomentarisati define)
- cita temperaturu sa 1 ili sa 2 NTC-a, u eepromu je tabela za RT16 i GT204 za 10bitno i 12bitno konvertovanje
- PID koeficijenti su u eepromu (zadnjih 12 bajtova)
- moguce je odabrati "autotuning" mod pravljen uz ogromnu Jovanovu pomoc (covek mi je poslao ceo diplomski rad, sazvakan + je izgubio cudo vremena pokusavajuci da mi objasni kako to sve radi i kako se koristi prokleti matlab da se to izsimulira i pronadju pravi koeficijenti) .. na zalost taj deo jos nije gotov potpuno posto ja nisam bas sve skapirao kako treba (davno sam ucio matematiku, a na ovim "business administration" fakultetima ne uce racun uopste :( ) ... sve u svemu, provalicu ja to (uz jos malo smaranja Jovana) pa ce i to da proradi :)
- temperatura sa ADC-a (oba) se "uprosecuje" pa se vuce kroz NF filter
- temperatura "srednja" se vadi kao prosek sa ADC-ova (jednog ili dva zavisi od define-ova) pa se vuce opet kroz NF (i to malo jaci) kako bi se uklonilo smece koga obicno ima (izlaz je ovde sada idealno gladak)
- temperatura se sampluje jednom u sekundi (moze i 2 puta ako ima potrebe)
- kontrolna funkcija (PID ili AutoTune) se poziva svakih 4.x sekundi (moze bez promene oscilatora na 8sec da se podigne) iz RTCC interrupta
- PWM ima rezoluciju od 0.2xsec (moze da se smanji step rezolucije po potrebi, ovo je najveci step koji moze sa ovim oscilatorom) i kontrolise signal u periodi od 20*0.2xsec (oko 4sec), to je lako promeniti u define-u i naravno radi u interruptu
toliko za sada .. kad nabudzim ovaj auto tuning javljam se sa novim sorsom :D
ako neko ima nekih ideja, slusam :)
(joj sto ruzno izgleda ovaj sors na crnom skinu, ko je pravio css mogao bi to da "opravi")
Code (c):
/***************************************************
* Project: Hot Bed controller with 18F2423
* Author: Bogdan Kecman <arhimed [at] gmail [dot] com>
* Licence: GPL
*
* $Revision: 18 $
*
***************************************************/
#case
#TYPE SIGNED
#include <18F2423.h> // \\192.168.89.1\public\Dokumenti\Elektronika\PIC18\PIC18F2423-2523-4423-4523.PDF
#device adc=12
#use fast_io (B)
#include <math.h>
#define BUTTON1 PIN_B0
#define BUTTON2 PIN_B1
#define HEATER_PIN PIN_C2
#define HEATER_ON output_low(HEATER_PIN)
#define HEATER_OFF output_high(HEATER_PIN)
//how many bits for adc
#define __ADC12__
//#define __ADC10__
//use self tuning controller
//#define __selftuning__
//use encoder
#define __encoder__
//be i2c slave
#define __i2cslave__
//log temperature on serial port
#define __rs232__
//use LCD
#define __USELCD__
//use thermistor GT204 (200K)
#define __GT204__
//use thermistor 135-104LAG-J01 (100K)
#define __RT16__
#ifdef __GT204__
#define TEMPS_start_gt 2
#define TEMPS_gt 28
#define ADCCH_gt 0
#endif
#ifdef __RT16__
#define TEMPS_start_rt 0x3A
#define TEMPS_rt 30
#define ADCCH_rt 1
#endif
//#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES NOWDT
#FUSES INTRC_IO //Internal RC Osc, no CLKOUT
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //Reset when brownout detected
#FUSES NOPUT //No Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOIESO //Internal External Switch Over mode disabled
#FUSES FCMEN //Fail-safe clock monitor enabled
#FUSES NOPBADEN //PORTB pins are configured as digital I/O on RESET
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#FUSES NOCPB //No Boot Block code protection
#FUSES NOLPT1OSC //Timer1 configured for high-power operation
#FUSES MCLR
#FUSES NOXINST //Extended set extension and Indexed Addressing mode disabled
#use delay(internal=8M, RESTART_WDT)
#ifdef __rs232__
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,restart_wdt,ERRORS,DISABLE_INTS)
#endif
#ifdef __i2cslave__
#use i2c(Slave,Fast,sda=PIN_C4,scl=PIN_C3,restart_wdt,force_hw,address=0xBE)
#endif
volatile unsigned int8 j ;
volatile unsigned int16 adc_raw ;
volatile unsigned int16 adc_avg_rt ;
volatile unsigned int16 adc_avg_gt ;
volatile unsigned int16 target ;
volatile float current ;
volatile float current_rt ;
volatile float current_gt ;
volatile float temp_filtered ;
//EEPROM (256 bytes)
#ROM int8 0xF00000 ={
//target temp (80C)
0x40, 0x1F,
#ifdef __ADC10__
//2
//204-GT thermistor with 10K in voltage divider
0x7F,0xFF, 0x03,0xE7, 0x03,0xD8, 0x03,0xC2, 0x03,0xA3, 0x03,0x78, 0x03,0x42, 0x02,0xFF, 0x02,0xB3, 0x02,0x61, //0-90 //0==1009
0x02,0x0E, 0x01,0xBE, 0x01,0x74, 0x01,0x33, 0,252, 0,206, 0,168, 0,136, 0,111, 0,91, //100-190
0,75, 0,62, 0,51, 0,43, 0,36, 0,30, 0,26, 0,22, // 200-270
//135-104LAG-J01 thermistor with 10K in voltage divider
//0x3A
0xFF,0, 0x03,0xCE, 0x03,0xB3, 0x03,0x8E, 0x03,0x5D, 0x03,0x21, 0x02,0xDA, 0x02,0x8B, 0x02,0x3A, 0x01,0xEA, //0-90 //0==1009
0x01,0x9E, 0x01,0x5A, 0x01,0x1F, 0,237, 0,195, 0,160, 0,132, 0,111, 0,90, 0,77, //100-190
0,63, 0,54, 0,45, 0,39, 0,33, 0,28, 0,24, 0,21, 0,18, 0,16, // 200-290
#endif
#ifdef __ADC12__
//2
//204-GT thermistor with 10K in voltage divider
0x3F,0xFF, 0x0F,0xA0, 0x0F,0x64, 0x0F,0x0C, 0x0E,0x8D, 0x0D,0xE3, 0x0D,0x09, 0x0B,0xFF, 0x0A,0xCE, 0x09,0x86, //0-90
0x08,0x38, 0x06,0xF8, 0x05,0xD2, 0x04,0xCF, 0x03,0xF1, 0x03,0x37, 0x02,0x9F, 0x02,0x22, 0x01,0xBE, 0x01,0x6D, //100-190
0x01,0x2C, 0x00,0xF8, 0x00,0xCE, 0x00,0xAC, 0x00,0x91, 0x00,0x7A, 0x00,0x67, 0x00,0x58, //200-270
//135-104LAG-J01 thermistor with 10K in voltage divider
//0x3A
0x3F,0xFF, 0x0F,0x3B, 0x0E,0xCF, 0x0E,0x3B, 0x0D,0x78, 0x0C,0x85, 0x0B,0x69, 0x0A,0x2F, 0x08,0xE9, 0x07,0xA8, //0-90
0x06,0x7A, 0x05,0x69, 0x04,0x7B, 0x03,0xB3, 0x03,0x0B, 0x02,0x80, 0x02,0x10, 0x01,0xBD, 0x01,0x69, 0x01,0x33, //100-190
0x00,0xFC, 0x00,0xD8, 0x00,0xB3, 0x00,0x9B, 0x00,0x82, 0x00,0x71, 0x00,0x61, 0x00,0x55, 0x00,0x49, 0x00,0x41, //200-290
#endif
//0x76
'H','E','A','T',' ','B','E','D',' ','C','O','N','T','R','O','L',
//0x86
' ',' ',' ',' ',' ','v','5','.','0',
#ifdef __encoder__
'e',
#else
' '
#endif
#ifdef __selftuning__
' ',' ','A','U','T','O',
#else
' ',' ',' ','P','I','D',
#endif
//0x96
'T','a','r','g','e','t',':',' ',' ',' ','0','0','.','0','0','C',
//0xA6
'C','u','r','r','e','n','t',':',' ',' ','0','0','.','0','0','C',
//0xB6
0,0,
//B8
0,0,0,0,
0,0,0,0,
//C0
0,0,0,0,
0,0,0,0,
//C8
0,0,0,0,
0,0,0,0,
//D0
0,0,0,0,
0,0,0,0,
//D8
0,0,0,0,
0,0,0,0,
//E0
0,0,0,0,
0,0,0,0,
//E8
0,0,0,0,
0,0,0,0,
//F0
0,0,0,0,
0x7A,0x4C,0xCC,0xCD, //Pid (0.05)
//F8
0x73,0x51,0xB7,0x17, //pId (0.0004)
0x71,0x51,0xB7,0x17 //piD (0.0001)
}
#define init1 0x76
#define init2 0x86
#define gen1 0x96
#define gen2 0xA6
#define Paddr 0xF4
#define Iaddr 0xF8
#define Daddr 0xFC
//pwm period in timer1 ticks
#define PWM_PERIOD 20
volatile float pwm =0;
#INT_TIMER1 //~0.2sec
void TIMER1_isr (){
static unsigned int16 PWM_POS =0;
if (PWM_POS < PWM_PERIOD * pwm ){
HEATER_ON ;
} else {
HEATER_OFF ;
}
if (++PWM_POS > PWM_PERIOD ) PWM_POS = 0;
}
//Timer 0 (RTCC) overflow //~4.19424
// CONTROLLER
#ifdef __selftuning__
//AUTO TUNING CONTROLLER WITH OBSERVER
//made using theory and examples from
//"Design of unconventional thermal process
// digital regulator with observer and with
// minimal process transition time" by Jovan Veselinovic
// NOT WORKING ATTM (I'm still trying to figure out
// how it should work)
//coefficients calculated by matlab script
#define p 0.7083
#define Ki 3.4287
#define K4 -1.9124
#define g1 0.2868
#define g2 0.2080
#define g3 0.1474
#define g4 0.1044
#int_RTCC
void controler (){
static float x_kapa_0_1 = 0.0;
static float x_kapa_0_2 = 0.0;
static float x_kapa_0_3 = 0.0;
static float x_kapa_0_4 = 0.0;
float x_kapa_1 ;
float x_kapa_2 ;
float x_kapa_3 ;
float x_kapa_4 ;
static float Uint , U ;
float current_temperature , target_temperature , error , temp ;
current_temperature = temp_filtered / 100.0;
target_temperature = target / 100.0;
//not sure why is error calculated like this
//paper talks about r(k) - c(k) but the example
//calculates the error like this
error = 1 - current_temperature / target ;
//this might be the proper way to calculate error
//error = target - current_temperature;
temp = current_temperature - x_kapa_0_1 ;
//observer coefficients
x_kapa_1 = current_temperature ; //What is the point, this one is never used
x_kapa_2 = x_kapa_0_2 + p * temp ;
x_kapa_3 = x_kapa_0_3 + p *p * temp ;
x_kapa_4 = x_kapa_0_4 + p *p *p * temp ;
//control value (U defines how "strong" you need to drive the target)
Uint = Uint + Ki * error ;
U = Uint - Ki * ( x_kapa_2 + x_kapa_3 ) - K4 *x_kapa_4 ;
//estimate future changes / fix coefficients
x_kapa_0_1 = x_kapa_2 +g1 *U ;
x_kapa_0_2 = x_kapa_3 +g2 *U ;
x_kapa_0_3 = x_kapa_4 +g3 *U ;
x_kapa_0_4 = p *x_kapa_4 +g4 *U ;
//wind up (there's no force cooling so negative value is not usable
//and we calculate with maximum U value of 3)
if (U > 3) U = 3;
if (U < 0) U = 0;
pwm = U / 3.0; //PWM value (heater control) is in 0-1 range so scale U
}
#else
float Pf ; //0.0500
float If ; //0.0004
float Df ; //0.0001
#int_RTCC
void pid (){
float error ;
float derivative ;
static float error_sum =0;
static float error_prev =0;
//P
error = target /100.0 - temp_filtered /100.0 ;
//I
error_sum += error ;
//D
derivative = error - error_prev ;
pwm = error * Pf + error_sum * If + derivative * Df ;
error_prev = error ;
//engolf it between 0 and 1
if (pwm < 0){
pwm = 0;
error_sum -= error ;
} else if (pwm > 1){
pwm = 1;
error_sum -= error ;
}
}
#endif
#ifdef __encoder__
volatile int8 encoder ;
//External interrupt
#int_ext
void detect_rb0_change () {
encoder = 1;
if (input (BUTTON1 ) == input (BUTTON2 ) ) {
if(target < 27000) target += 50;
} else {
if(target > 1500) target -= 50;
}
}
#endif
#ifdef __i2cslave__
BYTE incoming , state ;
BYTE address ;
BYTE buffer [4]; //[0] + [1]<<8 = TARGET TEMP; [2] + [3]<<8 = CURRENT TEMP
BYTE changed ;
#int_SSP
void SSP_isr (void) {
state = i2c_isr_state ();
if(state == 1){
incoming = i2c_read ();
address = incoming ;
if (address > 3) address = 0;
}
if(state == 2){
incoming = i2c_read ();
if (address > 1) address = 0; //only 0 and 1 are writable
buffer [address ] = incoming ;
if (address == 1) changed = 1;
}
if(state == 0x80){
i2c_write (buffer [address ]);
}
}
#endif
float eeprom_read_float (unsigned int16 addr )
{
float result ;
unsigned int8 *ptr =&result ;
unsigned int8 i ;
for (i =0;i <4;i ++)
*(ptr ++)=read_eeprom (addr ++);
return result ;
}
void eeprom_write_float (unsigned int16 addr , float data )
{
unsigned int8 *ptr =&data ;
unsigned int8 i ;
for (i =0;i <4;i ++)
write_eeprom (addr ++,*(ptr ++));
}
#ifdef __USELCD__
struct lcd_pin_map {
BOOLEAN analog1 ;
BOOLEAN analog2 ;
BOOLEAN rs ;
BOOLEAN enable ;
int data : 4;
} lcd ;
#locate lcd = getenv("sfr:PORTA")
#define set_tris_lcd(x) set_tris_a(x)
#define lcd_type 2
#define lcd_line_two 0x40
BYTE const LCD_INIT_STRING [4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
struct lcd_pin_map const LCD_WRITE = {1, 0,0,0,0x00}; // For write mode all pins are out
//struct lcd_pin_map const LCD_READ 0,0,0x0F}; // For read mode data pins are in
void lcd_send_nibble ( BYTE n ) {
lcd. data = n ;
delay_cycles (1);
lcd. enable = 1;
delay_us (2);
lcd. enable = 0;
}
void lcd_send_byte ( BYTE address , BYTE n ) {
lcd. rs = 0;
delay_us (100); //DELAY until LCD is ready
lcd. rs = address ;
delay_cycles (1);
delay_cycles (1);
lcd. enable = 0;
lcd_send_nibble (n >> 4);
lcd_send_nibble (n & 0xf);
}
void lcd_init () {
BYTE i ;
set_tris_lcd (LCD_WRITE );
lcd. rs = 0;
lcd. enable = 0;
delay_ms (15);
for(i =1;i <=3;++i ) {
lcd_send_nibble (3);
delay_ms (5);
}
lcd_send_nibble (2);
for(i =0;i <=3;++i )
lcd_send_byte (0,LCD_INIT_STRING [i ]);
}
#endif
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
// MEASURE TEMPERATURE
//////////////////////////////////////////////////////
//////////////////////////////////////////////////////
float getTemp (){
unsigned int16 tempVal ;
unsigned int16 lowValue ;
unsigned int16 highValue ;
unsigned int16 dataValue ;
unsigned int16 range ;
unsigned int16 max ;
unsigned int16 min ;
unsigned int32 adc_temp ;
unsigned int8 probes ;
float tmptemp ;
tmptemp = 0;
probes = 0;
#ifdef __GT204__
max = 0;
min = 0;
adc_temp = 0;
set_adc_channel (ADCCH_gt );
delay_ms (1);
for(j =0;j <34;j ++){
adc_raw = read_adc ();
if (min > adc_raw ) min = adc_raw ;
if (max < adc_raw ) max = adc_raw ;
adc_temp += adc_raw ;
delay_ms (1);
}
adc_raw = (adc_temp - min - max ) >> 5; //drop min and max read and get average from other 32
adc_avg_gt = (adc_avg_gt + adc_raw ) >> 1; //rudimentary low pass filter
for(j =1; j <TEMPS_gt ; ++j ){
tempVal = read_eeprom (TEMPS_start_gt + (j *2) );
tempVal = tempVal << 8;
tempVal = tempVal + read_eeprom (TEMPS_start_gt + (j *2) +1);
if (adc_avg_gt > tempVal ){
restart_wdt ();
lowValue = tempVal ;
highValue = read_eeprom (TEMPS_start_gt +(j -1)*2 );
highValue = highValue << 8;
highValue = highValue + read_eeprom (TEMPS_start_gt +(j -1)*2+1);
range = highValue - lowValue ;
dataValue = adc_avg_gt - lowValue ;
current_gt = j *1000.0 - dataValue * 1000.0 / (float)range ;
tmptemp += current_gt ;
probes ++;
break;
}
}
#endif
#ifdef __RT16__
max = 0;
min = 0;
adc_temp = 0;
set_adc_channel (ADCCH_rt );
delay_ms (1);
for(j =0;j <34;j ++){
adc_raw = read_adc ();
if (min > adc_raw ) min = adc_raw ;
if (max < adc_raw ) max = adc_raw ;
adc_temp += adc_raw ;
delay_ms (1);
}
adc_raw = (adc_temp - min - max ) >> 5; //drop min and max read and get average from other 32
adc_avg_rt = (adc_avg_rt + adc_raw ) >> 1; //rudimentary low pass filter
for(j =1; j <TEMPS_rt ; ++j ){
tempVal = read_eeprom (TEMPS_start_rt + (j *2) );
tempVal = tempVal << 8;
tempVal = tempVal + read_eeprom (TEMPS_start_rt + (j *2) +1);
if (adc_avg_rt > tempVal ){
restart_wdt ();
lowValue = tempVal ;
highValue = read_eeprom (TEMPS_start_rt +(j -1)*2 );
highValue = highValue << 8;
highValue = highValue + read_eeprom (TEMPS_start_rt +(j -1)*2+1);
range = highValue - lowValue ;
dataValue = adc_avg_rt - lowValue ;
current_rt = j *1000.0 - dataValue * 1000.0 / (float)range ;
tmptemp += current_rt ;
probes ++;
break;
}
}
#endif
if (probes > 0) return tmptemp / probes ;
return (55555); //error
}
void print_temp (int8 line , unsigned int16 temp ){ // temperature is *100
#ifdef __USELCD__
unsigned int8 x ;
//hundreds
x = (temp / 10000)%10;
if (x == 0) {
lcd_send_byte (0,0x80|(9+lcd_line_two *line ));
lcd_send_byte (1,' ');
} else {
x = x + 48;
lcd_send_byte (0,0x80|(9+lcd_line_two *line ));
lcd_send_byte (1, x );
}
restart_wdt ();
//tens
x = ((temp / 1000 ) % 10) + 48;
lcd_send_byte (0,0x80|(10+lcd_line_two *line ));
lcd_send_byte (1, x );
restart_wdt ();
//ones
x = ((temp / 100 ) % 10) + 48;
lcd_send_byte (0,0x80|(11+lcd_line_two *line ));
lcd_send_byte (1, x );
restart_wdt ();
// 1/10
x = ((temp / 10 ) % 10) + 48;
lcd_send_byte (0,0x80|(13+lcd_line_two *line ));
lcd_send_byte (1, x );
restart_wdt ();
// 1/100
x = (temp % 10) + 48;
lcd_send_byte (0,0x80|(14+lcd_line_two *line ));
lcd_send_byte (1, x );
restart_wdt ();
#endif
#ifdef __rs232__
printf("Current:\t%f\t%f\t%f\tTarget:\t%Lu\tPWM:\t%f\tERR:\t%i\r\n", current /100, current_gt , current_rt , target , pwm *100.0, rs232_errors );
#endif
}
#ifndef __encoder__
void menu (){
delay_ms (15);
if (!input (BUTTON1 )) if(target <27000) target += 50;
if (!input (BUTTON2 )) if(target >49) target -= 50;
if (!input (BUTTON1 ) && !input (BUTTON2 )){
write_eeprom (0, target & 0x00ff);
write_eeprom (1, target >> 8 );
}
print_temp (0, target );
delay_ms (15);
}
#endif
void setup (){
setup_oscillator (OSC_8MHZ |OSC_INTRC |OSC_31250 |OSC_PLL_OFF );
setup_adc_ports (AN0_TO_AN1 |VSS_VDD );
setup_adc (ADC_CLOCK_DIV_4 |ADC_TAD_MUL_20 );
//set_tris_a(0xff);
set_tris_b (0xff);
//set_tris_c(0xff);
//set_tris_d(0xff);
//setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256); // 1sec = (Fosc/4)/256 ticks; 1interrupt = 65545 ticks; 1interrupt = 65536 / (Fosc/1024) = (4MHz) 16.77696sec; (8MHz) 8.38848sec
setup_timer_0 (RTCC_INTERNAL |RTCC_DIV_128 ); // 1sec = (Fosc/4)/128 ticks; 1interrupt = 65545 ticks; 1interrupt = 65536 / (Fosc/512) = (4MHz) 8.38848sec; (8MHz) 4.19424sec
setup_timer_1 (T1_INTERNAL |T1_DIV_BY_8 ); // 1sec = (Fosc/4)/8 ticks; 1interrupt = 65545 ticks; 1interrupt = 65536 / (Fosc/32) = (4MHz) 0.52428sec; (8MHz) 0.26214sec
setup_timer_2 (T2_DISABLED ,0,1);
setup_timer_3 (T3_DISABLED );
setup_comparator (NC_NC_NC_NC );
setup_vref (FALSE );
enable_interrupts (INT_RTCC );
enable_interrupts (INT_TIMER1 );
#ifdef __encoder__
enable_interrupts (INT_EXT );
encoder = 0;
#endif
#ifdef __i2cslave__
enable_interrupts (INT_SSP );
#endif
#ifdef __USELCD__
lcd_init ();
#endif
set_tris_b (0x33);
HEATER_OFF ;
set_adc_channel (0);
enable_interrupts (GLOBAL );
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
// MAIN //
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
void main ()
{
setup ();
#ifdef __selftuning__
//read initial coefficient's from eeprom
#else
//read PID coefficients from eeprom
Pf = eeprom_read_float (Paddr );
If = eeprom_read_float (Iaddr );
Df = eeprom_read_float (Daddr );
#endif
target = read_eeprom (1);
target = target << 8;
target |= read_eeprom (0);
if (target > 30000) target = 7000;
current = 0;
temp_filtered = 0;
adc_raw = 0;
adc_avg_gt = 0;
adc_avg_rt = 0;
#ifdef __i2cslave__
changed = 0;
buffer [0]=buffer [1]=buffer [2]=buffer [3]=0;
address = 0;
#endif
#ifdef __USELCD__
for (j =0;j <16;j ++){
lcd_send_byte (0,0x80|j );
lcd_send_byte (1,read_eeprom (init1 +j ));
lcd_send_byte (0,0x80|(j +lcd_line_two ));
lcd_send_byte (1,read_eeprom (init2 +j ));
}
delay_ms (1000);
for (j =0;j <16;j ++){
lcd_send_byte (0,0x80|j );
lcd_send_byte (1,read_eeprom (gen1 +j ));
lcd_send_byte (0,0x80|(j +lcd_line_two ));
lcd_send_byte (1,read_eeprom (gen2 +j ));
}
print_temp (0, target );
#endif
output_high (PIN_C0 );
while (TRUE ){
output_toggle (PIN_C0 );
restart_wdt ();
current = getTemp ();
//filter temperature value for the PID controller (basic LF)
temp_filtered = ( temp_filtered *2.0 + current ) / 3.0;
print_temp (1, current );
delay_ms (855); //1sec "tuned"
#ifdef __encoder__
if(encoder ){
print_temp (0, target );
encoder = 0;
//store target value to eeprom
write_eeprom (0, target & 0x00ff);
write_eeprom (1, target >> 8 );
}
#else
if (!input (PIN_B0 ) || !input (PIN_B5 )) menu ();
#endif
#ifdef __i2cslave__
if (changed ){ //something came via I2C
target = buffer [1];
target = target << 8;
target |= buffer [0];
print_temp (0, target );
changed = 0;
}
//write data into buffer for I2C read
buffer [2] = (int16) floor(current ) & 0x00ff;
buffer [3] = (int16) floor(current ) / 256;
#endif
}
}
|