A library to operate the ESP8266
ESP8266_mdm.cpp@0:011fdf85bfc8, 2017-05-23 (annotated)
- Committer:
- epgmdm
- Date:
- Tue May 23 10:26:19 2017 +0000
- Revision:
- 0:011fdf85bfc8
A working version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
epgmdm | 0:011fdf85bfc8 | 1 | /** |
epgmdm | 0:011fdf85bfc8 | 2 | *@section DESCRIPTION |
epgmdm | 0:011fdf85bfc8 | 3 | * ESP8266_mdm Library |
epgmdm | 0:011fdf85bfc8 | 4 | * This sets up the ESP8266 as a server or client. |
epgmdm | 0:011fdf85bfc8 | 5 | * It detect \r\n sequence from the ESP8266 to chunk the response into lines. This then drives a state machine. |
epgmdm | 0:011fdf85bfc8 | 6 | *@section LICENSE |
epgmdm | 0:011fdf85bfc8 | 7 | * Copyright (c) 2016, Malcolm McCulloch |
epgmdm | 0:011fdf85bfc8 | 8 | * |
epgmdm | 0:011fdf85bfc8 | 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
epgmdm | 0:011fdf85bfc8 | 10 | * of this software and associated documentation files (the "Software"), to deal |
epgmdm | 0:011fdf85bfc8 | 11 | * in the Software without restriction, including without limitation the rights |
epgmdm | 0:011fdf85bfc8 | 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
epgmdm | 0:011fdf85bfc8 | 13 | * copies of the Software, and to permit persons to whom the Software is |
epgmdm | 0:011fdf85bfc8 | 14 | * furnished to do so, subject to the following conditions: |
epgmdm | 0:011fdf85bfc8 | 15 | * |
epgmdm | 0:011fdf85bfc8 | 16 | * The above copyright notice and this permission notice shall be included in |
epgmdm | 0:011fdf85bfc8 | 17 | * all copies or substantial portions of the Software. |
epgmdm | 0:011fdf85bfc8 | 18 | * |
epgmdm | 0:011fdf85bfc8 | 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
epgmdm | 0:011fdf85bfc8 | 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
epgmdm | 0:011fdf85bfc8 | 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
epgmdm | 0:011fdf85bfc8 | 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
epgmdm | 0:011fdf85bfc8 | 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
epgmdm | 0:011fdf85bfc8 | 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
epgmdm | 0:011fdf85bfc8 | 25 | * THE SOFTWARE. |
epgmdm | 0:011fdf85bfc8 | 26 | * @file "ESP8266_mdm.cpp" |
epgmdm | 0:011fdf85bfc8 | 27 | */ |
epgmdm | 0:011fdf85bfc8 | 28 | #include "ESP8266_mdm.h" |
epgmdm | 0:011fdf85bfc8 | 29 | |
epgmdm | 0:011fdf85bfc8 | 30 | // ********************* |
epgmdm | 0:011fdf85bfc8 | 31 | // * Protected variables: * |
epgmdm | 0:011fdf85bfc8 | 32 | // ********************* |
epgmdm | 0:011fdf85bfc8 | 33 | char* ESP8266_mdm::startCmnds[10]= { |
epgmdm | 0:011fdf85bfc8 | 34 | "AT", |
epgmdm | 0:011fdf85bfc8 | 35 | "AT", |
epgmdm | 0:011fdf85bfc8 | 36 | "AT", |
epgmdm | 0:011fdf85bfc8 | 37 | "AT+RST", |
epgmdm | 0:011fdf85bfc8 | 38 | "AT+CWMODE=1", |
epgmdm | 0:011fdf85bfc8 | 39 | "AT+CWJAP=\"epgmdm\",\"3F7540BC59\"", |
epgmdm | 0:011fdf85bfc8 | 40 | "AT+CIFSR", |
epgmdm | 0:011fdf85bfc8 | 41 | "AT+CIPMUX=1", |
epgmdm | 0:011fdf85bfc8 | 42 | "AT+CIPSERVER=1,8080", |
epgmdm | 0:011fdf85bfc8 | 43 | "AT+CIPSEND=0," |
epgmdm | 0:011fdf85bfc8 | 44 | }; |
epgmdm | 0:011fdf85bfc8 | 45 | char* ESP8266_mdm::startResp[10]= { |
epgmdm | 0:011fdf85bfc8 | 46 | "OK", |
epgmdm | 0:011fdf85bfc8 | 47 | "OK", |
epgmdm | 0:011fdf85bfc8 | 48 | "OK", |
epgmdm | 0:011fdf85bfc8 | 49 | "OK", |
epgmdm | 0:011fdf85bfc8 | 50 | "WIFI GOT IP", |
epgmdm | 0:011fdf85bfc8 | 51 | "OK", |
epgmdm | 0:011fdf85bfc8 | 52 | "OK", |
epgmdm | 0:011fdf85bfc8 | 53 | "+CIFSR:STAIP", |
epgmdm | 0:011fdf85bfc8 | 54 | "OK", |
epgmdm | 0:011fdf85bfc8 | 55 | "+IPD" |
epgmdm | 0:011fdf85bfc8 | 56 | }; |
epgmdm | 0:011fdf85bfc8 | 57 | |
epgmdm | 0:011fdf85bfc8 | 58 | int ESP8266_mdm::startMaxState=7; |
epgmdm | 0:011fdf85bfc8 | 59 | |
epgmdm | 0:011fdf85bfc8 | 60 | // ********************* |
epgmdm | 0:011fdf85bfc8 | 61 | // * Public functions: * |
epgmdm | 0:011fdf85bfc8 | 62 | // ********************* |
epgmdm | 0:011fdf85bfc8 | 63 | |
epgmdm | 0:011fdf85bfc8 | 64 | ESP8266_mdm::ESP8266_mdm(RawSerial *esp, int server, RawSerial *pc, PinName rstPn):esp(esp),server(server),pc(pc),rstPn(rstPn) |
epgmdm | 0:011fdf85bfc8 | 65 | { |
epgmdm | 0:011fdf85bfc8 | 66 | reset = new DigitalOut(rstPn,1); |
epgmdm | 0:011fdf85bfc8 | 67 | esp->baud(115200); |
epgmdm | 0:011fdf85bfc8 | 68 | esp->attach(callback(this, &ESP8266_mdm::dev_recv)); |
epgmdm | 0:011fdf85bfc8 | 69 | reset->write(0); |
epgmdm | 0:011fdf85bfc8 | 70 | // Init variables |
epgmdm | 0:011fdf85bfc8 | 71 | buffer=(char *)calloc(BUFF_SIZE,1); |
epgmdm | 0:011fdf85bfc8 | 72 | bufferPnt=0; |
epgmdm | 0:011fdf85bfc8 | 73 | ready=0; |
epgmdm | 0:011fdf85bfc8 | 74 | state=0; |
epgmdm | 0:011fdf85bfc8 | 75 | // Create hardware |
epgmdm | 0:011fdf85bfc8 | 76 | last = new Timer(); |
epgmdm | 0:011fdf85bfc8 | 77 | |
epgmdm | 0:011fdf85bfc8 | 78 | |
epgmdm | 0:011fdf85bfc8 | 79 | //esp->attach(this,&ESP8266_mdm::dev_recv, Serial::RxIrq); |
epgmdm | 0:011fdf85bfc8 | 80 | // |
epgmdm | 0:011fdf85bfc8 | 81 | // Setting up interrupts |
epgmdm | 0:011fdf85bfc8 | 82 | // |
epgmdm | 0:011fdf85bfc8 | 83 | INFO("Reseting"); |
epgmdm | 0:011fdf85bfc8 | 84 | wait(1.5); |
epgmdm | 0:011fdf85bfc8 | 85 | reset->write(1); |
epgmdm | 0:011fdf85bfc8 | 86 | pc->printf("Start up\n\r"); |
epgmdm | 0:011fdf85bfc8 | 87 | wait(2.0); |
epgmdm | 0:011fdf85bfc8 | 88 | esp->printf("AT\r\n"); |
epgmdm | 0:011fdf85bfc8 | 89 | |
epgmdm | 0:011fdf85bfc8 | 90 | INFO("Starting up v5"); |
epgmdm | 0:011fdf85bfc8 | 91 | |
epgmdm | 0:011fdf85bfc8 | 92 | // Startup |
epgmdm | 0:011fdf85bfc8 | 93 | command = startCmnds; |
epgmdm | 0:011fdf85bfc8 | 94 | responseRequired = startResp; |
epgmdm | 0:011fdf85bfc8 | 95 | maxState = startMaxState; |
epgmdm | 0:011fdf85bfc8 | 96 | timeOut=11; |
epgmdm | 0:011fdf85bfc8 | 97 | DBG("Start Do Loop"); |
epgmdm | 0:011fdf85bfc8 | 98 | doLoop(0); |
epgmdm | 0:011fdf85bfc8 | 99 | DBG ("DONE"); |
epgmdm | 0:011fdf85bfc8 | 100 | while(1); |
epgmdm | 0:011fdf85bfc8 | 101 | |
epgmdm | 0:011fdf85bfc8 | 102 | } |
epgmdm | 0:011fdf85bfc8 | 103 | |
epgmdm | 0:011fdf85bfc8 | 104 | // ********************* |
epgmdm | 0:011fdf85bfc8 | 105 | // * Protected functions: * |
epgmdm | 0:011fdf85bfc8 | 106 | // ********************* |
epgmdm | 0:011fdf85bfc8 | 107 | |
epgmdm | 0:011fdf85bfc8 | 108 | /** |
epgmdm | 0:011fdf85bfc8 | 109 | * Device has received a byte |
epgmdm | 0:011fdf85bfc8 | 110 | */ |
epgmdm | 0:011fdf85bfc8 | 111 | void ESP8266_mdm::dev_recv() |
epgmdm | 0:011fdf85bfc8 | 112 | { |
epgmdm | 0:011fdf85bfc8 | 113 | char c; |
epgmdm | 0:011fdf85bfc8 | 114 | if(bufferPnt==0) { |
epgmdm | 0:011fdf85bfc8 | 115 | memset(buffer,0,BUFF_SIZE); |
epgmdm | 0:011fdf85bfc8 | 116 | } |
epgmdm | 0:011fdf85bfc8 | 117 | while(esp->readable()) { |
epgmdm | 0:011fdf85bfc8 | 118 | c = (char)esp->getc(); |
epgmdm | 0:011fdf85bfc8 | 119 | //if (state>=maxState){ |
epgmdm | 0:011fdf85bfc8 | 120 | pc->putc(c); |
epgmdm | 0:011fdf85bfc8 | 121 | // } |
epgmdm | 0:011fdf85bfc8 | 122 | |
epgmdm | 0:011fdf85bfc8 | 123 | buffer[bufferPnt]=c; |
epgmdm | 0:011fdf85bfc8 | 124 | bufferPnt++; |
epgmdm | 0:011fdf85bfc8 | 125 | if (bufferPnt>1024) { |
epgmdm | 0:011fdf85bfc8 | 126 | ready=1; |
epgmdm | 0:011fdf85bfc8 | 127 | } |
epgmdm | 0:011fdf85bfc8 | 128 | if ((c==0x0a)||(c==0x0d)) { |
epgmdm | 0:011fdf85bfc8 | 129 | ready=1; |
epgmdm | 0:011fdf85bfc8 | 130 | } else if (c==0x0a) { |
epgmdm | 0:011fdf85bfc8 | 131 | if (bufferPnt>1) { |
epgmdm | 0:011fdf85bfc8 | 132 | if (buffer[bufferPnt -2]==0x0d) { |
epgmdm | 0:011fdf85bfc8 | 133 | ready=1; |
epgmdm | 0:011fdf85bfc8 | 134 | break; |
epgmdm | 0:011fdf85bfc8 | 135 | } |
epgmdm | 0:011fdf85bfc8 | 136 | } |
epgmdm | 0:011fdf85bfc8 | 137 | } |
epgmdm | 0:011fdf85bfc8 | 138 | if (!esp->readable()) { |
epgmdm | 0:011fdf85bfc8 | 139 | wait_us(100); |
epgmdm | 0:011fdf85bfc8 | 140 | } |
epgmdm | 0:011fdf85bfc8 | 141 | } |
epgmdm | 0:011fdf85bfc8 | 142 | } |
epgmdm | 0:011fdf85bfc8 | 143 | |
epgmdm | 0:011fdf85bfc8 | 144 | /** |
epgmdm | 0:011fdf85bfc8 | 145 | * Checks if pattern is in test. Returns 1 for true, 0 for no. -1 if busy. -2 ERROR |
epgmdm | 0:011fdf85bfc8 | 146 | * |
epgmdm | 0:011fdf85bfc8 | 147 | */ |
epgmdm | 0:011fdf85bfc8 | 148 | int ESP8266_mdm::OKResponse(char *test, const char *pattern) |
epgmdm | 0:011fdf85bfc8 | 149 | { |
epgmdm | 0:011fdf85bfc8 | 150 | |
epgmdm | 0:011fdf85bfc8 | 151 | char *p= strstr(test,pattern); |
epgmdm | 0:011fdf85bfc8 | 152 | if (p!=NULL) { |
epgmdm | 0:011fdf85bfc8 | 153 | return 1; |
epgmdm | 0:011fdf85bfc8 | 154 | } |
epgmdm | 0:011fdf85bfc8 | 155 | p= strstr(test,"busy"); |
epgmdm | 0:011fdf85bfc8 | 156 | if (p!=NULL) { |
epgmdm | 0:011fdf85bfc8 | 157 | return -1; |
epgmdm | 0:011fdf85bfc8 | 158 | } |
epgmdm | 0:011fdf85bfc8 | 159 | p= strstr(test,"ERROR"); |
epgmdm | 0:011fdf85bfc8 | 160 | if (p!=NULL) { |
epgmdm | 0:011fdf85bfc8 | 161 | return -2; |
epgmdm | 0:011fdf85bfc8 | 162 | } |
epgmdm | 0:011fdf85bfc8 | 163 | return 0; |
epgmdm | 0:011fdf85bfc8 | 164 | } |
epgmdm | 0:011fdf85bfc8 | 165 | /** |
epgmdm | 0:011fdf85bfc8 | 166 | * Loops through until state = maxState; |
epgmdm | 0:011fdf85bfc8 | 167 | */ |
epgmdm | 0:011fdf85bfc8 | 168 | void ESP8266_mdm::doLoop(int initState) |
epgmdm | 0:011fdf85bfc8 | 169 | { |
epgmdm | 0:011fdf85bfc8 | 170 | int resp; |
epgmdm | 0:011fdf85bfc8 | 171 | state = initState; |
epgmdm | 0:011fdf85bfc8 | 172 | // last->reset(); |
epgmdm | 0:011fdf85bfc8 | 173 | // last->start(); |
epgmdm | 0:011fdf85bfc8 | 174 | DBG("[%d] next %s : Waiting for %s",state,command[state],responseRequired[state]); |
epgmdm | 0:011fdf85bfc8 | 175 | |
epgmdm | 0:011fdf85bfc8 | 176 | while (1) { |
epgmdm | 0:011fdf85bfc8 | 177 | // printf(" {t %d}", *last); |
epgmdm | 0:011fdf85bfc8 | 178 | // Timeout code |
epgmdm | 0:011fdf85bfc8 | 179 | /* if ((*last)>timeOut){ |
epgmdm | 0:011fdf85bfc8 | 180 | WARN("Timeout on [%d] next %s : Waiting for %s",state,command[state],responseRequired[state]); |
epgmdm | 0:011fdf85bfc8 | 181 | last->reset(); |
epgmdm | 0:011fdf85bfc8 | 182 | if (state>0) { |
epgmdm | 0:011fdf85bfc8 | 183 | esp->printf("%s\r\n",command[state-1]); |
epgmdm | 0:011fdf85bfc8 | 184 | } else { |
epgmdm | 0:011fdf85bfc8 | 185 | esp->printf("%s\r\n",command[state]); |
epgmdm | 0:011fdf85bfc8 | 186 | } |
epgmdm | 0:011fdf85bfc8 | 187 | |
epgmdm | 0:011fdf85bfc8 | 188 | } |
epgmdm | 0:011fdf85bfc8 | 189 | */ |
epgmdm | 0:011fdf85bfc8 | 190 | if (ready) { |
epgmdm | 0:011fdf85bfc8 | 191 | ready=0; |
epgmdm | 0:011fdf85bfc8 | 192 | last->reset(); |
epgmdm | 0:011fdf85bfc8 | 193 | bufferPnt=0; |
epgmdm | 0:011fdf85bfc8 | 194 | printf("<%s>\r\n",buffer); |
epgmdm | 0:011fdf85bfc8 | 195 | DBG("[%d] next %s : Waiting for %s",state,command[state],responseRequired[state]); |
epgmdm | 0:011fdf85bfc8 | 196 | resp=OKResponse(buffer,responseRequired[state]); |
epgmdm | 0:011fdf85bfc8 | 197 | switch (resp) { |
epgmdm | 0:011fdf85bfc8 | 198 | case 0: { // not yet |
epgmdm | 0:011fdf85bfc8 | 199 | break; |
epgmdm | 0:011fdf85bfc8 | 200 | } |
epgmdm | 0:011fdf85bfc8 | 201 | case 1: { //Yes |
epgmdm | 0:011fdf85bfc8 | 202 | esp->printf("%s\r\n",command[state]); |
epgmdm | 0:011fdf85bfc8 | 203 | state++; |
epgmdm | 0:011fdf85bfc8 | 204 | break; |
epgmdm | 0:011fdf85bfc8 | 205 | } |
epgmdm | 0:011fdf85bfc8 | 206 | case -1: { // busy |
epgmdm | 0:011fdf85bfc8 | 207 | if (state>0) { |
epgmdm | 0:011fdf85bfc8 | 208 | esp->printf("%s\r\n",command[state-1]); |
epgmdm | 0:011fdf85bfc8 | 209 | } else { |
epgmdm | 0:011fdf85bfc8 | 210 | esp->printf("%s\r\n",command[state]); |
epgmdm | 0:011fdf85bfc8 | 211 | } |
epgmdm | 0:011fdf85bfc8 | 212 | break; |
epgmdm | 0:011fdf85bfc8 | 213 | } |
epgmdm | 0:011fdf85bfc8 | 214 | case -2: { //ERROR |
epgmdm | 0:011fdf85bfc8 | 215 | esp->printf("AT\r\n"); |
epgmdm | 0:011fdf85bfc8 | 216 | wait(1); |
epgmdm | 0:011fdf85bfc8 | 217 | if (state>0) { |
epgmdm | 0:011fdf85bfc8 | 218 | esp->printf("%s\r\n",command[state-1]); |
epgmdm | 0:011fdf85bfc8 | 219 | } else { |
epgmdm | 0:011fdf85bfc8 | 220 | esp->printf("%s\r\n",command[state]); |
epgmdm | 0:011fdf85bfc8 | 221 | } |
epgmdm | 0:011fdf85bfc8 | 222 | break; |
epgmdm | 0:011fdf85bfc8 | 223 | } |
epgmdm | 0:011fdf85bfc8 | 224 | } // switch |
epgmdm | 0:011fdf85bfc8 | 225 | } // if |
epgmdm | 0:011fdf85bfc8 | 226 | } // while |
epgmdm | 0:011fdf85bfc8 | 227 | last->stop(); |
epgmdm | 0:011fdf85bfc8 | 228 | } |