|
Forum Index : Microcontroller and PC projects : Best way to measure solar input power?
| Author | Message | ||||
| BrianP Senior Member Joined: 30/03/2017 Location: AustraliaPosts: 292 |
Hi team I desire to use a 'Mite (which one yet to be decided) to measure & accumulate the daily solar output. This is a 24volt system; over the last 7 years or so I have managed to accumulate 3 dissimilar solar panel banks & regulators, only 1 of which will store a daily total. All feed into the common 24 volt battery bank / inverter circuitry, hence the desire to combine them all into a daily totals record. Using a shunt on the common negative (probably a short length of suitable cable as combined input on a good day can be 150 amps) my options would seem to be: 1. Use a single hall effect sensor (would likely still need a shunt because of the current) 2. Amplify the shunt voltage drop & measure on the 'Mite. 3. Use 3 hall effect sensors - 1 on each regulator - max. amps then would be 80. On the 'Mite I would be measuring the input voltage & current to calculate the batteries input KWH & archiving over time. Not looking for maximum accuracy here. If anyone has any thoughts / suggestions / ideas / musings / experiences to share they will be most welcome. B |
||||
Chopperp![]() Guru Joined: 03/01/2018 Location: AustraliaPosts: 1106 |
I assume you have checked out the SOLAR forum on TBS. Lots of stuff to wade through there. Brian ChopperP |
||||
| Gizmo Admin Group Joined: 05/06/2004 Location: AustraliaPosts: 5160 |
A negative rail shunt is the easiest solution. Or the Alegro shunt sensors, work great with microcontrollers, see https://www.thebackshed.com/windmill/articles/Alegro.asp. Glenn The best time to plant a tree was twenty years ago, the second best time is right now. JAQ |
||||
| BrianP Senior Member Joined: 30/03/2017 Location: AustraliaPosts: 292 |
Thanks Glenn / Brian I'm thinking I might use 3 of these so each bank can be individually monitored & archived. Once you have a 'Mite involved the world is at your feet... B Edited 2020-09-12 11:07 by BrianP |
||||
| MikeO Senior Member Joined: 11/09/2011 Location: AustraliaPosts: 275 |
Hi Brian, I have had a Garden Solar Battery system for several Years, using ACS714 type sensors, they just work. A Maximite (that's how long ago I first stated the system) controls the system. I used to use Xbee's to transmit the results but last year was converted to ESP8266 running ESPeasy sending to my wifi network and the Emoncms data base running on a RPI4. I have attached the maximite code below , sorry there is an awfull lot of redundent code still in there from the previous Xbee's that were used but the acquisition code may be usefull. The lines like xbsend "TaskValueSet, 1,2," + str$(wpvAmps)" are the serial strings to the ESP8266 (ESPEasy). The are some photos of the system on my web page including some live data feed. Mike 'MMEDIT!!! Basic Version = Maximite_V4.5 'MMEDIT!!! Port = COM5:38400:30,150 'MMEDIT!!! Device = Maximite_V4.5 'MMEDIT!!! Config = 1001111011210001111010110100110 ' ******************************* ' ***** PV Solar System Monitor ) ***** ' ******************************* ' Filename: pvmonxx.bas ' Date: ' Org File Version: 0.5 ' Written by: M.Ogden, www.Codenquilts.com.au ' Function: PV Solar Monitor ' ******************************* '09 now running ESP8266/espeasy ' Global Variables wBattAmps=0 wBattWatts=0 wPVAmps=0 wPVWatts=0 wPVvolts=0 wBattVolts=0 wTime = 0 wTotalSecs=0 WattHours = 0 sample=0 TotalCharge=0 averageamps=0 ampSeconds=0 ampHours=0 BackLight=24 c$="," 'cGreenLed=b.3 'cPowerOn=b.7 iNewdayFlag=0 icheckTimeFlag=1 'get time from network when set iXbeeFlag=0 'clear Xbee data flag iXbeeAreaFlag=0 'clear Xbee Area flag lastline$="" ibytecount=0 inewline=0 pvtest=0 sVersion$="0.7" iRefOffset=0.01 ''I/O pin configuration SetPin 1,1 ' Pin 1 - PV Voltage SetPin 2,1 ' Pin 2 - Battery Voltage SetPin 3,1 ' Pin 3 - Battery Load current SetPin 4,1 ' Pin 4 - PV supply Current SetPin 5,8 ' Pin 5 - Sample Led setpin 9,1 'Pin 9 - 5vdc supply 'setpin 10,din 'SETPIN 23,DOUT ' Pin 23 - LCD Backlight 'libraries 'Library Load "shlbut00.lib" 'Library Load "sernet04.lib" 'Library Load "shlLcd00.lib" DIM MTH$(12) length 3 'Setup array for handling the months of the year MTH$(1)="JAN":MTH$(2)="FEB":MTH$(3)="MAR":MTH$(4)="APR":MTH$(5)="MAY":MTH$(6)="JUN" MTH$(7)="JUL":MTH$(8)="AUG":MTH$(9)="SEP":MTH$(10)="OCT":MTH$(11)="NOV":MTH$(12)="DEC" 'Keyboard and Display Initialise 'Lcd Init 25,26,27,28,29,30 'LCDBacklight (1) 'Lcd 2,1,"Initialising..." 'Lcd 1,1, "mmDevice v" + sVersion$ 'Pause 5000 'Lcd 2,1, "Running.. " 'Lcd 3,1, "Line 3 " 'Lcd 4,1, "Line 4 " 'Init xb communications InitxbComm 'initialise comms iDeviceID=21 'Device ID xbWake 'Xbee wake Pin(5)=0 'Heartbeat led off 'develop area 'end develop area 'Interrupts SetTick 1000, Heartbeat,1 'Heartbeart LED SetTick 60000, SendDataUpdate,2 ' Data update to network each minute 'Program Start Randomize timer 'seed random number routine ' xbopenconsole logdata "Restart" sample SendDataUpdate 'Main Program loop Do if iCheckTimeFlag=1 then ReqNetworkTime 'Periodic time Update from Server Sample 'Sample Voltage and currents sensors ' wait for the 10 second mark to come up pause 10000 Loop 'Typical use where Device reads some sensors ' Sample , reads sensors and updates stored variables for Voltage, current and power sub Sample Pulse 5,5 'Pulse led wRefVdc=ReadVoltage(9,1,64)+ iRefOffset 'RefVdc as 5vdc/2 'print wRefVDC ResetWatchDog 'Reset watchdog first wPVVolts = ReadVoltage(1,7.7,64) 'PV Voltage 'wPVvolts=rand(22,0) 'test Print"PV Volts=",wPVVolts 'DEBUG wPVAmps=ReadCurrent(4,wRefVDC,0.04,64) 'PV current 'wPVAmps=rand(6,1.34) 'test Print "PV Current=",wPVAmps 'DEBUG wBattVolts = ReadVoltage(2,7.7,64) 'Battery Voltage 'wBattVolts=rand(15,10) 'test'test Print"Battery Volts=",wBattVolts 'DEBUG wBattAmps=ReadCurrent(3,wRefVDC,0.04,64) 'Battery Load current 'wBattAmps=rand(10,0.34) 'test Print "Battery Current=",wBattAmps 'DEBUG wBattWatts=wBattAmps*wBattVolts 'Calc instantaneous watts wPVWatts=wPVAmps*wPVVolts 'Calc instantaneous watts 'Calculate slice in Watthours for Battery Usage FractionalBattWattHours=wBattWatts*0.00138 'Watts/(5/3600) 'Calculate slice in Watthours for PV Charge FractionalPVWattHours=wPVWatts*0.00138 'Watts/(5/3600) Print "FracBattWattHours=",FractionalBattwatthours 'DEBUG Print "FracPVWattHours=",FractionalPVWatthours 'DEBUG 'Add wattHour slices to total Watt Hours BattWattHours = BattWattHours+FractionalBattWattHours PVWattHours = PVWattHours+FractionalPVWattHours Print "BattWattHours=",Battwatthours 'DEBUG Print "PVWattHours=",PVwatthours 'DEBUG print "" 'DEBUG end sub 'Typical use where on request a data update is sent to network Sub SendDataUpdate 'CallHome ' ***** Do other things here ****** ' wpvvolts=19.5 ' wpvamps=2.5 ' wBattvolts=13.8 ' wBattamps=1.5 ' Battwatthours=23 ' pvwatthours=67 bhigh=Maxint(wpvvolts) blow=remainder(wpvvolts) 'xbsend (iAreaTX,93,iDeviceID,bhigh,blow) xbsend "TaskValueSet, 1,1," + str$(wpvvolts) bhigh=Maxint(wpvAmps) blow=remainder(wpvAmps) 'xbsend (iAreaTX,87,iDeviceID,bhigh,blow) xbsend "TaskValueSet, 1,2," + str$(wpvAmps) bhigh=Maxint(wBattVolts) blow=remainder(wBattVolts) 'xbsend (iAreaTX,88,iDeviceID,bhigh,blow) xbsend "TaskValueSet, 1,3," + str$(wBattVolts) bhigh=Maxint(wBattAmps) blow=remainder(wBattAmps) 'xbsend (iAreaTX,89,iDeviceID,bhigh,blow) xbsend "TaskValueSet, 1,4," + str$(wBattAmps) bSTR$=left$(wNumber$(wBattWatts),8) hhigh= BinToDec(bSTR$) bSTR$=right$(wNumber$(wBattWatts),8) blow= BinToDec(bSTR$) ' xbsend (iAreaTX,90,iDeviceID,bhigh,blow) bhigh=Maxint(Battwatthours) blow=remainder(Battwatthours) 'xbsend (iAreaTX,91,iDeviceID,bhigh,blow) xbsend "TaskValueSet, 2,1," + str$(Battwatthours) bhigh=Maxint(PVwatthours) blow=remainder(PVwatthours) 'xbsend (iAreaTX,92,iDeviceID,bhigh,blow) xbsend "TaskValueSet, 2,2," + str$(PVwatthours) Print time$;c$;wpvvolts;c$;wpvamps;c$;wbattvolts;c$;wbattamps;c$;wbattwatts;c$;battwatthours;c$;pvwatthours Logdata str$(wpvvolts)+c$+str$(wpvamps)+c$+str$(wbattvolts)+c$+str$(wbattamps)+c$+str$(wbattwatts)+c$+str$(battwatthours)+c$+str$(pvwatthours) End Sub 'UserProcess routine (programmed by User) is called by XBreceive routine when a complete data packet 'is received , to check for commands. Sub UserProcess 'User Subroutine to process incomming communications data 'update 'Data pkt DeviceID:CommandID:High:Low ' Print "Process new Packet:" + newline$ 'DEBUG inewline=0 'reset the flag ipktDeviceID=val(parse$(newline$,1)) iCommandID=val(parse$(newline$,2)) DataHi$=parse$(newline$,3) DataLo$=parse$(newline$,4) 'print "User process data:"+ Str$(icommandID) + " " + Datahi$ + " " + datalo$ 'DEBUG if ipktDeviceID<>iDeviceID then exit sub 'reject not this device ' print "User process data for this device:"+ Str$(icommandID) + " " + Datahi$ + " " + datalo$ 'DEBUG If icommandID=17 Then 'process Time Sync request validatetime if validtime=0 then exit sub Time$=Datahi$ + ":" + datalo$ + ":00" ' Print "Corrected Time:" + Time$ xbAck iCheckTimeFlag=0 EndIf If icommandID=117 Then 'request Time Sync ReqNetworkTime 'request Time Sync xbAck EndIf If icommandID=199 Then 'Start open console mode xbAck xbOpenConsole EndIf If icommandID=20 Then 'Request data Update to Network xbAck SendDataUpdate EndIf 'DisplaySysSettings End Sub 'general purpose routines function wNumber$( sNumber) 'creates binary string of Whole Number local tNumber tNumber=cint(sNumber) 'rounded Integer wNumber$= right$("0000000000000000" + bin$(tnumber),16) 'print wnumber$ end function Function DecToBin$(DecNum$) Local BinNum$ Local lDecNum Local I I = 0 lDecNum = Val(DecNum$) Do If lDecNum And 2 ^ I Then BinNum$= "1" + BinNum$ Else BinNum$ = "0" + BinNum$ EndIf I = I + 1 Loop Until 2 ^ I > lDecNum DecToBin$ = BinNum$ End Function Function BinToDec(BinNum$) local I , DecNum ' Loop thru BinString For I = Len(BinNum$) To 1 Step -1 ' If bit is 1 then raise 2^LoopCount and add it to DecNum If val(Mid$(BinNum$, I, 1)) And 1 Then DecNum = DecNum + 2 ^ (Len(BinNum$) - I) EndIf Next I ' Return DecNum as a String BinToDec = DecNum End Function Function Rand(Low , High ) Rand = ((High - Low + 1) * Rnd) + Low End Function function MaxInt(iNum) MaxInt=int(iNum) if MaxInt>255 then MaxInt=255 end function sub ResetWatchDog setpin 10,dout pause 200 setpin 10,din end sub sub LogData (msg$) LFILE$="B:\LOG\" + MID$(DATE$,1,2) + MTH$(VAL(MID$(DATE$,4,2))) + MID$(DATE$,9,2) + ".LOG" LDT$=DATE$ + "," + TIME$ + ">" + " " + msg$ + CHR$(13) OPEN LFILE$ FOR APPEND AS #3:FlagSD=1 PRINT #3,LDT$:CLOSE #3:FlagSD=0 end sub Sub LCDbackLight(N) pin(BackLight)=N end sub sub ValidateTime validtime=1 if val(datahi$)<0 or val(datahi$)>23 then validtime=0 if val(datalo$)<0 or val(datalo$)>59 then validtime=0 end sub Function Parse$(s$,FieldNumber) Local stringArg$ StringArg$ = S$ + "," intOldY = 1:intX=0:intY=0 Parse$ = "" While intY < Len(StringArg$) And intX < FieldNumber intY = Instr(intOldY, StringArg$, ",") intX = intX + 1 If intX = FieldNumber Then Parse$ = Mid$(StringArg$, intOldY, intY - intOldY) EndIf intOldY = intY + 1 Wend End Function sub Heartbeat Pin(0) = 1 Pause 100 Pin(0) = 0 'Pulse Heartbeat led 'Lcd 3,1, time$ itime= 3600*(Val(Left$(Time$,2))) itime=itime + (60*(Val(Mid$(Time$,4,2)))) + Val(Right$(Time$,2)) 'Print itime If itime<=3 Then ' midnight so reset for new day Battwatthours=0:pvWattHours=0 iCheckTimeFlag=1 'sync Clock EndIf End Sub Function Remainder (wNumber) wNumber=Abs(wNumber) 'return absolute number Remainder=Val(Mid$(Str$(wNumber-Fix(wNumber)),3,2)) if remainder>255 then remainder=255 End Function 'end General routines 'sensor routines Function ReadCurrent(InputPin,VoltageOffset,Cal,Smoothing) Local Count Local Voltage Local AccVoltage For Count = 1 To Smoothing 'take mulpiple reads Voltage=Pin(InputPin) AccVoltage = AccVoltage+Voltage Next Count ' print ((AccVoltage/smoothing)-VoltageOffset) AccVoltage = ((AccVoltage/smoothing)-VoltageOffset)/cal ' If AccVoltage<0 Then accvoltage=0 'trap negative numbers Readcurrent=AccVoltage End Function Function ReadVoltage(InputPin,Cal,Smoothing) Local Count Local Voltage Local AccVoltage For Count = 1 To Smoothing 'take mulpiple reads Voltage=Pin(InputPin) AccVoltage = AccVoltage+Voltage Next Count 'print accVoltage/smoothing AccVoltage = (AccVoltage/smoothing)*cal ' If AccVoltage<0 Then accvoltage=0 ReadVoltage=AccVoltage 'trap negative numbers End Function 'end Sensor routines ''$INCLUDE: mmsernet.lib ' *************************************************************** ' ******************** Maximite Wireless *********************** ' *************************************************************** ' Filename: MMsernet.bas ' Date: 09/10/2011 ' Org File Version: 1.01 ' Written by: M.Ogden, www.Codenquilts.com.au ' Function: Xbee wireless communications for Maximite ' using SerialNet protocol. ' ' SerialNet consists of a simple 6 byte ' packet developed for use with Picaxe ' Packet is Sync,Area,DestID,CallID,HiData,LoData ' Area byte allows for transmission areas. ' Pin 6 is Xbee sleep, file#5 is used for handle ' ' Revision: ' *************************************************************** '1.01 30/6/13 partially updated to user defined routines '1.02 added constants for sleep pin, added OpenConsole mode 'Initialise routines Sub initxbcomm iAreaTX=86:iArea=85:iDeviceID=21 'Transmision out of local Area, local area, of Device and Device ID (set to suit) icheckTimeFlag=1 'get time from network on start up iXbeeFlag=0 'clear Xbee data flag iXbeeAreaFlag=0 'clear Xbee Area flag lastline$="" ibytecount=0 inewline=0 iSleep=6 ' Sleep pin# , nb. set correct pin in Initialise routine "initxbcomm" SetPin 6,DOUT 'set digital output for Sleep pin connection Open "com1:19200,1024,xbreceive" As #5 'initialise comms End Sub Sub xbwake Pin(iSleep)=0 End Sub 'xbee wake Sub xbsleep Pin(iSleep)=1 End Sub 'Xbee sleep Sub closexbComm Close #5 'SetPin 23,0 End Sub 'close comms and xbee Sub xbOpenConsole Closexbcomm 'close xb comms handle xbwake 'wake up xbee module Open "com1:2400" As console 'open console mode End 'stop running program End Sub 'Sub xbsend (AreaTX,IDdestinationprocess,IDCallerprocess,IDdataHigh,IDdataLow) ' print IDdestinationprocess;IDCallerprocess;IDdataHigh;IDdataLow ' msgFrame$ = "U" + Chr$(AreaTX) + Chr$(IDdestinationprocess) + Chr$(IDCallerprocess) + Chr$(IDdataHigh) + Chr$(IDdataLow) ' Print #5, msgframe$ 'End Sub Sub xbsend (msgframe$) 'on error skip print "xbsend:" + msgframe$ Print #5,msgframe$ End Sub Sub xbreceive a$=Input$(1,#5) 'user supplied processing routine If iXbeeFlag=1 And iXbeeAreaFlag=1 Then GoTo CompletePacket 'read rest of data packet If iXbeeFlag=1 And iXbeeAreaFlag=0 Then 'check for correct area flag 'print asc(a$) If Asc(a$)=iArea Then 'check for correct Area (for this device) iXbeeAreaFlag=1 ' correct so set flag Else iXbeeFlag=0 And iXbeeAreaFlag=0 'not correct so clear flags and look again EndIf Exit Sub 'exit EndIf If iXbeeFlag=0 And iXbeeAreaFlag=0 Then If a$="U" Then 'check for xBee sync byte iXbeeFlag=1 'got sync byte so set flags, now we need correct area flag EndIf Exit Sub 'exit EndIf Exit Sub 'exit 'invalid so exit CompletePacket: temp$=Str$(Asc(a$)) 'add leading zero as required lastline$=lastline$+","+temp$ 'store data packet ibytecount=ibytecount+1 'count databytes If ibytecount=4 Then GoTo processPacket Exit Sub 'exit get more bytes 'data line received - now process processPacket: lastline$=Mid$(lastline$,2) 'print "packet:" + lastline$ Newline$=Lastline$ 'store data inewline=1 'new line available flag ' Print newline$ '-TESTING ONLY If Left$(newline$,2) = "14" Then 'PixBee network is requesting a data slot AreaTX$ = parse$(newline$,3) xbAck 'call RXslot routine to allow Device to Send data goto ClearFlags EndIf '******** Call external user routines to parse line data packet here ********* If inewline=1 Then Userprocess 'End of packet clear flags ClearFlags: iXbeeFlag=0 'clear Xbee data flag iXbeeAreaFlag=0 'clear Xbee Area flag lastline$="" ibytecount=0 End Sub 'from xbreceive sub Callhome 'xbsend (iAreaTX,8,iDeviceID,iArea,2) 'Call Home with counter value (status), ie 2 mins in dataLow end sub Sub CmdSlot 'xbsend (iAreaTX,13,iDeviceID,iArea,0) 'request Network command slot End Sub Sub xbAck 'Sub RxSlot , responds to Pixbee network data transfer request by Sending a ID "15" 'xbsend (iAreaTX,15,iDeviceID,iCommandID,1) 'Network command acknowledge End Sub Sub ReqNetworkTime ' xbsend (iAreaTX,17,iDeviceID,iArea,0) 'request Network time update End Sub 'UserProcess routine is called by XBreceive routine when a complete data packet is received , to check for commands 'Sub UserProcess 'User Subroutine to process incomming communications data 'End Sub 'End of Maximite wireless library'End INCLUDE Codenquilts |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |