/* * An unnamed project – esp8266 module * * Copyright (C) 2017 Gediminas Jakutis * * This library 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 library; 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 "indicator.h" #include "temperature.h" static const unsigned int iled = 2; /* D4 */ static const unsigned int wifiled = 12; /* D6 */ static const unsigned int wifibutton = 13; /* D7 */ static const unsigned int analog = A0; static volatile unsigned int wifidesired = 0; static unsigned int wifistate = 0; static unsigned int wifiledstate = 0; static const int port = 2191; static const int splitter_res = 4699; static char udppacketbuffer[32] = {0}; static char *udppacketcursor = NULL; IPAddress ip; WiFiUDP Udp; static void sleep(void); static void udp_init_packet(IPAddress ip, const int port); static void udp_push(const void * const data, const size_t size); static int udp_flush(void); static int wifi_connect(const char * const ssid, const char * const password, const char doblink, const int ledpin); static void wifi_disconnect(void); static void blink_led(const int pin, const int ontime, const int offtime); static void discover_client(void); void toggle_wifi(void); void wifiled_toggle(void); void setup(void) { pinMode(iled, OUTPUT); digitalWrite(iled, HIGH); pinMode(wifiled, OUTPUT); pinMode(wifibutton, INPUT); indicator_init(0, NULL); WiFi.forceSleepBegin(); attachInterrupt(digitalPinToInterrupt(wifibutton), toggle_wifi, RISING); } void loop(void) { static const char * const ssid = "SSID"; static const char * const password = "password"; static unsigned int ticker = 0; short int data; size_t i; udp_init_packet(ip, port); if (wifidesired && !wifistate) { if (!wifi_connect(ssid, password, 1, iled)) { Udp.begin(port); discover_client(); } } if (!wifidesired && wifistate) { wifi_disconnect(); } if (wifistate) { data = 0; udp_push(&data, sizeof(data)); udp_push(&ticker, sizeof(ticker)); } data = analogRead(analog); data = get_temperature(get_resistance(data, splitter_res)); if (wifistate) { udp_push(&data, sizeof(data)); if (!(udp_flush())) { Udp.stop(); sleep(); } } indicator_update(data); delay(1000); ++ticker; } static void sleep(void) { do { blink_led(iled, 3000, 3000); } while (1); } static void udp_init_packet(IPAddress ip, const int port) { Udp.beginPacket(ip, port); memset(udppacketbuffer, 0, sizeof(udppacketbuffer)); udppacketcursor = udppacketbuffer; } static void udp_push(const void * const data, const size_t size) { memcpy(udppacketcursor, data, size); udppacketcursor += size; } static int udp_flush(void) { Udp.write((const uint8_t *) udppacketbuffer, udppacketcursor - udppacketbuffer); return Udp.endPacket(); } static int wifi_connect(const char * const ssid, const char * const password, const char doblink, const int ledpin) { wifiled_toggle(); WiFi.forceSleepWake(); WiFi.begin(ssid, password); do { if (doblink) { blink_led(ledpin, 250, 250); } else { delay (500); } /* in case the wifi off interrupt gets triggered while trying to connect */ if (!wifidesired) { wifi_disconnect(); return 1; } } while (WiFi.status() != WL_CONNECTED); wifistate = 1; return 0; } static void wifi_disconnect(void) { wifiled_toggle(); WiFi.disconnect(1); WiFi.forceSleepBegin(); wifistate = 0; } static void blink_led(const int pin, const int ontime, const int offtime) { digitalWrite(pin, LOW); delay(ontime); digitalWrite(pin, HIGH); delay(offtime); } static void discover_client(void) { IPAddress bcastip(255, 255, 255, 255); static const char servermagic[] = "I love coffee!"; static const char clientmagic[] = "I love tea!"; 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); } void toggle_wifi(void) { static const unsigned int timeout = 2000000; /* 2 seconds */ static volatile unsigned int lastswitch; volatile unsigned int switchtime; switchtime = micros(); /* if the value overflowed */ if (switchtime < lastswitch) { if ((UINT_MAX - lastswitch + timeout) > switchtime) { return; } /* if the value overflows if we add 2 seconds */ } else if ((lastswitch + timeout) < lastswitch) { if (lastswitch + timeout > switchtime || lastswitch < switchtime) { return; } } lastswitch = switchtime; wifidesired = !wifidesired; } void wifiled_toggle(void) { if (wifiledstate) { digitalWrite(wifiled, LOW); } else { digitalWrite(wifiled, HIGH); } wifiledstate = !wifiledstate; }