Build1=Default,B4RDev
Group=Default Group
Library1=rcore
Library2=rrandomaccessfile
Library3=rliquidcrystal_i2c
Library4=rkeypad
NumberOfFiles=0
NumberOfLibraries=4
NumberOfModules=0
Version=2.51
@EndOfDesignText@
#Region Project Attributes
#AutoFlushLogs: True
#CheckArrayBounds: True
#StackBufferSize: 600
#End Region
'Comments
#Region
'Connections 24 x 4 LCD to Uno
'SCL to A5 Mega-IO 43 (Top right by LAN)
'SDA to A4 Mega-IO 44
'GND to GND
'VCC to 5V Either from Uno or external
'Stepper motor with DVR8825 driver board
'On driver board
'Enable no connection (driver enabled), can also be controlled by a Mega Pin
'M0 to M2 no connection (full step mode)
'Reset connect to 5V
'Sleep connect to 5V
'Step Mega Pin 7
'Dir Mega Pin 6
'Vmot 9V supply
'B2 to A1 Motor coils
'Fault no connection
'GND Mega GND
' **** Dont forget to set the maximum current! ***
#End Region
Sub Process_Globals
Dim Serial1 As Serial
Dim bc As ByteConverter
Dim HoldTimer As Timer 'Will be used to measure hold time later
' Dim MoveTimer As Timer 'Used for down and up movement
Dim CoilTimer As Timer 'Speed of the motor
'Variables for Keypad
Dim pad As Keypad
Dim KeyBuffer(6) As Byte
Dim vKey As Int=0
'Variables for Menu
Dim SpeedDown As Long=0
Dim HoldTime As Long=0
Dim Speedup As Long=0
Dim CommandActive As UInt=0
'Variable for 20 x 4 LCD Display
Dim lcd As LiquidCrystal_I2C
Dim MenuMode As Int=0 'Determines which screen will be displayed
Dim FirstTime As Boolean=True 'Used to change menu mode
'Variables for the motor control
Dim StepsPin As Pin
Dim DirPin As Pin
Dim Steps As Boolean=False
Dim Direction As Boolean=True 'True moves down, false moves up
Dim Park As Boolean=True 'Position Up=True
Dim SetSwitchMode As Boolean=False
'Variables for pin detection
Dim LowerEndSwitchL, LowerEndSwitchR As Pin 'End switches at bottom of dipper
Dim UpperEndSwitch As Pin
Dim t As Long 'used for timing calculation
End Sub
Private Sub AppStart
Serial1.Initialize(115200)
Log("AppStart")
pad.Initialize("123A456B789C*0#D", Array As Byte(39, 41, 43, 45), Array As Byte(47, 49, 51,53), _
"pad_KeyPressed")
HoldTimer.Initialize("HoldTimer_Tick",1000) 'set to run for 1 second, will be overwritten with HoldTime
' MoveTimer.Initialize("MoveTimer_Tick",1000) 'will be overwritten later
CoilTimer.Initialize("CoilTimer_Tick",100)
'Prepare LCD
lcd.Initialize(0x27, 20, 4)
lcd.Backlight = True
'Prepare motor pins Mega 7,6
StepsPin.Initialize(7,StepsPin.MODE_OUTPUT)
DirPin.Initialize(6,DirPin.MODE_OUTPUT)
StepsPin.DigitalWrite(False) 'set no step
DirPin.DigitalWrite(True) 'set direction to down
'Prepare switches
LowerEndSwitchL.Initialize(LowerEndSwitchL.A0, LowerEndSwitchL.MODE_INPUT_PULLUP) 'Using the internal pull up resistor to prevent the pin from floating.
LowerEndSwitchL.AddListener("LowerEndSwitchL_StateChanged")
LowerEndSwitchR.Initialize(LowerEndSwitchR.A1, LowerEndSwitchR.MODE_INPUT_PULLUP) 'Using the internal pull up resistor to prevent the pin from floating.
LowerEndSwitchR.AddListener("LowerEndSwitchR_StateChanged")
UpperEndSwitch.Initialize(UpperEndSwitch.A2, UpperEndSwitch.MODE_INPUT_PULLUP) 'Using the internal pull up resistor to prevent the pin from floating.
UpperEndSwitch.AddListener("UpperEndSwitch_StateChanged")
ShowMainScreen
End Sub
'state will be False when the switch is on because of the PULLUP mode.
Sub LowerEndSwitchL_StateChanged (State As Boolean)
'This is the movable end switch on the left used to stop down movement
Log("Lower End switch left triggered: ", State)
Log("SetSwitchMode ", SetSwitchMode)
Log("Direction ", Direction)
If State=False And SetSwitchMode=False Then 'move down during run has triggered end switch
MoveTimer_Tick
End If
If SetSwitchMode=True And Direction=False Then 'Cannot move down as we are on the switch
CoilTimer.Enabled=False
End If
End Sub
'state will be False when the switch is on because of the PULLUP mode. Failsafe for broken left switch.
Sub LowerEndSwitchR_StateChanged (State As Boolean)
'If this switch is triggered, then the left hand switch is too low or has failed. Park the arm.
Log("Lower End switch right triggered: ", State)
FirstTime=True
MenuMode=0
HoldTimer.Enabled=False
CoilTimer.Enabled=False
'Park the motor
SetSwitchMode=True 'trick the system to use the state changed sub
Direction=False 'move up
DirPin.DigitalWrite(Direction)
CoilTimer.Interval=15 'slowly!
lcd.Clear
lcd.SetCursor(0,0)
lcd.Write("Limit switch error!")
lcd.SetCursor(0,2)
lcd.Write("Parking arm ...")
CoilTimer.Enabled=True
End Sub
'state will be False when the switch is on because of the PULLUP mode.
Sub UpperEndSwitch_StateChanged (State As Boolean)
Log("Upper End switch triggered: ", State)
Log("SetSwitchMode: ", SetSwitchMode)
Log("FirstTime: ", FirstTime)
Log(" ")
If State=False And SetSwitchMode=False And FirstTime=False Then
'We are parked, turn off all timers
CoilTimer.Enabled=False 'Stop the motor
' MoveTimer.Enabled=False
Park=True
'Reset all values
SpeedDown=0
HoldTime=0
Speedup=0
FirstTime=True
MenuMode=0
Log("Test finished")
ShowMainScreen
End If
If State=False And SetSwitchMode=True Then 'finished setting end switches
CoilTimer.Enabled=False
Park=True
SetSwitchMode=False
FirstTime=True
MenuMode=0
ShowMainScreen
End If
End Sub
'Used to switch the coils on the motor
Sub CoilTimer_Tick
' If Direction=True Then
' Log("Movement down")
' Else
' Log("Movement up")
' End If
StepsPin.DigitalWrite(Steps)
Steps=Not(Steps)
End Sub
'Used for the down and up movement
Sub MoveTimer_Tick
'Tick is called when the movement should stop
CoilTimer.Enabled=False 'Stop the motor
' MoveTimer.Enabled=False 'Stop timer
If Direction=True Then 'Down movement is finished
Log("Down finished.")
Log("Waiting ", HoldTime, " seconds")
HoldTimer.Enabled=True 'Wait, tick event means time is up.
End If
End Sub
'Hold time is up, move to park position
Sub HoldTimer_Tick
Log("Done waiting")
Log("Moving up")
HoldTimer.Enabled=False 'Finished waiting
t=Power((Speedup/18.107),-10/9.572) 'based on Excel formula
CoilTimer.Interval=t
Log("CoilTimer interval for up: ",t)
t=(Power(CoilTimer.Interval,-0.9572))*18.107
Log("Up speed mm/s: ", t)
Direction=False
DirPin.DigitalWrite(Direction) 'Change direction
' MoveTimer.Enabled=False 'Tick stops the motor
FirstTime=False
CoilTimer.Enabled=True 'Coil switching enabled
End Sub
'Show run screen and run the program
Sub ShowRunScreen (Key As String)
If FirstTime=True And Park=True Then 'Can only run if we are parked!
If SpeedDown=0 Or Speedup=0 Or HoldTime=0 Then Return
lcd.Clear
lcd.SetCursor(0,0)
lcd.Write(" [A] Running ...")
lcd.SetCursor(0,2)
lcd.Write(" [D] Abort")
' FirstTime=False
HoldTimer.Interval=HoldTime*1000 'Time is in seconds
Direction=True 'Move down
DirPin.DigitalWrite(Direction)
' MoveTimer.Interval=Power((SpeedDown/18.107),-10/9.572)
Log(" ")
Log("Test started")
Log("Speed down mm/s - ", SpeedDown)
Log("Holdtime secs - ", HoldTime)
Log("Speed up mm/s - ", Speedup)
t=Power((SpeedDown/18.107),-10/9.572)
CoilTimer.Interval=t
Log("CoilTimer interval for down: ",CoilTimer.Interval)
t=(Power(CoilTimer.Interval,-0.9572))*18.107
Log("Down speed mm/s: ", t)
Park=False
Log("Moving down...")
' MoveTimer.Enabled=False 'Start timer, the tick stops the movement
CoilTimer.Enabled=True 'Start motor movement
End If
If Key = "D" Then
'Abort and reset
Log("Abort pressed")
FirstTime=True
MenuMode=0
SpeedDown=0
HoldTime=0
Speedup=0
HoldTimer.Enabled=False
CoilTimer.Enabled=False
' MoveTimer.Enabled=False
lcd.Clear
lcd.SetCursor(0,0)
lcd.Write(" Abort ...Parking")
'Park the motor
SetSwitchMode=True 'trick the system to use the state changed sub
Direction=False
DirPin.DigitalWrite(Direction)
CoilTimer.Interval=15
CoilTimer.Enabled=True
End If
End Sub
'React to keys pressed on Keypad.
Sub Pad_KeyPressed (Key As String)
'On first keypress, first time is set, the screen changes to next page
'further keypresses are routed to the subs defined by menumode
If Key = "A" And FirstTime=True Then
MenuMode=1
Else if Key = "B" And FirstTime=True Then
MenuMode=2
Else if Key = "C" And FirstTime=True Then
MenuMode=3
End If
Select Case MenuMode
Case 1
'Settings mode
ChangeSettings(Key) 'Pass key to sub
Case 2
'Set switch mode
ShowSetSwitchScreen(Key)
Case 3
'Run mode
ShowRunScreen(Key)
End Select
End Sub
'Show main screen menu
Sub ShowMainScreen
lcd.Clear
lcd.SetCursor(6,0)
lcd.Write("Main Menu")
lcd.SetCursor(0,1)
lcd.Write(" [A] Settings")
lcd.SetCursor(0,2)
lcd.Write(" [B] Set Switch")
lcd.SetCursor(0,3)
lcd.Write(" [C] Run")
SetSwitchMode=False
End Sub
'Change main settings
Sub ChangeSettings (Key As String)
If FirstTime=True Then 'Do nothing
FirstTime=False
ShowSettings 'Show new menu
Return
End If
If Key = "*" Then 'reset all settings
If CommandActive>0 Then Return
SpeedDown=0
HoldTime=0
Speedup=0
ShowSettings
Else if Key = "A" Then
'Speed down
If CommandActive>0 Then Return ' a different command key is active
CommandActive=1
lcd.Clear
lcd.SetCursor(0,0)
lcd.Write("Speed Down (1-9)")
lcd.SetCursor(0,1)
lcd.Write("<# to exit>")
vKey=0
Else if Key = "B" Then
'Hold time
If CommandActive>0 Then Return
CommandActive=2
lcd.Clear
lcd.SetCursor(0,0)
lcd.Write("Hold Time (secs)")
lcd.SetCursor(0,1)
lcd.Write("<# to exit>")
vKey=0
Else if Key = "C" Then
'Speed up
If CommandActive>0 Then Return
CommandActive=3
lcd.Clear
lcd.SetCursor(0,0)
lcd.Write("Speed Up (1-9)")
lcd.SetCursor(0,1)
lcd.Write("<# to exit>")
vKey=0
Else if Key = "D" Then
'Done
FirstTime=True
ShowMainScreen
MenuMode=0
Return
else if Key = "#" Then
'Enter pressed, get and store the new settings
Select Case CommandActive
Case 1
SpeedDown=bc.StringFromBytes(KeyBuffer)
If SpeedDown<1 Then SpeedDown=1
If SpeedDown>9 Then SpeedDown=9
CommandActive=0
ShowSettings
ClearKeyBuffer
Case 2
HoldTime=bc.StringFromBytes(KeyBuffer)
If HoldTime=0 Then HoldTime=1 'Cannot wait 0 secs
CommandActive=0
ShowSettings
ClearKeyBuffer
Case 3
Speedup=bc.StringFromBytes(KeyBuffer)
If Speedup<1 Then Speedup=1
If Speedup>9 Then Speedup=9
CommandActive=0
ShowSettings
ClearKeyBuffer
End Select
else if vKey<6 Then
'put the key in the buffer if a command is active. Up to 6 digits can be entered (999999)
If CommandActive>0 Then
lcd.SetCursor(vKey,2)
KeyBuffer(vKey)= Asc(Key)
lcd.Write(Key)
vKey=vKey+1
End If
End If
End Sub
'Show set end switch screen
Sub ShowSetSwitchScreen (Key As String)
If FirstTime=True Then 'Show menu and reset firsttime
FirstTime=False
lcd.Clear
lcd.SetCursor(3,0)
lcd.Write("Set end switch")
lcd.SetCursor(0,1)
lcd.Write("[A] Down [B] Up")
lcd.SetCursor(0,2)
lcd.Write("[C] Stop")
lcd.SetCursor(0,3)
lcd.Write("[D] Done & Park")
Return
End If
SetSwitchMode=True
CoilTimer.Interval=15 'set fast motor speed old=50,25,10
If Key="A" Then 'move down
Log("move down")
Direction=True
DirPin.DigitalWrite(Direction)
CoilTimer.Enabled=True
End If
If Key="B" Or Key = "D" Then 'move up
Log("Move up")
Direction=False
DirPin.DigitalWrite(Direction)
CoilTimer.Enabled=True
End If
If Key="C" Then 'stop
Log("Stopped")
CoilTimer.Enabled=False
End If
End Sub
'Show settings on LCD Display
Sub ShowSettings
lcd.Clear
lcd.SetCursor(0,0)
Public txt As String
txt=JoinStrings(Array As String("(A) Down: ",SpeedDown," mm/s"))
lcd.Write(txt)
lcd.SetCursor(0,1)
txt=JoinStrings(Array As String("(B) Hold: ",HoldTime," secs"))
lcd.Write(txt)
lcd.SetCursor(0,2)
txt=JoinStrings(Array As String("(C) Up: ",Speedup," mm/s"))
lcd.Write(txt)
lcd.SetCursor(0,3)
lcd.Write("(D) Done")
lcd.SetCursor(10,3)
lcd.Write("(*) Reset")
End Sub
'Clear the Key Buffer array
Sub ClearKeyBuffer
'Log("KeyBuffer before clear: ", KeyBuffer)
For i=0 To KeyBuffer.Length-1
KeyBuffer(i)=Asc(" ")
Next
'Log("KeyBuffer after clear: ", KeyBuffer)
End Sub