/**** IR Mrakomer 4 ****/#define VERSION "4.0"#define ID "$Id: irmrak3.c 1215 2008-08-08 12:25:25Z kakl $"#include "irmrak4.h"#define DOME PIN_B4 // Dome controll port#define SA 0x00 // Slave Address (0 for single slave / 0x5A<<1 default)#define RAM_Access 0x00 // RAM access command#define RAM_Tobj1 0x07 // To1 address in the eeprom#define RAM_Tamb 0x06 // Ta address in the eeprom#define HEATING PIN_B3 // Heating for defrosting#define MAXHEAT 10 // Number of cycles for heating#define MAXOPEN 10 // Number of cycles for dome open#bit CREN = 0x18.4 // USART registers#bit SPEN = 0x18.7#bit OERR = 0x18.1#bit FERR = 0x18.2char VER[4]=VERSION;char REV[50]=ID;int8 heat;int8 open;unsigned char PEC_calculation(unsigned char pec[]) // CRC calculation{unsigned char crc[6];unsigned char BitPosition=47;unsigned char shift;unsigned char i;unsigned char j;unsigned char temp;do{crc[5]=0; /* Load CRC value 0x000000000107 */crc[4]=0;crc[3]=0;crc[2]=0;crc[1]=0x01;crc[0]=0x07;BitPosition=47; /* Set maximum bit position at 47 */shift=0;//Find first 1 in the transmited messagei=5; /* Set highest index */j=0;while((pec[i]&(0x80>>j))==0 && i>0){BitPosition--;if(j<7){j++;}else{j=0x00;i--;}}/*End of while */shift=BitPosition-8; /*Get shift value for crc value*///Shift crc valuewhile(shift){for(i=5; i<0xFF; i--){if((crc[i-1]&0x80) && (i>0)){temp=1;}else{temp=0;}crc[i]<<=1;crc[i]+=temp;}/*End of for*/shift--;}/*End of while*///Exclusive OR between pec and crcfor(i=0; i<=5; i++){pec[i] ^=crc[i];}/*End of for*/} while(BitPosition>8);/*End of do-while*/return pec[0];}/*End of PEC_calculation*/int16 ReadTemp(int8 addr, int8 select) // Read sensor RAM{unsigned char arr[6]; // Buffer for the sent bytesint8 crc; // Readed CRCint16 temp; // Readed temperaturedisable_interrupts(GLOBAL);i2c_stop();i2c_start();i2c_write(addr);i2c_write(RAM_Access|select); // Select the teperature sensor in devicei2c_start();i2c_write(addr);arr[2]=i2c_read(1); // loarr[1]=i2c_read(1); // hitemp=MAKE16(arr[1],arr[2]);crc=i2c_read(0); //crci2c_stop();enable_interrupts(GLOBAL);arr[5]=addr;arr[4]=RAM_Access|select;arr[3]=addr;arr[0]=0;if (crc != PEC_calculation(arr)) temp=0; // Calculate and check CRCreturn temp;}void delay(int16 cycles){int16 i;if (open>0)for(i=0; i<cycles; i++) {output_toggle(DOME); delay_us(100);}elsefor(i=0; i<cycles; i++) {output_low(DOME); delay_us(100);}restart_wdt();}void main(){unsigned int16 n, temp, tempa;signed int16 ta, to;output_low(HEATING); // Heating offsetup_wdt(WDT_2304MS); // Setup Watch Dogsetup_adc_ports(NO_ANALOGS);setup_adc(ADC_OFF);setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);setup_timer_1(T1_DISABLED);setup_timer_2(T2_DISABLED,0,1);setup_comparator(NC_NC_NC_NC);setup_vref(FALSE);// setup_oscillator(OSC_4MHZ|OSC_INTRC,+2); // Pokud je nutna kalibrace RCoscsetup_oscillator(OSC_4MHZ|OSC_INTRC);delay_ms(1000);restart_wdt();printf("\n\r* Mrakomer %s (C) 2007 KAKL *\n\r",VER); // Welcome messageprintf("* %s *\n\r",REV);printf("<#seq.> <ambient temp.> <space temp.> <status>\n\r\n\r");tempa=ReadTemp(SA, RAM_Tamb); // Dummy readtemp=ReadTemp(SA, RAM_Tobj1);n=0;heat=0;open=0;// enable_interrupts(GLOBAL);// enable_interrupts(INT_RDA);restart_wdt();while(TRUE){while(kbhit()) getc(); // Flush USART bufferCREN=0; CREN=1; // Reinitialise USARTdo{delay(10000);if (heat>0){output_high(HEATING);heat--;}else{output_low(HEATING);}if (open>0) open--;} while (!kbhit());{char ch;ch=getc();switch (ch){case 'h':heat=MAXHEAT; // Needs heatingbreak;case 'c':heat=0; // Needs colderbreak;case 'o':open=MAXOPEN; // Open the domebreak;case 'l':open=0; // Lock the domebreak;}}n++; // Increment the number of measurementtempa=ReadTemp(SA, RAM_Tamb); // Read temperatures from sensortemp=ReadTemp(SA, RAM_Tobj1);ta=tempa*2-27315; // °K -> °Cto=temp*2-27315;{ // printfchar output[30];int8 j;sprintf(output,"#%Lu %Ld %Ld %u %u\n\r\0", n, ta, to, heat, open);j=0;while(output[j]!=0){delay(50);putc(output[j++]);output_toggle(DOME);}}}}