@detown, thank you for your reply. That is all I am asking for. I am not afraid of doing the work, Just need to be pointed in the right direction which you have done. Let the fun begin. Still like to know how to get to libreems end product. That is what I am looking for.
Look at the blink without delay example in the IDE. Start with getting that running on your Uno. It's not a very long way from there to something that simulates the camshaft signal, at least at fixed RPM.
Sounds good. Will get started on that tonight.
bwilliams60:
@detown, thank you for your reply. That is all I am asking for. I am not afraid of doing the work, Just need to be pointed in the right direction which you have done. Let the fun begin. Still like to know how to get to libreems end product. That is what I am looking for.
There is no end product. It is the sketch that you load to your Arduino and how to hook everything up.
First thing is to learn how to use the IDE and load a sketch to your Arduino.
If you have problems with that come back here and someone will help you.
One step at a time.
I think the Ardustim is what you need unless you wish a long process to develop your own code.
It has every crank pattern you could think of plus cam signals. It also has the ability to control the speed with a pot.
I have briefly looked at Ardu-Stim. I am assuming that this is an Arduino based sketch that will make the Arduino do what i want it to do is that correct? I would download a "sketch" and then it will perform these functions?
I will look into it more.
I am assuming that this is an Arduino based sketch that will make the Arduino do what i want it to do is that correct? I would download a "sketch" and then it will perform these functions?
It is somewhat more complicated to get Ardu-Stim up and running. I will give the process for Windows.
I assume you have the Arduino IDE installed, and can run sketches.
Next download the Ardu-Stim zip file from
There is a download pulldown menu next to a button called "Clone" which will allow you to select the .zip version.
Go to the downloaded file and right click on it
Select "extract all" and extract it to Arduino folder in your documents where the sketches are located. You will now be able to click on that folder and navigate to the Arduino program. You will be able to open the program in an IDE window. All the associated files will be opened in tabs automatically.
There are now two more supporting programs you will need.
Use the library manager of the ide to install a library called SerialUI.h. Do not install the latest version 3.1.0 but instead load 2.2.0. The Ardu-Stim and the latest version do not work together.
Finally, you will need a terminal program called "druid4arduino" which you can get from
With the SerialUI library in your user libraries, you should be able to open and compile Ardu-Stim.
Then open the druid4arduino terminal and use the wrench button to find settings and make sure that the COM port of the Arduino and baudrate of 9600 are selected.
At this point the program and user interface should be available. I haven't experimented much with the program yet, but you should be able to use your scope to see if the wheel pattern and rpm selected outputs what you need.
You should be able to get up and running with what I have provided, but if run into problems feel free to ask, as its all a bit complicated for a beginner.
Cattledog +1 on that. The documentation is a little week for Ardustim.
Also I read in the comments that the pot control for the speed was not working.
Okay I am back and have a little Arduino education now but man do i have a lot to learn.
@cattledog, I have downloaded Ardu-Stim and SerialUI.h V2.2.0 and now in a black box at the bottom I am showing Invalid library found in C: ...Arduino/libraries.ardu-stim-master.....
Also, Do I just download druid4arduino into an open file in what location?
Complied but got Invalid library error. no header files (.h) found
Okay who has patience here
Ardustim is a program, not a library so I'm not certain I understand the error.
Do you have ardustim extracted from the download .zip and sitting in a folder. There should be a folder inside that called ardustim which contains a program file with the Arduin blue logo and several other linked .h and .cpp files.
Do you see that?
Have you used the library manager to install SerialUI.h V2.2.0. Can you see it in the libraries folder of your sketch folder?
I believe that at this point the ardustim program should open and compile when you click on the icon in the extracted download folder.
If you can't get this far, let me know what is blocking you. If there is an error message when compiling, please post it in detail.
I got it working and am elated at how this works. Thank you for your help. I found another post regarding the error and just worked through it. I have my scope on it and it is working great. Would be nice to be able to vary the RPM on it but this is a good start. If you know how to do that, it would be very helpful. Thanks again.
In the Druid4Arduino terminal program which connects to the Arduino running Ardustim there is a menu button "Set Fixed RPM" and an Input window to enter the value.
Are you using this terminal program as the user interface?
The change entered is then shown in the window below the input bloc. Whether or not this actually changes the output from the Arduino is unknown to me as I'm not presently trying to read any output.
I just saw this thread. This is kind of brute force because it wasn't meant to be anything fancy but here's my crank/cam simulator for a honda engine. You can vary the RPM's by changing the "cycle" variable value. It's in microseconds per rev. The CYL is the index, the TDC is the top dead center for each cylinder(4), and the CPS signal is the crank position sensor for a 16 tooth wheel. You can find the digitalFastWrite routine by a search. If you make the cycle variable equal to the cyclezero/cycletimer you'll get a variable output setup that changes every 15 seconds. Thus you can look at advance timing changes and whatnot. I hope this helps.
/*/This routine simulates the output from the didtributor of a
1990 to 2000 Honda motor
**/
#include <digitalWriteFast.h>
// constants won't change. Used here to set the pins
const int outCYL = 2;// the number of the pin
const int outTDC = 3;// the number of the pin
const int outCPS = 4;// the number of the pin
const byte inMulti = A0;//analog pin
int outStateCYL = LOW;
int outStateTDC = LOW;
int outStateCPS = LOW;
float multiplier, cycleFac;
// Time variables
unsigned long newCYL;
unsigned long oldCYL;
unsigned long newTDC;
unsigned long oldTDC;
unsigned long newCPS;
unsigned long oldCPS;
unsigned long intervalCYL;
unsigned long intervalTDC;
unsigned long intervalCPS;
unsigned long cycle, cycleZero = 180000;
unsigned long delayTDC, durTDC, delayCPS, durCPS, durCYL;
unsigned long newTime, oldTime, timerCount = 1, timer;
void setup() {
// set the pins and the serial set-up for checking things:
pinModeFast(outCYL, OUTPUT);
pinModeFast(outTDC, OUTPUT);
pinModeFast(outCPS, OUTPUT);
Serial.begin(9600);
}
void loop() {
timer = 15000;
newTime = millis();
if (newTime - oldTime >= timer) {
oldTime = newTime;
timerCount++;
}
if (timerCount >= 6)timerCount = 1;
cycle = 87400;//cycleZero / timerCount;
newCYL = micros();
durCYL = cycle / 25;
delayTDC = cycle / 100;
durTDC = cycle / 25;
delayCPS = delayTDC - 100;
durCPS = cycle / 28;
if (newCYL - oldCYL >= cycle ) {
oldCYL = newCYL;
}
intervalCYL = newCYL - oldCYL;
//Serial.print(intervalCYL);
//Serial.print(" ");
if (intervalCYL >= 0 && intervalCYL <= 3100) {
outStateCYL = LOW;
digitalWriteFast(outCYL, outStateCYL);
}
else {
outStateCYL = HIGH;
digitalWriteFast(outCYL, outStateCYL);
}
//TDC
if (intervalCYL >= delayTDC && intervalCYL < durTDC) {
outStateTDC = LOW;
digitalWriteFast(outTDC, outStateTDC);
}
if (intervalCYL >= durTDC && intervalCYL < delayTDC + cycle / 4) {
outStateTDC = HIGH;
digitalWriteFast(outTDC, outStateTDC);
}
if (intervalCYL >= delayTDC + cycle / 4 && intervalCYL < durTDC + cycle / 4) {
outStateTDC = LOW;
digitalWriteFast(outTDC, outStateTDC);
}
if (intervalCYL >= durTDC + cycle / 4 && intervalCYL < cycle / 2) {
outStateTDC = HIGH;
digitalWriteFast(outTDC, outStateTDC);
}
if (intervalCYL >= delayTDC + cycle / 2 && intervalCYL < durTDC + cycle / 2) {
outStateTDC = LOW;
digitalWriteFast(outTDC, outStateTDC);
}
if (intervalCYL >= durTDC + cycle / 2 && intervalCYL < 3 * cycle / 4) {
outStateTDC = HIGH;
digitalWriteFast(outTDC, outStateTDC);
}
if (intervalCYL >= delayTDC + 3 * cycle / 4 && intervalCYL < durTDC + 3 * cycle / 4) {
outStateTDC = LOW;
digitalWriteFast(outTDC, outStateTDC);
}
if (intervalCYL >= durTDC + 3 * cycle / 4 ) {
outStateTDC = HIGH;
digitalWriteFast(outTDC, outStateTDC);
}
//---------------------------------------//
//CPS
if (intervalCYL >= delayCPS && intervalCYL < durCPS) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS && intervalCYL < delayCPS + cycle / 16) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + cycle / 16 && intervalCYL < durCPS + cycle / 16) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + cycle / 16 && delayCPS + intervalCYL < cycle / 8) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + cycle / 8 && intervalCYL < durCPS + cycle / 8) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + cycle / 8 && intervalCYL < 3 * cycle / 16) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 3 * cycle / 16 && intervalCYL < durCPS + 3 * cycle / 16) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 3 * cycle / 16 && intervalCYL < delayCPS + cycle / 4) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + cycle / 4 && intervalCYL < durCPS + cycle / 4) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + cycle / 4 && intervalCYL < delayCPS + 5 * cycle / 16) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 5 * cycle / 16 && intervalCYL < durCPS + 5 * cycle / 16) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 5 * cycle / 16 && intervalCYL < delayCPS + 3 * cycle / 8) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 3 * cycle / 8 && intervalCYL < durCPS + 3 * cycle / 8) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 3 * cycle / 8 && intervalCYL < delayCPS + 7 * cycle / 16) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 7 * cycle / 16 && intervalCYL < durCPS + 7 * cycle / 16) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 7 * cycle / 16 && intervalCYL < delayCPS + cycle / 2) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + cycle / 2 && intervalCYL < durCPS + cycle / 2) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + cycle / 2 && intervalCYL < delayCPS + 9 * cycle / 16) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 9 * cycle / 16 && intervalCYL < durCPS + 9 * cycle / 16) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 9 * cycle / 16 && intervalCYL < delayCPS + 5 * cycle / 8) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 5 * cycle / 8 && intervalCYL < durCPS + 5 * cycle / 8) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 5 * cycle / 8 && intervalCYL < delayCPS + 11 * cycle / 16) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 11 * cycle / 16 && intervalCYL < durCPS + 11 * cycle / 16) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 11 * cycle / 16 && intervalCYL < delayCPS + 3 * cycle / 4) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 3 * cycle / 4 && intervalCYL < durCPS + 3 * cycle / 4) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 3 * cycle / 4 && intervalCYL < delayCPS + 13 * cycle / 16) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 13 * cycle / 16 && intervalCYL < durCPS + 13 * cycle / 16) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 13 * cycle / 16 && intervalCYL < delayCPS + 7 * cycle / 8) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 7 * cycle / 8 && intervalCYL < durCPS + 7 * cycle / 8) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 7 * cycle / 8 && intervalCYL < delayCPS + 15 * cycle / 16) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= delayCPS + 15 * cycle / 16 && intervalCYL < durCPS + 15 * cycle / 16) {
outStateCPS = LOW;
digitalWriteFast(outCPS, outStateCPS);
}
if (intervalCYL >= durCPS + 15 * cycle / 16 ) {
outStateCPS = HIGH;
digitalWriteFast(outCPS, outStateCPS);
}
}
AJLindfors:
I just saw this thread. This is kind of brute force because it wasn't meant to be anything fancy but here's my crank/cam simulator for a honda engine. You can vary the RPM's by changing the "cycle" variable value. It's in microseconds per rev. The CYL is the index, the TDC is the top dead center for each cylinder(4), and the CPS signal is the crank position sensor for a 16 tooth wheel. You can find the digitalFastWrite routine by a search. If you make the cycle variable equal to the cyclezero/cycletimer you'll get a variable output setup that changes every 15 seconds. Thus you can look at advance timing changes and whatnot. I hope this helps.
Looks good, what model Arduino does it work on?
Thanks.. Tom...
Currently running on a Nano board.