Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
WROOM2.cpp@0:bc0e1a75926f, 2019-03-24 (annotated)
- Committer:
- titanium
- Date:
- Sun Mar 24 11:32:07 2019 +0000
- Revision:
- 0:bc0e1a75926f
- Child:
- 2:eaf4e7fa577e
Simple web server on LPC-1768 with WROOM2 WiFi module.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
titanium | 0:bc0e1a75926f | 1 | /* Simple embedded web server on LPC1768 with the WROOM2 WiFi module. |
titanium | 0:bc0e1a75926f | 2 | /* Copyright Toshihiro Matsui, IISEC, March, 2019 |
titanium | 0:bc0e1a75926f | 3 | /* Any form of use of this program is fully granted to anyone. |
titanium | 0:bc0e1a75926f | 4 | */ |
titanium | 0:bc0e1a75926f | 5 | |
titanium | 0:bc0e1a75926f | 6 | #include "mbed.h" |
titanium | 0:bc0e1a75926f | 7 | |
titanium | 0:bc0e1a75926f | 8 | #define MAXRECVBUF 2048 |
titanium | 0:bc0e1a75926f | 9 | #define WEBFILE "webfile.htm" |
titanium | 0:bc0e1a75926f | 10 | #define debug 0 |
titanium | 0:bc0e1a75926f | 11 | |
titanium | 0:bc0e1a75926f | 12 | class KBline |
titanium | 0:bc0e1a75926f | 13 | { char line[100]; |
titanium | 0:bc0e1a75926f | 14 | Serial *term; |
titanium | 0:bc0e1a75926f | 15 | |
titanium | 0:bc0e1a75926f | 16 | public: |
titanium | 0:bc0e1a75926f | 17 | int index, receiving; |
titanium | 0:bc0e1a75926f | 18 | private: |
titanium | 0:bc0e1a75926f | 19 | void serialirq() |
titanium | 0:bc0e1a75926f | 20 | { char ch; |
titanium | 0:bc0e1a75926f | 21 | if (term->readable()) { |
titanium | 0:bc0e1a75926f | 22 | ch=term->getc(); |
titanium | 0:bc0e1a75926f | 23 | switch(ch) { //simple line editing |
titanium | 0:bc0e1a75926f | 24 | case '\n': |
titanium | 0:bc0e1a75926f | 25 | case '\r': //LF and CR terminate reading |
titanium | 0:bc0e1a75926f | 26 | line[index++]=ch; line[index++]=0; |
titanium | 0:bc0e1a75926f | 27 | term->printf("\r\n"); |
titanium | 0:bc0e1a75926f | 28 | receiving=0; |
titanium | 0:bc0e1a75926f | 29 | break; |
titanium | 0:bc0e1a75926f | 30 | case 21: /* control-U cancels entire line*/ |
titanium | 0:bc0e1a75926f | 31 | term->printf("\n\r"); index=0; break; |
titanium | 0:bc0e1a75926f | 32 | case 0x08: |
titanium | 0:bc0e1a75926f | 33 | case 0x7f: /*BS and DEL delete the last character*/ |
titanium | 0:bc0e1a75926f | 34 | if (index>0) { index--; |
titanium | 0:bc0e1a75926f | 35 | term->putc(0x08); term->putc(0x20); term->putc(0x08);} |
titanium | 0:bc0e1a75926f | 36 | break; |
titanium | 0:bc0e1a75926f | 37 | default: |
titanium | 0:bc0e1a75926f | 38 | receiving=2; line[index++]=ch; term->putc(ch); break; |
titanium | 0:bc0e1a75926f | 39 | } } } |
titanium | 0:bc0e1a75926f | 40 | public: |
titanium | 0:bc0e1a75926f | 41 | KBline(Serial *pc) { term=pc; }; //constructor |
titanium | 0:bc0e1a75926f | 42 | void start_getline() { |
titanium | 0:bc0e1a75926f | 43 | index=0; receiving=1; |
titanium | 0:bc0e1a75926f | 44 | term->attach(this, &KBline::serialirq); } |
titanium | 0:bc0e1a75926f | 45 | char *getline() { |
titanium | 0:bc0e1a75926f | 46 | while (receiving) wait(0.1); |
titanium | 0:bc0e1a75926f | 47 | return(line); } |
titanium | 0:bc0e1a75926f | 48 | } ; |
titanium | 0:bc0e1a75926f | 49 | |
titanium | 0:bc0e1a75926f | 50 | |
titanium | 0:bc0e1a75926f | 51 | class Wroom //tried to extend Serial but failed ... |
titanium | 0:bc0e1a75926f | 52 | { |
titanium | 0:bc0e1a75926f | 53 | char sendbuf[256]; |
titanium | 0:bc0e1a75926f | 54 | char recvbuf[MAXRECVBUF]; /* 1024 */ |
titanium | 0:bc0e1a75926f | 55 | Serial *port, *pc; |
titanium | 0:bc0e1a75926f | 56 | /* Timer tm; */ |
titanium | 0:bc0e1a75926f | 57 | Timeout tmout; |
titanium | 0:bc0e1a75926f | 58 | int recvindex; |
titanium | 0:bc0e1a75926f | 59 | |
titanium | 0:bc0e1a75926f | 60 | public: |
titanium | 0:bc0e1a75926f | 61 | int receiving; |
titanium | 0:bc0e1a75926f | 62 | Wroom(Serial *p) { port=p;} ; |
titanium | 0:bc0e1a75926f | 63 | void printf(char *s) { port->printf(s); } |
titanium | 0:bc0e1a75926f | 64 | void recvtimeout() { |
titanium | 0:bc0e1a75926f | 65 | tmout.detach(); |
titanium | 0:bc0e1a75926f | 66 | recvbuf[recvindex++]=0; /*NULL at the end*/ |
titanium | 0:bc0e1a75926f | 67 | receiving=0; } /* receiving finished*/ |
titanium | 0:bc0e1a75926f | 68 | void prerecvtimeout() { |
titanium | 0:bc0e1a75926f | 69 | } |
titanium | 0:bc0e1a75926f | 70 | void recvirq() { |
titanium | 0:bc0e1a75926f | 71 | while (port->readable()) { |
titanium | 0:bc0e1a75926f | 72 | recvbuf[recvindex++]=port->getc(); |
titanium | 0:bc0e1a75926f | 73 | if (recvindex>=MAXRECVBUF) recvindex=0; } |
titanium | 0:bc0e1a75926f | 74 | receiving=2; |
titanium | 0:bc0e1a75926f | 75 | tmout.detach(); |
titanium | 0:bc0e1a75926f | 76 | tmout.attach(this, &Wroom::recvtimeout, 1.0); |
titanium | 0:bc0e1a75926f | 77 | } |
titanium | 0:bc0e1a75926f | 78 | void sendirq() { |
titanium | 0:bc0e1a75926f | 79 | } |
titanium | 0:bc0e1a75926f | 80 | void start_receiving() { |
titanium | 0:bc0e1a75926f | 81 | recvindex=0; receiving=1; |
titanium | 0:bc0e1a75926f | 82 | } |
titanium | 0:bc0e1a75926f | 83 | char *getreply() { |
titanium | 0:bc0e1a75926f | 84 | /* tmout.attach(this, &Wroom::recvtimeout, 7.0);*/ |
titanium | 0:bc0e1a75926f | 85 | while (receiving) { wait(0.1); } |
titanium | 0:bc0e1a75926f | 86 | return(recvbuf); } |
titanium | 0:bc0e1a75926f | 87 | char *getmessage() { //get http request |
titanium | 0:bc0e1a75926f | 88 | this->start_receiving(); |
titanium | 0:bc0e1a75926f | 89 | return(this->getreply()); } |
titanium | 0:bc0e1a75926f | 90 | |
titanium | 0:bc0e1a75926f | 91 | char *atcom(char *com) { |
titanium | 0:bc0e1a75926f | 92 | this->start_receiving(); |
titanium | 0:bc0e1a75926f | 93 | port->printf("%s\r\n", com); //pc->printf("atcom: %s\n", com); |
titanium | 0:bc0e1a75926f | 94 | return(this->getreply());} |
titanium | 0:bc0e1a75926f | 95 | char *atcom(char *com, int mode) { |
titanium | 0:bc0e1a75926f | 96 | sprintf(sendbuf, "%s=%d", com, mode); |
titanium | 0:bc0e1a75926f | 97 | return(this->atcom(sendbuf)); } |
titanium | 0:bc0e1a75926f | 98 | char *atcom(char *com, int param1, int param2) { |
titanium | 0:bc0e1a75926f | 99 | sprintf(sendbuf, "%s=%d,%d", com, param1, param2); |
titanium | 0:bc0e1a75926f | 100 | pc->printf("atcom2 -->%s\r\n", sendbuf); |
titanium | 0:bc0e1a75926f | 101 | return(this->atcom(sendbuf)); } |
titanium | 0:bc0e1a75926f | 102 | void configure(Serial *p) { //first set up of WROOM2 |
titanium | 0:bc0e1a75926f | 103 | pc=p; port->baud(115200); wait(2.0); |
titanium | 0:bc0e1a75926f | 104 | recvindex=0; port->attach(this, &Wroom::recvirq); |
titanium | 0:bc0e1a75926f | 105 | this->atcom("AT"); pc->printf("AT-->%s\n", this->getreply()); |
titanium | 0:bc0e1a75926f | 106 | this->atcom("ATE0"); //turn off echo |
titanium | 0:bc0e1a75926f | 107 | this->getreply(); pc->printf("ATE0-->%s\n", recvbuf); |
titanium | 0:bc0e1a75926f | 108 | this->atcom("AT+CWMODE", 1); //1=station, 2=AP, 3=both |
titanium | 0:bc0e1a75926f | 109 | this->getreply(); pc->printf("CWMODE-->%s\n", recvbuf); |
titanium | 0:bc0e1a75926f | 110 | this->atcom("AT+CIPMUX", 1); //0=single, 1=multi |
titanium | 0:bc0e1a75926f | 111 | this->getreply(); pc->printf("CIPMUX-->%s\n", recvbuf); |
titanium | 0:bc0e1a75926f | 112 | this->atcom("AT+CIPSTO", 120); |
titanium | 0:bc0e1a75926f | 113 | pc->printf("CIPSTO-->%s\n", this->getreply()); |
titanium | 0:bc0e1a75926f | 114 | this->atcom("AT+CWLAP"); //AP list |
titanium | 0:bc0e1a75926f | 115 | pc->printf("CWLAP-->%s\n", this->getreply()); |
titanium | 0:bc0e1a75926f | 116 | // connection to AP giving SSID and PASS is not programmed. |
titanium | 0:bc0e1a75926f | 117 | } |
titanium | 0:bc0e1a75926f | 118 | }; |
titanium | 0:bc0e1a75926f | 119 | |
titanium | 0:bc0e1a75926f | 120 | |
titanium | 0:bc0e1a75926f | 121 | DigitalOut myled(LED4), led1(LED1), led2(LED2), led3(LED3); |
titanium | 0:bc0e1a75926f | 122 | AnalogIn adc(p20); |
titanium | 0:bc0e1a75926f | 123 | Serial pc(USBTX, USBRX), ser_wroom(p28, p27); |
titanium | 0:bc0e1a75926f | 124 | KBline kbline(&pc); |
titanium | 0:bc0e1a75926f | 125 | Wroom wroom(&ser_wroom); |
titanium | 0:bc0e1a75926f | 126 | LocalFileSystem local("local"); |
titanium | 0:bc0e1a75926f | 127 | char webbuf[2000]; |
titanium | 0:bc0e1a75926f | 128 | |
titanium | 0:bc0e1a75926f | 129 | void strsubst(char *current, char *pat, char *subst, char *news) |
titanium | 0:bc0e1a75926f | 130 | //substitute pat in current with subst and generate in news |
titanium | 0:bc0e1a75926f | 131 | { char *s; |
titanium | 0:bc0e1a75926f | 132 | int i; |
titanium | 0:bc0e1a75926f | 133 | s=strstr(current, pat); |
titanium | 0:bc0e1a75926f | 134 | i=s-current; |
titanium | 0:bc0e1a75926f | 135 | if (s) { |
titanium | 0:bc0e1a75926f | 136 | strncpy(news, current, i); |
titanium | 0:bc0e1a75926f | 137 | strncpy(news+i, subst, strlen(subst)); |
titanium | 0:bc0e1a75926f | 138 | strncpy(news+i+strlen(subst), current+i+strlen(pat), strlen(current)-i-strlen(pat)); |
titanium | 0:bc0e1a75926f | 139 | news[strlen(current)-strlen(pat)+strlen(subst)]=NULL; |
titanium | 0:bc0e1a75926f | 140 | } |
titanium | 0:bc0e1a75926f | 141 | } |
titanium | 0:bc0e1a75926f | 142 | |
titanium | 0:bc0e1a75926f | 143 | char *readfile(char *fname, char *buf) |
titanium | 0:bc0e1a75926f | 144 | { int rdfd, filelen; |
titanium | 0:bc0e1a75926f | 145 | char fullfname[128]; |
titanium | 0:bc0e1a75926f | 146 | sprintf(fullfname, "/local/%s", fname); |
titanium | 0:bc0e1a75926f | 147 | rdfd=open(fullfname,O_RDONLY); |
titanium | 0:bc0e1a75926f | 148 | if (rdfd<0) { |
titanium | 0:bc0e1a75926f | 149 | pc.printf("%s not found\r\n", fullfname); |
titanium | 0:bc0e1a75926f | 150 | return(NULL); } |
titanium | 0:bc0e1a75926f | 151 | else { |
titanium | 0:bc0e1a75926f | 152 | filelen=read(rdfd, buf, 2000); |
titanium | 0:bc0e1a75926f | 153 | if (0<filelen && filelen<2000) buf[filelen]=0; |
titanium | 0:bc0e1a75926f | 154 | pc.printf("%d bytes read from %s\r\n", filelen, fullfname); |
titanium | 0:bc0e1a75926f | 155 | return(buf);} |
titanium | 0:bc0e1a75926f | 156 | } |
titanium | 0:bc0e1a75926f | 157 | |
titanium | 0:bc0e1a75926f | 158 | char *makepage() |
titanium | 0:bc0e1a75926f | 159 | { char altwebbuf[2000], adval[16]; |
titanium | 0:bc0e1a75926f | 160 | readfile(WEBFILE, webbuf); |
titanium | 0:bc0e1a75926f | 161 | if (led1) { |
titanium | 0:bc0e1a75926f | 162 | strsubst(webbuf, "$LED1ON$", "checked", altwebbuf); |
titanium | 0:bc0e1a75926f | 163 | strsubst(altwebbuf, "$LED1OFF$", " ", webbuf); } |
titanium | 0:bc0e1a75926f | 164 | else { |
titanium | 0:bc0e1a75926f | 165 | strsubst(webbuf, "$LED1OFF$", "checked", altwebbuf); |
titanium | 0:bc0e1a75926f | 166 | strsubst(altwebbuf, "$LED1ON$", " ", webbuf); } |
titanium | 0:bc0e1a75926f | 167 | if (led2) { |
titanium | 0:bc0e1a75926f | 168 | strsubst(webbuf, "$LED2ON$", "checked", altwebbuf); |
titanium | 0:bc0e1a75926f | 169 | strsubst(altwebbuf, "$LED2OFF$", " ", webbuf); } |
titanium | 0:bc0e1a75926f | 170 | else { |
titanium | 0:bc0e1a75926f | 171 | strsubst(webbuf, "$LED2OFF$", "checked", altwebbuf); |
titanium | 0:bc0e1a75926f | 172 | strsubst(altwebbuf, "$LED2ON$", " ", webbuf); } |
titanium | 0:bc0e1a75926f | 173 | sprintf(adval, "%6.3f", adc.read()); |
titanium | 0:bc0e1a75926f | 174 | strsubst(webbuf, "$ADVAL$", adval, altwebbuf); |
titanium | 0:bc0e1a75926f | 175 | strcpy(webbuf, altwebbuf); |
titanium | 0:bc0e1a75926f | 176 | return(webbuf); } |
titanium | 0:bc0e1a75926f | 177 | |
titanium | 0:bc0e1a75926f | 178 | void change_led(char *request) |
titanium | 0:bc0e1a75926f | 179 | { |
titanium | 0:bc0e1a75926f | 180 | if (strstr(request, "led1=1")) led1=1; |
titanium | 0:bc0e1a75926f | 181 | if (strstr(request, "led1=0")) led1=0; |
titanium | 0:bc0e1a75926f | 182 | if (strstr(request, "led2=1")) led2=1; |
titanium | 0:bc0e1a75926f | 183 | if (strstr(request, "led2=0")) led2=0; |
titanium | 0:bc0e1a75926f | 184 | } |
titanium | 0:bc0e1a75926f | 185 | |
titanium | 0:bc0e1a75926f | 186 | |
titanium | 0:bc0e1a75926f | 187 | |
titanium | 0:bc0e1a75926f | 188 | int main() { |
titanium | 0:bc0e1a75926f | 189 | char *line, *page; |
titanium | 0:bc0e1a75926f | 190 | pc.baud(9600); |
titanium | 0:bc0e1a75926f | 191 | pc.printf("\r\nWROOM AT commander.\r\n"); |
titanium | 0:bc0e1a75926f | 192 | wroom.configure(&pc); |
titanium | 0:bc0e1a75926f | 193 | pc.printf("\r\nWROOM is configured.\r\n"); |
titanium | 0:bc0e1a75926f | 194 | pc.printf(">"); |
titanium | 0:bc0e1a75926f | 195 | kbline.start_getline(); |
titanium | 0:bc0e1a75926f | 196 | wroom.start_receiving(); |
titanium | 0:bc0e1a75926f | 197 | while(1) { |
titanium | 0:bc0e1a75926f | 198 | myled=1; //prompt |
titanium | 0:bc0e1a75926f | 199 | if (kbline.receiving==0) { //kb input completed |
titanium | 0:bc0e1a75926f | 200 | line=kbline.getline(); /*pc.printf(line);*/ |
titanium | 0:bc0e1a75926f | 201 | myled=0; |
titanium | 0:bc0e1a75926f | 202 | if (line[0] == 'r') { //receive http request |
titanium | 0:bc0e1a75926f | 203 | line=wroom.getmessage(); |
titanium | 0:bc0e1a75926f | 204 | change_led(line); } |
titanium | 0:bc0e1a75926f | 205 | else if (*line == 's') { //send http message |
titanium | 0:bc0e1a75926f | 206 | page=makepage(); |
titanium | 0:bc0e1a75926f | 207 | wroom.atcom("AT+CIPSEND",0,strlen(page)); |
titanium | 0:bc0e1a75926f | 208 | pc.printf(wroom.getreply()); |
titanium | 0:bc0e1a75926f | 209 | wroom.atcom(page); //send html document |
titanium | 0:bc0e1a75926f | 210 | pc.printf(wroom.getreply()); |
titanium | 0:bc0e1a75926f | 211 | wroom.atcom("AT+CIPCLOSE", 0); |
titanium | 0:bc0e1a75926f | 212 | line=wroom.getreply(); } |
titanium | 0:bc0e1a75926f | 213 | else { //AT command |
titanium | 0:bc0e1a75926f | 214 | if(debug) pc.printf(line); |
titanium | 0:bc0e1a75926f | 215 | wroom.atcom(line); line=wroom.getreply(); } |
titanium | 0:bc0e1a75926f | 216 | pc.printf(line); |
titanium | 0:bc0e1a75926f | 217 | wroom.receiving=1; |
titanium | 0:bc0e1a75926f | 218 | pc.printf(">"); kbline.start_getline(); } |
titanium | 0:bc0e1a75926f | 219 | if (wroom.receiving==0) { |
titanium | 0:bc0e1a75926f | 220 | line=pc.printf(wroom.getreply()); |
titanium | 0:bc0e1a75926f | 221 | /* */ |
titanium | 0:bc0e1a75926f | 222 | wroom.start_receiving(); } |
titanium | 0:bc0e1a75926f | 223 | wait(0.1); |
titanium | 0:bc0e1a75926f | 224 | } |
titanium | 0:bc0e1a75926f | 225 | } ; |
titanium | 0:bc0e1a75926f | 226 |