[AVR] How to monitor external circuitry for a car project? ATMega 8-bit - Page 1
Forum section: electronics / general

author: expertmax
author_rank: Regular Contributor
timestamp: April 21, 2014, 09:25:44 pm
content: Hi folks, mates and cobbers,I have a verynicelittle project going on right now! I'm building a "Push To Start" button on my car (Subaru Forester) which will allow me to start the carjust by pressingthe "Start" buttonwithout having to hold it(the MCU will disengage the starter relay when itsenses that the engine is running).My project isworking wonderfullyon a breadboard, the MCU is programmed and responds to my switches. My main issue right now is thatI need a way to monitorthe frequency of the RPM signal to the tachometer. The signal is afixed PWM with a varying frequency... Now how do I program my MCU for when the frequency on the tachometer reaches thevalue for 1000 RPMthe relay releases.To sum my coding :0- Battery voltage supplied by the HOT AT ON positionfrom the ignition switch.1- Wait for user's Push To Start button to be pressed.2- If button pressed and it's thefirst timeit is being pressed, activate relay. If not, loop.3- Loop in the previous statement until tachometerreads more than 1000 RPM, then release relay.4- Set theinternal variableso the button cannot be pressed a second time.Thanksfor your help !![I'm going to include screen shots in a few seconds]

author: Andreas
author_rank: Super Contributor
timestamp: April 21, 2014, 09:50:45 pm
content: Hope you will never try to use this in your car.Usually there are much more measures to do against the hazard of unintended movement of the car as in your example.some typical measures are:- use 2 relays in case of one contact is welded. (often 2 different control units are involved).- monitor the relay contacts and disable automated start if one of the contacts is defective.- use clutch + neutral gear information- use a ASIL B certified hardware (monitoring module monitors processor and independantly disables the power stages)- Hardware disabling of the relay when T15 is off.Usually you can get the rpm value from CAN bus.with best regardsAndreas

author: dannyf
author_rank: Super Contributor
timestamp: April 21, 2014, 09:57:09 pm
content: 1 I would use logic names for those pins in case you need to relocate them.2. I would consider using a state machine for this.3. As to reading the frequency, I would double check that. A fixed duty cycle varying frequency signal wouldn't be natural for an analog Speedo.if you under need to read the frequency, I would use a counter to generate a time base and use input capture or external interrupt or simple pulling, if the signal is sufficiently fast.

author: expertmax
author_rank: Regular Contributor
timestamp: April 21, 2014, 10:08:33 pm
content: Quote from: Andreas on April 21, 2014, 09:50:45 pmI have experience working on cars but not AVRs (it's a little hobby of mine).1) The clutch start switch is still going to work because I'm going to feed signal directly to the START position on the Ignition Switch.2) There is no need to monitor the relay contacts because the relay is OFF by default and the MCU will be powered only when the key is set to ON from the Ignition Switch as well. And you know, worst case scenario : if the relay activates by itself the starter is going to grind, I'm going to notice it and turn off the car... that is if my foot is on the clutch.3) It's muuuuch more complicated to use the CAN bus, I need extra wires, extra chip (ELM317 or CAN-enabled AVR), extra coding, much more hardware (communication integrity issues).In terms of safety hasards, this mod is far from being unsafe !

author: expertmax
author_rank: Regular Contributor
timestamp: April 21, 2014, 10:18:05 pm
content: Quote from: dannyf on April 21, 2014, 09:57:09 pmHonestly I don't have a scope (yes, will buy one one day !) and I could not monitor the frequency but a friend of mine who works in the field of flashing car ECU's for performance and stuff told me this is the way they worked, well subarus. He might be wrong but I don't think the tachometer is analog. I'm using an automotive software called "ALLDATA" and in the description says the signal is frequency-based (not 100% sure about the duty cycle tho).How a counter would work in this case? It might be the way to go !

author: zapta
author_rank: Super Contributor
timestamp: April 21, 2014, 11:23:44 pm
content: Instead of measuring the frequency measure the time between pulses, once it's short enough for your target rpm turn the relay off.

author: dannyf
author_rank: Super Contributor
timestamp: April 21, 2014, 11:54:36 pm
content: QuoteThe datasheet would be your best source on that.In the mean time, if your pulse train is "nice" (not too slow and not too fast), the following would work:Code:wait for the signal pin to go low; //so you don't count partial cycleswait for the signal to go high;while (signal is still high) {delay 1 unit of time;increment count1; //count1 has duty cycle}while (signal is low) {delay 1 unit of time;increment count2; //count2 has period - duty cycle}return count1 + count2; //count1 + count2 = periodYou just need to operationalize it.

author: SL4P
author_rank: Super Contributor
timestamp: April 22, 2014, 12:58:59 am
content: Quote from: Andreas on April 21, 2014, 09:50:45 pmTo be fair - I think it's a very interesting project, butthe fail-safe aspects do need to be strongly considered- being fail-safe in themselves.If the relay can 'accidentally' fail or activate when you're at revs - the starter motor will end up on the seat next to you.If your neighbour's kids are standing behind the car, and regardless of sensors, the ATtiny decides top do its thing - then bad luck.Perhaps use a watchdog timer as well if you can see a way to implement more software security.Luck shouldn't come into it.Good luck with this - add some strong filter / decoupling caps, and triple check your solder joints & mounting.

author: expertmax
author_rank: Regular Contributor
timestamp: April 22, 2014, 02:13:35 am
content: Quote from: SL4P on April 22, 2014, 12:58:59 amHaha that wouldn't be nice but it is very unlikely to occur because the clutch needs to be pressed in order for the starter relay to click because of the Clutch Start Switch in the circuit.I'm going to read more about Watchdog Timers since I'm not an electronics student.

author: SL4P
author_rank: Super Contributor
timestamp: April 22, 2014, 02:22:15 am
content: Quote from: expertmax on April 22, 2014, 02:13:35 am

author: expertmax
author_rank: Regular Contributor
timestamp: April 22, 2014, 02:29:26 am
content: Quote from: SL4P on April 22, 2014, 12:58:59 amClutch down = engine revving down... And as soon as I depress the clutch the starter relay is going to switch off because of the Clutch Start Switch. I've seen people accidentally re-start their car while it as already running and no harm done. It is going to wear off the starter shaft gear or the ring gear on the flywheel (very unlikely) but nothing is going to explode.Anyway my original question was how to process input using an AVR, not how to prevent starter damage.

author: Rerouter
author_rank: Super Contributor
timestamp: April 22, 2014, 02:34:23 am
content: You will have to wait 5 hours for me to return home, but i have the circuit and the code on how to do this, as this was one of the input functions on a tester I've built,My code uses a falling interrupt to count the uS between pulses, and from this determine the frequency very easily, as ball park, V4 = 100Hz @ 3000RPMV6 = 150Hz @ 3000RPMV8 = 200Hz @ 3000RPM,or at-least those are the standard outputs of the electronic ignition controller,Don't forget to run what you measure through a filter, generally a window (cut out values that are more than x% more or less than the last average, and what is beyond possible for the car) then a rolling filter, this way load dump wont upset it,

author: expertmax
author_rank: Regular Contributor
timestamp: April 22, 2014, 03:07:40 am
content: Meanwhile, can you tell me if this circuit makes any sense in terms of frequency calculations?/** PushToStart.c** Created: 2014-04-4 4:44:44 PM* Author: expertmax*/#define F_CPU 1000000UL#include <avr/io.h>#include <avr/interrupt.h>#include <util/delay.h>int firstpass = 0;int rpm = 0;int main(void){DDRB |= (1 << PB4);MCUCR |= (1 << ISC00);GIMSK |= (1 << INT0);sei();while(1){if(bit_is_set(PINB, PB3) && firstpass == 0){PORTB |= (1 << PB4);while(rpm < 50){rpm = 0;_delay_ms(100);}PORTB &= ~(1 << PB4);firstpass = 1;cli();}}}ISR(INT0_vect){rpm++;}

author: Rerouter
author_rank: Super Contributor
timestamp: April 22, 2014, 07:41:55 am
content: First Off, my code (i am still tethered to the arduino IDE, so forgive me here), I've removed bits that would be more confusing than helpful, so it may be missing a bracket somewhereCode:volatile unsigned long Rising1 = 0; // Volatile variable for low frequecy measurementvolatile unsigned long Rising2 = 0; // Volatile variable for low frequecy measurementvoid Frequency() { // Frequency Counting Interrupt FunctionRising2 = Rising1; // Assign Last TimeRising1 = micros(); // Assign Current Time}Void FreqMeasure() {unsigned long TempHz = 0;unsigned long TempRise1 = 0;unsigned long TempRise2 = 0;unsigned long uS = 0;while(1) {TempRise1 = Rising1;TempRise2 = Rising2;uS = TempRise1 - TempRise2; // Get The Differenceif(micros() - TempRise1 <= 1500000) { // Timeout if its taken more than 1.5 secondsTempHz = 1000000/uS; // Divide 1 Second by the time for Hz}else {TempHz = 0; // If timed out Set To 0}}}Below is my circuit i have on my input, You could likely get away with hooking the right side of R24 into your micro and removing the U5A bit, and scrapping U5B with a pull down to ground around 47K (that was a sensitivity adjustment on its original device, with the second op amp being a schmitt trigger)The transistor bit just protects the micro from ever seeing any spikes, with C9 and R26 limiting the current for Q9, and D8 to protect the Base- emitter junction of the transistor against negative spikes,

author: pmbrunelle
author_rank: Regular Contributor
timestamp: April 22, 2014, 07:45:10 am
content: I wouldn't hard-code the 1000 RPM transition. At that speed, I think you'll be leaving the pinion engaged far too long. The transition RPM really needs to be tunable. For this purpose, a simple trimpot connected to an analog input on the micro should do the trick. Typically, automotive cranking speeds will be less than 300 RPM. Once the engine fires, it will accelerate on its own, without further assistance from the starter. To tune the transition speed, I would start low, then slowly increase the transition RPM until it just self-sustains, then make the permanent RPM setting ~1.25 times the barely-works RPM.In your power supply design, make sure the regulator doesn't drop out; consider that during cranking the voltage can drop below 9 V. Also, continuous overvoltage can happen on a car.Add some sort of timeout feature, so that if cranking time exceeds 5 seconds or so, stop!Quote from: Andreas on April 21, 2014, 09:50:45 pmIf your car has a CAN bus, it's too recent!

author: dannyf
author_rank: Super Contributor
timestamp: April 22, 2014, 10:52:59 am
content: QuoteThe basic structure will work. I would think about a few things:1) put it in a separate function to make the code easier to read;2) initialize the int0 pin;3) declare rpm a volatile type;4) think about how to maintain rpm's atomicity if it is a multi-byte type: you don't want it to return inconsistent data.

author: PeterG
author_rank: Frequent Contributor
timestamp: April 22, 2014, 11:52:10 am
content: Another way of sensing the engine has started would be to monitor the current the starter motor is pulling. When the engine starts the starter current should drop considerably causing the MCU to open the starter relay. This method could be more flexible due to it not being dependent on CAN bus or reading pulses from a tach system.Regards

author: expertmax
author_rank: Regular Contributor
timestamp: April 22, 2014, 12:45:56 pm
content: Quote from: pmbrunelle on April 22, 2014, 07:45:10 amI'm afraid that human reaction speed is not fast enough to release the starter when the engine just goes past over 300 RPM. I have to leave the starter a bit longer because the engine might sputter or even stall because of the sudden drop in the fuel line (and I know that from experience)...My original questions is still "How to monitor external circuitry". I don't need tips I've done the maths.

author: expertmax
author_rank: Regular Contributor
timestamp: April 22, 2014, 12:50:18 pm
content: Quote from: Rerouter on April 22, 2014, 07:41:55 amSheesh that's some good input filtering ! Of course I don't need something that precise but I might keep this schematic for a further project : Car ECU.Meanwhile your code looks like the last one I did, it's a tad too early for me to jump back in my project but I will have a go tonight ! Thanks mate !

author: expertmax
author_rank: Regular Contributor
timestamp: April 22, 2014, 12:52:52 pm
content: Quote from: PeterG on April 22, 2014, 11:52:10 amWe have -30 winters here, the load on the starter would be about the same when the engine will start, I'm afraid it's not going to be fail safe but still a very good idea.

author: expertmax
author_rank: Regular Contributor
timestamp: April 22, 2014, 01:10:28 pm
content: Quote from: dannyf on April 22, 2014, 10:52:59 am1) My own preferences2) No need, already initialized3) I don't know what a volatile type is but I'll listen to you!4) Nope, plain old fequency based 2003-era tach system.

author: pmbrunelle
author_rank: Regular Contributor
timestamp: April 22, 2014, 06:09:41 pm
content: Quote from: expertmax on April 22, 2014, 12:45:56 pmYou obviously haven't done the math, because the key is released well before 1000 RPM.I have datalogged enough engine starts to know this.

author: Rerouter
author_rank: Super Contributor
timestamp: April 22, 2014, 08:33:48 pm
content: Quote from: expertmax on April 22, 2014, 01:10:28 pmVolatile tells the compiler to make it so the value is directly read every time, rather than assuming that until another normal function has changed it it is the same,so as you have an interrupt doing your counting / time measurement this ensures that it will get the current values every timeWhat Danny was going on about making the code atomic was ensuring that in the few uS it takes to read in this volatile variable to your code, that if its wider than 8 bits half of it doesn't change while your in the process of reading it, to accomplish this you could simply disable that one interrupt while reading, or set a flag in the main code that when compared in the interrupt makes it skip updating while set,

author: expertmax
author_rank: Regular Contributor
timestamp: April 23, 2014, 01:26:08 am
content: Quote from: pmbrunelle on April 22, 2014, 06:09:41 pmWrong; next time you start your car take a look at the tachometer, jumps right to 1500 (in my case) before you release the key. You have a reaction time of 250ms, enough for the engine to rev up to 2500 rpm easily. I'm not speaking of relative inertia and injection rate which could double the value.

author: expertmax
author_rank: Regular Contributor
timestamp: April 23, 2014, 01:48:57 am
content: Quote from: Rerouter on April 22, 2014, 08:33:48 pmI 100% understand what you mean ! But I'm afraid my AVR-C skills are way too poor for this kind of calculation ! I dug back my old Arduino, generated a constant 150 hz, 100 hz and 50 hz and I got consistent results using that 100 Ms for the "interrupt pile-up timeout" that I originally coded.Next step on my list is to make this Arduino Frequency Counter and figure out the frequency of either the tachometer or the coil signal to the coil packs at near 1000 rpm, then calculate the milliseconds of that frequency, run it through my current test jig and use that number as the "release starter" variable. Sheesh was that easy to understand? Even I have trouble reading myself.

author: Mechatrommer
author_rank: Super Contributor
timestamp: April 23, 2014, 09:18:23 am
content: a while back i designed "starter cutoff while engine on" circuit without mcu, just relays and passive components. has been installed in my car for about a year or so, worked wonderfully, nobody (including me, the wife and the kids) will be able to crank the starter during engine ON again. tap the tacho line from ecu to the speedmeter, its PWM, iirc PWM freq = engine RPM / 60, 12V or 5V maxed logic 1 output iirc... feed it to buffer opamp and then low pass it to get average voltage. feed to a comparator with adjustable Vref to cutoff relay if RPM go to some threshold, i set at 500RPM. you can modify the lowpassed output to your mcu and decide by comparing ADC on the spot whenever you like, no need interupt no need clock counting. if your car is modern dont worry of thing like welded contact. the starter line in your car key (below the steering top of your lap) is actually another relay drive driving bigger starter relay outside in the bonnet, so you are fedding relay drive into your relay circuit, ie low ampere there. if your car is old, wear proper dressing and glove while driving to avoid electrocution during driving. please drive safeYMMV.

author: dannyf
author_rank: Super Contributor
timestamp: April 23, 2014, 11:00:32 am
content: QuoteWow!That's one wacky PWM signal for sure,

author: Rerouter
author_rank: Super Contributor
timestamp: April 23, 2014, 11:12:21 am
content: I agree, very odd, to be that low frequency your really in the electrical noise of the system, I'm guessing yours was a V8 with a divide by 4 converter hidden somewhere, as I've only seen frequencies that low when people get fancy with aftermarket ignition control modules, (I've seen at least a dozen V8 vehicles with 2 bastardized V4 controllers running in parallel and voodoo magic linking them together)Also Pro-tip to the op, you will want my fancy filtering if your looking at the low side of an ignition coil, 300V spikes are common, and forget direct high side measuring, better way is to wrap your test lead around one of the spark plug leads, and induce the signal,

author: Mechatrommer
author_rank: Super Contributor
timestamp: April 23, 2014, 03:01:22 pm
content: i found the old capture (engine at 1000rpm)... the exact value is pwm_freq = rpm / 30.... but i believe its specific to my car brand and model, yours maybe different. i dont care as long my cutoff circuit works and the speedometer showing the right rpmor maybe you or i misunderstanding between rev/min and rev/sec? 1000rpm = 16.7rps, so its about thereedit: my mistake, the main circuit was not a mere low pass pwm-to-v, but actually freq-to-voltage converter using 555 i found in the net last time.

author: dannyf
author_rank: Super Contributor
timestamp: April 23, 2014, 03:27:45 pm
content: QuoteGlade that you figured that out. It would have been a miracle for a low-pass filter to generate a voltage output that varies with input frequencies.

author: expertmax
author_rank: Regular Contributor
timestamp: April 26, 2014, 02:23:18 pm
content: Would you guys have any circuitry for that ? Parts list ? I'm not very good at op-amps, comparators, voltage followers, etc... I really need to buy a scope.

author: Mechatrommer
author_rank: Super Contributor
timestamp: April 26, 2014, 03:06:51 pm
content: http://www.circuitstoday.com/f-to-v-converter