; Program to chaacterize capacity of rechargable AA battery ; Roderick Young 07-FEB-2014 ; The program outputs a pwm waveform, which is smoothed by an RC filter ; to generate a voltage that drives the gate of a MOSFET. The native DAC ; does not have enough resolution to generate a precise gate drive voltage. ; The source of the transistor is grounded, and the drain goes through a one ; ohm sense resistor to draw current from the battery. ; The program periodically reads the voltage across the sense resistor, ; and adjusts the duty cycle of the pwm to generate the gate voltage which ; will allow the desired current through the drain. ; Periodic samples of the battery voltage are logged. #picaxe 08m2 #no_data symbol BatPort = C.1 symbol SensePort = C.4 symbol GateDrive = C.2 symbol StartSwitch = pinC.3 symbol GateDuty = w0 ; duty cycle of pwm symbol BatVolt = w1 symbol SenseVolt = w2 symbol ResVolt = w3 symbol Seconds=w4 symbol Minutes=w5 symbol temp=w7 symbol TargetVolt=50 ; target current, 2 mA per count, so 50 -> 100 mA pullup %001000 ; pullup only on input switch dirsC = %000100 ; 1=output, 0=input low GateDrive ; the ADC is set to read 2048 mV full scale ; that's 2 mV per bit, or 2 mA per bit across the 1.0 ohm sense resistor fvrsetup FVR2048 adcconfig %011 Seconds = 0 Minutes = 0 GateDuty = 680 ; fair starting value ; wait for start button StartWait: if StartSwitch != 0 then goto StartWait ; take initial reading without load readadc10 Batport,BatVolt BatVolt = BatVolt + BatVolt sertxd("Open circuit voltage = ",#BatVolt," mV",13,10) ; show intended load point temp = TargetVolt + TargetVolt sertxd("Load current = ",#temp," mA",13,10) sertxd("Minute, Voltage (mV)",13,10) sertxd("0, ",#BatVolt,13,10) ; show unloaded sample point pwmout GateDrive, 255, GateDuty SetCurrent: pause 994 ; this loop should average 1 second at 4 MHz readadc10 BatPort,BatVolt ; read voltage across sense resistor readadc10 SensePort,SenseVolt ResVolt = BatVolt - SenseVolt BatVolt = BatVolt + Batvolt ; double it for actual reading in mV Seconds = Seconds + 1 if Seconds >= 60 then Seconds = 0 Minutes = Minutes + 1 sertxd(#Minutes,", ",#BatVolt,13,10) endif ; for debug ;sertxd("Volt=",#BatVolt," SenseVolt=",#SenseVolt," ResVolt=",#ResVolt," Duty=",#GateDuty,13,10) if ResVolt = TargetVolt then goto SetCurrent ; spot on, no adjustment needed if ResVolt < TargetVolt and GateDuty < 1023 then GateDuty = GateDuty + 1 elseif ResVolt > 1023 and GateDuty < 1023 then ; there are no signed integers, so if ResVolt > 1023, it's really negative GateDuty = GateDuty + 1 elseif ResVolt > TargetVolt and GateDuty > 0 then GateDuty=GateDuty - 1 endif pwmduty GateDrive,GateDuty goto setcurrent end