Created
July 22, 2020 18:28
-
-
Save dov/2a6dbb3fdb98b3245b121426f0dbb1e0 to your computer and use it in GitHub Desktop.
A web server for sending raw IR codes
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
// This is as a web server library used for sending raw IR codes | |
// to an IR-Led. | |
// | |
// The raw string decoding code was borrowed from: | |
// | |
// https://github.com/crankyoldgit/IRremoteESP8266 | |
// | |
// | |
// License: GLPL v2.1 | |
// | |
// Setup: fill in the ssid and password below | |
// Connect the io pin 4 (D2) to the following circuit. | |
// | |
// | |
// 5V | |
// ^ | |
// | | |
// IR-LED | |
// | | |
// / | |
// /--\/ | |
// | /| | |
// | / | General purpose NPN transistor | |
// D2 -----< | | |
// | \ | | |
// | \ | |
// \--/\ | |
// | | |
// | | |
// --- GND | |
// | |
// | |
// Dov Grobgeld | |
// 2020-07-22 Wed | |
// Load Wi-Fi library | |
#include <ESP8266WiFi.h> | |
#include <IRremoteESP8266.h> | |
#include <IRsend.h> | |
#include "ir_Coolix.h" | |
// Replace with your network credentials | |
const char* ssid = "myssid"; | |
const char* password = "mypw"; | |
// Set web server port number to 80 | |
WiFiServer server(80); | |
// Variable to store the HTTP request | |
String header; | |
// Assign output variables to GPIO pins | |
const int output5 = 5; // for debugging only | |
const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use for IR | |
void setup() | |
{ | |
Serial.begin(115200); | |
// Initialize the output variables as outputs | |
pinMode(output5, OUTPUT); | |
pinMode(kIrLed, OUTPUT); | |
// Set outputs to LOW | |
digitalWrite(output5, LOW); | |
digitalWrite(kIrLed, LOW); | |
// Connect to Wi-Fi network with SSID and password | |
Serial.print("Connecting to "); | |
Serial.println(ssid); | |
WiFi.begin(ssid, password); | |
while (WiFi.status() != WL_CONNECTED) | |
{ | |
delay(500); | |
Serial.print("."); | |
} | |
// Print local IP address and start web server | |
Serial.println(""); | |
Serial.println("WiFi connected."); | |
Serial.println("IP address: "); | |
Serial.println(WiFi.localIP()); | |
server.begin(); | |
} | |
uint16_t countValuesInStr(const String str, char sep) | |
{ | |
int16_t index = -1; | |
uint16_t count = 1; | |
do { | |
index = str.indexOf(sep, index + 1); | |
count++; | |
} while (index != -1); | |
return count; | |
} | |
// Dynamically allocate an array of uint16_t's. | |
// Args: | |
// size: Nr. of uint16_t's need to be in the new array. | |
// Returns: | |
// A Ptr to the new array. Restarts the ESP8266 if it fails. | |
uint16_t * newCodeArray(const uint16_t size) | |
{ | |
uint16_t *result; | |
result = reinterpret_cast<uint16_t*>(malloc(size * sizeof(uint16_t))); | |
// Check we malloc'ed successfully. | |
if (result == NULL) { // malloc failed, so give up. | |
Serial.printf("\nCan't allocate %d bytes. (%d bytes free)\n", | |
size * sizeof(uint16_t), ESP.getFreeHeap()); | |
Serial.println("Giving up & forcing a reboot."); | |
ESP.restart(); // Reboot. | |
delay(500); // Wait for the restart to happen. | |
return result; // Should never get here, but just in case. | |
} | |
return result; | |
} | |
// Parse a raw IR code received from the web client | |
bool parseStringAndSendRaw(const String str) | |
{ | |
uint16_t count; | |
uint16_t freq = 38000; // Default to 38kHz. | |
uint16_t *raw_array; | |
// Find out how many items there are in the string. | |
count = countValuesInStr(str, ','); | |
// We expect the frequency as the first comma separated value, so we need at | |
// least two values. If not, bail out. | |
if (count < 2) | |
return false; | |
count--; // We don't count the frequency value as part of the raw array. | |
// Now we know how many there are, allocate the memory to store them all. | |
raw_array = newCodeArray(count); | |
// Grab the first value from the string, as it is the frequency. | |
int16_t index = str.indexOf(',', 0); | |
freq = str.substring(0, index).toInt(); | |
uint16_t start_from = index + 1; | |
// Rest of the string are values for the raw array. | |
// Now convert the strings to integers and place them in raw_array. | |
count = 0; | |
do { | |
index = str.indexOf(',', start_from); | |
raw_array[count] = str.substring(start_from, index).toInt(); | |
start_from = index + 1; | |
count++; | |
} while (index != -1); | |
IRsend irsend(kIrLed); | |
irsend.sendRaw(raw_array, count, freq); // All done. Send it. | |
free(raw_array); // Free up the memory allocated. | |
if (count > 0) | |
return true; // We sent something. | |
return false; // We probably didn't. | |
} | |
void loop(){ | |
WiFiClient client = server.available(); // Listen for incoming clients | |
if (client) { // If a new client connects, | |
Serial.println("New Client."); // print a message out in the serial port | |
String currentLine = ""; // make a String to hold incoming data from the client | |
while (client.connected()) { // loop while the client's connected | |
if (client.available()) { // if there's bytes to read from the client, | |
char c = client.read(); // read a byte, then | |
Serial.write(c); // print it out the serial monitor | |
header += c; | |
// values we parse | |
int pin=-1; | |
int output=-1; | |
String code=""; | |
if (c == '\n') { // if the byte is a newline character | |
// if the current line is blank, you got two newline characters in a row. | |
// that's the end of the client HTTP request, so send a response: | |
if (currentLine.length() == 0) { | |
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) | |
// and a content-type so the client knows what's coming, then a blank line: | |
client.println("HTTP/1.1 200 OK"); | |
client.println("Content-type:text/html"); | |
client.println("Connection: close"); | |
client.println(); | |
// Parse the query | |
int p = header.indexOf("?"); | |
while (p>=0) | |
{ | |
int peq=header.indexOf("=",p); | |
int np=header.indexOf("&",p+1); | |
int nsp=header.indexOf(" ",p+1); | |
// Check if this is a valid query string if so parse it | |
if (peq>0 && (np>0||nsp>0)) | |
{ | |
String key = header.substring(p+1,peq); | |
int val_end = np; | |
if (val_end < 0) | |
val_end = nsp; | |
if (val_end < 0) | |
// This shouldn't happen in a valid string | |
break; | |
String value = header.substring(peq+1,val_end); | |
// Here we parse | |
if (key=="pin") | |
pin = value.toInt(); | |
else if (key=="output") | |
output = value.toInt(); | |
else if (key=="code") | |
code=value; | |
Serial.println("kv: " + key + "->" + value); | |
} | |
p = np; // Progress to the next keyword entry | |
} | |
String message; | |
// Support the pin command for turning on pin 5. This | |
// is only for debugging. | |
if (pin == 5) | |
{ | |
int onoff = int(output>0); | |
message += "Setting pin " + String(pin) + " to " + String(output); | |
pinMode(pin, OUTPUT); | |
digitalWrite(pin, output); | |
} | |
// Send a raw IR code | |
else if (code.length()) | |
{ | |
parseStringAndSendRaw(code); | |
message += "Sending raw code!"; | |
} | |
else | |
message += "No request received!"; | |
Serial.println(message); | |
client.print("<!DOCTYPE html><html>" | |
"<head>" | |
"<title>ESP8266 Web Server</title>\n" | |
"<meta charset=\"UTF-8\">" | |
"</head>" | |
"<body>" | |
"<h1>Web IR Server</h1>" | |
"This is a ESP8266 IR server. You control me by\n" | |
"sending raw IR codes through the command\n" | |
"<pre>\n" | |
" wget http://"); | |
client.print(WiFi.localIP()); | |
client.print("/?code=«raw code»" | |
"</pre>\n"); | |
if (message.length()) | |
{ | |
client.print("<hr>message=" + message); | |
client.print("<br/>"); | |
} | |
client.print("</body>" | |
"</html>"); | |
break; | |
} else { // if you got a newline, then clear currentLine | |
currentLine = ""; | |
} | |
} else if (c != '\r') { // if you got anything else but a carriage return character, | |
currentLine += c; // add it to the end of the currentLine | |
} | |
} | |
} | |
// Clear the header variable | |
header = ""; | |
// Close the connection | |
client.stop(); | |
Serial.println("Client disconnected."); | |
Serial.println(""); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment