Simple Socket Server using PIC18F87J10
Posted: Fri Feb 05, 2016 12:14 pm
Hello, new here. Will tell you about a test project I am working on. This is a simple socket server that turns 8 LED's on and off on a Microchip PIC18F87J10 development board. I am using the CCS compiler. There is a terminal connected for debugging. It does work, but I am open to suggestions.
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.
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 '>'.
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.
Now, listen for a client request:
Handle Client parses out any needed data from the client request and acts on it accordingly.
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.
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.
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.
Code: Select all
// 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 '>'.
Code: Select all
// 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.
Code: Select all
// 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:
Code: Select all
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.
Code: Select all
// 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.
Code: Select all
// 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.