How to measure pulse duty cycle

binary1248

Senior Member
I need a few clues on this. It is a motorcycle tach taping into the control signal to the ignition circuit.
I will do the necessary signal conditioning to make the pulse PixAxe input freindly.
I just need some starting info on how to measure the duty cycle of the pulse.
Pulse is 1 ms wide
Duty cycle will range fro 120 ms to 12 ms where the 120 ms is idle and 12 ms is max (about 5000 rpm)
After measuring the duty cycle I can do the math to massage and convert it to a servo pulse control
The servo will be the analog readout (very small tach face).
Now the servo control and math is no problem for me, but the measuring the incoming pulse duty cycle, well just get me started and I can figure it out.
.
.
I have both 08m2 parts and 40X2 parts in my home lab.
Many thanks guys & girls.
Paul
 

Goeytex

Senior Member
Pulsin should do the job fairly well. One thing you might run into is that Pulsin WILL timeout and return a zero value at very low RPM.

With many ignitions systems, the pulse on time and pulse off time are proportional. Therefore only one value is needed in order calculate the other. In other words the duty cycle is fixed and never changes. However, if the ignition sensor pulse is conditioned and run through logic gates or a "one-shot" the duty cycle after the conditioning might change.

This can be easily tested with a simple program where pulsin measures the on time and then measures the off time. Add the two together and you have the time it takes for x number of revolutions, depending upon how many pulses are generated per engine revolution.

In my 4-stroke 2 cylinder racing engines there is one pulse per revolution (wasted spark type). The flywheel magnet takes up about 10 percent of the circumference of the flywheel. So if I measure the time that the magnet is passing the sensor and multiply that by 10, I get the time for one complete engine revolution. I have used this method with a Picaxe for both a tach/rev limiter and a Picaxe based ignition system with a programmable timing curve.

You "COULD" measure the time that the magnet is not passing the sensor, and in this case the time for one revolution would be Pulsin value / 9. The problem here is that the pulsin value cannot exceed 65534 or pulsin will overflow. If you are using the Picaxe at 4 Mhz then there will be 10 us per pulsin unit. 65543 units = 655430 us or 65.5 ms ms for one revolution is as slow as it can read. That is about 915 RPM.

I have found it much more practical to measure the sensor active time (mark) than the non active time (space). I have also found that 16Mhz generally gives better accuracy/resolution.
 
Last edited:

premelec

Senior Member
I suggest RC filtering at PICAXE input - R*C = .5ms or so- could be noisy environment [that's C from input to V- and R in series with tach signal].
 

binary1248

Senior Member
The motorcycle is a late model Harley with fuel injection and electronic ignition control The ignition pulse is a constant 1 ms wide (negative going, +12 to ground) and when it switches off (goes high) it has a terrible overshoot of about 60 volts which is typical of inductive loads.
It also fires the plug only on the power stroke, not the power and exhaust stroke like most small magento engines.
Yes, I will have to signal condition it to kill the overshoot and not load the ignition pulse. But that is something I had to do in my years of data acquisition work, signals we had to work with in the industry were often really ragged and even dangerous at times. So the signal conditioning and protection is easy for me.

Thanks for the inputs.
.Here is a scope image showing the nasty spike. The vertical is 10 volts per division, horz is 1 ms per div, 0 volts is the light line near the bottom of the posted screen shot..
NewFile4.jpg
 
Last edited:

binary1248

Senior Member
Correction to the above ignition firing, it is one pulse per revolution. I went back and studied my scope readings and realized I figured wrong.
This is at idle (about 500 rpm) the pulses are 120 ms apart which is 8.3 hz or 500 rpm. I need to check my math better.
.
NewFile6.jpg
 
Last edited:

binary1248

Senior Member
Goeytex, you are right in that I need to measure the time between pulses, as the pulse width stays the same at all rpm's. So I will have to work something else out if the pulsin overflows and returns zero. It is late and I am having brain malfunction so tomorrow I will review the math again.
Many thanks for the input.
Paul
 

Goeytex

Senior Member
It seems to me that on a late model Harley that the coil trigger signal would be a relatively clean pulse coming from the ECM that triggers an IGBT (or something similar) inside the coil.

What Model Harley? .... Is the ignition stock or aftermarket ?
 

binary1248

Senior Member
It seems to me that on a late model Harley that the coil trigger signal would be a relatively clean pulse coming from the ECM that triggers an IGBT (or something similar) inside the coil.

What Model Harley? .... Is the ignition stock or aftermarket ?
It is a 2009 crossbones 1600 cc, and it is the stock ignition system, so I was also surprised and wondered how they were driving this, in what appears to be an ignition (dual) coil from the ECM box. I would guess (and only guess) it is a very high voltage FET of some sort since it does not appear to have any spike suppression. I would really like to know the details of the ECM unit,
 

Goeytex

Senior Member
Are you getting the signal from the ECM ( coil front or coil rear) or from the crank position sensor? I would try getting the signal from either "coil front" or "coil rear" at the ECM connector. Wiring diagrams . The crossbones ignition should be the same as the 2009 Dyna Glide so that disgram could be a good reference.

I made a Picaxe "Tach Adaptor" that allows the use of an inexpensive automotive tach by converting the single ignition pulse to two pulses. This works very well with cheap Sunpro Tachs.

Condition the ignition/coil signal so that it it Picaxe friendly. The signal pulse triggers an interrupt. The interrupt routine then generates two 1 ms pulses on an I/0 pin with 1 ms between the pulses. This I/O pin can then directly drive the input to the Sunpro tach that is set for 4 cyl.


Good Luck
 

binary1248

Senior Member
Are you getting the signal from the ECM ( coil front or coil rear) or from the crank position sensor? I would try getting the signal from either "coil front" or "coil rear" at the ECM connector. Wiring diagrams . The crossbones ignition should be the same as the 2009 Dyna Glide so that disgram could be a good reference.
It is the signal from the ECM to the coil unit and I am using the rear. I thought about using the crank sensor but as I understand it the crank sensor senses a gear that has one tooth missing, so you get a lot of pulses then one missing. Using the crank sensor would probably be a clean signal, but I would need to create a missing pulse detector and measure the time between missing pulses. WAIT A MINute, JUST TYPING THIS I realized I can just measure the crank pulses and ignore the skipped tooth. WOW, thanks GOEYTEX.:)
.
Your mod for the Sunpro sounds great, but I want the tach to be small, maybe 1.5 inch in dia. I could buy the HD speedo with a built in tach, but that's no fun, and it is $300.
.
.
Well, another correction to my early correction. (10-11-2015, 23:49)
My ignition system is the 'single spark' system, not the 'wasted spark' system.
HD specs state idle rpm is '950 - 1050' rpm so my scope was showing 120 ms between spark and I guessed it was going 500 rpm idle. So with single spark system this makes the 120 ms correct for 1000 rpm.

[my brain is now going 'idiot,idiot,,idiot,idiot.....]:confused:
 
Last edited:

erco

Senior Member
Nothing to add since everyone here is much smarter than me, but I find this thread interesting. IMO engines, instrumentation, and hacking into the existing electronics will be of general interest to many folks here. It's a great example of binary1248 posing his problem with particularly well-informed input (specs & o'scope traces) which helps quickly zero in on a realistic solution. Also nice to see some honest corrections and AHA moments from binary along the way. And it's always fun to learn more about goeytex. Now we know he's a motorcycle whiz AND an electronics guru. :)
 

binary1248

Senior Member
Thanks erco, I was worried I was making a big tado about nothing, but now that I see interest I will continue to post my findings. Next I will scope the crank position sensor and post what it looks like.
It's people like you that keeps me going on projects like this.
 

binary1248

Senior Member
Here is the timing signal from the crank sensor. Period between cycles is 1.74ms, amplitude from gnd is 13.2V. You can see the missing pulse indicating TDC, missing pulse can be ignored in this application. This is at idle, about 1000 rpm.

.
Timing.jpg
 
Last edited:

binary1248

Senior Member
Looks like the command "Count" will do the trick. If I count long enough the missing pulse will be insignificant.
.
.
COUNT pin, period, wordvariable

Pin - is a variable/constant which specifies the input pin to use.

Period - is a variable/constant (1-65535ms at 4MHz).

Wordvariable - receives the result (0-65535).

- See more at: http://www.picaxe.com/BASIC-Commands/Digital-InputOutput/count/#sthash.gVKcBOZ2.dpuf
.
.
There are 30 pulses then the missing pulse, man these digital storage scope make measurements so easy.
timing02.jpg
 
Last edited:

fernando_g

Senior Member
When one sees the wiring diagrams of early 90s autos and motorcycles, one realizes that the CANBus was like a gift from heaven.
 

binary1248

Senior Member
I hope I am not getting to wordy on this project but I am posting my trend of thinking and coding, which may not be the most elegant.
.
Well, I have the servo part working, which will be the analog meter display, and the input counter of the 08m chip.
For 500 rpm (lower limit that I will use) it is 500 X 31 = 15500 ppm or 258 pps.
NOTE: I used 31 to add the missing tooth on the crank wheel.
For 6000 rpm = 6000 X 31 = 18600 ppm or 3100 pps.
Using a 1 sec gate would make the display to sluggish so my first setup will use 1/10 sec gate time.

count c.3,100,ctvalue

so my 500 rpm will count as 258
and 6000 will count as 310
Since my servo command must be between 75 and 225 I need to rescale the values to properly control the servo.

SERVO pin,pulse
- Pin is a variable/constant which specifies the i/o pin to use.
- Pulse is variable/constant (75-225) which specifies the servo position
Thus 258 will convert to 75 (500 rpm)
And 310 will convert to 225 (6000 rpm)
.
My poor math skills worked out this formula
S = ((f-25)/1.9)+75
Where S is sevo value
and f is the freq count number 258 to 310
.
I need to recheck it a few more times, but for now it's a great day so I am off to ride my motorcycle.
.
Let me know if any of this is wrong or needs corrections, after all I do make mistakes.


.
 

binary1248

Senior Member
Well here is the code such that count from 250 to 3100 will control servo from 75 to 225. Tested and works.
Need to add limit values to servo cmnd next.
.
Code:
;Nov 12 2015   PEH
[color=red];   *************************
;   * Motorcycle tachometer *
;   * Flie = TachXXX.bas    * 
;   *************************[/color]
;
;
;  Read the timing wheel (Crank Sensor) as a 
; count over a constrianed period
; That will be converted to RPM value to 
; control a servo that is the indicator
;
; some of the # dirictives may not be needed but
;included here for convience.
;
#picaxe	08M2

#no_data   'save some load time

;
symbol redled=C.2 ;pin 5 on chip
symbol ctvalue=w0 ;count value for rpm
	
Start:
	input 3         ;make ports  3 inputs, physical pins 4 
  	

;---------------This is just a alive indicator-------------------------	
	for b1=1 to 5	'little led test
	high redled
	pause 150   	;red led on, 
	low redled
	pause 150
	next b1
	low redled   	;red led off as we exit test
;---------------finished and done with stupid alive flashy test-----------------------------	
;
	init: servo c.4,75 ; initialise servo, physical pin 3
mainloop:

;---------------Input ctr value for rpm calculations ----------------
	count c.3, 100, ctvalue ; count pulses in 0.1 secs (at 4MHz) on pin 4
	
;---------Now calculate for rescaling for servo 75 to 225-----------
	w4=ctvalue*10  ;	scale up to keep some precision
	ctvalue=w4-250	;this is 25 scaled up X10
	w4=ctvalue/19	;This is 1.9 scaled up X10
	ctvalue=w4+75
;------------------ New value for servo in ctvalue------------------
;
;[color=red]xxxxxxxxxxxxxadd some limit stops for servo, max 225, min 75 xxxxxxx[/color]
  	

	servopos c.4,ctvalue  ; move servo to calculated command position 

	goto mainloop ; loop back to and do it all again
 
Last edited:

hippy

Technical Support
Staff member
Code:
Symbol INP_MIN = 258  ; Input range
Symbol INP_MAX = 310

Symbol OUT_MIN = 75   ; Output range
Symbol OUT_MAX = 225

Symbol INP_GAP = INP_MAX - INP_MIN
Symbol OUT_GAP = OUT_MAX - OUT_MIN

Symbol inp     = w1
Symbol out     = w2

inp = 258
out = inp Min INP_MIN - INP_MIN * OUT_GAP / INP_GAP + OUT_MIN Max OUT_MAX

SerTxd( "inp=", #inp, 9, "out=", #out, CR, LF )
 

Circuit

Senior Member
I hope I am not getting to wordy on this project ...
Absolutely not! I have little interest in motorcycles but following this thread is most educative - "listening in" on your analysis and solutions is of great value. - And I really learn a lot from the Gurus' re-workings (Goey and Hippy and so forth...)!
 

binary1248

Senior Member
Holy batman Hippy, what a beautiful coding sequence. An all in one code line. As you can see, I have to take each tiny step to understand it and for testing, but then I have been away from picaxe coding for awhile and the brain is rusty.
I am still amazed what these chips can do, or rather what the compiler (interpreter) can do, such as converting decimal to binary and back, without the programmer doing the conversions manually.
Many moons ago I used to program microchips in assembly for a living.
Somewhere on here I remember seeing info on the compiler and info on the output symbols [not called symbols, but I can't remember what the data downloaded to the chips interpreter were called.]. Oh yeah, they are called tokens.
 
Last edited:

binary1248

Senior Member
Well, here is the schematic of the input signal conditioner. Part values subject to change without warning.
I haven't built this part yet, waiting for some picaxe BB parts to arrive.

.
I need to add a 12V to 5V (78L5) regulator.
.
 

Attachments

Last edited:

techElder

Well-known member
I want to delete the smaller thumbnail, but I can't find out how ?
At the top of the forum page, go to "Settings". On the left side, under "Miscellaneous", choose "Attachments".

Choose the one to delete by checking the box on the far right.

Scroll to the bottom of the page. Choosing "Delete Selected" will delete whichever ones that you have checked.
 

tmfkam

Senior Member
Would you be kind enough to confirm something for me please? Your circuit diagram seems to show your regulator as a 7905 (-ve 5V). Should it be a 7805 (+ve 5V)?
 

binary1248

Senior Member
Would you be kind enough to confirm something for me please? Your circuit diagram seems to show your regulator as a 7905 (-ve 5V). Should it be a 7805 (+ve 5V)?
You are correct, it should be 7805. I pulled the part diagram from my schematic editor list and the two were next to each other and I must have clicked on the wrong one and never looked closely at the part number.
Thanks for the heads up.
.
The schematic has been corrected.:p
 
Last edited:

binary1248

Senior Member
Well, my little 08m2 bds came in, really neat little boards for small project breadboards. I added a 7805 to mine so I can run it from a 9V battery or 12 volts MC supply.
IMG_0113.JPG
But I am having trouble getting my Windows 10 to work with ASXE027, so I have to go back to my old lap top, bummer. I have a thread started in the software help forum.
 

premelec

Senior Member
Probably good to have capacitors to stabilize the regulator - perhaps you have them on the underside... don't know if that would also help WinX...
 

binary1248

Senior Member
Well, I will finish this tach/servo project and post results but will probably abandon it shortly after making it work on the motorcycle. Instead I will make an led bar-graph type, similar to the one pictured here. But mine will be a series of green,yellow and red led lights arranged around the perimeter of the existing speedometer. My motorcycle is a Crossbones styled after the old springers from the 50,s and I don't want to clutter it up with gauges. A low visibility set of leds around the spedo will be invisible when the bike is off.
LEDTach.jpg
Do I need a tach ? NO, but I like to know and it makes a interesting project.
It's interesting the catalog picture shows 1426 mph, some bike. ;)
 
Last edited:

binary1248

Senior Member
Well, like many of my projects I get it working then I decide to change it. The servo as a tach worked well but I couldn't find one that would turn 270 degrees, all in my RC pile only turns a max of slightly less than 180 degrees. But it is working, here is a picture of the finished BB.
I am going to the LED design which will be a series of LEDs arranged in a circular pattern around the trim ring of the existing spedo.
Need to add a couple of 74xx595 as serial in parallel out to drive the LEDs.
IMG_0119.JPG
 
Last edited:

binary1248

Senior Member
And here is the code for converting pulses to servo position.
I will keep this updated with the New and Better and Faster and Greater and Fancier and Brighter and Cheaper display development. (No I was not a used car salesman):p
Code:
.
;DEc 05 2015   PEH
;   *************************
;   *Harley Motorcycle tachometer 
;   * Flie = MC_TachX009.bas    
;   *************************
;
;
;  Read the timing wheel (Crank Sensor) as a 
; count over a constrianed period
; That will be converted to RPM value to 
; control a servo that is the indicator
;
; some of the # dirictives may not be needed but
;included here for convience.
;	12/2/2015 Set limits on input ctvalue to prevent overdriving the servo
;
#picaxe	08M2

#no_data   'save some load time
; #no_table
;
symbol redled=C.2 ;pin 5 on chip
symbol ctvalue=w0 ;count value for rpm
;    [-------------------------------------------------]
;    [ Use this terminal cmd when using sertxd cmnd    ]
;    [     #terminal 4800                              ]
;    [-------------------------------------------------]
	
Start:
	input 3         ;make ports  3 inputs, physical pins 4 
 ;
	init: servo c.4,225	; initialise servo, physical pin 3
	pause 2000
	ini2: servo c.4,75
	pause 2000
	
mainloop:

;---------------Input ctr value for rpm calculations ----------------
	count c.3, 100, ctvalue ; count pulses in 0.1 secs (at 4MHz) on pin 4
	w1=ctvalue ;full value befor limit checks

;limit input values to 258 and 26
	if ctvalue > 258 then
		ctvalue=258
	end if
	if ctvalue < 26 then
		ctvalue = 26
	end if
;
;debug
;----use the following without debug-------------------------
;sertxd (13,10)
;sertxd("The full input is ",#w1,13,10)
;sertxd ("The limited value is ",#ctvalue,13,10,13,10)
;pause 500
;------------------------------------------------------------

;---------Now calculate for rescaling for servo 75 to 225-----------
	w4=ctvalue*10  ;	scale up to keep some precision
	ctvalue=w4-250	;this is 25 scaled up X10
;------------ the next value is wrong, figure it out ----------------	
	w4=ctvalue/15	;This is 1.5 scaled up X10
	ctvalue=w4+75

	servopos c.4,ctvalue	 ; move servo to calculated command position 

	goto mainloop ; loop back to and do it all again
 
Last edited:

binary1248

Senior Member
Well, here is the preliminary schematic for the light bar tachometer. I wanted to continue the use of the 08m2, thus the addition of the serial to parallel registers.
sch_lt_bar.jpg
 

binary1248

Senior Member
As for the schematic above, I will always be shifting in one's so the data input pin of the serial to parallel IC's can be tied to +5V, then I will simply clear the display before the next shift in, which will be base on the crank sensor count.
So things remain fluid and changing as I develop the code.
Paul
 
Top