ESP8266 Matrix Display V2

Begonnen von hankyzoolander, 03 Februar 2018, 17:15:14

Vorheriges Thema - Nächstes Thema

hankyzoolander

Hallo,
vor einiger Zeit habe ich im Forum mein Matrix Display vorgestellt https://forum.fhem.de/index.php/topic,77316.msg692541.html#msg692541

Diese version wurde jetzt überarbeitet und möchte ich euch nicht vorenthalten und den ein oder anderen zum bauen anregen.

Zuerst mal ein großes DANKESCHÖN an Markus und Marc für ihre guten Nerven und Zeit mit diesem Projekt.

Hardware:
Wemos D1 mini (clone)
8x 4er Matrix Display mit Max7219 Chip
5V RGB LED Stripe 1m lang
2 kleine Taster
3x STP16NF06L (Transistoren für RGB LED Stripe)
5V Netzteil

RGB LED Stripe hinten am Gehäuse und leuchtet gegen Wand und/oder Decke(stimmungsvolle indirekte Beleuchtung)

Software:
folgender Code wird verwendet.
#include <LEDMatrixDriver.hpp>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>


const char* ssid = "wlan-ssid";
const char* password = "wlan-passwort";
// TCP server at port 80 will respond to HTTP requests
WiFiServer server(80);

const char* TEXT_KEY = "MatrixText";
const char* SCROLLING_KEY = "MatrixScrollen";
const char* BRIGHTNESS_KEY = "MatrixHelligkeit";
const char* RGB_KEY = "rgb";
const char* RGBPOWER_KEY = "rgbPower";
const char* SCROLLSPEED_KEY = "MatrixScrollSpeed";
const char* MATRIXPOWER_KEY = "MatrixPower";

/*
   ESP8266 pins need wired are below:
   DIN (data in) on Matrix ---> D7 or MOSI on ESP8266
   Clock(CLK) on Matrix --> D5 or SCK on ESP8266
   CS pin on Matrix define below  --->( pick 15 on esp8266)
*/
const uint8_t LEDMATRIX_CS_PIN = D3;

// Define LED Matrix dimensions (0-n) - eg: 32x8 = 31x7
const int LEDMATRIX_WIDTH = 256;
const int LEDMATRIX_HEIGHT = 8;
const int LEDMATRIX_SEGMENTS = 32;
const int RED = D0;
const int GREEN = D1;
const int BLUE = D2;

// The LEDMatrixDriver class instance
LEDMatrixDriver lmd(LEDMATRIX_SEGMENTS, LEDMATRIX_CS_PIN);

// Block font 8x8
byte  font[][8] = {
  { 0, 0, 0, 0, 0, 0, 0, 0 }, //space
  { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00},   // U+0021 (!)
  { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0022 (")
  { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00},   // U+0023 (#)
  { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00},   // U+0024 ($)
  { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00},   // U+0025 (%)
  { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00},   // U+0026 (&)
  { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0027 (')
  { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00},   // U+0028 (()
  { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00},   // U+0029 ())
  { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00},   // U+002A (*)
  { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00},   // U+002B (+)
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06},   // U+002C (,)
  { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00},   // U+002D (-)
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00},   // U+002E (.)
  { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00},   // U+002F (/)
  { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00},   // U+0030 (0)
  { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00},   // U+0031 (1)
  { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00},   // U+0032 (2)
  { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00},   // U+0033 (3)
  { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00},   // U+0034 (4)
  { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00},   // U+0035 (5)
  { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00},   // U+0036 (6)
  { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00},   // U+0037 (7)
  { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00},   // U+0038 (8)
  { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00},   // U+0039 (9)
  { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00},   // U+003A (:)
  { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06},   // U+003B (//)
  { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00},   // U+003C (<)
  { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00},   // U+003D (=)
  { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00},   // U+003E (>)
  { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00},   // U+003F (?)
  { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00},   // U+0040 (@)
  { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00},   // U+0041 (A)
  { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00},   // U+0042 (B)
  { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00},   // U+0043 (C)
  { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00},   // U+0044 (D)
  { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00},   // U+0045 (E)
  { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00},   // U+0046 (F)
  { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},   // U+0047 (G)
  { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},   // U+0048 (H)
  { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0049 (I)
  { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00},   // U+004A (J)
  { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00},   // U+004B (K)
  { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00},   // U+004C (L)
  { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00},   // U+004D (M)
  { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00},   // U+004E (N)
  { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00},   // U+004F (O)
  { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00},   // U+0050 (P)
  { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00},   // U+0051 (Q)
  { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00},   // U+0052 (R)
  { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00},   // U+0053 (S)
  { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0054 (T)
  { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00},   // U+0055 (U)
  { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0056 (V)
  { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00},   // U+0057 (W)
  { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00},   // U+0058 (X)
  { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00},   // U+0059 (Y)
  { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00},   // U+005A (Z)
  { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00},   // U+005B ([)
  { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00},   // U+005C (\)
  { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00},   // U+005D (])
  { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00},   // U+005E (^)
  { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},   // U+005F (_)
  { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+0060 (`)
  { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00},   // U+0061 (a)
  { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00},   // U+0062 (b)
  { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00},   // U+0063 (c)
  { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00},   // U+0064 (d)
  { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00},   // U+0065 (e)
  { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00},   // U+0066 (f)
  { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F},   // U+0067 (g)
  { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00},   // U+0068 (h)
  { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+0069 (i)
  { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E},   // U+006A (j)
  { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00},   // U+006B (k)
  { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},   // U+006C (l)
  { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00},   // U+006D (m)
  { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00},   // U+006E (n)
  { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00},   // U+006F (o)
  { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F},   // U+0070 (p)
  { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78},   // U+0071 (q)
  { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00},   // U+0072 (r)
  { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00},   // U+0073 (s)
  { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00},   // U+0074 (t)
  { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00},   // U+0075 (u)
  { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},   // U+0076 (v)
  { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00},   // U+0077 (w)
  { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00},   // U+0078 (x)
  { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F},   // U+0079 (y)
  { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00},   // U+007A (z)
  { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00},   // U+007B ({)
  { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},   // U+007C (|)
  { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00},   // U+007D (})
  { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   // U+007E (~)
};
int x = LEDMATRIX_WIDTH, y = 0; // start top left

// Marquee text
char text[75] = " Hello ";
int len = strlen(text);
// Marquee speed

// const int ANIM_DELAY = 60; TEST
int ANIM_DELAY = 60;
unsigned long myTime = millis();
unsigned long intro = millis();
IPAddress ip ;

int brightness = 0;
int scrollen = 1;
int buttonD4 = 0;
int lastbuttonD4 = 0;
int buttonD6 = 0;
int lastbuttonD6 = 0;
int red = 0;
int green = 0;
int blue = 0;
int rgb = 0x000000;

void setup() {

  pinMode(D4, OUTPUT); // Taster Helligkeit D4
  digitalWrite(D4, LOW);
  pinMode(D6, OUTPUT); // Taster Scrolling an/aus D6
  digitalWrite(D6, LOW);
  pinMode(RED, OUTPUT);
  digitalWrite(RED, LOW);
  pinMode(GREEN, OUTPUT);
  digitalWrite(GREEN, LOW);
  pinMode(BLUE, OUTPUT);
  digitalWrite(BLUE, LOW);

  //Initialize the display
  lmd.setEnabled(true);
  //lmd.setIntensity(brightness);   // 0 = low, 10 = high
  sprintf(text, "Connecting to %s", ssid);
  len = strlen(text);
  // Connect to WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    displayText(text);
    delay(ANIM_DELAY);
  }
  // Start TCP (HTTP) server
  server.begin();
  ip = WiFi.localIP();
  String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
  strcpy(text, ipStr.c_str());
  len = strlen(text);


  Serial.begin(57600);
}

void loop()
{
    buttonD4 = digitalRead(D4); //D4
    buttonD6 = digitalRead(D6); //D6

    if (buttonD4 != lastbuttonD4) {
      if (buttonD4 == HIGH) {
        brightness++ ;
        Serial.print("brightness: ");
        Serial.println(brightness);
        delay(20);
      }
    }
    if (brightness > 10) brightness = 0;
    lastbuttonD4 = buttonD4;

  lmd.setIntensity(brightness);

    if (buttonD6 != lastbuttonD6) {
      if (buttonD6 == HIGH) {
        if (scrollen == 1) scrollen = 0; else scrollen = 1;
        Serial.print("Scrollen: ");
        Serial.println(scrollen);
        lmd.clear();
        delay(20);
      }
    }
    lastbuttonD6 = buttonD6;



  displayText(text);
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }

  // Wait for data from client to become available
  while (client.connected() && !client.available()) {
    displayText(text);
    delay(1);
  }

  // Read the first line of HTTP request
  String req = client.readStringUntil('\r');

  // First line of HTTP request looks like "GET /path HTTP/1.1"
  // Retrieve the "/path" part by finding the spaces
  int addr_start = req.indexOf(' ');
  int addr_end = req.indexOf(' ', addr_start + 1);
  if (addr_start == -1 || addr_end == -1) {
    return;
  }
  req = req.substring(addr_start + 1, addr_end);
  client.flush();

  String s;
  int pos = req.indexOf('?');

  if (pos > 0) {
    req = req.substring(pos + 1);

    /* parse key value pairs */
    parseRequest(req);

    x = LEDMATRIX_WIDTH;
    lmd.clear();

    //Serial.println(req.substring(req.indexOf('=')+1));
    s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML><style> #header{ min-height: 20px; background-color: #666699; } #menu{ min-height: 20px; margin-top: 1%; background-color: #999999; } #body{ min-height: 200px; margin-top: 1%; } #footer{ min-height: 20px; margin-top: 1%; background-color: #666699; } #header, #menu, #body, #footer{ margin-left: 10%; margin-right: 10%; box-shadow: 3px 5px 7px #666666; border: 1px solid black; } @viewport{ zoom: 1.0; width: extend-to-zoom; } @-ms-viewport{ width: extend-to-zoom; zoom: 1.0; } </style> <html lang='en'> <head> <meta name='viewport' content='width=device-width, initial-scale=1'> <title>ESP8266 Web Server</title> </head> <body> <div id='header'><center><h1>Welcome to the ESP8266 Web Server</H1></center></div>";
    s += " <div id='menu'><center><H2>Printing to the 4 - 8x8 Matrix</h2></center></div> ";
    s += "<div id='body'><center><div><div><br/><H3>";
    s += text;
    s += "<p><a href='./'>Back</a></p>";
    s += "</H3></div></div> </center> </div> <div id='footer'> </div> </body></html> ";
    //s+=req.substring(req.indexOf('=')+1);
    s + "</body></html>\r\n\r\n";
    client.print(s);
    return;
  }
  else
  {

    s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n";
    s += "<!doctype html> <style> \#header{ min-height: 20px; background-color: \#666699; } \#menu{ min-height: 20px; margin-top: 1%; background-color: \#999999; } \#body{ min-height: 200px; margin-top: 1%; } \#footer{ min-height: 20px; margin-top: 1%; background-color: \#666699; } \#header, \#menu, \#body, \#footer{ margin-left: 10%; margin-right: 10%; box-shadow: 3px 5px 7px \#666666; border: 1px solid black; } @viewport{ zoom: 1.0; width: extend-to-zoom; } @-ms-viewport{ width: extend-to-zoom; zoom: 1.0; } </style> <html lang='en'> <head> <meta name='viewport' content='width=device-width, initial-scale=1'> <title>ESP8266 Web Server</title> </head> <body> <div id='header'><center><h1>Welcome to the ESP8266 Web Server</H1></center></div> <div id='menu'><center><H2>Enter text which will be displayed on a 4 - 8x8 led matrix</h2></center></div> <div id='body'><center><div><div><br> <form action='esp8266'> <br>Enter Text to display on LED Matrix:<br><input type='text' maxlength='70' name='text' value=''><br><br> <input type='submit' value='Submit'></form> </div></div> </center> </div> <div id='footer'> </div> </body>";
    s += "</html>\r\n\r\n";
    client.print(s);
    return;
  }

}

/* This function is called in loop but
    only does stuff when animimation delay
    is met.

    This will allow loop to do other thing instead
    of waiting for a delay to happen.

    Delay=bad programming.
*/

void setColor(int rgb) {
  analogWrite(RED, rgb >> 16);
  analogWrite(GREEN, rgb >> 8 & 0xFF);
  analogWrite(BLUE, rgb & 0xFF);
}

void displayText ( char * theText)
{
  if ( myTime + ANIM_DELAY < millis())
  {
    myTime = millis();
    // Draw the text to the current position
    if (scrollen == 1) drawString(theText, len, x, 0); else drawString(theText, len, 0, 0);
    // In case you wonder why we don't have to call lmd.clear() in every loop: The font has a opaque (black) background...
    // Toggle display of the new framebuffer
    lmd.display();
    // Advance to next coordinate
    if ( --x < len * -8 )
    {
      x = LEDMATRIX_WIDTH;
      lmd.clear();
    }
  }
}

/**
   This function draws a string of the given length to the given position.
*/
void drawString(char* text, int len, int x, int y )
{

  for ( int idx = 0; idx < len; idx ++ )
  {
    int c = text[idx] - 32;

    // stop if char is outside visible area
    if ( x + idx * 8  > LEDMATRIX_WIDTH )
      return;

    // only draw if char is visible
    if ( 8 + x + idx * 8 > 0 )
      drawSprite( font[c], x + idx * 8, y, 8, 8 );
  }
}

/**
   This draws a sprite to the given position using the width and height supplied (usually 8x8)
*/
void drawSprite( byte* sprite, int x, int y, int width, int height )
{
  // The mask is used to get the column bit from the sprite row
  byte mask = B10000000;

  for ( int iy = 0; iy < height; iy++ )
  {
    for ( int ix = 0; ix < width; ix++ )
    {
      //Yes my font is backwards so I swap it around.
      //lmd.setPixel(x + ix, y + iy, (bool)(sprite[iy] & mask ));
      lmd.setPixel(x + (width - ix), y + iy, (bool)(sprite[iy] & mask ));

      // shift the mask by one pixel to the right
      mask = mask >> 1;
    }

    // reset column mask
    mask = B10000000;
  }
}

void urlDecode(String& url) {
  /* special space encdoing for using in FHEM */
  url.replace('+', ' ');

  //Conver HTML URL to Text:
  //https://www.w3schools.com/tags/ref_urlencode.asp
  url.replace("%20", " ");
  url.replace("%21", "\!");
  url.replace("%22", "\"");
  url.replace("%23", "\#");
  url.replace("%24", "\$");
  url.replace("%25", "%");
  url.replace("%26", "&");
  url.replace("%27", "\'");
  url.replace("%28", "\(");
  url.replace("%29", "\)");
  url.replace("%2B", "\+");
  url.replace("%2C", "\,");
  url.replace("%2D", "\-");
  url.replace("%2E", "\.");
  url.replace("%2F", "\/");
  url.replace("%3A", "\:");
  url.replace("%3B", "\;");
  url.replace("%3C", "\<");
  url.replace("%3D", "\=");
  url.replace("%3E", "\>");
  url.replace("%3F", "\?");
  url.replace("%40", "\@");
  url.replace("%5B", "\[");
  url.replace("%5C", "\\");
  url.replace("%5D", "\]");
  url.replace("%5E", "\^");
  url.replace("%7B", "\{");
  url.replace("%7C", "\|");
  url.replace("%7D", "\}");
}

void parseRequest(String request) {
  while (request.length() > 0) {
    /* check if we have a key value pair */
    int valueStartPos = request.indexOf('=');

    /* cancel if we have no key value pair */
    if (valueStartPos == -1) return;

    /* look for end of value */
    int valueEndPos = request.indexOf('&');
    if (valueEndPos == -1) valueEndPos = request.length();

    /* extract value */
    String value = request.substring(valueStartPos + 1, valueEndPos);

    /* value is "url" encoded, decode it to plain text */
    urlDecode(value);

    /* look for valid keys ... */

    /* KEY: text */
    if (strncmp(TEXT_KEY, request.c_str(), valueStartPos) == 0) {
      strcpy(text, value.c_str());
      len = strlen(text);
    }

    /* KEY: MatrixPower */
    if (strncmp(MATRIXPOWER_KEY, request.c_str(), valueStartPos) == 0) {
      if (strcmp("off", value.c_str()) == 0) strcpy(text, "                          ");
      else strcpy(text, "on");
    }

    /* KEY: scrolling */
    if (strncmp(SCROLLING_KEY, request.c_str(), valueStartPos) == 0) {
      if (strcmp("on", value.c_str()) == 0) scrollen = 1;
      else scrollen = 0;
    }

    /* KEY: Scrollspeed */
    if (strncmp(SCROLLSPEED_KEY, request.c_str(), valueStartPos) == 0) {
      ANIM_DELAY = value.toInt();
    }

    /* KEY: rgbPower */
    if (strncmp(RGBPOWER_KEY, request.c_str(), valueStartPos) == 0) {
      if (strcmp("on", value.c_str()) == 0) rgb = 0xFFFFFF;
      else rgb = 0x000000;
      setColor(rgb);
    }


    /* KEY: brightness */
    if (strncmp(BRIGHTNESS_KEY, request.c_str(), valueStartPos) == 0) {
      brightness = value.toInt();
    }

    /* KEY: rgb */
    if (strncmp(RGB_KEY, request.c_str(), valueStartPos) == 0) {
      rgb = (int)strtol(value.c_str(), NULL, 0);
      setColor(rgb);
    }


    /* move to next key value pair */
    request = request.substring(valueEndPos + 1);
  }
}



Die beiden kleinen Taster haben die Funktionen
Hardwareseitiges dimmen der LedMatrix und Hardwareseitiges scrollen ein/aus.
Länge und Höhe des Displays anpassen.
Nachdem wlan ssid und passwort angepasst ist, wird der code mit der Arduino Software geflasht.
Auf dem Display erscheint die IP welche der Wemos vom Router bekommen hat.

Betrieb in Fhem:
Der Wemos wird von Fhem mit wget gefüttert.
Folgende Funktionen stehen nun bereit in Fhem.

-MatrixHelligkeit       <--> über Fhem Helligkeit des Matrix Displays in 10 Stufen mit Slider dimmen
-MatrixPower           <--> über Fhem das Matrix Display ein oder aus schalten
-MatrixScrollSpeed   <--> über Fhem die Scroll Geschindigkeit mit Slider einstellen von 10ms-100ms in 5er Schritten
-MatrixScrollen         <--> über Fhem das Textscrollen ein oder aus schalten
-MatrixText               <--> über Fhem einen text oder reading auf dem Display anzeigen lassen
-rgbPower                <--> über Fhem den LED Stripe ein oder aus schalten
-rgb                          <--> über Fhem die LED Stripe Farbe über den colorpicker einstellen

Im Moment besteht noch ein kleines Problem, und zwar wird für jede Funktion der ganzen Kiste ein separates notify benötigt!
Also 7 Funktionen = 7 notify.
Jetzt wird der ein oder andere sagen das geht auch in einem.
Wir haben es, ganz ehrlich gesagt nicht hinbekommen.(wenn jemand ne Idee hat, bitte her damit)  ;)

Zuerst wird ein DUMMY angelegt
define display dummy
attr display webCmd rgb
attr display widgetOverride rgb:colorpicker,RGB
attr display setList MatrixText rgb MatrixScrollen:on,off MatrixHelligkeit:slider,0,1,10 rgbPower:on,off MatrixScrollSpeed:slider,10,5,100 MatrixPower:on,off


Hier mal die notify`s
Das ganze Gerät heißt bei mir display

define display_matrix_dimm notify display:MatrixHelligkeit.* "wget -q -O - "http://192.168.0.146/esp8266?MatrixHelligkeit=$EVTPART1""

define display_matrix_power notify display:MatrixPower.* "wget -q -O - "http://192.168.0.146/esp8266?MatrixPower=$EVTPART1""

define display_matrix_scroll notify display:MatrixScrollen.* "wget -q -O - "http://192.168.0.146/esp8266?MatrixScrollen=$EVTPART1""

define display_matrix_text notify display:MatrixText.* "wget -q -O - "http://192.168.0.146/esp8266?MatrixText=$EVTPART1""

define display_scroll_speed notify display:MatrixScrollSpeed.* "wget -q -O - "http://192.168.0.146/esp8266?MatrixScrollSpeed=$EVTPART1""

define display_rgb notify display:rgb.* "wget -q -O - "http://192.168.0.146/esp8266?rgb=0x$EVTPART1""

define display_rgb_power notify display:rgbPower.* "wget -q -O - "http://192.168.0.146/esp8266?rgbPower=$EVTPART1""


Versuchsaufbau mit einem 4er Modul

betateilchen  <--- my personal hero

The-Holgi

Hallo hankyzoolander,
wie kann ich mehrere readings auf das Display übertragen?
Mit
Aussen_Sensor:temperature:.* "wget --quiet - "http://192.168.178.65/esp8266?max=Aussentemp.+$EVTPART1+C""

Übertrage ich die Temperatur, schön wäre es jetzt wenn auch noch Luftdruck und Luftfeuchtigkeit mit übertragen werden.

Gruß Holgi
HP T610 Thin Client; Docker Fhem 5.9; 2X CUL V3 868mhz; Max Heizungssteuerung; FS20kse; FS20UWS; FS20S8-3; 2 FS20DI; HM-CFG-LAN,HM-LC-SW1-PL,HM-SEC-SD, HM-SE1PBU-FM;
Harmony Hub;Hue-Bridge mit Iris, E27 Bulb & FLS-PP

robertPI

Hallo,

für alle die möglicherweise wie ich am flashen eines LoLin NodeMcu v3 verzweifeln http://www.instructables.com/id/Getting-Started-With-ESP8266LiLon-NodeMCU-V3Flashi/
Die Arduino IDE 1.8.5 setzt bei mir unter Linux die Speichergröße und Frequenz beim Aufruf des esptool nicht richtig. Wichtig sind die zusätzlichen Parameter  -bz 4M -bf 80
esptool -vv -cd nodemcu -cb 9600 -cp /dev/ttyUSB0 -ca 0x00000 -bz 4M -bf 80 -cf /tmp/arduino_build_523731/esp8266_LED_Matrix2_2018-02-09.ino.bin
FHEM auf Raspbery Pi 4
HM: HM-CFG-USB-2,HM-CC-RT-DN,HM-TC-IT-WM-W-EU,HM-SEC-SCo,HM-ES-PMSw1-Pl,HM-Sen-MDIR-WM55 | Philips hue: LCT001,LWL001,FLS-PP lp | Logitech Harmony Ultimate | zigbee2mqtt: WSDCGQ01LM, WSDCGQ11LM, MFKZQ01LM, MCCGQ11LM

Shojo

Ha das ja lustig  ;D
Habe fast das gleiche gebaut allerdings über MQTT .
FHEM auf: Shuttle PC (x64) (Docker)
Bridge: SignalESP 433mHz, ConBee (deCONZ in Docker)
Rest: ESP8266, SONOFF, Sonos, Echo Dot, Xiaomi Vacuum (root), ESP RGBWW Wifi Led Controller, Node-RED, LEDMatrix, Pixel It

The-Holgi

Zitat von: Shojo am 15 Februar 2018, 15:55:22
Ha das ja lustig  ;D
Habe fast das gleiche gebaut allerdings über MQTT .
Hallo,
hast Lust mehr darüber zu erzählen?
Habe nämlich bis jetzt keinen Weg gefunden mehrere readings als Laufschrift auf dem Dot Matrix Display
anzuzeigen.
Gruß Holgi
HP T610 Thin Client; Docker Fhem 5.9; 2X CUL V3 868mhz; Max Heizungssteuerung; FS20kse; FS20UWS; FS20S8-3; 2 FS20DI; HM-CFG-LAN,HM-LC-SW1-PL,HM-SEC-SD, HM-SE1PBU-FM;
Harmony Hub;Hue-Bridge mit Iris, E27 Bulb & FLS-PP

Shojo

Zitat von: The-Holgi am 15 Februar 2018, 20:51:45
Habe nämlich bis jetzt keinen Weg gefunden mehrere readings als Laufschrift auf dem Dot Matrix Display anzuzeigen.

Mein Display hat auch keine Queue, ich mach das einfach über ein DOIF.



([+00:00:18] and ([?$SELF:cmd] eq '0' or [?$SELF:cmd] eq '7'))
(
set BU.Anzeige.LEDMatrix Text WZ.Temp: [WZ.Sensor.Room:Temperature] C
)
DOELSEIF ([+00:00:18] and [?$SELF:cmd] eq '1')
(
set BU.Anzeige.LEDMatrix Text KZ.Temp: [KZ.Heizung_Clima:measured-temp] C
)
DOELSEIF ([+00:00:18] and [?$SELF:cmd] eq '2')
(
set BU.Anzeige.LEDMatrix Text GB.Temp: [GB.Heizung_Clima:measured-temp] C
)
DOELSEIF ([+00:00:18] and [?$SELF:cmd] eq '3')
(
set BU.Anzeige.LEDMatrix Text BZ.Temp: [BZ.Heizung_Clima:measured-temp] C
)
DOELSEIF ([+00:00:18] and [?$SELF:cmd] eq '4')
(
set BU.Anzeige.LEDMatrix Text SZ.Temp: [SZ.Heizung_Clima:measured-temp] C
)
DOELSEIF ([+00:00:18] and [?$SELF:cmd] eq '5')
(
set BU.Anzeige.LEDMatrix Text BU.Temp: [BU.Heizung_Clima:measured-temp] C
)
DOELSEIF ([+00:00:18] and [?$SELF:cmd] eq '6')
(
set BU.Anzeige.LEDMatrix Text TR.Temp: [TR.Sensor.Weather:Temperature] C
)
FHEM auf: Shuttle PC (x64) (Docker)
Bridge: SignalESP 433mHz, ConBee (deCONZ in Docker)
Rest: ESP8266, SONOFF, Sonos, Echo Dot, Xiaomi Vacuum (root), ESP RGBWW Wifi Led Controller, Node-RED, LEDMatrix, Pixel It

The-Holgi

Hm, wenn ich das doif richtig verstanden habe wechselt die Anzeige alle 18 Sekunden und läuft in einer Schleife?
Mal sehen ob ich das mit meinem code:
Aussen_Sensor:temperature:.* "wget --quiet - "http://192.168.178.65/esp8266?max=Aussentemp.+$EVTPART1+C""
auch hin bekomme.
HP T610 Thin Client; Docker Fhem 5.9; 2X CUL V3 868mhz; Max Heizungssteuerung; FS20kse; FS20UWS; FS20S8-3; 2 FS20DI; HM-CFG-LAN,HM-LC-SW1-PL,HM-SEC-SD, HM-SE1PBU-FM;
Harmony Hub;Hue-Bridge mit Iris, E27 Bulb & FLS-PP

Shojo

Zitat von: The-Holgi am 15 Februar 2018, 23:36:50
Hm, wenn ich das doif richtig verstanden habe wechselt die Anzeige alle 18 Sekunden und läuft in einer Schleife?
Ja genau.

Zitat von: The-Holgi am 15 Februar 2018, 23:36:50
Mal sehen ob ich das mit meinem code:
Aussen_Sensor:temperature:.* "wget --quiet - "http://192.168.178.65/esp8266?max=Aussentemp.+$EVTPART1+C""
auch hin bekomme.
Versuche mal dieses:
(Ohne das jetzt getestet zu haben, da ich nicht zu hause bin)

([+00:00:18] and ([?$SELF:cmd] eq '0' or [?$SELF:cmd] eq '2'))
(
{wget --quiet - "http://192.168.178.65/esp8266?max=Aussentemp.+ReadingsVal("Aussen_Sensor","temperature","0")+C";}
)
DOELSEIF ([+00:00:18] and [?$SELF:cmd] eq '1')
(
        {wget --quiet - "http://192.168.178.65/esp8266?max=Aussenhum.+ReadingsVal("Aussen_Sensor","humidity","0")+%";}

)
FHEM auf: Shuttle PC (x64) (Docker)
Bridge: SignalESP 433mHz, ConBee (deCONZ in Docker)
Rest: ESP8266, SONOFF, Sonos, Echo Dot, Xiaomi Vacuum (root), ESP RGBWW Wifi Led Controller, Node-RED, LEDMatrix, Pixel It

The-Holgi

#8
Hallo Shojo,
erstmal Danke für deine Hilfe.
Habe es mal so versucht:
define THPL_Display DOIF ([+00:00:18] and ([?$SELF:cmd] eq '0' or [?$SELF:cmd] eq '2'))
(
{wget --quiet - "http://192.168.178.65/esp8266?max=Aussentemp.+ReadingsVal("Aussen_Sensor","temperature","0")+C";}
)
DOELSEIF ([+00:00:18] and [?$SELF:cmd] eq '1')
(
        {wget --quiet - "http://192.168.178.65/esp8266?max=Aussenhum.+ReadingsVal("Aussen_Sensor","humidity","0")+%";}

)


darauf die Ausgabe:
THPL_Display DOIF: no right bracket: ( {wget --quiet - "http://192.168.178.65/esp8266?max=Aussentemp.+ReadingsVal("Aussen_Sensor","temperature","0")+C"
Unknown command }, try help.
Unknown command }, try help.
Error: >THPL_Display< has no TYPE, but following keys: >READINGS<


Ist vielleicht nur ein syntaxfehler?

Gruß Holgi
HP T610 Thin Client; Docker Fhem 5.9; 2X CUL V3 868mhz; Max Heizungssteuerung; FS20kse; FS20UWS; FS20S8-3; 2 FS20DI; HM-CFG-LAN,HM-LC-SW1-PL,HM-SEC-SD, HM-SE1PBU-FM;
Harmony Hub;Hue-Bridge mit Iris, E27 Bulb & FLS-PP

Shojo

#9
Zitat von: The-Holgi am 16 Februar 2018, 13:14:27
Ist vielleicht nur ein syntaxfehler?
Ja das kann gut sein... Bin kein Perl Crack und ich kann das hier jetzt nicht testen.

Vielleicht so?

([+00:00:18] and ([?$SELF:cmd] eq '0' or [?$SELF:cmd] eq '2'))
(
{
               my $url = 'http://192.168.178.65/esp8266?max=Aussentemp' + ReadingsVal("Aussen_Sensor","temperature","0") + 'C';;
               system("wget --quiet $url");;               
        }
)
DOELSEIF ([+00:00:18] and [?$SELF:cmd] eq '1')
(
{
               my $url = 'http://192.168.178.65/esp8266?max=Aussenhum' + ReadingsVal("Aussen_Sensor","humidity","0") + 'C';;
               system("wget --quiet $url");;               
        }
)
FHEM auf: Shuttle PC (x64) (Docker)
Bridge: SignalESP 433mHz, ConBee (deCONZ in Docker)
Rest: ESP8266, SONOFF, Sonos, Echo Dot, Xiaomi Vacuum (root), ESP RGBWW Wifi Led Controller, Node-RED, LEDMatrix, Pixel It

The-Holgi

So wurde zumindest das DOIF ohne Fehlermeldung erstellt.
Fhem hat sich jedoch komplett aufgehangen und das steht im log:
PERL WARNING: Argument "http://192.168.178.65/esp8266?max=Aussentemp" isn't numeric in addition (+) at (eval 228) line 1.
2018.02.16 13:54:14 3: eval: {                my $url = 'http://192.168.178.65/esp8266?max=Aussentemp' + ReadingsVal("Aussen_Sensor","temperature","0") + 'C';                system("wget --quiet $url");                        }
2018.02.16 13:54:14 1: PERL WARNING: Argument "C" isn't numeric in addition (+) at (eval 228) line 1.
2018.02.16 13:54:14 3: eval: {                my $url = 'http://192.168.178.65/esp8266?max=Aussentemp' + ReadingsVal("Aussen_Sensor","temperature","0") + 'C';                system("wget --quiet $url");                        }
2018.02.16 13:56:56 2: THPL_Display: {                my $url = 'http://192.168.178.65/esp8266?max=Aussentemp' + ReadingsVal("Aussen_Sensor","temperature","0") + 'C';                system("wget --quiet $url");                        }: -1

HP T610 Thin Client; Docker Fhem 5.9; 2X CUL V3 868mhz; Max Heizungssteuerung; FS20kse; FS20UWS; FS20S8-3; 2 FS20DI; HM-CFG-LAN,HM-LC-SW1-PL,HM-SEC-SD, HM-SE1PBU-FM;
Harmony Hub;Hue-Bridge mit Iris, E27 Bulb & FLS-PP

Shojo

ah ok !


([+00:00:18] and ([?$SELF:cmd] eq '0' or [?$SELF:cmd] eq '2'))
(
{
               my $url = 'http://192.168.178.65/esp8266?max=Aussentemp' . ReadingsVal("Aussen_Sensor","temperature","0") . 'C';;
               system("wget --quiet $url");;               
        }
)
DOELSEIF ([+00:00:18] and [?$SELF:cmd] eq '1')
(
{
               my $url = 'http://192.168.178.65/esp8266?max=Aussenhum' . ReadingsVal("Aussen_Sensor","humidity","0") . 'C';;
               system("wget --quiet $url");;               
        }
)


SO ?! :D
FHEM auf: Shuttle PC (x64) (Docker)
Bridge: SignalESP 433mHz, ConBee (deCONZ in Docker)
Rest: ESP8266, SONOFF, Sonos, Echo Dot, Xiaomi Vacuum (root), ESP RGBWW Wifi Led Controller, Node-RED, LEDMatrix, Pixel It

The-Holgi

#12
Hallo,
soweit funktioniert es so.
Allerdings habe ich gerade gesehen das die readings auch in opt/fhem geschrieben werden.
esp8266?max=Aussenhum73%25.2
esp8266?max=Aussentemp+5.8C
fhem.cfg
esp8266?max=Aussenhum73%25.1
esp8266?max=Aussentemp5.8C.6
fhem.db-wal
fhem.db-shm
esp8266?max=Aussenhum73%25
esp8266?max=Aussentemp5.8C.5
esp8266?max=Aussenhum75%25
esp8266?max=Aussentemp5.8C.4
esp8266?max=Aussentemp5.8C.3
esp8266?max=Aussenhum75C.2
esp8266?max=Aussentemp5.8C.2
esp8266?max=Aussenhum75C.1


Das liegt natürlich nicht an deinem DOIF.
Überlege gerade mosqito zu installieren.

:D
HP T610 Thin Client; Docker Fhem 5.9; 2X CUL V3 868mhz; Max Heizungssteuerung; FS20kse; FS20UWS; FS20S8-3; 2 FS20DI; HM-CFG-LAN,HM-LC-SW1-PL,HM-SEC-SD, HM-SE1PBU-FM;
Harmony Hub;Hue-Bridge mit Iris, E27 Bulb & FLS-PP

kroman

Hallo Leute,

hat von euch jemand elegant das Problem gelöst, dass nur das 1. Wort übertragen wird?
Also hierbei meine ich:


set display MatrixText eins zwei


Verursacht durch $EVTPART1 im notify.

Gruß
kroman

kroman

So geht's:


defmod n_dotmatrix1_MatrixText notify d_dotmatrix1:MatrixText.*\
{\
my $i = 1;;\
my $a = "";;\
foreach (split / /,$EVENT)\
{\
if ($i > 1)\
{\
$a = $a.$_."%20";;\
}\
$i++;;\
}\
system ("wget -q -O - http://esp11/esp8266?MatrixText=$a")\
}