#include "main.hpp" #include "secrets.hpp" #include "song.h" #define WIRE Wire #define SERVO_PIN 14 // D5 #define POTENTIOMETER_PIN A0 // A0 #define BUZZER_PIN 12 // D6 // buttons #define TACTILE_BTN_LEFT 0 // D3 #define TACTILE_BTN_RIGHT 2 // D4 #define TOUCH_BTN_PIN 16 // D0 // RFID #define PN532_IRQ 13 // D7 #define PN532_RESET 12 // D6 (not connected) Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET); // RFID with I2C // OLED display #define DISPLAY_PIN 4 // D2 (SDA) auto display = Adafruit_SSD1306(128, 32, &WIRE); // util classes ContinuousServo contServo(SERVO_PIN); TeaTimer teaTimer(&contServo); SmartRFID smartRFID(&nfc); SmartDial smartDial(POTENTIOMETER_PIN); SmartDisplay smartDisplay(&display); TeaNetworking teaNet; // networking String shuttleServer = "https://ias-tea-axum.shuttleapp.rs"; TeaData currentTea("Teafault", "c0derfid", 100, 30); enum State { WAIT_FOR_RFID_SCAN, DISPLAY_SCANNED_TEA_CONFIG, ADD_NEW_TEA_CONFIG, STEEPING_IN_PROGRESS, NETWORKING_DEBUG, }; State state = State::WAIT_FOR_RFID_SCAN; void setup() { Serial.begin(9600); teaNet.init(ssid, password); smartRFID.init(); Serial.println("Initializing OLED..."); display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false); // Address 0x3C for 128x32 printMsg("Tea is Great!"); delay(1000); pinMode(LED_BUILTIN, OUTPUT); pinMode(TOUCH_BTN_PIN, INPUT); pinMode(TACTILE_BTN_LEFT, INPUT); pinMode(TACTILE_BTN_RIGHT, INPUT); } int steepingSeconds = 60; void loop() { contServo.tick(); switch (state) { case NETWORKING_DEBUG: { if (!teaNet.wifiConnected()) { state = WAIT_FOR_RFID_SCAN; break; } JSONVar jsonData = teaNet.httpsGETRequest(shuttleServer + "/alltea"); Serial.println("JSON:"); Serial.println(jsonData[2]["teaname"]); delay(2000); String payload = teaNet.createTeaData("Unnamed Tea", "g8OhgB5", 90, 180); teaNet.httpsPOSTRequest("https://ias-tea-axum.shuttleapp.rs/addtea", payload); state = WAIT_FOR_RFID_SCAN; break; } case WAIT_FOR_RFID_SCAN: { smartDisplay.printWaitForRFIDScreen(); playSong(); // this blocks execution until a tag has been detected String uid = smartRFID.readTag(); display.println(uid); display.display(); delay(1000); display.println("Success!"); display.display(); delay(500); JSONVar result = teaNet.httpsGETRequest(shuttleServer + "/teabyrfid/" + uid); Serial.print("Result:"); Serial.println(result); if (JSONVar::stringify(result) == "null") { Serial.print("TEA DOES NOT EXIST YET!"); String payload = teaNet.createTeaData("Unnamed Tea", uid, 90, 180); teaNet.httpsPOSTRequest("https://ias-tea-axum.shuttleapp.rs/addtea", payload); result = teaNet.httpsGETRequest(shuttleServer + "/teabyrfid/" + uid); } currentTea = TeaData(result["teaname"], result["rfidcode"], result["watertemp"], result["steepingSeconds"]); state = State::DISPLAY_SCANNED_TEA_CONFIG; break; } case DISPLAY_SCANNED_TEA_CONFIG: { int dir = smartDial.smoothEdit(¤tTea.m_steepingSeconds, 0, 6000); if (digitalRead(TACTILE_BTN_LEFT) == LOW) { printMsg("BUTTON GREEN"); } else if (digitalRead(TACTILE_BTN_RIGHT) == LOW) { printMsg("BUTTON RED"); } else { smartDisplay.printTeaConfigScreen(currentTea.m_teaName, currentTea.m_steepingSeconds, dir); } // change state if start pressed if (isBtnPressed()) { teaTimer.beginSteeping(10000); state = State::STEEPING_IN_PROGRESS; } break; } case ADD_NEW_TEA_CONFIG: { break; } case STEEPING_IN_PROGRESS: { teaTimer.tick(); if (teaTimer.isSteeping()) { auto r = teaTimer.remainingSteepTimeSeconds(); smartDisplay.printTeaSteepingProgressScreen(currentTea.m_teaName, r); } else { printMsg("DONE"); if (!contServo.isTurning()) { delay(2000); state = State::WAIT_FOR_RFID_SCAN; } } break; } }; } void playSong() { int size = sizeof(durations) / sizeof(int); for (int note = 0; note < size; note++) { // to calculate the note duration, take one second divided by the note type. // e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. int duration = 1000 / durations[note]; tone(BUZZER_PIN, melody[note], duration); // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: int pauseBetweenNotes = duration * 1.30; delay(pauseBetweenNotes); // stop the tone playing: noTone(BUZZER_PIN); } } void toggle_led() { digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); } bool isBtnPressed() { return digitalRead(TOUCH_BTN_PIN) == HIGH; } void printMsg(const String &s) { display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(0, 10); display.println(s); display.display(); } void printMsg(unsigned long l) { display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(0, 10); display.println(l); display.display(); }