Indice

Titolo dell’esperienza

Progettare e realizzare un circuito con Arduino che implementi un accelerometro e un giroscopio al fine di rilevare scosse sismiche, in corrispondenza delle quali vi sarà l’emissione di un allarme acustico e visivo.

Scopo dell’esperienza

Progettare e realizzare un circuito elettrico con il microcontrollore Arduino in grado di rilevare eventuali scosse sismiche, sfruttando un accelerometro e un giroscopio, in base ai cui valori rilevati, dovrà segnalare la presenza o meno di un terremoto. Nel caso in cui non vengano rilevate scosse allora vi sarà l’accensione di un led verde, altrimenti l’accensione di un led rosso con annesso allarme acustico, emesso da un buzzer, che segnalerà l’evento calamitoso in corso.

Strumenti utilizzati

Tipo  MarcaModelloNumero
BreadboardELEGOOSOLDERLESS1
ResistoreELEGOO220 Ω2
 PC————————-1
Cavo elettricoELEGOOJumper12
BuzzerELEGOOAttivo1
LedELEGOORED1
LedELEGOOGREEN1
Accelerometro – GiroscopioARCELIGY-521 – MPU60501
ArduinoELEGOOUNO R31
Cavo USBELEGOOA – B1
Saldatore a StagnoJiaFuLinKit1
StagnoJiaFuLinKit1

Immagini dimostrative

Figura 1: Circuito in funzionamento con evento sismico non in atto
Figura 2: Circuito in funzionamento con evento sismico in atto

Collegamento degli strumenti

Posizionare Arduino UNO R3 sul banco di lavoro e collegare alla porta seriale il cavo USB di tipo B. Collegare i diversi cavetti jumper ai pin digitali (n. 2-3-4) e analogici (A5-A4) di Arduino, oltre al pin GND e a quello dell’alimentazione da 3.3 V. Le altre estremità dei cavetti jumper dovranno essere connesse alla breadboard, prestando attenzione a non realizzare cortocircuiti, collegando cavi differenti in fori comunicanti. Ai cavi connessi ai pin digitali n. 2-3 collegare rispettivamente uno dei due terminali delle resistenze da 220 Ω, assicurandosi che gli altri due terminali rimanenti siano connessi a fori in comune con gli anodi dei led rosso e verde, locati nella sezione superiore rispetto all’incavo isolante. Connettere a massa comune i due catodi. Al cavo connesso al pin n. 4 collegare il polo positivo del buzzer (piezo) attivo, mentre quello negativo a massa comune. Prima di poter posizionare l’MPU 6050 sulla breadboard è obbligatorio saldare il pettine all’integrato, sfruttando un saldatore basato su filo di stagno. Il cavo fuoriuscente dal pin di alimentazione da 3.3 V deve essere connesso al foro in comune con il pin VCC dell’integrato GY-521, così come il suo pin GND alla massa comune. I cavi connessi ai pin analogici A5 e A4 devono essere connessi rispettivamente ai fori in comune con il pin SCL e SDA dell’integrato dell’accelerometro/giroscopio. Infine, per rendere la massa comune, è necessario connettere il cavo fuoriuscente dal pin GND di Arduino con un foro qualsiasi della breadboard tra quelli dell’alimentazione con il segno -. Per alimentare Arduino e quindi il circuito sarà necessario connettere l’estremità di tipo A del cavo USB ad una porta del proprio PC.

Figura 3: Schema elettrico circuito realizzato

Progettazione

In questa fase, valutati i componenti necessari per realizzare il sismografo, si è passati a dimensionare le resistenze sulla base della tensione di soglia del led rosso e verde, rispettivamente pari a 1.8 V e 2.0 V. Per cui il valore delle due resistenze scelte per entrambi i diodi è pari a 220 Ω, tenendo conto anche della tensione erogata dai pin digitali di Arduino pari a 5 V. Definito tale aspetto elettronico, occorre ora realizzare l’algoritmo risolutivo da implementare attraverso Arduino IDE, sfruttando il linguaggio di programmazione C++ e soprattutto la libreria “Wire.h” per l’interfacciamento con il componente GY-521. L’obiettivo è quello di poter consentire all’utente finale di visualizzare i valori istantanei, degli assi X, Y e Z, forniti dall’accelerometro sul plotter seriale dell’IDE. L’algoritmo è così costituito: richiamare la funzione per effettuare la scrittura dei tre valori degli assi nel buffer comune e procedere a effettuare i primi controlli sulla base delle condizioni dei seguenti cicli. Finché questi tre valori sforano un determinato range, definito attraverso il parametro della “TOLLERANZA” e il loro valore di soglia, che definisce in termini numerici l’assenza di terremoto, allora verrà alimentato il led rosso con relativa emissione di un allarme acustico da parte del buzzer, con frequenza pari a 1000 Hz. Inoltre, viene “ciclata” la funzione che legge i valori e li pone nelle variabili del buffer comune. Usciti dal ciclo, si pone il led rosso allo stato di spento e si interrompe l’emissione del suono. Con un secondo ciclo si definisce quanto segue: finché i valori, relativi ai tre assi, forniti dall’accelerometro rientrano nel range, definito dal parametro “TOLLERANZA” e dalle proprie soglie di attivazione, allora verrà alimentato il led verde, “ciclando” anche la funzione che consente la scrittura dei valori degli assi nel buffer comune. Uscito dal ciclo si pone il led verde sullo stato di spento. Queste istruzioni sono presenti nella procedura “loop”, mentre in quella “setup” bisogna settare le modalità dei pin digitali, oltre a inizializzare la trasmissione verso il plotter, il monitor seriale dell’IDE e dal modulo GY-521.

Testing

Terminata la fase di progettazione elettronica e algoritmica, dopo aver concluso anche il montaggio dei componenti, si può effettuare il testing del circuito in maniera semplificata. La prima operazione da effettuare, dopo l’installazione dell’IDE, è scaricare la libreria “Wire.h” e inserirla nella directory delle librerie predefinite di Arduino IDE sul proprio PC. I file in questione che la compongono sono i seguenti: “i2cdevlib.h” e “MGU6050.h”. In questo modo sarà possibile interfacciare il modulo GY-521 con il software realizzato. In seguito, verificare la corretta installazione dell’integrato dell’accelerometro e giroscopio, compilando e caricando un codice pre-fornito dal produttore: mentre questo è in esecuzione su Arduino, se restituirà il seguente messaggio sul monitor seriale: “I2C Scanner Scanning… I2C device found at address 0x68 ! done”, allora è stato correttamente rilevato il modulo GY-521, altrimenti in corrispondenza del seguente messaggio: “Scanning… No I2C device found” esso non è stato rilevato. In caso di esito positivo, è possibile proseguire nel testing. Successivamente, aprire il progetto con il codice realizzato per il sismografo e compilarlo per tradurlo in linguaggio macchina, una sequenza di 0 e 1 comprensibile al microcontrollore Arduino, e caricarlo in memoria. Questo lo si può fare attraverso un unico “button” presente nell’IDE, in alto a destra, avente il simbolo di una freccia rivolta verso destra. Quando il processo di caricamento è terminato, uscirà una notifica in basso a destra nell’IDE che segnalerà l’evento: ora il programma è in esecuzione e se tutto è andato a buon fine, aprendo il plotter seriale e il monitor seriale nell’IDE si visualizzano i valori dei tre assi forniti dall’accelerometro. Per verificare il corretto funzionamento del circuito simulare un evento sismico, agitando la basetta prototipale con le proprie mani: se il led verde si spegne e quello rosso si accende, in contemporanea all’emissione dell’allarme acustico da parte del buzzer, allora la fase di testing è conclusa dato l’esito positivo.

Osservazioni

L’esperienza condotta risulta soddisfare pienamente i requisiti elettronici ed informatici richiesti per la realizzazione di un sistema di tale tipologia. L’aspetto cruciale del funzionamento risiede nella correttezza dell’algoritmo risolutivo ideato a partire da uno studio attento della realtà, così come delle proprietà dei componenti elettronici costituenti il circuito, adottando un approccio di tipo down, in cui il problema principale è stato suddiviso in porzioni più piccole, dette sotto problemi o sottoprogrammi, a ciascuno delle quali corrisponde l’implementazione di una procedura nel linguaggio C++. Inoltre, è proprio in queste fase che vi sono state le maggiori complessità: inizialmente l’algoritmo risolutivo era stato erroneamente progettato, a causa di una mancata corretta valutazione del ciclo di vita delle variabili, indispensabili per la lettura e scrittura dei valori relativi ai tre assi. Infatti, queste, essendo locali alle funzioni, venivano de-allocate in corrispondenza della terminazione dell’esecuzione delle istruzioni. Tale aspetto è stato risolto con un buffer comune, costituito da tre variabili globali, assicurandosi che l’accesso in lettura avvenga “se e solo se”, prima è avvenuta la scrittura. Si è realizzata una semplice sincronizzazione produttore/consumatore richiamando, nell’ordine corretto, le procedure deputate a eseguire tali azioni. Dato il corretto funzionamento del circuito è possibile smontarlo dalla basetta prototipale, al fine di saldare effettivamente i vari componenti tra loro, concludendo la realizzazione definitiva del progetto.

Codice

Codice pre-fornito per rilevamento modulo GY-521
#include <Wire.h>
 
 
void setup()
{
  Wire.begin();
 
  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}
 
 
void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}
Codice realizzato da Antonio Tortona per implementare il funzionamento del sismografo
#include <Wire.h>

enum PIN {
  LEDRED = 2,
  LEDGREEN,
  BUZZER
};

enum THESHOLD {
  X = 1500,
  Y = 0,
  Z = 16000,
  TOLLERANZA = 2000
};

const int MPU = 0x68;  //Default address of I2C for MPU 6050
int16_t AcX, AcY, AcZ;

void setup() 
{
  pinMode(LEDGREEN, OUTPUT);
  pinMode(LEDRED, OUTPUT);
  pinMode(BUZZER, INPUT);
  Wire.begin();                 // Wire library initialization
  Wire.beginTransmission(MPU);  // Begin transmission to MPU
  Wire.write(0x6B);             // PWR_MGMT_1 register
  Wire.write(0);                // MPU-6050 to start mode
  Wire.endTransmission(true);
  Serial.begin(9600);
}

void seismograph() 
{
  Wire.beginTransmission(MPU);      // Start transfer
  Wire.write(0x3B);                 // register 0x3B (ACCEL_XOUT_H), records data in queue
  Wire.endTransmission(false);      // Maintain connection
  Wire.requestFrom(MPU, 14, true);  // Request data to MPU

  //Reads byte by byte
  AcX = Wire.read() << 8 | Wire.read();  // 0x3B (ACCEL_XOUT_H) &  0x3C (ACCEL_XOUT_L)
  AcY = Wire.read() << 8 | Wire.read();  // 0x3D (ACCEL_YOUT_H) &  0x3E (ACCEL_YOUT_L)
  AcZ = Wire.read() << 8 | Wire.read();  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)

  //Prints values on Serial
  Serial.print(AcX);
  Serial.print(",");
  Serial.print(AcY);
  Serial.print(",");
  Serial.println(AcZ);
  delay(20);
}

void loop() 
{
  seismograph();
  while (abs(AcX - X) > TOLLERANZA || abs(AcY - Y) > TOLLERANZA || abs(AcZ - Z) > TOLLERANZA) 
  {
    digitalWrite(LEDRED, HIGH);
    tone(BUZZER, 1000);
    seismograph();
  }
  digitalWrite(LEDRED, LOW);
  noTone(BUZZER);
  while (abs(AcX - X) < TOLLERANZA && abs(AcY - Y) < TOLLERANZA && abs(AcZ - Z) < TOLLERANZA) 
  {
    digitalWrite(LEDGREEN, HIGH);
    seismograph();
  }
  digitalWrite(LEDGREEN, LOW);
}