Repetative Timing consistancy
I have recently aquired a basic stamp kit to create some simulators for automotive fuel and ignition systems (I teach vehicle repair and diagnostic tool usage)
A little background to let you know my experience level:
3 years University in EE and ME (years ago...)
15 years diagnosing and repairing vehicles (Primarily electrical / computer / emmisions systems)
I have Fortran and Pascal programming experience, and I currently use VB.net (intermediate skill level)
I understand electronic and circuits from a diagnostic point of view...Show me a diagram and I can diagnose and find the problem (and understand the cicuit in question)
What I do not have is practical electronic experience DESIGNING circuits (except for years ago in college), or programming said circuits to be functional.
I have gone completely through the "Whats a Micro Controller?" book and I have completed all of the practice examples (and modified most of them playing around)
The reason for the simulator is that it is much easier to hook up a scope to a known circuit in a classroom environment rather than everybody crowded around a vehicle.
For my first project, I am in process of making a fuel system simulator that would sequentially pulse 6 or 8 injectors. I would like to have a variable frequency (RPM) and pulsewidth (PW) for the injectors. I have designed a circuit using multiple LED's that I have used to get the programming right before I construct the actual circuit and training boards.
I have successfully created 2 totally different programs that accomplish ALMOST the same thing, but they each have a couple of issues that I would like some insight into..
The first (and simpler) program is this:
This program works very well with one minor issue... One a vehicle one of the characteristics of the fuel injectors when the vehicle is under load is that the individual pulses "overlap", in other words injector #2 fires before injector #1 turns off. Depending on the load this can cascade into having 3 or 4 injectors on at the same time. Obvously this first program does not address this issue. Other than that the program works flawlessly.
Here is another one that I wrote ( a little more complex) that addresses that issue but creates some more. This next one will overlap the pulses, but if I push the limits for PW or RPM ·it will appear to skip "Injectors" (LED's) or the timing is not consistant for each injector. (Even though this is not a time critical project, I get kind of anal about stuff like this)
THis is a little convoluted, but it does seem to work except when I start varying the PW and increment / cycle_time it will screw the timing up and the LEDs quit pulsing in the correct way.
Any insite would be much appreciated...I will post an explaination of my math in the second example tomorrow if needed (it is getting late and I am beat)
Thanks again for any help
Lee
A little background to let you know my experience level:
3 years University in EE and ME (years ago...)
15 years diagnosing and repairing vehicles (Primarily electrical / computer / emmisions systems)
I have Fortran and Pascal programming experience, and I currently use VB.net (intermediate skill level)
I understand electronic and circuits from a diagnostic point of view...Show me a diagram and I can diagnose and find the problem (and understand the cicuit in question)
What I do not have is practical electronic experience DESIGNING circuits (except for years ago in college), or programming said circuits to be functional.
I have gone completely through the "Whats a Micro Controller?" book and I have completed all of the practice examples (and modified most of them playing around)
The reason for the simulator is that it is much easier to hook up a scope to a known circuit in a classroom environment rather than everybody crowded around a vehicle.
For my first project, I am in process of making a fuel system simulator that would sequentially pulse 6 or 8 injectors. I would like to have a variable frequency (RPM) and pulsewidth (PW) for the injectors. I have designed a circuit using multiple LED's that I have used to get the programming right before I construct the actual circuit and training boards.
I have successfully created 2 totally different programs that accomplish ALMOST the same thing, but they each have a couple of issues that I would like some insight into..
The first (and simpler) program is this:
pulsewidth VAR Byte ' variable to store PW of each pulse off_time VAR word ' variable to store offtime between pulses Current_inj VAR Byte ' current injector being pulsed CUrrent_inj = 10 ' I used pins 10 - 15 for "injector" drivers, this is #1 DO If Current_inj > 15 THEN Current_inj = 10 GOSUB ck_timer PULSOUT Current_inj, pulsewidth PAUSE off_time Current_inj = CUrrent_inj + 1 LOOP ck_timer: HIGH 0 ' I used 2 variable pots with RCTIME to adjust PW and OFFTIME on the fly HIGH 2 PAUSE 25 RCTIME 0,1, off_time RCTIME 1,1, pulsewidth 'CALCULATIONS TO SCALE PW AND OFFTIME GO HERE RETURN
This program works very well with one minor issue... One a vehicle one of the characteristics of the fuel injectors when the vehicle is under load is that the individual pulses "overlap", in other words injector #2 fires before injector #1 turns off. Depending on the load this can cascade into having 3 or 4 injectors on at the same time. Obvously this first program does not address this issue. Other than that the program works flawlessly.
Here is another one that I wrote ( a little more complex) that addresses that issue but creates some more. This next one will overlap the pulses, but if I push the limits for PW or RPM ·it will appear to skip "Injectors" (LED's) or the timing is not consistant for each injector. (Even though this is not a time critical project, I get kind of anal about stuff like this)
' {$STAMP BS2} ' {$PBASIC 2.5} pulse_width VAR Word cycle_time VAR Word Counter VAR Word Current_injector VAR Byte ' current injector to be pulsed Last_Injector VAR Byte ' previous injector Increment VAR Byte ' step increment to loop (RPM) Num_Injectors CON 6 Cycle_time = 100 ' this is the number of "counts" to cycle through all LED's pulse_width = 15 ' ON Time Counter = 0 ' keep track of where I am in the cycle Increment = 5 ' how fast to loop through (RPM) DO Current_Injector = counter / ((cycle_time / Num_Injectors) + 1) ' this is the current injector to be triggered based on cycle_time position GOSUB ck_injector_status IF counter > (cycle_time - Increment) THEN counter = 0 LOOP ck_injector_status: IF Current_Injector = 0 THEN Last_Injector = 5 ELSE Last_Injector = Current_Injector - 1 ' figure out last injector fired '####### Check to see if the last injector needs to be turned off (It does work)################## IF counter < (cycle_time * Last_Injector) ** 10923 OR counter >= (cycle_time * Last_Injector) ** 10923 + pulse_width THEN LOW Last_Injector + 10 ENDIF ' ########### check to see if it is time to turn on the next injector (same logic as above) ################# IF counter >= (cycle_time * Current_Injector) ** 10923 AND counter < (cycle_time * Current_injector ** 10923) + pulse_width THEN HIGH Current_injector + 10 IF current_injector = 5 THEN PAUSE 5 '######### the last injector always seemed "Short" so I added this ENDIF Counter = Counter + Increment '########### move one step in cycle RETURN
THis is a little convoluted, but it does seem to work except when I start varying the PW and increment / cycle_time it will screw the timing up and the LEDs quit pulsing in the correct way.
Any insite would be much appreciated...I will post an explaination of my math in the second example tomorrow if needed (it is getting late and I am beat)
Thanks again for any help
Lee
Comments
Let's break this up into at least two posts, to avoid utter confusion. I have copied your first program below, and after we work on this, we can do the same thing with the second program. At this juncture I have made only minor modifications, just to make it a bit easier to read, and have it run a bit more efficiently. I have also added some comments and questions. Here is the ORIGINAL and unmodified Program One:
The first (and simpler) program is this:
[noparse][[/noparse]code]
pulsewidth VAR Byte········ ' variable to store PW of each pulse
off_time·· VAR word········ ' variable to store offtime between pulses
Current_inj VAR Byte······· ' current injector being pulsed
CUrrent_inj =·10··········· ' I used pins 10 - 15 for "injector" drivers, this is #1
DO
· If Current_inj > 15 THEN Current_inj = 10·'Reset inj to beginning
· GOSUB ck_timer
· PULSOUT Current_inj, pulsewidth
· PAUSE off_time
· Current_inj = CUrrent_inj + 1
LOOP
ck_timer:
· HIGH 0········ ' I used 2 variable pots with RCTIME to adjust PW and OFFTIME on the fly
· HIGH 2
· PAUSE 25
· RCTIME 0,1, off_time
· RCTIME 1,1, pulsewidth
'CALCULATIONS TO SCALE PW AND OFFTIME GO HERE
RETURN
This program works very well with one minor issue... One a vehicle one of the characteristics of the fuel injectors when the vehicle is under load is that the individual pulses "overlap", in other words injector #2 fires before injector #1 turns off. Depending on the load this can cascade into having 3 or 4 injectors on at the same time. Obvously this first program does not address this issue. Other than that the program works flawlessly.
Here is your Program One slightly modified:
<!--StartFragment -->The first (and simpler) program is this:
[noparse][[/noparse]code]
pulsewidth VAR Byte········ ' variable to store PW of each pulse
off_time·· VAR word········ ' variable to store offtime between pulses
Current_inj VAR·NIB······· ' current injector being pulsed
'Constants
'Now the starting and ending injectors can be changed throughout by
'only modifying the following·two constants:
Start_inj = 10
End_inj·· = 15
' DEBUG "Starting" 'See below, presently a comment
Main_Loop:
·FOR··Current_inj = Start_inj to End_inj·'Loop thru injectors 10-->15
·· GOSUB ck_timer·'Obtain user variables
·· PULSOUT Current_inj, pulsewidth ' Pulse injector "n"
·· PAUSE off_time·'Wait for variable off time
·NEXT
· GOTO Main_Loop
·
ck_timer: 'Subroutine
· ·HIGH 0···' 2 variable pots with RCTIME to adj. PW and OFFTIME on the fly
·· HIGH 2
·· 'PAUSE 25·'No idea why this pause is here?
·· RCTIME 0,1, off_time
·· RCTIME 1,1, pulsewidth
'CALCULATIONS TO SCALE PW AND OFFTIME GO HERE
· RETURN
END
Regardless of which copy of the programs you view above:
1.·either/both "fire" the injectors in sequence, and
2. every PBASIC instruction MUST complete before the next instruction can take place.
Thus, it is nearly impossible for the prgram logic to be causing what you seem to be seeing as injector overlap. So, I'd carefully check my wiring.
It IS possible that the program is resetting (usually due to a current overload) and the injectors are not firing as you wish them to. You can make the following the first executable statement in the program to detect that condition:
DEBUG "Starting"
If you see "Starting" displayed more than once during any iteration of the program, you will then know the Stamp is resetting.
Regards,
Bruce Bates
Also, I believe the pause 25 is there to allow the caps to fully charge.
FWIW
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Shawn Lowe
My last words shall be - "NOT YET!!!"
I appreciate the feedback...
I like the modifications that you made to my original code, it does make it flow a little better. The PAUSE 25 that you questions is there to give the caps time to charge up as Shawn suggested, I just made a typo for Pin 2 (should have been pin 1)
As far as the overlap, I understand that the controller only executes one command at a time and that this program will only turn the next injector on AFTER the previous one has been turned off. That is indeed how this works on the actual circuit.
I was trying to create the overlap by using the second bit of code by using HIGH and LOW rather than PULSOUT. That way I could turn injector (1) on with a HIGH, and then the injector (2) on before I issued the LOW for injector (1). I see that I copied some code that was a "beta"...(It was about 2AM when I posted so I was a little brain dead. I will post the actual code later that I was using that does "overlap" the pulses by keeping track of HIGH and LOW state on multiple outputs, the problem I was having was there was apparantly too much overhead in the code and it was causing timing errors.
I have not actually wired the injectors yet, I am currently just using 6 LED's until I get my logic straight
Thanks again for the help
Lee
The effect of what you are seeing on the Oscope that two or more Injectors are on at the same time at higher RPM could it be dwell of your caps discharging of the mosfet stiffin caps and not really the MCU telling the injectors to come on?
If you can get a print of a real Car MCU and put your scope directly to the output pin of the Processor then I think you will see a true step from the pins.
If you want the LEDS/Injectors to ack like they over lap on your project just use a cap to cause the injector or led to fade down.
With the right cap it should be no overlap with low RPM and then start causing it to overlap more the faster it sequences, kind of like the Red Lamps on the front of the Kight Rider Car...
Hope this help let us know
Thanks for the responses so far,
Here is a (reworked, as in brand new) program that does EXACTLY what I want it to, only it is SLOW. I would like to speed up the loop if possible. Forget about the injectors for now, this circuit/program is designed to drive 6 LEDs connected to pins 1-6 on the Stamp Controller. (and it does work, including the "overlap" of pulses)
I thought the process through and completely changed my strategy.
Here is the basic logic of the program:
Run through a loop that is an even multiple of the number of LED's, for this example I used 600 to keep the math easy
At each even interval (100,200,300,400,500,600) turn on the next LED in the sequence. I start the loop at 100 and end at 699 to avoid some div / 0 errors in the calculations.
With each iteration through the loop, add one to a counter for every LED that is illuminated
With each iteration of the loop, check the counter to see if it has exceeded the "pulsewidth" for the ON TIME, if it has then turn off the LED and reset the counter.
To change the Frequency you can either make the main loop shorter (so it has less cycles to go through) or change the STEP for the loop, the loop length and STEP values need to be even multiples so that it does not skip any events
TO change how long each LED is illuminated, adjust the pulse_width variable, longer values will case the pulses to overlap.
I understand that there is a certain amount of time it takes to run through these iterations, and there is overhead doing it this way. Does anybody see a way to optimize the code so that it is capable of higher frequencies?
Functional Code:
Thanks Again, this is a great forum and I have learned a bunch just in the last few days....
Lee
My education, I did finish high School but never did any serious studying in school but I do read quite a bit now.
Hope this helps.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Think Inside the box first and if that doesn't work..
Re-arrange what's inside the box then...
Think outside the BOX!
It's bloody slow so you may want to port it to something with a bigger engine [noparse]:)[/noparse]
This code will overlap 100% of up to the next three injectors.
You can add another load factor for on times if you like to fire them sooner but I wanted to keep it simple.
I started with a simulated shaft that rotates 360 degrees in 252 steps. Each injector fires at 1/6 of the rotation
Variables are set for both on and off so it is just a matter of setting the on and off times within the boundaries of the shaft rotation.
The logic is quite simple I could port it to an ATMEL mega48 in assembler if you like, someone here could toss it on SX or something.
If you have enough speed and memory for variables I would use 360 steps or 3600 depending on the resolution you need or want on the simulated shaft. If you want this one faster you could reduce the steps but it still won't win any races.
I am actually doing something similar to this, a simulated rotating light with 16 LED's using PWM to fade up the next led while the previous led fades down although it's all in assembler on mega48.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Think Inside the box first and if that doesn't work..
Re-arrange what's inside the box then...
Think outside the BOX!
Post Edited (metron9) : 12/24/2006 4:04:55 AM GMT
That first program really speeds things up..
I think that it will do what I need it to do, the timing is not that critical down to the mS level so it should work. Here is a 4 trace shot of 4 out of the 6 LED's
That is one thing that I am not real stong on, it bitwise math and operators. I need to read up on them some more I can see powerful they can be..
Thanks again