Shop OBEX P1 Docs P2 Docs Learn Events
I/O vs. Cog Headache — Parallax Forums

I/O vs. Cog Headache

DaemonDaemon Posts: 6
edited 2011-03-06 13:01 in Propeller 1
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)
{{
  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

  • Heater.Heater. Posts: 21,230
    edited 2011-03-06 06:58
    When you start code in a new COG that code needs to set the appropriate pins to output for itself.
    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.
  • TtailspinTtailspin Posts: 1,326
    edited 2011-03-06 07:08
    Are the pins for the compass module correct? Enable 27, Clock 26, and Data on pin 8?
    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...
  • DaemonDaemon Posts: 6
    edited 2011-03-06 07:52
    Don't worry, compas works like a charm. =)

    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
  • max72max72 Posts: 1,155
    edited 2011-03-06 08:42
    Check the propeller maual.
    I/O pins, page 25 and 26.
    You have 3 rules, it reminds me of Asimov..
  • Duane DegnDuane Degn Posts: 10,588
    edited 2011-03-06 10:15
    I think my failure to set the DIRA register in the correct cog was probably my most frequent error when I was first learning to program the Propeller.
  • DaemonDaemon Posts: 6
    edited 2011-03-06 11:49
    Apparently it's a common mistake.

    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!
  • Heater.Heater. Posts: 21,230
    edited 2011-03-06 13:01
    Excellent.
Sign In or Register to comment.