Making PIC Instruments and Controllers. Ancillary information |
06 Jan '09 |
Chapter 22 Logging data from a solar collector ; Program 22.1 Data logging CLEAR ; clear the RAM DEFINE OSC 4 ; define Osc Speed DEFINE LCD_DREG PORTD ; define the LCD connections DEFINE LCD_DBIT 4 ; as we always do DEFINE LCD_RSREG PORTE ; DEFINE LCD_RSBIT 0 ; DEFINE LCD_EREG PORTE ; DEFINE LCD_EBIT 1 ; LOW PORTE.2 ; ; TRISA = %00010000 ; set PORTA TRISB = %11110000 ; set PORTB TRISC = %11110000 ; set PORTC TRISD = %00000000 ; set PORTD TRISE = %00000000 ; set PORTE ADCON1= %00000111 ; don’t forget to set ADCON1 ; PAUSE 500 ; pause .500 second for LCD startup LCDOUT $FE, 1, “Clear” ; clear LCD, go to first line ; MAIN: ; GOSUB READ_CLOCK ; GOSUB READ_SENSORS ; GOSUB CONTROL_FAN ; GOSUB UPDATE_LCD ; IF RTCSEC =$00 THEN GOSUB SEND DATA ; send data when seconds read 00 GOTO MAIN ; END ; Program 22.2 Writing to the clock ; The alias pins are as follows CE VAR PORTA.2 ; CLK VAR PORTC.1 ; SDATA VAR PORTC.3 ; IO VAR PORTC.5 ; ; allocate variables RTCYEAR VAR BYTE ; RTCMONTH VAR BYTE ; RTCDATE VAR BYTE ; RTCDAY VAR BYTE ; RTCHR VAR BYTE ; RTCMIN VAR BYTE ; RTCSEC VAR BYTE ; set variables LOW CE ; disable RTC LOW CLK ; HIGH IO ; RTCYEAR=$07 ; RTCMONT=$01 ; RTCDATE=$01 ; RTCDAY=$01 ; RTCHR=$00 ; RTCMIN=$00 ; RTCSEC=$00 ; IO=1 ; set RTC to input CE=1 ; enable transfer ; Write to all 7 RTC registers, ; this is a reset condition SHIFTOUT SDATA, CLK, LSBFIRST, [RTCYEAR, RTCMONTH, RTCDATE,_ RTCDAY\4, RTCHR, RTCMIN, RTCSEC] Program 22.3 Reading the clock READ_CLOCK: ; clock reading subroutine IO=0 ; set RTC to output CE=1 ; enable transfer ; read all 7 RTC registers SHIFTIN SDATA, CLK, LSBPRE, [RTCYEAR, RTCMONTH, RTCDATE, RTCDAY\4,_ RTCHR, RTCMIN, RTCSEC] ; RETURN ; DEFINE ADC_BITS 8 ; set number of bits in result DEFINE ADC_CLOCK 3 ; set internal clock source (3=rc) DEFINE ADC_SAMPLEUS 50 ; set sampling time in uS ; define variables used INTEMP VAR BYTE Program 22.3 Reading the sensors READ_SENSORS: ; ADCIN 4, INTEMP ; read channel 4 into INTEMP if one of the pots ; is to modify this temp, add the code to read ; it in here. RETURN ; Program 22.4 Controlling the fan CONTROL_FAN: ; IF INTEMP >=135 THEN; if one of the pots is to modify this temp, ; add that logic here on this line. PORTD.3=1 ; ELSE ; PORTD.3=0 ; ENDIF ; RETURN ; Program 22.5 Updating the LCD UPDATE_LCD: ; LCDOUT $FE $80, “D=”, HEX2 RTCYEAR, “:”, HEX2 RTCMONTH, “:”, HEX2_ RTCDATE,” “,HEX2 RTCHR, “:”, HEX2 RTCMIN, “:”, HEX2 RTCSEC_ LCDOUT $FE $C0, “TEMP=”,DEC3 INTEMP,” FAN=”,DEC1 PORTD.3 RETURN ; Program 22.6 Sending data to the computer SEND_DATA: ; LCDOUT $FE, $80, “SENDING DATA “ ; LCDOUT $FE, $C0,” “ ; clears the line SEROUT PORTC.6, T2400, [RTCYEAR, RTCMONTH, RTCDATE, RTCHR, RTCMIN,_ RTCSEC, INTEMP, PORTD.3, 10, 13] ELSE ; ENDIF ; PAUSE 1000 ; RETURN Program 22.7 The finished program for the solar collector (Solar collector–based data logging) CLEAR ; clear the RAM DEFINE OSC 4 ; define osc speed INCLUDE “MODEDEFS.BAS” ; include shiftin/out modes DEFINE LCD_DREG PORTD ; define the LCD connections DEFINE LCD_DBIT 4 ; DEFINE LCD_RSREG PORTE ; DEFINE LCD_RSBIT 0 ; DEFINE LCD_EREG PORTE ; DEFINE LCD_EBIT 1 ; DEFINE ADC_BITS 8 ; set number of bits in result DEFINE ADC_CLOCK 3 ; set internal clock source (3=rC) DEFINE ADC_SAMPLEUS 50 ; set sampling time in us LOW PORTE.2 ; ; TRISA= %00111111 ; set PORTA TRISB= %00000000 ; set PORTB TRISC= %00000000 ; set PORTC TRISD= %00000000 ; set PORTD TRISE= %00000000 ; set PORTE ADCON1= %00000111 ; don’t forget to set ADCON1 ; alias pins are as follows CE VAR PORTA.2 ; Real time clock mode CLK VAR PORTC.1 ; SDATA VAR PORTC.3 ; IO VAR PORTC.5 ; ; allocate variables ; RTCYEAR VAR BYTE ; year RTCMONTH VAR BYTE ; month RTCDATE VAR BYTE ; date RTCDAY VAR BYTE ; day RTCHR VAR BYTE ; hour RTCMIN VAR BYTE ; minute RTCSEC VAR BYTE ; seconds INTEMP VAR BYTE ; temperature ; LOW CE ; disable RTC LOW CLK ; HIGH IO ; ADCON1 = 7 ; PORTA and e digital LOW PORTE.2 ; lcd r/w low = write ; set initial time to 00:00:00 am on 01/01/07 same will be true ; for all resets. RTCYEAR = $07 ; RTCMONTH = $01 ; RTCDATE = $01 ; RTCDAY= 2 ; RTCHR = 0 ; RTCMIN= 0 ; RTCSEC= 0 ; IO = 1 ; set RTC to input CE = 1 ; enable transfer ; write to the 7 RTC registers to initialize them SHIFTOUT SDATA, CLK, LSBFIRST, [RTCYEAR, RTCMONTH, RTCDATE,_ RTCDAY\4, RTCHR, RTCMIN] CE = 0 ; disable RTC PAUSE 500 ; pause .500 second for LCD LCDOUT $FE, 1, “CLEAR” ; clear LCD ; MAIN: ; GOSUB READ_CLOCK ; GOSUB READ_SENSORS ; GOSUB CONTROL_FAN ; GOSUB UPDATE_LCD ; GOSUB SEND_DATA ; GOTO MAIN ; ; READ_CLOCK: ; IO= 0 ; set RTC to output CE= 1 ; enable transfer ; read all 7 RTC registers SHIFTIN SDATA, CLK, LSBPRE, [RTCYEAR, RTCMONTH, RTCDATE, RTCDAY\4,_ RTCHR, RTCMIN, RTCSEC] CE = 0 ; disable RTC RETURN ; ; READ_SENSORS: ; ADCIN 4, INTEMP ; read channel 4 to intemp RETURN ; ; CONTROL_FAN: ; IF INTEMP=>135 THEN ; PORTD.3=1 ; ELSE ; PORTD.3=0 ; ENDIF ; RETURN ; ; UPDATE_LCD: ; LCDOUT $FE, $80, “TIME=”,HEX2 RTCHR, “:”, HEX2 RTCMIN, “:”, HEX2_ RTCSEC,” “ ; LCDOUT $FE, $C0, “TEMP=”,DEC3 INTEMP,” FAN=”,DEC1 PORTD.3 PAUSE 10 ; RETURN ; ; SEND_DATA: ; IF RTCSEC=$00 THEN ; LCDOUT $FE ,$80 ,”SENDING DATA“ ; LCDOUT $FE, $C0, ” “ ; ; in the next line we decide what we are going to ; send to the computer for storage. Day of week is omitted. SEROUT PORTC.6, T2400, [RTCYEAR, RTCMONTH, RTCDATE, RTCHR,_ RTCMIN, RTCSEC, INTEMP, PORTD.3, 10, 13] PAUSE 1100 ; so we are into the next second. ELSE ; do nothing ENDIF ; RETURN ; ; END ; Answer to the problem broulght up by Dr. Sun's student There are times when the fan can come on and we do not adequately cover the condition when it does. It can happen between data points and we miss the data. |
Program listings are listed in detail so you can see the code |