You many need to use an external circuit to clean-up the button bounce -- the trick with your program is that you're manually counting pulses from an external device with an ~8 ms period; by inserting debouncing code you will start missing counts.· You may want to consider that PCF8583 as an external counter I mentioned earlier; it may be a better solution for you to measure the period (accurately) between button presses.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Jon Williams Applications Engineer, Parallax
hmm.. bummer i figured it would be a easy solution. somehow the button is my problem tho. I hooked my counter up to another 555 timed at 3hz. and the numbers are much more steady. Only about a 7bpm difference between them. So somehow the button is making it very wack.
I dont know why, (prolly from my 555 timers inaccuracy) but I had to add 10 to my result to get the range in the proper BPM. Mabee this will be fixed with a crystal clock.
I dont know why, (prolly from my 555 timers inaccuracy) but I had to add 10 to my result to get the range in the proper BPM. Mabee this will be fixed with a crystal clock.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Jon Williams Applications Engineer, Parallax
Buttons are inherintly noisy.· The ticky part for you is that debouncing software takes a little more time than you have between raw input pulses.· If you use an external counter there will be a built-in delay while sending the message, so that will help -- you can go back to the non-debounced method to keep the code simple.
BPM said...
hmm.. bummer i figured it would be a easy solution. somehow the button is my problem tho. I hooked my counter up to another 555 timed at 3hz. and the numbers are much more steady. Only about a 7bpm difference between them. So somehow the button is making it very wack.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Jon Williams Applications Engineer, Parallax
Jon Williams (Parallax) said...
How do you figure (the 3600 part)? 120 Hz x 60 seconds (one minute) = 7200.
When I found out I questioned myself also.
But after calculating what my bpm SHOULD read, I found that it was double.
I ran the program like you wrote it.
My clock is 120hz.
My button click is hooked up to a 555 running at 3hz.
3 X 60 = 180BPM.
If you run the program with bpm = 7200 / pcount, your BPM will be around 80.
If you change it, the bpm will be correct (close to 180) (assuming you have exactly 3hz and 120hz)
Or this might be a result of me using DEBUG code.
Mabee its slowing the program down?
Heres a question.
How Do I NOT send the BPM back thru DEBUG? Is there a way to STORE it and send it in Bunches? Mabee this would prove if my debug is slow?
There is no problem with your BASIC Stamp being slow -- that should be abundantly clear by now.· Since you're sending the DEBUG output between measurement windows it's not affecting the count.
I'd say the *problem* is in your button pressing -- that's probably what's slow and is resulting in a higher-than-expected number.· Not that I got particularly scientific, mind you, but using the old "One thousand one, One thousand two..." counting between button presses always resulted in the correct value on every test.· Have you verified that your 120 Hz input is actually 120 Hz?· I had a scope to check my 555, but I also did this:
... and I got 122 (which is what my scope said as well) -- and this was close enough to test the code.· If you want to speed up your DEBUG output (again, it's NOT affecting the count routine -- unless you snuck a DEBUG output into the middle of it), just send the value:
· DEBUG DEC countHz, CR
This will print just the value without·the variable name (you know what you're looking at).
The lesson is you have to be very careful when you start "shotgun compensating" -- pretty soon nothing will work, nothing will match expectations, and ultimately you'll be left scratching your head wondering why.·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Jon Williams Applications Engineer, Parallax
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.
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.
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...
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.
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...
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.
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
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.
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
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.
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
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
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! [noparse]:)[/noparse]
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-segment·displays without worry.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ Jon Williams Applications Engineer, Parallax
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.
' {$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.
Jon Williams (Parallax) said...
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-segment displays without worry.
After trying to combine the two; my digit code, with the BPM calcualtion code, I see what you mean that the results will not be satisfying. I am having to call my Display Digits subroutine so many times thru the bpm count code, that it messes up the count. And the displays are still dim/flickering
I suppose this is where a latch comes in handy?
After looking at a latch-able 7-segment driver,HEF4511. I see what your saying about multiplexing. To use latching now, I need to add ANOTHER 5 pin outs to my monstrosity. (to drive a total of 3 4511's) (but what that many pinouts, latching, or blanking isn't needed)
But the latch doesn't help me with my flickering/dim displays, due to me using a 7 seg display (4 digits) that acually has common anodes, and common cathodes. (segments are tied together, all a's, b's. etc...) Each digit has its own common anode.
If I were using a display that had common anodes, and seperate cathodes for each digit, I would get away with using 3 4511's on the same 4 pin outs. Then I wouldn't need to blank each display, I would only need to latch each. Keeping me at my current 7 pin config.
BUT to use the 4511's I need a common cathode type display. I only have common anode. NEXT!
On to looking to see what I have for chips that match a 74HC595, or will I have the same issue using a common anode / common (segment) display type.
Is the only difference between a 74LS164 and 74HC595, basically a latch? Because I only have a bunch of 74LS164's
I am sure going to have some fun when more parts arrive. Allowing me to try out I2C, 1-wire, and 2-wire communications.
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
bpm = (3600 / pCount) + 10, NOT bpm = 7200 / pcount
I dont know why, (prolly from my 555 timers inaccuracy) but I had to add 10 to my result to get the range in the proper BPM. Mabee this will be fixed with a crystal clock.
try www.mouser.com also
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
When I found out I questioned myself also.
But after calculating what my bpm SHOULD read, I found that it was double.
I ran the program like you wrote it.
My clock is 120hz.
My button click is hooked up to a 555 running at 3hz.
3 X 60 = 180BPM.
If you run the program with bpm = 7200 / pcount, your BPM will be around 80.
If you change it, the bpm will be correct (close to 180) (assuming you have exactly 3hz and 120hz)
Or this might be a result of me using DEBUG code.
Mabee its slowing the program down?
Heres a question.
How Do I NOT send the BPM back thru DEBUG? Is there a way to STORE it and send it in Bunches? Mabee this would prove if my debug is slow?
I'd say the *problem* is in your button pressing -- that's probably what's slow and is resulting in a higher-than-expected number.· Not that I got particularly scientific, mind you, but using the old "One thousand one, One thousand two..." counting between button presses always resulted in the correct value on every test.· Have you verified that your 120 Hz input is actually 120 Hz?· I had a scope to check my 555, but I also did this:
· COUNT PulseIn, 1000, countHz
· DEBUG ? countHz
· END
... and I got 122 (which is what my scope said as well) -- and this was close enough to test the code.· If you want to speed up your DEBUG output (again, it's NOT affecting the count routine -- unless you snuck a DEBUG output into the middle of it), just send the value:
· DEBUG DEC countHz, CR
This will print just the value without·the variable name (you know what you're looking at).
The lesson is you have to be very careful when you start "shotgun compensating" -- pretty soon nothing will work, nothing will match expectations, and ultimately you'll be left scratching your head wondering why.·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
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
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.
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
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.
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. [noparse]:)[/noparse]
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
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.
digikey showed me a 0.027µF 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?
regards peter
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.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
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
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
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
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
I still dont understand what the HECK this says. LOL. But I am searching the help and slowly putting it together.
[noparse]:)[/noparse]
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
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! [noparse]:)[/noparse]
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Jon Williams
Applications Engineer, Parallax
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.
Obviously this method isn't efficient, or pin conserving, but it has taught me alot about displaying digits.
Its definely not efficient. uhhh dont ask why I included all that select case Smile.. LOL
This works exactly the same
After trying to combine the two; my digit code, with the BPM calcualtion code, I see what you mean that the results will not be satisfying. I am having to call my Display Digits subroutine so many times thru the bpm count code, that it messes up the count. And the displays are still dim/flickering
I suppose this is where a latch comes in handy?
After looking at a latch-able 7-segment driver,HEF4511. I see what your saying about multiplexing. To use latching now, I need to add ANOTHER 5 pin outs to my monstrosity. (to drive a total of 3 4511's) (but what that many pinouts, latching, or blanking isn't needed)
But the latch doesn't help me with my flickering/dim displays, due to me using a 7 seg display (4 digits) that acually has common anodes, and common cathodes. (segments are tied together, all a's, b's. etc...) Each digit has its own common anode.
If I were using a display that had common anodes, and seperate cathodes for each digit, I would get away with using 3 4511's on the same 4 pin outs. Then I wouldn't need to blank each display, I would only need to latch each. Keeping me at my current 7 pin config.
BUT to use the 4511's I need a common cathode type display. I only have common anode. NEXT!
On to looking to see what I have for chips that match a 74HC595, or will I have the same issue using a common anode / common (segment) display type.
Is the only difference between a 74LS164 and 74HC595, basically a latch? Because I only have a bunch of 74LS164's
I am sure going to have some fun when more parts arrive. Allowing me to try out I2C, 1-wire, and 2-wire communications.
Post Edited (BPM) : 6/30/2005 11:19:02 AM GMT