Mobile speed radar V2

After the realization of the radar that you can find here https://www.carrera-fun.com/?p=6961&lang=en, I decided to improve it a little. It was missing some features.

Functions:

  • Speed ​​limit display
  • Speed ​​limit setting (flash trigger)
  • Adding a flash
  • Switch indicating the direction of the car
  • Parameter reset button

To achieve this, I added 2 buttons, a green one to add 5 to the display and a green one to subtract 5. The red display indicates the authorized speed limit in cm/s.

The main display indicates several information.

  • The last speed of passage in cm/s on the first line.
  • The number of laps completed and how many times you were flashed (exceeding the authorized / set speed)
  • The minimum and maximum speeds achieved
  • The average of the passage speeds.

The black button on the side of the radar allows you to reset the data.

Material :

  • LCM2004 (4-line display) (3.5€)
  • TM1637 (Red display) (1€)
  • 3W high-power LED module with PCB chassis (2€)
  • 3 push buttons (0.2€)
  • 2-position lever switch (0.3€)
  • 1 Arduino Nano (3€)
  • 1 Arduino nano support (2€)

The Nesquik box has filled up nicely. Buttons and displays connect to the Arduino Nano support.

I used spade terminals on the switches. I cut the end of the Dupont wires to insert the spade terminals for easy attachment to the switches.

On the cover side, a high-brightness diode was added to represent the radar flash. (red element in the photo)

Video :

Here is the connection diagram of all the components.

And now the code to program the Arduino.
If you want more information about the implementation to send the program to the Arduino, you can check the following Article : https://www.framboise314.fr/commencer-avec-larduino/

//Libraries 
#include <Wire.h>  
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address, if it's not working try 0x27.

int IR1 = 4;
int IR2 = 5;

      int bouton_1 = 3; // déclaration du bouton
      int bouton_2 = 2; // déclaration du bouton

int compteur1 = 1;      // variable enregistre un passage compteur 1
int compteur2 = 1;      // variable enregistre un passage compteur 2
long temps1=millis();    // Variable prise de temps pour IR 1
long temps2=millis();    // Variable prise de temps pour IR 2
long temps3 = 0;         // Variable pour le calcul du temps reel passe
float V = 0.0;            // Variable Vitesse
float TTS = 0.0;          // Variable temps passe en secondes

float V_min = 99999999;        // Vitesse min
float V_max = 0.0;        // Vitesse max
float V_moy = 0.0;        // Vitesse moy
float V_som = 0.0;        // Vitesse som

int radar_seuil = 70; // valeur vitesse demarrage



int levier_1 = 8; // déclaration du bouton
int levier_2 = 9; // déclaration du bouton
int etatlevier_1 = 0; // variable lorsque j'appuie sur le bouton
int etatlevier_2 = 0; // variable lorsque j'appuie sur le bouton

int boutonappui_1 = 0; // variable lorsque j'appuie sur le bouton
int etatbouton_1 = 0; // etat dans lequel se trouve le bouton
int bouton_pasappui_1 = 0;// variable lorsque je n'appuie pas sur le bouton

int boutonappui_2 = 0; // variable lorsque j'appuie sur le bouton
int etatbouton_2 = 0; // etat dans lequel se trouve le bouton
int bouton_pasappui_2 = 0;// variable lorsque je n'appuie pas sur le bouton

String texte="";
String txt_sens="===";
int tours=0;
int nb_flash=0;

// flash
int pin_led_flash = 13;

// Inclue la librairie ecran rouge:
#include <TM1637Display.h>
// Define the connections pins:
#define CLK 6
#define DIO 7
// Create display object of type TM1637Display:
TM1637Display display = TM1637Display(CLK, DIO);
// Create array that turns all segments on:
const uint8_t data[] = {0xff, 0xff, 0xff, 0xff};
// Create array that turns all segments off:
const uint8_t blank[] = {0x00, 0x00, 0x00, 0x00};

const uint8_t done[] = {
  SEG_B | SEG_C | SEG_D | SEG_E | SEG_G,           // d
  SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F,   // O
  SEG_C | SEG_E | SEG_G,                           // n
  SEG_A | SEG_D | SEG_E | SEG_F | SEG_G            // E
};

const uint8_t pts[] = {
  SEG_B | SEG_C | SEG_F | SEG_G ,           // d
  SEG_A | SEG_B | SEG_E | SEG_F | SEG_G ,   // O
  SEG_D | SEG_E | SEG_F | SEG_G ,           // n
  SEG_A | SEG_F | SEG_D | SEG_C | SEG_G     // E
};

void setup(){
  
  // Boutons
  pinMode(bouton_1, INPUT_PULLUP);// déclaration du bouton en entrée avec la résistance pullup
  pinMode(bouton_2, INPUT_PULLUP);// déclaration du bouton en entrée avec la résistance pullup
  
  pinMode(levier_1, INPUT_PULLUP);// déclaration du bouton en entrée avec la résistance pullup
  pinMode(levier_2, INPUT_PULLUP);// déclaration du bouton en entrée avec la résistance pullup

    etatlevier_1 = digitalRead(levier_1);//etatbouton est égale à la lecture du bouton
    etatlevier_2 = digitalRead(levier_2);//etatbouton est égale à la lecture du bouton
    
    if (etatlevier_1 == 1) {// si etatbouton est différent de bouton pas_appui, simplement si j'appuie sur le bouton
      IR1 = 5;
      IR2 = 4;
      txt_sens="<<<<<";
    }
    if (etatlevier_2 == 1) {// si etatbouton est différent de bouton pas_appui, simplement si j'appuie sur le bouton
      IR1 = 4;
      IR2 = 5;
      txt_sens=">>>>>";
    }

  
  lcd.begin(20,4);   // iInit the LCD for 16 chars 2 lines
  lcd.backlight();   // Turn on the backligt (try lcd.noBaklight() to turn it off)
  lcd.setCursor(0,0); //First line
  lcd.print(txt_sens+" attente  "+txt_sens);
  lcd.setCursor(0,1); //Second line
  lcd.print(txt_sens+" vehicule "+txt_sens);
  lcd.setCursor(0,2); //3eme line
  lcd.print(txt_sens+"   SLOT   "+txt_sens);
  lcd.setCursor(0,3); //4eme line
  lcd.print(txt_sens+"  RACING  "+txt_sens);
  // capteurs
  pinMode(IR1,INPUT);
  pinMode(IR2,INPUT);
  //Serial.begin(9600);

  // Clear the display:
  display.clear();
  delay(100);
  // Set the brightness:
  display.setBrightness(7);
  // All segments on:
  display.setSegments(data);
  display.clear();
  display.showNumberDec(radar_seuil, false, 4, 0);


  // Flash
  pinMode(pin_led_flash, OUTPUT);
    //digitalWrite(pin_led_flash, HIGH);
    //delay(200);
    digitalWrite(pin_led_flash, LOW);
}

void loop(){
  
  int valIR1 = digitalRead(IR1);  
  // Lecture de broche A2 et mise du resultat dans la variable valIR1
  int valIR2 = digitalRead(IR2);   
  // Lecture de broche A3 et mise du resultat dans la variable valIR2
 
   if(valIR1 == LOW && compteur1 == 1 && compteur2 == 1) {  
   // Si passage devant IR1 ET compteur1 = 1 alors ....
   temps1=micros();       // enregistrement dans temps1 de la valeur millis
   compteur1 = compteur1 + 1;   
  // On rajoute +1 a compteur1 ce qui empeche le remplacement de la valeur de temps1   
   } 
 
   if(valIR2 == LOW && compteur2 == 1 && compteur1 == 2) {   
   // Si passage devant IR2 ET compteur2 = 1 alors .... 
   temps2=micros();      // enregistrement dans temps1 de la valeur millis    
   compteur2 = compteur2 + 1; 
  // On rajoute +1 a compteur2 ce qui empeche le remplacement de la valeur de temps2    

   }

   if(compteur1 > 1 && compteur2 > 1) {   
       // Si les valeurs de Compteur1 ET de compteur2 sont differente de 1 alors le calcul peut debuter
      tours=tours+1;
       temps3 = (temps2 - temps1);       
       // temps en millisecondes passez entre les deux capteurs

       TTS = ((float)temps3 / 1000000.0);          
       // conversion milisecondes en secondes
     
       V = (0.05 / (float)TTS)*100;               
       // calcul de d/t, ma distance est ici de 5 cm, soit 0,05 m
       // en cm/s
      V_som =V_som+V;
      V_moy=V_som/tours;
      if(V < V_min) {
        V_min=V;
      }
      if(V > V_max) {
        V_max=V;
      }
      //texte=String(V)+"cm/s -"+String(tours)+"    ";
      
      if(V > radar_seuil) {
        nb_flash=nb_flash+1;
        affichage(String(V),String(tours),String(V_min),String(V_max),String(V_moy));
        over_speed();
      } else {
        affichage(String(V),String(tours),String(V_min),String(V_max),String(V_moy));
        delay(500);  // delais avant reprise du programme 
      }
        // Pour permettre la liberation de la zone IR
     
        compteur1=1;  // Variable remise a 1
        compteur2=1;  // Variable remise a 1
        temps1 = 0;   // Variable remise a 0
        temps2= 0;    // Variable remise a 0
   }
 
  //delay(10);

  // #### BOUTONS 
    etatbouton_1 = digitalRead(bouton_1);//etatbouton est égale à la lecture du bouton
    etatbouton_2 = digitalRead(bouton_2);//etatbouton est égale à la lecture du bouton
    
    if (etatbouton_1 != bouton_pasappui_1) {// si etatbouton est différent de bouton pas_appui, simplement si j'appuie sur le bouton
      push_bt_1();
    }
    bouton_pasappui_1 = etatbouton_1;
    
    if (etatbouton_2 != bouton_pasappui_2) {// si etatbouton est différent de bouton pas_appui, simplement si j'appuie sur le bouton
      push_bt_2();
    }
    bouton_pasappui_2 = etatbouton_2;
  
}

void  affichage(String vitesse,String tours,String V_min, String V_max ,String V_moy) {

  lcd.backlight(); 
  //lcd.noBacklight();
  lcd.clear();
  lcd.setCursor(0,0); //First line
  lcd.print(vitesse+"cm/s");
  lcd.setCursor(0,1); //Second line
  lcd.print(tours+" tours "+String(nb_flash)+" flashs");
  lcd.setCursor(0,2); //3eme line
  lcd.print(V_min+" a "+V_max);
  lcd.setCursor(0,3); //4eme line
  lcd.print("Moy. "+V_moy);
}



void push_bt_1(){
    if (etatbouton_1 == LOW) {// et que la position du bouton est à LOW (inversé avec la résistance de PULLUP)
    //Serial.println("+1");
    radar_seuil=radar_seuil+5;
    Serial.println(radar_seuil);
    display.clear();
    display.showNumberDec(radar_seuil, false, 4, 0);
    } 
    delay(50);
}

void push_bt_2(){
    if (etatbouton_2 == LOW) {// et que la position du bouton est à LOW (inversé avec la résistance de PULLUP)
    //Serial.println("-1");
    radar_seuil=radar_seuil-5;
    Serial.println(radar_seuil);
    display.clear();
    display.showNumberDec(radar_seuil, false, 4, 0);
    } 
    delay(50);
}

void over_speed(){
  //display.setSegments(pts);
  lcd.noBacklight();
  display.showNumberDec(int(V), false, 4, 0);
  digitalWrite(pin_led_flash, HIGH);
  delay(20);
  digitalWrite(pin_led_flash, LOW);
  delay(50);
  digitalWrite(pin_led_flash, HIGH);
  delay(50);
  digitalWrite(pin_led_flash, LOW);
  lcd.backlight(); 
  delay(800);
  display.clear();
  display.showNumberDec(radar_seuil, false, 4, 0);
}