Appendix B Source Code Listing

----- For Experiment 2: Dueling Solar Cells

LeftSpLed PIN 9 '

RightSpLed PIN 8 '

Left Solar Panel LED on P9 Right Solar Panel LED on P8

offSet VAR

offset = 0

codePtr 'Nib

Value proportional to A/D voltage resolution of 0.02 volts/bit. Example:offSet=10x0.02V = 0.20V

For Experiment 3: Solar Cell Sun Tracker

Servo waitCount

WaitVal

PIN VAR CON

12 Nib 1

Sun tracker servo on P12 Dampens servo's "hunting" initial value of waitCount

----- For Experiment 4: Half and Full Wave Rectification ----------------

sampleCount VAR waitCount 'Nib ' Number of A/D samples per period sampleArray VAR Byte(10) ' 10-element array for A/D samples

For Experiment 5: Three-Phase AC Alternator

Plotting CON

Sampling CON

eepromAddr VAR eepromAddr = $0000 plotCount VAR mode VAR

mode = Sampling

dataPtr 'Word codePtr 'Nib Bit

Program is plotting Program is taking samples EEPROM address pointer Initial eepromAddr value Number plotted so far Plot mode or sample mode Initially will be sampling

Main Routine

Main: DO

' GOSUB Exp_1 ' GOSUB Exp_2 ' GOSUB Exp_3 ' GOSUB Exp_4 GOSUB Exp_5 GOSUB Plot_It LOOP

' Programmable Battery Charger ' Dueling Solar Cells ' Solar Cell Sun Tracker ' Half&Full Wave Rectification Three-Phase AC Alternator Plot Data w/ StampPlot Pro

Subroutines

Experiment 1: Programmable Battery Charger

Based on codePtr, branch to the appropriate subroutine Exp_1_Init codePtr = 0

Exp_1_Charge codePtr = 1

Exp_1_Drain codePtr = 2

Exp_1_Replay codePtr = 3

Exp_1_Init

Halt charging and discharging Extinguish all LEDs Zero relevant variables Read last codePtr value from eeProm, increment it test for overflow Write codePtr back to eeProm Exit

Exp_1_Charge

Check to see if battery is done charging. If not, Enable charging Disable discharging Flash the charging LED

Average the battery voltage and current for 256 PlotIt cycles (64 seconds) Abort the charge cycle if the battery voltage is too high at the beginning Else, store the average of the sampled voltage and current to eeProm Increment the eeProm pointer

Test to see if the timed charge cycle is complete (dataPtr=DataPtrMax)

If so, set doneCharging = True to begin draining the battery the next time thru

Exit

Exp_1_Drain

Check to see if battery is drained already. If not,

Disable charging

Enable discharging

Flash the discharging LED

Sample the discharge voltage and current

If battery voltage is below minimum set doneDraining = True, turn the Drain LED on, and deactivate any more draining.

Exp_1_Replay

Disable charging and discharging Flash the replay LED

For each data pair in eeProm sampled during the charge cycle Display the charge voltage and current using StampPlot

Using the PlotIt routine's 25 0 ms delay as a timer for each sample pair Exit

BRANCH codePtr,[Exp_1_Init,Exp_1_Charge,Exp_1_Drain,Exp_1_Replay]

Exp 1 Init:

LOW ChargeBatt

' halt battery charging

LOW DrainBatt

' and discharging

LOW ChargeLed

' and extinguish all LEDs

LOW DrainLed

LOW ReplayLed

avgVolts = 0

' zero the average battery charging voltage

avgCurrent = 0

' zero the average battery charging current

maxVolts = 0

' zero the maximum measured voltage

counter = 0

' zero the 64 second loop counter

dataPtr = 0

' zero the eeProm data logging pointer

READ DataPtrMax+1,

codePtr

' select the routine to execute

codePtr=codePtr+1

' by incrementing the codePtr

IF codePtr>3 THEN

codePtr=0

' test for overflow then...

WRITE DataPtrMax+1

,codePtr

' write it's value back to eeProm

GOTO Exp_1_End

' and exit...the selected subroutine will ' run based on the BRANCH instruction above ' the next time thru

Exp_1_Charge: ' codePtr = 1 : charge batteries

' Jump out if battery is charged already

IF (doneCharging = True) THEN GOTO Exp_1_End

HIGH ChargeBatt

' activate battery charging transistor

LOW DrainBatt

' deactivate battery discharging transistor

TOGGLE ChargeLed

' flash the charge LED

LOW DrainLED

' extinguish the others

LOW ReplayLED

a2dMuxId =

a2dMuxId3

' sample the battery charge current (BCI) and

GOSUB A2D

' add it to avgCurrent

ch3 = (255-

a2dResult)

' I = (Vdd - Vcollector)/10 ohms

avgCurrent

= avgCurrent+ch3

a2dMuxId = a2dMuxId2

' sample the

battery voltage (BV) and

GOSUB A2D

' add it to

aveBattVolt

ch2 = a2dResult

avgVolts = avgVolts+ch2

' abort charge cycle - battery is charged

IF (ch2 > BattFullChg) AND

(dataPtr <10 ) THEN

doneCharging = True

' set flag

HIGH ChargeLed

' turn charge LED on

steadily

LOW ChargeBatt

' deactivate battery

charging transistor

ENDIF

counter = counter - 1

' decrement the averaging counter

IF counter <> 0 THEN Exp_1_

End ' exit if not zero,

else

WRITE dataPtr,avgVolts.HIGHBYTE ' store the average charging voltage to eeProm dataPtr = dataPtr+1 ' increment the EEPROM pointer

WRITE dataPtr,avgCurrent.HIGHBYTE ' store the average charging current to eeProm dataPtr = dataPtr+1 ' increment the EEPROM pointer

'' IF

avgVolts

.HIGHBYTE

> maxVolts

THEN

maxVolts = avgVolts.

HIGHBYTE

'' IF

avgVolts

.HIGHBYTE

=< maxVolts

- 10

THEN codePtr=2:GOTO

Exp 1 End

avgVolts = 0

' reset for the next set of data

avgCurrent = 0

IF (dataPtr = DataPtrMax)

THEN ' charge cycle complete

doneCharging = True

' set flag so we don't charge any more

HIGH ChargeLed

' turn charge LED on steadily

LOW ChargeBatt

' deactivate battery charging transistor

ENDIF

GOTO Exp_1_End ' beginning with the next time thru

GOTO Exp_1_End ' beginning with the next time thru

Exp_1_Drain: ' codePtr = 2 : discharge batteries

' Jump out if battery is drained already

IF (doneDraining = True) THEN GOTO Exp_1_End

LOW ChargeBatt

' deactive battery charging transistor

HIGH DrainBatt

' activate battery discharging transistor

TOGGLE DrainLED

' flash the DrainLed

LOW ChargeLed

' extinguish the others

LOW ReplayLed

a2dMuxId = a2dMuxId0

' sample the load voltage (BLV)

GOSUB A2D

ch0 = a2dResult

a2dMuxId = a2dMuxId2

' sample the battery voltage (BV)

GOSUB A2D

ch2 = a2dResult

a2dMuxId = a2dMuxId1

' sample the load current (BLI)

GOSUB A2D

ch1 = ch2 - a2dResult

' ch1 = I = (Vbatt-Vcollector)/10 ohms ' test battery voltage for below min

IF (ch2 < MinVolts) THEN

doneDraining = True

' Set a flag so we don't drain anymore

HIGH DrainLed

' Turn Drain LED on steadily

LOW DrainBatt

' deactivate battery discharging transistor

ENDIF

GOTO Exp_1_End

Exp_1_Replay: '

codePtr = 3 :

replay charge cycle

LOW ChargeBatt

' deactivate battery charging transistor

LOW DrainBatt

' deactivate battery discharging transistor

TOGGLE ReplayLed

' flash the replayLed

LOW ChargeLed

' extinguish the others

LOW DrainLed

READ dataPtr,avgVolts.LOWBYTE

ch2 = avgVolts.LOWBYTE ' display the voltage and ...

dataPtr = dataPtr+1

READ dataPtr,avgCurrent.LOWBYTE

ch3 = avgCurrent.LOWBYTE ' current from the last charge dataPtr = dataPtr+1

IF (dataPtr => DataPtrMax) THEN dataPtr = 0

HIGH ReplayLed ' turn replay LED on solid

ENDIF

Exp_1_End: RETURN

' Experiment 2: Dueling Solar Cells

' Convert the left solar panel voltage to an 8-bit value ' Convert the right solar panel voltage to an 8-bit value ' Compare the two voltage values: ' IF both are equal plus or minus offSet ' Then illuminate both LEDs

' IF the left solar panel voltage > the right solar panel ' Then illuminate the left LED and extinguish the right

voltage LED

IF the right solar panel voltage > the left solar panel voltage Then illuminate the right LED and extinguish the left LED Return

Exp 2:

a2dMuxId = A2dMuxId1

' convert A/D Channel 1

GOSUB A2D

' which is the left solar panel

ch1 = a2dResult

' set CH1 = converted value

a2dMuxId = A2dMuxId2

' convert A/D Channel 2

GOSUB A2D

' which is the right solar panel

ch2 = a2dResult

' set CH2 = converted value

Exp 2 Compare CH1 CH2:

IF (ch1 > ch2) THEN

' test

for

CH1

> CH2

GOTO Exp 2 CH1 Is Greater

ELSEIF (ch2 > ch1) THEN

' test

for

CH2

> CH1

GOTO Exp_2_CH2_Is_Greater

ELSE

GOTO Exp_2_CH1_Equals_CH2

ENDIF

Exp 2 CH1 Equals CH2:

' both CH1 and CH2 are equal, so

HIGH LeftSpLed

' illuminate the left LED and

HIGH RightSpLed

' illuminate the right LED

GOTO Exp_2_End

' and exit

Exp 2 CH1 Is Greater:

' CH1 is > CH2, so

ch1 = ch1 - offSet

' subtract the offSet from CH1

IF (ch1 = ch2) THEN

GOTO Exp_2_CH1_Equals_CH2

' brach if CH1 = CH2, else

ELSE

HIGH LeftSpLed

' illuminate the left LED and

LOW RightSpLed

' extinguish the right LED

GOTO Exp_2_End

' and exit

ENDIF

Exp 2 CH2

Is Greater:

ch2 = ch2 - offSet

' CH2 is > CH1, so

IF (ch2

= ch1) THEN

GOTO

Exp_2_CH1_Equals_CH2

' branch if CH2 = CH1, else

ELSE

LOW

LeftSpLed

' extinguish the left LED and

HIGH

RightSpLed

' illuminate the right LED

GOTO

Exp_2_End

' and exit

ENDIF

Exp 2 End:

RETURN

' Experiment 3:

Solar

Cell Sun Tracker

' Based on the

values

for CH1 and CH2 from

Experiment 2

' Determine if

the servo should stop, move

left or move right

By moving the servo left or right, the individual solar cell voltages will eventually become equal and the program will cause the servo to stop. That is, until the sun moves and the voltages become unequal again thus causing the servo to reposition the solar panels.

Return

Exp_3_End: RETURN

Experiment 4: Half and Full Wave Rectification

Set the A/D conterter to convert only on ch3

If sampleCount is not equal to 10 Then plot existing samples Else prepare to plot new samples

To plot new samples first wait for the rectified wave to equal zero Once zero, wait for the beginning of the first peak Then take ten (10) samples as rapidly as possible Zero sampleCount to begin plotting next

Plot each sample in the order taken using Plot_It Increment sampleCount and

Exit

a2dMuxId = A2dMuxId3 IF (sampleCount <> 10) THEN

GOTO Exp_4_Plot ENDIF

Set the A/D to convert Channel 3

Exp_4_Wait_For_Zero: GOSUB A2D

GOTO Exp_4_Wait_For_First_Peak ENDIF

sampleCount = sampleCount + 1 IF (sampleCount = 10) THEN

GOTO Exp_4_Take_Samples ENDIF

GOTO Exp_4_Wait_For_Zero

Exp_4_Wait_For_First_Peak: GOSUB A2D

IF (a2dResult > 5) THEN Exp_4_Take_Samples GOTO Exp_4_Wait_For_First_Peak

Loop until the rectified wave is zero

If the rectified wave stays above zero for 10 counts, assume that a smoothing capacitor is attached

Loop until the first peak is detected

Exp_4_Take_Samples:

FOR sampleCount = 0 TO 9 GOSUB A2D

sampleArray(sampleCount) = a2dResult NEXT

sampleCount = 0

As rapidly as possible take 10 A/D samples and save them in the sampleArray

Re-initialize sampleCount for plotting

Exp_4_Plot:

ch3 = sampleArray(sampleCount) sampleCount = sampleCount + 1

Get the next A/D sample into CH3 and increment sampleCount

Exp_4_End: RETURN

Experiment 5: Three-Phase AC Alternator

Enter from power-on or reset with eepromAddr = $000, mode = Sampling, and plotCount = 0

This routine will be called once each time through Main, and right after this routine, Plot_It will be called.

If mode = Sampling, then take a set of 40 samples from all 4 A/D converter inputs. 10 samples per channel.

If mode = Plotting, then retreive one set of 4 samples from EEPROM. Jump out of Exp_5... the one set will get plotted when Plot_It is called. This will happen 10 times to get all 10 sets of 4 samples plotted.

Sampling:

For each of the three phases and the rectified output, take samples as follows:

- Increment the eepromAddr to the next sub-block (except for phase 3)

- Set the A/D converter to sample phase 3

- Sync up to the positive peak of phase 3 (except for phase 3, itself)

- Switch the A/D to sample the next phase or the rectified output

(again, except for phase 3)

- Gather 10 samples of the covertered values in sampleArray (RAM)

- Transfer the 10 samples from sampleArray to EEPROM

Plotting:

For each of the three phases and the rectified output, plot samples as follows:

- Increment plotCount for the next time around

- Read each sample from EEPROM into the appropriate variable (ch3, ch2, ch2, ch0)

- Exit the program and let the Plot_It routine graph the four samples

- When we've plotted all the samples, increment the eepromAddr to the next sub-block, change mode to Sample the next time through, and reset plotCount to zero

Note: If the eepromAddr is greater than address $300, reset it to zero -we don't want to clobber the program memory

Exp 5:

SELECT mode

CASE Plotting

' Will plot 10 sets of data

plotCount = plotCount + 1

' numbered 0..9

GOSUB Exp_5_Retrieve_For_Plotting

' Get 1 set of data to plot

IF (plotCount = 9) THEN

mode = Sampling

' Done plotting, switch state

plotCount = 0

' Reset plotCount

GOSUB Exp_5_Inc_EepromAddr

' Inc. addr to next bank

ENDIF

CASE Sampling

GOSUB Exp 5 Sample Phase 3

' Take 10 samples each of Phases

GOSUB Exp 5 Sample Phase 2

' 3, 2, 1, Rectified Out

GOSUB Exp_5_Sample_Phase_1

GOSUB Exp_5_Sample_Rectified_Output

GOSUB Exp_5_Retrieve_For_Plotting

' Queue up 1st set of samples

mode = Plotting

' Change state back to plotting

ENDSELECT

Subroutines for Experiment 5

Exp 5 Sample Phase 3:

a2dMuxId = A2dMuxId3

' Set the A/D to convert Channel 3

GOSUB Exp 5 Wait For Zero

' Loop until the wave is zero

GOSUB Exp_5_Wait_For_Next_Peak GOSUB Exp_5_Take_Samples GOSUB Exp_5_Write_Samples

Exp_5_Sample_Phase_3_End: RETURN

Wait for wave to begin to peak Take samples of phase 3 Write samples to EEPROM

Exp_5_Sample_Phase_2:

GOSUB Exp_5_Inc_EepromAddr a2dMuxId = A2dMuxId3

GOSUB Exp_5_Wait_For_Zero GOSUB Exp_5_Wait_For_Next_Peak a2dMuxId = A2dMuxId2

GOSUB Exp_5_Take_Samples GOSUB Exp_5_Write_Samples

Exp_5_Sample_Phase_2_End: RETURN

Increment pointer to EEPROM Set the A/D to convert Channel 3 sync up to phase 3 Loop until the wave is zero Wait for wave to begin to peak

Switch the A/D to convert Channel 2

Take samples of phase 2 Write samples to EEPROM

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

Exp_5_Sample_Phase_1_End: RETURN

Increment pointer to EEPROM Set the A/D to convert Channel 3 sync up to phase 3 Loop until the wave is zero Wait for wave to begin to peak

Switch the A/D to convert Channel 1

Take samples of phase 1 Write samples to EEPROM

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

Exp_5_Sample_Rectified_OutputEnd: RETURN

Increment pointer to EEPROM Set the A/D to convert Channel 3 sync up to phase 3 Loop until the wave is zero Wait for wave to begin to peak

Switch the A/D to convert Channel 0

Take samples of the rectified wave Write samples to EEPROM

' Retrieve 4 samples, one for each channel. This will be called 10 times, ' to get the total "bank", which is 4 sets of 10 samples per channel. Exp_5_Retrieve_For_Plotting:

READ (eepromAddr - $30 + plotCount), ch3 ' Read phase 3 into ch3

READ (eepromAddr - $20 + plotCount), ch2 ' Read phase 2 into ch2 READ (eepromAddr - $10 + plotCount), ch1 ' Read phase 1 into ch1 READ (eepromAddr - $00 + plotCount), ch0 ' Read rectified val into ch0

Exp_5_Retrieve_For_Plotting_End: RETURN

Exp_5_Wait_For_Zero: DO

GOSUB A2D LOOP UNTIL (a2dResult <= 5)

Exp_5_Wait_For_Zero_End: RETURN

Loop until the rectified wave is below 0.10 volts

Exp_5_Wait_For_Next_Peak: DO

GOSUB A2D LOOP UNTIL (a2dResult => 5)

Exp_5_Wait_For_Next_Peak_End: RETURN

Loop until the rectified wave is non-zero

Exp_5_Take_Samples:

FOR sampleCount = 0 TO 9 GOSUB A2D

sampleArray(sampleCount) = a2dResult NEXT

Exp_5_Take_Samples_End: RETURN

Enter with A2D channel set Acquire 10 samples of the wave as quickly as possible

Exp_5_Write_Samples:

FOR sampleCount = 0 TO 9

WRITE (eepromAddr + sampleCount), NEXT

Exp_5_Write_Samples_End: RETURN

' Enter with eepromAddr set ' Store the wave samples to EEPROM sampleArray(sampleCount)

Initialize the eepromAddr to the bottom of EEPROM

Exp_5_EepromAddr_To_Zero_End: RETURN

Exp_5_EepromAddr_To_Zero: eepromAddr = $0000

Exp_5_Inc_EepromAddr:

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

GOSUB Exp_5_EepromAddr_To_Zero ENDIF

Exp_5_Inc_EepromAddr_End: RETURN

Add 16 to move to next bank Make sure not to overwrite our PBASIC program which starts around $0300

A/D Converter Routine

Enter with a2dMuxId as the channel to convert

Return with 8-bit result in a2dResult (msb,6,5,4,3,2,1,lsb)

A2D:

HIGH A2dChipSel LOW A2dDataIn LOW A2dClk a2dResult = 0

A2D_Start_Conversion: LOW A2dChipSel

A2D Shift Out Channel ID:

Initialize signals Disable A/D Chip Select Initial state of data in Initial state of clock Clear the 8-bit result

Start the conversion process Enable A/D chip select

Shift out the Channel ID value

SHIFTOUT A2dDataIn,A2dClk,MSBFIRST,[a2dMuxId\4]

' Shift in the result

A2D_Shift_In_Result: PULSOUT A2dClk,10

SHIFTIN A2dDataOut,A2dClk,MSBPRE,[a2dResult\8] HIGH A2dChipSel

A2D_End: RETURN

Disable A/D chip select Return to calling routine

Plot Acquired Data Using StampPlot Software

Plot_It:

checkSum = ch0 + ch1 + ch2 + ch3 DEBUG ch0, ch1, ch2, ch3, checkSum PAUSE 250

Plot_It_End: RETURN

Compute checksum for StampPlot Transmit data to StampPlot Give StampPlot time to plot data

Solar Power Sensation V2

Solar Power Sensation V2

This is a product all about solar power. Within this product you will get 24 videos, 5 guides, reviews and much more. This product is great for affiliate marketers who is trying to market products all about alternative energy.

Get My Free Ebook


Post a comment