Jump to content
LLegoLLaS

Adaptive flashing car brake-lights (arduino + accelerometer)

Recommended Posts

RST Note: Am scurtat articolul, am postat doar ce e relevant pentru a-l construi; puteti citi intregul articol la sursa;
Pentru componente am scos linkurile, ele se pot gasi pe orice site din RO (ardushop,cleste,optimusdigital,digikey etc) la pret mic;




Abstract

In this project, the idea of the adaptive brake light was reinterpreted using an Arduino Nano (ATMEGA328P) microcontroller. With a transistor as switching unit and an acceleration or GPS sensor, the components are connected in between the braking signal – only one additional power cable needs to be pulled. Any vehicle type can be easily retrofitted in this way without complicated wiring or the need to detect pedal force. The code was programmed using existing Arduino libraries, the cases were 3D printed and the finished modules were tested in practice. The total price of required components does not exceed $15.

Materials & Methods


Components
Microcontroller: ATMEGA328P (Arduino Nano Clone) (15 lei)
Accelleration-sensor: GY-521 MPU-6050 (15-30 de lei)
GPS-sensor: GY-NEO6MV2 (¬50 de lei)
Transistor: BD139 Genuine ON Semiconductor NPN 1.5 A / 80 V To-126 ZBDE W0HW ($0.20) (Polarity here is C/E/B! Regular C/B/E polarity will of course work aswell)
LEDs: T10 COB-LED (optionale, pentru testare in ''laborator@ - leduri de masina)
Software
Autodesk Inventor Professional 2019 (Build: 265, Release: 2019.2) (optional)
Fritzing beta (Ver. 0.9.4 ) (optional)
Arduino IDE 1.8.10 (Board: Arduino Nano, Processor: ATmega328P, Programmer: AVRISP mkII)
Libraries for Arduino IDE:
– without GPS: Wire.h
– with GPS: Wire.h, SoftwareSerial.hTinyGPS.h



Source code
The operating principle of the source code is based on an interruption of the light signal using the transistor. This means that without triggering the sketch (i.e. at slow speeds or only slight changes in acceleration) the current sent by the brake pedal is passed through the microcontroller to light up the brake lights. Only as soon as the acceleration sensor detects an acceleration above a defined threshold value and (if used) the GPS sensor detects a speed above a defined threshold value, the sketch is triggered and interrupts the continuous light signal for a defined time by the parameters BLINKON and BLINKOFF, resulting in a flashing effect. If the sketch is once activated, the flashing will then last for a defined STOPPINGTIME, independent of the currently read out data – so that, as in the example video, the flashing signal will last until the vehicle has come to a standstill or for a short time during the strong speed reduction in order to obtain the desired warning effect.
 

#include "Wire.h"
#include "SoftwareSerial.h" 
#include "TinyGPS.h"


#define STOPPINGTIME 1500   // in ms
#define G_THRESHOLD 1.1   // activate above threshold
#define G 2.7e8             // = 1 g
#define BLINKON 75          // in ms
#define BLINKOFF 75         // in ms
#define INITFILT 400        // number of values averaged to get initial acceleration
#define FILT 140            // number of values averaged to get current acceleration

#define V_THRESHOLD 100   // in km/h
#define MAXFAILEDGPSBYTES 1000  // number of bytes received from gps to abort without valid gps sequence
#define MAXTIMESINCELASTFIX 2000  // in ms


const int ledPin = 11;
const int ledPin2 = 13;
const int MPU_addr = 0x68;  //I2C address
const int GPSrxPin = 3;
const int GPStxPin = 4;


bool blinkStatus, ledStatus, risingEdge;

unsigned long endTime, toggleTime;

double gforce, oldforce;

int16_t Xi, Yi, Zi;
int32_t Xc = 0, Yc = 0, Zc = 0;
double X, Y, Z, AccP;

int16_t Xbuf[FILT] = {0}, Ybuf[FILT] = {0}, Zbuf[FILT] = {0};
int bufpos = 0, i;
int32_t tmp;


SoftwareSerial gpsSerial(GPSrxPin, GPStxPin);  //rx (D3),tx (D4) for GPS
TinyGPS gps; // create gps object 
float speed = 0;  //vehicle speed in km/h
long lat, lon;
unsigned long fix_age;
bool goodfix;


void setup() {
  //Connect to G-Sensor
  Wire.begin();
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x6B);  // PWR_MGMT_1 register
  Wire.write(0);     // set to zero (wakes up the MPU-6050)
  Wire.endTransmission(true);

  Serial.begin(9600);     // for USB monitor

  gpsSerial.begin(9600); // connect gps sensor

  for (i = 0; i<INITFILT; i++) {
  
    Wire.beginTransmission(MPU_addr);
    Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
    Wire.endTransmission(false);
    Wire.requestFrom(MPU_addr,6,true); // request a total of 6 registers
    Xc+=Wire.read()<<8|Wire.read();    // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
    Yc+=Wire.read()<<8|Wire.read();    // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
    Zc+=Wire.read()<<8|Wire.read();    // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)

  }

  Xc = Xc/FILT;
  Yc = Yc/FILT;
  Zc = Zc/FILT;
  

  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, true);
  pinMode(ledPin2, OUTPUT);
  digitalWrite(ledPin2, true);
  blinkStatus = false;
  ledStatus = true;

}

void loop() {
  
  // GPS read
  i = 0;
  while(gpsSerial.available()) { //Data available?
    if(gps.encode(gpsSerial.read())) {  //GPS telegram complete?
      speed = gps.f_speed_kmph();

      break;  // end while loop
    }

    if (i++ > MAXFAILEDGPSBYTES)  // cancel after MAXFAILEDGPSBYTES bytes without valid telegram
      break;
  }
  //check for valid signal
  gps.get_position(&lat, &lon, &fix_age);
  goodfix = ((fix_age == TinyGPS::GPS_INVALID_AGE) || (fix_age > MAXTIMESINCELASTFIX)) ? false : true;


  //G-Sensor read
  Wire.beginTransmission(MPU_addr);
  Wire.write(0x3B);  // starting with register 0x3B (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(MPU_addr,6,true); // request a total of 6 registers
  Xbuf[bufpos]=Wire.read()<<8|Wire.read();    // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)    
  Ybuf[bufpos]=Wire.read()<<8|Wire.read();    // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  Zbuf[bufpos]=Wire.read()<<8|Wire.read();    // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)

  tmp = 0;
  for (i = 0; i<FILT; i++) {
    tmp += Xbuf[i];
  }
  Xi = tmp;
  tmp = 0;
    for (i = 0; i<FILT; i++) {
    tmp += Ybuf[i];
  }
  Yi = tmp;
  tmp = 0;
    for (i = 0; i<FILT; i++) {
    tmp += Zbuf[i];
  }
  Zi = tmp;

  X = Yc*Zi - Zc*Yi;
  Y = Zc*Xi - Xc*Zi;
  Z = Xc*Yi - Yc*Xi;

  gforce = sqrt(X*X + Y*Y + Z*Z);

  Serial.print(G_THRESHOLD * G);
  Serial.print(',');
  Serial.print(8e8);
  Serial.print(',');
  Serial.print(G);
  Serial.print(',');
  Serial.println(gforce);
  delay(0);


  // blinkstuff
  risingEdge = false;

  if (blinkStatus) {
    if (gforce > G_THRESHOLD * G) {
      endTime = millis() + STOPPINGTIME;
    }
  } else {
    if ( (gforce > G_THRESHOLD * G) && ( !goodfix || (speed > V_THRESHOLD)) ) {
      risingEdge = true;
      blinkStatus = true;

      endTime = millis() + STOPPINGTIME;
    }
  }

  if (risingEdge) {
    toggleTime = millis() + BLINKOFF;
    digitalWrite(ledPin, false);
    ledStatus = false;
  }

  if (blinkStatus) {
    if (millis() > toggleTime) {
      if (ledStatus) {
        ledStatus = false;
        toggleTime = millis() + BLINKOFF;
        digitalWrite(ledPin, false);
        digitalWrite(ledPin2, false);
      } else {
        ledStatus = true;
        toggleTime = millis() + BLINKON;
        digitalWrite(ledPin, true);
        digitalWrite(ledPin2, true);
      }
    }

    if (millis() > endTime) {
      blinkStatus = false;
      digitalWrite(ledPin, true);
      digitalWrite(ledPin2, true);
    }
  }
}


Schema montaj:

Spoiler

Untitled-Sketch2_Steckplatine1.jpg


sursa

  • Upvote 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...