PDA

View Full Version : Remote Vehicle Starter Help



Art
- 12th December 2011, 01:27
Hi Guys, I have used a 16F877A to control a couple of relays so it can start my car. The sequence to start the car begins when the Unlock button on my remote keyfob is held down for approx two seconds. I have a working demo: http://www.youtube.com/watch?v=z61WynAPVfg The unit turns the ignition on, and then waits for the heater coils (diesel), and then cranks the starter motor for a period of time. Problem is, there is no ideal period to crank the starter since, depending on temperature, etc. the motor will be more difficult to start sometimes. Looks like I need some feedback from the engine to determine when it is running off it's own steam so the starter motor can be disengaged asap. The obvious feedback to use is the tachometer (Less than 100 RPM while cranking - approx 800RPM while idling). The turbo pressure sensor may also be useful (0 - 1.9 Volts while idling - 1.9 - 4.5 Volts while racing). The current program is cycling all the time, even the power LED is a POV display. Good news is while the starter motor is cranking I can stop everything and wait for any PBP commands that delay program execution such as COUNT or ADCIN. I'm thinking the tach signal would be the most reliable indication, so any programming ideas without having to make a full on digital tachometer(which I have never done)? I do still have RBO interrupt pin free in hardware. I'd like to consider all options and have my head clear before I go playing with the ECU in my vehicle. Cheers Art.

Art
- 12th December 2011, 01:32
Well I did press return after my sentences.

Charles Linquis
- 12th December 2011, 04:36
It is my belief that anytime you are controlling machinery of any sort, you need to use interrupts. People can wait, machines can't. It sounds like you aren't using DT-INTs, on a timer which would make pauses unnecessary, and which would allow you to read the RPM (assuming you have access to a signal - like the crankshaft position sensor) simultaneously with everything else. Search the forum for my tachometer example. Since uses a timer to poll pins, you can use any pin at all for your tachometer.
If you have a belt pulley on the engine, you can use that as well. Years ago, I glued two magnets on a pully (using JB Weld - a good epoxy), and read an engine's RPM with
a Hall-effect sensor mounted on a bracket that was about 6mm away.

amgen
- 12th December 2011, 12:46
Some alternators have a tach or "R" output that has different voltages during cranking and running. Some diesel or gas generators use that output to stop cranking.
Don

Art
- 13th December 2011, 00:56
Charles, I did see your post with that code before posting this. Some of it's description seems ambiguous to me, but that's likely my own fault. PRELOAD value for example... I don't know what my shortest tach half cycle is, and then in code comments it says "depends on clock speed", but I don't know what to change if using a 4MHz Xtal. Seems a lot to work out when I only need to measure the time between two pulses. The current program is cycling all the time as said in my first post, or the power LED wouldn't work... as I also said, it's a POV display. I'm not using any pause commands at all. Timing is done by counting program cycles so there is opportunity to multitask. The alternator does sound like a good idea, even if it doesn't have the right output as described, the output of the regulator wouldn't reach it's full voltage until idling. With the right resistor divider, I assume I could produce a logic high or low state on a pin so there would still be no halting program execution.

Charles Linquis
- 13th December 2011, 03:21
I think voltage out of the alternator is probably not an accurate measure. What if the battery is discharged?

PRELOAD is simply a var I load into TMR0 on every interrupt to get the interrupt period to be what I want. If you are running 7000 RPM and your tach signal is a square wave that has one cycle per revolution, then the period is 8.5 mSec, and a half-cycle is 4.25mSec. In order to make certain that you don't miss a pulse, your interrupt rate (period) would need to be 4mSec. At 4Mhz, PRELOAD would be 0xF067 (PRELOADH = 0xF0, PRELOADL = 0x67). Directly from MisterE's PIC MultiCalc.

Measuring the time between two pulses is OK if your signal is not "noisy". But the signals I had to measure were very noisy. Sometimes the time between two pulses was 1.5 mSec, sometimes it was 5mSec. That really screwed up my program. In order to get an accurate reading, I had to average a large number of pulses. Then my "quick and dirty" routine wasn't so quick anymore. And the slower the input signal, the longer my routine took.

Timer interrupts to the rescue. I run an interrupt at 500uSec. Now, I can measure any number of signals simultaneously - on any pin. I count transitions over a time interval - say half a second, and I automatically get the average number of pulses over that time interval. The best part is, it all takes place entirely in the background. I can read a variable anywhere in my program, and it has the latest RPM value. The accuracy is limited only by the sampling time.

b1arrk5
- 21st December 2011, 02:30
With a gas engine, I energize the fuel pump, wait a few seconds for preessure to stabilize, energize the ignition, read and store the battery voltage and then start a timer and energize the starter. The timer limits how long the starter can be engaged. As soon as the starter is engaged, I start to continuously read the battery voltage. When it rises a half a volt above the stored voltage value the starter is disengaged. I've used this system for years now, in two different vehicles, and it works great. If the timer times out, then the engine didn't start. In this case, I'll try again twice more.Hope this helps,Jerry

Art
- 21st December 2011, 08:48
I do have the device installed in the car now, but haven't done anything other than a timer for the starter,
and you can manually disengage the starter by pressing the button again while the starter is engaged.
This is not acceptable for the long term, but at least the hardware and existing software is all working well.

You would need a resistor voltage divider at the ADC input yes?

spcw1234
- 21st December 2011, 11:59
A voltage resistor divider would be needed! I would use 33K/12K or similar changing your 0-15VDC to 0-5VDC. I would first verify that your alternator produces voltage as soon as the engine starts. Newer vehicles with computer controlled alternators sometimes don't turn on immediatly. I have an automatic engine starter I built on a diesel engine and I am using a 5PSI oil pressure switch to check if the engine is running or not. Perhaps your motor has one of these already for an idiot light on the dash to show that there is no oil pressure.

timmers
- 21st December 2011, 21:08
I built an auto starter for a generator.
Used a hall effect sensor looking at the starter teeth of the flywheel. Fed this into TIMER 1 external clock input, and used it to count the number of pulses (teeth) over a time period. I then did some tests and measured the fastest it could crank when warm, then set a threshold about 20% higher. Never had a problem with it.

For the record, I built in lots of safety features, which included low voltage cutout, under speed cranking, low oil pressure, over temperature, with visual and audible warnings before starting and an emergency stop switch.

I was able to have a remote control panel in the house where I could display and configure the parameters or manually start the engine and switch over the electric contactors. Never used it in manual, auto was fine.

Art
- 22nd December 2011, 07:24
I can understand why people would do this with generators. Who wants to walk outside to start an engine :)

My alternator may not produce voltage straight away (although I'm pretty sure it does),
I am able to see an initial voltage, then a drop while cranking, then a gradual rise to a higher voltage.

I think this is nice because I should be able to use the supply leg of the 7805 to take
the voltage measurement, and need no extra wires.

b1arrk5
- 24th December 2011, 01:27
I used a voltage divider. For my test circuit, I had the ADC continuously read the voltage, and send the result out the serial port. With my laptop watching the serial port, I started the car, and had before and after battery voltage readings. Merry Christmas,Jerry

amgen
- 24th December 2011, 02:00
Cool deal, my guess about voltages is about 8 volts cranking and jumps to 12 to 12.8 when first starts ? A rare problem with that setup is a dying battery that sits at rest at 12 volts but when starter enguages, the voltage dips so low that the starter drops out and the voltage goes up then repeats that chatter in and out. Not sure how you would detact that. Timmers may have thought of that but with more circuitry.
Don

Art
- 28th December 2011, 11:17
I'm not having any luck using the ACD of a 16F877A.
Maybe I should have given the thing a better output than a flashing light,
but I'm pretty sure I'm getting a zero reading every time.
The circuit always waits for the timeout to stop the starter motor.

if anyone likes to take a look...






' Remote start controller
' for '92 Toyota Surf
'
DEFINE OSC 04 'hardware is using a 4MHz crystal
DEFINE ADC_BITS 10 '10 bit ADC for 16F877A
'
adcon1.0 = 1 : adcon1.3 = 1 'set porte pins digital
trise.0 = 1 : trise.2 = 1 'set porte pins as inputs
trisb.1 = 1 : trisb.2 = 1 'set portb pins as inputs
trisd.2 = 1 : trisd.3 = 1 'set portd pin as input
trisa.0 = 1 : trisa.1 = 1 'set all analogue channels as inputs
trisa.2 = 1 : trisa.3 = 1 '
ADCON1 = 0 'set analogue inputs
ADCON1.7 = 1 'right justified for 10 bit ADC
'
seq var byte 'run sequence flag
timea var byte 'time lsd
timeb var byte 'time msd
timec var byte 'timer
timed var byte 'timer
timee var byte 'timer
xtimed var byte 'timer
xtimee var byte 'timer
debouncea var byte 'input a debounce counter
debounceb var byte 'input b debounce counter
debouncec var byte 'input c debounce counter
srelay var byte 'starter relay status
irelay var byte 'ignition relay status
bvoltage var word 'battery voltage value
avoltage var word 'running voltage value
ttiimmee var byte 'timer
held var bit 'button held flags
xheld var bit '
rlock var bit '
gosub reset '
'
'
main:
if timeb > $04 then '
'
if srelay = 0 then '
high portb.5 'led on
else '
low portb.5 'led off
endif
endif '
pauseus 500 'delay
if irelay = 0 then '
low portb.5 'led off
endif '
'
timea = timea + 1 'increment timer
if timea = $FF then '
timeb = timeb + 1 '
timea = 0 '
endif '
'
if timeb = $06 then 'check timer
if timec < $F0 then '
timec = timec + 1 '
endif '
timeb = 0 'reset timer
endif '
'



'
'
if debouncea < $F9 then 'increment debounce a timer
debouncea = debouncea + 1 '
endif '
if debounceb < $F9 then 'increment debounce b timer
debounceb = debounceb + 1 '
endif '
if debouncec < $F9 then 'increment debounce c timer
debouncec = debouncec + 1 '
endif
'
if debouncea = $F9 then '
if portb.1 = 0 then 'ignition off button, yellow wire
seq = 0 'end sequence
irelay = 0 'turn relays off
srelay = 0 '
gosub reset '
endif '
endif '
'
if debounceb = $F9 then '
if portb.2 = 0 then 'violet wire... unlock button
debounceb = $F8 '
held = 1 '
timed = timed + 1 '
if timed = $FE then '
timed = 0 '
timee = timee + 1 '
endif '
endif '
if portb.2 = 1 then '
held = 0 '
timed = 0 '
timee = 0 '
debounceb = 0 '
endif '
if timee > $09 then 'unlock button held delay define here
timed = 0 '
timee = 0 '
debounceb = 0 '
held = 0 '
seq = 1 'activate sequence
timec = 0 '
endif '
endif '
'
if debouncec = $F9 then '
if portd.2 = 0 then 'blue wire... lock button
debouncec = $F8 '
xheld = 1 '
xtimed = xtimed + 1 '
if xtimed = $FE then '
xtimed = 0 '
xtimee = xtimee + 1 '
endif '
endif '
if portd.2 = 1 then '
xheld = 0 '
xtimed = 0 '
xtimee = 0 '
debouncec = 0 '
endif '
if xtimee > $09 then 'lock button held delay define here
xtimed = 0 '
xtimee = 0 '
debouncec = 0 '
seq = 0 'end sequence
rlock = 0 '
irelay = 0 'turn relays off
srelay = 0 '
gosub reset '
endif '
endif '
'
if seq = 1 then '
irelay = 1 'turn on ignition power relay
if timec = 02 then '
srelay = 1 'turn on starter motor relay
endif '
'
if srelay = 1 then '
'
ttiimmee = ttiimmee + 1 'increment timer
if ttiimmee = 70 then 'time between samples is set here
ADCIN 0, avoltage 'read running voltage
if avoltage > bvoltage + 1 then 'detect vehicle start
srelay = 0 'turn off starter motor
endif '
ttiimmee = 0 '

bvoltage = avoltage 'remember old voltage reading


endif '
'
if portb.2 = 0 then '
timec = $03 '
timeb = $02 '
rlock = 0 '
srelay = 0 '
low portd.1 '
pause 1000 '
endif '
endif '
'
if timec = $03 then 'starter motor on time defined here
if timeb = $03 then '
rlock = 0 '
srelay = 0 'turn off starter motor
endif '
endif '
'
endif '
'
if seq = 0 then irelay = 0 'turn off ignition power relay
'
'
if srelay = 0 then 'set starter relay state to starter relay flag
rlock = 0 '
low portd.1
else
high portd.1
endif
'
if irelay = 0 then 'set ignition relay state to ignition relay flag
low portd.0
else
high portd.0
endif
'
goto main 'repeat main loop
'
'
reset:
srelay = 0 : irelay = 0 'reset relay status for start program
timea = 0 : timeb = 0 'reset timer variables for start program
timec = 0 : timed = 0 '
timee = 0 : ttiimmee = 0 '
xtimed = 0 : xtimee = 0 '
debouncea = 0 : debounceb = 0 'reset debounce timers
debouncec = 0 '
held = 0 : xheld = 0 'reset flag
avoltage = 0 : rlock = 0 '
bvoltage = 65533 '
low portd.1 : low portd.0 'start with relays off hardware controlled
seq = 0 '
return '
'
'
'
'
'


Cheers, Art.

mackrackit
- 28th December 2011, 12:19
This sorta conflicts
adcon1.0 = 1 : adcon1.3 = 1 'set porte pins digital
With This
ADCON1 = 0 'set analogue inputs
ADCON1.7 = 1 'right justified for 10 bit ADC
But the last two lines should be OK. See register 11-2 in the data sheet.

Not sure I follow this:
ADCIN 0, avoltage 'read running voltage
if avoltage > bvoltage + 1 then 'detect vehicle start
avoltage will not be greater than 1023.. 10 bit
Then there is this
bvoltage = 65533

Art
- 29th December 2011, 03:45
I'll have to look at the ADCON1 register. I think there is some insight for me there.

The initial value for bvoltage is set higher than any 10 bit reading can be so the flag is not triggered on the first cycle.
It could just as easily be 1024, but it's a 10 bit value stored in a 16 bit word var, so I can use a higher number.

bvoltage is the last reading stored for X number of cycles to be compared to the current value which is avoltage.
If no branch condition is met, then the current value becomes the last value for comparison the next time.

b1arrk5
- 1st January 2012, 06:03
I'll try to see if I can find some code. I've been doing Arm7 C programming the last two years, so I have to dig out my old basic files. My code worked well in two Ford vehicles, and I drove them both through a full winter using the starter every cold winter morning! I built the first one on a Lab-x board from melabs, it has an LCD to show whats happening, but the output to the laptop was safer for testing because I had history to look at after I drove the car.If the initial battery voltage was about 11 vdc, the processor would refuse to try to start the engine. I typically see 12.4 to 12.8 before the starter engages, and 13.8 or so as soon as the starter is disengaged. Happy New Year!Jerry

mister_e
- 1st January 2012, 11:21
Happy new year y'all!

I've installed remote car starter for 12 years and there's quite a few method you can use if you don't have any Tach signal generated by the Alternator, available on the Cluster connector or ECM.

The oldest method in early 90's
1) use a vacuum switch...
Con:
not always easy and doable to find a proper vacuum source/hose,
need to cut the hose, and take chance the switch could freeze

The next most popular in those years
2) read the Battery voltage, should be 'round 13.8ish V when the vehicle is started
Con:
Starter often stay engaged when not properly implemented or with "Soon to die" alternator

The most valuable and still in use solutions are
1) use a Field effect sensor attached on the top of the alternator.
Easy to implement, but some alternator do not generate enough magnetic field, OR have their own
"Strong Sweet spot", so you may have to monitor it to find the sweet spot. And once you find it, sometime it's just not simple to sit your detector there. You also need to route more wires.

2) read the Alternator output, the wire that goes "High" when the vehicle is started
The easiest solution, easy to implement with an averaged ADCIN routine (plus some extra pause and double/triple check) and a really strong power supply, board and noise filtering design. The safest and easiest in the installation field. Most alternator have this specific output.

3) grab the junk generated by the alternator on the 12V line and use it as "Tach" signal
Really popular available and patented by many car starter brand. If properly designed it works a treat for all type of car, truck, everything and do not require any extra wiring.

Enjoy, back to my batcave.

Art
- 4th January 2012, 01:02
Thnaks for the ideas mr_e :)

mackrackit (http://www.picbasic.co.uk/forum/member.php?u=220),
I set the pins to analogue after setting them digital, so I don't think that's the problem using ADC.

Art
- 30th January 2012, 15:54
Now, I can measure any number of signals simultaneously - on any pin
How, if there's only one interrupt pin (RB0), do the newer pics have more, or is there a trick?

I'm up to this:
http://www.youtube.com/watch?v=DwSt6ONWBTs

& would like to do a tachometer if it could be done on the same chip.
Maybe a way to cause the input for every pin pulse RB0, and then check the status of other pins..

mackrackit
- 31st January 2012, 10:57
Comparator Interrupt maybe

Darrel has several if not all setup for ease of use.
http://darreltaylor.com/DT_INTS-14/intro.html

Art
- 31st January 2012, 15:46
I'm thinking you could connect a signal diode between each pin and RB0 so that a pulse to any pin would also trigger RBO interrupt.
Then in the interrupt service routine go and check which pin has the pulse on it... if it can be done fast enough.

Art
- 20th February 2012, 01:40
Just got the tachometer working yesterday without any interrupt! :)

I decided to check the tach signal port in the main loop
just to roughly check the engine is not already running before engaging the starter motor.

I found that a single pulse is counted several times.
Adjusted the check to count only low to high transitions,
and voila! I have my pulse count!! :D

This would probably be too low res to measure time between pulses, and program adjustments would interfere
with timing so I count the number of pulses over a second for a display that is updated every second.
Not bad for free though ;)