TSS ausgabe, Internetradio mit LED Dot Matrix

Begonnen von Tueftler1983, 16 April 2018, 21:08:13

Vorheriges Thema - Nächstes Thema

Tueftler1983

Hallo zusammen,

Ich mache mal einen eigenen Thead auf.

Ich habe jetzt verschiedene Projekte gesehen und auch Teilweise umgesetzt.
Aber ich bin auf der Suche nach einer kombination aus diesen 3 Punkten, klar könnte ich dafür 3 ESP in ein gehäuse pachen aber ich denke das ist Overkilled

Ich hätte gerne einen Wlan Lautsprecher auf dem ich TTS ausgaben und einen Stream von nem Internetradio oder einer MP3 Wiedergabeliste laufen lassen kann, Zudem Soll eine LED Dot Matrix verbaut sein die die Uhrzeit anzeigt oder aus Fhem Herraus einen Text

z.b Es wird die uhrzeit angezeigt, Zur Weckzeit erklingt ein Wecksignal, dieses bestätigt man und ein Radiostream wird gestartet oder eine Sprachausgabe mit Aktuellem Wetter oder Verkehrslage etc

Leider bin ich in der Arduino Programmierung echt nicht fitt und bin schon immer Froh wenn ich ein Projekt von Grithub auf den ESP bekomme.

Vielleicht gibt es hier genug Interesse und schwarmwissen meine Idee umzusetzen

denke die kosten für alles zusammen liegen bei unter 50€ für ein Allround Lösung

TomLee

Zwar aktuell nicht für unter 50 €, davon aber abgesehen wäre alles mit einem Echo-Spot möglich.

TTS und MP3 geht seit kurzem auch mit dem echodevice-Modul
Internetradio, Weckzeit und Uhrzeit sind Standard
Einen Text anzeigen geht scheinbar auch schon irgendwie

Gruß

Thomas


Tueftler1983

Ja aber es soll ja um die Eierlegende Wollmilch Sau Gehen für unter 50€

Brauche aber hilfe bei der umsetzung des Codes für die Arduino IDE

Tueftler1983

Wer kann denn Helfen 2 Codes zu einem zusammen zu führen??

das eine ist der Code vom ESP8266 LED MAtriv Modul V2
https://forum.fhem.de/index.php/topic,83774.msg760320.html#msg760320

#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);
  }
}


Der andere ist vom WLAN Lautsprecher auf ESP Basis
https://forum.fhem.de/index.php/topic,71087.0.html

// *******************************************************************************************
//
// The code provides a webserver listening on port 5522 for an 8-bit mono PCM data stream.
// On pin IO3 (RXD) a pseudo 7-bit (8-bit dithered) PWM is ouput.
// This pin is setup as I2S interface and normally provides a 2 x 16-bit bit raw audio data stream.
// However in this usecase we output 32 x 4 = 128-bit of data to form a 7-bit (8-bit dithered) pseudo PWM.
// From version V4 on, pwm dithering is used.
//
// IMPORTANT:
// Set CPU clock to be 160 MHz in Arduino IDE!
//
// Comments and improvements welcome:
// huawatuam@gmail.com
//
// To provide the 8-bit PCM mono stream expected from the host, we need to convert the original e.g. mp3-file using "avconv" or similar.
//
// EXAMPLE:
// ========
// avconv -i gong.mp3 -f s32be -acodec pcm_u8 -ac 1 -ar 33000 tcp://192.168.1.100:5522
//
// When you want to use it with Text2Speech in FHEM, you can for example use a "notify" to forward the "lastFilename" reading from TTS,
// which contains the link to the last played mp3 file, to the ESP8266 wifi speaker.
//
// EXAMPLE CALL IN FHEM:
// =====================
// define myTTSforwarder notify myTTS:lastFilename:.* { system("avconv -i /opt/fhem/$EVTPART1 -f s32be -acodec pcm_u8 -af \"volume=0dB\" -ac 1 -ar 33000 tcp://192.168.1.100:5522 >/dev/null 2>&1&");
//
//
// VERSION HISTORY:
// ================
//
// V1 (14.05.2017)
// - initial version
//
// V2 (16.05.2017)
// - added option to set static IP, netmask and gateway
// - 160MHz cpu speed is automatically
// - fixed 0% PWM bug
// - increased buffer size
// - added "setNoDelay" to server & client
// - added "flush" when disconnected
//
// V3 (17.05.2017)
// - playback code removed from main loop
// - webserver connection handling reworked
// - stability improved by removing "delay(1)"
//
// V4 (21.05.2017)
// - pwm dithering added and enabled by default
// - status LED on gpio12 added (fast blinking when wifi is disconnected; short flash every 2 seconds when connected to AP; slow blining during playback)
// - fixed crash playing streams shorten than rx-buffer and disconnects during buffering
//
// V5 (23.05.2017)
// - ramp-up and -down transferred to one function
// - removed serial interface to avoid side-effects using i2s pwm output and uart-rx on the same pin
//
// V6 (28.05.2017)
// - added OTA update feature
// - improved transition between status led blink patterns
// - changed blinking pattern during streaming from slow blinking to constant on
// - changed blinking pattern on disconnected to blink slower
//
// V7 (30.05.2017)
// - buffer read index corrected (should fix occational distortions when streaming ends)
// - added handling of client disconnect and timeout during buffering
//
// V8 (13.08.2017)
// - added amp enable on GPIO15
// - moved STATUS_LED_MODES enum to a .h file because of compiler problems
//


#include "Arduino.h"
#include <ESP8266WiFi.h>
#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include "i2s.h"
#include "StatusLedModes.h"

extern "C" {
  #include "user_interface.h"
}

const char* ssid = "yourSSID";
const char* password = "yourPASSWORD";

const uint8_t staticIP[] = {0, 0, 0, 0};   // set to 0, 0, 0, 0 for DHCP
const uint8_t gwIP[] = {192, 168, 1, 1};
const uint8_t subnet[] = {255, 255, 255, 0};
const uint16_t port = 5522;

WiFiServer server(port);

// valid buffer Sizes are e.g. 0x1000, 0x2000, 0x4000
#define BUFFER_SIZE    0x4000
#define ONBOARD_LED    2
#define STATUS_LED     12
#define AMP_ENABLE_PIN 15

uint8_t buffer8b[BUFFER_SIZE];
uint16_t bufferPtrIn;
uint16_t bufferPtrOut;
uint32_t ultimeout;
uint8_t toggleOffOn = 0;
uint8_t OTA_update = 0;

enum RAMP_DIRECTIONS { DOWN, UP };
enum PWM_MODES { PWM_RESET, PWM_NORMAL, PWM_DIRECT };
volatile STATUS_LED_MODES statusLEDmode = WIFI_DISCONNECTED;

// **************************************************
// **************************************************
// **************************************************
void ICACHE_RAM_ATTR statusLED_ISR()
{
  switch (statusLEDmode)
  {
    default:                  // --
    case WIFI_DISCONNECTED:   timer0_write(ESP.getCycleCount() + (160000 * 250));       // om & off-time [ms]
                              break;
    case WIFI_CONNECTED:      if (toggleOffOn)
                                timer0_write(ESP.getCycleCount() + (160000 * 20));      // off-time [ms]
                              else
                                timer0_write(ESP.getCycleCount() + (160000 * 2000));    // on-time [ms]
                              break;
    case STREAMING:           timer0_write(ESP.getCycleCount() + (160000 * 1000));      // dummy timer
                              toggleOffOn = 1;
                              break;
  }

  if (toggleOffOn || OTA_update)
  {
    digitalWrite(STATUS_LED, LOW);
    //digitalWrite(ONBOARD_LED, LOW);
  } else {
    digitalWrite(STATUS_LED, HIGH);
    //digitalWrite(ONBOARD_LED, HIGH);
  }

  toggleOffOn ^= 0x01;
}

// **************************************************
// **************************************************
// **************************************************
void setStatusLEDmode(STATUS_LED_MODES new_statusLEDmode)
{
  if (statusLEDmode != new_statusLEDmode)
  {
    toggleOffOn = 0;
    statusLEDmode = new_statusLEDmode;

    // update timer immediately
    timer0_write(ESP.getCycleCount() + 160000);
  }
}

// **************************************************
// **************************************************
// **************************************************
void WiFiStart()
{
  // connect to wifi
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED)
    yield();

  setStatusLEDmode(WIFI_CONNECTED);

  // use static IP if specified - otherwise use DHCP
  if (*staticIP != '\0')
  {
    IPAddress ip(staticIP[0], staticIP[1], staticIP[2], staticIP[3]);
    IPAddress gateway(gwIP[0], gwIP[1], gwIP[2], gwIP[3]);
    IPAddress subnet(subnet[0], subnet[1], subnet[2], subnet[3]);
    WiFi.config(ip, gateway, subnet);
  }

  // start server
  server.begin();
}

// **************************************************
// **************************************************
// **************************************************
void setup()
{
  system_update_cpu_freq(SYS_CPU_160MHZ);

  pinMode(STATUS_LED, OUTPUT);
  digitalWrite(STATUS_LED, HIGH);

  timer0_isr_init();
  timer0_attachInterrupt(statusLED_ISR);
  timer0_write(ESP.getCycleCount() + 160000000); 
  interrupts();

  WiFi.mode(WIFI_STA);
  WiFiStart();

  i2s_begin();
  i2s_set_rate(96000);      // 33 ksps

  wifi_status_led_uninstall();

  pinMode(ONBOARD_LED, OUTPUT);
  digitalWrite(ONBOARD_LED, HIGH);

  pinMode(AMP_ENABLE_PIN, OUTPUT);
  digitalWrite(AMP_ENABLE_PIN, LOW);

  ArduinoOTA.onProgress([](unsigned int progress, unsigned int total)
  {
    OTA_update = 1;
    timer0_write(ESP.getCycleCount() + 160000);
  });
  ArduinoOTA.onError([](ota_error_t error)
  {
    OTA_update = 0;
    timer0_write(ESP.getCycleCount() + 160000);
  });
  ArduinoOTA.onEnd([]()
  {
    OTA_update = 0;
    timer0_write(ESP.getCycleCount() + 160000);
  });
  ArduinoOTA.setHostname("ESP8266_speaker");
  ArduinoOTA.begin();
}

// **************************************************
// **************************************************
// **************************************************
// ctrl = 0 : reset the PWM
// ctrl = 1 : normal playback
// ctrl = 2 : direct 8-bit value output
//
inline void doPWM(uint8_t ctrl, uint8_t value8b)
{
  static uint8_t dly = 0;
  static uint8_t sample = 0;
  static uint8_t dWordNr = 0;
  static uint32_t i2sbuf32b[4];
  static uint8_t prng;
  uint8_t shift;

  // reset
  if (ctrl == PWM_RESET)
  {
    dWordNr = 0;
    sample = 0;
    i2sbuf32b[0] = 0;
    i2sbuf32b[1] = 0;
    i2sbuf32b[2] = 0;
    i2sbuf32b[3] = 0;
    return;
  }

  // playback
  if (i2s_write_sample_nb(i2sbuf32b[dWordNr]))
  {
    dWordNr = (dWordNr + 1) & 0x03;

    // previous 4 DWORDS written?
    if (dWordNr == 0x00)
    {
      yield();

      // normal playback
      if (ctrl == PWM_NORMAL)
      {
        // new data in ring-buffer?
        if (bufferPtrOut != bufferPtrIn)
        {
          sample = buffer8b[bufferPtrOut];
          bufferPtrOut = (bufferPtrOut + 1) & (BUFFER_SIZE - 1);
        }
      } else if (ctrl == PWM_DIRECT)
      {
        // direct output mode
        sample = value8b;
      }

      shift = sample >> 1;

      if (!(sample & 0x01))
      {
        shift -= (prng & 0x01);     // subtract 0 or 1 from "shift" for dithering
        prng ^= 0x01;
      }

      yield();

      shift = 0x80 - shift;     // inverse shift
     
      if (shift < 0x20)
      {
        i2sbuf32b[0] = 0xFFFFFFFF >> shift;
        i2sbuf32b[1] = 0xFFFFFFFF;
        i2sbuf32b[2] = 0xFFFFFFFF;
        i2sbuf32b[3] = 0xFFFFFFFF;
      } else if (shift < 0x40)
      {
        i2sbuf32b[0] = 0x00000000;
        i2sbuf32b[1] = 0xFFFFFFFF >> (shift - 0x20);
        i2sbuf32b[2] = 0xFFFFFFFF;
        i2sbuf32b[3] = 0xFFFFFFFF;
      } else if (shift < 0x60)     
      {
        i2sbuf32b[0] = 0x00000000;
        i2sbuf32b[1] = 0x00000000;
        i2sbuf32b[2] = 0xFFFFFFFF >> (shift - 0x40);
        i2sbuf32b[3] = 0xFFFFFFFF;
      } else if (shift < 0x80)
      {
        i2sbuf32b[0] = 0x00000000;
        i2sbuf32b[1] = 0x00000000;
        i2sbuf32b[2] = 0x00000000;
        i2sbuf32b[3] = 0xFFFFFFFF >> (shift - 0x60);
      } else {
        i2sbuf32b[0] = 0x00000000;
        i2sbuf32b[1] = 0x00000000;
        i2sbuf32b[2] = 0x00000000;
        i2sbuf32b[3] = 0x00000000;
      }
    }
  }
}

// **************************************************
// **************************************************
// **************************************************
void rampPWM(uint8_t direction)
{
  uint8_t dl = 0;

  for (uint8_t value = 0; value < 0x80; value++)
  {
    while (dl++ < 250)
    {
      if (direction == UP)
        doPWM(PWM_DIRECT, value);
      else
        doPWM(PWM_DIRECT, 0x80 - value);
    }
    dl = 0;
  }
}

// **************************************************
// **************************************************
// **************************************************
inline void startStreaming(WiFiClient *client)
{
  uint8_t i;
  uint8_t dl;

  bufferPtrIn = 0;
  bufferPtrOut = 0;

  setStatusLEDmode(STREAMING);
  digitalWrite(AMP_ENABLE_PIN, HIGH);

  // ===================================================================================
  // fill buffer
 
  ultimeout = millis() + 500;
  do
  {
    // yield();
   
    if (client->available())
    {
      buffer8b[bufferPtrIn] = client->read();
      bufferPtrIn = (bufferPtrIn + 1) & (BUFFER_SIZE - 1);
      ultimeout = millis() + 500;
    }
  } while ((bufferPtrIn < (BUFFER_SIZE - 1)) && (client->connected()) && (millis() < ultimeout));

  if ((!client->connected()) || (millis() >= ultimeout))
    return;
 
  // ===================================================================================
  // ramp-up PWM to 50% (=Vspeaker/2) to avoid "blops" 

  rampPWM(UP);
 
  // ===================================================================================
  // start playback

  ultimeout = millis() + 500;
  do
  {
    doPWM(PWM_NORMAL,0);

    // new data in wifi rx-buffer?
    if (client->available())
    {
      // ring-buffer free?
      if (((bufferPtrIn + 1) & (BUFFER_SIZE - 1)) != bufferPtrOut)
      {
        buffer8b[bufferPtrIn] = client->read();
        bufferPtrIn = (bufferPtrIn + 1) & (BUFFER_SIZE - 1);
      }
    }

    if (bufferPtrOut != bufferPtrIn)
      ultimeout = millis() + 500;

  } while (client->available() || (millis() < ultimeout) || (bufferPtrOut != bufferPtrIn));

  // disabling the amplifier does not "plop", so it's better to do it before ramping down
  digitalWrite(AMP_ENABLE_PIN, LOW);

  // ===================================================================================
  // ramp-down PWM to 0% (=0Vdc) to avoid "blops"
  rampPWM(DOWN);

gloob

Hast du es denn schon selber probiert? Hast du versucht den Code zu verstehen?
Raspberry Pi 3 | miniCUL 433MHz | nanoCUL 868 MHz | nanoCUL 433 MHz | MySensors WLAN Gateway | LaCrosse WLAN Gateway | SignalESP 433 MHz | SignalESP 868 MHz | HM-MOD-UART WLAN Gateway | IR - 360 Grad WLAN Gateway

Tueftler1983

Ja habe es schon mal versucht bekomme dann aber nur fehlermeldungen. Weiß auch nicht wie ich das mit dem WLAN machen muss da es ja quasi 2 ports gibt. Für das display und den Lautsprecher.

Und nein so richtig verstehen tue ich es nicht

Beta-User

Bin bisher auch nicht so der Experte mit diesen Chips, aber hier ist beschrieben, wie man parallel einen web- und einen websocket-Server aufzieht:
https://tttapa.github.io/ESP8266/Chap14%20-%20WebSocket.html

Da ist auch etwas erklärt, wie man auf unterschiedliche Events auf Web-Ebene reagiert. Dürfte nicht wesentlich unterschiedlich sein, wenn man mehrere "andere" Ports hat (vorausgesetzt, der Chip geht deswegen nicht auf die Knie).

Aber ohne zu wissen und ansatzweise zu verstehen, was da abläuft, dürfte es schwierig werden.

Hast du wenigstens schon mal einfache C-Codes übereinandergeschoben, wie z.B. hier https://forum.mysensors.org/topic/2597/combining-mysensors-examples beschrieben?
Wenn nein, würde ich damit anfangen, damit kann man lernen, die diversen Fehlermeldungen (welche...) zu verstehen.

Just my2ct
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files