Does this microcontroller code make any sense to you?

I

Ignoramus27153

Jan 1, 1970
0
It is my implementation of a welding controller. Right now it only
knows Stick and TIG welding, but later it would know a few more
processes. See PROCESS_* enumeration.

It uses a lot of functions that access low level relays, etc, that I
am not showing here (and have not yet written, even).

Let me know if you think that it is a sensible organization of code. This code is untested.

Note that ANY error condition fully latches the system, powers it off, rendering it
inoperable until reboot.

Initialize function has safety checks, such as, if START switch is on
during startup, an error condition is reported and latched. Also, if
at boot it detects serial cable connected, it would also latch with
error (to save my laptop).

Const Device = CB280
Ramclear

' ====================================================================== Constants

' ======================================== Parameters
Const Integer delayInLoop = 30 ' milliseconds to sleep after every pass of the main loop
Const Integer preflowTime = 10 ' seconds
Const Integer postflowTime = 15 ' seconds, to be changed later to dynamic postflow based on current
Const Integer PowerLimit = 12000 ' Power limit in Watts, stop if reached rather than trip breakers
Const Integer TigHFMinVoltage = 40 ' voltage to turn on HF
Const Integer TigHFVoltageInterval = 5 ' interval to avoid switching HF too much like idiots

' ============================================================ Process Type
Const Byte PROCESS_UNKNOWN = 1 ' Error condition, shut everything down
Const Byte PROCESS_STICK_WELDING = 2 ' Stick welding -- low voltage CC
Const Byte PROCESS_TIG_WELDING = 3 ' TIG welding -- low voltage CC, gas, water, HF
Const Byte PROCESS_MIG_WELDING = 4 ' MIG welding -- low voltage CV
Const Byte PROCESS_PLASMA_CUTTING = 5 ' HV plasma cutting, HF, air
Const Byte PROCESS_LOW_VOLTAGE = 6 ' Arbitrary LOW voltage power supply (using pots) - 0-80VDC, 0-200A
Const Byte PROCESS_HIGH_VOLTAGE = 7 ' Arbitrary HIGH voltage power supply (using pots) - 0-300VDC, 0-100A


' ============================================================ Process States
Const byte STATE_BOOT = 0
' STICK is simply a CC power supply with 80V OCV
Const Byte STATE_STICK_IDLE = 1
Const Byte STATE_STICK_WELDING = 2 ' welding

' TIG is preflow, weld, postflow. Also remember that WATER relay may be closed
' after TIG is done, for a specified period of time depending on how much we welded,
' to cool water.
Const Byte STATE_TIG_IDLE = 10 ' No OCV
Const Byte STATE_TIG_PREFLOW = 11 ' Open gas solenoid and water
Const Byte STATE_TIG_WELD = 12 ' Gas, water, maybe HF
Const Byte STATE_TIG_POSTFLOW = 13 ' Gas, water

' ====================================================================== Variables
Dim currentProcess As Byte
currentProcess = GetProcessSelection

Dim iteration As Long ' iteration used mostly for emulating changes in conditions
iteration = 0

Dim highVoltage As byte
highVoltage = 0

Dim errorMessage As String( 15 )
errorMessage = "OK"

Dim currentState As byte
currentState = STATE_BOOT

Dim startIteration As Long
startIteration = -1

Dim postflowStartIteration As Long
postflowStartIteration = -1

' ====================================================================== Process Logic (main loop)
Initialize ' Does safety checks too

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' RULES:
' * Avoid directly mentioning any relays or inputs
' * Only call subroutines and deal with named constants/variables/functions
' * Any unhandled condition should lead to error message and PROCESS_UNKNOWN.
' Only a reboot can bring us out of PROCESS_UNKNOWN.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Do
' Main loop

Dim requested_process As byte
requested_process = GetProcessSelection '' get current reading of process selector

If currentProcess = PROCESS_UNKNOWN Then

DisplayStatus

Else If currentProcess = PROCESS_STICK_WELDING Then

If currentState = STATE_BOOT Then
currentState = STATE_STICK_IDLE
End If

' handle change of process
If requested_process != PROCESS_STICK_WELDING Then
If currentState = STATE_STICK_IDLE Then
' it is OK to switch to another process when IDLE
ChangeProcess( requested_process )
Else
' it is NOT OK to switch to another process when welding
OnErrorCondition( "HOT switching" )
End if
Else If currentState = STATE_STICK_IDLE Then ' now actual STICK logic
If GetStartSwitch = 1 Then
currentState = STATE_STICK_WELD
startIteration = iteration
StartSupplyingPower
End if
Else If currentState = STATE_STICK_WELD Then
If GetStartSwitch = 0 Then
currentState = STATE_STICK_IDLE
StopSupplyingPower
Else If GetPower > PowerLimit Then ' power limit exceeded, stop welding
currentState = STATE_STICK_IDLE
StopSupplyingPower
End If

Else
OnErrorCondition( "Unknown STICK STATE" )
End If

DisplayStatus

Else If currentProcess = PROCESS_TIG_WELDING Then

If currentState = STATE_BOOT Then
currentState = STATE_TIG_IDLE
End If

' handle change of process
If requested_process != PROCESS_TIG_WELDING Then
If currentState = STATE_TIG_IDLE Then
' it is OK to switch to another process when IDLE
ChangeProcess( requested_process )
Else
' it is NOT OK to switch to another process when welding
OnErrorCondition( "HOT switching" )
End if

Else If currentState = STATE_TIG_IDLE Then ' now actual TIG logic
If GetStartSwitch = 1 Then
currentState = STATE_TIG_PREFLOW
startIteration = iteration
OpenGasValve
OpenWaterValve
End if
Else If currentState = STATE_TIG_PREFLOW Then
If ElapsedTime( startIteration ) > preflowTime Then
currentState = STATE_TIG_WELD
StartSupplyingPower
End If
Else If currentState = STATE_TIG_WELD Then
If GetStartSwitch = 0 Then
currentState = STATE_TIG_POSTFLOW
StopSupplyingPower
postflowStartIteration = iteration
Else If GetPower > PowerLimit Then ' power limit exceeded, stop welding
currentState = STATE_TIG_POSTFLOW
StopSupplyingPower
postflowStartIteration = iteration
Else If GetBusVoltage > TigHFMinVoltage Then
TurnOnHF
Else If GetBusVoltage < TigHFMinVoltage-TigHFVoltageInterval Then
TurnOffHF
End if
Else If currentState = STATE_TIG_POSTFLOW Then
If postflowStartIteration == -1 Then
OnErrorCondition( "postflow start missing" );
Else If ElapsedTime( postflowStartIteration ) > postflowTime Then
CloseGasValve
CloseWaterValve
currentState = STATE_TIG_IDLE
End if
Else
OnErrorCondition( "Unknown TIG STATE" )
End If

DisplayStatus
Else
' unhandled case, BAD BAD BAD
OnErrorCondition( "Bad Process Selection" )
End If

DisplayStatus
Delay delayInLoop
iteration = iteration + 1
Loop
 
I

Ian Bell

Jan 1, 1970
0
Ignoramus27153 said:
It is my implementation of a welding controller. Right now it only
knows Stick and TIG welding, but later it would know a few more
processes. See PROCESS_* enumeration.

It uses a lot of functions that access low level relays, etc, that I
am not showing here (and have not yet written, even).

Let me know if you think that it is a sensible organization of code. This
code is untested.

snip

Your huge repeated If Then Else construct is clumsy, hard to read, prone to
errors and poor programming practice. A case statement would be an
improvement.

Ian
 
I

Ignoramus27153

Jan 1, 1970
0
snip

Your huge repeated If Then Else construct is clumsy, hard to read, prone to
errors and poor programming practice. A case statement would be an
improvement.

OK, I have changed the top level if...else construct with Case
statement. The lower level ifs cannot be replaced with case, they have
various logical expressions in them.

Here's the new code:

Const Device = CB280
Ramclear

' ====================================================================== Constants

' ======================================== Parameters
Const Integer delayInLoop = 30 ' milliseconds to sleep after every pass of the main loop
Const Integer preflowTime = 10 ' seconds
Const Integer postflowTime = 15 ' seconds, to be changed later to dynamic postflow based on current
Const Integer PowerLimit = 12000 ' Power limit in Watts, stop if reached rather than trip breakers
Const Integer TigHFMinVoltage = 40 ' voltage to turn on HF
Const Integer TigHFVoltageInterval = 5 ' interval to avoid switching HF too much like idiots

' ============================================================ Process Type
Const Byte PROCESS_UNKNOWN = 1 ' Error condition, shut everything down
Const Byte PROCESS_STICK_WELDING = 2 ' Stick welding -- low voltage CC
Const Byte PROCESS_TIG_WELDING = 3 ' TIG welding -- low voltage CC, gas, water, HF
Const Byte PROCESS_MIG_WELDING = 4 ' MIG welding -- low voltage CV
Const Byte PROCESS_PLASMA_CUTTING = 5 ' High Voltage plasma cutting, HF, air
Const Byte PROCESS_LOW_VOLTAGE = 6 ' Arbitrary LOW voltage power supply (using pots) - 0-80VDC, 0-200A
Const Byte PROCESS_HIGH_VOLTAGE = 7 ' Arbitrary HIGH voltage power supply (using pots) - 0-300VDC, 0-100A


' ============================================================ Process States
Const byte STATE_BOOT = 0
' STICK is simply a CC power supply with 80V OCV
Const Byte STATE_STICK_IDLE = 1
Const Byte STATE_STICK_WELDING = 2 ' welding

' TIG is preflow, weld, postflow. Also remember that WATER relay may be closed
' after TIG is done, for a specified period of time depending on how much we welded,
' to cool water.
Const Byte STATE_TIG_IDLE = 10 ' No OCV
Const Byte STATE_TIG_PREFLOW = 11 ' Open gas solenoid and water
Const Byte STATE_TIG_WELD = 12 ' Gas, water, maybe HF
Const Byte STATE_TIG_POSTFLOW = 13 ' Gas, water

' ====================================================================== Variables
Dim currentProcess As Byte
currentProcess = GetProcessSelection

Dim iteration As Long ' iteration used mostly for emulating changes in conditions
iteration = 0

Dim highVoltage As byte
highVoltage = 0

Dim errorMessage As String( 15 )
errorMessage = "OK"

Dim currentState As byte
currentState = STATE_BOOT

Dim startIteration As Long
startIteration = -1

Dim postflowStartIteration As Long
postflowStartIteration = -1

' ====================================================================== Process Logic (main loop)
Initialize ' Does safety checks too

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' RULES:
' * Avoid directly mentioning any relays or inputs
' * Only call subroutines and deal with named constants/variables/functions
' * Any unhandled condition should lead to error message and PROCESS_UNKNOWN.
' Only a reboot can bring us out of PROCESS_UNKNOWN.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Do ' Main loop

Dim requested_process As byte
requested_process = GetProcessSelection '' get current reading of process selector

Select Case currentProcess
Case PROCESS_UNKNOWN

DisplayStatus

Case PROCESS_STICK_WELDING

If currentState = STATE_BOOT Then
currentState = STATE_STICK_IDLE
End If

' handle change of process
If requested_process != PROCESS_STICK_WELDING Then
If currentState = STATE_STICK_IDLE Then
' it is OK to switch to another process when IDLE
ChangeProcess( requested_process )
Else
' it is NOT OK to switch to another process when welding
OnErrorCondition( "HOT switching" )
End if
Else If currentState = STATE_STICK_IDLE Then ' now actual STICK logic
If GetStartSwitch = 1 Then
currentState = STATE_STICK_WELD
startIteration = iteration
StartSupplyingPower
End if
Else If currentState = STATE_STICK_WELD Then
If GetStartSwitch = 0 Then
currentState = STATE_STICK_IDLE
StopSupplyingPower
Else If GetPower > PowerLimit Then ' power limit exceeded, stop welding
MomentarilySuppressPower
End If

Else
OnErrorCondition( "Unknown STICK STATE" )
End If

DisplayStatus

Case PROCESS_TIG_WELDING

If currentState = STATE_BOOT Then
currentState = STATE_TIG_IDLE
End If

' handle change of process
If requested_process != PROCESS_TIG_WELDING Then
If currentState = STATE_TIG_IDLE Then
' it is OK to switch to another process when IDLE
ChangeProcess( requested_process )
Else
' it is NOT OK to switch to another process when welding
OnErrorCondition( "HOT switching" )
End if

Else If currentState = STATE_TIG_IDLE Then ' now actual TIG logic
If GetStartSwitch = 1 Then
currentState = STATE_TIG_PREFLOW
startIteration = iteration
OpenGasValve
OpenWaterValve
End if
Else If currentState = STATE_TIG_PREFLOW Then
If ElapsedTime( startIteration ) > preflowTime Then
currentState = STATE_TIG_WELD
StartSupplyingPower
End If
Else If currentState = STATE_TIG_WELD Then
If GetStartSwitch = 0 Then
currentState = STATE_TIG_POSTFLOW
StopSupplyingPower
postflowStartIteration = iteration
Else If GetPower > PowerLimit Then ' power limit exceeded, stop welding
MomentarilySuppressPower
Else If GetBusVoltage > TigHFMinVoltage Then
TurnOnHF
Else If GetBusVoltage < TigHFMinVoltage-TigHFVoltageInterval Then
TurnOffHF
End if
Else If currentState = STATE_TIG_POSTFLOW Then
If postflowStartIteration == -1 Then
OnErrorCondition( "postflow start missing" )
Else If ElapsedTime( postflowStartIteration ) > postflowTime Then
CloseGasValve
CloseWaterValve
currentState = STATE_TIG_IDLE
End if
Else
OnErrorCondition( "Unknown TIG STATE" )
End If

DisplayStatus
Case Else
' unhandled case, BAD BAD BAD
OnErrorCondition( "Bad Process Selection" )
End Select

DisplayStatus
Delay delayInLoop
iteration = iteration + 1
Loop

'====================================================================== Functions

Sub Initialize ' initializes everything, all relays etc

If GetStartSwitch Then
OnErrorCondition( "START at boot" )
End If

If SerialCableIsConnected Then
OnErrorCondition( "Serial Connected" )
End if
End Sub
 
I

Ignoramus27153

Jan 1, 1970
0
Code below sorta runs and changes states and prints on LCD screen nicely.

I am right now working on special faking code that would fake inputs
(since I am programming in the upstairs bedroom and cannot yet plug
this uC into the welder)

The faking code will alter functions like GetStartSwitch(), so that
they fake key being on based on time and faking mode.

===========================================================================
Dim postflowStartIteration As Long
postflowStartIteration = -1

Dim lastMsg As String
lastMsg = "OK"
Dim previousLastMsg As String
previousLastMsg = ""

Dim previousTime As Long
previousTime = -1

' ====================================================================== Process Logic (main loop)
'
'

Initialize ' Does safety checks too

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' RULES:
' * Avoid directly mentioning any relays or inputs
' * Only call subroutines and deal with named constants/variables/functions
' * Any unhandled condition should lead to error message and PROCESS_UNKNOWN.
' Only a reboot can bring us out of PROCESS_UNKNOWN.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Do ' Main loop

Dim requested_process As Byte
requested_process = GetProcessSelection() '' get current reading of process selector

Select Case currentProcess

Case PROCESS_UNKNOWN ' ----------------------------------------

DisplayStatus

Case PROCESS_STICK_WELDING ' ----------------------------------------

If currentState = STATE_BOOT Then
currentState = STATE_STICK_IDLE
End If

' handle change of process
If requested_process <> PROCESS_STICK_WELDING Then
If currentState = STATE_STICK_IDLE Then
' it is OK to switch to another process when IDLE
ChangeProcess requested_process
Else
' it is NOT OK to switch to another process when welding
lastMsg = "HOT switching"
OnErrorCondition
End If
Elseif currentState = STATE_STICK_IDLE Then ' now actual STICK logic
If GetStartSwitch() = 1 Then
currentState = STATE_STICK_WELDING
startIteration = iteration
StartSupplyingPower
End If
Elseif currentState = STATE_STICK_WELDING Then
If GetStartSwitch() = 0 Then
currentState = STATE_STICK_IDLE
StopSupplyingPower
Elseif GetPower() > PowerLimit Then ' power limit exceeded, stop welding
MomentarilySuppressPower
End If

Else
lastMsg = "Unknown STICK STATE"
OnErrorCondition
End If

DisplayStatus

Case PROCESS_TIG_WELDING ' ----------------------------------------

If currentState = STATE_BOOT Then
currentState = STATE_TIG_IDLE
End If

' handle change of process
If requested_process <> PROCESS_TIG_WELDING Then
If currentState = STATE_TIG_IDLE Then
' it is OK to switch to another process when IDLE
ChangeProcess requested_process
Else
' it is NOT OK to switch to another process when welding
lastMsg = "HOT switching"
OnErrorCondition
End If

Elseif currentState = STATE_TIG_IDLE Then ' now actual TIG logic
If GetStartSwitch() = 1 Then
currentState = STATE_TIG_PREFLOW
startIteration = iteration
OpenGasValve
OpenWaterValve
End If
Elseif currentState = STATE_TIG_PREFLOW Then
If ElapsedTime( startIteration ) > preflowTime Then
currentState = STATE_TIG_WELD
StartSupplyingPower
End If
Elseif currentState = STATE_TIG_WELD Then
If GetStartSwitch() = 0 Then
currentState = STATE_TIG_POSTFLOW
StopSupplyingPower
postflowStartIteration = iteration
ElseIf GetPower() > PowerLimit Then ' power limit exceeded, stop welding
MomentarilySuppressPower
Elseif GetBusVoltage() > TigHFMinVoltage Then
TurnOnHF
Elseif GetBusVoltage() < TigHFMinVoltage-TigHFVoltageInterval Then
TurnOffHF
End If
Elseif currentState = STATE_TIG_POSTFLOW Then
If postflowStartIteration = -1 Then
lastMsg = "postflow start missing"
OnErrorCondition
Elseif ElapsedTime( postflowStartIteration ) > postflowTime Then
CloseGasValve
CloseWaterValve
currentState = STATE_TIG_IDLE
End If
Else
lastMsg = "Unknown TIG STATE"
OnErrorCondition
End If

DisplayStatus
Case Else ' ------------------------------------------------------------
' unhandled case, BAD BAD BAD
lastMsg = "Bad Process Selection"
OnErrorCondition
End Select

DisplayStatus
Delay delayInLoop
If SystemTime() > timeLimit Then
lastMsg = "TimeLimit"
currentState = STATE_EXPIRED
OnErrorCondition
Else
iteration = iteration + 1
End If
Loop

End
'====================================================================== Functions

Sub Initialize() ' initializes everything, all relays etc

Set Display 2,0,0,50
If GetStartSwitch() Then
lastMsg = "START at boot"
OnErrorCondition
Return
End If

If SerialCableIsConnected() Then
lastMsg = "Serial Connected"
OnErrorCondition
End If


End Sub
 
Top