Sunday,17-May-2015

Saxo Central Locking Addons

EN Hi folks, friend of mine has Saxo with central locking but unfortunately it doesn`t have any “blinking” or indication of the lock-unlock state. So he ask me if we can do something about it, and if I can add some addition small fade in and out light in front. For the blinking I use direction lights, for the other option - low beam lamps and PWM.Represented here by that small bulbs, first in the video. (that is my solution, if you check on ebay there are quite many central locking units with lot functions. So there you can get 4 button ones, and to add lights on with timer on button)

Currently, the circuit work well, fitted and tested. The elements are shown on the circuit diagram below. I use 2 of the IRF4905 mosfet for controlling the low beam lights instead one. Even by book it has 70A/55V and 2×55W are ~12A for low beam lamps, still I do not trust somehow adding 12A only on that one small pin. Or you can use - STP80PF55 - guess will work also. For that 12-15A diode for now I use 20SQ045 20A 45V Schottky Rectifiers(ebay). That I need because when switch to normal low beam control appear +12V and reverse down back to the mainboard. Maybe there is more elegant solution but for now work perfect.
As for the operation - if you push the remote , signal + and - are send to the door motors.There are two wires and when is the unlock state it has let`s say: A+B- , lock state A-B+. You`ve got the point I bet. So I take that 2 wires signal to the micro-controller(ATTINY85 in my case) via optocouplers and look only for HIGH state. The other third signal is from the HIGH BEAM stalk switch - if you pull it then you set the “FOLLOW ME” state.
How it goes:
1) UNLOCK -> direction lights blink & PWM UP -> delay ~3sec -> PWM DOWN -> ALL OFF
2) LOCK -> direction lights steady & PWM UP -> delay ~3sec -> PWM DOWN -> ALL OFF
3) LOCK + FOLLOW ME -> direction lights steady & PWM UP -> delay ~30sec -> PWM DOWN -> ALL OFF

If you wish to skip the cycle when the car is locked and 30sec timer is ON - just unlock the car, or switch the lights stalk to park lights. To activate FOLLOW ME - with car open and lights off -> pull the stalk for about second, the blinkers (also visible on the dash) will blink to show that the state is ON. Pulling again - they will stay steady for while to show is OFF.

If you forget your car with park lamps ON, that micro relay on the diagram will be off, no power to the atmel chip no blinking, and you`ll notice there is some problem

diagram.jpgsaxo2a.jpgsaxo2b.jpgsaxo2c.jpg

// Attiny 85 - on 5V 16Mhz - SAXO
#define PWMLB 0  // define LOW BEAM PWM pin
#define PWMBLINKERS 1 // define Blinkers pin
#define HIBEAM 2 // High Beam input signal 0 or 1
#define UNLOCK 3  // UNLOCK signal 0 or 1
#define LOCK 4    // LOCK signal 0 or 1

long int currentMillis = 0;
long int millisGone = 0;
long int millisFade = 0;
long int someDebonce = 0;

 boolean longPauseAvbl = false;
     int longPauseCounter = 0;
 boolean longPauseBlinker = false;
    byte longPauseFlip = LOW;
long int longPauseMillis = 0;
     int tmpCounter = 0;
     int pause = 0;
     int counterPause = 0;

     int counterLockUnlock = 0;
     int lockUnlockState =0; // 0-no,1-lock,2-unlock

 boolean enableBlinker = false;
 boolean stateBlinker = false;
     int blinkerCounter = 0;

     int fadeSteps = 0;
 boolean fadeStepsDown = false;
     int faderStage = 0;

void setup() {
  pinMode(PWMLB, OUTPUT);      
  pinMode(PWMBLINKERS, OUTPUT);

  pinMode(13,OUTPUT);  

  pinMode(UNLOCK, INPUT);      
  pinMode(LOCK, INPUT);  
  pinMode(HIBEAM, INPUT);  
}

void loop(){
 
currentMillis = millis(); 

byte tmpUnlock = digitalRead(UNLOCK);
byte tmpLock = digitalRead(LOCK);

if(currentMillis - longPauseMillis > 80){
                   longPauseMillis +=80;
         if(longPauseBlinker == true && tmpCounter <= 10){          
                 digitalWrite(PWMBLINKERS, longPauseFlip);
                 longPauseFlip = !longPauseFlip;
                 tmpCounter +=1;
         } 
}

if(currentMillis - someDebonce > 125){
                   someDebonce +=125;
          if(digitalRead(HIBEAM) == HIGH){
                   longPauseCounter += 1;
          }
          if(tmpUnlock == HIGH || tmpLock == HIGH){
                   counterLockUnlock += 1;
                   if(tmpUnlock == HIGH)lockUnlockState =2;
                   else if(tmpLock == HIGH)lockUnlockState =1;
         }
}   

if(longPauseCounter > 8){
                longPauseAvbl = !longPauseAvbl;
                longPauseCounter = 0;
      if(longPauseAvbl == false){
                digitalWrite(PWMBLINKERS, LOW);
                delay(10);
                digitalWrite(PWMBLINKERS, HIGH);
                delay(1000);
                digitalWrite(PWMBLINKERS, LOW);
                
     }  
     if(longPauseAvbl == true) {
                longPauseBlinker = true;
                longPauseFlip = false;
                tmpCounter = 0;
     }  
     
}

if(counterLockUnlock > 2){   //2x125ms -> 250ms(1/4sec)
     enableBlinker = true;
     counterLockUnlock = 0;
     blinkerCounter = 0;
     faderStage = 1;
}     

if(currentMillis - millisGone > 80){
                   millisGone +=80;
    if(enableBlinker == true){
               blinkerCounter += 1;
                          if(blinkerCounter > 20){
                                stateBlinker = false;
                                enableBlinker = false;
                                lockUnlockState = 0;
                          }
                   if(lockUnlockState == 2){
                               stateBlinker = !stateBlinker;
                               longPauseAvbl = false;
                               
                   }
                   if(lockUnlockState == 1){
                               stateBlinker = true; 
                   }
                   digitalWrite(PWMBLINKERS, stateBlinker);
     }
}
   

if(currentMillis - millisFade > 8){
                   millisFade +=8;
         if(faderStage == 1){
                     fadeSteps += 1;
                     if(fadeSteps >= 255){
                           faderStage = 2;
                           counterPause = 0;
                     } 
         }  
         if(faderStage == 2){
                    counterPause += 1;
               if(longPauseAvbl == true){
                        pause = 4000;
               }else{
                        pause = 400;
               }  
               if(pause != counterPause){      
                        fadeSteps = 255; 
               }else{
                        pause = 0;
                        fadeSteps = 255;
                        faderStage = 3;
               }   
         }
         if(faderStage == 3){
                     fadeSteps -= 1;
                     if(fadeSteps <= 0){
                          faderStage = 0;
                          longPauseAvbl = false; 
                     }

         }
  }                   
  analogWrite(PWMLB,fadeSteps);  
//---------------------------------------- end --------------------      
}