|
Forum Index : Microcontroller and PC projects : Network UPS Tools (NUT) monitor using Micromite/Picomite
| Author | Message | ||||
| MikeO Senior Member Joined: 11/09/2011 Location: AustraliaPosts: 275 |
If you have constructed a UPS that does not have a network connection or even an old mains powered unit, here is a serial software driver using MMBasic. The software was ported from an Arduino design, the ref is in the code header. ' ' ***** upsnut ***** ' ******************************* ' Filename: upsnut-mm.bas ' Date: Mar 2022 ' File Version: ' Written by: M.Ogden ' Function: UPS NUT Tools hardware driver ' Device: micromite mx170, picomite ' Last Revision: ' Initial v0.5 ' Based on Megatec UPS emulation for use with NUT UPS software ' on Raspberry Pi , by Mike Waldron ' See https://github.com/xm381/Raspberry-Pi-UPS ' ******************************* 'IO Pin List 'Set for your hardware dim Vin_pin = A7 dim Vout_pin = A0 dim Vbat_pin = A6 dim LBO_pin = A2 dim Vout_Enable_pin = A3 ' Dim float Bsoc Dim Integer LBO 'hardware low battery (has no hysteresis): low = low battery dim float Vin=12.2 dim float Vout=5.2 dim float Vbat=12.2 Dim Integer LowBat = 0 'software low battery Dim Integer DeadBat = 0 Dim Integer Vin_Fail = 0 Dim integer Starting_Up = 0 Dim integer Running = 1 Dim integer Low_Battery = 2 Dim integer Shutting_Down = 3 Dim integer Shutdown = 4 Dim integer ShutdownCommand = 5 Dim integer RestartCommand = 6 Dim Integer State = Starting_Up Dim Integer Vout_Enable = 0 Dim Integer Beeper_Enable = 1 Dim Integer LED = 0 Dim Integer Command_Shutdown = 0 Dim Integer Command_Restart = 0 Dim String inputString = "" ' a string to hold incoming data Dim Integer stringComplete = 0 ' whether the string is complete 'UPS Rating Information Dim float UPS_RV = 5.2 'Rated Voltage Dim float UPS_RC = 1.3 'Rated Current Dim float UPS_BV = 3.7 'Rated Voltage Dim integer UPS_HZ = 0.0 'Rated Frequency ' Hysteresis for software lowbat Dim integer LowBat_Max = 3.60 Dim integer LowBat_Min = 3.55 Dim integer Dead_Bat = 3.50 Dim Integer Startup_Delay = 10 Dim Integer Shutdown_Delay = 60 Dim Integer Restart_Delay = 0 Dim Integer secs '********************* Change these values as needed ***********************/ dim header$="( " Dim string Company_Name ="Raspberry Pi " '15 characters, leave space if less than 15 characters Dim string UPS_Model ="Pi UPS " '10 characters, leave space if less than 10 characters Dim string CodeName ="UPSNUT " Dim string Version ="v1.0 " '10 characters, leave space if less than 10 characters '************ Set this section up for your hardware ' pinMode(Vin_pin, INPUT) ' Analog pin to measure input voltage (utility) ' pinMode(Vout_pin, INPUT) ' Analog pin to measure output voltage ' pinMode(Vbat_pin, INPUT) ' Analog pin to measure battery voltage ' pinMode(LBO_pin, INPUT_PULLUP) ' Digital pin to read low battery signal ' ' pinMode(Vout_Enable_pin, OUTPUT) ' Digital pin to turn on output ' digitalWrite(Vout_Enable_pin, LOW) ' ' pinMode(LED_BUILTIN, OUTPUT) ' Digital pin to iluminate Pin 13 LED durring UPS restart timeout 'serial Com1 setpin gp0,gp1,com1 open "com1:2400" as #5 SetTick 1000, T1,1 '1 sec secs Print codename+version 'main loop processing Do rec1 Loop '************************ Core Subs ***************** Sub T1 UPS_Status() UPS_State() secs = secs + 1 if State = Shutting_Down then State = ShutdownCommand) 'LED = !LED else LED= false end if if State = Starting_Up then LED = 1 if (State = RestartCommand) and (Restart_Delay >0) then LED = 1 'digitalWrite(LED_BUILTIN, LED) End Sub Sub rec1 'reads bytes from comms buffer , data terminated by CR will output a NewLine$ and set the UserFlag 'if userprocessflag=1 then exit sub Local a$ Local Integer p,l,i ' Print "Buffer:";loc(5) If Loc(5)=0 Then Exit Sub If Len(a$)>=235 Then i=255-Len(a$) Else i=20 EndIf 'print "i:";i a$=Input$(i,5) 'user supplied processing routine 'pause 100 ' Print a$; On error skip 'DEBUG lastline$=lastline$ + a$ 'add to data packet 'DEBUG ' Print lastline$ packet: l=Len(lastline$) p=Instr(lastline$,Chr$(13)) ' Print "Line Lenght:";l ' Print "CR?:";p ' Print "Buffer:";Loc(5) ' Print lastline$ ' Print newline$ ' ' If l>=235 And p=0 Then 'long line and no CR 'force line to be processed newline$=lastline$ lastline$="" userprocess 'force data process Exit Sub EndIf If p>0 Then 'CR found so process 'lastline$=replace$(lastline$,chr$(10),"") 'remove LF Newline$=Left$(Lastline$,p-1) 'check comms using temperature string from Pi 'if good reset the countdown clock If Instr(newline$,"{"+q$+"pi-temp"+q$+":")>0 Then cdclock=20 If l>p+1 Then lastline$=Mid$(lastline$,p+1) 'save the rest of the line Else lastline$="" EndIf 'recover standard data pairs from Pi Print "Process:";newline$ userprocess EndIf End Sub Sub UPS_Status() ' Dummy values Vin = 15.6 Vout = 5.2 Vbat = 12.2 lbo=1 '************ Set this section up for your hardware ' Vin = analogRead(Vin_pin) * 0.008 ' resistor divider halves voltage so double value for correct reading, 0.008 for 4.096v reference. ' Vout = analogRead(Vout_pin) * 0.008 // resistor divider halves voltage so double value For correct reading, 0.008 For 4.096v reference. ' Vbat = analogRead(Vbat_pin) * 0.004 // 0.008 For 4.096v reference. ' ' LBO = digitalRead(LBO_pin) If Vin < Vbat then Vin_Fail = 1 Else Vin_Fail = 0 end if End Sub Sub UPS_State() select case State Case 0 'Starting_Up If Vin_Fail =1 then State = Shutdown ElseIf (secs > Startup_Delay) then secs = 0 Vout_Enable = 1 State = Running end if Case 1 'Running If (Vin_Fail = 1) and (LowBat = 1) then State = Low_Battery secs = 0 end if Case 2 'Low_Battery If DeadBat = 1 then State = Shutdown ElseIf LowBat = 0 then State = Running secs = 0 end if Case 4 'Shutdown If Vin_Fail = 0 then State = Starting_Up secs = 0 end if Case 5 'ShutdownCommand If secs > Shutdown_Delay then secs = 0 Vout_Enable = 0 State = RestartCommand end if Case 6 'RestartCommand If Restart_Delay = 0 then secs = 0 ElseIf secs > Restart_Delay secs = 0 Restart_Delay = 0 Vout_Enable = 1 State = Running end if end select 'digitalWrite(Vout_Enable_pin, Vout_Enable) End Sub function constrain(v,a,b) If v>=a And v<=b Then constrain=v Else If v<a Then constrain=a Else constrain=b EndIf EndIf End function Sub userprocess ' Q1 Status Inquiry (MMM.M NNN.N PPP.P QQQ RR.R SS.S TT.T b7b6b5b4b3b2b1b0<cr> If newline$ = "Q1" Then 'print #5, "215.0 195.0 230.0 014 49.0 2.27 30.0 00101000" print #5, "( "; print #5, Str$(Vin,3,1,"0"); ' MMM.M Input voltage print #5, " "; print #5, Str$(Vin,3,1,"0"); ' NNN.N Input fault voltage print #5, " "; print #5, Str$(Vout,3,1,"0"); ' PPP.P Output voltage print #5, " "; print #5, "050"; ' QQQ Output current % print #5, " "; print #5, "00.0"; ' RR.R Input frequency print #5, " "; print #5, Str$(Vbat,1,2,"0"); ' S.SS Battery voltage print #5, " "; print #5, "21.1"; ' TT.T Temperature centigrade print #5, " "; ' UPS Status Byte print #5, Str$(Vin_Fail); ' 7 Utility Fail (Immediate) print #5, Str$(LowBat); ' 6 Battery Low print #5, Str$(Vin_Fail); ' 5 Bypass/Boost or Buck Active print #5, Str$(0); ' 4 UPS Failed print #5, Str$(1); ' 3 UPS Type is Standby (0 is On_line) print #5, Str$(0); ' 2 Test in Progress If (State = Shutting_Down ) Then State = ShutdownCommand print #5, "1"; ' 1 Shutdown Active Else print #5, "0"; EndIf print #5, str$(Beeper_Enable) ' 0 Beeper On ' S<n>R<m> Shut Down and Restore Command ElseIf (Left$(newline$,1)="S") And (Mid$(newline$,3,1)="R")Then 'and (val(mid$(newline$,4,1)>=0)) then ' elseif (inputString.startsWith("S") && inputString.indexOf("R") >= 0) then 'Integer R_index = val(mid$(newline$,4,1)) 'String SD_delay = inputString.substring(1, R_index) Shutdown_Delay = Val(Mid$(newline$,2,1)) * 60 Shutdown_Delay = constrain(Shutdown_Delay, 60,600) 'ensuring value is at least 1 minute 'String RS_delay = inputString.substring(R_index + 1) Restart_Delay = Val(Mid$(newline$,4,1)) * 60 If Restart_Delay > 0 Then Restart_Delay = constrain(Restart_Delay, 60, 36000) ' 1 minute to 10 hours (600 minutes) State = ShutdownCommand EndIf ' S<n> Shut Down Command ElseIf (Left$(newline$,1)="S") Then 'and (val(mid$(newline$,2,1)>0)) then Shutdown_Delay = Val(Mid$(newline$,2,1)) * 60 Shutdown_Delay = constrain(Shutdown_Delay, 60, 600) 'ensuring value is at least 1 minute State = ShutdownCommand ' C Cancel Shut Down Command ElseIf Left$(newline$,1)="C" Then State = Running ' I UPS Information Command #Company_Name UPS_Model Version<cr> ElseIf Left$(newline$,3)="I" Then print #5, "#" + Company_Name +" "+ UPS_Model +" "+ Version ' F UPS Rating Information #MMM.M QQQ SS.SS RR.R<cr> ElseIf Left$(newline$,3)="F" Then print #5, "#"; print #5, Str$(UPS_RV,3,1,"0"); print #5, " "; print #5, Str$(UPS_RC,3,1,"0"); print #5, " "; print #5, Str$(UPS_BV,2,2,"0"); print #5, " "; print #5, Str$(UPS_HZ,2,1,"0"); ' Q Turn On/Off beep ElseIf Left$(newline$,3) ="Q" Then if Beeper_Enable=1 then Beeper_Enable=0 else Beeper_Enable=1 end if ' ***** Unsupported Commands ***** ' D Status Inquiry *disable ElseIf Left$(newline$,3) ="D" Then print #5, "@" ' T 10 Seconds Test ' TL Test until Battery Low ' T<n> Test for Specified Time Period ElseIf (Left$(newline$,1)="T") Then print #5, "@" ' CT Cancel Test Command ElseIf Left$(newline$,3)= "CT" Then print #5, "@" ' ***** Custom Commands ***** ElseIf Left$(newline$,2)= "MS") Then print #5, "State: "; str$(State) print #5, "Startup: "; str$(Startup_Delay) print #5, "Shutdown: "; str$(Shutdown_Delay) print #5, "Restart: "; str$(Restart_Delay) ' Invalid command Else print #5, newline$ print #5, "" EndIf End Sub Network query from attached Linux box. mike@q4os-desktop:~/Desktop$ upsc RPUPS Init SSL without certificate database battery.charge: 100 battery.runtime: 3000 battery.voltage: 12.20 battery.voltage.high: 4.10 battery.voltage.low: 3.45 battery.voltage.nominal: 3.70 device.mfr: Raspberry Pi device.model: Pi UPS device.type: ups driver.name: blazer_ser driver.parameter.offdelay: 60 driver.parameter.ondelay: 1 driver.parameter.pollinterval: 2 driver.parameter.port: /dev/ttyUSB0 driver.parameter.runtimecal: 1500,100,3000,50 driver.parameter.synchronous: no driver.version: 2.7.4 driver.version.internal: 1.57 input.frequency: 0.0 input.voltage: 15.6 input.voltage.fault: 15.6 output.voltage: 5.2 ups.beeper.status: enabled ups.delay.shutdown: 60 ups.delay.start: 60 ups.firmware: v1.0 ups.load: 50 ups.mfr: Raspberry Pi ups.model: Pi UPS ups.status: OL ups.temperature: 21.1 ups.type: offline / line interactive mike@q4os-desktop:~/Desktop$ Codenquilts |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |