iām back from taking my late afternoon nap as Mr @ Bill suggested, if he only knew how I still get paid while taking my naps :whistle:
please Jason replace the SimpleSerial.cs file with this one: and read the below code on how to properly use it to reply to client requestsā¦
SimpleSerial.cs
//Source for SimpleSerial taken from IggMoe's SimpleSerial Class https://www.ghielectronics.com/community/codeshare/entry/644
using System;
using System.Diagnostics;
using System.IO.Ports;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
namespace ESP8266Wifi
{
/// <summary>
/// Extends the .NET Micro Framework SerialPort Class with additional methods from the
/// Full .NET Framework SerialPort Class as well as other useful methods.
/// </summary>
public class SimpleSerial : SerialPort
{
private string _remainder;
internal SimpleSerial(string portName, int baudRate)
: base(portName, baudRate, Parity.None, 8, StopBits.One)
{
DiscardInBuffer();
DiscardOutBuffer();
}
/// <summary>
/// Stores any incomplete message that hasn't yet been terminated with a delimiter.
/// This will be concatenated with new data from the next DataReceived event to (hopefully) form a complete message.
/// This property is only populated after the Deserialize() method has been called.
/// </summary>
internal string Remainder
{
get { return _remainder; }
}
/// <summary>
/// Writes the specified string to the serial port.
/// </summary>
/// <param name="txt" />
internal void Write(string txt)
{
base.Write(Encoding.UTF8.GetBytes(txt), 0, txt.Length);
}
/// <summary>
/// Writes the specified string and the NewLine value to the output buffer.
/// </summary>
internal void WriteLine(string txt)
{
Write(txt + "\r\n");
}
/// <summary>
/// Reads all immediately available bytes, as binary data, in both the stream and the input buffer of the SerialPort
/// object.
/// </summary>
/// <returns>
/// System.Byte[]
/// </returns>
internal byte[] ReadExistingBinary()
{
var arraySize = BytesToRead;
var received = new byte[arraySize];
var count = Read(received, 0, arraySize);
// Debug.Print("*******Count:" + i + " Bytead=" + BytesToRead);
if (count > 0)
return received;
return new byte[] { 32 };
}
internal string ReadExisting()
{
var data= ReadExistingBinary();
var t = new char[data.Length];
for (int i = 0; i < data.Length; i++)
{
t[i] = (char)data[i];
}
try
{
return new string(t);
}
catch (Exception ex)
{
Debug.Print("Error" + ex.Message);
return String.Empty;//"Error\r\n";//
}
}
/// <summary>
/// Opens a new serial port connection.
/// </summary>
internal new void Open()
{
_remainder = String.Empty;
base.Open();
}
/// <summary>
/// Splits data from a serial buffer into separate messages, provided that each message is delimited by one or more
/// end-of-line character(s).
/// </summary>
/// <param name="delimiter">Character sequence that terminates a message line. Default is "\r\n".</param>
/// <param name="includeDelimiterInOutput"></param>
/// <returns>
/// An array of strings whose items correspond to individual messages, without the delimiters.
/// Only complete, properly terminated messages are included. Incomplete message fragments are saved to be appended to
/// the next received data.
/// If no complete messages are found in the serial buffer, the output array will be empty with Length = 0.
/// </returns>
internal string[] Deserialize(string delimiter = "\r\n", bool includeDelimiterInOutput = false, bool findfrw = false)
{
return ReadExisting().Split(delimiter.ToCharArray());
}
#endregion
}
}
and you would use it as follow:
//private const UInt16 _autoResetWaitTime = 20000;
public static AutoResetEvent SerialBlocking = null;
public static SimpleSerial MySerialPort;
public delegate void DataProcessorHandler(string rawdata, SimpleSerial port);//SerialPort
public static event DataProcessorHandler DataProcessor;
// The method which fires the Event
protected static void OnDataProcessor(string rawdata, SimpleSerial port)//SerialPort
{
// Check if there are any Subscribers
if (DataProcessor != null)
{
// Call the Event
DataProcessor(rawdata, port);
}
}
public static void NewProcess(string rawData, SimpleSerial sp)
{
switch (rawData)
{
case ">":
{
// Debug.Print("**************************Serve the page**************************");
//checkHttpRequest = false;
var strr = "<html><head><title>Welcome</title></head><body><p>Welcome " + "Pages Requested" +
"=" + _pageCounter
+ " Pages Served=" + ++_pagesServed + " RebootCounter=" + _rebootCounter +
" ChannelId=" + _channelId + ".</p></body></html>";
var headersr = "HTTP/1.1 200 OK\r\nContent-Type: " + "text/html" + "\r\nContent-Length: " +
strr.Length + "\r\nServer: " + "hostname" +
"\r\nCache-Control: no-cache\r\nConnection: keep-alive\r\n\r\n"; //
var cmd = Encoding.UTF8.GetBytes(headersr + strr);
lock (sp)
{
sp.Write(cmd, 0, cmd.Length);
}
}
break;
case "ready":
Debug.Print("Ready Found");
if (SerialBlocking != null) SerialBlocking.Set();
break;
case "OK":
// Debug.Print("OK FOUND");
if (SerialBlocking != null) SerialBlocking.Set();
break;
default:
{
if (rawData.Length > 5)
{
if (rawData.Substring(0, 4) == "+IPD")
{
// if (sentence.Length > 5)
// {
_channelId = Int32.Parse(rawData.Substring(5, 1));
// }
// else
// {
// Debug.Print("No channel found=" + sentence + "=" + sentence.IndexOf("+IPD") + "=" + sentence.Length);
// }
// var strr = Resources.GetString(Resources.StringResources.index);
var strr = "<html><head><title>Welcome</title></head><body><p>Welcome " +
"Pages Requested" + "=" + _pageCounter++
+ " Pages Served=" + _pagesServed + " RebootCounter=" + _rebootCounter +
" ChannelId=" + _channelId + ".</p></body></html>";
var headersr = "HTTP/1.1 200 OK\r\nContent-Type: " + "text/html" +
"\r\nContent-Length: " +
strr.Length + "\r\nServer: " + "hostname" +
"\r\nCache-Control: no-cache\r\nConnection: keep-alive\r\n\r\n"; //
//Thread.Sleep(1);
var cmd =
Encoding.UTF8.GetBytes("AT+CIPSEND=" + _channelId + "," +
(int)(headersr.Length + strr.Length) +
"\r\n");
//checkHttpRequest = true;
lock (sp)
{
sp.Write(cmd, 0, cmd.Length);
//Esp.Flush();
}
}
}
break;
}
}
// }
// }
// MyProcTimer.Stop();
}
public static void Main()
{
Debug.Print("Serial Port Count is: " + SerialPortCount);
DataProcessor += NewProcess;
SerialBlocking = new AutoResetEvent(false);
MySerialPort = new SimpleSerial("COM2", 115200);
MySerialPort.Open();
MySerialPort.DataReceived += MySerialPort_DataReceived;
new Thread(() => TestEsp(MySerialPort)).Start();
//keep the program running
Thread.Sleep(Timeout.Infinite);
}
private static void MySerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
if (e.EventType == SerialData.Chars)
{
// Cast the event source as a SimpleSerial object
var sp = sender as SimpleSerial;
// Extract an array of complete sentences from the port.
// Only complete, properly terminated sentences are included in this array.
if (sp != null)
{
var sentences = sp.Deserialize("");//this is important to not look for any delimiter must be an empty string we don't want it to terminate at \r\n to be able to catch the >
Thread.Sleep(1);//important to have this sleep or you will miss data from the serial port.
// Pull each sentence from the array and perform further processing
for (var index = 0; index < sentences.Length; index++)
{
//Debug.Print("Got:" + sentences[index]);
OnDataProcessor(sentences[index], sp);
}
}
}
}
public static void TestEsp(SerialPort Esp)
{
Debug.Print("TestEsp Started");
if (SerialBlocking == null) SerialBlocking = new AutoResetEvent(false);
// SerialBlocking.Reset();
var cmd = Encoding.UTF8.GetBytes("AT\r\n");
Esp.Write(cmd, 0, cmd.Length);
// Wait for the command to be completed
SerialBlocking.WaitOne();//_autoResetWaitTime, true);
//resets the module only during first boot.
if (!_softRest)
{
// Debug.Print("Reset");
_softRest = true;
// SerialBlocking.Reset();
cmd = Encoding.UTF8.GetBytes("AT+RST\r\n");
Esp.Write(cmd, 0, cmd.Length);
// Wait for the command to be completed
SerialBlocking.WaitOne(); //AT+RST Returns OK immediately
//wait for the reset to return ready
SerialBlocking.WaitOne();
}
// Debug.Print("Done Reset");
//Thread.Sleep(100);
// Query firmware version
//cmd = Encoding.UTF8.GetBytes("AT+GMR\r\n");
//Esp.Write(cmd, 0, cmd.Length);
//// Wait for the command to be completed
//SerialBlocking.WaitOne();
//Thread.Sleep(100);
// SerialBlocking.Reset();
// Set wifi mode 3 = Client and Soft AP
cmd = Encoding.UTF8.GetBytes("AT+CWMODE=3\r\n");
Esp.Write(cmd, 0, cmd.Length);
// Wait for the command to be completed
SerialBlocking.WaitOne();//_autoResetWaitTime, true);
// SerialBlocking.Reset();
// Set the Soft AP
cmd = Encoding.UTF8.GetBytes("AT+CWSAP=\"COOLAP2\",\"21030826\",5,0\r\n");
Esp.Write(cmd, 0, cmd.Length);
// Wait for the command to be completed
SerialBlocking.WaitOne();//_autoResetWaitTime, true);
// SerialBlocking.Reset();
// AT+CWLAP = List access points
cmd = Encoding.UTF8.GetBytes("AT+CWLAP\r\n");
Esp.Write(cmd, 0, cmd.Length);
// Wait for the command to be completed
SerialBlocking.WaitOne();//_autoResetWaitTime, true);
while (true)
{
//Thread.Sleep(100);
// SerialBlocking.Reset();
// Join an access point
cmd = Encoding.UTF8.GetBytes("AT+CWJAP=\"" + Apssid + "\",\"" + Password + "\"\r\n");
Esp.Write(cmd, 0, cmd.Length);
// Wait for the command to be completed
if (SerialBlocking.WaitOne())//_autoResetWaitTime, true))
break;
}
//Thread.Sleep(100);
// SerialBlocking.Reset();
// Show IP address
cmd = Encoding.UTF8.GetBytes("AT+CIFSR\r\n");
Esp.Write(cmd, 0, cmd.Length);
// Wait for the command to be completed
SerialBlocking.WaitOne();//_autoResetWaitTime, true);
// Thread.Sleep(100);
// SerialBlocking.Reset();
//change it to multiple mode connection required to start a server
cmd = Encoding.UTF8.GetBytes("AT+CIPMUX=1\r\n");
Esp.Write(cmd, 0, cmd.Length);
// Wait for the command to be completed
SerialBlocking.WaitOne();//_autoResetWaitTime, true);
//Thread.Sleep(100);
// SerialBlocking.Reset();
// Start the server port 80
cmd = Encoding.UTF8.GetBytes("AT+CIPSERVER=1,80\r\n");
Esp.Write(cmd, 0, cmd.Length);
// Wait for the command to be completed
SerialBlocking.WaitOne();//_autoResetWaitTime, true);
//Thread.Sleep(100);
// SerialBlocking.Reset();
//set timeout
cmd = Encoding.UTF8.GetBytes("AT+CIPSTO=20\r\n");
Esp.Write(cmd, 0, cmd.Length);
// Wait for the command to be completed
SerialBlocking.WaitOne();//_autoResetWaitTime, true);
_softRest = false;
}
Cheers,
Jay