Code Review - Gate Controller
I decide to fix Gate Controller at the end of my driveway as it hasn't worked since I moved in 2 years ago.
The cost of replacing the motherboard was $220. then I thought I have a Basic Stamp 2, buy a relay board for $20, and I can save money.
As I have not coded in PBasic in a while, I would like to post my code for review and comments.
The Relays will provide power to the Gate motor via the COM connection, and NO connection passing negative or positive voltage as required.
The Gate has Open Limit,Close limit switches to trigger stopping the gate.
A Keypad, Visor button, and manual button for inputs all work for the original install.
There is also a surge detector circuit, but I will not be wiring that in just yet.
Below is the code. Please provide comments/critiques.
Thanks,
Phil
The cost of replacing the motherboard was $220. then I thought I have a Basic Stamp 2, buy a relay board for $20, and I can save money.
As I have not coded in PBasic in a while, I would like to post my code for review and comments.
The Relays will provide power to the Gate motor via the COM connection, and NO connection passing negative or positive voltage as required.
The Gate has Open Limit,Close limit switches to trigger stopping the gate.
A Keypad, Visor button, and manual button for inputs all work for the original install.
There is also a surge detector circuit, but I will not be wiring that in just yet.
Below is the code. Please provide comments/critiques.
Thanks,
Phil
' =========================================================================
'
' File...... Gate Opener Motor Controller
' Purpose... Replacing a Bad Motor Control Board
' Author.... Phil Lutz
' Created... 2013-02-19
' Updated...
'
' {$STAMP BS2}
' {$PBASIC 2.5}
'
' =========================================================================
' -----[ Program Description ]---------------------------------------------
' 2 x Dual SPDT/NC Relays used to control Gate Opener Motor
' Relay1 - NC=GND, NO=12v, COM=Left Side of Motor
' Relay2 - NC=GND, NO=12v, COM=Right Side of Motor
' True Table
' ----------------------------
' | Relay1 | Relay2 | Motor |
' ----------------------------
' | NC | NC | Brake |
' | NC | NO | CW |
' | NO | NC | CCW |
' | NO | NO | Brake |
' ----------------------------
' Multi-Code Rcvr - Continuity means valid signal received from visor button
' KeyPad Receiver - Continuity means valid signal received from keypad
' Button Trigger - Continuity means valid signal received from button
' Close Limit - Continuity means Gate fully Closed
' Open Limit - Continuity means Gate fully Open
' Voltage Sensor#1 - Baseline voltage when gate motor running
' Voltage Sensor#2 - Surge Voltage reading if gate is blocked from moving
' (if this happens, reverse gate direction)
'
' -----[ Revision History ]------------------------------------------------
' -----[ I/O Definitions ]-------------------------------------------------
RELAY1 PIN 1 ' Motor Control
RELAY2 PIN 2 ' Motor Control
CLIMIT PIN 3 ' Close Limit
OLIMIT PIN 4 ' Open Limit
MENTRY PIN 5 ' MultiCode Receiver signal
KENTRY PIN 6 ' KeyPad Entry signal
BENTRY PIN 7 ' Button on Control Box
'SENSE1 PIN 8 ' Voltage Baseline ' not implemented yet
'SENSE2 PIN 9 ' Voltage Surge (blockage) ' not implemented yet
'LCD PIN 10 ' Signal to LCD Panel
' -----[ Constants Command Value Constants ]-------------------------------
' -----[User Constants & Variables ]-------------------------------------------------------
Status VAR Byte 'O=Opening,C=Closing,S=Stopped
' -----[ EEPROM Data ]-----------------------------------------------------
' -----[ Initialization ]--------------------------------------------------
' wait a second
PAUSE 1000
' -----[ Program Code ]----------------------------------------------------
Initialize:
Status = "S" ' Gate is stopped
' On Power Up
' if Gate is partial open, close it
IF ((CLIMIT=0) AND (OLIMIT=0)) THEN
GOSUB CloseGate
ENDIF
Init2:
' if Gate is open, leave it open
' if Gate is closed, leave it closed
IF ((CLIMIT=1) OR (OLIMIT=1)) THEN
GOSUB StopGate
ELSE
GOTO Init2
ENDIF
Main:
' Check for Entry Signals
IF ((MENTRY=1) OR (KENTRY=1) OR (BENTRY=1)) THEN
' Activate Signal received
IF (Status = "S") THEN
' if Gate closed, open it
IF (CLIMIT = 1) THEN
GOSUB OpenGate
ELSE
' if Gate open, close it
IF (OLIMIT = 1) THEN
GOSUB CloseGate
ENDIF
ENDIF
ELSE ' Gate in motion
GOSUB ReverseGate
ENDIF
ENDIF
' while gate in motion,
' check for limit switches being triggered
InMotion:
IF ((CLIMIT=1) OR (OLIMIT=1)) THEN
GOSUB StopGate
ELSE
' Need to code for blocked gate -- check for voltage surge
GOTO InMotion
ENDIF
' Return to top of Process Loop
GOTO Main
' -----[ Subroutines ]-----------------------------------------------------
CloseGate:
LOW RELAY1
HIGH RELAY2
Status = "C"
DO WHILE ((CLIMIT=1) OR (OLIMIT=1)) ' Allow Limit switches to clear
LOOP
RETURN
OpenGate:
HIGH RELAY1
LOW RELAY2
Status = "O"
DO WHILE ((CLIMIT=1) OR (OLIMIT=1)) ' Allow Limit switches to clear
LOOP
RETURN
ReverseGate:
TOGGLE RELAY1
TOGGLE RELAY2
IF Status = "C" THEN
Status = "O"
ELSE
Status = "C"
ENDIF
RETURN
StopGate:
LOW RELAY1
LOW RELAY2
Status = "S"
RETURN
Comments
I think it's a pretty neat idea to use a BS2 to replace your gate controller. Now you have the ability to control it just the way you want.
I looked over your program, and I'll say it is well documented and logical. That really helps when you go back in 2 years and wonder why you did this.
One thing you should consider is the failure mode of any component in a mechanical system controlled by a processor. For example, what would happen if one of the limit switches failed? The motor might keep going until it burns out, if it is not thermally protected or somehow cutoff.
There are at least two areas in your program where this is an issue:
DO WHILE ((CLIMIT=1) OR (OLIMIT=1)) ' Allow Limit switches to clear LOOP
The DO WHILE loop will never exit if either limit switch is stuck on. You do this in both CloseGate and OpenGate, but have no way out of the routine if the limit switch doesn't clear and the motor is running...
I also think you only need to check one of the two limit switches in each routine, not both. That eliminates half of the problem. The other half I would suggest you use a suitable PAUSE to let the limit switch clear, and if it doesn't do so in that time, then jump into the StopGate routine. Maybe have an indicator light turn on when this happens so that you know why your gate isn't moving.
Good luck with your project.
Thank you for your post. I will recode those sections to look at failure points.
The wiring from the Motor has electronics for "Surge" testing, so once this is wired in, should resolve a limit switch failure.
There is also a mechanical limit imposed on the Gate at both ends of travel (post in the ground at full open, and a half latch at full close)
The motor should operate at a specific current, when the gate is blocked by an object or reaches limit, the current raises significantly.
With "Surge test code", if the limit failed, the Gate would reverse. A clear indication something is wrong.
Good things to think about.
Thanks again.
Phil