// An IRC chat client for the ESP8266-12E "nodemcu" ESP8266MOD AI-Thinker WiFi module

// Uses the Arduino IDE with thie board manager URL http://arduino.esp8266.com/stable/package_esp8266com_index.json

// Forked from https://github.com/JhonControl/ESP8266_Client_IRC_terminal_Serial

#include <ESP8266WiFi.h>

const char* ssid = "my-ssid"; // Your WiFi SSID

const char* password = "my-wifi-password"; // Your WiFi password

const char* host = "chat.freenode.net"; // the IRC server

const char* nick = "esp8266-bot-"; // First part of our IRC nickname

const char* channel = "#esp8266"; // The IRC channel we will join

#define IRC_BUFSIZE 32

char from[IRC_BUFSIZE];

char type[IRC_BUFSIZE];

char to[IRC_BUFSIZE];

char inbuf[IRC_BUFSIZE];

char longbuf[512];

#define ESP8266_LED 16

WiFiClient client;

void setup() {

pinMode(ESP8266_LED, OUTPUT);

digitalWrite(ESP8266_LED, HIGH); // red led off

Serial.begin(115200);

delay(10);

// We start by connecting to a WiFi network

Serial.println();

Serial.println();

Serial.print("Connecting to ");

Serial.println(ssid);

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(500);

Serial.print(".");

}

Serial.println("");

Serial.println("WiFi connected");

Serial.println("IP address: ");

Serial.println(WiFi.localIP());

}

void loop()

{

if ( !client.connected() ) {

Serial.println("Connecting ...");

if (client.connect(host, 6667)) {

sprintf(longbuf, "Connected to %s", host);

Serial.println(longbuf);

delay(3000);

sprintf(longbuf, "USER %s * * :%s ESP8266\r", nick, nick);

client.println(longbuf);

delay(500);

sprintf(longbuf, "NICK %s%03d\r", nick, random(1, 999));

client.println(longbuf);

delay(500);

sprintf(longbuf, "JOIN %s\r", channel);

client.println(longbuf);

handle_irc_connection();

}

else {

// if you didn't get a connection to the server:

Serial.println("Not connected.");

delay(2000);

}

}

}

void handle_irc_connection() {

char c;

int inbufIndex, prefixLen;

inbufIndex = sprintf(longbuf, "PRIVMSG %s :", channel);

prefixLen = inbufIndex;

// if there are incoming bytes available

// from the server, read them and print them:

while (true) {

// pack received characters in the buffer

if (Serial.available()) {

c = Serial.read();

longbuf[inbufIndex] = c;

inbufIndex++;

longbuf[inbufIndex] = 0;

// if we have a line of serial data print it

if ( c == 0x0a ) {

if ( longbuf[prefixLen] != '/' ) {

Serial.printf("%s

", longbuf);

client.println(longbuf);

} else {

Serial.printf("%s

", longbuf + prefixLen + 1);

client.println(longbuf + prefixLen + 1);

}

inbufIndex = sprintf(longbuf, "PRIVMSG %s :", channel);

prefixLen = inbufIndex;

}

}

if (!client.connected()) {

return;

}

if (client.available()) {

c = client.read();

}

else {

continue;

}

digitalWrite(ESP8266_LED, LOW);

if (c == ':') {

memset(from, 0, sizeof(from));

memset(type, 0, sizeof(type));

memset(to, 0, sizeof(to));

read_until(' ', from);

read_until(' ', type);

read_until(' ', to);

if (strcmp(type, "PRIVMSG") == 0) {

print_nick(from);

ignore_until(':');

print_until('\r');

}

else {

ignore_until('\r');

}

digitalWrite(ESP8266_LED, HIGH);

}

// could be a PING request by the server.

else if (c == 'P') {

char buf[5];

memset(buf, 0, sizeof(buf));

buf[0] = c;

for (int i = 1; i < 4; i++) {

c = client.read();

buf[i] = c;

}

ignore_until('\r');

if (strcmp(buf, "PING") == 0) {

client.println("PONG\r");

//Serial.println("PING->PONG");

}

}

digitalWrite(ESP8266_LED, HIGH);

} // end while

}

void print_nick(char buffer[]) {

Serial.print("<");

for (int i = 0; i < IRC_BUFSIZE - 1; i++) {

if (buffer[i] == '!') {

break;

}

Serial.print(buffer[i]);

}

Serial.print(">");

}

int read_until(char abort_c, char buffer[]) {

int bytes_read = 0;

memset(buffer, 0, sizeof(buffer));

for (int i = 0; i < IRC_BUFSIZE - 1; i++) {

if (client.available()) {

char c = client.read();

bytes_read++;

if (c == abort_c) {

return bytes_read;

}

else if (c == '

') {

return bytes_read;

}

buffer[i] = c;

}

}

ignore_until(abort_c);

return bytes_read;

}

// reads characters from the connection until

// it hits the given character.

void ignore_until(char c) {

while (true) {

if (client.available()) {

char curr_c = client.read();

if (curr_c == c) {

return;

}

}

}

}

// reads characters from the connection until

// it hits the given character.

void print_until(char c) {

while (true) {

if (client.available()) {

char curr_c = client.read();

if (curr_c == c) {

Serial.println("");

return;

}

Serial.print(curr_c);

}

}