Nice and simple UPS/Battery 18650 Li-on power supply which are easily hack-able if you want to make it a little smarter. These units , I got mine here
These units are cheap and perfect for using reclaimed 18650 cells from battery packs. Shown here is one of the new units and then a modified one adding a voltage adjustable/trimmed output and a mosfet controlled switched output. The supply could then run a small micro or raspberry Pi.
in these photos is the original prototype shown where a Picomite is controlling the PSU which then powers a Raspberry Pi Zero with soft power up/power down, UPS functions , power fail detection , Pi shutdown etc.
Cheap simple UPS/Battery supply for projects.
Cheap simple UPS/Battery supply for projects.
You do not have the required permissions to view the files attached to this post.
- cicciocb
- Site Admin
- Posts: 2092
- Joined: Mon Feb 03, 2020 1:15 pm
- Location: Toulouse
- Has thanked: 448 times
- Been thanked: 1384 times
- Contact:
Re: Cheap simple UPS/Battery supply for projects.
Hi,
thanks for the tips and for your interesting solution.
I've bought some of them ....
thanks for the tips and for your interesting solution.
I've bought some of them ....
Re: Cheap simple UPS/Battery supply for projects.
Thanks for the support cicciob, code to drive the UPS is on the way.[Local Link Removed for Guests] wrote: [Local Link Removed for Guests]Mon Sep 18, 2023 2:26 pm Hi,
thanks for the tips and for your interesting solution.
I've bought some of them ....
Re: Cheap simple UPS/Battery supply for projects.
Here is a software package for ESP32 to go with the UPS/Battery pack. In this setup the UPS/Battery pack is working as a power supply for the ESP32 which may continue working when (mains) power fails. The ESP32 is always being powered by the UPS (mains or battery) but although not actually being used in this setup there is also a 5VDC switched output which can power other attached equipment.
Functions are :
Soft switch Running/standby controlling a switched 5VDC
Power fail detected
Time on UPS monitored , at expiration switched 5VDC is turned off, goes into standby
Power Restoration detected
On power restoration Startup occurs , switched 5VDC turned on.
Last known status retained if complete power removed from esp32
Functions are :
Soft switch Running/standby controlling a switched 5VDC
Power fail detected
Time on UPS monitored , at expiration switched 5VDC is turned off, goes into standby
Power Restoration detected
On power restoration Startup occurs , switched 5VDC turned on.
Last known status retained if complete power removed from esp32
Code: [Local Link Removed for Guests]
' ' ***** Annex UPS *****
' *******************************
' Filename: ups.bas
' Date: Sept 2023
' File Version:
' Written by: M.Ogden
' Function: ups controller
' Device: esp32
' Last Revision:
' Initial v.5 ported from picomite (rpi-pico)
'
' *******************************
'Constants & Variables
ver$="v0.5"
flogs$="/root/logs/"
fvar$="/root/cfg/var.dat" 'variables save address
vvar$="" 'variables save contents
no_battchg=0 'set if no battery charge pin
max_task=15 'max number of tasks
upsexpired=3600 'time in seconds allowed on battery (default 1Hr)
cm$=",":q$=chr$(34):J$="&":temp1$="":temp$="":lastline$="":newline$=""
'prop temp control, when used
ffan=70
fan_cycle=60
temp_run=40
stall_percent=30
temp_max=55
fan_ratio=((99-stall_percent)/(temp_max-temp_run))
rt=0:it=0
secs=0:flag=0 'periods
uptime=0 'time up in seconds
upspower=0 'ups power on
upstime=0 'time on battery
errflag=0 'error
userprocessflag=0
cdclock=20 ' seconds
rpitemp$="45"
rpiload$=""
rpidate$="":rpitime$="":rpiutc$=""
standby=0
powerflag=0:powerfail=0
powermsgflag=1
dim tt(max_task) 'Task Timer array
tx=0:ty=0
'
'***** User Variables ******
''ESP32 38pin dev kit Pin Numbers
pipwr=27
battchg=14
upspwr=12
pled=26
nled=25
aled=33
butt=32
fdrv=13 'when used
ftemp=2 'when used
'pin.mode IO
pin.mode pled, output 'Power Led
pin.mode nled, output 'Network Led
pin.mode aled, output 'Activity Led
pin.mode pipwr, output 'ups switched
pin.mode butt,input ,pullup 'button
interrupt butt, buttonpress ' set button interrupt
pin.mode battchg,input ,pullup 'ups battery charged input
'interrupt battchg, battcharged ' set ups battery charged interrupt
pin.mode upspwr,input,pulldown 'ups power input
interrupt upspwr, nopower' set ups power interrupt
pin(pled)=0 'Power Led (on)
pin(nled)=1 'Network Led (Off)
pin(aled)=1 'Activity Led (Off)
'
' Timers & Interupts
'Task "Tick" Timer List
'tt(0)=Expired, tt(-1)=Disabled
'setup initial tasks
task 0,-1 ' usually run once on startup
timer0 1000 ,T1 'establish seconds "Tick Timer"
'
'setup and Initialise
ONERROR GOTO Error_Handler
udp.begin 5001 'set the UDP commmunication using port 5001
ONERROR GOTO Error_Handler
option.WDT 20000 ' set the WDT at 10 second
'********* Start Up *********
wlog ""
wlog"UPS - ";
wlog"ver: "+ver$
'
varRestore
if standby=1 then
onudp off 'UDP receive Off
wlog"Standby"
led3 pled, 1 'power led off
pin(pipwr)=1 'shutdown power supply
''pwm 1,ffan,stop 'off
else
'start up via Power Source check
if pin(upspwr)=1 then
powerflag=1
gosub startupseq
end if
end if
if no_battchg=1 then gosub battcharged 'get battery status
'********* Main Loop *********
'main loop processing
'main:
do
it=millis
option.WDTreset
if standby =0 then
task 0,-1
'wlog"Run Tasks"
task 2,10 'active
'********************************************
' insert your main code here....
'********************************************
end if
if upstime>upsexpired then shutdownseq
'if upstime>some-triggerpoint then some-event
'eg close down some other server
rt=(millis-it)/1000
' wlog"Elapsed:";timer-looptime/1000
loop
'***** End main program loop
end
'core routines
sub runonce
settick 0,0,2 'disable timer
end sub
battcharged:
if pin(battchg)=1 then return
if pin(battchg)=0 then
wlog"Battery is charged"
upstime=0 'reset UPS timer
else
if pin(upspwr)=1 then
wlog"Power On - Battery is charging"
else
wlog"Power Off - Battery not charged"
end if
end if
return
'power plug interupt
nopower:
pause 100 'debounce
if no_battchg=1 then upstime=0 'reset UPS timer
if pin(upspwr)=1 then
wlog"Power OK"
powerflag=1
powermsgflag=1
if powerfail=1 then gosub startupseq 'only start if in standby
else
if powerfail=0 then
wlog"Power Disconnected"
wlog"UPS Power"
textmsg "text","Power has been disconnected"
if standby =0 then
powerfail=1
powerflag=0
upstime=0 'reset time
end if
end if
end if
return
'sub notrunning
'if standby=1 then exit sub
'wlog"Pi Not-running"
'shutdownseq
'end sub
'Heartbeat
T1:'Tick Timer
'wlog"Standby:Cdclock";standby;" ";cdclock
for tx= 0 to 15
ty=tt(tx)
if ty>0 then
ty=ty-1
tt(tx)=ty
end if
next tx
if standby=0 then 'normal running
uptime=uptime+1 'time while running
if uptime=60 and powermsgflag=0 then powermsgflag=1 'set flag 60secs after power restored
else 'in standby
task 1,5
end if
if powerflag=0 then
upstime=upstime+1 'time in disconnected and on ups power
task 1,5 'in No Power
end if
if errflag=1 then
led2 pled
end if
'wlog"Uptime:";uptime;" upstime:";upstime
return
'task run , t- task#, l- load value
sub task(tsk,lsk)
'wlog"Task";str$(tsk)
if tsk>max_task then exit sub
if tt(tsk)<0 then exit sub
if tt(tsk)>0 then exit sub
tt(tsk)=lsk
select case tsk
case 0
gosub onstartup
case 1 '5 secs
LED1 pled ,100
if powerflag=0 then gosub upsruntime 'print UPS running time
case 2 '10 secs
'adjFanSpeed val(rpitemp$)
'textmsg "cpucore",str$(val(rpitemp$),2,1)
case 3
'blank
case 4
'midnight
case 9
'wlog"********************************** HTTP, UDP data"
case 5
'
case 6
'
case 7
status
case 8
'
case 9
'
case 10
'
case 11
'
case else
tt(tsk)=-1 'stop the task
'wlog"No Task! - stop the task"
end select
end sub
'Led1 pulse p=pin
sub led1(le,d)
if d=0 then d=50
if pin(le)=1 then
pin(le)=0
pause d
pin(le)=1
else
pin(le)=1
pause d
pin(le)=0
end if
end sub
'Led2 toggle
sub led2(le)
if pin(le)=1 then
pin(le)=0
else
pin(le)=1
end if
end sub
'Led3 set
sub led3(le,hl)
pin(le)=hl
end sub
upsruntime:
wlog "UPS RunTime"
wlog uptime;" ";upstime
textmsg "text","Will close down in "+str$(upsexpired-upstime/60,"%6.0f")+" mins"
wlog"Will close down in ";str$(upsexpired-upstime/60,"%6.0f")+" mins"
return
# Set the 'pwm of fan pin
sub adjFanSpeed(CPU_temp)
if CPU_temp > temp_run then
FAN_cycle = (((CPU_temp - temp_run)*fan_ratio)+stall_percent)
FAN_cycle = min(100,max(stall_percent,FAN_cycle))
'pwm 1,ffan,fan_cycle
else
'pwm 1,ffan,stop 'off
FAN_cycle=0
end if
end sub
sub textmsg(obj$,tmsg$)
'print#5, "{"+q$+obj$+q$+":"+q$+tmsg$+q$+"}"
end sub
buttonpress:
if pin(butt)=1 then return
wlog "button"
pause 50 'debounce
if pin(butt)=0 then gosub presstime
return
presstime:
wlog "button presstime"
pause 1000
if pin(butt)=0 then
if standby=0 then 'running
gosub shutdownseq
else
'start up via Power Source check
wlog"Check Power:";pin(upspwr)
if pin(upspwr)=1 then
powerflag=1
gosub startupseq
end if
end if
else
wlog"shortpress"
led1 pled,100
end if
return
shutdownseq:
option.WDTreset ' reset
onudp off 'UDP receive off
wlog"Shutdown"
textmsg "text","Shutting down RPI"
led1 pled, 1000
'pin(pishdn)=0 'shutdown RPI
'pause 1000
'pin(pishdn)=1
wlog"Standby"
errflag=0
standby=1
OPTION.CPUFREQ 80
wlog"RPI-Shutdown Delay"
pause 15000' Wait for pi to shutdown
led3 pled, 1 'power led off
wifi.sleep
wlog"shutdown supply"
pin(pipwr)=1 'shutdown RPI power supply
'pwm 1,ffan,stop 'off
varSave
return
startupseq:
wlog"Startup"
led1 pled,1000
uptime=0
pin(pipwr)=0 'power supply on
uptime=0
upstime=0
standby=0
powerfail=0
OPTION.CPUFREQ 240
varSave
wifi.awake
pause 2000
onudp gudp 'UDP receive
led3 pled, 0 'power led on
'pwm 1,ffan,60 'Run fan default
wlog"Running"
return
gudp:
v$ = udp.read$
pause 100
'wlog "UDP:";v$
led1 nled,100
newline$=v$
v$=""
return
sub varRestore
if file.exists(fvar$) then
vvar$=file.read$(fvar$)
standby=val(word$(vvar$,1))
powerfail=val(word$(vvar$,2))
end if
end sub
sub varSave
FILE.SAVE fvar$, str$(standby)+cm$+str$(powerfail)
end sub
sub onStartup
wlog"On-Startup"
end sub
Error_Handler:
temp$=flogs$+"err.txt"
temp1$="Error text:"+BAS.ErrMsg$+" ,Error num="+str$(BAS.ErrNum)+" ,Error line="+str$(BAS.ErrLine)
wlog temp1$
msglog temp$,temp1$
Return ' returns to the line following the error
sub msglog(f$,msg$)
file.append f$,date$+","+time$+","+msg$+chr$(13)+chr$(10)
end sub
onStartup:
temp$=flogs$+"logs.txt"
select case BAS.RESETREASON
case 0: msglog temp$,"Unknown"
case 1: msglog temp$, "Power on reset"
case 2: msglog temp$, "Unknown"
case 3: msglog temp$, "Software reset digital core"
case 4: msglog temp$, "Legacy watch dog reset digital c"
case 5: msglog temp$, "Deep Sleep reset digital core"
case 6: msglog temp$, "Reset by SLC module, reset digital core"
case 7: msglog temp$, "Timer Group0 Watch dog reset digital core"
case 8: msglog temp$, "Timer Group1 Watch dog reset digital core"
case 9: msglog temp$, "RTC Watch dog reset digital core"
case 10: msglog temp$, "Intrusion tested to reset CPU"
case 11: msglog temp$, "Time Group reset CPU"
case 12: msglog temp$, "Software reset CPU"
case 13: msglog temp$, "RTC Watch dog reset CPU"
case 14: msglog temp$, "for APP CPU, reset by PRO CPU"
case 15: msglog temp$, "Reset when the vdd voltage is not stable"
case 16: msglog temp$, "RTC Watch dog reset digital core and rtc module"
case else
msglog temp$, "Code-"+str$(BAS.RESETREASON)
end select
return
'**************** End Core routines and functions ********
'user subs and tasks
'*** User subs and other code here ***
'End user subs and tasks
- cicciocb
- Site Admin
- Posts: 2092
- Joined: Mon Feb 03, 2020 1:15 pm
- Location: Toulouse
- Has thanked: 448 times
- Been thanked: 1384 times
- Contact:
Re: Cheap simple UPS/Battery supply for projects.
Thanks for your code, I'll try it in a near future ....