Shop OBEX P1 Docs P2 Docs Learn Events
Another pair of eyes needed please — Parallax Forums

Another pair of eyes needed please

morris4019morris4019 Posts: 145
edited 2009-06-06 03:38 in Propeller 1
So i'm finished designing the circuit for my beacon, and i thought i would try and build my first real object (version one). Everything seems to work fine, and i did not have this problem about an hour ago, but for some reason i do now. The problem being the Suspend Signal button (ONOFF_PIN in the code). When the user presses the button it should stop the cog, then, when the user pushes the button again, it should start back up (running GenerateSignal in a new cog). The problem i'm having is that when the object runs, the first time the user presses the button, the cog stops. Just like it is suppose to. But when the user presses the button again (2nd time) the cog does not start up, nothing happens. At this point the LEDs that display the Beacon ID are still on (and they should never go out actually). When the user hits the button for a 3rd time, for some reason the Beacon Id leds all go out, meaning the repeat loop inside the Start method has either hung up or exited all together. But the funny thing is, a new cog starts with GenerateSignal.

I've been running through this code line by line for hours now and can't seem to find the problem. Below i have attached the object file (cause it is a little too large to include), and i here is the demo code that i used to run the object. Any help would be appretiated, and remember this is my first REAL object that i've created. I love critisizm but just remember that i'm trying my best.

Thanks

CON

  _clkmode = xtal1 + pll16x
  _xinfreq = 5_000_000

OBJ

  beacon : "38kHzBeacon"

PUB main

  beacon.Start(15,16,21,0,1)



-Mike

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
======

······ I'll try everything once [noparse]:)[/noparse]

Comments

  • kwinnkwinn Posts: 8,697
    edited 2009-06-04 06:11
    The first thing I can see is that there is no debouncjng of the pushbutton. This means the signal can go from high to low several times when you push it. You need to repeat the ina and have it stay high for several iterations before considering it closed, then wait for it to stay low for several iterations before considering it open.
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-06-04 06:27
    Is it possible that the outa[noparse][[/noparse]C_PIN]~ is missing in the ChangeState else - when restarting the COG?
    In the stop function you set it to 1 but never clear it again. As the OUTA of all COGs are ORed, it will stay 1 after the first stop.

    Usually I would give the advice not to use one PIN in several COGs unless you have a good reason for that. But I guess your good reason is that the PIN should be high if there is no frequency output.

    Another thing:
    PRI CoordinateDisplay
      ShowBeaconID                'Display the Beacon ID in the indicator LEDs
      
      if myState == on            'If signal is being generated, turn on indicator LED
        outa[noparse][[/noparse]IND_PIN]~~
      else [s][color=red]myState == off[/color][/s]
        outa[noparse][[/noparse]IND_PIN]~ 
    

    remove that or use elseif - which is not needed here and only adds execution time / memory usage.

        if ina[noparse][[/noparse]ONOFF_PIN]           'If Signal Suspend button is pressed
          repeat while ina[noparse][[/noparse]ONOFF_PIN] 'Wait until the button is released
          ChangeState               'Change the state.
    

    Oh ... I see that kwinn already posted a comment on that. The repeat while comes short time after the if, so there is a chance that you find a low level from bouncing and you would immediately change the state.
    Maybe adding some waitcnt would be a good idea as well. Just for a few ms.

    By the way ... using OUTA[noparse][[/noparse]C_PIN] in the first COG would be enough to stop and start frequency generation. Simply let the COG run. Only drawback is that your signal will start with any kind of low-time for the first cycle.

    Post Edited (MagIO2) : 6/4/2009 6:34:12 AM GMT
  • morris4019morris4019 Posts: 145
    edited 2009-06-04 13:14
    I'm glad you brought the debouncing to light, i did not even think of it. Thanks

    As far as letting the cog run, I have been thinking thats what i would do. But that does not change the fact that the code should produce another cog. Thats what gets to me, I really want to know why this is not working properly. But this could just be simply that the button is bouncing it's state cause instant ChangeStates and the rest is not catching up. I'll fix that first, then we will see what we've got.

    Thank for the input.

    -Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
  • kwinnkwinn Posts: 8,697
    edited 2009-06-04 15:40
    Mike, when I started in electronics and computers I was surprised at the number of times fixing a minor error that I thought could not possibly be related to the problem I was having would either solve the problem or make the cause of it obvious. My philosophy very quickly became "fix the errors you find as soon as you find them". Saves a lot of time in the long run.
  • morris4019morris4019 Posts: 145
    edited 2009-06-04 16:44
    I totally agree. My eyes were just getting tired. I needed another set of eyes at that point. I really do appretiate all help. Thank you all very much.

    -Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
  • morris4019morris4019 Posts: 145
    edited 2009-06-04 17:52
    You were completely right, debouncing the button has fixed all the problems. I have updated the code, and finished writing the methods to let the user cycle through BeaconID. I am watching my niece and nephew because my brother is having surgery right now, but when i get home I will be testing it with the monitor object running on a different propeller to make sure the signal generation is still correct.

    Here is the finished product of 38kHzBeacon.spin that i wrote.

    Thank you everyone for helping me put it together.



    -Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-06-04 20:01
    You now have 2 buttons, right?

     
        if ina[noparse][[/noparse][color=red]CYCL_PIN[/color]] AND (! myState)                    'If the cycle button is pressed an signal generation is suspended
          waitcnt(clkfreq/3 + cnt)                          'Debounce the button
          repeat while ina[noparse][[/noparse][color=red]ONOFF_PIN[/color]]                       'Wait until the button is released
    

    So is that realy what you want?

    Where did you get the SquareWave object from - can't find it? So this is currently just a guess: Isn't·SquareWave using the counters to produce to squarewave? If so, how can you call it 4 times? My expectation would be that it only drives one pin in your case.

      byte BP1            'Bit 1 Pin for displaying Beacon ID
     [s][color=orange] byte BP2            'Bit 2 Pin for displaying Beacon ID
      byte BP3            'Bit 3 Pin for displaying Beacon ID
      byte BP4            'Bit 4 Pin for displaying Beacon ID
    [/color][/s]  byte BP5            'Bit 5 Pin for displaying Beacon ID
    
    


    As far as I can see you don't use BP2,BP3 and BP4, you only use BP5..BP1, so why waste the bytes?
  • morris4019morris4019 Posts: 145
    edited 2009-06-04 23:07
    Your right on the BP2-4, that was a mistake on my part, before i combined them. I do have 2 buttons, one to suspend the signal (stop it), and the other, while the signal is stopped cycles the Beacon ID to change it. I had to call Square wave 4 times because i was using 4 pins as outputs to IR LEDs, but now that i think about it, there shouldn't been any adverse effects to having 4 LEDs run off of one pin.

    -Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
  • morris4019morris4019 Posts: 145
    edited 2009-06-04 23:13
    Should look like this...



    -Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
  • morris4019morris4019 Posts: 145
    edited 2009-06-05 02:29
    Is there a way to set each bit of a byte a different value at different times. For instance, if i have an array of 5 or so, each containing 0's and 1's in sequence. Is there any way to put it back together in a single vairable.

    I tried to the following, this might make more sense seeing it.

    SIGNAL := data[noparse][[/noparse]0..4]
    



    But the ".." is not allowed aparently in normal arrays. Only the special registers right?

    -Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
  • morris4019morris4019 Posts: 145
    edited 2009-06-05 04:31
    Anyone have any ideas? I would appretiate the help, i've been trying to figure this one out for awhile.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
  • kwinnkwinn Posts: 8,697
    edited 2009-06-05 04:40
    To set a bit to 0 'and' a byte that has all ones except the bit you want to set to 0.
    To set a bit to 1 'or' a byte that has all zeros except the bit you want to set to 1.
  • W9GFOW9GFO Posts: 4,010
    edited 2009-06-05 05:15
    morris4019 said...
    Anyone have any ideas? I would appretiate the help, i've been trying to figure this one out for awhile.


    You can do this to set each bit.

    Value := %1111000

    There is almost certainly a better way, I'm sure someone will pipe up.

    Rich H
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-06-05 08:36
    Hi Morris!

    Your SIGNAL is a variable of a certain size. In case of long it has 32 bits, in case of word it has 16 bits, in case of byte it has 8 bits.
    If you want to initialize the SIGNAL you simply give a bit-pattern:

    SIGNAL := %00001111
    Please note, the bits on the left side are the Most Significant Bits (MSB). The bit following % is bit 7. This is very essential to know, because when you assign the SIGNAL to OUTA it can behave differently:
    OUTA[noparse][[/noparse]3..0]:=SIGNAL in this case will set pins 0 to 3 to 1 -> easy to understand: bits 4 to 7 of the SIGNAL are not needed
    OUTA[noparse][[/noparse]7..0]:=SIGNAL will set pins 0 to 3 to 1, pins 4 to 7 to 0 -> easy to unerstand: the OUTA range has the same size and order as the SIGNAL variable
    OUTA[noparse][[/noparse]0..7]:=SIGNAL will set pins 0 to 3·to 0, pins 4 to·7 to 1 -> OUTA range has the same size, but different order than the SIGNAL
    OUTA[noparse][[/noparse]7..4]:=SIGNAL will set pins 4 to 7 to 1·-> because in this case bit0 of SIGNAL will be copied to bit4 of OUTA

    If you now want to modify single bits you need·bit operations. The OR (bitwise or operator is '|') will set a bit and the NOT·AND (bitwise not = '!',·bitwise and = '&') will clear a bit. With the |< operator you can generate a number where exactly one bit is set at the place specified after the operator.

    |<1 will generate bit pattern %00000010 (as the bit number starts from 0)

    SIGNAL := %00001111
    SIGNAL := SIGNAL | |<1····· -> result: %00001111 as bit number 1 was already set
    SIGNAL := SIGNAL | |<5····· -> result: %00101111
    SIGNAL := SIGNAL & ! |<1·· ·-> result: %00101101
    SIGNAL := SIGNAL & ! |<4····-> result: %00101101 as bit number 4 was already cleared

    Did this answer your question?

    Post Edited (MagIO2) : 6/5/2009 8:51:07 AM GMT
  • morris4019morris4019 Posts: 145
    edited 2009-06-05 18:35
    I know how to set the bit pattern manually. But maybe i need to be a little more specific on my question. I have an array of byte (because it is the smallest variable available). I have 5 array elements in data.
    Data[noparse][[/noparse] 5 ]
    



    I have a variable SIGNAL that needs to be the combined value of data. So, what i need is

    Rightmost bit needs to be data
    Shift one bit left, needs to be data[noparse][[/noparse] 4 ]
    ...
    MSB, left most bit, needs to be bit[noparse][[/noparse] 0 ]

    When i monitor for the signal, i decode the value, either 0 or 1, and set it in a variable respective to it's position. So the first data bit i recieve goes in data[noparse][[/noparse] 0 ] then data... and then data. The problem i'm having is that i can only process one bit value at a time when monitoring, but in the end i need the bit pattern in a single variable.

    I tried, like i said, this:

    SIGNAL := data[noparse][[/noparse]0..4]
    
    




    And the ".." is not allowed because it is not a register. But i do not know how to get the bit pattern stored in the array, in to one single variable.

    I think i might just have to use a formula. I.E. the MSB in a 5bit variable is x16, the next is x8, the next is x4 the next is x2 and the final is x1. So i could use a formula like this.

    SIGNAL := (data[noparse][[/noparse] 4 ]*16) + (data[noparse][[/noparse] 3 ]*8) + (data[noparse][[/noparse] 2 ]*4) + (data[noparse][[/noparse] 1 ]*2) + (data[noparse][[/noparse] 0 ]*1)
    
    




    That should give me a bit pattern stored in one variable.


    -Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
  • morris4019morris4019 Posts: 145
    edited 2009-06-05 19:27
    I found the problem. Its because, when viewed with serial terminal, the binary value was showing 1s and 0s, when in reality, 1 for a byte is actually 255. So the above code will work, except for the fact that before using the formula, data[noparse][[/noparse]x] needs to be changed to it's binary value of 1 or 0. Which is fine. Now that i've changed the forumal to the one above, i get consistent bit patterns every time. Also, the range on my beacon is staggering. Indoors in very high light (i havn't had a change to test it ouside yet), I tested the the beacon with the monitor app that i just made in our biggest room. 25ft with no problem, with only 1 IR LED emitting the signal. I might even need to add a higher resistor to cut the range down a bit.

    But more to come on this. I've made a drawing of what i will build the beacon in to. Using plexiglas to build a small cube (for the inards), and a smaller octagon on top. 4 sides of the octogon will contain 4 IR LEDs for multi-direction signal. Holes will be drilled in the remaining sides for future use of detectors. The next version will be able to talk back [noparse]:)[/noparse]

    -Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
  • morris4019morris4019 Posts: 145
    edited 2009-06-05 21:38
    MagIO2, that is the problem. I was not using "|" or the "& !" before the bitwise operator "|<", i did not really understand how to use it. Thank you for your explination, now it makes sense.

    -Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-06-05 22:09
    Instead of this:
    SIGNAL := (data[noparse][[/noparse] 4 ]*16) + (data[noparse][[/noparse] 3 ]*8) + (data[noparse][[/noparse] 2 ]*4) + (data[noparse][[/noparse] 1 ]*2) + (data[noparse][[/noparse] 0 ]*1)
    

    you could use

    SIGNAL := data[noparse][[/noparse] 4 ]<<4 + data[noparse][[/noparse] 3 ]<<3 + data[noparse][[/noparse] 2 ]<<2 + data[noparse][[/noparse] 1 ]<<1 + data[noparse][[/noparse] 0 ]
    

    A multiplication is slower than a shift.

    But why do you store the bits in an array and not directly in SIGNAL? Instead of

    data[noparse][[/noparse] currentBit ]:=whatever you monitor

    you can say

    if whateveryoumonitor

    · SIGNAL |= |<currentBit

    Of course you have to set SIGNAL to 0 if you start reading from bit 0 again.
  • hover1hover1 Posts: 1,929
    edited 2009-06-05 23:49
    MagIO2 said...
    Hi Morris!

    Your SIGNAL is a variable of a certain size. In case of long it has 32 bits, in case of word it has 16 bits, in case of byte it has 8 bits.
    If you want to initialize the SIGNAL you simply give a bit-pattern:

    SIGNAL := %00001111
    Please note, the bits on the left side are the Most Significant Bits (MSB). The bit following % is bit 7. This is very essential to know, because when you assign the SIGNAL to OUTA it can behave differently:
    OUTA[noparse][[/noparse]3..0]:=SIGNAL in this case will set pins 0 to 3 to 1 -> easy to understand: bits 4 to 7 of the SIGNAL are not needed
    OUTA[noparse][[/noparse]7..0]:=SIGNAL will set pins 0 to 3 to 1, pins 4 to 7 to 0 -> easy to unerstand: the OUTA range has the same size and order as the SIGNAL variable
    OUTA[noparse][[/noparse]0..7]:=SIGNAL will set pins 0 to 3·to 0, pins 4 to·7 to 1 -> OUTA range has the same size, but different order than the SIGNAL
    OUTA[noparse][[/noparse]7..4]:=SIGNAL will set pins 4 to 7 to 1·-> because in this case bit0 of SIGNAL will be copied to bit4 of OUTA

    If you now want to modify single bits you need·bit operations. The OR (bitwise or operator is '|') will set a bit and the NOT·AND (bitwise not = '!',·bitwise and = '&') will clear a bit. With the |< operator you can generate a number where exactly one bit is set at the place specified after the operator.

    |<1 will generate bit pattern %00000010 (as the bit number starts from 0)

    SIGNAL := %00001111
    SIGNAL := SIGNAL | |<1····· -> result: %00001111 as bit number 1 was already set
    SIGNAL := SIGNAL | |<5····· -> result: %00101111
    SIGNAL := SIGNAL & ! |<1·· ·-> result: %00101101
    SIGNAL := SIGNAL & ! |<4····-> result: %00101101 as bit number 4 was already cleared

    Did this answer your question?
    MagIO2
    This is such a·perfect explanation with great examples, I vote for inclusion in the Propeller Tips and Traps.
    OK Phil?

    Jim
  • morris4019morris4019 Posts: 145
    edited 2009-06-06 03:38
    MagIO2, perfect! That is ultimately what i was trying to do. I did not realize i could stack up the shifts in that way. With Signal |= |< i should be able store the bit pattern in one variable instaed of storing them in an array. It was had for me to explain what i needed to happen. That is why I figured that if i wrote out that formula everyone would get an idea of what i was trying to do. Thats a bunch, that tidys up the code a bunch.

    And your explanation IS a perfect example. I agree with hover1. Good on ya for those examples.

    [noparse]:)[/noparse]
    -Mike

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ======

    ······ I'll try everything once [noparse]:)[/noparse]
Sign In or Register to comment.