After using the solution from Klaus here, to create a list of animations and then call them, the tick event of my timer is not called any more. I am sure I have missed something fundemental but I cannot see it.
It was working when I called the subs on their own but not with callsub. What have I missed?
It was working when I called the subs on their own but not with callsub. What have I missed?
B4X:
'Non-UI application (console / server application)
#Region Project Attributes
#CommandLineArgs:
#MergeLibraries: True
#End Region
Sub Process_Globals
Private controller As GpioController
Private dataPin As GpioPinDigitalOutput 'serial data input
Private latchPin As GpioPinDigitalOutput 'memory clock input STCP (latch) copies inputs to outputs when toggled
Private clockPin As GpioPinDigitalOutput 'shift register clock input SHCP
Dim Value As Byte
Dim pause As Int
Private aTimer As Timer
Dim l(3) As GpioPinDigitalOutput
Dim lState(3) As Boolean
Dim b(2) As Byte
Dim BitOrder As Boolean=True
'Define an animation state type
Type State (Byte1 As Byte, Byte2 As Byte, LayerBottom As Boolean, LayerMiddle As Boolean, LayerTop As Boolean)
Dim states As List
Dim st As State
Dim aa, bb, cc As Int
Dim Clockwise As Boolean=True
Dim Alist As List 'List of animations
Dim CurrentAnimation As Int=0
End Sub
Sub AppStart (Args() As String)
'Set delay in ms
pause=100
'Initialise all pins
controller.Initialize
dataPin.Initialize(2, False) 'Pin 13, GPIO 2
latchPin.Initialize(4, False) 'Pin 16, GPIO 4
clockPin.Initialize(3, False) 'Pin 15, GPIO 3
l(0).Initialize(23,False) 'Bottom layer
l(1).Initialize(21,False) 'middle layer
l(2).Initialize(22,False) 'top layer
aTimer.Initialize("aTimer",5000) '5 seconds for each animation
states.Initialize
Alist.Initialize
'Turn off ALL leds
ClearLED
Alist.Add("Wheel")
Alist.Add("FrontRoll")
Alist.Add("SideRoll")
CallSub(Me, Alist.Get(CurrentAnimation))
StartMessageLoop
End Sub
Sub SideRoll
'Create and add the animation states
states.Clear
states.Add(CreateState(7, 0, True, False, False))
states.Add(CreateState(7, 0, False, True, False))
states.Add(CreateState(7, 0, False, False, True))
states.Add(CreateState(56, 0, False, False, True))
states.Add(CreateState(192, 1, False, False, True))
states.Add(CreateState(192, 1, False, True, False))
states.Add(CreateState(192, 1, True, False, False))
states.Add(CreateState(56, 0, True, False, False))
states.Add(CreateState(7, 0, True, False, False))
aTimer.Enabled=True
Animate
End Sub
Sub FrontRoll
'Create and add the animation states
states.Clear
states.Add(CreateState(73, 0, True, False, False))
states.Add(CreateState(73, 0, False, True, False))
states.Add(CreateState(73, 0, False, False, True))
states.Add(CreateState(146, 0, False, False, True))
states.Add(CreateState(36, 1, False, False, True))
states.Add(CreateState(36, 1, False, True, False))
states.Add(CreateState(36, 1, True, False, False))
states.Add(CreateState(146, 0, True, False, False))
states.Add(CreateState(73, 0, True, False, False))
aTimer.Enabled=True
Animate
End Sub
Sub Wheel
'Create and add the animation states
states.Clear
states.Add(CreateState(17, 1, True, False, False))
states.Add(CreateState(146, 0, True, False, False))
states.Add(CreateState(84, 0, True, False, False))
states.Add(CreateState(56, 0, True, False, False))
states.Add(CreateState(17, 1, False, True, False))
states.Add(CreateState(146, 0, False, True, False))
states.Add(CreateState(84, 0, False, True, False))
states.Add(CreateState(56, 0, False, True, False))
states.Add(CreateState(17, 1, False, False, True))
states.Add(CreateState(146, 0, False, False, True))
states.Add(CreateState(84, 0, False, False, True))
states.Add(CreateState(56, 0, False, False, True))
states.Add(CreateState(17, 1, False, False, True))
aTimer.Enabled=True
Log("Timer on")
Animate
End Sub
Sub Animate
If Clockwise Then
aa=0
bb=states.Size-1
cc=1
Else
aa=states.Size-1
bb=0
cc=-1
End If
For i=aa To bb Step cc
st=states.Get(i)
b(0)=st.Byte1
b(1)=st.Byte2
lState(0)=st.LayerBottom
lState(1)=st.LayerMiddle
lState(2)=st.LayerTop
MultiWrite(b,lState)
Delay(pause)
Next
Clockwise=Not(Clockwise)
Animate
End Sub
Sub aTimer_tick
Log("Clock tick")
Clockwise=True
aTimer.Enabled=False
CurrentAnimation=CurrentAnimation+1
If CurrentAnimation=Alist.Size Then CurrentAnimation=0
CallSub(Me, Alist.Get(CurrentAnimation))
End Sub
Sub MultiWrite(ByteValue() As Byte, levelState() As Boolean)
latchPin.State=False
'Activate layer
l(0).State=levelState(0)
l(1).State=levelState(1)
l(2).State=levelState(2)
For i = ByteValue.Length - 1 To 0 Step -1
Value = ByteValue(i)
ShiftOut
Next
latchPin.State=True
End Sub
Sub ShiftOut
Dim aa, bb, cc As Int
If BitOrder Then
aa = 7
bb = 0
cc = -1
Else
aa = 0
bb = 7
cc = 1
End If
For i = aa To bb Step cc
clockPin.State=False
If getBits(Value,i,i) = 1 Then
dataPin.State=True
Else
dataPin.State=False
End If
clockPin.State=True
dataPin.State=False
Next
clockPin.State=False
End Sub
Sub SendBit(BitState As Boolean) 'not used
clockPin.State=False
dataPin.State=BitState 'Set data bit
clockPin.State=True 'set shift register clock input
latchPin.State=True 'Toggle latch
latchPin.State=False
End Sub
Sub ClearLED 'Clear two bytes
For i=0 To 15
SendBit(False)
Next
End Sub
Sub Delay (DurationMs As Int)
Dim target As Long = DateTime.Now + DurationMs
Do While DateTime.Now < target
Loop
End Sub
Sub getBits(v As Int,bitStart As Int,bitEnd As Int) As Int 'Called in ShiftOut
Dim res As Int = 0
For a = bitStart To bitEnd
res = res + Power(2,a)
Next
Return (Bit.ShiftRight(Bit.And(v,res),bitStart))
End Sub
Sub CreateState(Byte1 As Byte, Byte2 As Byte, LayerBottom As Boolean, LayerMiddle As Boolean, LayerTop As Boolean) As State
Dim st As State
st.Initialize
st.Byte1=Byte1
st.Byte2=Byte2
st.LayerBottom = LayerBottom
st.LayerMiddle = LayerMiddle
st.LayerTop = LayerTop
Return st
End Sub