Ducati Cutaway Display

Hello!

I finally took the plunge into the Arduino world to help complete my Ducati 916 Engine display. The overall goal is to make the engine light up showing different cycles of operation like most other engine cut away displays seen at big automotive events. Since the engine needs 720 degree to complete one cycle, I am trying to base my led light sequence off the sine waves.

I would like some help writing/understanding the code to create the light sequence. Once the cycle is ideal, I will then tackle how to use my crank position sensor for an activation input (possibly).

I will need 5 led triggers: intake light compression light strobed spark light power light exhaust light

Any help would be greatly appreciated.

Manderioli: Hello!

I finally took the plunge into the Arduino world to help complete my Ducati 916 Engine display. The overall goal is to make the engine light up showing different cycles of operation like most other engine cut away displays seen at big automotive events. Since the engine needs 720 degree to complete one cycle, I am trying to base my led light sequence off the sine waves.

I would like some help writing/understanding the code to create the light sequence. Once the cycle is ideal, I will then tackle how to use my crank position sensor for an activation input (possibly).

I will need 5 led triggers: intake light compression light strobed spark light power light exhaust light

Any help would be greatly appreciated.

You want each LED to come on, then trun off at discrete times in a 720 degree cycle, right? Can you give us details of the crank position sensor?

I presume the machine will only be turning slowly? Why not put a rotary encoder on the crankshaft or camshaft as that will give the Arduino lots of accurate position data.

…R

Yes the goal is to have the LED cycle on and off throughout one 720 degree cycle.

From my research, the engine I have uses a single crank sensor that emits 50 pulses per revolution at camshaft speed. 2 pulses from two teeth missing. I would like to use this sensor to keep the motor as original as possible but understand the simplicity of a rotary encoder.

The engine will rotate way below cranking speed of 200 rpm so viewers can see the operation of the desmo valves, pistons, etc.

My understanding with a rotary encoder, I could program a light to turn on and off at a certain pulse number? If I am wrong, please correct me.

Do you have any recommendations on rotary encoders if the original crank sensor cannot be used?

Manderioli: My understanding with a rotary encoder, I could program a light to turn on and off at a certain pulse number?

Do you have any recommendations on rotary encoders if the original crank sensor cannot be used?

YES

NO. Maybe have a look at the Pololu or Sparkfun websites.

...R

Interesting project. You will need a second sensor to tell you program when “0” degrees is reached so all can start over.

Paul

Thank you for the input on the reset sensor. I am still at the tip of the iceberg for programming and have a few questions:

How would I assign a specific output of turning a led on at a certain number of pulses in the code?

Since the encoder does not have an absolute position, should the code not start until the reset sensor is triggered?

Would a higher pulse/rev be more beneficial at higher rotating speeds of the encoder? Or would my application be better off with a lower pulse/rev?

Manderioli: Since the encoder does not have an absolute position, should the code not start until the reset sensor is triggered?

When the Arduino starts its first task should be to rotate the system until it triggers the ZERO sensor. Then you can count the encoder pulses using that as a base.

It would probably be wise to check that every time the ZERO sensor is passed that the position count is what it should be.

I would choose the lowest number of pulses per revolution that gives you the accuracy you need for triggering events. That will minimize the computational load on the Arduino.

Your code to turn on an LED might be as simple as

if (positionCount == 73) {
  digitalWrite(ledPin, HIGH);
}

...R Planning and Implementing a Program

I received a simple 12 step rotary encoder from spark fun and also still learning about programming. (Rotary Encoder - COM-09117 - SparkFun Electronics)

Thanks to the following article I have a better understanding of the overall picture. (https://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino)

I modified the code ever so slightly:

int ledPin = 6:

Within void setup():

pinMode(ledPin, OUTPUT);

Then within void loop() using Robin2 example:
if(counter == 21) {
digitalWrite(ledPin, HIGH);
}

This is very simple and gratifying to make the led come on at a certain position for me.

Can the code become more complex by defining a range of counter values to illuminate the led? Example: if(21<counter<73){
digitalWrite(ledPin, HIGH);
}

I also reversed the above code to turn the led off at a certain value number. Is it possible to condense the code?

Also, I am trying to make the rotary encoder turn at camshaft speed (but may go off the crank for 2 revolutions vs one). Currently the output values from 0-255 take about 5.5 turns. How could I reduce the range or make the range fit within one revolution?

Or would it be easier to program a reset button and only use the values associated with one revolution? What would the code look like for a reset?

you should be able to use the existing sensor(s)

can I assume that the coils/spark occurs at every TDC on every rotation ? (sorry, not too sure about auto ignition timing.)

my point is that if the sparks only fly on the compression cycle at TDC (plus whatever advance) then you already have a means of knowing which is the compression stroke for firing.

my old lawn mower had a pair of gears that drove the cam shaft. The gear ratio was set so it already had the stages laid out in the mechanical bits. I would expect you have the same sort of timing.

Don't worry about making the code compact. It will just make it harder for you to understand and it won't make any difference for the output from the compiler.

Post your complete program.

If you have a 12 step encoder I don't understand where you get a count of 255 after 5.5 turns.

I had not envisaged that you would use that sort of encoder (which is meant to be operated by hand). Rather this type (though there may be cheaper alternatives). I don't know if the small encoder will have the longevity that you need.

@dave-in-nj, I believe the OP wants a number of things to activate at different points in the engine cycle.

...R

The rotary encoder may not be the best way to cycle the lights. It did help me visualize and understand some of the coding needed to make the sequence of lights turn on and off. Below is the code that I modified to sequence the leds.

I am only using 48 out of the 255 counts to simulate one rotation of the camshaft (2 rotations of the crank). The goal is to hopefully only need one rotation and not have duplicate coding just to take up the full range values for the encoder. How would I decrease the 0-255 range of the encoder into one turn? 256/48=5.3333??

/* Rotary encoder read example */
#define ENC_A 8
#define ENC_B 9
#define ENC_PORT PINB
int intake = 2; //intake led
int comp = 3; //compression led
int spark = 4; //spark led flashing
int ext = 5; // exhaust led

void setup()
{
 /* Setup encoder pins as inputs */
 pinMode(ENC_A, INPUT);
 digitalWrite(ENC_A, HIGH);
 pinMode(ENC_B, INPUT);
 digitalWrite(ENC_B, HIGH);
 Serial.begin (115200);
 Serial.println("Start");

 //led outputs
 pinMode(intake, OUTPUT);
 pinMode(comp, OUTPUT);
 pinMode(spark, OUTPUT);
 pinMode(ext, OUTPUT);

}

void loop()
{
static uint8_t counter = 0;      //this variable will be changed by encoder input
int8_t tmpdata;
/**/
 tmpdata = read_encoder();
 if( tmpdata ) {
   Serial.print("Counter value: ");
   Serial.println(counter, DEC);
   counter += tmpdata;
 
if(counter == 0){
 digitalWrite(intake, HIGH); // intake led turn on
}
if(counter == 11){
 digitalWrite(intake, LOW); //intake led turn off
}

if(counter == 12){
 digitalWrite(comp, HIGH);// compression led turn on
}
if(counter == 23){
 digitalWrite(comp, LOW); // compression led turn off
}
if(counter == 24){
 digitalWrite(spark, HIGH); // spark led flash on
}
if(counter == 35){
 digitalWrite(spark, LOW); // spark led off
}
if(counter == 36){
 digitalWrite(ext, HIGH); // exhaust led turn on
}
if(counter == 48){
 digitalWrite(ext, LOW); // exhaust led turn off
}
 }
}

/* returns change in encoder state (-1,0,1) */
int8_t read_encoder()
{
 static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
 static uint8_t old_AB = 0;
 /**/
 old_AB <<= 2;                   //remember previous state
 old_AB |= ( ENC_PORT & 0x03 );  //add current state
 return ( enc_states[( old_AB & 0x0f )]);
}

Could the same code work using a hall effect sensor? The ducati has a hall effect sensor positioned directly at the counter gear spinning at 1/2 crank speed. The sensor has the following data:

Technical Data
Supply voltage…4.5 > 24 Vdc
Nominal sensing distance…1.5 mm
Max be increased in proportion to pick up size
Current (typ) …1 0 mA
Current (max) …20 mA
Enviroment sealing… IP67
Weight… …30 g
Temperature range … -30 > + 130 °C
Tightening torque… 6 Nm
Output… …PNP
Output sink voltage …0.4v Max
Trigger type… ferrous

Electrical connections
Pin 1 Gnd
Pin 2 signal
Pin 3 VBB

Please modify your post and use the code button </> so your code looks like this and is easy to copy to a text editor. See How to use the Forum Your code is too long to study quickly without copying to a text editor.

…R

My apologies for the long post. I corrected it.

Manderioli: I am only using 48 out of the 255 counts to simulate one rotation of the camshaft (2 rotations of the crank).

I don't understand this. What is the encoder connected to?

I am assuming the encoder you are using produces 256 (?) steps per revolution (0 - 255). If it is connected to the crankshaft of a 4 stroke engine it needs to do 512 steps for a complete cycle. If it is connected to the camshaft then a single rotation (256 steps) is a full cycle.

I have no idea where the 48 comes from - it is not a simple factor (is that the right word?) of 256.

Have you checked that your Arduino program is reading the encoder correctly?

...R

The encoder is connect to the UNO board at pins 8 and 9. Maybe I need to switch to other pins?

Right now, there is 48 counts per revolution of the encoder. I am not sure how this has happened within the code.

Manderioli: The encoder is connect to the UNO board at pins 8 and 9. Maybe I need to switch to other pins?

I meant what part of the engine is it connected to?

It would be more normal to connect the encoder to the external interrupt pins 2 and 3.

Originally you had a 12-step encoder. What one are you using now? Post a link to its datasheet.

...R

I would like to connector the encoder to the camshaft gear so that one revolution of the encoder = one complete combustion cycle on the engine.

I will try connecting the encoder to pins 2 and 3 to see if that will help.

I am still using the 12 step encoder from spark fun. You're advice on longevity made me think about using the hall effect sensor from the engine. It is directed at the same cam shaft gear and would last much longer.

Manderioli: I would like to connector the encoder to the camshaft gear

I am more confused than ever.

That sounds like the encoder is NOT connected to the engine at the moment - so how can you get any number of pulses per revolution.

And where did the 0-255 in Reply #8 come from?

What does the hall effect sensor detect?

...R

I am spinning the encoder by hand and watching the output from the Serial Monitor to watch the count of the encoder. Currently bench testing the unit before I machine the necessary brackets to mount every device. If you'd like, I could create a video of me turning the encoder by hand.

0-255 came from the display and is mentioned in the article from which the code is taken. I may be wrong but I believe that is how the encoder is setup from manufacture..if there are 4 counts/step (rise and fall) and 12 steps per revolution, then the 48 counts per revolution right?

The hall effect sensor reads the number of teeth on the cam shaft gear. Its primary purpose with the engine ecu is to read revolutions per minute. On the gear itself, there are 2 or 3 teeth (if i remember correctly) that are half the width of the entire gear (or other teeth) to give the hall effect sensor a reference point. The sensor is mounted within a few millimeters of the gear. When those 2-3 teeth pass by the sensor, the gap become much larger and does not disrupt the magnetic field.