I/O vs. Cog Headache
Daemon
Posts: 6
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] := 1In 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_led4So 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.
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!