Created
November 1, 2018 10:26
-
-
Save janhajk/401e0dbb4364e177786daea3e0fd583d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ESP8266WiFi.h> | |
#include <Encoder.h> | |
#include <WiFiClient.h> | |
#include <ArduinoJson.h> // Achtung! Nur Version 5 installieren; V6 gibt Fehler | |
/* Verknüpfung von D? mit GPIO# */ | |
static const uint8_t D0 = 16; | |
static const uint8_t D1 = 5; | |
static const uint8_t D2 = 4; | |
static const uint8_t D3 = 0; | |
static const uint8_t D4 = 2; | |
static const uint8_t D5 = 14; | |
static const uint8_t D6 = 12; | |
static const uint8_t D7 = 13; | |
static const uint8_t D8 = 15; | |
static const uint8_t D9 = 3; | |
static const uint8_t D10 = 1; | |
// W-Lan Konfiguration | |
const char WIFI_SSID[] = "<Your WIFI ID>"; | |
const char WIFI_PSK[] = "<Your WIFI-Password"; | |
WiFiClient hue; | |
// Hue Configuration | |
// Die Adresse, zu welcher eine GET-Abfrage gemacht werden soll | |
const int HUE_PORT = 80; // 80 oder 443 für SSL | |
const char* HUE_IP = "192.168.1."; // IP der HUE Bridge | |
const char* HUE_USERNAME = ""; | |
const int HUE_LIGHT_ID = 6; | |
const int LED_PIN = LED_BUILTIN; | |
const char LIGHTS_ON[] = "{\"on\":true}"; | |
const char LIGHTS_OFF[] = "{\"on\":false}"; | |
const char EFFECT_COLORLOOP[] = "{\"effect\":\"colorloop\"}"; | |
const char EFFECT_NONE[] = "{\"effect\":\"none\"}"; | |
Encoder myEnc(D1, D2); | |
long oldPosition = -99999; | |
long lastPositionSet = 0; | |
int bri; | |
boolean isButtonPressed = false; | |
long lastUpdateMillis = 0; | |
void handleKey() { | |
isButtonPressed = true; | |
} | |
void setup() { | |
// Set up serial console to read web page | |
Serial.begin(115200); | |
Serial.print("Mit W-Lan verbinden..."); | |
// Mit dem WLAN verbinden | |
connectWiFi(WIFI_SSID, WIFI_PSK); | |
// LED Pin wird auf OUTPUT gesetzt, damit wir sie ein und ausschalten können | |
pinMode(LED_PIN, OUTPUT); | |
//hueGetBri(); | |
JsonObject& settings = hueGetState(); | |
bri = settings["state"]["bri"]; | |
Serial.println(bri); | |
pinMode(D3, INPUT_PULLUP); | |
// attachinterrupt() für externe Unterbrechungen, in unserem Fall drücken des Knopfes | |
// Referenz: https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/ | |
// Funktion: attachInterrupt(pin, ISR, mode); | |
// pin Pin, welcher interrupt-Signal erhält | |
// ISR Funktion, die bei Interrupt aufgerufen wird | |
// Mode nachfolgende Auswahl: | |
// LOW wenn der pin auf "low" ist | |
// CHANGE beim drücken und loslassen | |
// RISING wenn pin von "low" auf "high" geht | |
// FALLING wenn pin von "high" auf "low" geht | |
// HIGH wenn pin auf "high" ist | |
attachInterrupt(D3, handleKey, RISING); | |
} | |
void loop() { | |
// TODO: only update hue once every 500 ms | |
// | |
long newPosition = myEnc.read(); | |
if (newPosition != oldPosition) { | |
if (oldPosition == -99999) { | |
lastPositionSet = newPosition; | |
} | |
if (oldPosition != -99999) { | |
int diff = newPosition - lastPositionSet; | |
bri = bri + diff; | |
if (bri > 254) { | |
bri = 254; | |
} | |
else if (bri < 0) { | |
bri = 0; | |
} | |
Serial.print("Brigthness set: "); | |
Serial.println(bri); | |
// Nur alle 4 Stufen änderung an HUE-Bridge senden | |
if (abs(diff) >= 4) { | |
lastPositionSet = newPosition; | |
String command = "{\"bri\":"; | |
command += bri; | |
command += "}"; | |
int str_len = command.length() + 1; | |
char char_array[str_len]; | |
command.toCharArray(char_array, str_len); | |
Serial.print("Command: "); | |
Serial.println(char_array); | |
hueSetBri(char_array); | |
} | |
} | |
oldPosition = newPosition; | |
Serial.println(newPosition); | |
} | |
// software debounce | |
if (isButtonPressed && millis() - lastUpdateMillis > 50) { | |
isButtonPressed = false; | |
lastUpdateMillis = millis(); | |
// Reset the counter | |
Serial.println("Button pressed"); | |
myEnc.write(0); | |
} | |
} | |
// Eine HTTP GET Abfrage ausführen | |
JsonObject& hueGetState() { | |
hue.connect(HUE_IP, HUE_PORT); | |
String cmd = "GET /api/"; | |
cmd += HUE_USERNAME; | |
cmd += "/lights/"; | |
cmd += HUE_LIGHT_ID; | |
cmd += " HTTP/1.1"; | |
char ac[cmd.length() + 1]; | |
cmd.toCharArray(ac, cmd.length() + 1); | |
hue.println(ac); | |
hue.print("Host: "); | |
hue.println(HUE_IP); | |
hue.println("Connection: close"); | |
String line = ""; | |
int statusCode = readResponse(&line); | |
hue.stop(); | |
StaticJsonBuffer<600> jsonBuffer; // <600> Grösse des Buffers | |
JsonObject& root = jsonBuffer.parseObject(line); | |
return root; | |
} | |
// Eine HTTP GET Abfrage ausführen | |
bool hueGetBri() { | |
if ( !hue.connect(HUE_IP, HUE_PORT) ) { | |
return false; | |
} | |
String cmd = "GET /api/"; | |
cmd += HUE_USERNAME; | |
cmd += "/lights/"; | |
cmd += HUE_LIGHT_ID; | |
cmd += " HTTP/1.1"; | |
char ac[cmd.length() + 1]; | |
cmd.toCharArray(ac, cmd.length() + 1); | |
hue.println(ac); | |
hue.print("Host: "); | |
hue.println(HUE_IP); | |
hue.println("Connection: close"); | |
String line = ""; | |
int statusCode = readResponse(&line); | |
StaticJsonBuffer<600> jsonBuffer; // <600> Grösse des Buffers | |
Serial.print("Helligkeit: "); | |
JsonObject& root = jsonBuffer.parseObject(line); | |
bri = root["state"]["bri"]; | |
Serial.println(bri); | |
hue.stop(); | |
return true; | |
} | |
// HUE-Helligkeit setzen | |
bool hueSetBri(char* brightness) { | |
if ( !hue.connect(HUE_IP, HUE_PORT) ) { | |
return false; | |
} | |
String cmd = "PUT /api/"; | |
cmd += HUE_USERNAME; | |
cmd += "/lights/"; | |
cmd += HUE_LIGHT_ID; | |
cmd += "/state HTTP/1.1"; | |
char ac[cmd.length() + 1]; | |
cmd.toCharArray(ac, cmd.length() + 1); | |
Serial.println(ac); | |
hue.println(ac); | |
hue.print("Host: "); | |
hue.println(HUE_IP); | |
hue.println("Connection: close"); | |
char contentLength[30]; | |
sprintf(contentLength, "Content-Length: %d", strlen(brightness)); | |
hue.println(contentLength); | |
hue.println("Content-Type: application/json"); | |
hue.println(""); | |
hue.println(brightness); | |
hue.println(""); | |
//String line = ""; | |
//int statusCode = readResponse(&line); | |
//Serial.println(line); | |
hue.stop(); | |
return true; | |
} | |
// Mit WLAN verbinden | |
int connectWiFi(const char* ssid, const char* psk) { | |
byte led_status = 0; // LED ausschalten | |
// WLAN Modus auf Client-Modus setzten | |
WiFi.mode(WIFI_STA); | |
// mit statischer IP geht das Verbinden 4x schneller | |
WiFi.config(IPAddress(192, 168, 1, 75), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0), IPAddress(192, 168, 1, 1)); | |
// Verbindung mit WLAN initieren mittels SSID und WLAN-Passwort | |
WiFi.begin(ssid, psk); | |
// Versuchen mit dem WLAN zu verbinden | |
// Während dem Verbindungsversuch die LED Blinken lassen | |
while ( WiFi.status() != WL_CONNECTED ) { | |
digitalWrite(LED_PIN, led_status); | |
led_status ^= 0x01; // XOR Operation zum umschalten zwischen 0 und 1 | |
delay(100); // Wart-Intervall in Millisekunden | |
Serial.print("."); | |
} | |
// Wenn die Verbindung erfolgreich ist, dann LED einschalten | |
digitalWrite(LED_PIN, LOW); | |
return WiFi.status(); | |
} | |
int readResponse(String* response) { | |
boolean currentLineIsBlank = true; | |
boolean httpBody = false; | |
boolean inStatus = false; | |
char statusCode[4]; | |
int i = 0; | |
int code = 0; | |
while (hue.connected()) { | |
if (hue.available()) { | |
char c = hue.read(); | |
if (c == ' ' && !inStatus) { | |
inStatus = true; | |
} | |
if (inStatus && i < 3 && c != ' ') { | |
statusCode[i] = c; | |
i++; | |
} | |
if (i == 3) { | |
statusCode[i] = '\0'; | |
code = atoi(statusCode); | |
} | |
if (httpBody) { | |
//only write response if its not null | |
if (response != NULL) response->concat(c); | |
} | |
else { | |
if (c == '\n' && currentLineIsBlank) { | |
httpBody = true; | |
} | |
if (c == '\n') { | |
// you're starting a new line | |
currentLineIsBlank = true; | |
} | |
else if (c != '\r') { | |
// you've gotten a character on the current line | |
currentLineIsBlank = false; | |
} | |
} | |
} | |
} | |
return code; | |
} | |
/* | |
"6": { | |
"state": { | |
"on": false, | |
"bri": 254, | |
"hue": 8378, | |
"sat": 144, | |
"effect": "none", | |
}, | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment