Operácie

Notification System

Zo stránky SensorWiki

Autor: Viktor Lučkanič
Študijný odbor: Robotika a kybernetika 3. Bc. (2019)

Opis projektu

Cieľom projektu je vytvoriť model úložného priestoru v aute, konkrétne miesto na mobil a miesto na vodu/pohár. Pri simulovanom odchode človeka z auta (zoberie mobil), ho notifikačný systém v prípade zabudnutia vecí na to svetelne aj zvukovo upozorní.


Prečo?

V budúcnosti, teda o 20 - 30 rokov sa predpokladá, že bude naplno fungovať "carsharing", teda zdieľanie áut. Auto teda za jeden deň môže zmeniť hneď niekoľko používateľov. Práve na zabezpečenie komfortu a čistoty pri používaní takýchto áut sa môže využiť tento notifikačný systém, ktorý upozorní užívateľa na znečistenie auta pri odchode.

Ako ?

Na výrobu modelu budeme potrebovať nasledujúce komponenty:

  1. vytlačený 3D model skladajúci sa z niekoľkých častí
  2. niekoľko drevených častí vyrezaných na laseri z preglejky, ktoré sú použité na zostavenie váhového senzoru
  3. Arduino Nano
  4. 2 x AD prevodník HX711
  5. 2 x váhový senzor pre maximálnu hmotnosť 1 kg
  6. niekoľko prepojovacích káblov
  7. nepájivé kontaktné pole
  8. sirénka
  9. RGB led pásik
  10. USB mini kábel na napájanie

Postup výroby:

  • ako prvé si na laseri vyrežeme kusy z preglejky (pre každý senzor obdĺžnik 5 x 10 cm, kruh s priemerom 7 cm a dve kúsky 2.5 x 1 cm) na zostavenie váhového senzoru a zlepíme ich dokopy ako vidíme na obrázku:

  • na 3D tlačiarni vytlačíme model, na ktorý následne nanesieme tmel a nastriekame farbou

  • led pásik nalepíme po obvode miesta na pohár

  • napájkujeme kábliky z váhového senzora na prevodník HX711 a podľa schémy v časti "Popis riešenia" zapojíme Arduino Nano a všetky periférie do nepájivého kontaktného poľa

  • na váhové senzory nalepíme nosné plochy tak, aby zaťažovaný bod senzoru bol približne v strede nosných plôch a prilepíme ich do vnútra modelu (je potrebné ich vypodložkovať, aby sme dosiahli potrebnú výšku). Taktiež prilepíme aj kontaktné pole so zvyšnou elektronikou

  • všetky časti modelu dáme dokopy

  • do Arduina nahráme kód (s nakalibrovanými hodnotami)


Použité zdroje:

    Držiak dolný diel
    Držiak horný diel
    Krúžok platnička svetlo
    Veľká časť

Analýza

Pre identifikáciu istého predmetu na mieste sa dajú použiť rôzne senzory na meranie vzdialenosti ako napr. ultrazvukový senzor. V našom projekte sme sa rozhodli použiť váhový senzor, pretože sme nechceli, aby bolo navonok vidieť akúkoľvek elektroniku ako by to bolo napr. pri ultrazvukovom senzore.

Váhový senzor + AD prevodník HX711

Váhový senzor vracia analogovú hodnotu v závislosti od zaťaženia koncového bodu senzora. V AD prevodníku sa tento signál prevedie na signál (konkrétne Data a Clock), ktorý ide do dvoch digitálnych vstupov Arduina. Prevodník ma ešte ďalšie 2 vstupy na napájanie 5V a GND.


Digitálny RGB Led pásik

Tento RGB pásik má 3 vstupy: 5V, GND a Dátový vstup. Dátovým vstupom sa posiela signál o tom, ktoré konkrétne ledky majú byť rozsvietené a akou farbou. Na ovládanie tohoto pásika bola použitá knižnica FastLED


Popis riešenia

Požiadavky na tento model sú také, že pri neprítomnosti pohára v odkladacom mieste bude led pásik svietiť na modro. Pri prítomnosti pohára aj mobilu na zeleno. Pri odchode z auta, teda pri odobratí mobilu a nechaní pohára začnú ledky blikať na červeno a po 2 bliknutiach začne aj zvukové upozornenie pípaním sirénky.

Ako hlavný riadiaci prvok bolo pre jeho malé rozmery použité Arduino Nano, na ktoré boli pripojené ďalšie periférie. Boli použité 2 váhové senzory na zisťovanie prítomnosti mobilu resp. pohára spolu s dvoma prevodníkmi, ktoré zabrali na Arduine každé po 2 digitálne piny. Ďalej bola pripojená jedna sirénka na jeden digitálny pin a taktiež RGB led pásik so samostatne adresovateľnými ledkami s jedným dátovým vstupom. Celá táto elektronika bola umiestnená do vnútra vytlačeného modelu.

Schéma zapojenia Arduina s perifériami

Algoritmus a program

Program bol vytvorený v prostredí Arduino IDE. Ako základ pre získanie hodnôt z váhových senzorov bol použitý kód (súbory HX711.cpp a HX711.h) z návodu na kalibráciu senzoru uvedený v zdrojoch ako Zdroj kódu. Celý program sa skladá z 3 zdrojových súborov (dve pôvodné zo zdroja a jeden mnou upravený a doplnený - LoadCell.ino).

Algoritmus

  • Podmienky pre modrú farbu: ak nie je na senzore pohára prítomná hmotnosť pohára, na mobile nezáleží
  • Podmienky pre zelenú farbu: ak je na senzore mobilu prítomná hmotnosť mobilu a na senzore pohára hmotnosť pohára
  • Podmienky pre červenú farbu: ak na senzore mobilu nie je prítomná hmotnosť mobilu a na senzore pohára je hmotnosť pohára

Ďalej je uvedený vývojový diagram:

Pre fungovanie nasledujúceho kódu je potrebné do Arduino IDE importovať knižnicu FastLED


#define FASTLED_INTERRUPT_RETRY_COUNT 0
#define FASTLED_ESP8266_RAW_PIN_ORDER

#include "HX711.h"
#include <FastLED.h>

#define NUM_LEDS 8

HX711 cellM(9, 10); //DT,SCK   //senzor pre mobil
HX711 cellP(4, 5); //DT,SCK    //senzor pre pohar
CRGB leds[8];
const int ledPin = 7;
const int sirenPin = 12;
const int mobil = 80;
const int pohar = 15;
const int rychlost = 4;
const int krok = 1;

//long val=0;
long valM = 0;
long valP = 0;
float count = 0;
float vahaM = 0;
float vahaP = 0;


void setup() {

  Serial.begin(9600);
  FastLED.addLeds<WS2812B, ledPin, RGB>(leds, NUM_LEDS);

  pinMode(sirenPin, OUTPUT);
}


void loop() {

  char farba ;
  int pocetCImp = 0;

  while (1) {

    count = count + 1;

    //vyrazy na kalibraciu vahovych senzorov
    //val = ((count-1)/count) * val    +  (1/count) * cellP.read();   // dlhodoby priemer
    //val = 0.8 * val    +   0.2 * cell.read();                       // kratkodoby priemer
    valM = cellM.read(); // most recent reading
    valP = cellP.read(); // most recent reading

    //vypocet aktualnej vahy na senzoroch v [g]
    vahaM = ((valM - 8572579) / 31748.0f) * 32.6;
    vahaP = ((valP - 8230240) / 33190.0f) * 32.6;
    Serial.print("Mobil:  ");
    Serial.print(vahaM);
    Serial.print(" [g] \t\t");
    Serial.print("Pohar:  ");
    Serial.print(vahaP);
    Serial.println(" [g]");

    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    // situacia ked je tam mobil a aj pohar
    if (vahaM > mobil && vahaP > pohar) {      //ZELENA ZIADANA

      if (farba != 'z') {

        if (farba == 'm') {
          for (int j = 255; j >= 0; j -= krok) {
            for (int i = 0; i < NUM_LEDS; i++) {
              leds[i] = CRGB(0, 0, j);        //MODRA stmievanie                  //GRB
            }

            FastLED.show();
            delay(rychlost);
          }
        }


        for (int j = 0; j <= 255; j += krok) {
          for (int i = 0; i < NUM_LEDS; i++) {
            leds[i] = CRGB(j, 0, 0);      //ZELENA rozsvecovanie                  //GRB
          }

          FastLED.show();
          delay(rychlost);
        }
      }
      farba = 'z';

      //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // situacia ked mobil nie je na mieste a pohar je
    } else if (vahaP > pohar && vahaM < mobil) {        //CERVENA ZIADANA

      pocetCImp = 0;

      if (farba != 'c') {
        for (int j = 255; j >= 0; j -= krok) {
          for (int i = 0; i < NUM_LEDS; i++) {
            if (farba == 'm') {
              
              leds[i] = CRGB(0, 0, j);      //MODRA stmievanie                  //GRB
            }
            else if (farba == 'z') {

              leds[i] = CRGB(j, 0, 0);      //ZELENA stmievanie                  //GRB
            }
          }

          FastLED.show();
          delay(rychlost);
        }

        // blikanie cervenej
        while (1) {  //cervena

          if (pocetCImp > 1) {
            siren();
          }

          for (int j = 0; j <= 255; j += krok) {
            for (int i = 0; i < NUM_LEDS; i++) {
              leds[i] = CRGB(0, j, 0);      //CERVENA rozsvecovanie
            }

            FastLED.show();
            delay(rychlost);
          }


          if (pocetCImp > 1) {
            siren();
          }

          for (int j = 255; j >= 0; j -= krok) {
            for (int i = 0; i < NUM_LEDS; i++) {
              leds[i] = CRGB(0, j, 0);      //CERVENA stmievanie
            }

            FastLED.show();
            delay(rychlost);
          }

          pocetCImp++;

          // kontrola vahy pre vyskocenie z cyklu blikania cervenej 
          valM = cellM.read(); // most recent reading
          valP = cellP.read(); // most recent reading
          vahaM = ((valM - 8572579) / 31748.0f) * 32.6;
          vahaP = ((valP - 8230240) / 33190.0f) * 32.6;
          Serial.print("Mobil:  ");
          Serial.print(vahaM);
          Serial.print(" [g] \t\t");
          Serial.print("Pohar:  ");
          Serial.print(vahaP);
          Serial.println(" [g]");

          if (vahaM > mobil || vahaP < pohar) {
            break;
          }
        }

        pocetCImp = 0;
        farba = 'c';
      }

      ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // situacia ked pohar nie je pritomny, na mobile nezalezi
    } else {                //MODRA ZIADANA

      if (farba != 'm') {
        if (farba == 'z') {
          for (int j = 255; j >= 0; j -= krok) {
            for (int i = 0; i < NUM_LEDS; i++) {
              leds[i] = CRGB(j, 0, 0);      //ZELENA stmievanie                  //GRB
            }

            FastLED.show();
            delay(rychlost);
          }
        }

        for (int j = 0; j <= 255; j += krok) {
          for (int i = 0; i < NUM_LEDS; i++) {
            leds[i] = CRGB(0, 0, j);      //MODRA rozsvecovanie                      //GRB
          }

          FastLED.show();
          delay(rychlost);
        }

        farba = 'm';
      }
    }
  }
}


//funkcia pipania sireny
void siren() {

  digitalWrite(sirenPin, HIGH);
  delay(50);
  digitalWrite(sirenPin, LOW);
  delay(50);
  digitalWrite(sirenPin, HIGH);
  delay(50);
  digitalWrite(sirenPin, LOW);

}


Zdrojové kódy: HX711.cpp, HX711.h a LoadCell.ino


Výsledok

Môžeme skonštatovať, že sa podarilo vytvoriť model, ktorý funguje podľa očakávaní a stanovených požiadaviek.

Fotka výsledného modelu


Video interakcie