Shop OBEX P1 Docs P2 Docs Learn Events
Reading a pin and increasing a counter, Finally done!!!! - Page 2 — Parallax Forums

Reading a pin and increasing a counter, Finally done!!!!

2»

Comments

  • Ron SutcliffeRon Sutcliffe Posts: 420
    edited 2008-02-23 07:40
    OK Mosquito
    Your led should be working with this code...............so should your TV
    con
          _clkmode        = xtal1 + pll16x
          _xinfreq        = 5_000_000
          led_pin         = 27        'I just changed name from pin to Led_pin
                                       'declared now as a CON because it does not
                                       'change after compilation 
    OBJ
    term   : "tv_text"
       
    VAR
    byte cntrr
    byte stack[noparse][[/noparse]20]
      
     
    PUB Start 
      cntrr:=0
      term.Start(12)
      cognew(starttt,@stack) 
      waitcnt(clkfreq  + cnt)
      
     repeat
        if ina[noparse][[/noparse]led_pin]==1 
          cntrr++
          term.dec(cntrr)
          term.out(13) 
     
    PUB Starttt
    dira[noparse][[/noparse]led_pin]:=1
    outa[noparse][[/noparse]led_pin]:=1
    repeat  
      !outa[noparse][[/noparse]led_pin]
      waitcnt(clkfreq/8+cnt)
       
    

    I will post again shortly with a few question which I would like you to consider.
    Then we can look at the code in more·detail. You may wish to re-think your approach to the problem after we have been through your code.




    Ron
  • Ron SutcliffeRon Sutcliffe Posts: 420
    edited 2008-02-23 08:07
    @steve
    I missed initialising the variable "pin" to 27 in the code that I first posted .......uh?
    I was sure I declared it as a CON..........I talked about it, but didn't happen in the edit.


    @Mozzi
    sorry about that
  • mosquito56mosquito56 Posts: 387
    edited 2008-02-23 08:10
    Ron , this code works exactly as you expect it. I just want the led to turn off
        
     repeat
        if ina[noparse][[/noparse]led_pin]==1 
          cntrr++
          term.dec(cntrr)
          term.out(13)
    

    should read

    ·repeat
    ··· if ina[noparse][[/noparse]led_pin]==1
    ····· cntrr++
    ····· term.dec(cntrr)
    ····· ina[noparse][[/noparse]led_pin]:=0 ' turn off the pin nothing more
    ····· term.out(13)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·······

    ······· "What do you mean, it doesn't have any tubes?"
    ······· "No such thing as a dumb question" unless it's on the internet
    ········
  • Ron SutcliffeRon Sutcliffe Posts: 420
    edited 2008-02-23 08:32
    Does the led continue to Blink continuosly?
    Is your TV_text scrolling continuosly ?


    That is all the code I have posted at this stage.
    I have tested it here and it does these two steps OK

    We will get to the turning off Led later. When we deal with your code in detail.

    Ron
  • mosquito56mosquito56 Posts: 387
    edited 2008-02-23 08:36
    Yes it blinks continuely

    yes the·t.v. ·scrolls continuesly. I am using your code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·······

    ······· "What do you mean, it doesn't have any tubes?"
    ······· "No such thing as a dumb question" unless it's on the internet
    ········
  • Ron SutcliffeRon Sutcliffe Posts: 420
    edited 2008-02-23 08:51
    Ok good.
    Now WHEN or UNDER WHAT CONDITION do you want to stop the led blinking?

    and WHEN of UNDER WHAT CONDITION do you want to start the led blinking again?

    Ron
  • Paul BakerPaul Baker Posts: 6,351
    edited 2008-02-23 10:22
    mosquito, are you still trying to turn off the pin from another cog? If so, it can't be done, it's simply impossible, search the manual for "wired or".

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.
  • Chuck McManisChuck McManis Posts: 65
    edited 2008-02-23 10:39
    Mosquito, have you gotten any closer to a resolution here?

    I thought this was a pretty clear problem statement:
    mosquito said...

    Start a seperate cog that turns a pin high, led on.

    Read the pin in MAIN program, increase counter and turn light off.

    The challenge of using a pin to communicate however is that there isn't a single register which holds the pin state. Basically if any COG sets a pin high (like your counter cog turning on the LED) then no other COG can set it low. A way to get around that is to have one "owner" for the LED and then tell that owner that you've seen the LED and that it can reset it.

    One way to do that would be to have a spin object (LED_Manager) which had a PUB entry called "Start" which did two things, it turns on or off an LED based on a variable "LED_State", and it reads a variable "LED_Ack". So the code would be something like:
    VAR
        BYTE LED_State, LED_Ack
        LONG Cog_id, Stack[noparse][[/noparse]20]
    
    PUB Start : ok
        ok := Cog_id := COGNEW(@LED_Policy, @Stack)
    
    PRI LED_Policy
        Repeat
          IF LED_State
            OUTA[noparse][[/noparse]LED_pin] := 1
          Else
            OUTA[noparse][[/noparse]LED_pin] := 0
          IF LED_Ack
            LED_Ack := 0            ' We saw the acknowledgement
            LED_State := 0          ' This will cause the LED to go off
        {{ code that determines if LED should be turned on }}
         IF Counter > 1000
           LED_State := 1
    
    PUB Ack
        LED_Ack := 1
        
    PUB State : isLit
        isLit := LED_State
        
    
    



    In your MAIN code you would add an object in the OBJ clause that was something like:
    OBJ
        led : "LED_Manager"
    
    



    Then in your main code initialization you could start it up with
    PUB main_entry
        IfNot led.start
            ' Do something because you are out of COGs
        ...
        If led.State         ' This will tell you if the LED is let or not
            counter++      ' Add one to the counter
           ... do something ... ' Do what ever you want to do
           led.Ack                  ' Tell the LED manager to turn the LED off again
    
    



    In this way only one COG needs to control the LED and you tell it what to do (either turn it on or turn it off). You can ask the COG what the current state of the LED is with the call to the State function.

    That will achieve your goal of having a COG communicate back to Main and Main back to the COG with an LED being on or off depending on whether or not the event your LED manager is watching for has occurred and whether or not the Main program has acknowledged seeing the event.

    Is that at all helpful?

    --Chuck
  • ClemensClemens Posts: 236
    edited 2008-02-23 17:33
    mosquito56 said...

    Clems, I saw your post and have to ask. If doing it in private doesn't work, what is next? Read my previous msg about private msg for D.

    1. Private msg

    2.?

    3. Parallax for official complaint. I have put him on ignore and only ask he do the same to me. Since I am no longer reading his posts I will not be bothered again but he has a condesending attitude and I have had enough.

    Well, if you have put him on ignore, the issue should be settled for you. Why do you bother then? To be honest, I think asking someone to stay out of your thread is the rudest behavior I have seen on this forum. Almost everyone else likes to hear what deSilva has to say to the problems you post when they are of general interest, so you cannot claim extra-treatment for your threads. Sometimes not answering could mean that someone else is mislead by following in your footsteps, so it is valuable for the public to know if code is well-written or not.

    I remember you even told two visitors of your - now dead - newbies thread to leave because in your opinion they were talking OT. Why are you so annoyed by OT, why can't you just quietly ignore it like Paul asked us to?

    I can understand that considering your background of database programming it gets you upset that with the propeller you have to start almost from the beginning again. But isn't this fun also? Isn't it cool to learn something new at advanced age even if the price is to get some sarcastic remarks when you keep·not·noticing·the obvious or when you're thinking in the wrong direction?

    By ignoring deSilva you may have decreased the value of this forum by 20% and I find it odd that in the future someone of us will have to repost his answers to your questions because you can't see them.

    And if he doesn't post links and you don't find what he relates to - just ask for it, someone else can look it up for you. - If he says "this question has been asked before", just ask and someone can look up the thread for you if you don't find it. It is not insulting to tell someone that the answer to his question is in the archives.

    Just relax and enjoy the remaining 80% of this brilliant forum·;-)
  • mosquito56mosquito56 Posts: 387
    edited 2008-02-23 18:54
    Paul, I have read that and completely misunderstood it's meaning. If it can't be done, it can't be done.

    Chuck, I see exactly what your driving at.

    Which is the line that returns the info to the main program to tell it the light is on? Returning a variable from another cog is a problem I see posted alot and I have still not resolved it.

    Clems, Yes the issue is settled for me. I see no other alternative. Please don't feel the need to repost info for my sake I guess I'll just have to take that chance. Not trying to be flippant, I just disagree with your %20 number. He may make %20 of the posts but alot is nonsense and totally useless but his attitude is UNACCEPTABLE.

    · He has gotten me so angry I have been rude to others in response. When that has been brought to my attention, I have sent 'PRIVATE' applogies to them. I applogize to everyone that this has gone public but private msgs didn't work, then somewhat rude didn't work, then VERY rude didn't work so public was the only way to go.
    ·· I have recieved numerous private msgs on the topic of rudeness on this forum. I've even had one person ask me to ask a question so I would take the flaming for him. I sincerely believe he is hurting parallax business but that is MHO.

    O.T. drives me nuts. If a person wants to change the subject they can start another post.·I· have notice a decline in postings here. Some think it's the greater amount of info for newbies.·This may be true, or it just may be fear.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·······

    ······· "What do you mean, it doesn't have any tubes?"
    ······· "No such thing as a dumb question" unless it's on the internet
    ········
  • Chuck McManisChuck McManis Posts: 65
    edited 2008-02-23 20:16
    mosquito said...

    Chuck, I see exactly what your driving at.

    Which is the line that returns the info to the main program to tell it the light is on? Returning a variable from another cog is a problem I see posted alot and I have still not resolved it.

    When MAIN calls led.State the line which reads:

        isLit := LED_State
    
    



    Returns the state of the LED to the main program.

    The definition of the method which reads:
    PUB State : isLit
    
    



    Tell the propeller interpreter that the value in isLit is to be returned to the caller. Then by assigning to that name in the method body you establish what the return value will be. So in the MAIN program it can treat the name "LED.State" as a readonly variable which tells it if the LED is lit, and LED.Ack as a function to reset it. Using some code you posted above, you wrote:
    repeat
        if ina[noparse][[/noparse]led_pin]==1
          cntrr++
          term.dec(cntrr)
          ina[noparse][[/noparse]led_pin]:=0 [color=#990000]' turn off the pin nothing more[/color]
          term.out(13)
    
    'To do this with the LED_manager object you would change two lines:
    
    repeat
        if [b]LED.State[/b]
          cntrr++
          term.dec(cntrr)
          [b]LED.Ack[/b]              ' turn off the pin nothing more
          term.out(13)
    
    



    Spin to Spin communication between COGs is pretty straightforward using objects in this way, Spin to Assembler or Assembler to Spin can be a bit more complicated as the data inside the COG isn't visible to the SPIN interpreter, that is where you get the COG using RDLONG and WRLONG (or RDBYTE/RDWORD/WRBYTE/WRWORD) assembly instructions to copy data from the cogs memory into the common memory area.

    If you had two pins in the I/O register to spare you could do it by having main look at one of them and set a different one. Your LED manager code could look at the one main sets and set the LED one. The challenge is that two cogs can't both write the same pin as has been made pretty clear now.

    --Chuck

    Post Edited (Chuck McManis) : 2/23/2008 8:24:17 PM GMT
  • mosquito56mosquito56 Posts: 387
    edited 2008-02-24 00:14
    if timerb.state==1
           hobbs++
           timerb.ack
        dec(hobbs)
    

    Sorry, i read the : as a |, need new glasses, I may have messed it up
    repeat  
        
       if phsb>oldcnt 'if outa is changed to !outa, led will blink on and off a 1 sec rate
         oldcnt:=phsb
          outa[noparse][[/noparse]pin] :=1
          statebyte:=1
    pub state:statee
     return statebyte
    pub ack
      outa[noparse][[/noparse]pin]:=0
      statebyte:=0  
    

    This is what I have. The hobbs is counting up but the ack does nothing.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·······

    ······· "What do you mean, it doesn't have any tubes?"
    ······· "No such thing as a dumb question" unless it's on the internet


    Post Edited (mosquito56) : 2/24/2008 12:22:39 AM GMT
  • Chuck McManisChuck McManis Posts: 65
    edited 2008-02-24 00:58
    Hi Mosquito,

    Some suggestions, first one is that the IF statement in Spin treats a non-zero value as true and a zero value as false. In another language I might have declared statebyte in your code to be a Boolean but the effect is the same here since it can only be either 1 (true) or 0 (false). That is why you could rewrite this first bit of code thusly (my change is bold, your original is italics, use ctrl-+ in Firefox to increase the page font size):
    [i]' if timerb.state==1[/i]
        [b]if timerb.state[/b]        ' If the value returned by state is non-zero this if clause will execute
            hobbs++
            timerb.ack
           dec(hobbs)
    
    


    Now there is another question here, and it becomes clear if you turn on the 'show block group indicators' on the Preferences page. Since there are no BEGIN and END indicators in Spin this code may not execute all at the same time depending on the indication (I realize that its tough to type in code in the forums here too) The way I wrote it above if the timerb.state flag is set then the call to dec(hobbs) will also be executed. If this isn't what you were expecting you will need to adjust indentation in your code to move it out of the way.

    Now the second bit of code (the implementation of timerb) I've also modified slightly (same notation, your code in italics, my bold):
    [b]pub start
        cognew(@watch_timer, 0)
    
    pub watch_timer                ' added this for clarity [/b]
        repeat 
            if phsb>oldcnt 'if outa is changed to !outa, led will blink on and off a 1 sec rate
                oldcnt:=phsb
                outa[noparse][[/noparse]pin] :=1
                statebyte:=1
    
    pub state:statee
    [i]' return statebyte[/i]
        [b]statee := statebyte[/b]
    
    pub ack
        outa[noparse][[/noparse]pin]:=0
        statebyte:=0 
    
    



    Now I've made only two changes here, one was to add a method start to run this endless loop in a separate cog, and watch_timer which is the name I gave to the method that is running in the endless loop. If it wasn't in a separate cog (the point of this exercise yes?) then you wouldn't get a chance to call state or ack. I expect you have dealt with those details in your code but for people reading I wanted it to be clear what we were doing here. It doesn't change what the code does. But in the state method I removed your return statement and replaced it with an assignment of the return value. I cannot say if the return syntax would work, only that I've used this syntax where I simply assign the return value and drop off the end of the method and it works as one might expect (the value I've assigned to the return value is returned). I believe with those two changes the code runs certainly as I expect it to, but you added:
    mosquito said...

    This is what I have. The hobbs is counting up but the ack does nothing.

    And I have to ask how you know the ack does nothing? Consider the situation where the code works like we are expecting, pshb's value exceeds that of oldcnt and the output pin is set to one (and as you know it is repeatedly set to one because of the blinking behavior). Now your main code increments hobbs and calls timerb.ack. That will turn off the pin, but if pshb is already greater than oldcnt the repeat loop will nearly instantly turn it back on again (so fast that you would not be able to see it with your naked eye, but an oscilloscope might catch it). If you have a spare pin attached to an LED consider adding the line:
        !outa[noparse][[/noparse]debug_pin]
    
    


    And see if it starts blinking too. That will tell you that ack is being called and it will tell you that state is returning a non-zero value on occasion (but if hobbs is counting up in your main code then you already know that).

    Its entirely possible that the whole transaction happens so quickly its not easily perceived so if we can slow it down to human perception speed that would be a good thing.

    --Chuck

    Post Edited (Chuck McManis) : 2/24/2008 1:08:44 AM GMT
  • Ron SutcliffeRon Sutcliffe Posts: 420
    edited 2008-02-24 01:48
    mosquito

    I see you have a little bit more code get your head around.

    ina[noparse][[/noparse]led_pin]:=0 'turn on led_pin, nothing more'

    Chuck has taken you back to the above line of code, albeit a little quicker than I would have, so I'll just sit this one out.

    Ron
  • mosquito56mosquito56 Posts: 387
    edited 2008-02-24 03:04
    Working, but defeats the purpose. THanx a million Ron, you solved this problem and my next problem at the same time. Heres the code. My next problem is so stupid I won't even mention it. Guess I just had a bad brain day.

    Original Idea. I want a clock to run a timer. Needs to be in seperate cog since original cog is used for other purposes.
    Very educational and intuitive idea from Mike Green(many thanx for your patience) however one person always makes sure to give credit somewhere else as if that were important.
    ·I have been working on this for about a month off and on. I was reluctant to post for fear of flaming. I got my flaming as you all saw but it was worth it. Thanks to everyone for their constructive opions. Apologies to Mark, Glad you accepted my appology.
    · As you can tell I am extremely happy that these problems have been solved.
    Have a proping Day
    repeat  
        
       if phsb>oldcnt
         oldcnt:=phsb
          statebyte:=1
      if statebyte
        outa[noparse][[/noparse]pin] :=1
           
      else
        outa[noparse][[/noparse]pin] :=0
           
    
    pub state:statee
     return statebyte
    pub ack:otherr
      statebyte:=0
      return statebyte
    

    The pin only flashes but since it is totally useless now I can just delete the code.
    Original question? Can you use a pin output to pass bit info from 1 cog to another? Answer: No


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·······

    ······· "What do you mean, it doesn't have any tubes?"
    ······· "No such thing as a dumb question" unless it's on the internet
    ········
  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-24 03:10
    You can certainly use a pin output to pass bit information from one cog to another. I've done it a number of times.

    For example, I've set up two copies of FullDuplexSerial with the two copies of the assembly portion in each of two cogs and two other cogs with the Spin interpreters running Spin code, one to transmit out an I/O pin and the other receiving on the same I/O pin. The assembly portions are the actual routines doing the I/O. The Spin code just talks to the buffers. Works fine. I've done the same thing using serial I/O routines written in Spin. Works fine.
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-02-24 03:12
    mosquito, you can use pins to pass bits between cogs. You could for example use one of the serial routines to send data on a pin and have it received (using a serial object) from another cog. I think that your original question was about turning off a pin that was turned on in another cog which is something entirely different. If you wanted to be able to turn the pin off you would either need to use a variable in the memory or use another pin to signal the cog that has the pin turned on to turn it off.
  • mosquito56mosquito56 Posts: 387
    edited 2008-02-24 03:21
    I must have mistated something. My bad. I just wanted to turn on a·led ·in one cog and turn it off in another.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·······

    ······· "What do you mean, it doesn't have any tubes?"
    ······· "No such thing as a dumb question" unless it's on the internet
    ········
  • Mike GreenMike Green Posts: 23,101
    edited 2008-02-24 03:31
    Because of the wired-or nature of the I/O pin connections, there's a priority relationship between turning something on and turning something off. If you wire up the LED so it goes on when the I/O pin becomes logic low, then the turn off can be done in a 2nd cog where it overrides the first cog turning the LED on. That works. Both cogs would have their DIRA bit set to 1. The 2nd cog would be initialized with its OUTA bit set to zero and the 1st cog would be initialized with its OUTA bit set to 1 to keep the LED off. The 1st cog would change its OUTA bit to 0 to turn the LED on. The 2nd cog would change its OUTA bit to 1 to turn the LED off. The 2nd cog would eventually have to change its OUTA bit back to 0 to allow the LED to be turned on by the 1st cog. They could either communicate via hub memory or by using another I/O pin to signal that the LED was forced off by the 2nd cog and the 1st cog would need to set its OUTA bit back to 1.

    Post Edited (Mike Green) : 2/24/2008 3:36:28 AM GMT
Sign In or Register to comment.