Skip to content
This repository was archived by the owner on Feb 4, 2023. It is now read-only.

Commit 1bd70ec

Browse files
authored
Add files via upload
1 parent 1ef95e5 commit 1bd70ec

File tree

1 file changed

+309
-0
lines changed

1 file changed

+309
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
/****************************************************************************************************************************
2+
Async_AdvancedWebServer_MemoryIssues_Send_CString.ino - Dead simple AsyncWebServer for STM32 LAN8720 or built-in LAN8742A Ethernet
3+
For Portenta_H7 (STM32H7) with Vision-Shield Ethernet
4+
Portenta_H7_AsyncWebServer is a library for the Portenta_H7 with with Vision-Shield Ethernet
5+
Based on and modified from ESPAsyncWebServer (https://github.com/me-no-dev/ESPAsyncWebServer)
6+
Built by Khoi Hoang https://github.com/khoih-prog/Portenta_H7_AsyncWebServer
7+
Licensed under GPLv3 license
8+
Copyright (c) 2015, Majenko Technologies
9+
All rights reserved.
10+
Redistribution and use in source and binary forms, with or without modification,
11+
are permitted provided that the following conditions are met:
12+
Redistributions of source code must retain the above copyright notice, this
13+
list of conditions and the following disclaimer.
14+
Redistributions in binary form must reproduce the above copyright notice, this
15+
list of conditions and the following disclaimer in the documentation and/or
16+
other materials provided with the distribution.
17+
Neither the name of Majenko Technologies nor the names of its
18+
contributors may be used to endorse or promote products derived from
19+
this software without specific prior written permission.
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
24+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
27+
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*****************************************************************************************************************************/
31+
32+
#if !( defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) )
33+
#error For Portenta_H7 only
34+
#endif
35+
36+
#define _PORTENTA_H7_ATCP_LOGLEVEL_ 1
37+
#define _PORTENTA_H7_AWS_LOGLEVEL_ 1
38+
39+
#define USE_ETHERNET_PORTENTA_H7 true
40+
41+
#include <Portenta_Ethernet.h>
42+
#include <Ethernet.h>
43+
#warning Using Portenta_Ethernet lib for Portenta_H7.
44+
45+
#include <Portenta_H7_AsyncWebServer.h>
46+
47+
// Enter a MAC address and IP address for your controller below.
48+
#define NUMBER_OF_MAC 20
49+
50+
byte mac[][NUMBER_OF_MAC] =
51+
{
52+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x01 },
53+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x02 },
54+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x03 },
55+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x04 },
56+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x05 },
57+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x06 },
58+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x07 },
59+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x08 },
60+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x09 },
61+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0A },
62+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0B },
63+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0C },
64+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0D },
65+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0E },
66+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x0F },
67+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x10 },
68+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x11 },
69+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x12 },
70+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x13 },
71+
{ 0xDE, 0xAD, 0xBE, 0xEF, 0x32, 0x14 },
72+
};
73+
// Select the IP address according to your local network
74+
IPAddress ip(192, 168, 2, 232);
75+
76+
AsyncWebServer server(80);
77+
78+
int reqCount = 0; // number of requests received
79+
80+
#define LED_OFF HIGH
81+
#define LED_ON LOW
82+
83+
84+
#define BUFFER_SIZE 768 // a little larger in case required for header shift (destructive send)
85+
char temp[BUFFER_SIZE];
86+
87+
void handleRoot(AsyncWebServerRequest *request)
88+
{
89+
digitalWrite(LED_BUILTIN, LED_ON);
90+
91+
int sec = millis() / 1000;
92+
int min = sec / 60;
93+
int hr = min / 60;
94+
int day = hr / 24;
95+
96+
snprintf(temp, BUFFER_SIZE - 1,
97+
"<html>\
98+
<head>\
99+
<meta http-equiv='refresh' content='5'/>\
100+
<title>AsyncWebServer-%s</title>\
101+
<style>\
102+
body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
103+
</style>\
104+
</head>\
105+
<body>\
106+
<h2>AsyncWebServer_Portenta_H7!</h2>\
107+
<h3>running on %s</h3>\
108+
<p>Uptime: %d d %02d:%02d:%02d</p>\
109+
<img src=\"/test.svg\" />\
110+
</body>\
111+
</html>", BOARD_NAME, BOARD_NAME, day, hr % 24, min % 60, sec % 60);
112+
113+
request->send(200, "text/html", temp, false);
114+
115+
digitalWrite(LED_BUILTIN, LED_OFF);
116+
}
117+
118+
void handleNotFound(AsyncWebServerRequest *request)
119+
{
120+
digitalWrite(LED_BUILTIN, LED_ON);
121+
String message = "File Not Found\n\n";
122+
123+
message += "URI: ";
124+
message += request->url();
125+
message += "\nMethod: ";
126+
message += (request->method() == HTTP_GET) ? "GET" : "POST";
127+
message += "\nArguments: ";
128+
message += request->args();
129+
message += "\n";
130+
131+
for (uint8_t i = 0; i < request->args(); i++)
132+
{
133+
message += " " + request->argName(i) + ": " + request->arg(i) + "\n";
134+
}
135+
136+
request->send(404, "text/plain", message);
137+
digitalWrite(LED_BUILTIN, LED_OFF);
138+
}
139+
140+
void PrintHeapData(String hIn){
141+
mbed_stats_heap_t heap_stats;
142+
143+
Serial.print("HEAP DATA - ");
144+
Serial.print(hIn);
145+
146+
mbed_stats_heap_get(&heap_stats);
147+
Serial.print(" Cur heap: ");
148+
Serial.print(heap_stats.current_size);
149+
Serial.print(" Res Size: ");
150+
Serial.print(heap_stats.reserved_size);
151+
Serial.print(" Max heap: ");
152+
Serial.println(heap_stats.max_size);
153+
}
154+
155+
char cStr[41000];
156+
157+
void drawGraph(AsyncWebServerRequest *request)
158+
{
159+
char temp[80];
160+
161+
//char * cStr = (char *)malloc(41000); // IF NO SDRAM available - use main RAM
162+
// make a little larger than required - can malloc, or create an external (cStr[41000]) variable that can be reused
163+
164+
if (cStr == NULL) {
165+
Serial.println("Unable top Allocate RAM");
166+
for(;;);
167+
}
168+
169+
cStr[0] = '\0';
170+
171+
strcat(cStr, "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" width=\"1810\" height=\"150\">\n");
172+
strcat(cStr, "<rect width=\"1810\" height=\"150\" fill=\"rgb(250, 230, 210)\" stroke-width=\"2\" stroke=\"rgb(0, 0, 0)\" />\n");
173+
strcat(cStr, "<g stroke=\"blue\">\n");
174+
int y = rand() % 130;
175+
176+
for (int x = 10; x < 5000; x += 10)
177+
{
178+
int y2 = rand() % 130;
179+
sprintf(temp, "<line x1=\"%d\" y1=\"%d\" x2=\"%d\" y2=\"%d\" stroke-width=\"2\" />\n", x, 140 - y, x + 10, 140 - y2);
180+
strcat(cStr, temp);
181+
y = y2;
182+
}
183+
184+
strcat(cStr, "</g>\n</svg>\n");
185+
186+
PrintHeapData("Pre Send");
187+
188+
Serial.print("Out String Length=");
189+
Serial.println(strlen(cStr));
190+
191+
request->send(200, "image/svg+xml", cStr, false);
192+
193+
//free(cStr);
194+
195+
PrintHeapData("Post Send");
196+
}
197+
198+
199+
void setup()
200+
{
201+
pinMode(LED_BUILTIN, OUTPUT);
202+
digitalWrite(LED_BUILTIN, LED_OFF);
203+
204+
Serial.begin(115200);
205+
while (!Serial && millis() < 5000);
206+
207+
delay(200);
208+
209+
Serial.print("\nStart Async_AdvancedWebServer_MemoryIssues_Send_CString on "); Serial.print(BOARD_NAME);
210+
Serial.print(" with "); Serial.println(SHIELD_TYPE);
211+
Serial.println(PORTENTA_H7_ASYNC_TCP_VERSION);
212+
Serial.println(PORTENTA_H7_ASYNC_WEBSERVER_VERSION);
213+
214+
///////////////////////////////////
215+
216+
// start the ethernet connection and the server
217+
// Use random mac
218+
uint16_t index = millis() % NUMBER_OF_MAC;
219+
220+
// Use Static IP
221+
//Ethernet.begin(mac[index], ip);
222+
// Use DHCP dynamic IP and random mac
223+
Ethernet.begin(mac[index]);
224+
225+
if (Ethernet.hardwareStatus() == EthernetNoHardware)
226+
{
227+
Serial.println("No Ethernet found. Stay here forever");
228+
229+
while (true)
230+
{
231+
delay(1); // do nothing, no point running without Ethernet hardware
232+
}
233+
}
234+
235+
if (Ethernet.linkStatus() == LinkOFF)
236+
{
237+
Serial.println("Not connected Ethernet cable");
238+
}
239+
240+
Serial.print(F("Using mac index = "));
241+
Serial.println(index);
242+
243+
Serial.print(F("Connected! IP address: "));
244+
Serial.println(Ethernet.localIP());
245+
246+
///////////////////////////////////
247+
248+
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request)
249+
{
250+
handleRoot(request);
251+
});
252+
253+
server.on("/test.svg", HTTP_GET, [](AsyncWebServerRequest * request)
254+
{
255+
drawGraph(request);
256+
});
257+
258+
server.on("/inline", [](AsyncWebServerRequest * request)
259+
{
260+
request->send(200, "text/plain", "This works as well");
261+
});
262+
263+
server.onNotFound(handleNotFound);
264+
265+
server.begin();
266+
267+
Serial.print(F("HTTP EthernetWebServer is @ IP : "));
268+
Serial.println(Ethernet.localIP());
269+
270+
271+
PrintHeapData("Pre Create Arduino String");
272+
273+
}
274+
275+
void heartBeatPrint()
276+
{
277+
static int num = 1;
278+
279+
Serial.print(F("."));
280+
281+
if (num == 80)
282+
{
283+
Serial.println();
284+
num = 1;
285+
}
286+
else if (num++ % 10 == 0)
287+
{
288+
Serial.print(F(" "));
289+
}
290+
}
291+
292+
void check_status()
293+
{
294+
static unsigned long checkstatus_timeout = 0;
295+
296+
#define STATUS_CHECK_INTERVAL 10000L
297+
298+
// Send status report every STATUS_REPORT_INTERVAL (60) seconds: we don't need to send updates frequently if there is no status change.
299+
if ((millis() > checkstatus_timeout) || (checkstatus_timeout == 0))
300+
{
301+
heartBeatPrint();
302+
checkstatus_timeout = millis() + STATUS_CHECK_INTERVAL;
303+
}
304+
}
305+
306+
void loop()
307+
{
308+
check_status();
309+
}

0 commit comments

Comments
 (0)