Týden 7 - Výstupní zařízení
O projektu
Cílem tohoto týdne bylo vytvořit obvod s výstupními zařízeními se kterým jsme ještě nepracovali. Zvolil jsem jednoduchý obvod s OLED displejem a bzučákem. Můj výrobek má jediný cíl - Rickrollnout co nejvíce lidí 😈.
Zapojení
Nejdříve bylo třeba navrhnout zapojení. Na internetu jsem si našel, jak správně zapojit 128x64 Oled displej přes I2C sběrnici (OLED v kitu má adresu 0x3C). Bzučák jsem zapojil na digitální pin a rezistor, stejně jako tlačítko.
Testovací obvod na breadboardu
Krabička na elektroniku
Jakmile jsem měl sestrojený obvod a věděl jsem, které komponenty použiju, bylo třeba navrhnout krabičku. Vytvořil jsem si jednoduchý design ve Fusion 360. Krabička má jednoduché víko, které se zaaretuje pomocí zip pásky. Na samotné krabičce jsou pak otvory pro uchycení displeje, kabelů a bzučáku.
Krabičku jsem následně vytiskl na 3D tiskárně. Použil jsem experimentální nastavení fuzzy skin, které vytváří na povrchu objektu jemné vrypy. Krabička je velimi tenká a lehká, jelikož jsem nechtěl takovou blbinou zatěžovat přírodu.
Program
Program jsem napsal v Arduino IDE. Použil jsem knihovnu Adafruit_GFX a Adafruit_SSD1306. Inspiroval jsem se již hotovým příkladem naprogramované melodie, kterou jsem zkopíroval a implementoval do svého kódu. Po stisknutí tlačítka se spustí melodie a na displeji se postupně zobrazují lyrics.
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);
#define BUZZER_PIN 7
int led = LED_BUILTIN;
#define BUTTON_PIN 6
// Noty a melodie - lehka modifikace kodu: https://projecthub.arduino.cc/rowan07/rickroll-piezo-buzzer-b3d9fd.
#define a4f 415 // 415 Hz
#define b4f 466 // 466 Hz
#define b4 493 // 493 Hz
#define c5 523 // 523 Hz
#define c5s 554 // 554 Hz
#define e5f 622 // 622 Hz
#define f5 698 // 698 Hz
#define a5f 831 // 831 Hz
#define rest -1
volatile int beatlength = 100;
float beatseparationconstant = 0.3;
//Indexy
int b;
int c;
bool playing = false; //Flag
int song1_chorus_melody[] = {
b4f, b4f, a4f, a4f,
f5, f5, e5f, b4f, b4f, a4f, a4f, e5f, e5f, c5s, c5, b4f,
c5s, c5s, c5s, c5s,
c5s, e5f, c5, b4f, a4f, a4f, a4f, e5f, c5s,
b4f, b4f, a4f, a4f,
f5, f5, e5f, b4f, b4f, a4f, a4f, a5f, c5, c5s, c5, b4f,
c5s, c5s, c5s, c5s,
c5s, e5f, c5, b4f, a4f, rest, a4f, e5f, c5s, rest
};
int song1_chorus_rhythmn[] = {
1, 1, 1, 1,
3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2,
1, 1, 1, 1,
3, 3, 3, 1, 2, 2, 2, 4, 8,
1, 1, 1, 1,
3, 3, 6, 1, 1, 1, 1, 3, 3, 3, 1, 2,
1, 1, 1, 1,
3, 3, 3, 1, 2, 2, 2, 4, 8, 4
};
const char* lyrics_chorus[] = {
"Never ", "", "gonna ", "", "give ", "you ", "up",
"Never ", "", "gonna ", "", "let ", "you ", "down", "", "",
"Never ", "", "gonna ", "", "run ", "around ", "", "", "", "and ", "desert ", "", "you",
"Never ", "", "gonna ", "", "make ", "you ", "cry",
"Never ", "", "gonna ", "", "say ", "goodbye ", "", "", "",
"Never ", "", "gonna ", "", "tell ", "a ", "lie ", "", "", "and ", "hurt ", "you"
};
void setup() {
pinMode(BUZZER_PIN, OUTPUT);
pinMode(led, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
digitalWrite(led, LOW);
Serial.begin(9600); // Badu Rate
// OLED displej
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.display(); // Zapnutí - logo adafruit
delay(1000);
display.clearDisplay();
// Press Button
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Press");
display.setCursor(0, 15);
display.print("Button");
display.display();
b = 0;
c = 0;
}
void loop() {
// Wait for button press to start playback
if (!playing && digitalRead(BUTTON_PIN) == LOW) {
delay(10); // Debounce delay
if (digitalRead(BUTTON_PIN) == LOW) { // Confirm button press
playing = true;
display.clearDisplay();
display.setCursor(20, 20);
display.display();
}
}
// Play only if the button was pressed
if (playing) {
play();
}
}
void play() {
int notelength = beatlength * song1_chorus_rhythmn[b];
if (song1_chorus_melody[b] > 0) {
digitalWrite(led, HIGH); // blikani ondboard led
if (strlen(lyrics_chorus[c]) > 0) { // pokud se nemeni slovo na tonech - necha starsi
display.clearDisplay();
display.setTextSize(3);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print(lyrics_chorus[c]);
display.display();
}
tone(BUZZER_PIN, song1_chorus_melody[b], notelength);
c++;
}
b++;
if (b >= sizeof(song1_chorus_melody) / sizeof(int)) {
b = 0;
c = 0;
playing = false; // Ukonci hrani
display.clearDisplay();
// Press Button znovu
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.print("Press");
display.setCursor(0, 15);
display.print("Button");
display.display();
return;
}
delay(notelength);
noTone(BUZZER_PIN);
digitalWrite(led, LOW);
delay(notelength * beatseparationconstant);
}
Celkový výrobek
Výrobek jsem nakonec zkompletoval a otestoval. Vše funguje jak má.