I/O vs. Cog Headache
Greetings,
I have the following question:
I wrote a static object in which I could control 4 pins that are set to output. Worked like a charm and I could control exactly which pin to set high.
Function to control the pins: (Yes, I know this breaks convention, where the Start function doesn't start a cog. Sue me. this is done in a later version, see rest of post)
So now I wanted to add a feature in which the led is triggered, but only for a configurable amount of seconds:
Whenever a trigger is set (Trigger(LedID)) the time is noted, the led is set and after a few seconds the leds are killed again.
The sad thing is, that SetLed(ledID) is called, because I can see that with the function 'GetLedTriggered', in my main program.
'GetCatchTrigger' reports a trigger that is neatly '0' for exactly the right amount of time.
For the sake of completeness: The main program:
So the big question is, why aren't the leds lighting up? Tests with the origional led code show that my processor is still working. Also the serial data in the monitor shows all values ok and running.
Leds aren't broken either, given the fact that in the simple program they're still working.
The only thing I figure, is that it'd somehow not be possible to control the IO from a secondary cog like this...?
Thanks in advance. Kind regards,
Daemon.
I have the following question:
I wrote a static object in which I could control 4 pins that are set to output. Worked like a charm and I could control exactly which pin to set high.
Function to control the pins: (Yes, I know this breaks convention, where the Start function doesn't start a cog. Sue me. this is done in a later version, see rest of post)
{{
Led control: Simple object to control 4 leds.
}}
VAR
Long Cog
Long Stack[15]
Long m_led1
Long m_led2
Long m_led3
Long m_led4
PUB Start(led1, led2, led3, led4)
m_led1 := led1
m_led2 := led2
m_led3 := led3
m_led4 := led4
dira[m_led1]~~
dira[m_led2]~~
dira[m_led3]~~
dira[m_led4]~~
KillAllLeds
PRI KillAllLeds
outa[m_led1] := 0
outa[m_led2] := 0
outa[m_led3] := 0
outa[m_led4] := 0
PUB SetLed(ledID)
KillAllLeds
if ledID == 1
outa[m_led1] := 1
if ledID == 2
outa[m_led2] := 1
if ledID == 3
outa[m_led3] := 1
if ledID == 4
outa[m_led4] := 1
In my main code, I could instantiate this code and call 'SetLed', which in turn would set all leds to '0' (KillAllLeds) and then trigger the appropriate led.So now I wanted to add a feature in which the led is triggered, but only for a configurable amount of seconds:
{{
Led control: Simple object to control 4 leds.
}}
VAR
Long Cog
Long Stack[20]
Long m_led1
Long m_led2
Long m_led3
Long m_led4
Byte m_ledTriggered
Byte m_catchTrigger
Byte m_trigger1
Byte m_trigger2
Byte m_trigger3
Byte m_trigger4
Long m_triggerTime
Long m_triggerLength
PUB Start(led1, led2, led3, led4, activeLength)
m_led1 := led1
m_led2 := led2
m_led3 := led3
m_led4 := led4
m_ledTriggered := 0
m_catchTrigger := 1
m_trigger1 := 0
m_trigger2 := 0
m_trigger3 := 0
m_trigger4 := 0
dira[m_led1]~~
dira[m_led2]~~
dira[m_led3]~~
dira[m_led4]~~
m_triggerLength := activeLength * clkfreq
KillAllLeds
Cog := cognew(MonitorTriggers, @Stack) + 1
PUB GetCatchTrigger : triggerVal
triggerVal := m_catchTrigger
PUB GetTriggerTime : triggerTime
triggerTime := m_triggerTime
PUB GetTriggerLength : triggerLength
triggerLength := m_triggerLength
PUB GetTriggerDrop : triggerDrop
triggerDrop := m_triggerTime + m_triggerLength
PUB GetLedTriggered : ledTriggered
ledTriggered := m_ledTriggered
PUB Trigger(ledID)
if m_catchTrigger == 1
m_catchTrigger := 0
if ledID == 1
m_trigger1 := 1
if ledID == 2
m_trigger2 := 1
if ledID == 3
m_trigger3 := 1
if ledID == 4
m_trigger4 := 1
PRI MonitorTriggers
repeat
if m_trigger1 == 1
SetLed(1)
m_trigger1 := 0
if m_trigger2 == 1
SetLed(2)
m_trigger2 := 0
if m_trigger3 == 1
SetLed(3)
m_trigger3 := 0
if m_trigger4 == 1
SetLed(4)
m_trigger4 := 0
if m_catchTrigger == 0
if cnt => m_triggerTime + m_triggerLength
KillAllLeds
m_catchTrigger := 1
PRI KillAllLeds
m_ledTriggered := 0
outa[m_led1] := 0
outa[m_led2] := 0
outa[m_led3] := 0
outa[m_led4] := 0
PUB SetLed(ledID)
KillAllLeds
m_triggerTime := cnt
if ledID == 1
outa[m_led1] := 1
m_ledTriggered := m_led1
if ledID == 2
outa[m_led2] := 1
m_ledTriggered := m_led2
if ledID == 3
outa[m_led3] := 1
m_ledTriggered := m_led3
if ledID == 4
outa[m_led4] := 1
m_ledTriggered := m_led4
So start now initializes all properties of the class, instantiates a cog and it starts scanning the 'trigger' values.Whenever a trigger is set (Trigger(LedID)) the time is noted, the led is set and after a few seconds the leds are killed again.
The sad thing is, that SetLed(ledID) is called, because I can see that with the function 'GetLedTriggered', in my main program.
'GetCatchTrigger' reports a trigger that is neatly '0' for exactly the right amount of time.
For the sake of completeness: The main program:
{{
Main program for the compas reader.
}}
CON ''General Constants for Propeller Setup
_CLKMODE = XTAL1 + PLL16X
_XINFREQ = 5_000_000
CON ''Setup Constants for the Compass
Enable = 27
Clock = 26
Data = 8
{{
+----------+
+----?¦1? ???? ?6¦?--? +5V P0 = Enable
¦ 1K ¦ +----¦ ¦ P1 = Clock
P2 ??-??-?¦2 ¦ /\ ¦ 5¦?--? P0 P2 = Data
¦ ¦/ \¦ ¦
VSS ?--?¦3 +----+ 4¦?--? P1
+----------+
}}
VAR ''Setup variables related to the compass
long CorrectHeading
long Deg, OldDeg
long triggerVal
byte catchTrigger
long triggerTime
long triggerLength
long triggerDrop
byte ledTriggered
OBJ ''Setup Object references that make this demo work
HM55B : "HM55B Compass Module Asm"
Calibrate : "HM55B Compass Calibration"
Ser : "FullDuplexSerial"
Leds : "LedControl"
Trigger : "TriggerDetect"
PUB DEMO_Initialization | i,dx,dy
Ser.start(31, 30, 0, 38400) '' Initialize serial communication to the PC
Leds.Start(0, 1, 2, 9, 3)
HM55B.start(Enable,Clock,Data) '' Initialize Compass Object
Trigger.start(10) '' Initialize trigger.
Compass_Demo '' Start the Compass DEMO
PUB Compass_Demo|RawHeading
repeat
ser.tx(1) ' Send the HOME code to the DEBUG terminal
ser.str(string("HM55B Propeller Compass Demo")) ' Display Header Text
ser.tx(13) ' Send the RETURN key code to the DEBUG terminal
ser.tx(13) ' Send the RETURN key code to the DEBUG terminal
ser.tx(13) ' Send the RETURN key code to the DEBUG terminal
RawHeading := HM55B.Theta ' Read RAW 13-bit Angle
CorrectHeading := Calibrate.Correct(RawHeading) ' Calibrate Correct Heading
Deg := CorrectHeading * 45 / 1024 ' Convert 13-Bit Angle to Deg
' Note: This only makes it easier for us Humans to
' read.
ser.str(string("Correct Heading: ")) ' Display Correct Heading as a Degree
ser.dec(Deg)
ser.str(string(" "))
triggerVal := Trigger.GetTrigger
if triggerVal == 1
if Deg => 225
if Deg < 315
Leds.Trigger(1)
ser.str(string("|Led 1|"))
if Deg => 315
Leds.Trigger(2)
ser.str(string("|Led 2|"))
if Deg < 45
Leds.Trigger(2)
ser.str(string("|Led 2|"))
if Deg => 45
if Deg < 135
Leds.Trigger(3)
ser.str(string("|Led 3|"))
if Deg => 135
if Deg < 225
Leds.Trigger(4)
ser.str(string("|Led 4|"))
ser.tx(13)
ser.tx(13)
ser.tx(13)
catchTrigger := Leds.GetCatchTrigger
triggerTime := Leds.GetTriggerTime
triggerLength := Leds.GetTriggerLength
triggerDrop := Leds.GetTriggerDrop
ledTriggered := Leds.GetLedTriggered
ser.str(string("Trigger: "))
ser.dec(triggerVal)
ser.tx(13)
ser.str(string("CatchTrigger: "))
ser.dec(catchTrigger)
ser.tx(13)
ser.str(string("TriggerTime: "))
ser.dec(triggerTime)
ser.tx(13)
ser.str(string("TriggerLength: "))
ser.dec(triggerLength)
ser.tx(13)
ser.str(string("TriggerDrop: "))
ser.dec(triggerDrop)
ser.tx(13)
ser.str(string("Led Triggered: "))
ser.dec(ledTriggered)
ser.tx(13)
ser.str(string("cnt: "))
ser.dec(cnt)
ser.tx(13)
''#########################################################
''#########################################################
So the big question is, why aren't the leds lighting up? Tests with the origional led code show that my processor is still working. Also the serial data in the monitor shows all values ok and running.
Leds aren't broken either, given the fact that in the simple program they're still working.
The only thing I figure, is that it'd somehow not be possible to control the IO from a secondary cog like this...?
Thanks in advance. Kind regards,
Daemon.
Comments
Reason being that each COG has it's own DIRA register. So no output can leave that COG unless it's own DIRA register is set correctly.
CON ''Setup Constants for the Compass Enable = 27 Clock = 26 Data = 8 {{ +----------+ +----?¦1? ???? ?6¦?--? +5V P0 = Enable ¦ 1K ¦ +----¦ ¦ P1 = Clock P2 ??-??-?¦2 ¦ /\ ¦ 5¦?--? P0 P2 = Data ' is this supposed to be Pin2 or Pin8 ???? ¦ ¦/ \¦ ¦ VSS ?--?¦3 +----+ 4¦?--? P1 +----------+
I can't tell if this will make a difference, do You want the compass data pin to be Pin8 ?P.S. what heater said...
It was really just the leds that were being a pain in the output.
Its own seperate DIRA, huh? Should have known. But at least I figured with was something like that.
So the dira's chould be set in the MonitorTriggers function?
Thank you VERY much for the input! I'll try it as soon as I'm home again!
Kind regards,
Daemon
I/O pins, page 25 and 26.
You have 3 rules, it reminds me of Asimov..
I've moved the code to set direction of the pins to the starting function of the cog, before the repeat block.
My leds now work.
Thank you all!