Want to run a simple web server on your TinyCLR2.0? Check out my toggle sample. It is very rudimentary, but it works. Tested using a FEZ feather.
using GHIElectronics.TinyCLR.Devices.Display;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Devices.I2c;
using GHIElectronics.TinyCLR.Devices.Network;
using GHIElectronics.TinyCLR.Devices.Spi;
using GHIElectronics.TinyCLR.Devices.Uart;
using GHIElectronics.TinyCLR.Drivers.Microchip.Winc15x0;
using GHIElectronics.TinyCLR.Drivers.SolomonSystech.SSD1306;
using GHIElectronics.TinyCLR.Pins;
using Prowler.Properties;
using System;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.Net;
using System.Net.Sockets;
using System.Resources;
using System.Text;
using System.Threading;
namespace Prowler
{
class Program
{
static string _address = "0.0.0.0";
static HttpListener webServer;
static Thread webWorkerThread;
static GpioPin led;
static void Main()
{
webServer = new HttpListener("http", 80);
webWorkerThread = new Thread(() =>
{
while (webServer.IsListening)
{
var context = webServer.GetContext();
ProcessInboundGetRequest(context);
}
});
var gpioController = GpioController.GetDefault();
led = gpioController.OpenPin(SC20100.GpioPin.PE11);
led.SetDriveMode(GpioPinDriveMode.Output);
SetupWiFiConnection(gpioController);
}
private static void SetupWiFiConnection(GpioController gpioController)
{
var enablePin = gpioController.OpenPin(GHIElectronics.TinyCLR.Pins.SC20100.GpioPin.PA8);
enablePin.SetDriveMode(GpioPinDriveMode.Output);
enablePin.Write(GpioPinValue.High);
var cs = gpioController.OpenPin(SC20100.GpioPin.PD15);
WiFiNetworkInterfaceSettings wifiSettings = new WiFiNetworkInterfaceSettings()
{
Ssid = "ssid",
Password = "password",
IsDhcpEnabled = true,
IsDynamicDnsEnabled = true,
TlsEntropy = new byte[] { 0, 1, 2, 3 }
};
var settings = new SpiConnectionSettings()
{
ChipSelectLine = cs,
ClockFrequency = 4000000,
Mode = SpiMode.Mode0,
ChipSelectType = SpiChipSelectType.Gpio,
ChipSelectHoldTime = TimeSpan.FromTicks(10),
ChipSelectSetupTime = TimeSpan.FromTicks(10)
};
SpiNetworkCommunicationInterfaceSettings netInterfaceSettings = new SpiNetworkCommunicationInterfaceSettings()
{
SpiApiName = SC20100.SpiBus.Spi3,
GpioApiName = SC20100.GpioPin.Id,
SpiSettings = settings,
InterruptPin = gpioController.OpenPin(SC20100.GpioPin.PB12),
InterruptEdge = GpioPinEdge.FallingEdge,
InterruptDriveMode = GpioPinDriveMode.InputPullUp,
ResetPin = gpioController.OpenPin(SC20100.GpioPin.PB13),
ResetActiveState = GpioPinValue.Low
};
var networkController = NetworkController.FromName("GHIElectronics.TinyCLR.NativeApis.ATWINC15xx.NetworkController");
networkController.SetInterfaceSettings(wifiSettings);
networkController.SetCommunicationInterfaceSettings(netInterfaceSettings);
networkController.SetAsDefaultController();
byte[] address = new byte[4];
networkController.NetworkAddressChanged += (NetworkController sender, NetworkAddressChangedEventArgs e) =>
{
var ipProperties = sender.GetIPProperties();
address = ipProperties.Address.GetAddressBytes();
if (address[0] > 0)
{
if (!webServer.IsListening)
{
webServer.Start();
webWorkerThread.Start();
}
}
else
{
if (webServer.IsListening)
{
webServer.Stop();
webWorkerThread.Abort();
}
}
_address = $"{address[0]}.{address[1]}.{address[2]}.{address[3]}";
Debug.WriteLine(_address);
};
// Starting a new thread for monitoring the WiFi
new Thread(() =>
{
while (enablePin.Read() == GpioPinValue.High)
{
try
{
//Try enabling WiFi interface
networkController.Enable();
//Sleep for 2sec to give ample time fr wifi to connect
Thread.Sleep(2000);
//Poll WiFi connection link every 5sec
while (networkController.GetLinkConnected())
{
Thread.Sleep(5000);
}
if (!networkController.GetLinkConnected())
networkController.Disable();
}
catch (Exception)
{
Debug.WriteLine("Unable to connect to AP");
Thread.Sleep(2000);
}
}
}).Start();
}
private static void ProcessInboundGetRequest(HttpListenerContext context)
{
try
{
switch (context.Request.HttpMethod.ToUpper())
{
case "POST":
switch (context.Request.RawUrl.ToUpper())
{
case "/":
led.Write(led.Read() == GpioPinValue.High ? GpioPinValue.Low : GpioPinValue.High);
context.Response.StatusCode = 200;
context.Response.ContentType = "application/json";
var buffer = Encoding.UTF8.GetBytes($"{{\"led\": {(led.Read() == GpioPinValue.High).ToString().ToLower()}}}");
context.Response.ContentLength64 = buffer.Length;
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
break;
default:
break;
}
break;
default:
switch (context.Request.RawUrl.ToUpper())
{
case "/":
var resource = Resources.GetString(Resources.StringResources.index);
context.Response.StatusCode = 200;
context.Response.ContentType = "text/html";
var buffer = Encoding.UTF8.GetBytes(resource);
context.Response.ContentLength64 = buffer.Length;
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
break;
default:
break;
}
break;
}
}
finally
{
context.Response.OutputStream.Close();
}
}
}
}
Create an index.html file and add it as a resource.then add this code.
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<!--<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z" crossorigin="anonymous">-->
<title>Hello, FEZ Web Server!</title>
</head>
<body>
<h1>Hello, FEZ Web Server</h1>
<div>
<form id="frmAction">
<div>
<label>
<input type="checkbox" name="led" id="led" readonly disabled />
Onboard LED
</label>
</div>
<p>
<button type="submit">
Change
</button>
</p>
</form>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<!--<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js" integrity="sha384-B4gt1jrGC7Jh4AgTPSdUtOBvfO8shuf57BaghqFfPlYxofvL8/KUEfYiJOMMV+rV" crossorigin="anonymous"></script>-->
<script type="text/javascript">
var led = document.getElementById('led');
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function (state) {
if (state.currentTarget.readyState == 4) {
var data = JSON.parse(state.currentTarget.responseText);
if (data.led) {
led.checked = true;
} else {
led.checked = false;
}
}
};
window.onload = function () {
var checked = false;
var data = {};
var form = document.getElementById('frmAction');
if (led) {
data[led.name] = false;
}
if (form) {
led.addEventListener('change', function (event) {
data[led.name] = led.checked;
});
form.addEventListener('submit', function (event) {
event.preventDefault();
ajax.open('POST', '', true);
ajax.setRequestHeader('content-type', 'applcation/json');
var json = JSON.stringify(data);
ajax.send(json)
});
}
};
</script>
</body>
</html>