Activity How The Threephase Ac Alternator Program Works

This experiment samples, then plots, then increments the EEPROM address pointer to the next bank. The sampling can be done in one fell swoop, but the plotting is done by 10 separate calls to the Piot_it routine. We'll sample 10 data points for each channel, for a total of 40 data points in each bank. Then, we'll retrieve 4 samples at a time, one for each channel, and plot them, 10 times in all. For this reason, we need to keep track of whether Experiment 5 is currently taking samples, or plotting. A variable, mode, will help keep track of this state. Two constants, Plotting and Sampling, equal to 1 and 0, respectively, are introduced to abstract the state of the program. If mode is set to

Sampling, the program is in the middle of plotting our 10 samples. If mode is equal to Plotting, then the current bank of samples has been plotted, and it is time to take some more samples. Our program initializes the value of mode to Sampling, to force the program to take samples the first time through.

i ----- For Experiment 5: Three-Phase AC Alternator -----------

Plotting

CON

1

Sampling

CON

0

eepromAddr

VAR

dataPtr

'Word

eepromAddr =

$0000

plotCount

VAR

codePtr

'Nib

mode

VAR

Bit

mode = Sampl

ing

A select...case statement examines the mode variable. The first time through, it is equal to Sampling, so the program will take samples. Each phase gets its own subroutine to perform the sampling.

SELECT mode CASE Plotting plotCount = plotCount + 1 GOSUB Exp_5_Retrieve_For_Plotting IF (plotCount = 9) THEN mode = Sampling plotCount = 0

GOSUB Exp_5_Inc_EepromAddr ENDIF CASE Sampling

GOSUB Exp_5_Sample_Phase_3 GOSUB Exp_5_Sample_Phase_2 GOSUB Exp_5_Sample_Phase_1 GOSUB Exp_5_Sample_Rectified_Output GOSUB Exp_5_Retrieve_For_Plotting mode = Plotting ENDSELECT

Exp_5_End: RETURN

Exp_5_sample_Phase_3 is where we start taking samples of Phase 3 and store them into EEPROM. The first instruction activates CH3 of the A/D converter. Then, through a series of subroutine calls, we'll wait for the zero point, then the next peak, as shown in Figure 6-5.

Exp_5_Sample_Phase_3: a2dMuxId = A2dMuxId3 GOSUB Exp_5_Wait_For_Zero GOSUB Exp_5_Wait_For_Next_Peak GOSUB Exp_5_Take_Samples GOSUB Exp_5_Write_Samples RETURN

The purpose of the Exp_5_Wait_For_Zero subroutine is to "sync up" to the next positive cycle of phase 3 (as we have arbitrarily named it). We did much the same in Experiment 4 by first waiting for the half wave rectified voltage output to go to zero or just below 5 (5 = 5 * 0.02volts/sample = 0.10 volts). This routine does exactly the same thing, however we have converted it into a subroutine since other parts of our program will also make calls to it. Once it finds that the phase 3 wave is at zero volts, it exits (returns) to the next instruction, which is a call to Exp_Wait_For_Next_Peak.

Exp_5_Wait_For_Zero: DO

GOSUB A2D LOOP UNTIL (a2dResult <= 5) RETURN

As its name implies, Exp_Wait_For_Next_Peak waits until the phase 3 voltage output just begins to start is peak voltage cycle. With subsequent calls to the A/D converter the a2dResult is tested against the value of 5, which is really 0.10 volts as explained earlier. Once past this level we can be assured that the wave is beginning to peak. It is at this point that we want to begin taking voltage samples.

Exp_5_Wait_For_Next_Peak: DO

GOSUB A2D LOOP UNTIL (a2dResult => 5) RETURN

The Exp_5_Take_Samples routine quickly takes ten converted voltage samples and stores them in the sampleArray in RAM, just as we did in Experiment 4.

Exp_5_Take_Samples:

FOR sampleCount = 0 TO 9

GOSUB A2D

sampleArray(sampleCount) = a2dResult NEXT

Exp_5_Take_Samples_End: RETURN

Exp_5_Write_Samples is where the program transfers the ten samples in sampleArry to EEPROM. Notice how it does this. Within the for...next loop the sampleCount starts at zero and increments to nine. Using the write instruction we store the sample in sampleArray indexed by sampleCount to EEPROM at the address that is the sum of eepromAddr plus sampleCount. In this one WRITE instruction sampleCount is used twice as an index; once to acquire the sample in sampleArray and again to write the sample into EEPROM.

Exp_5_Write_Samples:

FOR sampleCount = 0 TO 9

WRITE (eepromAddr + sampleCount), sampleArray(sampleCount) NEXT

Exp_5_Write_Samples_End: RETURN

Exp_5_Sample_Phase_2 is quite similar to the previous Phase 3 sample code with two important exceptions. The first difference is a call is to Exp_5_inc_eepromAddr.

Exp_5_Sample_Phase_2:

GOSUB Exp_5_Inc_EepromAddr

Recall from Figure 6-11 that each of the four groups within each bank is separated by sixteen bytes, or $10 hexadecimal. The Exp_5_inc_eepromAddr subroutine effectively moves the EEPROM address from the last entry of the Phase 3 samples to the first entry of Phase 2 samples.

Exp_5_Inc_eepromAddr:

eepromAddr = eepromAddr + 16 IF (eepromAddr >= $0300) THEN

GOSUB Exp_5_EepromAddr_To_Zero ENDIF

Exp_5_Inc_EepromAddr_End: RETURN

We don't want to overwrite our PBASIC code! Our program code occupies from about address 960 ($3C0) to 2047 ($7FF). Therefore, the subroutine tests the absolute address of the eepromAddr pointer to determine if it will encroach into the area of EEPROM ! where our program code is stored. We test it at 768 ($300), which is sufficiently away from • the last program byte. If we've just incremented it at or above this value, we must reset the eepromAddr pointer back to 0000. In effect, we will be using EEPROM from 0000 to 768 ($000 ^ $300) for storing data samples.

Once this is done, set the A/D converter to sample phase 3 (CH3) and then make the two calls to "sync up" to its next positive-going part.

a2dMuxId = A2dMuxId3

GOSUB Exp_5_Wait_For_Zero GOSUB Exp_5_Wait_For_Next_Peak

Now here is where things get a little different. The next instruction switches the A/D converter to sample phase 2 (CH2) rather than phase 3. This is so that we can sample the phase 2 waveform "in sync with" the phase 3 waveform, which we are arbitrarily using as the reference phase. Since each phase is equally separated from the other two, we could have chosen phase 1 or phase 2 as the reference. However, we simply chose to use phase 3, instead. The next two instructions again take ten samples of phase 2 and write them to EEPROM as the next group in this bank.

a2dMuxId = A2dMuxId2

GOSUB Exp_5_Take_Samples GOSUB Exp_5_Write_Samples

The code that samples phase 1 and the rectified output is a carbon copy of the code for phase 2, with the exception that the phase 1 code sets the A/D converter to sample CH1 and the rectified output code samples CH0.

Exp_5_Sample_Phase_1:

GOSUB Exp_5_Inc_EepromAddr a2dMuxId = A2dMuxId3

GOSUB Exp_5_Wait_For_Zero GOSUB Exp_5_Wait_For_Next_Peak a2dMuxId = A2dMuxId1

GOSUB Exp_5_Take_Samples GOSUB Exp_5_Write_Samples RETURN

Exp_5_Sample_Rectified_Output: GOSUB Exp_5_Inc_EepromAddr a2dMuxId = A2dMuxId3

GOSUB Exp_5_Wait_For_Zero GOSUB Exp_5_Wait_For_Next_Peak a2dMuxId = A2dMuxId0

GOSUB Exp_5_Take_Samples GOSUB Exp_5_Write_Samples RETURN

Well, we're done with the sampling tasks, at least for the first set of samples. Our program has successfully captured four sets of A/D converter samples from each channel, stored them in RAM (sampieArray), then transferred them to EEPROM in bank 0 on a one-at-a-time basis.

Since we are done with sampling, the last statement in our case statement switched mode back to Plotting. This completes the select...case statement, and control returns to the Main program.

When Main jumps back to Exp_5, the select.case will drop into the Plotting case. A variable named Piotcount will keep track of how many sets of samples have been plotted. We increment the piotcount so that it points to the next set of four samples.

plotCount = plotCount + 1

Execution now jumps to the Exp_5_Retrieve_For_Plotting subroutine.

Now comes the part of the program that extracts four channels of data from EEPROM for eventual display by the Plot_it routine. By commenting out individual read commands, we can choose which channels to plot individually, or together. (Here we have only channel 1 plotting).

Exp_5_Retrieve_For_Plotting:

'READ (eepromAddr - $30 + plotCount), ch3 'READ (eepromAddr - $20 + plotCount), ch2 READ (eepromAddr - $10 + plotCount), ch1 'READ (eepromAddr - $00 + plotCount), ch0

The program code can execute up to four separate read commands to EEPROM to extract four bytes of sample data stored there. The key to doing this is knowing what address to use. We started at the top of the program with eepromAddr = $000, and each pass through the code groups Exp_5_Sample_Phase_2, Exp_5_Sample_Phasei and Exp_5_Sample_Rectified_Output incremented eepromAddr by 16 or $10 hexadecimal. Therefore, at this point, eepromAddr is at address $030 hexadecimal. Therefore, to read back the data we stored in EEPROM we first need to "subtract" the group address from eepromAddr. Then to get to the proper byte of data in each group, we need to "add" the value of plotCount .

Look at the first read instruction. Here we subtract $30 from eepromAddr thus making the effective address $000 ($030 - $030=$000). Then we add the current value of plotCount, which is currently at 0. So our effective address for the first read instruction is $000. The effective addresses of the other read instructions are $010, $020 and $030, respectively. Refer, again, to Figure 6-11 to see what we've done.

In reading all four samples into their respective channel variables (ch3 - ch0) the Plot_it routine will plot the four values the next time through.

The next time Main calls Exp_5 the select...case will increment plotCount, then branch to Exp_5_Retrieve_For_Plotting again. Only this time plotCount is at 1 and our effective addresses for ch3 through ch0 are as follows:

As plotCount is incremented with each call to Exp_5_Retrieve_For_Plotting it eventually reaches the value of 9. This is where the if.then statement in the case statement will be true. After switching mode back to Sampling, we'll jump to the

Exp_5_inc_eepromAddr subroutine and increment eepromAddr to the next bank of EEPROM data storage area. In this case it will increment from $030 to $040.

IF (plotCount = 9) THEN mode = Sampling plotCount = 0

GOSUB Exp_5_Inc_EepromAddr ENDIF

Then we'll take ten more sets of samples per channel, storing them into Bank 1, which starts at $0040. This process of sampling, plotting, and incrementing to the next bank repeats over and over.

Of course, we don't have unlimited storage, and we don't want to clobber our stored program, so we have to reset the eepromAddress back to Bank 0 at some point. This is taken care of in Exp_5_Inc_eepromAddr.

Exp_5_Inc_EepromAddr:

eepromAddr = eepromAddr + $10 IF (eepromAddr >= $0300) THEN

GOSUB Exp_5_eepromAddr_To_Zero ENDIF

The if-then statement tests for our EEPROM address limit, which we have chosen as $300 or 768. If the program increments eepromAddr over $300 a call to the Exp_5_EEPROM_To_zero subroutine is executed, where the eepromAddr is reset to $000 as follows:

Exp_5_EepromAddr_To_Zero: eepromAddr = $0 00 0

Exp_5_EepromAddr_To_Zero_End: RETURN

What all of this address manipulation has accomplished has been to preserve the life of our EEPROM. The program has spread out the writes to EEPROM over as wide an area as possible. If you left the power to the Board of Education on twenty-four hours a day -AND - if the wind turbine were spinning all of that time, the life of our EEPROM would be 10 years.

10 months/bank * 12 banks = 120 months / 12 months / year = 10 years

Remember at the very beginning of our program explanation we mentioned that EEPROM would only be written when the wind turbine was spinning? Well, take a look at the code under Exp_5_Sample_Phase_3 again.

Exp_5_Sample_Phase_3: a2dMuxId = A2dMuxId3 GOSUB Exp_5_Wait_For_Zero GOSUB Exp_5_Wait_For_Next_Peak GOSUB Exp_5_Take_Samples GOSUB Exp_5_Write_Samples

Whether the wind turbine is spinning, or not, the first two instructions will be executed. However the third instruction, the call to Exp_5_Wait_For_Next_Peak, will never return and will be caught in an endless loop waiting for the voltage to go from zero to non-zero; something that usually won't happen if the wind turbine is NOT spinning. Therefore, our program will be caught in this subroutine until the wind turbine begins spinning once again. The result is that while the program is stuck in this loop it will not write to EEPROM, thus extending its functional life even further.

DIY Battery Repair

DIY Battery Repair

You can now recondition your old batteries at home and bring them back to 100 percent of their working condition. This guide will enable you to revive All NiCd batteries regardless of brand and battery volt. It will give you the required information on how to re-energize and revive your NiCd batteries through the RVD process, charging method and charging guidelines.

Get My Free Ebook


Post a comment