1. 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.
    Dismiss Notice

HELP! Building Keyless Access for Automobile

Discussion in 'Microcontrollers' started by thekyguy11, Jan 15, 2009.

  1. thekyguy11

    thekyguy11 New Member

    Joined:
    Jan 12, 2008
    Messages:
    104
    Likes:
    1
    I attached my first attempt at a State Diagram, How does it look?

    I don't think I mentioned about the Siren Output yet. I want it to warn the driver if the Prox Detector loses signal of the "KEY" (I don't even know what the device is called yet, lol) while in State 2,3, or 4. I'll have to check how the Acura TL is setup, but I know if you leave the car running and take the Key FOB out of range it sends a warning beep, then I think there is a timer for how long it will remain on, unless the FOB is brought back into range.

    Also, as far as an RPM input, should I build an RPM switch that outputs a simple ON/OFF to the PIC once the right RPM is reached, or should I connect an RPM signal right into the PIC and have the program handle it? Or should I go back to my original plan to build the rpm switch and wire it to a starter cut relay?

    I'm learning so much with this, and you guys have been great so far. Thanks again.
     

    Attached Files:

  2. arhi

    arhi Member

    Joined:
    Apr 17, 2008
    Messages:
    887
    Likes:
    12
    Location:
    Belgrade, .rs
    rethink the 3->1 change .. note for "blue" start pressed that it is with brake "not pressed" .. but in general, it looks ok, just check if that's what you want :) .. it is very easy to read :) ...

    also, you might think about that 3->1 as if engine is off, that's fairly clear but, if engine is on you might want to take "extra step" in doing some checks / tests before you just turn the engine off.... note that different interferences might affect your uC, image you overtaking the truck and in the mid of that the truckers anti radar mess up your uC and it decide to go from 3->1 and turn off your engine!!! I'd not wanna be in car with you then :)

    also, think about "uC / whole device" gets stuck for unknown reason ... you have WDT (watchdog timer) to test for that and reset the device when that happens but - you do not want WDT to reset your device and that to turn off the car (in the same place when you are overtaking the truck) so you need to think about initialisation routine and how can device know in what state it is when it is booted as you cannot expect it to always boot when "car is off and in the garage)

    also, the TA14832 or similar regulator will provide you with the power you need (it will give you one 5V out "always" and one only when the car is "on")...

    with regards to control of the different external equipment you can try out the ULN2003 that will be able to drive 7x 0.5A 50V "devices"
     
  3. thekyguy11

    thekyguy11 New Member

    Joined:
    Jan 12, 2008
    Messages:
    104
    Likes:
    1
    I agree, the 3->1 should have more checks. Here is how the TL works...

    "Emergency Engine Stop Function
    If you must stop the engine while driving in a serious emergency condition, do either of the following operations:

    Press and hold the engine start/stop button.

    Press the engine start/stop button three times continuously."

    It's funny, when I was reading through the actual system description for the TL Keyless Access System, it had a few State Diagrams too.:)

    I updated my diagram to include the "Press and Hold" 3->1 step.
     
    Last edited: Jan 19, 2009
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. thekyguy11

    thekyguy11 New Member

    Joined:
    Jan 12, 2008
    Messages:
    104
    Likes:
    1
    Last edited: Jan 21, 2009
  6. thekyguy11

    thekyguy11 New Member

    Joined:
    Jan 12, 2008
    Messages:
    104
    Likes:
    1
    I finally got a chance to play around with some programming and I need some help. I got this code, from Pommie, to work:
    Code (text):
    Device = 18F1320
    Clock = 4 // 4MHz clock
    Config OSC = INTIO2, WDT = OFF, LVP = OFF

    Dim NOT_RBPU As INTCON2.7
    Dim Lit As Byte
    Dim Keys As Byte

    OSCCON = $62            // select 4MHz internal clock
    ADCON1  = $7f           //all digital
    NOT_RBPU=0              //WPUs on port B
    While true
        DelayMS(10)
        If(PORTB.0=0) Then                  //is button 1 pressed
            TRISA.7 = 1
            High(PORTA.0)
            Low (PORTA.6)
        EndIf
        If(PORTB.2=0) Then
            TRISA.7 = 1
            Low (PORTA.0)
            High(PORTA.6)      
        EndIf
        If(PORTB.5=0) Then
            TRISA.0 = 1
            High(PORTA.6)
            Low (PORTA.7)      
        EndIf
    Wend
    End
    I don't understand how to have the same button light 1 LED, then that same button, when pressed again, simultaneously light the second and shut off the first, etc. As if button 1 "advances" the leds, one at a time.
     
    Last edited: Feb 3, 2009
  7. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,791
    Likes:
    134
    Location:
    morristown,tn
    It will work but put a current limiting resistor from your 12 volt pos to the Vin of the 7805 a 24 Ohms 1 watt would work and a fuse. That way if your 7805 go's out it will save you a lot trouble.
     
    Last edited: Feb 3, 2009
  8. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    Hi kyguy,

    Because the Junebug LEDs are charlieplexed it is not easy to light more than one at a time. To solve this problem I wrote a interrupt routine to rapidly switch each LED on in turn so that they appear to be on permanently.

    Here's the code,
    Code (text):

    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

    //interrupt routine gets called 500 times per second
    //and multiplexes the LEDs Aslo sets a flag after 0.5S.
    Interrupt MyInt()
    Dim Count As Byte
    Dim Row As Byte
        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
        Count=Count+1
        If Count=250 Then
            Count=0
            IntFlag=1
        EndIf
    End Interrupt

    //main code starts here

    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
    While true
        If(PORTB.0=0) Then  //is button 1 pressed
            Lit.0=1         //yes so turn on LED 1
        Else
            Lit.0=0         //no so turn off
        EndIf
        If(PORTB.2=0) Then
            Lit.2=1
        Else
            Lit.2=0
        EndIf
        If(PORTB.5=0) Then
            Lit.4=1
        Else
            Lit.4=0
        EndIf
        If IntFlag=1 Then   //if 0.5S passed then flash other LEDs
            Lit=Lit Xor %00101010
            IntFlag=0
        EndIf
    Wend

    End
     
    If you use this code then to turn on any LED you just do Lit.n=1 where n=LED number. So Lit.3=1 will turn on LED 3. I have just made the main code blink LEDs 1, 3 & 5 and made the switches illuminate LEDs 0, 2 & 4.

    Have a play with it and see if it makes sense. <edit> If your comfortable with this code then I can show you how to advance the LEDs.</edit>

    Mike.
     
    Last edited: Feb 3, 2009
  9. thekyguy11

    thekyguy11 New Member

    Joined:
    Jan 12, 2008
    Messages:
    104
    Likes:
    1
    hey thanks Pommie! I really appreciate it! Slight problem though, it won't compile. It says "end expected" and it highlighted this line

    Code (text):
     TRISA = TRISA Or %11000001          ;turn all LEDs off
     
  10. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    It should be,
    Code (text):
     TRISA = TRISA Or %11000001          //turn all LEDs off
    Mike.
     
  11. thekyguy11

    thekyguy11 New Member

    Joined:
    Jan 12, 2008
    Messages:
    104
    Likes:
    1
    Oooo, I tried to figure it out on my own... I can't believe I missed that, lol.
     
  12. thekyguy11

    thekyguy11 New Member

    Joined:
    Jan 12, 2008
    Messages:
    104
    Likes:
    1
    ok I tried Pommies code and kinda understand whats going on there. Here is what I am trying to do now, but can't seem to get to work.

    I know to make LED 1 lite when button 1 is pressed, i use this section

    Code (text):
     If(PORTB.0=0) Then                  //is button 1 pressed
            TRISA.7 = 1
            High(PORTA.0)
            Low (PORTA.6)
        EndIf
    But to press the same button again and have the 4th LED come on while the first one is lit, I want to say something like...

    "If(PORTB.0=0) and (LED 1 is already ON) Then
    TRISA.7 = 1
    High(PORTA.0)
    Low (PORTA.6) //LED1 lit

    and

    TRISA.6 = 1
    High(PORTA.6)
    Low (PORTA.7) //LED4 lit
    EndIf"

    Something like that. Not sure how to accomplish this.
     
    Last edited: Feb 4, 2009
  13. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    Here's another bit of code for you to play with. It shows how to detect key presses rather than keys held down.

    To do what you asked, you would do, if(PORTB.0=0 AND Lit.1=1) then ..... but you will get problems with debounce etc.

    Code (text):

    //main code starts here
    Dim Keys As Byte
    Dim Previous As Byte
    Dim NewKeys 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
    Lit=1
    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
     
    Have fun.

    Mike.
     
  14. thekyguy11

    thekyguy11 New Member

    Joined:
    Jan 12, 2008
    Messages:
    104
    Likes:
    1
    I gotta tell ya, this code writing is turning out to be considerably more difficult than I anticipated. I feel like I need to know all the basics for half of this stuff to make any sense. The blue notes after each line help, but I still have so many questions. I was hoping i could just keep studying different examples and making changes to suit my needs, but without understanding why things are doing what they are doing, I feel like I am getting nowhere. I keep referencing the Swordfish manual for explanations, but i don't understand half the explanations either!

    I can't for the life of me get the same button to do one thing, then something else when pressed again. It just keeps jumping right to the second thing I want it to do.:(

    Where can I learn the basics so this all makes more sense? OR should I just have someone write all the code I need to make my project work? Is that going to cost me money? I am determined to get this keyless access thing working one way or another!!!
     
    Last edited: Feb 4, 2009
  15. futz

    futz Active Member

    Joined:
    Sep 15, 2007
    Messages:
    2,043
    Likes:
    24
    Location:
    Vancouver, B.C.
    This is why we always try to tell newb programmers to maybe scale back the (usually) advanced projects they always seem to want to do right away, and try to nudge them toward learning the basics first. Either way they always end up having to learn the basics anyway. :p

    Comments won't teach you the basics, but they can really help make someone else's code more understandable.

    Sounds like you need to learn to debounce your switch. Try this: when the switch is detected, go immediately to a loop that keeps checking the switch until it is released. Then go to the action you wanted that button press to perform. Simple, easy debouncing. :D

    Time and lots of simple programming projects, gradually getting more advanced, will help.

    Bundles of it! Got a wheelbarrow? ;)
     
  16. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    That is because you are not waiting for the button to be released. The last piece of code I posted debounces the switches and the variable NewKeys only gets a bit set when there is a new keypress.


    Try doing something like,
    Code (text):

    Lit=1
    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 and Lit.0=1) Then    //is button 1 pressed
            Lit.0=0
            Lit.1=1
        EndIf
        If(NewKeys.0=1 and Lit.1=1) Then
            Lit.0=1          
            Lit.1=0
        EndIf
    Wend
     
    Mike.
     
  17. ameal

    ameal New Member

    Joined:
    Aug 24, 2008
    Messages:
    28
    Likes:
    0
    Location:
    Coimbra, Portugal
    optocouplers

    isn´t it possible to use optocouplers?

    just guessing, but could exist a comun cathode six pack of optocouplers, usable in cmos levels considering the low voltages.

    also the 7805 should be protected against voltage surge due to the start engine. i guess it should be considered up to 60v.

    the electric steering lock is a nice idea. where can one find such a device?

    warm regards,
    Hugo
    Portugal
     
  18. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,791
    Likes:
    134
    Location:
    morristown,tn
    I think this would be cool a add on to the old car that you could put on a keychain. Controlling the cars starting and door locks wouldn't be that hard but writing the code is for now be on me. Mike could I know he could. and Futz there good at it. But any way here some things that may make it easier to do
    as far as hardware
    1 Keyswitch use a relay that turns on to start and a button to use starter to start the car the car like in a BMW the check engine light go's off when engine started. You could use it to tell if the car is ruining.
    2 You can use the door lock relay on the car to open the door with your remote
    3 Steering wheel lock most new car use a solenoid to unlock the wheel and gear shifter and checks for the brakes to be pressed use that
    just some thing you may want to think about.
     
  19. thekyguy11

    thekyguy11 New Member

    Joined:
    Jan 12, 2008
    Messages:
    104
    Likes:
    1
    Thanks for the suggestions. I know the steering lock sol. is going to take some fab work, so I'll address that last. The motor/control unit for the '09 TL steering lock costs over $800! Needless to say, I'll be making that part myself. The shift-lock solenoid is a good idea tho! And I picked up my official '09 Acura TL Engine Start/Stop button from work yesterday ($48, my cost! Pretty pricey button if you ask me!!! )

    Pommie, I tried that last bit of code. When powered up, LED 0 is on. The buttons do nothing. Here is my copy of the code...

    Code (text):
    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

    //interrupt routine gets called 500 times per second
    //and multiplexes the LEDs Aslo sets a flag after 0.5S.
    Interrupt MyInt()
    Dim Count As Byte
    Dim Row As Byte
        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
        Count=Count+1
        If Count=250 Then
            Count=0
            IntFlag=1
        EndIf
    End Interrupt

    //main code starts here
    Dim Keys As Byte
    Dim Previous As Byte
    Dim NewKeys 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
    Lit=1
    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 And Lit.0=1) Then    //is button 1 pressed
            Lit.0=0
            Lit.1=1
        EndIf
        If(NewKeys.0=1 And Lit.1=1) Then
            Lit.0=1          
            Lit.1=0
        EndIf
    Wend
     
  20. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,007
    Likes:
    316
    Location:
    Brisbane Australia
    Sorry, that should have been,
    Code (text):

        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
     
    I must remember to test code before I post it in future.

    To implement your state machine you could do something like,
    Code (text):

    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
                if NewKeys.2=1 then
                    State=3
                endif
            case 3
                Lit.2=1
        end select            
    wend
     
    Note the difference between Keys and NewKeys. Keys will be one if the button is held down. Newkeys will be one only when the button is first pressed.

    Mike.
     
    Last edited: Feb 5, 2009
  21. thekyguy11

    thekyguy11 New Member

    Joined:
    Jan 12, 2008
    Messages:
    104
    Likes:
    1
    Mike! You are awesome. I feel like I am getting close and learning a lot, all thanks to you!

    Here is what I changed it to
    Code (text):
    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 NewKeys.2=1 then   //if key1 pressed then light first LED
                   State=1
               endif
           case 1
               Lit.0=1
               if NewKeys.2=1 then
                   State=2
               endif
           case 2
               Lit.1=1
               if NewKeys.2=1 then
                   State=3
               endif
           case 3
               Lit.2=1
               if NewKeys.2=1 Then
               state=0
               endif        
        end select
    wend
    Button one "acts" as the RFID input, button 2 is the Stop/Start button. I just had to add Dim State as Byte (I don't know if it should be byte or bit) and then I added an if-then statement to the end.

    Now suppose I want in case 3, lit.2 to light for say 5 seconds then go back to state 2, how could I accomplish this? I tried replacing code 3 with
    Code (text):
     case 3
               Lit.2=1
               DelayMS(5000)
               Lit.2=0
     
    But that didn't work. What am I doing wrong?
     

Share This Page