This project covers the automation of long-term data collection using a small and simple solar collector as the source of the data (see Figure 22.1).
There is a constant need for automated data logging because there are many times when we need instruments and controllers that can gather information unattended over long periods of time and simultaneously control a related function or two. We learn how to do this project with a solar data collector, which is the subject of this chapter.
Dr. Sun of Peking Polytechnic University in Beijing, China is running a project for the United Nations to determine how much energy is available from the sun on a yearly basis at every location around the world. He has asked the chairman of our electronics department to look into how you and your fellow students might help in this endeavor. A very simple and inexpensive way to collect the data automatically is desired. Many thousands of units will be needed and the budget is limited, so he is not looking for the most accurate instruments in the world but has stressed that he does want reliability. This investigation is being made as a direct result of Dr. Sun’s request.
In this exercise, we will build a small solar collector that will let us collect valuable data over an extended period of time automatically. The solar collector will have a ventilation fan built into it to reduce the temperature within the collector when it gets past a certain temperature, so as to more accurately reflect the collection conditions in a collector. The fan will be controlled by our controller. We will also keep track of the (inside) temperature of the air moved by the fan so we can determine how much energy the collector is ejecting. We will not actually measure how much air the fan moves. Instead, Dr. Sun’s team will make an estimate of that during the analysis phase of the work.
Figure 22.1 A solar collector for a data logging project.
Figure 22.2 shows a single-line schematic of the collector with the sensors and other ancillary equipment for initial review as we proceed with the discussion.
The efficiency of a “hot air” solar collector decreases as the temperature inside it increases. In temperate climates, the maximum temperature can rise above 400°F in a commercial solar collector. If the energy is not removed from the collector, no more energy
Figure 22.2 Overall schematic of our solar collector. (See the wiring diagram in Figure 22.3 for further details.)
will be collected. The collector ceases to collect further energy for a number of reasons that do not concern us here. Our interest is focused on how to remove energy from the collector so we can maximize the amount of energy that can be collected. We can do this by adding a small cooling fan, like one recycled from an old computer cabinet, to move the air through the collector. We could also add a couple of fabric check valves at the inlet and outlet to keep the air from blowing backwards through the collector when the fan is off, if necessary. We will use 135°F always (adj) as the max permitted temperature in our experiment to reflect residential heating conditions. We will turn the fan on if the internal temperature reaches 135°F but this temperature can be made adjustable by comparing it to the reading on one of the onboard potentiometers (the set point).
We will collect the data once every minute to get an accurate profile of how much energy the collector captures during the day. Let’s assign 1 byte to each digit we have to collect, even though we are aware that the data could be packed much more tightly. The temperature will be read in degrees Fahrenheit so we will need 3 bytes for the temperature. The information we collect consists of the following data points:
1. Date and time of day, 12 bytes (YYMMDDHHMMSS)
2. Temperature inside the cabinet, 3 bytes (TTT)
3. Whether the fan is on or off, 1 byte (F = 0 or 1)
These 16 bytes have to be collected 60 times an hour all day and all night. (We are collecting nighttime data to allow Dr. Sun to estimate the heating needs in the area during evenings.) We have to collect an average of 23,040 (16 × 60 × 24) bytes every day. To make things move along and to allow for overhead and so on, let’s say that we need space for 25K of data every day in round numbers, which would be 9125K of data in a year. Not a large amount of data considering the capability of even the smallest computers on the market, and within reach of storage in an MCU-based engine without any external storage if we could add a modest amount of memory to the MCU. We could ship the data to Dr. Sun at the Peking all these also need to be changed to keep with Beijing elsewhere Polytechnic University in Beijing on a CD-ROM or over the Internet, if the collection point has Web access. (We should contact Dr. Sun to inform him that the project could very easily be modified to collect the data every 30 seconds, or even more often, at no additional cost.)
Our preceding calculations have indicated that the problem is completely within our reach and so we can proceed with the fabrication of our collector and the design of the hardware and software we will need to get the job done. The drawings for the collector are on the Web site that supports this text, so we will not go into fabrication details here. Our interest is in the electronics and the software, but you are encouraged to make up a rudimentary collector to see how the project comes together. A few sheets of cardboard, a bit of sheet Styrofoam, a few scraps of wood, and some plastic sheeting will make a surprisingly effective collector that you can experiment with.
For the complete project, we need the items shown in Table 22.1:
Study the wiring diagram in Figure 22.3 to get familiar with how the various components are wired to the LAB-X1 before starting on the fabrication.
Since it would be a major expense and effort for each student to design and build a controller for this project, and since we already have a LAB-X1 available to us, we will use the LAB-X1 as the controller for the project. This will limit what we can do a bit but since the main function of the exercise is data collection, this will not distract from the experience we are seeking.
In order to use the LAB-X1, we need to make the following changes/modifications to the board:
1. Add a clock chip in U6.
2. Add a crystal for the clock chip at J5.
3. Add headers to the LAB-X1 at P1, P2, P3, and P4 so we can connect to the MCU as needed.
The diagram in Figure 22.2 reflects the modifications that have to be made. Of particular interest is the fact that there are three potentiometers on the board that can interfere with our using the three lines that they are connected to for reading any inputs. However, the potentiometers can be used to modify variables we are using (for example, the temperature at which we turn on the fan), and we can still use the lines for I/O if we set the potentiometers to appropriate intermediate positions. If we do that, the inputs will be able to override the intermediate settings and we can read the input. (The program as written does not use these pots, but you should be aware that this can be done.)
Figure 22.3 Wiring diagram for the solar collector instrument/controller/data transmitter.
Note The software listings are written as if the controller was a LAB-X1 board so that a new board does not have to be created to execute the requirements of the experiment. A much more versatile system could be created if a new board was designed. Since the major problem with the LAB-X1 is the fact that there are three pots already attached to the analog input lines, the circuit layout for this experiment must reflect this.
The devices we will be using are to be attached as follows:
The temperature will be read from PORTA.5.
The clock uses the NJU6355 chip and is located as shown on the LAB-X1 schematic at U6.
A 32.786-KHz crystal must be added to the board at J5 to support the clock.
The fan switch will be at PORTD.3.
The interface to the computer will be the DB9 connector on the board.
The LCD display addresses will be the standard LCD addresses for the board.
The software for the solar collector has to perform the following functions:
Provide a clock function (with the hardware addition)
Read the temperature sensor
Make minor decisions / Control the fan
Send the data to the computer periodically
Recover from power outages automatically
The hardware needed to support these functions is shown on the wiring diagram in Figure 22.2, with all the pins that will be used identified.
If there is no battery backup, the clock must have an arbitrary starting time so the recovery from a power outage can be effected based on the data collected during the previous and following day. When the data is analyzed, any reset/discontinuity of the clock will indicate a power outage and the readings will have to be adjusted for time of day based on extrapolation from the daily cycles. Dr. Sun has indicated that these functions are to be performed when the data is finally analyzed by his group in Beijing.
Let’s write the software as subroutines, one for each function. Each of the subroutines needs to have some preliminary work done up front during the setup of the program, and this is listed separately before each subroutine.
First, let’s set up the LCD as we always do. Then, we can call the code out as a subroutine in the program where we need it. See Program 22.1.
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 ;
The subroutines called in the preceding code are developed in the following section. A short description precedes each code listing.
SETTING THE INTERNAL CLOCK
There are seven registers of interest in the NJU6355 clock module. They contain the following pieces of information:
Year
Month
Date
Day
Hours
Minutes
Seconds
As programmed for this experiment, the clock is set to 01 Jan, 2007 on startup, and after every power failure. It can, of course, be set to any date and time you choose, and it will not affect the results of our experiments in that we are not using the exact time/date information as such, but rather the daily cycle of the collected data. Even missing a day or two of data would not adversely affect our effort.
We have no way of intervening to set the clock if/when there is a power failure, so we set the clock to the beginning of the year 2007 on startup and whenever there is a power failure. Later on, when the data is analyzed, we can use the temperature data and number of data points since the last night cycle to determine the approximate time of day for each recovery. Fortunately, the exact time at which the readings are taken is not important in this particular investigation.
Note There is a provision for a battery backup for the clock on the LAB-X1, and a battery could be provided to keep the clock going during power failures if this was desired. However, chances are, the batteries will not be easily available in many parts of the less-developed world where data must be gathered, so we should take that into consideration.
The “date data” does not show up on the display but is sent to the computer along with the other data as a matter of course during each transmission to the PC.
The clock is seen as a set of memory locations by the MCU. The actual locations will depend on the clock chip we select. For this application, we have selected the NJU6355 IC chip. The use of this chip is explained in some detail in Chapter 7. We read the clock but the exact actual time is not of interest because we do not have a way to reset to the correct time after a power failure. Our interest is in the time that has elapsed since the last sunrise and since the last power failure. We can estimate the actual time from the information gathered for the day if we know the first date that the data was collected. (The program segment to read the IC is taken from a program on the microEngineering Labs Web site.)
The routine to send the data to the computer looks at the seconds value, and then every minute, based on the changes in the registers, it sends the relevant information to the computer for storage.
The initialization code for the clock module is shown in Program 22.2.
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 ;
On the LAB-X1, there are seven lines, distributed across ports A and E, that can be used for analog inputs. Lines A.0, A.1, and A.3 are connected to the three pots on the card and so cannot be used. Line A.2 is being used by the real-time clock, and line A.4 is not available for analog input (open collector). This leaves only line A.5 as a free analog input line (this is analog channel 4). Lines on port E are being used to control the display and are thus not available to us. Accordingly, we will use the channel 4 line for reading the internal temperature of the collector.
The initialization code for reading the sensor is as follows:
; define the A2D set up
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
READ THE SENSORS
The routine in Program 22.4 reads each sensor and stores its value in its appropriate variable. The Display Routine will read these values from the variables and put them in the display when necessary.
Program 22.4 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 ;
CONTROLLING THE FAN
This routine looks at the internal temperatures, and if the temperature is above 135°F, it turns the fan on. 135°F approximates the temperature of the air coming out of a residential furnace in winter. See Program 22.5.
We will use pin D.3 to control the solid state relay so we can see the condition of the relay on the bargraph when the relay is turned on. Some relays have an LED on them, some don’t. We will be covered in either case.
Program 22.5 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 ;
UPDATING THE LCD
During each 1-second cycle, the system reads all the variables to appear on the LCD and displays them. It turns the fan on and off as necessary. The display is a convenience for the operation of the system. It can accommodate two lines of 20 characters each and we will fill these in as follows:
D=YY:MM:DD:HH:MM:SS
TEMP=TTT FAN=X
This arrangement allows the investigator to look at current conditions at any time. If the investigator needs to know the actual time, they can look at a wrist watch. Program 22.6 implements the updating of the LCD.
Program 22.6 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 ;
The routine in Program 22.7 checks the time on the internal clock to determine when to send the data to the computer. It monitors the seconds display. When 1 minute has passed, the seconds go to 00. At that time, the program jumps to the Send routine and all the data to be recorded is sent to the computer for storage. Then, it pauses for 1 second to make sure it will not see 00 in the seconds counter again within this minute and continues.
Program 22.7 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 ;
If there has been a power failure, the appropriate compensation will be made when the data is analyzed. If for some reason the power is off for more than a day, there will be a problem with data lost for that day, but for an investigation of this kind that is not really critical.
When we combine all of the preceding routines in one listing, we get what’s shown in Program 22.8. This program is set up to record the data every 5 seconds so you can see what is going on both in the LAB-X1 and in the computer in real time. The computer must be set up as a dumb terminal to match the requirements of the output from the LAB-X1 for all this to work as desired. After you are sure the program is working as expected, you can change the time between transmissions to once a minute or whatever is desired.
Program 22.8 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 ;
In Program 22.8, the data is stored on disk in hexadecimal format. If you want it in decimal format, you have to read it into a program variable and then convert it to the desired format. As provided (in the compiler), the SEROUT instruction offers a limited choice for the data transfer as it was read in from the clock.
Note There is a certain amount of nonvolatile memory on the PIC 16F877A that could have been utilized to store power failure information for future analysis. However, because there is no provision that allows us to reset the clock accurately, the use of this memory cannot provide a more perfect solution.
PROBLEM!
When this program was sent to Dr. Sun, one of his students complained that the program was not completely correct. Can you find what he or she thinks the problem is? The answer is provided at the end of the support Web site.