' {$STAMP BS2} ' {$PBASIC 2.5} ' ' Title: Experiments with Solar Panels ' File: Parallax_Solar_Exp.bs2 ' Copyright: LearnOnLine, Inc. ' Author: J. Gavlik ' Last Updated: 06-30-2009 '------------------------------------------------------------------ ' Declarations '------------------------------------------------------------------ ' ' General VARs ' tempByte VAR Byte tempWord VAR Word i VAR Byte j VAR Byte innerLoopSolar VAR Word innerLoopOneOhm VAR Word 'adjust the following two constants depending on your lighting conditions 'larger numbers provide more averaging - slower display speed 'smaller numbers provide less averaging - faster display speed innerLoopLimit CON 16 '1 is minimum - 16 is maximum outerLoopLimit CON 4 '1 is minimum - 16 is maximum 'average = innerLoopLimit x outerLoopLimit = 16 x 4 = 64 voltage VAR Word oneOhmDrop VAR Word current VAR Word ckSum VAR Byte ' ' VARs for MCP3208 8 channel, 12 bit multiplexed A/D Converter ' a2dClk CON 0 'clock (P0) a2dDout CON 1 'data out (P1) a2dDin CON 2 'data in (P2) a2dCs CON 3 'chip select (P3) a2dId0 CON %1000 'A/D Channel 0 ID a2dId1 CON %1001 'A/D Channel 1 ID a2dId2 CON %1010 'A/D Channel 2 ID a2DId3 CON %1011 'A/D Channel 3 ID a2dId4 CON %1100 'A/D Channel 4 ID a2dId5 CON %1101 'A/D Channel 5 ID a2dId6 CON %1110 'A/D Channel 6 ID a2DId7 CON %1111 'A/D Channel 7 ID a2dIdShiftOut VAR Nib 'A/D Channel ID to shift out a2dResult VAR Word '16-bit result of A/D conversion '------------------------------------------------------------------ ' Solar Experiment Algorithm '------------------------------------------------------------------ ' ' Sample the solar panel input voltage ' Sample the voltage across the 1 ohm sense resistor ' Repeat above xx times (innerLoopLimit x outerLoopLimit)to reduce voltage ripple from AC lights ' Convert the voltage counts to millivolts ' Test to see if the solar panel voltage > voltage drop across the 1 ohm resistor ' if so, continue ' if not,ignore readings and loop back to the top ' Convert the 1 ohm voltage drop to current in milliamps ' Transmit the voltage and current values to the computer ' Repeat ' '------------------------------------------------------------------ Solar_Exp: GOSUB Get_Average_Voltages 'acquire solar panel and voltage drop across 1 ohm sense resistor 'and take an average of 64 readings to smooth out ripple IF (voltage < oneOhmDrop) THEN 'test for catching voltage drop > input voltage GOTO Solar_Exp 'which can occur when voltage has ripples or changes fast ENDIF current = (voltage - oneOhmDrop) / 1 'compute the voltage drop across the 1 ohm sense resistor 'which is automatically now in milliamps by the following: ' ' I = E / R where ' I = current in milliamps ' E = voltage in millivolts ' R = resistance in ohms GOSUB Plot_It ' transmit the value to the computer GOTO Solar_Exp ' repeat '------------------------------------------------------------------ ' Get Average Voltages '------------------------------------------------------------------ Get_Average_Voltages: voltage = 0 'clear outer loop voltages oneOhmDrop = 0 FOR j = 1 TO outerLoopLimit innerLoopSolar = 0 'clear inner loop voltages innerLoopOneOhm = 0 FOR i = 1 TO innerLoopLimit a2dIdShiftOut = a2dId0 'set the a/d converter to ch0 (solar panel voltage) GOSUB A2D 'get A/D count innerLoopSolar = innerLoopSolar + a2dresult 'add result to average a2dIdShiftOut = a2dId5 'set the a/d converter to ch5 (1 ohm sense resistor) GOSUB A2D 'get A/D count innerLoopOneOhm = innerLoopOneOhm + a2dresult 'add result to average NEXT voltage = voltage + (innerLoopSolar / innerLoopLimit) 'get average voltage count for inner loop oneOhmDrop = oneOhmDrop + (innerLoopOneOhm / innerLoopLimit) 'and add to outer loop counts NEXT voltage = voltage / outerLoopLimit 'get average voltage count for outer loop oneOhmDrop = oneOhmDrop / outerLoopLimit oneOhmDrop = oneOhmDrop */$0138 'convert to millivolts (1.22mv / count) voltage = voltage */$0138 'convert to millivolts (1.22mv / count) RETURN '------------------------------------------------------------------ ' Plot Acquired Data '------------------------------------------------------------------ Plot_It: ckSum = (voltage.HIGHBYTE + voltage.LOWBYTE + current.HIGHBYTE + current.LOWBYTE) 'compute checksum DEBUG voltage.HIGHBYTE, voltage.LOWBYTE, current.HIGHBYTE, current.LOWBYTE ,ckSum 'Transmit data to computer RETURN '------------------------------------------------------------------ ' A/D Converter Routine ' Enter with a2dIdShiftOut as the channel to convert ' Return with 12-bit result in a2dResult - right shifted '------------------------------------------------------------------ A2D: 'Initialize signals HIGH a2dCs 'Disable A/D chip select HIGH a2dDin 'Initial state of data in LOW a2dClk 'Initial state of clock a2dResult = 0 'Clear the 10-bit result A2D_Start_Conversion: 'Start the conversion process LOW a2dCs 'Enable A/D chip select A2D_Shift_Out_Channel_ID: 'Shift out the Channel ID value PULSOUT a2dClk,10 'Send first clock with Din high SHIFTOUT a2dDin,a2dClk,MSBFIRST,[a2dIdShiftOut\4] A2D_Shift_In_Result: 'Shift in the result PULSOUT a2dClk,10 'clock out null bit PULSOUT a2dClk,10 'clock out null bit SHIFTIN a2dDout,a2dClk,MSBPRE,[a2dResult\12] A2D_End_Conversion: HIGH a2dCs 'Disable A/D chip select RETURN '------------------------------------------------------------------ ' Program End '------------------------------------------------------------------ END