Advertisement
Guest User

http://www.etechpath.com

a guest
Jun 9th, 2018
283
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.37 KB | None | 0 0
  1.  
  2. // IP address for the ESP8266 is displayed on the scrolling display
  3. // after startup initialisation and connected to the WiFi network.
  4. //
  5. // Connections for ESP8266 hardware SPI are:
  6. // Vcc 3v3 LED matrices seem to work at 3.3V
  7. // GND GND GND
  8. // DIN D7 HSPID or HMOSI
  9. // CS or LD D8 HSPICS or HCS
  10. // CLK D5 CLK or HCLK
  11. //
  12.  
  13. #include <ESP8266WiFi.h>
  14. #include <MD_MAX72xx.h>
  15. #include <SPI.h>
  16.  
  17. #define PRINT_CALLBACK 0
  18. #define DEBUG 1
  19. #define LED_HEARTBEAT 0
  20.  
  21. #if DEBUG
  22. #define PRINT(s, v) { Serial.print(F(s)); Serial.print(v); }
  23. #define PRINTS(s) { Serial.print(F(s)); }
  24. #else
  25. #define PRINT(s, v)
  26. #define PRINTS(s)
  27. #endif
  28.  
  29.  
  30. #if LED_HEARTBEAT
  31. #define HB_LED D2
  32. #define HB_LED_TIME 500 // in milliseconds
  33. #endif
  34.  
  35. // Define the number of devices we have in the chain and the hardware interface
  36. // NOTE: These pin numbers will probably not work with your hardware and may
  37. // need to be adapted
  38. #define MAX_DEVICES 4
  39.  
  40. #define CLK_PIN D5 // or SCK
  41. #define DATA_PIN D7 // or MOSI
  42. #define CS_PIN D8 // or SS
  43.  
  44. // SPI hardware interface
  45. MD_MAX72XX mx = MD_MAX72XX(CS_PIN, MAX_DEVICES);
  46. // Arbitrary pins
  47. //MD_MAX72XX mx = MD_MAX72XX(DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
  48.  
  49. // WiFi login parameters - network name and password
  50. const char* ssid = "wifiname"; // edit your wifi SSID here
  51. const char* password = "wifipassword"; // edit your wifi password here
  52.  
  53. // WiFi Server object and parameters
  54. WiFiServer server(80);
  55.  
  56. // Global message buffers shared by Wifi and Scrolling functions
  57. const uint8_t MESG_SIZE = 255;
  58. const uint8_t CHAR_SPACING = 1;
  59. const uint8_t SCROLL_DELAY = 75;
  60.  
  61. char curMessage[MESG_SIZE];
  62. char newMessage[MESG_SIZE];
  63. bool newMessageAvailable = false;
  64.  
  65. char WebResponse[] = "HTTP/1.1 200 OK\nContent-Type: text/html\n\n";
  66.  
  67. char WebPage[] =
  68. "<!DOCTYPE html>" \
  69. "<html>" \
  70. "<head>" \
  71. "<title>eTechPath MAX7219 ESP8266</title>" \
  72. "<style>" \
  73. "html, body" \
  74. "{" \
  75. "width: 600px;" \
  76. "height: 400px;" \
  77. "margin: 0px;" \
  78. "border: 0px;" \
  79. "padding: 10px;" \
  80. "background-color: white;" \
  81. "}" \
  82. "#container " \
  83. "{" \
  84. "width: 100%;" \
  85. "height: 100%;" \
  86. "margin-left: 200px;" \
  87. "border: solid 2px;" \
  88. "padding: 10px;" \
  89. "background-color: #b3cbf2;" \
  90. "}" \
  91. "</style>"\
  92. "<script>" \
  93. "strLine = \"\";" \
  94. "function SendText()" \
  95. "{" \
  96. " nocache = \"/&nocache=\" + Math.random() * 1000000;" \
  97. " var request = new XMLHttpRequest();" \
  98. " strLine = \"&MSG=\" + document.getElementById(\"txt_form\").Message.value;" \
  99. " request.open(\"GET\", strLine + nocache, false);" \
  100. " request.send(null);" \
  101. "}" \
  102. "</script>" \
  103. "</head>" \
  104. "<body>" \
  105. "<div id=\"container\">"\
  106. "<H1><b>WiFi MAX7219 LED Matrix Display</b></H1>" \
  107. "<form id=\"txt_form\" name=\"frmText\">" \
  108. "<label>Msg:<input type=\"text\" name=\"Message\" maxlength=\"255\"></label><br><br>" \
  109. "</form>" \
  110. "<br>" \
  111. "<input type=\"submit\" value=\"Send Text\" onclick=\"SendText()\">" \
  112. "<p><b>Visit Us at</b></p>" \
  113. "<a href=\"http://www.eTechPath.com\">www.eTechPath.com</a>" \
  114. "</div>" \
  115. "</body>" \
  116. "</html>";
  117.  
  118. char *err2Str(wl_status_t code)
  119. {
  120. switch (code)
  121. {
  122. case WL_IDLE_STATUS: return("IDLE"); break; // WiFi is in process of changing between statuses
  123. case WL_NO_SSID_AVAIL: return("NO_SSID_AVAIL"); break; // case configured SSID cannot be reached
  124. case WL_CONNECTED: return("CONNECTED"); break; // successful connection is established
  125. case WL_CONNECT_FAILED: return("CONNECT_FAILED"); break; // password is incorrect
  126. case WL_DISCONNECTED: return("CONNECT_FAILED"); break; // module is not configured in station mode
  127. default: return("??");
  128. }
  129. }
  130.  
  131. uint8_t htoi(char c)
  132. {
  133. c = toupper(c);
  134. if ((c >= '0') && (c <= '9')) return(c - '0');
  135. if ((c >= 'A') && (c <= 'F')) return(c - 'A' + 0xa);
  136. return(0);
  137. }
  138.  
  139. boolean getText(char *szMesg, char *psz, uint8_t len)
  140. {
  141. boolean isValid = false; // text received flag
  142. char *pStart, *pEnd; // pointer to start and end of text
  143.  
  144. // get pointer to the beginning of the text
  145. pStart = strstr(szMesg, "/&MSG=");
  146.  
  147. if (pStart != NULL)
  148. {
  149. pStart += 6; // skip to start of data
  150. pEnd = strstr(pStart, "/&");
  151.  
  152. if (pEnd != NULL)
  153. {
  154. while (pStart != pEnd)
  155. {
  156. if ((*pStart == '%') && isdigit(*(pStart+1)))
  157. {
  158. // replace %xx hex code with the ASCII character
  159. char c = 0;
  160. pStart++;
  161. c += (htoi(*pStart++) << 4);
  162. c += htoi(*pStart++);
  163. *psz++ = c;
  164. }
  165. else
  166. *psz++ = *pStart++;
  167. }
  168.  
  169. *psz = '\0'; // terminate the string
  170. isValid = true;
  171. }
  172. }
  173.  
  174. return(isValid);
  175. }
  176.  
  177. void handleWiFi(void)
  178. {
  179. static enum { S_IDLE, S_WAIT_CONN, S_READ, S_EXTRACT, S_RESPONSE, S_DISCONN } state = S_IDLE;
  180. static char szBuf[1024];
  181. static uint16_t idxBuf = 0;
  182. static WiFiClient client;
  183. static uint32_t timeStart;
  184.  
  185. switch (state)
  186. {
  187. case S_IDLE: // initialise
  188. PRINTS("\nS_IDLE");
  189. idxBuf = 0;
  190. state = S_WAIT_CONN;
  191. break;
  192.  
  193. case S_WAIT_CONN: // waiting for connection
  194. {
  195. client = server.available();
  196. if (!client) break;
  197. if (!client.connected()) break;
  198.  
  199. #if DEBUG
  200. char szTxt[20];
  201. sprintf(szTxt, "%03d:%03d:%03d:%03d", client.remoteIP()[0], client.remoteIP()[1], client.remoteIP()[2], client.remoteIP()[3]);
  202. PRINT("\nNew client @ ", szTxt);
  203. #endif
  204.  
  205. timeStart = millis();
  206. state = S_READ;
  207. }
  208. break;
  209.  
  210. case S_READ: // get the first line of data
  211. PRINTS("\nS_READ");
  212. while (client.available())
  213. {
  214. char c = client.read();
  215. if ((c == '\r') || (c == '\n'))
  216. {
  217. szBuf[idxBuf] = '\0';
  218. client.flush();
  219. PRINT("\nRecv: ", szBuf);
  220. state = S_EXTRACT;
  221. }
  222. else
  223. szBuf[idxBuf++] = (char)c;
  224. }
  225. if (millis() - timeStart > 1000)
  226. {
  227. PRINTS("\nWait timeout");
  228. state = S_DISCONN;
  229. }
  230. break;
  231.  
  232.  
  233. case S_EXTRACT: // extract data
  234. PRINTS("\nS_EXTRACT");
  235. // Extract the string from the message if there is one
  236. newMessageAvailable = getText(szBuf, newMessage, MESG_SIZE);
  237. PRINT("\nNew Msg: ", newMessage);
  238. state = S_RESPONSE;
  239. break;
  240.  
  241. case S_RESPONSE: // send the response to the client
  242. PRINTS("\nS_RESPONSE");
  243. // Return the response to the client (web page)
  244. client.print(WebResponse);
  245. client.print(WebPage);
  246. state = S_DISCONN;
  247. break;
  248.  
  249. case S_DISCONN: // disconnect client
  250. PRINTS("\nS_DISCONN");
  251. client.flush();
  252. client.stop();
  253. state = S_IDLE;
  254. break;
  255.  
  256. default: state = S_IDLE;
  257. }
  258. }
  259.  
  260. void scrollDataSink(uint8_t dev, MD_MAX72XX::transformType_t t, uint8_t col)
  261. // Callback function for data that is being scrolled off the display
  262. {
  263. #if PRINT_CALLBACK
  264. Serial.print("\n cb ");
  265. Serial.print(dev);
  266. Serial.print(' ');
  267. Serial.print(t);
  268. Serial.print(' ');
  269. Serial.println(col);
  270. #endif
  271. }
  272.  
  273. uint8_t scrollDataSource(uint8_t dev, MD_MAX72XX::transformType_t t)
  274. // Callback function for data that is required for scrolling into the display
  275. {
  276. static enum { S_IDLE, S_NEXT_CHAR, S_SHOW_CHAR, S_SHOW_SPACE } state = S_IDLE;
  277. static char *p;
  278. static uint16_t curLen, showLen;
  279. static uint8_t cBuf[8];
  280. uint8_t colData = 0;
  281.  
  282. // finite state machine to control what we do on the callback
  283. switch (state)
  284. {
  285. case S_IDLE: // reset the message pointer and check for new message to load
  286. //PRINTS("\nS_IDLE");
  287. p = curMessage; // reset the pointer to start of message
  288. if (newMessageAvailable) // there is a new message waiting
  289. {
  290. strcpy(curMessage, newMessage); // copy it in
  291. newMessageAvailable = false;
  292. }
  293. state = S_NEXT_CHAR;
  294. break;
  295.  
  296. case S_NEXT_CHAR: // Load the next character from the font table
  297. //PRINTS("\nS_NEXT_CHAR");
  298. if (*p == '\0')
  299. state = S_IDLE;
  300. else
  301. {
  302. showLen = mx.getChar(*p++, sizeof(cBuf) / sizeof(cBuf[0]), cBuf);
  303. curLen = 0;
  304. state = S_SHOW_CHAR;
  305. }
  306. break;
  307.  
  308. case S_SHOW_CHAR: // display the next part of the character
  309. //PRINTS("\nS_SHOW_CHAR");
  310. colData = cBuf[curLen++];
  311. if (curLen < showLen)
  312. break;
  313.  
  314. // set up the inter character spacing
  315. showLen = (*p != '\0' ? CHAR_SPACING : (MAX_DEVICES*COL_SIZE)/2);
  316. curLen = 0;
  317. state = S_SHOW_SPACE;
  318. // fall through
  319.  
  320. case S_SHOW_SPACE: // display inter-character spacing (blank column)
  321. //PRINT("\nS_ICSPACE: ", curLen);
  322. //PRINT("/", showLen);
  323. curLen++;
  324. if (curLen == showLen)
  325. state = S_NEXT_CHAR;
  326. break;
  327.  
  328. default:
  329. state = S_IDLE;
  330. }
  331.  
  332. return(colData);
  333. }
  334.  
  335. void scrollText(void)
  336. {
  337. static uint32_t prevTime = 0;
  338.  
  339. // Is it time to scroll the text?
  340. if (millis() - prevTime >= SCROLL_DELAY)
  341. {
  342. mx.transform(MD_MAX72XX::TSL); // scroll along - the callback will load all the data
  343. prevTime = millis(); // starting point for next time
  344. }
  345. }
  346.  
  347. void setup()
  348. {
  349. #if DEBUG
  350. Serial.begin(115200);
  351. PRINTS("\n[MD_MAX72XX WiFi Message Display]\nType a message for the scrolling display from your internet browser");
  352. #endif
  353.  
  354. #if LED_HEARTBEAT
  355. pinMode(HB_LED, OUTPUT);
  356. digitalWrite(HB_LED, LOW);
  357. #endif
  358.  
  359. // Display initialisation
  360. mx.begin();
  361. mx.setShiftDataInCallback(scrollDataSource);
  362. mx.setShiftDataOutCallback(scrollDataSink);
  363. mx.control(MD_MAX72XX::INTENSITY, 0);
  364.  
  365. curMessage[0] = newMessage[0] = '\0';
  366.  
  367. // Connect to and initialise WiFi network
  368. PRINT("\nConnecting to ", ssid);
  369. WiFi.mode(WIFI_STA);
  370. WiFi.begin(ssid, password);
  371.  
  372. while (WiFi.status() != WL_CONNECTED)
  373. {
  374. PRINT("\n", err2Str(WiFi.status()));
  375. delay(500);
  376. }
  377. PRINTS("\nWiFi connected");
  378.  
  379. // Start the server
  380. PRINTS("\nServer started");
  381. // Set up first message as the IP address
  382. sprintf(curMessage, "%03d:%03d:%03d:%03d", WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], WiFi.localIP()[3]);
  383. PRINT("\nAssigned IP ", curMessage);
  384. IPAddress myAddress = WiFi.localIP();
  385. PRINT("\n", myAddress);
  386. server.begin();
  387. }
  388.  
  389. void loop()
  390. {
  391. #if LED_HEARTBEAT
  392. static uint32_t timeLast = 0;
  393.  
  394. if (millis() - timeLast >= HB_LED_TIME)
  395. {
  396. digitalWrite(HB_LED, digitalRead(HB_LED) == LOW ? HIGH : LOW);
  397. timeLast = millis();
  398. }
  399. #endif
  400.  
  401. handleWiFi();
  402. scrollText();
  403. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement