Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

HELP! Building Keyless Access for Automobile

Status
Not open for further replies.
You didn't set the state to 2 after extinguishing the LED.

However, using a delay is normally not a good idea as nothing else can happen like going back to state zero if key 0 is released. Better to let the interrupt preform the timing and just change the state when it times out.
Code:
        Case 3
            Lit.2=1         
            TimeUp=0        //reset flag
            Count=500*5     //wait 5 seconds
            state=4
        Case 4
            if TimeUp=1 then
                state=2     //if time up then go to state 2
            endif                
        End Select

This does require that the interrupt code is changed and so here is the full code,
Code:
Device = 18F1320
Clock = 8 // 8MHz clock
Config OSC = INTIO2, WDT = OFF, LVP = OFF

Dim NOT_RBPU As INTCON2.7
Dim TMR2IE As PIE1.1
Dim TMR2IF As PIR1.1

//global variables
Dim Lit As Byte
Dim IntFlag As Bit
Dim Count As Integer
Dim TimeUp as bit
Dim Row As Byte

//interrupt routine gets called 500 times per second
//and multiplexes the LEDs Aslo sets a flag after 0.5S.
Interrupt MyInt()
    TMR2IF=0
    Row=Row+1
    If Row=3 Then 
        Row=0
    EndIf
    TRISA = TRISA Or %11000001          //turn all LEDs off
    PORTA = PORTA And %00111110
    Select Row
        Case 0
            TRISA.0=0
            PORTA.0=1
            If Lit.0=1 Then
                TRISA.6=0
            EndIf
            If Lit.5=1 Then
                TRISA.7=0
            EndIf
        Case 1
            TRISA.6=0
            PORTA.6=1
            If Lit.1=1 Then
                TRISA.0=0
            EndIf
            If Lit.2=1 Then
                TRISA.7=0
            EndIf
        Case 2
            TRISA.7=0
            PORTA.7=1
            If Lit.4=1 Then
                TRISA.0=0
            EndIf
            If Lit.3=1 Then
                TRISA.6=0
            EndIf
    EndSelect
    if Count>0 then
        Count=Count-1
        If Count=0 Then
            TimeUp=1
        endif
    EndIf
End Interrupt

//main code starts here
Dim Keys As Byte
Dim Previous As Byte
Dim NewKeys As Byte
Dim State As Byte

OSCCON = $72            // select 8MHz internal clock
ADCON1  = $7f           //all digital
NOT_RBPU=0              //WPUs on port B
Lit=0                   //turn all LEDs off
T2CON = %01001110       //pre=16 post=10
PR2 = 25                //=8000000/4/16/10/25 = 500Hz
TMR2IE=1                //enable timer 2 interrupts
Enable(MyInt)           //set interrupt going
State=0
While true
    DelayMS(10)             //required for debounce
    Previous=Keys           //keep copy of previous key state
    Keys=PORTB Xor $ff      //get new keys and invert
    NewKeys=(Keys Xor Previous) And Keys //keep only new presses
    
    If Keys.0=0 Then        //if key 0 is released then reset
        State=0
    EndIf
    Select State
        Case 0              
            Lit=0           //if key1 pressed then light first LED
            If NewKeys.0=1 Then
                State=1
            EndIf
        Case 1          
            Lit.0=1         
            If NewKeys.2=1 Then
                State=2
            EndIf
        Case 2
            Lit.1=1
            Lit.2=0         //extinguish LED 2 incase we came from state 4
            If NewKeys.2=1 Then
                State=3
            EndIf
        Case 3
            Lit.2=1         
            TimeUp=0        //reset flag
            Count=500*5     //wait 5 seconds
            state=4
        Case 4
            if TimeUp=1 then
                state=2     //if time up then go to state 2
            endif                
        End Select            
Wend


Lit=1
While true
    DelayMS(10)             //required for debounce
    Previous=Keys           //keep copy of previous key state
    Keys=PORTB Xor $ff      //get new keys and invert
    NewKeys=(Keys Xor Previous) And Keys //keep only new presses
    If(NewKeys.0=1 And Lit.0=1) Then    //is button 1 pressed
        Lit.0=0
        Lit.1=1
    ElseIf(NewKeys.0=1 And Lit.1=1) Then
        Lit.0=1          
        Lit.1=0
    EndIf
Wend


While true
    DelayMS(10)             //reqired for debounce
    Previous=Keys           //keep copy of previous key state
    Keys=PORTB Xor $ff      //get new keys and invert
    NewKeys=(Keys Xor Previous) And Keys //keep only new presses
    If(NewKeys.0=1) Then    //is button 1 pressed
        Lit=Lit*2           //shift it left
        If(Lit=64) Then     //got to end
            Lit=1           //yes so wrap around
        EndIf
    EndIf
    If(NewKeys.2=1) Then    //is button 2 pressed
        Lit=Lit/2           //shift it right
        If(Lit=0) Then      //got to end
            Lit=32          //yes so wrap around
        EndIf
    EndIf
    
Wend


End

Have fun.

Mike.
 
wow. I've got a lot to learn about writing code to be able to do this myself. I was thinking about taking a class or two next semester!

Thanks again Mike. I'll let you know how that last bit of code goes.
 
I'm Happy to report that I finally got some more time to spend on the code, and I made more progress!!!!! Here is my latest code

Code:
Dim Keys As Byte
Dim Previous As Byte
Dim NewKeys As Byte
Dim State As Byte
                        //key.0 is RFID Input
                        //key.2 is Start/Stop Button
                        //key.5 is Brake SW Input

OSCCON = $72            // select 8MHz internal clock
ADCON1  = $7f           //all digital
NOT_RBPU=0              //WPUs on port B
Lit=0                   //turn all LEDs off
T2CON = %01001110       //pre=16 post=10
PR2 = 25                //=8000000/4/16/10/25 = 500Hz
TMR2IE=1                //enable timer 2 interrupts
Enable(MyInt)           //set interrupt going
State=0
While true
   DelayMS(10)             //required for debounce
   Previous=Keys           //keep copy of previous key state
   Keys=PORTB Xor $ff      //get new keys and invert
   NewKeys=(Keys Xor Previous) And Keys //keep only new presses

   If Keys.0=0 Then        //if key 0 is released then reset
       State=0
   EndIf
   Select State
       Case 0               //state 0    "Ignition OFF"
           Lit.0=0
           Lit.1=0
           Lit.2=0           
           If NewKeys.2=1 and Keys.5=1 then
               State=3
           elseIf NewKeys.2=1 Then
               State=1
           EndIf
       Case 1                   //state 1    "Accessory ON"
           Lit.0=1
           Lit.1=0
           Lit.2=0
           If NewKeys.2=1 and Keys.5=1 then
               State=3
           elseIf NewKeys.2=1 Then
               State=2
           EndIf
       Case 2                   //state 2        "Ignition ON"
           Lit.0=1
           Lit.1=1
           Lit.2=0         
           If NewKeys.2=1 and Keys.5=1 then
               State=3
           ElseIf NewKeys.2=1 Then
               State=0
           EndIf
       Case 3                  //state 3 "Start Sequence" 
           Lit.0=1
           Lit.1=1
           Lit.2=1
           TimeUp=0        //reset flag
           Count=500*5     //wait 5 seconds
           State=4
       Case 4
           If TimeUp=1 Then
               State=2     //if time up then go to state 2
           EndIf
       End Select
Wend


Lit=1
While true
   DelayMS(10)             //required for debounce
   Previous=Keys           //keep copy of previous key state
   Keys=PORTB Xor $ff      //get new keys and invert
   NewKeys=(Keys Xor Previous) And Keys //keep only new presses
   If(NewKeys.0=1 And Lit.0=1) Then    //is button 1 pressed
       Lit.0=0
       Lit.1=1
   ElseIf(NewKeys.0=1 And Lit.1=1) Then
       Lit.0=1
       Lit.1=0
   EndIf
Wend


While true
   DelayMS(10)             //reqired for debounce
   Previous=Keys           //keep copy of previous key state
   Keys=PORTB Xor $ff      //get new keys and invert
   NewKeys=(Keys Xor Previous) And Keys //keep only new presses
   If(NewKeys.0=1) Then    //is button 1 pressed
       Lit=Lit*2           //shift it left
       If(Lit=64) Then     //got to end
           Lit=1           //yes so wrap around
       EndIf
   EndIf
   If(NewKeys.2=1) Then    //is button 2 pressed
       Lit=Lit/2           //shift it right
       If(Lit=0) Then      //got to end
           Lit=32          //yes so wrap around
       EndIf
   EndIf

Wend


End

Now I'm having a hard time getting another input to work. I was hoping i could use one of the variable resistor inputs and its dip switch as an on/off switch to simulate the (on or off) input signal of an rpm switch. When on, I need it to interrupt 5 second 3rd led and set it back to state 2. Also, state 3 should not be attainable if the rpm input says the engine is already running.

Thanks again!
Kyle
 
Well, to read the VR on A1 you need to use the ADC. This is fairly easy to do once you get it setup. Here is my earlier code with the ADC bit added. All it does is light LED 6 (Lit.5) if the pot is turned past 1/4. I'll leave you to incorporate it into your modified code.

Code:
//main code starts here
Dim Keys As Byte
Dim Previous As Byte
Dim NewKeys As Byte
Dim State As Byte
Dim GO As ADCON0.1

OSCCON = $72            // select 8MHz internal clock
ADCON1 = %11110101      // digital I/O except RA1 & RA3
ADCON0 = %00000101      //A2D on and select AN1
ADCON2 = %00110101      //Left justify - Fosc/16
NOT_RBPU=0              //WPUs on port B
Lit=0                   //turn all LEDs off
T2CON = %01001110       //pre=16 post=10
PR2 = 25                //=8000000/4/16/10/25 = 500Hz
TMR2IE=1                //enable timer 2 interrupts
Enable(MyInt)           //set interrupt going
State=0
While true
    DelayMS(10)             //required for debounce
    Previous=Keys           //keep copy of previous key state
    Keys=PORTB Xor $ff      //get new keys and invert
    NewKeys=(Keys Xor Previous) And Keys //keep only new presses
    
    GO=1                    //start ADC
    While(GO=1)             //wait for conversion to finish
    Wend
    If(ADRESH>64) then      //if VR1 is 1/4 or more  
        Lit.5=1             //light last LED
    else
        Lit.5=0             //turn it off
    endif
    
    If Keys.0=0 Then        //if key 0 is released then reset
        State=0
    EndIf
    Select State
        Case 0              
            Lit.0=0         //extinguish LEDs
            lit.1=0
            lit.2=0
            If NewKeys.0=1 Then
                State=1
            EndIf
        Case 1          
            Lit.0=1         
            If NewKeys.2=1 Then
                State=2
            EndIf
        Case 2
            Lit.1=1
            Lit.2=0         //extinguish LED 2 incase we came from state 4
            If NewKeys.2=1 Then
                State=3
            EndIf
        Case 3
            Lit.2=1         
            TimeUp=0        //reset flag
            Count=500*5     //wait 5 seconds
            State=4
        Case 4
            If TimeUp=1 Then
                State=2     //if time up then go to state 2
            EndIf                
        End Select            
Wend

You will have to turn the VR1 dip switch on for it to work.

Mike.
 
I've been working on the code here and there, and I keep wondering why I need this part of the code? It won't work without it, and its odd that there are "If, Then" statements that don't even correlate to the way it works.

Code:
Lit=1
While true
   DelayMS(10)             //required for debounce
   Previous=Keys           //keep copy of previous key state
   Keys=PORTB Xor $ff      //get new keys and invert
   NewKeys=(Keys Xor Previous) And Keys //keep only new presses
   If(NewKeys.0=1 And Lit.0=1) Then    //is button 1 pressed
       Lit.0=0
       Lit.1=1
   ElseIf(NewKeys.0=1 And Lit.1=1) Then
       Lit.0=1
       Lit.1=0
   EndIf
Wend


While true
   DelayMS(10)             //reqired for debounce
   Previous=Keys           //keep copy of previous key state
   Keys=PORTB Xor $ff      //get new keys and invert
   NewKeys=(Keys Xor Previous) And Keys //keep only new presses
   If(NewKeys.0=1) Then    //is button 1 pressed
       Lit=Lit*2           //shift it left
       If(Lit=64) Then     //got to end
           Lit=1           //yes so wrap around
       EndIf
   EndIf
   If(NewKeys.2=1) Then    //is button 2 pressed
       Lit=Lit/2           //shift it right
       If(Lit=0) Then      //got to end
           Lit=32          //yes so wrap around
       EndIf
   EndIf

Wend

Also, I thinking about the hardware I'm going to use, and I was wondering if I should use 12v relays, or transistors? I like that transistors have no moving parts and should last longer. Plus there wouldn't be any field collapse to worry about, like with a relay. But, if I used a transistor, what kind would I use? I have only had experience with NPN and PNP types. It would need to handle probably 15amps, and I am going to measure what the amperage actually is before ordering anything. What do you guys think?
 
Last edited:
You shouldn't need that code. Post the cut down code that doesn't work and I'll have a look.

Mike.
 
Alright! Here it is!!! My code now does everything I want!!! :D

Please let me know if you see any problems with it. Also, it was mentioned on here before that the watchdog timer might mess with it. From what I understand, the watchdog timer prevents the program from freezing up. So what will it do with my program?? Could it just randomly reset the program to state 0?

Code:
Device = 18F1320
Clock = 8 // 8MHz clock
Config OSC = INTIO2, WDT = OFF, LVP = OFF

Dim NOT_RBPU As INTCON2.7
Dim TMR2IE As PIE1.1
Dim TMR2IF As PIR1.1

//global variables
Dim Lit As Byte
Dim Count As Integer
Dim TimeUp As Bit
Dim Row As Byte

//interrupt routine gets called 500 times per second
//and multiplexes the LEDs Aslo sets a flag after 0.5S.
Interrupt MyInt()
   TMR2IF=0
   Row=Row+1
   If Row=3 Then
       Row=0
   EndIf
   TRISA = TRISA Or %11000001          //turn all LEDs off
   PORTA = PORTA And %00111110
   Select Row
       Case 0
           TRISA.0=0
           PORTA.0=1
           If Lit.0=1 Then
               TRISA.6=0
           EndIf
           If Lit.5=1 Then
               TRISA.7=0
           EndIf
       Case 1
           TRISA.6=0
           PORTA.6=1
           If Lit.1=1 Then
               TRISA.0=0
           EndIf
           If Lit.2=1 Then
               TRISA.7=0
           EndIf
       Case 2
           TRISA.7=0
           PORTA.7=1
           If Lit.4=1 Then
               TRISA.0=0
           EndIf
           If Lit.3=1 Then
               TRISA.6=0
           EndIf
   EndSelect
    If Count>0 Then
       Count=Count-1
       If Count=0 Then
           TimeUp=1
       EndIf    
    EndIf     
End Interrupt

//main code starts here
//key.0 is Brake SW Input
//key.2 is Start/Stop Button
//key.5 is Engine On/Off
//VR1 is Proximity Detector
Dim Keys As Byte
Dim Previous As Byte
Dim NewKeys As Byte
Dim State As Byte
Dim GO As ADCON0.1
Dim Detect As Byte
Dim Eng As Byte

OSCCON = $72            // select 8MHz internal clock
ADCON1 = %11110101      // digital I/O except RA1 & RA3
ADCON0 = %00000101      //A2D on and select AN1
ADCON2 = %00110101      //Left justify - Fosc/16
NOT_RBPU=0              //WPUs on port B
Lit=0                   //turn all LEDs off
T2CON = %01001110       //pre=16 post=10
PR2 = 25                //=8000000/4/16/10/25 = 500Hz
TMR2IE=1                //enable timer 2 interrupts
Enable(MyInt)           //set interrupt going
State=0
Keys=0
Detect=0
Eng=0
While true
   DelayMS(10)             //required for debounce
   Previous=Keys           //keep copy of previous key state
   Keys=PORTB Xor $ff      //get new keys and invert
   NewKeys=(Keys Xor Previous) And Keys //keep only new presses

   GO=1                    //start ADC
   While(GO=1)             //wait for conversion to finish
   Wend
   If(ADRESH>64) Then      //if VR1 is 1/4 or more
       Lit.5=1             //detect status indicator
       Detect=1             
   Else
       Lit.5=0              
       Detect=0             //turn it off
   EndIf    
       
   If Keys.5=1 Then         
       Eng=1
       lit.4=1                 //engine is on
   Else 
       Eng=0
       lit.4=0                 //engine is off
   EndIf
   
  Select State
       Case 0               //state 0    "Ignition OFF"
           Lit.0=0            //Acc Relay
           Lit.1=0            //Ignition ON Relay
           Lit.2=0            //Starter Signal
           Lit.3=0            //Shutdown Buzzer
           Lit.4=0            //Eng status 
           If Detect=1 Then
               If NewKeys.2=1 And Keys.0=1 Then
                   Lit.0=1
                   Lit.1=1
                   DelayMS(1000)
                   State=3
               ElseIf NewKeys.2=1 Then
                   State=1
               EndIf
           ElseIf Detect=0 Then
               State=0
           EndIf
       Case 1                   //state 1    "Accessory ON"
           Lit.0=1
           Lit.1=0
           Lit.2=0
           lit.3=0
           If Detect=1 Then
           If NewKeys.2=1 And Keys.0=1 Then
               Lit.0=1
               Lit.1=1
               DelayMS(1000)
               State=3
           ElseIf NewKeys.2=1 Then
               State=2
           EndIf
           ElseIf Detect=0 Then
               State=0
           EndIf
           
       Case 2                   //state 2        "Key ON Engine Off"
           Lit.0=1
           Lit.1=1
           Lit.2=0
           Lit.3=0         
           If Detect=1 Then
               If NewKeys.2=1 Then
                   State=0
               EndIf 
               If NewKeys.2=1 And Keys.0=1 Then
                   State=3
               EndIf
               If Eng=1 Then
                   State=4
               EndIf
           ElseIf Detect=0 Then
               State=0
           EndIf
           
       Case 3                  //state 3 "Start Sequence" 
           Lit.0=1
           Lit.1=1
           Lit.2=1
           Lit.3=0
           TimeUp=0            //reset flag
           Count=500*5         //wait 5 seconds
           State=5
           
       Case 4                  //state 4 "Key ON Engine ON"
           Lit.0=1
           Lit.1=1
           Lit.2=0
           lit.3=0
           If NewKeys.2=1 Then
               State=0
           EndIf 
           If NewKeys.2=1 And Keys.0=1 Then
               State=0
           EndIf
           If Eng=0 Then
               State=2
           EndIf
           If Detect=0 Then
               TimeUp=0            //reset flag
               Count=500*60         //wait 60 seconds
               State=6   
           EndIf    
       
       Case 5                     //Timed Start Seq.
           If Eng=1 Then
               State=4
           EndIf
           If TimeUp=1 Then
               State=2
           EndIf        
      
      Case 6                     //Timed Shutdown 
          Lit.3=1
          If detect=1 then
              state=4
          Endif
          If eng=0 then
              state=0
          endif
          If TimeUp=1 Then
              State=0
          EndIf     
          If NewKeys.2=1 Then
                   State=0
          EndIf 
          If NewKeys.2=1 And Keys.0=1 Then
              State=0
          EndIf 
   End Select
Wend

End

Now I suppose the next step is changing the code to what it will be when it is not in the junebug.
 
Congratulations, looks like you learnt a lot and quickly.

Don't worry about the WDT as it's turned off in the config line.

Now you need to decide on a hardware design. I would guess the first thing would be to get the RFID tag working.

Mike.
 
what do you think about amperage draw when in state 0? Should I try to add code to make the PIC go into a sleep mode when idle for a while? Thanks.
 
The simple 7805 might work (I used it in few "not important" projects in the car) but some more specialised regulator should be used imho, for example: TA14832

screenshot1-png.25369

I'm in the process of designing the hardware, and I'm wondering if the voltage regulator needs to be connected like it is in the picture? I have to imagine it can be a little more simple than that for my application?

For Example, Can I just connect the Batt IN and IGN IN together and connect it to a always hot 12v? Then OUT1 to the VDD on the PIC? And of course ground the GND? Or do I need all those other pins connected as well?

Any help is appreciated. Thanks.
 
That regulator isn't going to give you much power it only puts out 80 ma to your pic. The one superbrew posted it way better.
 
I really think you need to go with specialised "auto" regulator like the one in that old post of mine. The "standard" regulator (like 7805 for example) might work but power lines in a car can be nasty, in my old car 7809 died twice (and was on huge heat sink with paste and all ) and the worst of all, it drained my battery twice (was very cold for a few days) ... changing it to some "auto" regulator (pretty similar connection schematic to TA14832) it worked like a charm ..

note that you do not have to use all the pins in TA14832 :)
 
worst of all, it drained my battery twice
That's why that one is so low on power. But what he is wanting to do you have to feed all your relays with some thing like ULN2803A witch adds a lot more parts. I would find something with more power that can switch to low power when the car is off. That chip you bring out of sleep to get full power
plus bring the 18f1230 out of sleep and your only getting 30mA more from sleep to power on.
 
thing is, the 7809 I used was "leaking current" when cold/moist .. that killed the battery (took 7 days of not driving to kill it .. but ..)

the TA14832 will give you 50mA on standby and 80mA on "enabled" output .. that's not "low on power", that's much more then this device should use... (you are not going to power the relay's with regulated 5V source)

The general idea would be to
- power the uC from standby power (50mA is enough)
- power the display with status and stuff (backlight) from "enabled power" (80mA is more then enough)
- everything else you power from unregulated 12V (relays etc)
 
To me I would think if you have a chip that can use this
Maximum current into VDD pin ..250 mA
It low power for that chip and he been taking about using 5 volts relays so what am I to think
Proximity detector.
Door handle.
Door-open monitoring.
Brake pedal.
Clutch pedal.
Stop/Start switch.
Engine RPM sensor. (is engine running above cranking speed?)
Vehicle speed sensor. (VSS - is the vehicle actually moving above a certain speed and would it be safe to switch off the engine at this speed and lose power steering etc.)
Parking brake.
Ignition circuit 1 feedback. (Auxiliary position - heater system, entertainment etc.)
Ignition circuit 2 feedback. (Ignition position - engine management, transmission management, ABS, Traction control, Stability control, etc.)
Starter feedback. (Is the engine actually cranking?)

The feedback inputs could be argued as being redundant, but there would be no point cranking the engine if the ignition 2 relay is not functioning correctly. Also, these inputs could be used for fault diagnosis - no output detected from Ignition circuit 1 relay, flash an LED indicator once and repeat. No output detected from Ignition circuit 2 relay, flash an LED indicator twice, pause, then repeat. No output from Starter relay, flash an LED three times, pause, then repeat.

Ok the last example (Starter) could theoretically be monitored by the Engine RPM sensor, but suppose the starter motor itself is actually faulty....you could probably rule out the relay as being the cause of a no-crank condition if you have an output, saving some time spent troubleshooting.


Outputs that should be considered:

Ignition circuit 1 relay.
Ignition circuit 2 relay.
Starter relay.
That's a lot
 
If it helps, this is what the regulator will be powering...

-Pic18f1320
-->3 outputs drive transistors which will activate the 12v relays
-->1 output drives a transistor which will power a small 5v buzzer/speaker.

I would like it to be able to drive 2 more transistors if I ever get around to building a steering column lock. I think that's it.

I'm kinda counting on you guys to help me wire the regulator, because I'm not sure what all the other pins are for. Plus, I'm not sure how it will work, considering the PIC will be controlling when the Ignition is on etc.
When I get home, I'll post my (work in progress) schematic I drew on Express Schematic (expresspcb.com).

Thanks!
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top