Hello to everyone. I need some help with programming my project. So I'm doing a engine simulation with Arduino Uno. The whole idea is to simulate an engine running via setting predefined RPM by a potentiometer, when the engine is "running" the uno should count the time passed since the engine has started, and at the end of each loop update the crankshaft angle as precise as it could be. At this particular moment the logic is to store the time each loop starts with ~ micros(), then see where the crankshaft is, activate ignition and injection signals. (I'm basically simulating fuel injection and fuel ignition). After all the logic I update the crank angle (between 0.00 and 720.00) based on the microseconds passed.
The problem I have is, when I set the RPM at 60. Meaning 1 full rotation for 1 second, the controller does a full rotation for something like 5-6 seconds. What I do is calculate the revolutions per microsecond (currentRPM/60/1000/1000) and then multiply by 360 and the microseconds passed. The whole thing I have simplified to currentRPM * (0.000006) * microsPassed which I believe is mathematically right, but the uno seems to not care. I do know time counting is hard especially with such slow processors, but it's 4-5 times slower than expected even on 4us resolution. Am I making a mistake somewhere with my maths or there some other error.
I can't upload the code right now as I am not from my PC, but I will make sure to update the thread once I get home.
then your program does something wrong, but we can't see your program.
In general I would expect that you have a sensor for the top dead center and use that signal as reference when to fire which spark and activate which injection depending on the order of the cylinder.
I only have 3 ignition coils and 3 injectors. I don't have a real engine. Also no sensors, just a on/off switch and potentiometer to control the RPM.
I must simulate a engine ignition and fuel system, it's for a university project. I already have the hardware working, but I can't figure out the crank rotation simulation.
You probably mean crank or cam position/speed sensor, which sends information to the ECM about the position and or the speed of the crankshaft or camshafts.
All this sensor does is tell the ECM at what rotation between 0-720 degrees the crankshaft is at, which is the same thing I'm trying to simulate. By knowing the position of the crankshaft you can then find absolutely everything else, cam position, piston position, at which stroke a cylinder is...
Also spark signals should be sent earlier, before TDC, as you need like 3ms because of the coil dwell time, if you interrupt the signal earlier this will cause little or no spark on the spark plug.
The real hardware is as it goes:
-12V battery, connected to a COP (coil on plug), triggered directly by the Arduino.
MOSFET Module (IRF520), powering my injector through the 12V battery.
The injector needs 12V and has 14.6Ohm of resistance, so it will draw like 0.86A (~1A).
The simulation is very very simple, just set the RPM by the potentiometer.
If the RPM signal is more than ENGINE_START_RPM the engines starts, from 0 degrees of the crankshaft, then it counts time at each loop and updates the crankshaft position based on the time passed and the currentRPM set by the potentiometer. Each loop it checks if the crankshaft is at certain angle based on the engine parameters like number of cylinders, firing order etc... and determines which signals to send, likecylinder to ignite or inject.
Currently I have only 1 coil and 1 injector, but later I will use 3, as I have to simulate a 3 cylinder engine, but for sake of simplicity before I solder everything in I want to make sure I have a working software, because if it can control 1 coil and 1 injector it should also control 3 with no problems.
That's unimportant in a simulation. Have virtual time bound to the RPM and crankshaftAngle. If you know at which angle increment the next event occurs then simply set the virtual time for that angle, handle the event and go on to the next event.
Yes, but I am curious because of the separation of taking the time for figuring elapsed time is just the calculations, and the time to exit and return to the loop is unaccounted for.
Yes, still unimportant. I might as well say why use micros() or any reference to real time at all?
It would make more sense to me to simply say that the loop can get around to doing the calculations and setting the outputs at some fixed frequency, which would be some fixed period.
With the loop as it is, I'd like to see where the time is getting spent is all.
for the 4 stroke motor timing calculation I would use a 720 cylce, not the crankshaft angle.
millis/mircros is just used to slow down the simulation (=throttle)
I didn't do a RPM calculation, because I wanted to stay within 42 lines of code (should be quite easy when you devide the cylce by 2 and then calculate how many rotation passed per minute) - and it's not my homework.
Sadly, with this software the coil will not produce any spark or will produce very weak one.
I have to wait atleast 3ms before turning the coil signal off, because the primary coil needs to "charge up" before discharging, else the secondary coil will not induce enough high voltage from the collapsing electromagnetic field to produce a good spark.
This is one of the main reasons I need the actual crank position, because based on the currentRPM, I have to calculate the dwellAngle (The angle at which I should send the trigger signal, so it has enough time to charge before I discharge it).
Are you not allowed to just use a crank position sensor, or equivalent and some spinning disk affixed to an electric motor with a known (calibrated) RPM controlled by the potentiometer?
Quick story: the local Hyundai stealership tried to rip me off when I asked them to replace the crank sensor on my 2012 Santa Fe. I dropped it off for other work like an oil change and said there was a problem I think is the crank sensor (long time to turnover, brand new battery and such, plus my OBDII reader indicated a possible faulty crank sensor).
Long story short, after they lied to me about replacing it, I went to Napa and bought a new one. I went home, took out the sensor that was obviously not new and connected it to my scope and tested it against an old hole saw drill bit that I dremeled a couple of the teeth out of to simulate how a crank sensor is used. Then I compared it to the new one, obviously the dead one was noise on the scope at even 0.2 (iirc) volts/division whereas the new one gave me nice square waves at 5V per division. Then I returned to the stealership but that's another story.
Point (question I guess) is, would something like the test rig I cooked up to catch those lying b*****ds work for your project?
Adapting my code like this managed to fix the time problem, now time leakage is not noticable.
At 60 RPM one 360 degree cycle takes around 1 sec ± 1-2ms, but now to the next problem - my loop takes significantly more time, like 1 loop takes up 15 ms which is too slow to run at more than 60 RPM.
Thanks for sharing. See if the next thing I do is add a ring of neopixels to that. Or just some extra LEDs for the other two strokes.
OK, that's a 10 millisecond loop time. An eternity!
Bump the printing to 115200 or even higher as @DaveX pointed out. Or lose 99 percent of it: anything you are over with for informational purposes can just be // commented out. Anything you do need printed could be made shorter. Consider LEDs for feedback instead &c.
There are ways of doing better than floating point, but I don't know at a glance if that's a or the problem.