Luigi Morelli
Published © LGPL

How to design a breathalyser shield for Arduino

A complete project, from the design to the electric scheme, from the PCB to the 3D-printed container.

IntermediateFull instructions provided4 hours1,594
How to design a breathalyser shield for Arduino

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Seeed Studio Seeed - Grove alcohol sensor MQ303A
×1
Fixed network resistor 330 ohm 10 elements
Bourns
×1
Array LED mulricolor Broadcom
×1
Buzzer
Buzzer
×1

Software apps and online services

Arduino IDE
Arduino IDE
Tinkercad
Autodesk Tinkercad
EasyEDA
JLCPCB EasyEDA

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Custom parts and enclosures

The container for our breathalyser

Etilometro - Breathalyser

Schematics

The electric scheme of the project

The PCB layout

The 3D view of the project

Code

The code to pre-heat the sensor

C/C++
#define PIN_RISCALDATORE 15

void setup() {
  Serial.begin(9600);
  pinMode(PIN_RISCALDATORE, OUTPUT);
  digitalWrite(PIN_RISCALDATORE, LOW);
}

void loop() {
  float tensione_sensore;
  float Rs_aria;  // Acquisisce il parametro RS in aria
  float valore_sensore = 0.0;

  // --- Richiediamo la media su 100 letture ---
  for (int x = 0; x < 100; x++) {
    valore_sensore = valore_sensore + analogRead(A0);
  }
  valore_sensore = valore_sensore / 100;
  Serial.print("Valore sensore = ");
  Serial.println(valore_sensore);
  // ---

  tensione_sensore = valore_sensore / 1024.0 * 5.0;
  // La tensione  inversamente proporzionale alla concentrazione
  Rs_aria = tensione_sensore / (5.0 - tensione_sensore);
  Serial.print("Tensione sensore = ");
  Serial.print(tensione_sensore);
  Serial.println("V");
  Serial.print("Rs aria = ");
  Serial.println(Rs_aria);
  delay(1000);
}

A basic testing program to check the setup

C/C++
#define PIN_RISCALDATORE 15


float valore_sensore;
float tensione_sensore;
float Rs_aria;

void setup() {
  Serial.begin(9600);
  pinMode(PIN_RISCALDATORE, OUTPUT);
  digitalWrite(PIN_RISCALDATORE, LOW);

  // --- Sostituire il valore ricavato nello sketch MQ_303A_test
  // --- Oppure richiediamo la media su 1000 letture ---
  for (int x = 0; x < 1000; x++) {
    valore_sensore = valore_sensore + analogRead(A0);
  }  
  valore_sensore = valore_sensore / 1000.0; 
  tensione_sensore = (float)valore_sensore/1024*5.0;
  Rs_aria = tensione_sensore / (5.0 - tensione_sensore);
}


void loop() {
  float Rs_gas;
  float rapporto;

  valore_sensore = analogRead(A0);
  tensione_sensore = (float)valore_sensore/1024*5.0;
  Rs_gas = tensione_sensore/(5.0 - tensione_sensore);

  rapporto = Rs_gas / Rs_aria;

  Serial.print("Tensione sensore = ");
  Serial.print(tensione_sensore);
  Serial.println("V");
  Serial.print("Rs_gas = ");
  Serial.println(Rs_gas);
  Serial.print("Rs/R0 = ");
  Serial.println(rapporto);

  Serial.println("---");

  delay(1000);
}

The final code for the breathalyser!

C/C++
#define PIN_BUZZER        2
#define PIN_RISCALDATORE 15

int scala = 0;
float valore_sensore;
float tensione_sensore;
float Rs_aria;

void setup() {
  // Serial.begin(9600);
  
  pinMode(PIN_BUZZER, OUTPUT);
  pinMode(PIN_RISCALDATORE, OUTPUT);
  digitalWrite(PIN_RISCALDATORE, LOW);
  
  // Pin di pilotaggio dei LED
  pinMode( 3, OUTPUT);
  pinMode( 4, OUTPUT);
  pinMode( 5, OUTPUT);
  pinMode( 6, OUTPUT);
  pinMode( 7, OUTPUT);
  pinMode( 8, OUTPUT);
  pinMode( 9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);

  digitalWrite( 3, LOW);
  digitalWrite( 4, LOW);
  digitalWrite( 5, LOW);
  digitalWrite( 6, LOW);
  digitalWrite( 7, LOW);
  digitalWrite( 8, LOW);
  digitalWrite( 9, LOW);
  digitalWrite(10, LOW);
  digitalWrite(11, LOW);
  digitalWrite(12, LOW);

  // --- Richiediamo la media su 1000 letture ---
  for (int x = 0; x < 1000; x++) {
    valore_sensore = valore_sensore + analogRead(A0);
  }  
  valore_sensore = valore_sensore / 1000.0; 
  tensione_sensore = (float)valore_sensore/1024*5.0;
  Rs_aria = tensione_sensore / (5.0 - tensione_sensore);  
}

void loop() {
  float Rs_gas;
  float rapporto;
  
  valore_sensore = analogRead(A0);
  tensione_sensore = (float)valore_sensore/1024*5.0;
  Rs_gas = tensione_sensore/(5.0 - tensione_sensore);

  rapporto = Rs_gas / Rs_aria;

  // Definiamo una scala a 10 elementi per gestire il rapporto alcolemico
  scala = 0;
  if (rapporto > 0.8) scala = 0;
  if (rapporto > 0.7 && rapporto < 0.8) scala = 1;
  if (rapporto > 0.6 && rapporto < 0.7) scala = 2;
  if (rapporto > 0.5 && rapporto < 0.6) scala = 3;  
  if (rapporto > 0.4 && rapporto < 0.5) scala = 4;
  if (rapporto > 0.3 && rapporto < 0.4) scala = 5;
  if (rapporto > 0.2 && rapporto < 0.3) scala = 6;
  if (rapporto > 0.15 && rapporto < 0.2) scala = 7;
  if (rapporto > 0.1 && rapporto < 0.15) scala = 8;  
  if (rapporto < 0.1) scala = 9;

  accendi(scala);
  suona(scala);
/*
  Serial.print("Tensione sensore = ");
  Serial.print(tensione_sensore);
  Serial.println("V");
  Serial.print("Rs_gas = ");
  Serial.println(Rs_gas);
  Serial.print("Rs/R0 = ");
  Serial.println(rapporto);
  Serial.println(scala);

  Serial.println("---");
*/  
  delay(2000);
}

void accendi(int n) {
  // Spegne tutti i LED
  for (int i = 0; i < 10; i++) {
    digitalWrite(i + 3, LOW);
  }

  // Accende i LED necessari
  for (int i = 0; i < n + 1; i++) {
    digitalWrite(i + 3, HIGH);
  }
}

void suona(int n) {
  switch (n) {
    case 7:
      for (int i = 0; i < 3; i++) {
        tone(PIN_BUZZER, 220, 200);
        delay(200);
        tone(PIN_BUZZER,   0, 200);
        delay(200);
      }
      break;
    case 8:
      for (int i = 0; i < 4; i++) {
        tone(PIN_BUZZER, 440, 100);
        delay(100);
        tone(PIN_BUZZER,   0, 100);
        delay(100);
      }    
      break;
    case 9:
      for (int i = 0; i < 5; i++) {
        tone(PIN_BUZZER, 880,  50);
        delay(50);
        tone(PIN_BUZZER,   0, 50);
        delay(50);
      }   
      break;
    default: 
      break;
  }
}

Credits

Luigi Morelli
13 projects • 6 followers
I work to contribute to the change of the key sectors of computer science and to offer reasoned syntheses and consultancy to ICT companies.
Contact

Comments

Please log in or sign up to comment.