Shift Indicator using Arduino Nano

-

KitCarlson

Well-Known Member
Joined
Jan 17, 2008
Messages
2,624
Reaction score
462
Location
Middle Tennessee
See this post about request for shift light method: http://www.forabodiesonly.com/mopar/showthread.php?t=325823

This post is an example of how to program an Arduino nano for use as a shift light driver. Nano board are inexpensive, a year ago $10, now about $5 each. This post does not cover conditioning of an ignition signal for use as a logic input to the micro, it varies much with ignition system.

Step one was to program an ignition simulator using a second nano. This was easy to do. The simulator allowed me to easily test the shift indicator without using a car. The tach drive signal from the simulator puts out four 0-5V pulses per revolution, from about 650 to 7000 RPM, then repeats. This simulator could be used to test ignition boxes, or bench test EFI ECUs.

Shown are two nano boards. They are about the size of a thumb. They easily are connected and powered and programmed via the USB on a PC. I use the CodeVisionAVR C compiler, to write programs and load into the nanos. There is an Arduino IDE, but I have limited experience with that, and find no need for it.
View attachment 20150906_194826.jpg
The top board is the shift indicator, the bottom the ignition simulator. The output of the sim is connected to the input of the shift indicator, the second wire is common ground.

There is a serial connection via the USB not only for loading code but also for communicating with the micro. I used it to display the RPM, so with a terminal the shift indicator becomes a very accurate tachometer.
View attachment ShiftLt1.jpg
View attachment ShiftLt2.jpg
The two screen shots show the parts of the program I wrote, the rest is typical startup and initializations that are done with the compiler wizard. Sorry view is bad.
A zip of program files is here:
View attachment ShiftLite.zip

There 4 LED indicators on a nano, TX,RX, Power, and L. The power is always lit when power is available, TX indicates the nano is sending data via serial, RX means data is being received, L is a green LED that is turned on as the shift indicator.

The Nano schematic is found here:[ame="https://www.arduino.cc/en/uploads/Main/ArduinoNano30Schematic.pdf"]https://www.arduino.cc/en/uploads/Main/ArduinoNano30Schematic.pdf[/ame]

The CodeVisionAVR compiler is found here: http://www.hpinfotech.ro/

The data sheet for the ATmega328p used on the board is found by googling "ATmega328p datasheet" my attempt to attach that URL failed because the forum attempts to view a 650 page document, and fails. I just want to list the URL. If only I knew how to use a PC ....
 
Attached is the zip file for the engine timing sensor simulator. The Arduino timer 1 is set to run in the CTC mode. The OCR1A register is set for the maximum count to be reached before the counter resets to zero, then starts counting up again. At the time of reset, an output pin is toggled, that means it changes state. Two state changes are a complete cycle, four cycles is one RPM 0-1-0-1-0-1-0-1. The period is controlled by adjusting the OCR1A, a larger value entered there means more timer ticks to reach that value and slower simulated RPM. Lesser counts go the other way and result in higher RPM.

Constant RPM is achieved with a constant value of OCR1A, but by changing it the RPM can be varied. I wrote a few lines of code to ramp the RPM from about 650 to 7,000 RPM.

Note: comments are preceded by //

while (1) // main loop of program
{
delay_ms(11500/period); // generates a variable delay between changes
if (period-- >= 1050) // period-- subtracts 1 from the period, and checks if limit is reached
{ // the timer is a 16 bit register, the micro is 8 bit, so write register with two operations
OCR1AH = WORD_HI_BYTE(period); // set next event, with atomic operation
OCR1AL = WORD_LO_BYTE(period);
}
else period = 11500; // this resets to lowest RPM
}

I was non mathematical, and arrived at 11500 for low RPM, and 1050, by measuring periods with scope, they are approximate. There are many settings for crystal divisors and time clock prescalars. Changing those changes period. The important part, timer1 is a 16 bit timer, it can count from 0 to 65,535, so the low RPM number, cannot be set above that. The simulator is running slow, it takes several seconds for a complete RPM ramp. That can all be changed by reducing the timer resolution or reducing time between changes. That is an exercise for learning.

There are initialization settings for the timer1,not shown, but done with wizard. In this case it is set to CTC mode, with 500kHz clock rate, Output toggle on compare match of OCR1A.
 

Attachments

  • NgenSim.zip
    35.1 KB · Views: 115
Well thanks Dave!!! I promise I'll look through this, but I don't promise I'll ever find time to do anything with it, LOL
 
Del,
I won't tell everybody that you have a couple nano boards on the shelf. Add two wires , upload the programs, you will be running in minutes. :)

I am here to help.
 
I know, I know. I've also got a couple of Arduino "kit" boards here, as well as a "pi." Hell I can't get anything done anymore
 
Wow cool.
Now all I gotta do is get the time to play with it and get a few boards to experiment with.

Thank you K--- I mean Dave?
Why did you ever tell me that. :D
 
Here is the most used book for learning C: The C Programming Language Ritchie & Kernighan. It is available as an e-book, free online.
 
Last night I watched some Youtube video's on the Arduino chips and boards, and it looks pretty interesting.
I'm already fairly confident I could make a rev limiter easy enough using this tech to block the signal from the distributor to the ECU at a given RPM.
It also looks like one could make it RPM adjustable within the cabin and have a lit LCD screen showing the limit it is set at.
(Or to switch from white light to red at a certain RPM) :D

Now I see why Kit suggested it in the thread about dash lights changing at a set RPM.

The amount of hardware available is pretty impressive also.
Light sensors
sound sensors
Gyro's
LCD and LED panels
Stepping motors
servo's



All kinds of cool things.

Also downloaded the free "The C Programming Language Ritchie & Kernighan" in free PDF version.
 
To make the shift point adjustable for the least amount of work, would be to add two buttons, one for increase, the other for decrease. The constant value used in my code would be changed to an EEPROM stored value. EEPROM retain values after unit is powered down. Adding a LCD would be slightly more work, but would aid in adjusting settings.

The same timer1 that is used to measure RPM, may also be used to control an output pin, based on a control register called output compare. That pin could be used for control of engine timing. Since the period is measured for 90 degrees, you know the counts for that, and easily retard timing. That is the basis for all the EFI/IGN control in my systems. Retarding timing burns the fuel, but cuts power. In EFI systems the fuel is cut, but ignition stays on. Rev limiting is smooth when done correctly.

Timers and compares let you control only in the future. Since timer is free running, a future control is done by adding timer ticks to the "now" time to set the compare point. This is like setting an alarm clock. The "now" time is the timer value that was captured at the edge by the input capture ISR. The program flow is like walking stepping stones....

To do a shift light and rev limit two different setpoints/compare points are required.
 
To make the shift point adjustable for the least amount of work, would be to add two buttons, one for increase, the other for decrease. The constant value used in my code would be changed to an EEPROM stored value. EEPROM retain values after unit is powered down. Adding a LCD would be slightly more work, but would aid in adjusting settings.

The same timer1 that is used to measure RPM, may also be used to control an output pin, based on a control register called output compare. That pin could be used for control of engine timing. Since the period is measured for 90 degrees, you know the counts for that, and easily retard timing. That is the basis for all the EFI/IGN control in my systems. Retarding timing burns the fuel, but cuts power. In EFI systems the fuel is cut, but ignition stays on. Rev limiting is smooth when done correctly.

To do a shift light and rev limit two different setpoints/compare points are required.

From what I see and hear the code for a lot of functions has already been written by others and available online for download.
That way you could just find the basic code and tweak it as needed per application.
As far as the rev limiting goes, I would personally be more interested in building for NA engines, so it looks like ignition cut would be the only choice in that application.
 
From what I see and hear the code for a lot of functions has already been written by others and available online for download.
That way you could just find the basic code and tweak it as needed per application.

There is a bunch of C++ code written for Arduino, but I have not really looked at it or tried. It is fairly high level stuff and made with compatibility for all the platforms, so is layers deep. That means it is not very efficient for most real-time controls. An example is, if I want to control an output in C, that is one cpu instruction to change a bit, but via the C++ it takes around 25 cpu cycles. Getting to the core registers and changing values is easy in C, but may not be easy using the C++ language of Arduino IDE. I do not want to stop you from that. I looked at it from the back side, already done with C, can I do it with the direct elements in the Adruino IDE? My limited investigation suggested no way.

The CodeVisionAVR compiler has easy to use libraries too, for memory management, interfacing with LCD, SPI, and many other smart devices. The compiler is a great tool, always compatible with my existing projects. Open source code is forever changing, that can be a great disadvantage when you try changes in the future.
 
-
Back
Top