====== Modulo matrix max 7219 ====== **CONEXIÓN** {{:personas:johnny:proyectos:max-7219module.png?600|}} {{:personas:johnny:proyectos:photo5141023261893700065.jpg?400|}} {{:personas:johnny:proyectos:photo5141023261893700066.jpg?600|}} **Code** Este código hace que el esp sirva una página web, donde se escribe un mensaje y se presenta en la pantalla #include #include #include #define PRINT_CALLBACK 0 #define DEBUG 0 #define LED_HEARTBEAT 0 #if DEBUG #define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); } #define PRINTS(s) { Serial.print(F(s)); } #else #define PRINT(s, v) #define PRINTS(s) #endif #if LED_HEARTBEAT #define HB_LED D2 #define HB_LED_TIME 500 // in milliseconds #endif // Define the number of devices we have in the chain and the hardware interface // NOTE: These pin numbers will probably not work with your hardware and may // need to be adapted #define HARDWARE_TYPE MD_MAX72XX::FC16_HW #define MAX_DEVICES 4 #define CLK_PIN D5 // or SCK #define DATA_PIN D7 // or MOSI #define CS_PIN D8 // or SS // SPI hardware interface MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES); // Arbitrary pins //MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES); // WiFi login parameters - network name and password const char* ssid = "name wifi"; const char* password = "clave wifi"; // WiFi Server object and parameters WiFiServer server(80); // Global message buffers shared by Wifi and Scrolling functions const uint8_t MESG_SIZE = 255; const uint8_t CHAR_SPACING = 1; const uint8_t SCROLL_DELAY = 75; char curMessage[MESG_SIZE]; char newMessage[MESG_SIZE]; bool newMessageAvailable = false; const char WebResponse[] = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n"; const char WebPage[] = "" \ "" \ "" \ "MYTECTUTOR ESP8266 AND MAX7219" \ ""\ "" \ "" \ "" \ "

ESP8266 and MAX7219 LED Matrix WiFi Control

" \ "
"\ "
" \ "
" \ "
" \ "
" \ "" \ "
" \ "" \ ""; const char *err2Str(wl_status_t code) { switch (code) { case WL_IDLE_STATUS: return("IDLE"); break; // WiFi is in process of changing between statuses case WL_NO_SSID_AVAIL: return("NO_SSID_AVAIL"); break; // case configured SSID cannot be reached case WL_CONNECTED: return("CONNECTED"); break; // successful connection is established case WL_CONNECT_FAILED: return("CONNECT_FAILED"); break; // password is incorrect case WL_DISCONNECTED: return("CONNECT_FAILED"); break; // module is not configured in station mode default: return("??"); } } uint8_t htoi(char c) { c = toupper(c); if ((c >= '0') && (c <= '9')) return(c - '0'); if ((c >= 'A') && (c <= 'F')) return(c - 'A' + 0xa); return(0); } boolean getText(char *szMesg, char *psz, uint8_t len) { boolean isValid = false; // text received flag char *pStart, *pEnd; // pointer to start and end of text // get pointer to the beginning of the text pStart = strstr(szMesg, "/&MSG="); if (pStart != NULL) { pStart += 6; // skip to start of data pEnd = strstr(pStart, "/&"); if (pEnd != NULL) { while (pStart != pEnd) { if ((*pStart == '%') && isdigit(*(pStart+1))) { // replace %xx hex code with the ASCII character char c = 0; pStart++; c += (htoi(*pStart++) << 4); c += htoi(*pStart++); *psz++ = c; } else *psz++ = *pStart++; } *psz = '\0'; // terminate the string isValid = true; } } return(isValid); } void handleWiFi(void) { static enum { S_IDLE, S_WAIT_CONN, S_READ, S_EXTRACT, S_RESPONSE, S_DISCONN } state = S_IDLE; static char szBuf[1024]; static uint16_t idxBuf = 0; static WiFiClient client; static uint32_t timeStart; switch (state) { case S_IDLE: // initialize PRINTS("\nS_IDLE"); idxBuf = 0; state = S_WAIT_CONN; break; case S_WAIT_CONN: // waiting for connection { client = server.available(); if (!client) break; if (!client.connected()) break; #if DEBUG char szTxt[20]; sprintf(szTxt, "%03d:%03d:%03d:%03d", client.remoteIP()[0], client.remoteIP()[1], client.remoteIP()[2], client.remoteIP()[3]); PRINT("\nNew client @ ", szTxt); #endif timeStart = millis(); state = S_READ; } break; case S_READ: // get the first line of data PRINTS("\nS_READ"); while (client.available()) { char c = client.read(); if ((c == '\r') || (c == '\n')) { szBuf[idxBuf] = '\0'; client.flush(); PRINT("\nRecv: ", szBuf); state = S_EXTRACT; } else szBuf[idxBuf++] = (char)c; } if (millis() - timeStart > 1000) { PRINTS("\nWait timeout"); state = S_DISCONN; } break; case S_EXTRACT: // extract data PRINTS("\nS_EXTRACT"); // Extract the string from the message if there is one newMessageAvailable = getText(szBuf, newMessage, MESG_SIZE); PRINT("\nNew Msg: ", newMessage); state = S_RESPONSE; break; case S_RESPONSE: // send the response to the client PRINTS("\nS_RESPONSE"); // Return the response to the client (web page) client.print(WebResponse); client.print(WebPage); state = S_DISCONN; break; case S_DISCONN: // disconnect client PRINTS("\nS_DISCONN"); client.flush(); client.stop(); state = S_IDLE; break; default: state = S_IDLE; } } void scrollDataSink(uint8_t dev, MD_MAX72XX::transformType_t t, uint8_t col) // Callback function for data that is being scrolled off the display { #if PRINT_CALLBACK Serial.print("\n cb "); Serial.print(dev); Serial.print(' '); Serial.print(t); Serial.print(' '); Serial.println(col); #endif } uint8_t scrollDataSource(uint8_t dev, MD_MAX72XX::transformType_t t) // Callback function for data that is required for scrolling into the display { static enum { S_IDLE, S_NEXT_CHAR, S_SHOW_CHAR, S_SHOW_SPACE } state = S_IDLE; static char *p; static uint16_t curLen, showLen; static uint8_t cBuf[8]; uint8_t colData = 0; // finite state machine to control what we do on the callback switch (state) { case S_IDLE: // reset the message pointer and check for new message to load PRINTS("\nS_IDLE"); p = curMessage; // reset the pointer to start of message if (newMessageAvailable) // there is a new message waiting { strcpy(curMessage, newMessage); // copy it in newMessageAvailable = false; } state = S_NEXT_CHAR; break; case S_NEXT_CHAR: // Load the next character from the font table PRINTS("\nS_NEXT_CHAR"); if (*p == '\0') state = S_IDLE; else { showLen = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf); curLen = 0; state = S_SHOW_CHAR; } break; case S_SHOW_CHAR: // display the next part of the character PRINTS("\nS_SHOW_CHAR"); colData = cBuf[curLen++]; if (curLen < showLen) break; // set up the inter character spacing showLen = (*p != '\0' ? CHAR_SPACING : (MAX_DEVICES*COL_SIZE)/2); curLen = 0; state = S_SHOW_SPACE; // fall through case S_SHOW_SPACE: // display inter-character spacing (blank column) PRINT("\nS_ICSPACE: ", curLen); PRINT("/", showLen); curLen++; if (curLen == showLen) state = S_NEXT_CHAR; break; default: state = S_IDLE; } return(colData); } void scrollText(void) { static uint32_t prevTime = 0; // Is it time to scroll the text? if (millis() - prevTime >= SCROLL_DELAY) { mx.transform(MD_MAX72XX::TSL); // scroll along - the callback will load all the data prevTime = millis(); // starting point for next time } } void setup() { #if DEBUG Serial.begin(115200); PRINTS("\n[MD_MAX72XX WiFi Message Display]\nType a message for the scrolling display from your internet browser"); #endif #if LED_HEARTBEAT pinMode(HB_LED, OUTPUT); digitalWrite(HB_LED, LOW); #endif // Display initialization mx.begin(); mx.setShiftDataInCallback(scrollDataSource); mx.setShiftDataOutCallback(scrollDataSink); curMessage[0] = newMessage[0] = '\0'; // Connect to and initialize WiFi network PRINT("\nConnecting to ", ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { PRINT("\n", err2Str(WiFi.status())); delay(500); } PRINTS("\nWiFi connected"); // Start the server server.begin(); PRINTS("\nServer started"); // Set up first message as the IP address sprintf(curMessage, "%03d:%03d:%03d:%03d", WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], WiFi.localIP()[3]); PRINT("\nAssigned IP ", curMessage); } void loop() { #if LED_HEARTBEAT static uint32_t timeLast = 0; if (millis() - timeLast >= HB_LED_TIME) { digitalWrite(HB_LED, digitalRead(HB_LED) == LOW ? HIGH : LOW); timeLast = millis(); } #endif handleWiFi(); scrollText(); }
Este otro código es tomado de internet del señor [[https://www.youtube.com/watch?v=F9w72sDUamY&ab_channel=HumbertoHiginio|humberto higinio]]. /* Programa: Wifi controlled LED matrix display Autor: Humberto Higinio Web: www.humbertohiginio.com Canal de Youtube: https://www.youtube.com/user/HHSolis Video Exclusivo para mi canal de Youtube Todos los Derechos Reservados - 2018 Código de Dominio Público Wemos D1 Mini o NodeMCU pines -> Matrix pines MOSI-D7-GPIO13 -> DIN CLK-D5-GPIO14 -> Clk GPIO0-D3 -> CS o LOAD */ #include #include #include #include #include #define SSID "XXXXXX" // insert your SSID #define PASS "XXXXXX" // insert your password // ******************* String form to sent to the client-browser ************************************ String form = "

" "

" "

Humberto Higinio Web Server

" "

Tipee su mensaje

" "
"; ESP8266WebServer server(80); // HTTP server will listen at port 80 long period; int offset=1,refresh=0; int pinCS = 0; // Attach CS to this pin, DIN to MOSI and CLK to SCK (cf http://arduino.cc/en/Reference/SPI ) int numberOfHorizontalDisplays = 8; int numberOfVerticalDisplays = 1; String decodedMsg; Max72xxPanel matrix = Max72xxPanel(pinCS, numberOfHorizontalDisplays, numberOfVerticalDisplays); String tape = "Arduino"; int wait = 20; // In milliseconds int spacer = 2; int width = 5 + spacer; // The font width is 5 pixels /* handles the messages coming from the webbrowser, restores a few special characters and constructs the strings that can be sent to the oled display */ void handle_msg() { matrix.fillScreen(LOW); server.send(200, "text/html", form); // Send same page so they can send another msg refresh=1; // Display msg on Oled String msg = server.arg("msg"); Serial.println(msg); decodedMsg = msg; // Restore special characters that are misformed to %char by the client browser decodedMsg.replace("+", " "); decodedMsg.replace("%21", "!"); decodedMsg.replace("%22", ""); decodedMsg.replace("%23", "#"); decodedMsg.replace("%24", "$"); decodedMsg.replace("%25", "%"); decodedMsg.replace("%26", "&"); decodedMsg.replace("%27", "'"); decodedMsg.replace("%28", "("); decodedMsg.replace("%29", ")"); decodedMsg.replace("%2A", "*"); decodedMsg.replace("%2B", "+"); decodedMsg.replace("%2C", ","); decodedMsg.replace("%2F", "/"); decodedMsg.replace("%3A", ":"); decodedMsg.replace("%3B", ";"); decodedMsg.replace("%3C", "<"); decodedMsg.replace("%3D", "="); decodedMsg.replace("%3E", ">"); decodedMsg.replace("%3F", "?"); decodedMsg.replace("%40", "@"); //Serial.println(decodedMsg); // print original string to monitor //Serial.println(' '); // new line in monitor } void setup(void) { matrix.setIntensity(10); // Use a value between 0 and 15 for brightness // Adjust to your own needs // matrix.setPosition(0, 1, 0); // The first display is at <0, 0> // matrix.setPosition(1, 0, 0); // The second display is at <1, 0> // Adjust to your own needs matrix.setPosition(0, 7, 0); // The first display is at <0, 7> matrix.setPosition(1, 6, 0); // The second display is at <1, 0> matrix.setPosition(2, 5, 0); // The third display is at <2, 0> matrix.setPosition(3, 4, 0); // And the last display is at <3, 0> matrix.setPosition(4, 3, 0); // The first display is at <0, 0> matrix.setPosition(5, 2, 0); // The second display is at <1, 0> matrix.setPosition(6, 1, 0); // The third display is at <2, 0> matrix.setPosition(7, 0, 0); // And the last display is at <3, 0> matrix.setRotation(0, 3); // The first display is position upside down matrix.setRotation(1, 3); // The first display is position upside down matrix.setRotation(2, 3); // The first display is position upside down matrix.setRotation(3, 3); // The first display is position upside down matrix.setRotation(4, 3); // The first display is position upside down matrix.setRotation(5, 3); // The first display is position upside down matrix.setRotation(6, 3); // The first display is position upside down matrix.setRotation(7, 3); // The first display is position upside down //ESP.wdtDisable(); // used to debug, disable wachdog timer, Serial.begin(115200); // full speed to monitor WiFi.begin(SSID, PASS); // Connect to WiFi network while (WiFi.status() != WL_CONNECTED) { // Wait for connection delay(500); Serial.print("."); } // Set up the endpoints for HTTP server, Endpoints can be written as inline functions: server.on("/", []() { server.send(200, "text/html", form); }); server.on("/msg", handle_msg); // And as regular external functions: server.begin(); // Start the server Serial.print("SSID : "); // prints SSID in monitor Serial.println(SSID); // to monitor char result[16]; sprintf(result, "%3d.%3d.%1d.%3d", WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], WiFi.localIP()[3]); Serial.println(); Serial.println(result); decodedMsg = result; Serial.println("WebServer ready! "); Serial.println(WiFi.localIP()); // Serial monitor prints localIP Serial.print(analogRead(A0)); } void loop(void) { for ( int i = 0 ; i < width * decodedMsg.length() + matrix.width() - 1 - spacer; i++ ) { server.handleClient(); // checks for incoming messages if (refresh==1) i=0; refresh=0; matrix.fillScreen(LOW); int letter = i / width; int x = (matrix.width() - 1) - i % width; int y = (matrix.height() - 8) / 2; // center the text vertically while ( x + width - spacer >= 0 && letter >= 0 ) { if ( letter < decodedMsg.length() ) { matrix.drawChar(x, y, decodedMsg[letter], HIGH, LOW, 1); } letter--; x -= width; } matrix.write(); // Send bitmap to display delay(wait); } }
* Otros enlaces: [[https://www.youtube.com/watch?v=CI9DBJKcKeU&ab_channel=G6EJD-David|video]] * [[https://github.com/G6EJD/ESP8266-Remote-Message-Board|github]]