Wieniec świąteczny automatycznie pozdrawiający gości

Wieniec świąteczny automatycznie pozdrawiający gości

Święta Bożego Narodzenia to taki moment w roku, w którym każdy elektronik myśli o wykonaniu jakiejś ozdoby czy innego elementu wpisującego się w ten piękny okres. Obecnie możliwości są większe niż kiedykolwiek – z łatwością można wykonać coś, co wygląda i działa imponująco i z pewnością ucieszy wszystkich domowników oraz świątecznych gości.

Moduły Arduino mają bardzo ogromne możliwości, ograniczone niemal tylko fantazją projektantów. W poniższym projekcie zastosowano jedną z takich możliwości – odtwarzanie plików MP3. Świąteczne piosenki są nierozerwalnie związane z tym zimowym okresem, więc co może być ciekawszego, niż urządzenie, które automatycznie będzie je odtwarzać. Sprzężenie tej funkcji z wykrywaczem ruchu, pozwala na reakcję np. na zbliżających się do naszego domu gości i pozdrawianie ich kolędami.

Zaprezentowany system zawiera moduł Arduino wraz z czujnikiem PIR do wykrywania ruchu i automatycznego odtwarzania zapisanych na karcie SD plików MP3. Autor projektu zintegrował ten system z ozdobnym wieńcem, który umieścił na drzwiach wejściowych do domu. Dzięki temu, gdy ktokolwiek pojawi się przed jego drzwiami, usłyszy jedną z zapisanych w pamięci systemu kolęd.

Wieniec został zbudowany na bazie modułu z mikrokontrolerem ekosystemu Arduino z shieldem Adafruit MP3 i czujnikiem ruchu Parallax PIR. Po wykryciu, że ktoś zbliża się do drzwi, następuje odtwarzanie nagranego wcześniej niestandardowego powitania, które brzmi jak świąteczny elf, a następnie odtwarzana jest losowa kolęda. Piosenki będą odtwarzane tak długo, jak czujnik PIR będzie wykrywał ruch w oknie 15 sekund od uruchomienia.

Potrzebne elementy

Do zbudowania systemu potrzebne będą:

  • Arduino Uno (lub podobna płytka z mikrokontrolerem);
  • shield Arduino – Adafruit Music Maker, moduł odtwarzacza plików MP3 z wbudowanym wzmacniaczem stereo o mocy 3 W;
  • karta microSD do przechowywania plików MP3;
  • sensor PIR, autor zastosował sensor firmy Parallax, ale do projektu nada się każdy sensor PIR z wyjściem kompatybilnym z Arduino;
  • głośnik o impedancji nie mniejszej niż 4 Ω;
  • obudowa na moduł Arduino;
  • zasilanie (jedno z dwojga):
    • zasilacz 9 V DC o wydajności prądowej 1000 mA lub podobny, kompatybilny z Arduino,
    • pakiet baterii, dający ok 9 V na wyjściu (nie jest to rekomendowane rozwiązanie z uwagi na brak optymalizacji systemu pod kątem aplikacji bateryjnych);
  • wieniec świąteczny – musi być dostatecznie duży, aby zmieściły się za nim wszystkie komponenty.

Część elektroniczna

System składa się z kilku modułów, których integracja jest bardzo prosta. Na fotografii 1 pokazane są wszystkie elementy połączone ze sobą.

Fotografia 1. Poszczególne moduły połączone ze sobą

Shield MP3

Shield Adafruit MP3 można zakupić jako niezmontowany. Upraszcza to montaż złącza w miejsce pinów, dzięki czemu można dołączyć tam złącze, które pozwala na połączenie shielda z Arduino nie na stałe. Ma to tę zaletę, że możliwe jest odłączenie shielda po świętach i zastosowanie Arduino do innych celów.

Moduł Adafruit Music Maker MP3 jest przeznaczony do odtwarzania muzyki z plików MP3, AAC, WMA, OGG i wielu innych. Zawiera scalony kodek VS1053B, który sprzętowo dekoduje dane odczytywane z karty pamięci. Moduł może być również używany do nagrywania dźwięku w formacie PCM (WAV), jak i skompresowanym Ogg Vorbis. Dodatkowo kodek pozwala na, cyfrową regulację basów, tonów wysokich i głośności. Układ ma zintegrowany przetwornik cyfrowo-analogowy (DAC), dzięki czemu wyjście z układu podać można bezpośrednio na, np. wzmacniacz mocy. Dostępny jest również specjalny tryb MIDI, w którym można uruchomić układ, w trybie, w którym odczytuje on klasyczne komunikaty MIDI nadawane z prędkością 31250 kbaud z portu szeregowego Arduino i działa jak automat syntezatorowy/perkusyjny – ma wiele wbudowanych efektów perkusyjnych i sampli.

Shield ma wbudowany wzmacniacz audio, podłączony do wyjścia kodeka. Dzięki temu można do modułu podłączyć bezpośrednio głośnik, na którym odtwarzana będzie muzyka. Na płytce modułu znajduje się również miejsce do instalacji opcjonalnych filtrów itp. Moduł wyposażony jest ponadto w siedem dodatkowych linii GPIO, które można zapisywać lub odczytywać za pomocą biblioteki Arduino. Linie te można użyć np. do czytania stanu przycisków lub kontrolowania diod LED.

Na płytce shielda znajduje się gniazdo karty microSD, dla dowolnej karty SD sformatowanej w systemie plików FAT16/FAT32 o pojemności 64 MB lub większej. Shield zawiera również przesuwniki poziomów, dzięki czemu moduł może współpracować z układami Arduino (5 V), mimo że karta SD i chipset kodeka audio zasilane są napięciem 3,3 V.

Czujnik PIR

Sensor PIR (pasywny sensor pracujący w podczerwieni) to najprostszy elektroniczny sensor do wykrywania ruchu. W dużym uproszczeniu, jest to czujnik mierzący natężenie światła podczerwonego i reagujący na jego zmianę – oznacza to, że przed sensorem poruszyło się coś, odbijającego (lub absorbującego) promieniowanie w tym zakresie widmowym. Sensory PIR wykorzystują daleką podczerwień, dokładnie ten sam zakres, jaki stosuje się np. przy pomiarze temperatury lub w systemach termowizji. Dlatego czujki PIR tak dobrze reagują na ruch ludzi – emitują oni promieniowanie termiczne, które odróżnia ich od, na ogół chłodniejszego otoczenia.

Oprócz samego elementu czułego na podczerwień (piroelement) czujnik taki zawiera soczewkę Fresnela lub lustro, kierujące promieniowanie IR w kierunku sensora. Na ogół, w celu eliminacji fałszywych detekcji stosuje się skomplikowane algorytmy wykorzystujące dwa lub cztery czujniki podczerwieni. Cała logika jest zawarta w sensorze, a na zewnątrz wystawia on jedynie sygnał logiczny, informujący o ty, czy wykryty został ruch w polu widzenia czujnika.

Czujnik PIR połączony jest z modułem Arduino z pomocą trzech linii – dwie z nich to zasilanie (VCC – 5 V oraz masa – GND). Trzecia linia to cyfrowy sygnał, który podłączony jest do wejścia cyfrowego numer 2. Jeśli podłączymy sensor PIR do innego wejścia, należy zmienić to w kodzie programu. Linia, do której dołączony jest sensor PIR zdefiniowana jest w następujący sposób:

int inputPin = 2; // wybierz linię, do której dołączono sensor PIR

Głośnik

Głośnik podłączony jest po prostu do modułu Adafruit Music Maker MP3 do przeznaczonego złącza (dwa lub cztery złącza śrubowe, zależnie, czy korzystamy z opcjo mono czy stereo). Dołączany głośnik musi mieć moc maksymalną nie mniejszą niż 3 W i impedancję nie mniejszą niż 4 Ω, inaczej możemy uszkodzić głośnik lub wzmacniacz.

Zasilanie/pakiet baterii

Ostatnim elementem systemu, jest źródło zasilania. Autor początkowo zasilał moduł z baterii, ale okazało się, że to źródło nie wytrzymuje za długo. System zasilany był z ośmiu baterii AA, jednakże energii w nich wystarczyło tylko na kilka dni działania systemu. Po kilku dniach, gdy baterie się rozładowały, autor zmienił źródło zasilania na zwykły zasilacz wtyczkowy o napięciu wyjściowym na poziomie 9 V. Istotne jest, aby był to zasilacz prądu stałego o stabilizowanym wyjściu. Wydajność prądowa zasilacza powinna być nie mniejsza niż 1 A. Jedynym problemem, przy takim źródle zasilania, może być estetyczne ukrycie kabla, który prowadzi do gniazdka.

Oprogramowanie

Pliki MP3

Pliki MP3 należy umieści na karcie SD w shieldzie MP3. Należy upewnić się, że znajduje się tam plik merry02.mp3, który zostanie odtworzony na powitanie po wykryciu ruchu. Można nazwać go inaczej, ale należy zaktualizować po tej zmianie kod programu (listing 1), aby poprawnie go obsługiwał. Należy upewnić się, że na karcie SD znajduje się, co najmniej 20 plików MP3. Należy w odpowiedni sposób zaktualizować tablicę plików, uwzględniając konwencje nazewnictwa zapisanych na karcie plików z utworami (więcej informacji na ten temat w dalszej części artykułu).

Listing 1. Uproszczony kod programu sterującego napisanego w Arduino

#include <MemoryFree.h>
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// Piny mikrookontrolera używane przez system
#define BREAKOUT_RESET  9
#define BREAKOUT_CS     10
#define BREAKOUT_DCS    8
//  Piny używane przez shield
#define SHIELD_RESET    -1
#define SHIELD_CS       7
#define SHIELD_DCS      6

#define CARDCS 4
#define DREQ 3

// Utworzenie obiektu do kontroli odtwarzacza MP3
Adafruit_VS1053_FilePlayer musicPlayer =
Adafruit_VS1053_FilePlayer(SHIELD_RESET,
SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

// wybierz linię do której dołączono diodę LED
int ledPin = 13;
// wybierz linię do której dołączono sensor PIR
int inputPin = 2;
// system uruchamia się zakładając brak ruchu
int pirState = LOW;
// zmienna do odczytywania stanu pinu
int val = 0;

// moment uruchomienia aplikacji (w milisekundach)
unsigned long detectTime;       
unsigned long resetTime;

char* myFiles[]={"track001.mp3", "track002.mp3", ...};

// losowy numer ścieżki
int randFile;
// zmienna do przechowywania ścieżki do pliku MP3
char MP3;
// czas kalibracji sensora
int calibrationTime = 15;

void setup() {
 Serial.begin(9600);
 delay(50);
 Serial.println("Adafruit VS1053 Library Test");
 resetTime = millis();
 // Inicjalizacja odtwarzacza MP3
 if (!musicPlayer.begin()) {
    Serial.println(F("Couldn’t find VS1053,
do you have the right pins defined?"));
    while (1);
 }
 Serial.println(F("VS1053 found"));
 pinMode(ledPin, OUTPUT);
 pinMode(inputPin, INPUT);
 // Kalibracja sensora
 Serial.print("calibrating sensor ");
 for(int i = 0; i < calibrationTime; i++){
   Serial.print(".");
   delay(1000);
   }
 Serial.println("done");
 Serial.println("SENSOR ACTIVE");
 delay(50);  
 if (!SD.begin(CARDCS)) {
   Serial.println(F("SD failed, or not present"));
   while (1);  
// koniec działania, jeśli karta SD nie działa
 }
 printDirectory(SD.open("/"), 0);
// ilość plików MP3 na liście
 int mp3ArrSize = 20;  
 Serial.println("------------------");
 Serial.print("MP3 Array Size: ");
 Serial.println(mp3ArrSize);
 for (int arrelement = 0; arrelement < mp3ArrSize;
arrelement++) {
   Serial.println(myFiles[arrelement]);
 }
 musicPlayer.setVolume(10,10); // ustawienie głośności
 if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
   Serial.println(F("DREQ pin is not an interrupt pin"));
}

void loop(){
// odczytaj wartość wejścową
 val = digitalRead(inputPin);
 Serial.println(val);
// ustaw losową ścieżkę
 randFile = random(20);
// wybierz losowy plik MP3
 char* MP3 = myFiles[randFile];
 Serial.println(MP3);
// sprawdza czy wejście jest w stanie wysokim
 if (val == HIGH) {
// zapala diodę LED
   digitalWrite(ledPin, HIGH);
   Serial.println("Motion detected!");
   detectTime = millis();
   if (!musicPlayer.playingMusic==true){
     if (! musicPlayer.playFullFile("merry02.mp3")) {
       Serial.print("Could not open");
       Serial.println("merry02.mp3");
       musicPlayer.softReset();
       while (1);
     }
     delay(1000);
     if (! musicPlayer.startPlayingFile(MP3)) {
       Serial.print("Could not open");
       Serial.println(MP3);
       while (1);
     }
     Serial.print("Start Playing ");
     Serial.println(MP3);
   }
 }
 // Jeśli nie ma ruchu prze 15 s zatrzymaj muzykę
 if ( (millis() – detectTime) >= 15000){
   Serial.println("No motion for 15 seconds");
   musicPlayer.stopPlaying();
   musicPlayer.softReset();
   delay(200);
   digitalWrite(ledPin,LOW);
   val = 0;  
   detectTime = 0;
 }
 
 // Monitorowanie ilości wolnej pamięci
 ...

 }
 delay(1000);
}

// Funkcja do listowania plików z karty SD
void printDirectory(File dir, int numTabs) {
 ...
 }
}

Kod programu

Na listingu 1 pokazano szkic programu Arduino, który obsługuje omawiane urządzenie. Zanim możliwe będzie skompilowanie i wgranie go do modułu Arduino, trzeba wprowadzić kilka zmian w kodzie. Pierwszym krokiem jest zmiana nazw utworów, aby odpowiadały plikom MP3, które znajdują się na karcie SD w module MP3. Istnieje pewne ograniczenie długości nazwy pliku, zdefiniowane w instrukcjach shielda MP3. W przykładzie wszystkie pliki mają nazwę w konwencji track0##.mp3, gdzie ## to kolejne numery. Jeśli zdecydujemy się jednak na zmianę tej konwencji, edytować musimy następującą definicję:

char* myFiles[]={"track001.mp3", "track002.mp3"..."track020.mp3"};

Ta tablica jest inicjowana raz, a następnie w pętli pobierane są z niej losowe nazwy plików. Konieczność posiadania predefiniowanej listy plików w tablicy wynika z faktu, że ciągłe wczytywanie listy plików z karty SD może powodować jej niestabilną pracę. Autor projektu zauważył, że na etapie testów, gdy w taki sposób rozwiązana była ta sekcja kodu, powodowało to zawieszanie się modułu po około 10 cyklach. Dodatkowo, pozwala to magazynować na karcie SD pliki, których w danej chwili nie chcemy odtwarzać.

Na tym etapie można skomplikować i wgrać szkic do układu, aby sprawdzić czy działa. Po uruchomieniu czujnik czeka 15 sekund na celem kalibracji. Następnie, gdy zostanie wykryty ruch, losowy plik jest wprowadzany do bufora szeregowego i odtwarzany przez około sekundę, po czym system sprawdza, czy nadal wykrywany jest ruch. Jeśli, przez co najmniej piętnaście pętli (15 s) ruch nie zostanie wykryty, muzyka przestaje grać i moduł MP3 jest resetowany. Dzięki resetowaniu kodeka, przy każdym nowym utworze, zacznie on działać od znanego stanu. Dokumentacja Adafruit nie specyfikuje w jednoznaczny sposób, czy to poprawne podejście, ale doświadczenia autora pokazują, że poprawnie działa.

Montaż wieńca

Ten krok nie jest zbyt trudny. Na fotografii 2 pokazano wieniec świąteczny ze zintegrowaną elektroniką.

Fotografia 2. Układ zainstalowany w wieńcu

Autor włożył Arduino do filcowej torby z wywieszonym na zewnątrz czujnikiem PIR (fotografia 3) i wejściem zasilania Arduino. Samą torbę z Arduino umieszczono pomiędzy świerkowymi gałązkami tak, aby nie była zbyt widoczna z zewnątrz. Do zamocowania kabli w nierzucający się w oczy sposób autor zastosował czyściki do fajek w kolorze zielonym. Pozwalają one też umieścić sensor PIR w odpowiedni miejscu. Dodatkowo, można go zamaskować np. jakąś ozdobną wstążką, która jest nieco luźniejszą siateczką i nie utrudnia wykrywania ruch z odległości około półtora metra od sensora.

Fotografia 3. Miejsce umieszczenia czujnika ruchu

Podsumowanie i dalszy rozwój systemu

Autor ma kilka innych pomysłów na ulepszenie tego systemu, na których uwzględnienie nie miał jeszcze czasu. Jest to kilka kwestii, które mogą ulepszyć, bądź rozbudować to ciekawe urządzenie.

Ulepszone zarządzanie energią – dostępny jest samouczek Arduino, który opisuje, jak wyłączyć większość elementów, odpowiedzialnych za zużycie energii w mikrokontrolerze, aby oszczędzać energię z baterii i wybudzić system tylko wtedy, gdy czujnik PIR wykryje ruch. Autor wskazuje, że chce to w pewnym momencie wprowadzić, aby urządzenie mogło być całkowicie zasilane bateryjnie.

Synchronizacja muzyki i światła – w module pozostawiono zapasowe światełka, które mają swój własny zegar, ale teoretycznie możliwe jest zsynchronizowanie ich z momentem włączenia muzyki i użycie czujnika światła, aby automatycznie włączały się po zmroku.

Nikodem Czechowski, EP

Źródło: https://bit.ly/3FQ38Xo

Artykuł ukazał się w
Elektronika Praktyczna
grudzień 2021
DO POBRANIA
Materiały dodatkowe

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik styczeń 2022

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio styczeń - luty 2022

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka Podzespoły Aplikacje grudzień 2021

Automatyka Podzespoły Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna styczeń 2022

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich styczeń 2022

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów