Skip to content

Instantly share code, notes, and snippets.

@NeoCat
Last active December 15, 2023 15:11
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save NeoCat/a57f73b8db0605e1763d3ca1a1f75941 to your computer and use it in GitHub Desktop.
Save NeoCat/a57f73b8db0605e1763d3ca1a1f75941 to your computer and use it in GitHub Desktop.
ESP8266 + AMG8833 WebSocket-based Viewer
// ESP8266 Pins
// 4(SDA) --- AMG8833 SDA
// 5(SCL) --- AMG8833 SCL
// 13 --- LED (Anode) via 100ohm
#include <pgmspace.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <WebSocketsServer.h>
#include <ESP8266mDNS.h>
#include <ArduinoOTA.h>
#include <Wire.h>
#include <Adafruit_AMG88xx.h>
Adafruit_AMG88xx amg;
const char* ssid = "<SSID>";
const char* password = "<PASSWORD>";
const int pin_led = 13;
ESP8266WebServer server(80);
WebSocketsServer webSocket(81);
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
switch (type) {
case WStype_DISCONNECTED:
Serial.printf("[%u] Disconnected!\n", num);
break;
case WStype_CONNECTED:
IPAddress ip = webSocket.remoteIP(num);
Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
break;
}
}
void toggle() {
static bool last_led = false;
last_led = !last_led;
digitalWrite(pin_led, last_led);
}
void handleRoot() {
auto ip = WiFi.localIP();
String ip_str = String(ip[0]) + "." + ip[1] + "." + ip[2] + "." + ip[3];
server.send(200, "text/html", String(ws_html_1()) + ip_str + ws_html_2());
}
void handleNotFound() {
String message = "File Not Found\n\n";
message += "URI: ";
message += server.uri();
message += "\nMethod: ";
message += (server.method() == HTTP_GET)?"GET":"POST";
message += "\nArguments: ";
message += server.args();
message += "\n";
for (uint8_t i = 0; i<server.args(); i++){
message += " " + server.argName(i) + ": " + server.arg(i) + "\n";
}
server.send(404, "text/plain", message);
}
void WiFiEvent(WiFiEvent_t event) {
switch(event) {
case WIFI_EVENT_STAMODE_DISCONNECTED:
digitalWrite(pin_led, LOW);
Serial.println("WiFi lost connection: reconnecting...");
WiFi.begin();
break;
case WIFI_EVENT_STAMODE_CONNECTED:
Serial.print("Connected to ");
Serial.println(ssid);
break;
case WIFI_EVENT_STAMODE_GOT_IP:
digitalWrite(pin_led, HIGH);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("esp8266-amg8833")) {
Serial.println("MDNS responder started");
}
enableOTA();
break;
}
}
void enableOTA() {
// Port defaults to 8266
// ArduinoOTA.setPort(8266);
// Hostname defaults to esp8266-[ChipID]
// ArduinoOTA.setHostname("myesp8266");
// No authentication by default
// ArduinoOTA.setPassword((const char *)"123");
ArduinoOTA.onStart([]() {
Serial.println("Start");
});
ArduinoOTA.onEnd([]() {
Serial.println("\nEnd");
});
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
Serial.printf("Progress: %u%%\r", (progress / (total / 100)));
});
ArduinoOTA.onError([](ota_error_t error) {
Serial.printf("Error[%u]: ", error);
if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed");
else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed");
else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed");
else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed");
else if (error == OTA_END_ERROR) Serial.println("End Failed");
});
ArduinoOTA.begin();
}
void setup(void) {
pinMode(pin_led, OUTPUT);
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.onEvent(WiFiEvent);
WiFi.begin(ssid, password);
Serial.println("");
server.on("/", handleRoot);
server.on("/current", [](){
String str;
server.send(200, "text/plain", get_current_values_str(str));
});
server.onNotFound(handleNotFound);
server.begin();
webSocket.begin();
webSocket.onEvent(webSocketEvent);
Serial.println("HTTP server started");
amg.begin(0x68);
delay(100); // let sensor boot up
}
void loop(void) {
ArduinoOTA.handle();
server.handleClient();
webSocket.loop();
// Wait for connection
if (WiFi.status() != WL_CONNECTED) {
static unsigned long last_ms;
unsigned long t = millis();
if (t - last_ms > 500) {
Serial.print(".");
toggle();
last_ms = t;
}
} else {
digitalWrite(pin_led, millis() % 3000 < 200);
}
static unsigned long last_read_ms = millis();
unsigned long now = millis();
if (now - last_read_ms > 100) {
last_read_ms += 100;
String str;
get_current_values_str(str);
Serial.println(str);
webSocket.broadcastTXT(str);
}
}
String& get_current_values_str(String& ret)
{
float pixels[AMG88xx_PIXEL_ARRAY_SIZE];
amg.readPixels(pixels);
ret = "[";
for(int i = 0; i < AMG88xx_PIXEL_ARRAY_SIZE; i++) {
if( i % 8 == 0 ) ret += "\r\n";
ret += pixels[i];
if (i != AMG88xx_PIXEL_ARRAY_SIZE - 1) ret += ", ";
}
ret += "\r\n]\r\n";
return ret;
}
const __FlashStringHelper* ws_html_1() {
return F("<!DOCTYPE html>\n"
"<html>\n"
"<head>\n"
"<title>thermo</title>\n"
"<style>\n"
"body {\n"
" background-color: #667;\n"
"}\n"
"table#tbl td {\n"
" width: 64px;\n"
" height: 64px;\n"
" border: solid 1px grey;\n"
" text-align: center;\n"
"}\n"
"</style>\n"
"</head>\n"
"<body>\n"
"<table border id=\"tbl\"></table>\n"
"<script>\n"
"function bgcolor(t) {\n"
" if (t < 0) t = 0;\n"
" if (t > 30) t = 30;\n"
" return \"hsl(\" + (360 - t * 12) + \", 100%, 80%)\";\n"
"}\n"
"\n"
"var t = document.getElementById('tbl');\n"
"var tds = [];\n"
"for (var i = 0; i < 8; i++) {\n"
" var tr = document.createElement('tr');\n"
" for (var j = 0; j < 8; j++) {\n"
" var td = tds[i*8 + 7 - j] = document.createElement('td');\n"
" tr.appendChild(td);\n"
" }\n"
" t.appendChild(tr);\n"
"}\n"
"var connection = new WebSocket('ws://");
}
const __FlashStringHelper* ws_html_2() {
return F(":81/');\n"
"connection.onmessage = function(e) {\n"
" const data = JSON.parse(e.data);\n"
" for (var i = 0; i < 64; i++) {\n"
" tds[i].innerHTML = data[i].toFixed(2);\n"
" tds[i].style.backgroundColor = bgcolor(data[i]);\n"
" }\n"
"};\n"
"</script>\n"
"</body>\n"
"</html>\n");
}
@tmsd2001
Copy link

Hello,
I use your code and do some change. My question is how can I publish the code. Can I publish this in my git or how do you do this. I am not yet familiar with git and can not see license information.
regards

@leobard
Copy link

leobard commented Oct 17, 2020

I can confirm this script works. I just uploaded it to an ESP8266 / NodeMCU Wemos D1 Mini.

Only change I had to do was changing the I2C address of the camera:
amg.begin(0x68); --> amg.begin(0x69);

I had to learn about the dependencies, so for the interested reader:
// depends on https://github.com/Links2004/arduinoWebSockets , "WebSockets" by Markus Sattler (installed via Sketch > Include Libary)
// depends on https://github.com/adafruit/Adafruit_AMG88xx, "AdaFruit AMG88xx Library" (installed via Sketch > Include Libary)

@NeoCat - thank you! awesome work. Neat. Elegant. WebSockets. Minimal. Beautiful.

@stress1ner
Copy link

I can confirm this script works. I just uploaded it to an ESP8266 / NodeMCU Wemos D1 Mini.

Only change I had to do was changing the I2C address of the camera:
amg.begin(0x68); --> amg.begin(0x69);

I had to learn about the dependencies, so for the interested reader:
// depends on https://github.com/Links2004/arduinoWebSockets , "WebSockets" by Markus Sattler (installed via Sketch > Include Libary)
// depends on https://github.com/adafruit/Adafruit_AMG88xx, "AdaFruit AMG88xx Library" (installed via Sketch > Include Libary)

@NeoCat - thank you! awesome work. Neat. Elegant. WebSockets. Minimal. Beautiful.

Hi how did u get the values into home assistant?

@Radio-active69
Copy link

does someone had a video tutorial for this? I cant somehow get the IP for websocket. its not showing on my serial monitor. I might miss somethng please enlighten me.

@nzwildcode
Copy link

Following is what I have done.

  1. Found the i2c address of the sensor using a i2c scanner sketch...then changed the i2c address
    amg.begin(0x69);
  2. Increased the delay!
    delay(6000); // let sensor boot up

Check for something like this in the serial monitor immediately after booting the esp8266 board.

HTTP server started
Connected to yourssid
IP address: 192.168.1.100
MDNS responder started

This is what I see!
image
Hope that might help!

Can any one suggest how to convert that values to something meaningful....say a thermal image?

@LunaVulpine8309
Copy link

Hello, I use your code and do some change. My question is how can I publish the code. Can I publish this in my git or how do you do this. I am not yet familiar with git and can not see license information. regards

hi, how can i do the wiring for this esp8266 and amg8833? thank you.

@LunaVulpine8309
Copy link

Following is what I have done.

  1. Found the i2c address of the sensor using a i2c scanner sketch...then changed the i2c address
    amg.begin(0x69);
  2. Increased the delay!
    delay(6000); // let sensor boot up

Check for something like this in the serial monitor immediately after booting the esp8266 board.

HTTP server started Connected to yourssid IP address: 192.168.1.100 MDNS responder started

This is what I see! image Hope that might help!

Can any one suggest how to convert that values to something meaningful....say a thermal image?

hello, how can i do the wiring? thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment