RPM

RubiksRune

New Member
I have made a generator/motor, with a rotating disc. on the disc I have
a white line that reflex the IR on the OPB715 IR reflex detector.
I now want to use my picaxe 40x1 to find the RPM.

I thougt of using the pulsin command, when the white line crosses the IR
detector, the pulsin starts measuring.when the disc have rotated, and
the white line crosses again, the pulsin stops. and lets say that the disc
used 0,5sec. I then take 60/0,5=120, the RPM is then 120.

but I got some trouble with programming it. Anyone have a suggestion?
or maybe a better way of doing it. thanx anyway.
 

westaust55

Moderator
Rather than lots of maths with divisions and possible error, try the COUNT command for exactly 1 second.

COUNT pin, 1000, wordvariable

then variable * 60 = rpm
 

westaust55

Moderator
Thinking further, what is the rpm of the disk?
If we are talking about very slow shaft speeds such as around 1 to 100 rpm then pulsin might be better.

If the rpm will be in several hundreds or thousands of revs per minute then COUNT is the recommended way to go.
 
Last edited:

RubiksRune

New Member
The RPM of the motor will be something like 200-500RPM
The IR reflex sensor gives out 0-255. 0 when nothing is reflected, and 255 when reflected.
This is the program I have so far. A LED blinks everytime the disc rotates. so my problem
is to get the count/pulsin command to the program. can I take the count command right on the ADC0 input?


Code:
main:
	debug
	
	readadc 0,b1		          'IR reflex sensor
	
	if b1 < 150 then
	low 7				'LED off
	endif
	
	if b1 > 150 then
	high 7		            	'LED on
	endif
	
	goto main
 

gbrusseau

Senior Member
When the sensor is reflecting the light from a white object, the output is high. (from datasheet). Therefore the PULSIN command SHOULD BE triggering on the sensor output going low (trailing edge of the white line) and when the PULSIN command sees the sensor output going high (leading edge of the white line), that would be one complete revolution of the disc.
example: PULSIN 1,0,W1

This post was before I read your last post RubiksRune.
This sensor has a digital on/off output, not analog as you are suggesting. On/high when reflecting light and off/low when not. No ADC is required to read the output.
 
Last edited:

RubiksRune

New Member
your right, the sensor is digital! when I use the code with only the LED, the LED blinks on every reflection, but when I add count or pulsin, its like the Picaxe laggs, the LED blinks slowly, even without the debug meny running.

anyhow, I tryed the count,1,1000,w1, as u suggested westaust55, and w1*60. but i only got readings like 60,120,300. thats the RPM,tho its a bit big gap,no reading inbetween, not so precise reading, could it be due to the lagging?

I also tryed the pulsin. here I got a better reading's "update time" in the debug meny. if you know what I meen, the numbers never stood still. but the numbers varying from 0-65535, so I somehow got to make that number, to ms. and then to RPM.
 

eclectic

Moderator
@RubiksRune.

If your sensor is connected to input1, then
please try this code
and see what happens

Code:
main:

count 1, 1000, w1

sertxd (#w1,cr,lf)

pause 1000 

goto main
e
 
Last edited:

BCJKiwi

Senior Member
Also been working on an RPM meter.

The criteria for deciding on count vs pulsin seem to be;
1. The rpm range
2. the rate of updating required
3. Will it to work 'out of the box' or is calibrating/tweaking OK?

I was looking for a range of 0 through 2500 rpm.

The issues I found;
Pulsin
A single target of 15degrees out of 360 will produce a pulsin value of;
100 at 2500 rpm
50000 at 5 rpm
The program needs to know if it's 15 degress (or whatever) when calculating the rpm and should be checked against a known speed - i.e. calibrated. This angle can easily change depending on the position of sensor and target. e.g. with a hall effect sensor and magnet the effective pulse length will vary with the strength of magnet and the distance between them.

Count
A single target will provide (per second) 41.66' counts at 2500 rpm and 3.33' at 200rpm
However adding further targets increases the count;
24 targets provide (per second) 2 counts at 5rpm an 1000 counts at 2500 rpm.
No calibration required.

Decided on a photo-interrupter and slotted disk with 24 slots.
This (for me) was simpler to construct than the pulsin setup, does not depend on mounting accuracy and requires no calibration.

the code;
Code:
'####################################################################################
'# PICAXE 28X1  fw A.2,  SAA1064 7 Seg Driver             #
'####################################################################################
'
#picaxe 28x1
SetFreq m8
'
'####################################################################################
'# EEPROM use - 0 to 255 available 'STATIC VALUES            #
'####################################################################################
'
'RPM Bit Patterns - I/O Exp 0
' 7 Segment Display
'   b0
eeprom 0,(%00111111)    '0 RPM
eeprom 1,(%00000110)    '1 RPM
eeprom 2,(%01011011)    '2 RPM
eeprom 3,(%01001111)    '3 RPM
eeprom 4,(%01100110)    '4 RPM
eeprom 5,(%01101101)    '5 RPM
eeprom 6,(%01111101)    '6 RPM
eeprom 7,(%00000111)    '7 RPM
eeprom 8,(%01111111)    '8 RPM
eeprom 9,(%01101111)    '9 RPM
'          .gfedcba      
'
eeprom 10,(%10111111)   '0 RPM + DP
eeprom 11,(%10000110)   '1 RPM + DP
eeprom 12,(%11011011)   '2 RPM + DP
eeprom 13,(%11001111)   '3 RPM + DP
eeprom 14,(%11100110)   '4 RPM + DP
eeprom 15,(%11101101)   '5 RPM + DP
eeprom 16,(%11111101)   '6 RPM + DP
eeprom 17,(%10000111)   '7 RPM + DP
eeprom 18,(%11111111)   '8 RPM + DP
eeprom 19,(%11101111)   '9 RPM + DP
'           .gfedcba
eeprom 20,(%00000000)   'all digits OFF     
'
'####################################################################################
'# SYMBOL ASSIGNMENTS                     #
'####################################################################################
'
symbol SAA1064  = %01110000   '7Seg display - SAA1064 7Seg LED Driver i2c WRITE address
symbol L_Count  = 1     'in1 == Lathe count input
symbol Count_In = w2     ;Input Count value
symbol FIFO_1  = w3     'FIFO accumulator
symbol FIFO_2  = w4     'FIFO accumulator
symbol FIFO_3  = w5     'FIFO accumulator
symbol FIFO_4  = w6     'FIFO accumulator
symbol FIFOAVE  = w7     'Average of FIFO Accumulator
symbol ThoD   = b16     'w8 Thousands Digit 
symbol HunD      = b17     'w8 Hundreds Digit
symbol TenD   = b18     'w9 Tens Digit 
symbol OneD      = b19     'w9 Ones Digit
symbol RPM   = w10     'Average from Accumulator converted to RPM
'
'####################################################################################
'# Initialise                        #
'####################################################################################
'
Init:
'
'SAA1064
 hi2csetup i2cmaster,SAA1064,i2cslow_16,i2cbyte
 hi2cout (%00000000,%00101111)
'   write control , 0,0,6mA,0,Test,NoBlank,NoBlank,Dynamic
'   Instruction , Control
 pause 500
 hi2cout (%00000000,%00100111)
'   write control , 0,0,6mA,0,NoTest,NoBlank,NoBlank,Dynamic
'   Instruction , Control
 pause 500
 hi2cout (%00000000,%00101111)
'   write control , 0,0,6mA,0,Test,NoBlank,NoBlank,Dynamic
'   Instruction , Control
 pause 500
 hi2cout (%00000000,%00100111)
'   write control , 0,0,6mA,0,NoTest,NoBlank,NoBlank,Dynamic
'   Instruction , Control
 hi2cout (%00000001,%00000000,%00000000,%00000000,%00000000)
'   write Digit1, all off , all off , all off , all off
'   Instruction , Digit 1 , Digit 2 , Digit 3 , Digit 4
'
'
'#################################################################################
Main: 
'#################################################################################
' 
'
 Count L_Count, 1000, Count_In  ;Period 1000 = 1/2 second at 8MHz clock
 gosub Accumulator
 If Count_In < 2 then     ;remove spurious counts when stationary
  RPM = 0
 Else
  RPM = FIFOAVE * 5 / 12    '*5 for 500 counts == 2500rpm
            ' /12 as FIFOAVE = 12 times actual count
 EndIf
'
;RPM represents range from 0 to ~ 2500 RPM.
If RPM > 999 then
 ThoD = RPM DIG 3 + 10    ;Thousands +10 to show dp as 1000s indicator
 HunD = RPM DIG 2      ;Hundreds
 TenD = RPM DIG 1      ;Tens
 OneD = RPM DIG 0      ;Ones
ElseIf RPM > 99 Then
 ThoD = 20        ;Thousands == Blank
 HunD = RPM DIG 2      ;Hundreds
 TenD = RPM DIG 1      ;Tens
 OneD = RPM DIG 0      ;Ones
ElseIf RPM > 9 Then
 ThoD = 20        ;Thousands == Blank
 HunD = 20        ;Hundreds == Blank
 TenD = RPM DIG 1      ;Tens
 OneD = RPM DIG 0      ;Ones
Else
 ThoD = 20        ;Thousands == Blank
 HunD = 20        ;Hundreds == Blank
 TenD = 20        ;Tens == Blank
 OneD = RPM DIG 0      ;Ones
EndIf 
Read ThoD, ThoD       ;get bit pattern for LED from EEPROM
Read HunD, HunD       ;get bit pattern for LED from EEPROM
Read TenD, TenD       ;get bit pattern for LED from EEPROM
Read OneD, OneD       ;get bit pattern for LED from EEPROM
 hi2cout (%00000001,ThoD,HunD,TenD,OneD) 'SAA1064 Digit one = MSD= Left side
 
Goto Main         'Loop for continuous display
End
'
Accumulator:
'Sum the last 4 Count values to smooth output
'* 3 to improve resolution
FIFO_1 = FIFO_2
FIFO_2 = FIFO_3
FIFO_3 = FIFO_4
FIFO_4 = Count_In * 3
FIFOAVE = FIFO_1 + FIFO_2 + FIFO_3 + FIFO_4 '12 * Average last 4 Readings
'
Return
'
 
Last edited:

westaust55

Moderator
Im using number 2. but maybe its better to use number 3 to get 50% duty cycle? equal on-off time.
If you use diagram 1 that eclectic gave then only multiply by 30 (instead of 60) you will get slightly better resolution. A "+" will give 4 counts and then multiply by 15 instead. 8 makes and multiply 75 and divided by 10 (= divide by 7.5)

Okay we know the speed range which is relatively low so roughly the best accuracy with 4 makes as a "+" will be about 15 rpm steps, or with 8 marks about 7 rpm steps.

If you need better than that, you will need to think about how many marks you can have or have a white sector as BCJKiwi describes and use the PULSIN command.
 

RubiksRune

New Member
I don't got a protoboard, im using a breadboard. the pulsin command was more complicated then I expected, with all the thing BCJkiwi describes. I don't need it to be THAT good. lol. I just tried with the "+" markes as u suggested westaust55, and multiplied with 15, and it worked just fine!:D and as you say, I can add or subtract the numbers of marks to get a better result.
 

westaust55

Moderator
Detecting/Calculating rpm

I don't got a protoboard, im using a breadboard. the pulsin command was more complicated then I expected, with all the thing BCJkiwi describes. I don't need it to be THAT good. lol. I just tried with the "+" markes as u suggested westaust55, and multiplied with 15, and it worked just fine!:D and as you say, I can add or subtract the numbers of marks to get a better result.
Great to see that you have it working to your satisfaction. :)
 

Skygeorge

New Member
@RubiksRune.

If your sensor is connected to input1, then
please try this code
and see what happens

Code:
main:

count 1, 1000, w1

sertxd (#w1,cr,lf)

pause 1000 
goto main
e
Hi,

I have try in Programmeditor to simulate the above mentioned suggestion.
I have try to give pulses pushing the button1(input1) but the button was inactive ,the w1 was every time 0.why? As I have given through generic a value to b2 ,I have numbers received 50,100... etc. What is happen with this command COUNT, i have try the time to change .... nothing .
Can me anyone help?

Thanks
 

SilentScreamer

Senior Member
You're only counting for one second then pausing for a second if the button is pressed during the time it is paused it won't be counted. Also where is the push switch connected to? Is it input pin 1 (that is NOT leg one).
 

Skygeorge

New Member
@Skygeorge

Welcome to the Forum.

Did you press the

>>

button?

e
First of all Thank you for your response.
I have used 08M .
The Code :

main:
count 3,1000,w1 ( count pulses in 3, for 1sec,write the number on w1)
pause 1000
if w1=0 then main ( I want to see w1<>0 it means 3button give pulses

high 4 ( if w1<>0 the output 4 should be become green)
pause 2000
low 4
goto main

the Editor ( photo no2) has 4 buttons (1,2,3,4) during the programm i have button 3 pushed more times in order to create minimum one pulse so that the high 4 to come in ON situatation, nothing. All four buttons have no reaction.
After that I pushed button Generic >> and b2 has the value 50 (it means w1>0 ) and the 4 button is hell high and after low.
I would like to measure the pulses of a read switch and in 10nth pulse to execute a subroutine ( how with the COUNT command)?

Thanks
 

hippy

Ex-Staff (retired)
@ Skygeorge : When simulating, all values for COUNT are taken from the "Generic" entry field. Pressing the input pins will have no affect. Adjust the value in "Generic" to set the value you want COUNT to use.
 

Skygeorge

New Member
@ Skygeorge : When simulating, all values for COUNT are taken from the "Generic" entry field. Pressing the input pins will have no affect. Adjust the value in "Generic" to set the value you want COUNT to use.
Hippy! thank you for your answer .

The Generic set his value ( 50,100....) by pressing it, how is possible to set my values?
What mines this value (50,100,...) 50pulses, 100pulses, set the generic as w1 value these numbers?



Thank you
 
Last edited:

hippy

Ex-Staff (retired)
Whatever you enter into the Generic text field will be stored to your variable whenever the COUNT command executes.
 
Top