Detection of the sirens of priority vehicles (police, ambulance, fire brigade...)

lorraineber4

New member
Hello, I'm using a Teensy for a project. My project is to use a microphone to detect the sirens of priority vehicles (police, ambulance, fire brigade...). I've tried programming, but it doesn't work...

I don't know what to do... Can you help me?


For your information, in France, the 1st tone is always 435 +/- 2/100 Hz.
The second tone then depends on the emergency service.
- For the police: it's 580 +/- 2/100 Hz
- Gendarmerie: 732 +/- 2/100 Hz
- Fire department: 488 +/- 2/100 Hz
- EMS: 651 +/- 2/100 Hz
All have a cadence of 50 to 60 cycles per minute, except firefighters (25 to 30 cycles / minute).


Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <time.h>
#include <SoftwareSerial.h>

// GUItool: begin automatically generated code
AudioInputI2S            i2s1;           //xy=275.0056610107422,280.0056552886963
AudioMixer4              mixer1;         //xy=486.9999771118164,294.99999618530273
AudioAnalyzeNoteFrequency notefreq1;      //xy=684.9999008178711,355.9999713897705
AudioConnection          patchCord1(i2s1, 0, mixer1, 0);
AudioConnection          patchCord2(i2s1, 1, mixer1, 1);
AudioConnection          patchCord3(mixer1, notefreq1);
AudioControlSGTL5000     sgtl5000_1;     //xy=367,469
// GUItool: end automatically generated code

// Fréquences spécifiées pour chaque type de sirène
int police[2] = {435, 580};
int gendarmerie[2] = {435, 732};
int pompier[2] = {435, 488};
int SAMU[2] = {435, 651};
int ambulance[3] = {420, 516, 420};

// Variables globales
unsigned long temps_precedent = 0;
int note_precedente = 0;
int tableau[4] = {0, 0, 0, 0};
float note_as_float = 0;

void setup() {
  Serial.begin(9600);
  notefreq1.begin(0.15);
  AudioMemory(1000);
  sgtl5000_1.enable();
  sgtl5000_1.volume(1);
  sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN);
  sgtl5000_1.micGain(36);
}

void loop() {
  if (notefreq1.available()) {
    note_as_float = notefreq1.read();
    int note = (int)note_as_float;
    float prob = notefreq1.probability();

    if ((note >= 150 && note <= 1000)) {
      if (temps_precedent == 0) {
        temps_precedent = millis();
      } else {
        unsigned long temps_actuel = millis();
        unsigned long delai = temps_actuel - temps_precedent;
        temps_precedent = temps_actuel;

        if ((delai > 10) && ((note >= 435 && note <= 735))) {
          Serial.println("AUCUNES SIRENES DETECTEES");

          // Ajoutez ici la logique pour détecter le type de sirène en comparant avec les modèles
          for (int f = 0; f < 3; f++) {
            tableau[f] = tableau[f + 1];
          }
          tableau[3] = note;
          Serial.printf("\n\n%d %d %d %d\n\n", tableau[0], tableau[1], tableau[2], tableau[3]); // Permet l'affichage des 4 derniers tons regardés

          // Test si sirène détectée correspond à une sirène connue
          test_tableau_ton(tableau, police, "POLICE");
          test_tableau_ton(tableau, gendarmerie, "GENDARMERIE");
          test_tableau_ton(tableau, pompier, "POMPIER");
          test_tableau_ton(tableau, SAMU, "SAMU");
          test_tableau_ton(tableau, ambulance, "AMBULANCE");
          note_precedente = note;
        }
      }
    }
  }
}

void test_tableau_ton(int* enregistrement, int* test, char* message) {
  if (enregistrement[0] == test[0] &&
      enregistrement[1] == test[1] &&
      enregistrement[2] == test[2] &&
      enregistrement[3] == test[3])
  {
    Serial.printf("DETECTION D'UNE SIRENE %s\n", message);
  }
}

void detecter_type_sirene(int note, int* modele, char* message) {
  // Tolerance pour la comparaison des fréquences
 float tolerance = 2.0 / 100.0 * note_as_float;

  // Comparaison avec le modèle de la sirène en prenant en compte la tolérance
  if (abs(note - modele[0]) <= tolerance && abs(note - modele[1]) <= tolerance) {
    Serial.printf("DETECTION D'UNE SIRENE %s\n", message);
  }
}
 
I'm hardly an expert on this but I think you need to use the tone functionality not the notefreq function.
notefreq is designed to find the main frequency of a sound. You are looking for a tone made up of two different frequencies, it'd not going to give you both of them.

tone can be used to detect whether a known tone is in the input and give you an indication of the strength/probability.
So you could create one tone for the main 435 Hz and then once for each service. You can then check if the required combination of tones are all over a set threshold at the same time.

Your code would then be something along the lines of
Code:
float tone435Level = 0;
float tonePoliceLevel = 0;

setup() {
 ...
 tone435.frequency(435);
 tonePolice.frequency(580);
 ...
}


loop {

 if (tone435.read()> myThreshold) {
  if (tonePolice.read()> myThreshold) {
    Serial.printlln("Police");
    // probably need to set a flag / time marker so we only report once per detect or at a maximum rate.
   }
 }
}



Or a bit more work in terms of code but more CPU efficient would be to use the fft1024 function to give you the spectrum of the input. You can then check any combination of frequencies you want with minimal CPU hit for each additional frequency.
 
Hello,

If the vehicles are moving away/to the mic, frequencies would change. See doppler effect.

Angelo
 
Last edited:
Back
Top