Skip to content

Instantly share code, notes, and snippets.

@buzztiaan
Created November 5, 2019 18:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save buzztiaan/0c23bd2a1014a7669c1331546fb13a40 to your computer and use it in GitHub Desktop.
Save buzztiaan/0c23bd2a1014a7669c1331546fb13a40 to your computer and use it in GitHub Desktop.
esp8266 pixelflut server with a SSD1306 oled 128x64 screen
// esp8266 pixelflut server with a SSD1306 oled 128x64 screen
// only ascii PX x y RRGGBB\n supported for now, no SIZE or RRGGBBAA or binary protocol
#include <Wire.h>
#include "SSD1306Wire.h"
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
#define MAXBUF 4096
SSD1306Wire display(0x3c, D3, D5);
WiFiUDP Udp;
unsigned int localUdpPort = 4242;
char incomingPacket[MAXBUF];
char replyPacket[] = "OK";
byte hexToByte (char c) {
if ( (c >= '0') && (c <= '9') ) {
return c - '0';
}
if ( (c >= 'A') && (c <= 'F') ) {
return (c - 'A')+10;
}
}
void setup() {
int error;
// setup network
WiFi.begin("ssid", "password");
display.init();
display.flipScreenVertically(); // yeah lol, didnt even notice this in the test sketch when i breadboarded the screen
display.setFont(ArialMT_Plain_10);
while (WiFi.status() != WL_CONNECTED)
{
delay(100);
}
Udp.begin(localUdpPort);
display.clear();
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.drawString(64, 22, WiFi.localIP().toString());
display.display();
delay(4000);
display.clear();
display.display();
}
int pixels[128*64];
unsigned long previousMillis = 0;
const long interval = 50;
unsigned long timerstart = 0;
void loop() {
unsigned long currentMillis = millis();
// grab pixelflut ascii data
// start by grabbing a packet from udp if any are there
int packetSize = Udp.parsePacket();
if (packetSize)
{
int len = Udp.read(incomingPacket, MAXBUF);
if (len > 0)
{
incomingPacket[len] = '\0';
}
}
// the buffer now has a packet (probably..) so lets parse it
// format is "PX x y 24bithexcolor\n" and can come multiple times per package
char *saveptr1, *saveptr2;
char *token = strtok_r(incomingPacket, "\n", &saveptr1);
while (token) {
// token should be a single pixel now
char *subtoken = strtok_r(token," ", &saveptr2);
int pos = 0;
int pixelvalues[8];
byte n = 0;
while (subtoken) {
// iterate through space seperated
if (pos==3) {
n = hexToByte( subtoken[ 0 ] );
n = ( n * 16 ) + hexToByte( subtoken[1] );
pixelvalues[2] = n;
n = hexToByte( subtoken[ 2 ] );
n = ( n * 16 ) + hexToByte( subtoken[3] );
pixelvalues[3] = n;
n = hexToByte( subtoken[ 4 ] );
n = ( n * 16 ) + hexToByte( subtoken[5] );
pixelvalues[4] = n;
} else if (pos>0) {
pixelvalues[pos-1] = atoi(subtoken);
}
pos++;
// first time 'PX' , second time 'x' , third time 'y' , last time 'hex'
// maybe an array?
subtoken = strtok_r(NULL," ", &saveptr2);
}
token = strtok_r(NULL, "\n", &saveptr1);
// some fancier methods are possible for picking a 0-255 value for a pixel, but i'm just grabbing G for now
//pixels[(pixelvalues[1]*20)+pixelvalues[0]] = (pixelvalues[2]/3)+(pixelvalues[3]/2)+(pixelvalues[4]/6);
//pixels[(pixelvalues[1]*20)+pixelvalues[0]] = (pixelvalues[2]+pixelvalues[3]+pixelvalues[4])/3;
pixels[(pixelvalues[1]*128)+pixelvalues[0]] = pixelvalues[2];
}
// display
display.clear();
for (int x = 0; x < 128; x++ ) {
for (int y = 0; y < 64; y+=2 ) {
// either this pixel is on or off
if (pixels[(y*128)+x]>127) {
display.setPixel(x,y);
} else {
// dont have to do anything, cause we .clear()'ed the buffer
}
}
}
// oled isnt that fast, dont draw too often
// actually not really needed but meh
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
display.display();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment