Raspberry Pi Power Switch (with mains relay)

Hi,

We have a Raspberry Pi employed as a media player, but like to isolate everything from the mains at night time. There are already plenty of devices and designs that will shut the Pi down and isolate it from the 5V power supply, but I want something that completely and utterly shuts off! We often shutdown the media player and forget to switch it off at the wall socket.

And besides, I needed a PICAXE project :)

The 'interrupt' tells the Pi to shut down and relies on someone else's Python code running on the Pi. In this case the PICAXE merely 'passes on the message' and could be deemed superfluous. Shutting down the Pi from its menu will now notify the PICAXE when one of the GPIO ports (GPIO 14, physical pin 08) drops in voltage and the PICAXE will shut off the relay. The downside to this set-up is that a dual-pole momentary action button is required to switch on the mains to the rig, at which point the relay latches on.

I haven't had much experience coding, so I would welcome any feedback, thanks!
Craig.

Code:
#picaxe 14M2                            ' specify processor

#rem

Not using interrupts because immediate action is not required.
There are also several 'if' statements and subroutines to determine the course of action.
For example, the reset sequence requires that the power is NOT switched off.

#endrem

symbol GPIO = pinC.3        ; connects to GPIO14 (phys pin #08) TXD0 to measure level
                    ; *need a weak pull-down resistor on this connection (will need testing)
symbol RLY = B.1            ; o/p to the transistor to turn off the relay via transistor
symbol OFF_BTTN = C.4        ; initiate shut-down after 0.5s press with beep to confirm
symbol PIEZO = C.2        ; sound output
symbol RST_BTTN = C.1        ; if Pi is powered-down initiate re-boot, else shut-down first
symbol RSTPi = B.5        ; needs an o/p to ground GPIO03 (phys pin #5) SCL1 to reset Pi
                    ;    B.5 requires pull-UP
symbol PiGoOff = B.3        ; o/p to ground GPIO23 (phys pin #16) GPIO_GEN4 to interrupt Pi
                    ;    B.3 requires pull-UP
symbol LED = B.2            ; Power indication - necessary?
symbol statusLED = B.4        ; indicates the status checking

; want this to run ONCE at power-on!
tune PIEZO, 4, ($60,$67,$40,$65,$6A,$45,$67,$42,$47,$10)    ;Arpeggio UP

pause 2000                ; wait for GPIO14 TXD0 to settle down

init:    b2 = 0 : b3 = 0

main:            
low led : low statusLED    : high RSTPi        ; ensure LEDs are back off after a return to main routine
            ; *** smarten up with a dirs mask?
    do while GPIO = 1         ; loop checking GPIO level + button status
        high led            ; power LED on
        button OFF_BTTN,1,255,0,b2,1,hold_off                    
                        ; i/p ?, act hi, delX, no rep, b2-var, when = 1, goto sub
        button RST_BTTN,1,255,0,b3,1,hold_rst
        if GPIO = 0 then exit    ; if GPIO is low then the loop exits
    loop                    ; end of loop
goto offPi                    ; this line executes when the loop is exited

;    ***************************************************

hold_off:                    ; delay to time press-duration
let b4 = 1                    ; reset counter variable b4 to 1
    do while b4 < 5 AND pinC.4 = 1    ; begin a loop, ensures the button is held down 
           high statusLED        ; statusLED on
           pause 250            ; wait 150 ms
           inc b4            ; increment the loop counter
           low statusLED        ; statusLED off
           pause 250            ; wait 250 ms
    loop                    ; end of loop

if pinC.4 = 0 then            ; OFF button is NOT held down
goto main                    ; jump to main and its loop
else                        ; otherwise proceed
    high statusLED            ; statusLED on
    tune PIEZO, 3,($50,$40)        ; confirmation the button was held long enough
high PiGoOff                ; *** tells the Pi to shut down..!
                        ; *** Python code in Pi states GPIO23 (phys pin #16) GPIO_GEN4
goto offPi                    ; go to the power off subroutine - necessary??
                        ;    might require a delay
    endif                    ; end the 'if' statement    

; ***************************************************

hold_rst:                    ; delay to time press-duration

let b5 = 1                    ; reset counter variable b5 to 1
    do while b5 < 10 AND pinC.1 = 1    ; begin a loop
        high statusLED        ; statusLED on
        pause 150            ; wait 150 ms
        inc b5            ; increment the loop counter
        low statusLED        ; statusLED off
        pause 150            ; wait 150 ms
    loop    ;                 ; the above code ensures the button is held down 

    if pinC.1 = 0 then        ; reset button is NOT held down
    goto main                ; cancel & jump to main and its loop
    else                    ; otherwise proceed
    tune PIEZO, 3,($50,$40)        ; confirmation the button was held long enough
    
low RSTPi                    ; o/p to ground GPIO03 (phys pin #5) SCL1 to reset Pi
    
let b6 = 1
    Do until GPIO = 0            ; hold the process here until the Pi is off
        if b6 => 20 then        ;
            goto main        ; return to the main routine if nowt happens!
        endif                ; end the 'if' statement
        high statusLED        ; statusLED on
        pause 250            ; wait 250 ms
        low statusLED        ; statusLED off
        pause 125            ; wait 125 ms
        inc b6            ; increment the variable
    loop                    ; end of the loop
        
goto resetSequence            ; jump to the reset routine
    endif                    ; end the 'if' statement

;    ******************************************************************

resetSequence:                ; the reset routine!
pause 250                    ; wait 250 ms ? necessary for debugging?
low RSTPi                    ; set RESET GPIO03 (phys pin #5) SCL1 to 0V
                        ; Python code in the Pi states GPIO23 (phys pin #16) GPIO_GEN4
let b7 = 1                    ; prime the variable
    Do until GPIO = 1            ; hold the process here until the Pi is on
        if b7 => 10 then        ; 9 counter cycles
            goto offPi        ; a safety exit in case the reset fails
        endif                ; end the 'if' statement
        high statusLED        ; statusLED on
        pause 50            ; wait 100 ms
        low statusLED        ; statusLED off
        pause 400            ; wait 350 ms
        inc b7            ; increment the counter
loop                    ; end of the loop statement
goto main                    ; return to the main routine


;     *************************************************
    
offPi:
            
let b8 = 7                    ; prime the variable - approx 7 secs delay 
    Do while GPIO = 0 AND b8 <> 0    ; loops when Pi has shutdown GPIO14 (phys pin #08)
        low led            ; power LED off
        pause 500            ; wait 500 ms
        high led            ; power LED on
        pause 500            ; wait 500 ms
        b8 = b8 - 1            ; decrement the variable value
    loop                    ; end loop 
                    
    if GPIO <> 0 then         ; check Pi power!
    goto main                ; need to double check the Pi is off!
    else
    tune PIEZO, 2,  ($50,$4B,$49,$47,$45,$44,$42,$40,$27,$A0,$40,$50)    ;scale DOWN
        'tune PIEZO, 12,(7,9,5,37,192)    'plays Close Encounters tune
     high RLY                 ; turns the relay off - THIS IS POWER OFF!!
    pause 500                ; why? it's powered off!
    endif                    ; end the 'if' statement
    end
PiPower-iv_schem.jpg
 

fernando_g

Senior Member
I don't have time to review the software, but can tell you something:
Ports In1 and In4 (Reset and Off buttons) must not be allowed to float. You must use a 10k pulldown resistor to ground.
 
Hi Fernando,

Thank-you &#8212; I have missed them off the circuit diagram! They are actually in place on my breadboard as well... D'oh! :p

Does anyone have an opinion on buttons being active high vs active low. With the latter I assume I can use internal pull-ups, but is there any trade-off with this..?

Cheers,
Craig.
 

BeanieBots

Moderator
Active low is more traditional because older gate inputs already had a 6k8 pullup resistor as part of their design. The more recent FET gates can be used either way without issue. However, many micros such as PICs have the ability to enable pullUP resistors internally thus avoiding the need to external resistors.
Internal pullups are week and should only be used for very short wire runs and/or on the same PCB.
It really does not matter with PICAXE chips which method you use but I still go for active low because I'm from an earlier generation!
 

techElder

Well-known member
I've tried to standardize on active HIGH, because my brain likes the idea of things being TRUE or "1" to gain access to them.

It isn't always possible ... the RESET on a 40X2 is an example.
 

rossko57

Senior Member
There are wiring advantages too; extending wires to e.g. remote pushbuttons using signal + earth pair is more convenient than using signal + power. Easy to screen, no short-circuit protection needed, blah.
 

techElder

Well-known member
Oh, yeah. Symbols are your lifelong friends.

Using a symbol Pressed = x means you can change that positive or negative logic at the symbol instead of having to go through all of your code to find all of the places where you placed "0" or "1".

How much spare time do you have? :)



Try using symbols.

Symbol Pressed = 0

If Button = Pressed then.....
 
There are wiring advantages too; extending wires to e.g. remote pushbuttons using signal + earth pair is more convenient than using signal + power. Easy to screen, no short-circuit protection needed, blah.
I like it — thanks!
As there are two 'reasons that I like', I can standardise all my future builds to aid fault-finding and future modifications :D

Cheers fellas,
Craig.
 
Last edited:
Top