Monday, December 11, 2017

ESP8266 WIFI CHAT SERVER CLIENT

Useful for programmers and students

ESP8266 is a serial Wi-Fi module that means it uses serial communication port to interface with driver (PC Serial Port or Microcontrollers). It is easy to communicate with this module by using   Attention commands (AT Commands).

AT Commands are used to control modems.
Following commands are used to setup Wi-Fi server.
Configure ESP8266 as a client:    
  1. Finding Hotspot :  AT+CWLAP 
  1. Connecting to Hotspot :  AT+CWJAP="HOTSPOTNAME","PASSWORD"
  1. Disconnecting Hotspot : AT+CWQAP

Finding IP address of Module:

 Automatic (DHCP) IP Address
Mostly, Wi-Fi module get IP address automatically assigned. 
Using Command AT+CIFSR will give IP address assigned to module 
This IP can change every time to connect to hotspot depending of devices connected to hotspot and LAN to which hotspot is connected.

Manual Configuration of IP address (Static IP Address)

Set Static IP Address:  AT+CIPSTA="IP_ADDRESS","DEF_GATEWAY","SUBNET_MASK"
This IP  doesn't change. but if other device is using this IP, can cause IP address conflicts. Best way to avoid this is assign last end IP available by router. for e.g. 192.168.xxx.200 (255 is max).

MODES OF WIFI MODULE:
There are three wifi modes available.

  1. Station Mode
  2. Access Point (AP) mode
  3. Both
Command AT+CWMODE=? shows current wifi mode: 1=Station Mode (as a Client ) and is default mode, 2=AP mode (Accesspoint or Hotspot Mode), 3= Both (Sta mode and AP mode)
To set mode Use Command: AT+CWMODE=1 or  AT+CWMODE=2 or  AT+CWMODE=3
 PART-1: Hardware design and setting up as wifi server.

PIN OUT For ESP8266:

Here we are going to use only RXD and TXD pins for communication. Connect VCC and CH_PD pins to 3.3v (3V3) Supply and GND pin to ground . keep others unconnected.


Schematic of  Driver circuit. (Not Module)


Assembled PCB (With Module Inserted)


Connect module  to PC and Run Telnet Software (Windows Hyper Terminal).
Default Baud rate for Module is 115200 BPS. 8 bit data, 1 stop bit Parity None and Flow Control is none.

Module Power on:



If RED LED turned on then your power supply is OK.

Module Data Activity:



When there is data activity on module Blue LED will Blink.
When everything is OK, you will get response as follows:


Now Use Commands :
  1. Finding HotSpot :  AT+CWLAP 
  2. Connecting to HotSpot :  AT+CWJAP="HOTSPOTNAME","PASSWORD"
If connected successfully response will be as follows:
  


NOTE THAT I HAVE ENABLE ECHO MODE IN HYPER TERMINAL (AS I TYPED I GOT CHARACTER BACK TO DISPLAY). 

Now we are going to start server.

Type: 
  1. AT+CIPMUX=1
  2. AT+CIPSERVER=1,8080
Note: 8080 is port. if not specified then default port 333 is used.

You will get response as OK.

Here we are using esp8266 module as a client but connecting PC as a client and module as a server. 

Now everything is set. 

PART-2:

We will design PC Application to communicate with Wi-Fi Module.



CODE: C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;

namespace Wifi_Server_Client_Test
{
    public partial class Form1 : Form
    {
        Socket sck;
        EndPoint epLocal, epRemote;
        string receivedMessage;
        byte[] bytes = new byte[1024];
        private Thread demoThread;

        public Form1()
        {
            InitializeComponent();
            sck =  new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // get local IP
            txtHost.Text = GetLocalIP();
            txtHost.Enabled = false;
            btnStp.Enabled = false;
            btnCon.Enabled = true;
            btnSend.Enabled = false;
            //--------------------------
        }


        private void Form1_Load(object sender, EventArgs e)
        {


           
        }

        private string GetLocalIP()
        {
            IPHostEntry Host;
            Host = Dns.GetHostEntry(Dns.GetHostName());
            foreach(IPAddress ip in Host.AddressList)
            {if (ip.AddressFamily == AddressFamily.InterNetwork)
                    return ip.ToString();
            }
            return ("192.0.0.0");
        }


        private void MessageReceive(IAsyncResult aResult)
        {

            try
            {
                int size = sck.EndReceiveFrom(aResult, ref epRemote);
                if (size > 0)
                {
                    byte[] RecData = new byte[1024];
                    RecData = (byte[])aResult.AsyncState;
                    ASCIIEncoding eEncoding = new ASCIIEncoding();
                 receivedMessage = eEncoding.GetString(RecData);

                 this.demoThread = new Thread(new ThreadStart(this.ThreadProcSafe));
                 this.demoThread.Start();
                }
                byte[] buffer = new byte[1500];
                sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageReceive), buffer);
                //LISTEN ESP8266

            }
            catch (Exception exp)
            {
                //MessageBox.Show(exp.ToString());
            }
        }


        private void ThreadProcSafe()
        {
            this.SetText( receivedMessage);
        }

        delegate void SetTextCallback(string text);

        private void SetText(string text)
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.listMessage.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.listMessage.Items.Add("ESP8266 Said:" + text);
                receivedMessage=null;
                listMessage.SelectedIndex = listMessage.Items.Count - 1;
            }
        }

        private void Close_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void Minimise_Click(object sender, EventArgs e)
        {
            WindowState = FormWindowState.Minimized;
        }

        private void bunifuCustomTextbox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void btnCon_Click(object sender, EventArgs e)
        {
            //connecting to client
            try
            {
                //IPHostEntry Host;
                //Host = Dns.GetHostEntry(Dns.GetHostName());
                // Setup Socket
               // epLocal = new IPEndPoint(IPAddress.Parse(txtHost.Text),                 Convert.ToInt32(HostPort.Text));
               // sck.Bind(epLocal);
                epRemote = new IPEndPoint(IPAddress.Parse(txtClient.Text),     Convert.ToInt32(txtPort.Text));

              
                //connecting to client remote

                if (!sck.Connected)
                {
                    sck.Connect(epRemote);
                    listMessage.Items.Add("Succssfully Connected to: " + epRemote.ToString());
                    listMessage.SelectedIndex = listMessage.Items.Count - 1;
                    btnStp.Enabled = true;
                    btnCon.Enabled = false;
                    
                    btnSend.Enabled = true;
                    byte[] buffer = new byte[1500];
                    sck.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref epRemote, new AsyncCallback(MessageReceive), buffer);
                    btnCon.Text = "Connected";
                    txtClient.Enabled = false;
                    txtPort.Enabled = false;
                    listMessage.Focus();
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());

            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            //convert string message to  byte[]
            ASCIIEncoding aEncoding = new ASCIIEncoding();
            byte[] sendingMessage = new byte[1500];
            sendingMessage = aEncoding.GetBytes(txtMessage.Text);
            //sending encodded byte
            sck.Send(sendingMessage);
            //sending encodded byte
            listMessage.Items.Add("Me: " + txtMessage.Text);
            listMessage.SelectedIndex = listMessage.Items.Count - 1;
            txtMessage.Clear();
        }

        private void listMessage_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void btnStp_Click(object sender, EventArgs e)
        {
            sck.Shutdown(SocketShutdown.Both);
            sck.Disconnect(true);
           // sck.Close();
            listMessage.Items.Add("Disconnected");
            listMessage.SelectedIndex = listMessage.Items.Count - 1;
            btnCon.Text = "Connect";
            btnStp.Enabled = false;
            btnCon.Enabled = true;
            btnSend.Enabled = false;
            sck = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            txtClient.Enabled = true;
            txtPort.Enabled = true; 

        }


    }
}

RESULT:

Enter Wifi module IP and Port 8080 (Set when server is started on module).


SUCCESFULLY CONNECTED Message will be shown on message window and connect button will show Connected.
Wifi modul connected to PC comport (same pc or another pc) will receive some data showing ID with text "CONNECT".



Sending HI and Receiving HELLO:

Send HI from windows APPLICATION we designed.
To receive HELLO
USE COMMAND: AT+CIPSEND=0,5 ==> PressENTER wait for OK message
Note: in above command 0 is link ID and 5 id number of bytes (HELLO is five bytes)
Now TYPE HELLO
you will receive ACK message "SEND OK"







.......END.......


ESP8266 WIFI CHAT SERVER CLIENT

Useful for programmers and students ESP8266 is a serial Wi-Fi module that means it uses serial communication port to interface with driv...