/* * Usurpation – wearable device main logic * * Copyright (C) 2019 Gediminas Jakutis * Copyright (C) 2019 Ramūnas Mažeikis * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2.1 * of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ #include #include #include #include #include #include "SSD1306Wire.h" #include "DejaVu_Sans_Mono_13.h" #include "udp.h" static const unsigned int internal_led = 2; static unsigned int led_state = 0; static const char servermagic[] = "I love coffee!"; static const char clientmagic[] = "I love tea!"; SSD1306Wire display(0x3c, 4, 5, GEOMETRY_128_32); static void init_OLED(void); unsigned int toggle_led(const int ip); static int wifi_connect(const char * const ssid, const char * const password, const char doblink, const int ledpin); static void blink_led(const int pin, const int ontime, const int offtime); void setup(void) { extern const char * const ssid; extern const char * const password; pinMode(internal_led, OUTPUT); toggle_led(internal_led); init_OLED(); display.fillCircle(32, 16, 12); display.display(); wifi_connect(ssid, password, 1, internal_led); Udp.begin(com_port); display.fillCircle(64, 16, 12); display.display(); discover_client(com_port); display.fillCircle(92, 16, 12); display.display(); } /* the logic is a placeholder right now */ void loop(void) { static const String devstr = "Device IP:"; static const String daemonstr = "Daemon IP:"; static String prefix; static IPAddress ip_to_print; static int print_dev_ip = 0; static unsigned int delta = 2000; /* sleep length to use (ms) */ /* static int dot_idx = 0; */ delay(delta); udp_init_packet(ip, com_port); udp_push(clientmagic, sizeof(clientmagic)); udp_flush(); #if 0 if (dot_idx >= 2) { display.clear(); dot_idx = 0; } display.fillCircle(32 * (dot_idx + 1), 16, 12); dot_idx++; #endif prefix = (print_dev_ip) ? devstr : daemonstr; ip_to_print = (print_dev_ip) ? WiFi.localIP() : ip; display.clear(); display.drawString(0, 0, prefix); display.drawString(0, 16, ip_to_print.toString()); display.display(); print_dev_ip = !print_dev_ip; } static void init_OLED(void) { display.init(); display.flipScreenVertically(); display.setTextAlignment(TEXT_ALIGN_LEFT); display.setFont((uint8_t *)DejaVu_Sans_Mono_13); } /* toggle the bult-in led and return current state */ unsigned int toggle_led(const int pin) { led_state = !led_state; /* as the cathode of the builtin diode is connected to the MCU's pin, * while the anode is connected to Vcc, to turn it off, we need to set * the pin to HIGH. */ digitalWrite(pin, led_state ? LOW : HIGH); return led_state; } static int wifi_connect(const char * const ssid, const char * const password, const char doblink, const int ledpin) { size_t i = 30; WiFi.forceSleepWake(); yield(); WiFi.persistent(0); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); do { if (doblink) { blink_led(ledpin, 250, 250); } else { delay (500); } } while (WiFi.status() != WL_CONNECTED); return 0; } static void discover_client(const int port) { IPAddress bcastip(255, 255, 255, 255); char buffer[32] = {0}; size_t done = 0; do { udp_init_packet(bcastip, port); udp_push(servermagic, sizeof(servermagic)); udp_flush(); delay(5); while (Udp.parsePacket()) { if (Udp.available() >= sizeof(clientmagic)) { Udp.read(buffer, sizeof(clientmagic)); if (!(strcmp(clientmagic, buffer))) { ip = Udp.remoteIP(); ++done; } } } delay(95); } while (!done); } static void blink_led(const int pin, const int ontime, const int offtime) { toggle_led(pin); delay(ontime); toggle_led(pin); delay(offtime); }