Turning your M5Core2 into a nanoFramework based web server

Like most of my posts regarding nanoFramework and the M5Core2, I owe a debt to those who created this stuff and I’m really just going through some of the samples etc. Trying them out and documenting my findings. This post is no different, it’s based on the Welcome to the .NET nanoFramework WebServer repository

Add the NuGet package nanoFramework.WebServer to your nanoFramework project.

You’ll need to also include code to connect to your WiFi, so checkout my post on that subject – Wifi using nanoFramework on the M5Core2.

Assuming you’ve connected to your WiFi, we can set up a WebServer like this

using var server = new WebServer(80, HttpProtocol.Http, new[] { typeof(PowerController) });
server.Start();

Thread.Sleep(Timeout.Infinite);

The first line supplies an array of controllers, so you can have multiple controllers for your different endpoints. In this case we’ve just got the single controller PowerController. This is a simple class that includes RouteAtrribute and MethodAttribute adorned methods to acts as routes/endpoints.

Let’s look at the PowerController, which just returns some M5Core2.Power values when accessed via http://m5core2_ip_address/power.

public class PowerController
{
   [Route("power")]
   [Method("GET")]
   public void PowerRoute(WebServerEventArgs e)
   {
      var power = M5Core2.Power;
           
      var sb = new StringBuilder();
      sb.AppendLine("Power:");
      sb.AppendLine($"  Adc Frequency: {power.AdcFrequency}");
      sb.AppendLine($"  Adc Pin Current: {power.AdcPinCurrent}");
      sb.AppendLine($"  Adc Pin Current Setting: {power.AdcPinCurrentSetting}");
      sb.AppendLine($"  Adc Pin Enabled: {power.AdcPinEnabled}");
      sb.AppendLine($"  Batt. Temp. Monitor: {power.BatteryTemperatureMonitoring}");
      sb.AppendLine($"  Charging Current: {power.ChargingCurrent}");
      sb.AppendLine($"  Charging Stop Threshold: {power.ChargingStopThreshold}");
      sb.AppendLine($"  Charging Voltage: {power.ChargingVoltage}");
      sb.AppendLine($"  Dc Dc1 Voltage: {power.DcDc1Voltage.Millivolts} mV");
      sb.AppendLine($"  Dc Dc2 Voltage: {power.DcDc2Voltage.Millivolts} mV");
      sb.AppendLine($"  Dc Dc3 Voltage: {power.DcDc3Voltage.Millivolts} mV");
      sb.AppendLine($"  EXTEN Enable: {power.EXTENEnable}");
      sb.AppendLine($"  VOff Voltage: {power.VoffVoltage}");
      sb.AppendLine($"  Gpio0 Behavior: {power.Gpio0Behavior}");
      sb.AppendLine($"  Gpio0 Value: {power.Gpio0Value}");

      e.Context.Response.ContentType = "text/plain";
      WebServer.OutPutStream(e.Context.Response, sb.ToString());
}

As you can see from the last line of code, we send the response back with our payload, the string of power information.

We can also return HTTP codes using

WebServer.OutputHttpCode(e.Context.Response, HttpStatusCode.OK);

This is great, but what’s the IP address of our IoT device, so I can access the web server?

Well, ofcourse you could check your router or DHCP server, but better still, let’s output the IP address to the M5Core2 screen using

Console.WriteLine(IPGlobalProperties.GetIPAddress().ToString());

We can support multiple routes per method, such as

[ublic class PowerController
{
[Route("power")]
[Route("iotpower")]
[Method("GET")]
public void PowerRoute(WebServerEventArgs e)
{
// code removed
}

Note: Routes are usually case insensitive, unless you add the CaseSensitiveAttribute to your method.