Mise en veille et reveil en fonction d'un distance

Hello,

J'ai un projet personnel qui me permet de mesurer une distance.
Ce projet est en gros un radar de recul, mais il est fixé au mur du garage. Cela permet de se garer au plus près du mur pour laisser un maximum de place.
Le module est sur pile 9V et doit donc consommer un minimum.
De plus, une fois la voiture rentrée, il doit arréter de clignoter et de sonner.
Pour cela j'avais donc pensé a mettre en veille mon arduino nano.
J'ai donc fait des recherches et tenté quelque chose, seulement cela ne fonctionne pas.
Voici le code :

#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

//Constantes broches Led RGB
const int ledr = 11;
const int ledg = 10;
const int ledb = 9;
const byte COLOR_RED = 0b100;
const byte COLOR_GREEN = 0b010;
const byte COLOR_BLUE = 0b001;

/* Constantes pour les broches */
const byte TRIGGER_PIN = 2; // Broche TRIGGER
const byte ECHO_PIN = 3;    // Broche ECHO

/* Constantes pour le timeout */
const unsigned long MEASURE_TIMEOUT = 25000UL; // 25ms = ~8m à 340m/s

/* Vitesse du son dans l'air en mm/us */
const float SOUND_SPEED = 340.0 / 1000;

long distance_cm = 0;

const int pinbuzzer = 12;
const int pinpot = A5;

int valpot = 0;
int valpotmap = 0;

int dodo1 = 0;
int dodo2 = 0;

const byte interruptPin = 3;

void setup() 
{
  //Initialisation des broches de la Led RGB
  pinMode(ledr, OUTPUT);
  pinMode(ledg, OUTPUT);
  pinMode(ledb, OUTPUT);

  //Initialisation des pins pour le buzzer
  pinMode(pinbuzzer, OUTPUT);
  pinMode(pinpot, INPUT);

  /* Initialise le port série */
  Serial.begin(9600);

  /* Initialise les broches */
  pinMode(TRIGGER_PIN, OUTPUT);
  digitalWrite(TRIGGER_PIN, LOW); // La broche TRIGGER doit être à LOW au repos
  pinMode(ECHO_PIN, INPUT);
  
}

void loop() 
{
  //Lecture des valeurs du potentiometre
  valpot = analogRead(pinpot);
  valpotmap = map(valpot, 0, 1023, 500, 5000);
  
  /* 1. Lance une mesure de distance en envoyant une impulsion HIGH de 10µs sur la broche TRIGGER */
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);
  
  /* 2. Mesure le temps entre l'envoi de l'impulsion ultrasonique et son écho (si il existe) */
  long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);
   
  /* 3. Calcul la distance à partir du temps mesuré */
  float distance_mm = measure / 2.0 * SOUND_SPEED;
   
  /* Affiche les résultats en mm, cm et m */
  Serial.print(F("Distance: "));
  distance_cm = distance_mm /10.0, 2;
  Serial.print(distance_cm);
  Serial.println(F("cm"));
  
  if(distance_cm > 200)
  {
    displayColor(COLOR_GREEN);
    dodo1++;
  }
  else if(distance_cm < 200 && distance_cm > 100)
  {
    dodo1 = 0;
    dodo2 = 0;
    Serial.println("délai 800");
    displayColor(COLOR_RED);
    tone(pinbuzzer, valpotmap);
    delay(800);
    digitalWrite(ledr, !bitRead(0, 2));
    noTone(pinbuzzer);
    delay(800);
  }
  else if(distance_cm < 100 && distance_cm > 50)
  {
    dodo1 = 0;
    dodo2 = 0;
    Serial.println("délai 600");
    displayColor(COLOR_RED);
    tone(pinbuzzer, valpotmap);
    delay(600);
    digitalWrite(ledr, !bitRead(0, 2));
    noTone(pinbuzzer);
    delay(600);
  }
  else if(distance_cm < 50 && distance_cm > 30)
  {
    dodo1 = 0;
    dodo2 = 0;
    Serial.println("délai 400");
    digitalWrite(ledg, LOW);
    displayColor(COLOR_RED);
    tone(pinbuzzer, valpotmap);
    delay(400);
    digitalWrite(ledr, !bitRead(0, 2));
    noTone(pinbuzzer);
    delay(400);
  }
  else if(distance_cm < 30 && distance_cm > 10)
  {
    dodo1 = 0;
    dodo2 = 0;
    Serial.println("délai 200");
    digitalWrite(ledg, LOW);
    displayColor(COLOR_RED);
    tone(pinbuzzer, valpotmap);
    delay(200);
    digitalWrite(ledr, !bitRead(0, 2));
    noTone(pinbuzzer);
    delay(200);
  }
  else if(distance_cm < 10)
  {
    dodo1 = 0;
    dodo2++;
    Serial.println("délai 50");
    digitalWrite(ledg, LOW);
    displayColor(COLOR_RED);
    tone(pinbuzzer, valpotmap);
    delay(50);
    digitalWrite(ledr, !bitRead(0, 2));
    noTone(pinbuzzer);
    delay(50);
  }

  if(dodo1 == 1000 || dodo2 == 30)
  {
    displayColor(COLOR_GREEN);
    dodo1 = 0;
    dodo2 = 0;
    Serial.println("DODO");
    delay(3000);
    digitalWrite(ledg, !bitRead(0, 1));
    attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
    set_sleep_mode(SLEEP_MODE_STANDBY);
    sleep_enable();
    sleep_mode();
  }
  
}

void blink() 
{
  /* 1. Lance une mesure de distance en envoyant une impulsion HIGH de 10µs sur la broche TRIGGER */
  digitalWrite(TRIGGER_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIGGER_PIN, LOW);
  
  /* 2. Mesure le temps entre l'envoi de l'impulsion ultrasonique et son écho (si il existe) */
  long measure = pulseIn(ECHO_PIN, HIGH, MEASURE_TIMEOUT);
   
  /* 3. Calcul la distance à partir du temps mesuré */
  float distance_mm = measure / 2.0 * SOUND_SPEED;
   
  /* Affiche les résultats en mm, cm et m */
  Serial.print(F("Distance: "));
  distance_cm = distance_mm /10.0, 2;
  Serial.print(distance_cm);
  Serial.println(F("cm"));

  if(distance_cm < 200 && distance_cm > 100)
  {
    sleep_disable();
    power_all_enable();
    Serial.println("REVEIL");
    detachInterrupt(digitalPinToInterrupt(interruptPin));
    software_Reboot(); 
  }
  
  delay(3000);
}

void software_Reboot()
{
  wdt_enable(WDTO_15MS);

  while(1)
  {

  }
}

/** Affiche une couleur */
void displayColor(byte color) {

  // Assigne l'état des broches
  // Version cathode commune
  //digitalWrite(PIN_LED_R, bitRead(color, 2));
  //digitalWrite(PIN_LED_G, bitRead(color, 1));
  //digitalWrite(PIN_LED_B, bitRead(color, 0));
  // Version anode commune
  digitalWrite(ledr, !bitRead(color, 2));
  digitalWrite(ledg, !bitRead(color, 1));
  digitalWrite(ledb, !bitRead(color, 0));
}

J'aurais donc aimé savoir ce qui ne va pas dans mon code, ou si cela est complètement faux, vers où me diriger pour la mise en veille.

L'arduino est censé se réveiller lorsqu'on rentre dans le champ du télémètre, donc quand on s'approche à 2 mètres.

Merci d'avance pour votre aide, si vous avez des questions parce que ce n'est pas clair, allez-y.

Si l’arduino dort, qui va lui dire de faire une mesure et de se réveiller. ??

C'est bien pour cela que je me tourne vers vous. Si ce n'est pas possible, comment le faire consommer moins ?

Si vous voulez rester sur cette approche il vous faudra réveiller l’arduino toutes les 2 secondes par exemple pour faire un Ping.

  • Si quelque chose à moins de 20cm, c’est la voiture qui est garée, vous vous rendormez
  • Si quelque chose entre 20cm et 1.5m, c’est que la voiture arrive ou part vous passez en cycle d’assistance au parking et ne dormez pas si départ voiture tant que la voiture n’est pas à au moins 2m
    -si rien à moins d’un mètre vous vous rendormez pour 2 secondes

il faudra bien sûr éteindre tous les éléments associés avant de dormir aussi (par exemple avec un switch du type POLOLU-281x MOSFET)

Avec cette approche et avec un bon arduino sans fioritures le mode sleep ne consomme pas grand chose et tant qu’il n’y a pas d’assistance à faire vous allez vous réveiller pour quelques ms. Si vous mettez un UNO et ne coupez pas les alims des afficheurs ou capteur ultra son votre batterie sera morte hyper rapidement même en sleep

Il vous faudra une bonne batterie genre LiPo (pas vos 9V) genre de 1200mAh - et vous tiendrez plusieurs mois si vous ne vous garez pas trop souvent

Vous pouvez aussi regarder du côté des VL53L0X ou VL53L1X pour mesurer la distance, en mode veille ils ne consomment quasiment rien et sont bcp plus rapide que les ultrasons donc vous pourrez vous rendormir plus vite

D'accord, je vais explorer cette voie.
On oublie donc les piles 9 volts ?
J'utilise un Arduino nano, pas une version officielle.
Le problème d'une batterie, c'est que cela reviens très rapidement cher, je voulais que mon projet reste simple au niveau du hard et pas trop cher (Pas au dessus de 10-15€).
J'ai celle-ci sur un site chinois : Vente MJX B6 Bugs 6 Quadricoptère RC Pièces de Rechange 7.4V 2300mAH 35C Lipo Batterie Mise à Jour Batterie - Banggood Français-arrival notice-arrival notice
Il faut compter le prix de la batterie et du chargeur.
Dans le pire des cas il reste toujours l'alimentation filaire mais donne au projet un coté dépendant.
Je n'ai aucun afficheur à alimenter, juste un buzzer, un strip de 6 leds et le télémètre à ultrasons.
Pour la télémétrie laser, je ne pense pas que cela soit une bonne alternative, la carrosserie des voiture est peut-être trop irrégulière pour réfléchir correctement la lumière.
Merci à toi :wink:

si c'est à demeure dans le garage, le filaire c'est pas mal....

dans le genre pas cher, il y a aussi le vieux pneu contre le mur :slight_smile: