Does this microcontroller code make any sense to you?

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

Reply to
Ignoramus27153
Loading thread data ...

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

Reply to
Ian Bell

On Thu, 01 Jun 2006 19:30:03 +0100, Ian Bell wrote:

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

Reply to
Ignoramus27153

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

Reply to
Ignoramus27153

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.