+ Reply to Thread
Page 3 of 4 FirstFirst 1234 LastLast
Results 41 to 60 of 64

Thread: Is there a way to count pulses (a steady 120hz) for a changing length of a butt

  1. #41

    Default

    I agree with Jon that the Stamp will be quite accurate in its counting, and the discrepancies you are seeing might be something in your 555 circuit or more likely in our collective misunderstanding of what you want to do.

    The existing routine counts for 1/2 of a cycle of your 555 input, whereas it looks to me that you probably want to count for a full cycle.

    Here is the existing subroutine:

    Count_Pulses:
    DO : LOOP UNTIL (Bttn = Pressed)
    DO : LOOP UNTIL (Bttn = Released)
    DO
    IF (Hz = 1) THEN
    pCount = pCount + 1
    DO : LOOP UNTIL (Hz = 0)
    ENDIF
    LOOP UNTIL (Bttn = Pressed)
    RETURN

    It starts counting when the button is "released" and stops counting when it is next "pressed". That is 1/2 cycle. And that may explain why you need 3600/pcount instead of 7200/pcount. Also, since 555 oscillators are usually not symmetrical output, more time in one state than the other, that 3600 would not be right on either, so that might explain your "+10".

    To count for the full cycle, you need something more like this:

    Count_Pulses:
    DO : LOOP UNTIL (Bttn = Pressed)
    DO : LOOP UNTIL (Bttn = Released)
    DO ' count the + half cycle
    IF (Hz = 1) THEN
    pCount = pCount + 1
    DO : LOOP UNTIL (Hz = 0)
    ENDIF
    LOOP UNTIL (Bttn = Pressed) ' until + half cycle ends
    DO ' then count the - half cycle
    IF (Hz = 1) THEN
    pCount = pCount + 1
    DO : LOOP UNTIL (Hz = 0)
    ENDIF
    LOOP UNTIL (Bttn = released) ' until it ends
    RETURN ' this should give the 7200/pcount=bpm

    That will have the effect of waiting until the button is pressed and released, then counting the + half cycle, then the - half cycle. The counting ends when the button is released a second time. The system then waits for the button to be pressed and released again before it starts counting. That is, the alternate program skips every other cycle of your 3hz button input.

    I'm puzzled why your experiment yielded such scattered reults. Was that also from the 3hz 555 oscillator, or was it from a real finger pressing a button? The 555 should not bounce. If it is a real pushbutton, you can deal with that using an RC circuit in parallel with the button, or by a software test outside the main counting loop, where it will not limit your counting speed.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  2. #42

    Default

    ok. Ran this code to verify HZ

    COUNT PulseIn, 1000, countHz
    DEBUG ? countHz
    END

    My results.
    Heres my 555 BUTTON simulator.
    countHz = 4
    countHz = 5
    countHz = 5
    countHz = 5
    countHz = 5
    countHz = 5
    countHz = 5
    I then swapped pins to measure 120hz....
    countHz = 120
    countHz = 120
    countHz = 120
    countHz = 120
    countHz = 120
    countHz = 120
    countHz = 120
    countHz = 120
    countHz = 120
    countHz = 119
    countHz = 119

    I then used this code, file attached.
    This is NOT MODIFIED, from you.

    My results are this

    Press button. Wait. Press again.
    Count = 12
    BPM = 600

    The BPM is double, for 5hz.
    5 X 60 = 300. BPM.

    So then I changed ONLY ONE THING in the code.
    this: bpm = 7200 / pCount
    to this: bpm = 3600 / pCount

    My results are:

    Press button. Wait. Press again.
    Count = 12
    BPM = 300

    If you still say that 7200 is correct. I beg of you to teach me why. I am not being mean here, just learning, trying to understand everything that is being put out here.
    Attached Files Attached Files
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  3. #43

    Default

    Tracy Allen said...

    The existing routine counts for 1/2 of a cycle of your 555 input, whereas it looks to me that you probably want to count for a full cycle.

    It starts counting when the button is "released" and stops counting when it is next "pressed". That is 1/2 cycle. And that may explain why you need 3600/pcount instead of 7200/pcount. Also, since 555 oscillators are usually not symmetrical output, more time in one state than the other, that 3600 would not be right on either, so that might explain your "+10".

    That will have the effect of waiting until the button is pressed and released, then counting the + half cycle, then the - half cycle. The counting ends when the button is released a second time. The system then waits for the button to be pressed and released again before it starts counting. That is, the alternate program skips every other cycle of your 3hz button input.

    I'm puzzled why your experiment yielded such scattered reults. Was that also from the 3hz 555 oscillator, or was it from a real finger pressing a button? The 555 should not bounce. If it is a real pushbutton, you can deal with that using an RC circuit in parallel with the button, or by a software test outside the main counting loop, where it will not limit your counting speed.
    The one that had VERY scattered results was an acutal button. And I will havta deal with the bounce issue in circuit I guess. You say it can be dealt with OUTSIDE the main counting loop.? I would imagine that any software that will deal with my bouncing button, will affect the counting.? Due to the BUTTON command using up time to do its work?

    So wait. This program, it only counts from LAST BUTTON RELEASE to NEXT BUTTON PRESS?
    So I am acutally loosing some timing in there.?
    If I need to count every hz, then I need to reprogram it to count from LAST BUTTON RELEASE to NEXT BUTTON RELEASE right? Or is that what you had just said? LOL.. and gave me the program for... heh...

    Post Edited (BPM) : 6/28/2005 5:15:49 AM GMT
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  4. #44

    Default

    after reading your code, and message a few more times, you did say that. GREAT! so thats why I was all wack! I didn't realize the code wasn't counting for the full cycle button release to button release. (I am not that good at understanding programs yet)

    I do havta say, after being "all about hardware" I am pushed into the software realm without the EDGE that is associated with learning a language.
    I love it, what a great way to help teach microprocessors and programming.
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  5. #45

    Default

    I tried out your code tracy, and it works without me changing the 7200. GREAT, (now I get to compare the two codes and learn exactly what is going on between them heh)

    I thank you very much for all your help, you too Jon!

    I have attached the working code.

    Heres my results after a bit more design tweaking.
    I raised the HZ to 240. Hoping for a bit more accuracy on counting. Not sure if it will help.
    And obviously I changed the divisor to 14400.
    I know I still need a debouncer...

    BPM = 123
    BPM = 129
    BPM = 124
    BPM = 126
    BPM = 133
    BPM = 129
    BPM = 128
    BPM = 133
    BPM = 123
    BPM = 129
    BPM = 124
    BPM = 127
    BPM = 127
    BPM = 124
    BPM = 128
    BPM = 120
    BPM = 126
    BPM = 119
    BPM = 125
    BPM = 129
    BPM = 128
    BPM = 127
    BPM = 126
    BPM = 125
    BPM = 138
    BPM = 129

    But thats pretty good!

    I am guessing my target bpm was 128.
    Testing this with a steady, 4hz signal, resulted in the following.
    The average being 240. :)
    BPM = 240
    BPM = 236
    BPM = 236
    BPM = 244
    BPM = 240
    BPM = 240
    BPM = 236
    BPM = 236
    BPM = 236
    BPM = 244
    BPM = 240
    BPM = 236
    BPM = 240
    BPM = 240
    BPM = 240
    BPM = 244
    BPM = 240
    BPM = 240
    BPM = 240
    BPM = 236
    BPM = 236
    BPM = 236
    BPM = 244
    BPM = 240
    BPM = 240
    BPM = 240
    BPM = 240
    BPM = 236
    BPM = 240
    BPM = 240
    Attached Files Attached Files
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  6. #46

    Default

    Now mabee I should actually build the BO-BOT, I have the kit... Just didn't do it. Heh, I had other evil plans in mind for my stamp2 (like a BPM tool)
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  7. #47

    Default

    I would like to continue on the BPM, but the next step i think is to debounce the button. and I need an external circuit for that?
    Then I need to display the bpm (external circuit)
    etc.. I must wait for my stuff to get here.
    Then comes the issue of me only having a BS2.
    My external circuits prolly require some elaborate subroutine to communicate to them. Untill the parts get here I guess I can't do much.
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  8. #48

    Default

    I searched for PCF8483 on BOTH mouser.com and digikey and NO parts were found that describe some kind of counter.

    digikey showed me a 0.027F capacitor when searching on "PCF 8483"
    and nothing when searching on "PCF8483"

    mouser showed 4 semiconductor results...
    two were RS-485/422 Interface ICs
    one was a 4-BIT BIN FULL ADDER
    and the other was a Driver IC.

    The ever elusive PCF8483 hunt continues!

    could I debounce with SCHMITT TRIGGER LOGIC?
    Or some other way?
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  9. #49

    Default

    The part mentioned was pcf8583.

    regards peter
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  10. #50

    Default

    Thanks for the corrected part #
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  11. #51

    Default

    Can you define for me what you mean by beats-per-minute? When I run your code I get exactly double what I think I should, though looking at you code the results are correct (though not matching my input).
    If I press the button every six seconds is this not 10 beats per minute? When I run your code as is I get 20 if there is six seconds between button presses.
    There will be a treshold where the instruction cycle won't be able to keep up with your input; I'd suggest that 120 Hz is probably pretty close to it in high-level PBASIC. Of course, if you port this over to the SX using SX/B then it's a different story ... though SX/B does not offer th convenience of 16-bit math.

    BPM said...
    I tried out your code tracy, and it works without me changing the 7200. GREAT, (now I get to compare the two codes and learn exactly what is going on between them heh)

    I thank you very much for all your help, you too Jon!

    I have attached the working code.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  12. #52

    Default

    Yeh, counting for 6 seconds with an input of 240 hz should yield 6*240=1440 counts. And 14400/1440 = 10 beats per minute. I don't see offhand where the discrepancy lies in the setup wrt BPM's result.

    I think the limit for count frequency with this routine may go as high as 300 hertz even with a BS2.
    There is still some optimization that could be applied. For example, the statement
    LOOP UNTIL (startBtn=pressed) ' pressed defined as =0
    is within the loop and the loop will run significantly faster with
    LOOP WHILE startBtn ' loop while startBtn=1, using WHILE construct and leaving off the =
    Less transparent for self documentation, granted, but faster.
    If I get a chance I'll run a little test to compare techniques, how fast they can go.

    BPM could get an extra decimal point in the result, using the formula,
    BPM = 14400/pcount *10 + (14400//pcount * 10 / pcount)
    debug dec BPM/10,".",dec1 BPM

    that gives one extra decimal point over simply
    BPM = 14400/pcount
    e.g., 10.3 BPM instead of 10.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  13. #53

    Default

    I misse the part where he changed to 240 Hz... I think I'll bow out of this thread; I don't seem to be smart enough to understand what's wanted or contribute anything useful.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  14. #54

    Default

    Please don't bow out, Jon . No one here will ever attribute to you a lack of smarts! Quite quite the contrary. The problem goal under consideration is ambiguous and developing, so there is a lot of second guessing going on.

    I did test the attached program, which has three possible methods around a #SELECT#CASE directive. It counts square wave on p0 during a 1 second interval that p1 is high. (The p1 1 second high gating signal is generated by a second Stamp, and the p0 frequency input to be counted is generated by an Extech process calibrator.)


    Method 1: The BS2pe counted without error up to 400 hertz but failed at 480 hertz. On a BS2p, it counted up to 800 hertz, but failed at 1200. (The Extech calibrater has only discrete steps, with nothing between 400 and 480 nor between 800 and 1200).

    Method 2: This is code optimized method 1, using the LOOP WHILE startBtn instead of LOOP UNTIL (startBtn=pressed) within the main loop. On a BS2pe that could count up to 800 hertz without error and on a BS2p up to 1200 hertz.

    Method 3: This is the code using XOR bit manipulation I posted earlier, but with the same optimization as method 2. On the BS2pe it counted ccorrectly up to 400 hertz, and on a BS2p, ujp to 800 hertz. So it is indeed slower than Jon's approach with the IF-THEN logic. I still like this method, because it is less modal, and thus easier to add additional parallel processing.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Tracy Allen
    www.emesystems.com
    Attached Files Attached Files
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  15. #55

    Default

    Jon Williams (Parallax) said...
    I misse the part where he changed to 240 Hz... I think I'll bow out of this thread; I don't seem to be smart enough to understand what's wanted or contribute anything useful.

    LOL you not smart?

    The problem is, I am constantly changing my parameters and requirements. And I am asking multiple questions one after another.
    I am being very confusing, and I appologise for it.


    For instance, I am learning how to drive a dual 7seg display using a 74LS47. (stamp2 ----> BCD(with common anode lines) -----> 74ls47 ----> 7segment)
    I have searched and found your code

    Code:
    Pins = decVal / 10 * 16
    Pins = decVal // 10 | Pins



    I still dont understand what the HECK this says. LOL. But I am searching the help and slowly putting it together.
    :)
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  16. #56

    Default

    To start with, that code you reference is for the BS1 (I can tell because PINS is a BS1 reserved word). But let me see if I can explain because you can sustitute OUTH (P8..P15) on the BS2, like this:

    OUTD = decVal / 10
    OUTC = decVal // 10

    The first line divides decVal by 10, so the 10s digit gets output to OUTD (P12..P15, which would connect to your 74LS47 pins A..D). The second line uses the modulus (//) operator which returns the remainder of a division. Let's say that decVal is 25: 25 dvidied by 10 is 2, with 5 left over (remainder). So 5 (%0101) would be output OUTC (P8..P11).

    That said, it's actually easier with the BS2's DIG opertor -- it returns the digit in the specific position of a number. So you can do this:

    OUTD = bpm DIG 1 ' get 10s (101) digit
    OUTC = bpm DIG 0 ' get 1s (100)digit

    But didn't you say somewhere you wanted three digits? If yes and you can squeeze your Hz input and button(s) into P0..P3, then you can use the OUTB, OUTC, and OUTD pin groups like this:

    OUTD = bpm DIG 2 ' get 100s (102)digit
    OUTC = bpm DIG 1 ' get 10s (101) digit
    OUTB = bpm DIG 0 ' get 1s (100)digit

    Make sense?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  17. #57

    Default

    GREAT it makes 100% sense!

    I can see where having an I2C device to decode the digits comes in handy now. Just 3 digits and I am already using 75% of my out pins.

    If I have digit displays that have common anodes, couldn't I use the same 4 out pins for all 3 digits(74ls47 inputs), and then just use 3 more pins to BLANK the other digits, then flashing the digit that I am sending to my output?

    So, send number to all 3 74ls47's, but two of the 47's keep BLANK on. And the other 47 turn it off.
    And so on for the other two digits.

    OUTB = bpm DIG getDig ' get digit 0, 1, 2 (i would use a, For getDig = 0 to 3)
    OUTC = blank DIG blankDig 'get blank mode of 3 digits, 000, or 111. But if I do this, it will convert the digit to BCD, So I need to figure out which BCD numbers will send the proper blank signals. Easy...

    This way I am still using alot, but now 7 pins for 3 digits. I am sure theres some catch to doing this tho, and look forward to your reply! :)
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  18. #58

    Default

    To share the outputs with multiple 47s you end up multiplexing -- not easy to do in PBASIC and the results will not be satisfying. I would use three 74HC595 output shift registers that are daisy-chained. With three pins and a few lines of code you would end up with 24 additional digital outputs, enough to handle your 7-segmentdisplays without worry.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Jon Williams
    Applications Engineer, Parallax
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  19. #59

    Default

    Tell me what you think of this. It works really good. It uses 1 - 74ls47. And 3 transistors. (1 for each common anode).
    To add any number of digits, only requires 1 additional line per digit. (so 1 transistor, and one pinout per digit)

    Using this method, you could drive up to 12 digits? (with no leftover pins)
    I don't have any artifacts or shadow in any of my digits AT ALL! (in total darkness)
    To blank each digit, I cut off the power to the digit using the transistor.

    Actually I am amazed at how easy it is to add more digits.

    But at the same time, this 3 digit 7-segment BCD out display takes up 7 pins.

    Code:
    ' {$STAMP BS2}
    ' {$PBASIC 2.5}
    
    number    VAR    Word
    digit     VAR    Word
    
    
    DIRS = %1111111
    
    Main:
    
    number = 159
    
    DO
      FOR digit = 0 TO 2
          SELECT digit
    
          CASE 0
            OUTB = 000                 ' blank all displays
            OUTA = number DIG digit    ' load 1's digit in 74ls47
            OUTB = 001                 ' turn on 1's display.
    
          CASE 1
            OUTB = 000                 ' blank all displays
            OUTA = number DIG digit    ' load 10's digit in 74ls47
            OUTB = 010                 ' turn on 10's display.
    
          CASE 2
            OUTB = 000                 ' blank all displays
            OUTA = number DIG digit    ' load 100's digit in 74ls47
            OUTB = 100                 ' turn on 100's display.
    
          ENDSELECT
      NEXT
    LOOP



    Obviously this method isn't efficient, or pin conserving, but it has taught me alot about displaying digits.
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

  20. #60

    Default

    I am sure your laughing at that....
    Its definely not efficient. uhhh dont ask why I included all that select case crap.. LOL

    This works exactly the same

    Code:
    Display_Digits:
    
            OUTA = bpm DIG 0           ' load 1's digit in 74ls47
            OUTB = 001                 ' turn on 1's display.
            PAUSE 1                    ' let em burn!
            OUTB = 000                 ' blank all displays
    
            OUTA = bpm DIG 1           ' load 10's digit in 74ls47
            OUTB = 010                 ' turn on 10's display.
            PAUSE 1                    ' let em burn!
            OUTB = 000                 ' blank all displays
    
            OUTA = bpm DIG 2           ' load 100's digit in 74ls47
            OUTB = 100                 ' turn on 100's display.
            PAUSE 1                    ' let em burn!
            OUTB = 000                 ' blank all displays
    
    RETURN
    Last edited by ForumTools; 09-30-2010 at 10:07 AM. Reason: Forum Migration

+ Reply to Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts