1
1
#include " board.hpp"
2
2
#include " Drives.hpp"
3
3
#include " wifi_ap.hpp"
4
+ #include " library_extension.hpp"
5
+ #include < assert.h>
4
6
#include < ESP8266WebServer.h>
7
+ #include < atomic>
5
8
6
9
static ESP8266WebServer server (80 );
7
10
@@ -14,28 +17,58 @@ static struct
14
17
bool clockwise = true ;
15
18
} newTarget;
16
19
17
- constexpr auto htmlSource =
18
- " <!DOCTYPE html>\n "
19
- " <html lang=\" en\" >\n "
20
- " <head>\n "
21
- " <title>Robot Control</title>\n "
22
- " <meta charset=\" utf-8\" />\n "
23
- " <meta name=\" viewport\" content=\" width=device-width, initial-scale=1.6\" >\n "
24
- " </head>\n "
25
- " <body>\n "
26
- " <main>\n "
27
- " <form method=\" post\" action=\" /\" >\n "
28
- " <table>\n "
29
- " <tbody align=center valign=middle>\n "
30
- " <tr><td></td><td><button type=\" submit\" name=\" forwards\" value=\" 10\" title=\" +37,70mm\" >↑</button></td><td></td></tr>\n "
31
- " <tr><td><button type=\" submit\" name=\" left\" value=\" 5\" title=\" -86,4°\" >↺</button></td><td>🤖</td><td><button type=\" submit\" name=\" right\" value=\" 5\" title=\" +86,4°\" >↻</button></td></tr>\n "
32
- " <tr><td></td><td><button type=\" submit\" name=\" backwards\" value=\" 10\" title=\" -37,70mm\" >↓</button></td><td></td></tr>\n "
33
- " </tbody>\n "
34
- " </table>\n "
35
- " </form>\n "
36
- " </main>\n "
37
- " </body>\n "
38
- " </html>" ;
20
+ static constexpr std::size_t numberOfPositions = 50 ;
21
+ static Position positions[numberOfPositions] = { {0 ,0 } };
22
+ static std::size_t positionIndex = 0 ;
23
+
24
+ static constexpr char htmlSourceTemplate[] =
25
+ " <!DOCTYPE html>\n "
26
+ " <html lang=\" en\" >\n "
27
+ " <head>\n "
28
+ " <title>Robot Control</title>\n "
29
+ " <meta charset=\" utf-8\" />\n "
30
+ " <meta name=\" viewport\" content=\" width=device-width, initial-scale=1.6\" >\n "
31
+ " <meta http-equiv=\" refresh\" content=\" 5\" >\n "
32
+ " </head>\n "
33
+ " <body>\n "
34
+ " <main>\n "
35
+ " <form method=\" post\" action=\" /\" >\n "
36
+ " <table>\n "
37
+ " <tbody align=center valign=middle>\n "
38
+ " <tr><td></td><td><button type=\" submit\" name=\" forwards\" value=\" 10\" title=\" +37,70mm\" >↑</button></td><td></td></tr>\n "
39
+ " <tr><td><button type=\" submit\" name=\" left\" value=\" 5\" title=\" -86,4°\" >↺</button></td><td>🤖</td><td><button type=\" submit\" name=\" right\" value=\" 5\" title=\" +86,4°\" >↻</button></td></tr>\n "
40
+ " <tr><td></td><td><button type=\" submit\" name=\" backwards\" value=\" 10\" title=\" -37,70mm\" >↓</button></td><td></td></tr>\n "
41
+ " </tbody>\n "
42
+ " </table>\n "
43
+ " </form>\n "
44
+ " <img style=\" max-width:90vw; max-height:100vh;\" src=\" https://david.hebbeker.info/robot-control.php?positions=%s\" />\n "
45
+ " </main>\n "
46
+ " </body>\n "
47
+ " </html>" ;
48
+
49
+
50
+ constexpr std::size_t maxCharPerPosition = (5 +1 )*2 ; // !< when serializing the position, the number of characters maximum used per position
51
+ constexpr std::size_t positionsStringMaxLength = maxCharPerPosition*numberOfPositions+1 ;
52
+
53
+ static char htmlSourceBackBufferA[size(htmlSourceTemplate) + positionsStringMaxLength] = {0 };
54
+ static char htmlSourceBackBufferB[size(htmlSourceTemplate) + positionsStringMaxLength] = {0 };
55
+ static std::atomic<const char *> htmlSourceFrontBuffer (htmlSourceTemplate);
56
+
57
+ void updateHtmlSource ()
58
+ {
59
+ char * const backBuffer = (htmlSourceFrontBuffer.load () == htmlSourceBackBufferA) ? htmlSourceBackBufferB : htmlSourceBackBufferA;
60
+ char positionStringBuffer[positionsStringMaxLength] = { 0 };
61
+ std::size_t charPos = 0 ;
62
+ for (std::size_t i=0 ; i<=positionIndex; i++)
63
+ {
64
+ const int writtenCharacters = snprintf (&(positionStringBuffer[charPos]), maxCharPerPosition+1 , " %i;%i;" , positions[i].x , positions[i].y );
65
+ assert (writtenCharacters>0 );
66
+ charPos += writtenCharacters;
67
+ }
68
+ const int writtenCharacters = snprintf (backBuffer, size (htmlSourceBackBufferA), htmlSourceTemplate, positionStringBuffer);
69
+ assert (writtenCharacters>0 );
70
+ htmlSourceFrontBuffer = backBuffer;
71
+ }
39
72
40
73
static void handleRoot ()
41
74
{
@@ -68,7 +101,7 @@ static void handleRoot()
68
101
newTarget.isTargetNew = true ;
69
102
Serial.printf (" Got right by %u!\n " , newTarget.newRotate );
70
103
}
71
- server.send (200 , " text/html" , htmlSource );
104
+ server.send (200 , " text/html" , htmlSourceFrontBuffer. load () );
72
105
digitalWrite (board::debugLed, HIGH);
73
106
}
74
107
@@ -109,22 +142,33 @@ void setup()
109
142
server.begin ();
110
143
Serial.printf (" webserver has IP %s\n " , WiFi.localIP ().toString ().c_str ());
111
144
server.on (" /" , handleRoot);
145
+ updateHtmlSource ();
112
146
}
113
147
114
148
void loop ()
115
149
{
116
- server.handleClient ();
117
- // Serial.printf("left: \t%3u, right: \t%3u\n", drives::LeftDrive::counter, drives::RightDrive::counter);
118
- if (drives::LeftDrive::isIdle && drives::RightDrive::isIdle && newTarget.isTargetNew )
119
- {
120
- if (newTarget.newDrive !=0 )
121
- {
122
- drives::driveCounter (newTarget.newDrive , drives::cruiseSpeed, !newTarget.forward );
123
- }
124
- else if (newTarget.newRotate !=0 )
125
- {
126
- drives::rotateCounter (newTarget.newRotate , drives::cruiseSpeed, newTarget.clockwise );
127
- }
128
- newTarget = { };
129
- }
150
+ server.handleClient ();
151
+ // Serial.printf("left: \t%3u, right: \t%3u\n", drives::LeftDrive::counter, drives::RightDrive::counter);
152
+ if (drives::LeftDrive::isIdle && drives::RightDrive::isIdle)
153
+ {
154
+ const Position newPositionCandidate = drives::flushCurrentPosition ();
155
+ if (positions[positionIndex] != newPositionCandidate)
156
+ {
157
+ positions[++positionIndex] = newPositionCandidate;
158
+ positionIndex %= numberOfPositions;
159
+ updateHtmlSource ();
160
+ }
161
+ if (newTarget.isTargetNew )
162
+ {
163
+ if (newTarget.newDrive !=0 )
164
+ {
165
+ drives::driveCounter (newTarget.newDrive , drives::cruiseSpeed, !newTarget.forward );
166
+ }
167
+ else if (newTarget.newRotate !=0 )
168
+ {
169
+ drives::rotateCounter (newTarget.newRotate , drives::cruiseSpeed, newTarget.clockwise );
170
+ }
171
+ newTarget = { };
172
+ }
173
+ }
130
174
}
0 commit comments