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:
- vytlačený 3D model skladajúci sa z niekoľkých častí
- niekoľko drevených častí vyrezaných na laseri z preglejky, ktoré sú použité na zostavenie váhového senzoru
- Arduino Nano
- 2 x AD prevodník HX711
- 2 x váhový senzor pre maximálnu hmotnosť 1 kg
- niekoľko prepojovacích káblov
- nepájivé kontaktné pole
- sirénka
- RGB led pásik
- 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
- v tejto fáze nakalibrujeme oba snímače podľa návodu: https://www.youtube.com/watch?v=nGUpzwEa4vg
- do Arduina nahráme kód (s nakalibrovanými hodnotami)
Použité zdroje:
- Zdroj kódu a návod kalibrácie: https://www.youtube.com/watch?v=nGUpzwEa4vg
- STL súbory tlačeného modelu:
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