First, the Put Command function. The ESP8266 is connected to UART2 and a terminal is on UART1. Both running at 9600. This just shoves commands out to the The ESP8266 then calls getReply.
// AT Put Command
// Send AT Commands to ESP8266
// ----------------------------------------------------------------------------
void at_putCommand(char * com) {
int8 i = 0;
fputs(com, UART1); // Print command to terminal
while (com[i] > 31) { // Send command to ESP8266
fputc(com[i], UART2);
delay_ms(6); // Need delay because of echo
i++;
}
delay_ms(6);
fputc('\r', UART2);
delay_ms(6);
fputc('\n', UART2);
at_getReplay();
}
Get Reply function. Listens for data coming from the ESP8266 and sends it to the terminal. Has a timeout so we don't get stuck. Also, returns quicker on a 'K' or '>'.
// AT Get Reply
// Get reply from ESP8266
// ----------------------------------------------------------------------------
void at_getReplay() {
int16 tout = 0;
char c;
while (!kbhit(UART2)) { // Check for no reply Timeout
delay_ms(1);
if (++tout > 3000) {
fputs("Timeout 1\n", UART1);
return;
}
}
tout = 0;
while (TRUE) {
if (kbhit(UART2)) {
c = fgetc(UART2);
if (c > 10) fputc(c, UART1); // Send to terminal, Ignore NL
if (c == 'K') tout = 3800; // 'OK'
if (c == '>') return; // Send prompt
} else delay_us(100);
if (++tout > 4000) { // Timeout
fputc('\n', UART1);
return;
}
}
}
Using the two functions above we can now set up the ESP8266 (And experiment with the settings.) Here I am setting things up for a socket server.
// AT Setup
// ----------------------------------------------------------------------------
void at_setup() {
at_putCommand((char*)"AT+GMR");
at_putCommand((char*)"AT+CWMODE=2"); // 2=Access Point
at_putCommand((char*)"AT+CWSAP=\"ESP8266\",\"12345678\",1,3"); // Set up access point
at_putCommand((char*)"AT+CIPAP=\"192.168.4.4\""); // Set IP Address ???
at_putCommand((char*)"AT+CIPMODE=0"); // 1=Transparent mode // 0
at_putCommand((char*)"AT+CIPMUX=1"); // 1=Multiple connections // 1
at_putCommand((char*)"AT+CIFSR"); // Show IP Address
at_putCommand((char*)"AT+CIPSERVER=1,222"); // Server Mode, Port
at_putCommand((char*)"AT+CIPSTO=2"); // Timeout Seconds
fputs("Setup complete\n", UART1);
}
Now, listen for a client request:
void main(void) {
while (TRUE) { // Wait for client request
if (kbhit(UART2)) at_handleClient(); // Client request
}
}
Handle Client parses out any needed data from the client request and acts on it accordingly.
// AT Handle Client
// ----------------------------------------------------------------------------
void at_handleClient() {
int16 tout = 0;
char c, req[80], leds[9], *p;
int8 i=0;
while (TRUE) { // Get client request
while (kbhit(UART2)) {
c = fgetc(UART2);
if (c > 10 && i < 80) req[i++] = c; // Save first 80 chars in req
}
delay_ms(1);
if (++tout > 1000) break;
}
req[i] = 0;
fputs(req, UART1); // Send client request to terminal
if (strstr(req, (char*)"/led") != null) { // '/led?v=0'
p = strstr(req, (char*)"?v="); // Find pointer
if (p == null) strcpy(leds, "00000000"); // If null use 00000000
else strncpy(leds, p+3, 8); // else use value
setLed(leds); // Turn LED's on/off
at_write((char*)"HTTP/1.0 200 OK\n\n"); // Any way to make this faster?
sprintf(req, "<html><body><h1>LED %s </h1><hr>\n", leds);
at_write(req);
at_write((char*)"<form id='leds' action='led' method='get'>\n");
sprintf(req, "<input type='text' name='v' size='8' value='%s'>\n", leds);
at_write(req);
at_write((char*)"<input type='submit' value='Submit'>\n");
at_write((char*)"</form>\n");
at_write((char*)"</body></html>\n");
at_putCommand((char*)"AT+CIPCLOSE");
}
}
The above uses this to send data out the socket. This way I can have the PIC find the buffer length and take care of the overhead for me. It is slower than I would like, but at least it works.
// AT Write
// ----------------------------------------------------------------------------
void at_write(char * s) {
int8 i, length;
char cb[80];
length = strlen(s);
sprintf(cb, "AT+CIPSEND=0,%u", length);
at_putCommand(cb);
for (i=0; i<length; i++) {
fputc(s[i], UART2);
delay_us(100);
}
at_getReplay();
}
That is pretty much it. Pretty simple for what it does I think. From here I can create all sorts of remote control devices. Hopefully someone can find this helpful.