'---------------------------------------------------------------------------------------- ' ' Whirlybird Wind Turbine PICAXE Code ' ' file: picaxe_wind.bas ' ' created: 5-28-2009 ' updated: 6-30-2009 ' ' owner: LearnOnLine, Inc. ' author: John Gavlik ' ' created for the PicAxe 28X2 microprocessor uisng internal 8Mhz oscillator ' '---------------------------------------------------------------------------------------- '---------------------------------------------------------------------------------------- ' ' A/D Setup - Use all A/D channels ' '---------------------------------------------------------------------------------------- let adcsetup = %0000000011111111 'use ADC0,1,2,3,8,9,10,11,12 '---------------------------------------------------------------------------------------- ' ' Defines ' '---------------------------------------------------------------------------------------- '' #com3 'change com port number to match your system #picaxe 28X2 'don't change this!!! '---------------------------------------------------------------------------------------- ' ' Important I/O Pins for PIC 28X2 Microprocessor ' '---------------------------------------------------------------------------------------- ' rectDC ADC11 pin 25 ' phase1 ADC9 pin 24 ' phase2 ADC8 pin 23 ' phase3 ADC10 pin 22 ' oneOhmDrop ADC12 pin 21 ' serin pin 6 ' serout pin 7 ' reset pin 1 ' gnd pin 8 & 19 ' +5v pin 20 '---------------------------------------------------------------------------------------- ' ' Variables ' '---------------------------------------------------------------------------------------- symbol tempWord = w0 'general vars symbol tempByte = b2 symbol i = b3 symbol cksum = b4 'for data transmission to PC symbol delay = b5 'progressive delay for time slicing symbol rpm = w3 'revolutions per minute of turbine spin symbol flag = b8 'to indicate when next zero volts is reached symbol j = b9 symbol phase1Volts = w5 'phase voltages symbol phase2Volts = w6 symbol phase3Volts = w7 symbol rectDC = w8 'rectified DC voltage symbol phase1Prev = w9 'previous phase voltages for averaging symbol phase2Prev = w10 symbol phase3Prev = w11 symbol rectDCPrev = w12 symbol Iaverage = w13 'current average of (rectDCave - oneOhmave) / 1 symbol rectDChi = w14 'rectDC voltage hi value symbol rectDClo = w15 'rectDC voltage lo value symbol rectDCave = w16 'rectDC voltage average symbol oneOhmhi = w17 '1 ohm resistor drop hi value symbol oneOhmlo = w18 '1 ohm resistor drop lo value symbol oneOhmave = w19 '1 ohm resistor drop average symbol rpmDelay = w20 'delay for rpm measurement '---------------------------------------------------------------------------------------- ' ' Main Routine ' '---------------------------------------------------------------------------------------- Main: gosub Wait_For_Zero_Volts 'resync to beginning of next phase1 cycle gosub Wait_For_Next_Peak rpmDelay = 0 gosub Wait_For_Zero_Volts gosub Wait_For_Next_Peak pause delay 'delay x milliseconds before taking samples gosub Acquire_Phase_Samples 'take phase 1,2,3 and rectified DC samples gosub Average_DC_Samples 'average rectified DC samples for voltage and current gosub Convert_To_Mv 'convert raw A/D counts to millivolts gosub Compute_RPM 'compute latest RPM value gosub Compute_Cksum 'compute checksum for transmission of data gosub Transmit_Data 'transmit data to PC delay = delay + 1 'increment delay to next part of phase goto Main 'repeat '---------------------------------------------------------------------------------------- ' ' Sub Routines ' '---------------------------------------------------------------------------------------- Wait_For_Zero_Volts: pause 1 rpmDelay = rpmDelay + 1 readadc10 9,phase1Volts if phase1volts > 10 then goto Wait_For_Zero_Volts endif Wait_For_Zero_Volts_End: return '---------------------------------------------------------------------------------------- Wait_For_Next_Peak: pause 1 rpmDelay = rpmDelay + 1 readadc10 9,phase1volts if phase1volts < 30 then goto Wait_For_Next_Peak endif Wait_For_Next_Peak_End: return '---------------------------------------------------------------------------------------- Acquire_Phase_Samples: readadc10 9,phase1Volts 'take phase 1,2,3 and rectDC samples readadc10 8,phase2Volts readadc10 10,phase3volts readadc10 11,rectDC tempWord = phase1Volts 'average samples with previous readings phase1Volts = phase1Volts + phase1prev phase1Volts = phase1Volts /2 phase1Prev = tempWord tempWord = phase2Volts phase2Volts = phase2Volts + phase2prev phase2Volts = phase2Volts /2 phase2Prev = tempWord tempWord = phase3Volts phase3Volts = phase3Volts + phase3prev phase3Volts = phase3Volts /2 phase3Prev = tempWord tempWord = rectDC rectDC = rectDC + rectDCPrev rectDC = rectDC /2 rectDCPrev = tempWord return '---------------------------------------------------------------------------------------- Average_DC_Samples: rectDChi = 0 'initialize vars rectDClo = $FFFF oneOhmhi = 0 oneOhmlo = $FFFF for i = 1 to 50 readadc10 11,tempWord 'sample rectified DC and 1 ohm drop voltage if tempWord > rectDChi then '50 times to get the high and low values rectDChi = tempWord 'in order to smooth out ripples endif if tempWord < rectDClo then rectDClo = tempWord endif readadc10 12,tempWord if tempWord > oneOhmhi then oneOhmhi = tempWord endif if tempWord < oneOhmlo then oneOhmlo = tempWord endif next rectDCave = rectDChi + rectDClo 'compute average rectified DC voltage rectDCave = rectDCave / 2 'based on hi and lo values oneOhmave = oneOhmhi + oneOhmlo 'compute average 1 ohm drop voltage oneOhmave = oneOhmave / 2 if rectDCave > oneOhmave then 'test to see if OK to compute average current Iaverage = rectDCave - oneOhmave 'current = (rectDCave - oheOhmave) / 1 ohm endif return '---------------------------------------------------------------------------------------- Convert_To_Mv: 'use fractional multipy phase1Volts = phase1Volts */$04E1 'normalize to 4.88mv/count for the 10-bit A/D based on a phase2Volts = phase2Volts */$04E1 '5 volt reference = 5000 millivolts reference phase3Volts = phase3Volts */$04E1 '5000 mv / 1024 counts = 4.88 mv / count where rectDC = rectDC */$04E1 '$04 part is the integer rectDCave = rectDCave */$04E1 '$E1 part is the fraction based on 0.88*256 = 225 = $E1 Iaverage = Iaverage */$04E1 'current falls out to 4.88ma/count return '---------------------------------------------------------------------------------------- Compute_RPM: rpmDelay = rpmDelay * 3 'compensate delay for all 3 coils per rotation rpm = 10000 /rpmDelay 'compute rpm rpm = rpm * 3 'adjust for ratio of 12 coils and 16 magnets (3/4) rpm = rpm / 4 return '---------------------------------------------------------------------------------------- Compute_Cksum: cksum = b11 + b10 + b13 + b12 + b15 + b14 + b17 + b16 + b33 + b32 + b27 + b26 + b7 + b6 return '---------------------------------------------------------------------------------------- ' ' Note: Keep the bytes in the order shown as the PC software depends on having them transmitted ' exactly in this sequence. ' Transmit_Data: serout A.4,N9600_8,(b11,b10,b13,b12,b15,b14,b17,b16,b33,b32,b27,b26,b7,b6,cksum) return '---------------------------------------------------------------------------------------- end