Mikrobus.Net Quail, Weather & nRF-C clicks and xively

My next proof of concept uses a Weather click and nRF C click to upload temperature and humidity data to a Xively gateway running on a spare Netduino 2 Plus. I have a couple of Azure Event hub gateways (direct & queued) which require a Netduino 3 Wifi (for TLS/AMQPS support) and I’ll build a client for them in a coming post.

I initially purchased an nRF T click but something wasn’t quite right with its interrupt output. The interrupt line wasn’t getting pulled low at all so there were no send success/failure events. If I disabled the pull up resistor and strobed the interrupt pin on start-up the device would work for a while.


using (OutputPort Int = new OutputPort(socket.Int, true))
{
 Int.Write(true);
};

...

_irqPin = new InterruptPort(socket.Int, false, Port.ResistorMode.Disabled, Port.InterruptMode.InterruptEdgeLow);

The code sends a reading every 10 seconds and has been running for a couple of days. It strobes Led1 for each successful send and turns on Led2 when a send fails.

private static readonly byte[] deviceAddress = Encoding.UTF8.GetBytes("Quail");
private static readonly byte[] gatewayAddress = Encoding.UTF8.GetBytes("12345");
private const byte gatewayChannel = 10;
private const NRFC.DataRate gatewayDataRate = NRFC.DataRate.DR1Mbps;
private const int XivelyUpdateDelay = 10000;
private const char XivelyGatewayChannelIdTemperature = 'J';
private const char XivelyGatewayChannelIdHumidity = 'K';

public static void Main()
{
   NRFC nRF24Click = new NRFC(Hardware.SocketFour);
   nRF24Click.Configure(deviceAddress, gatewayChannel, gatewayDataRate);
   nRF24Click.OnTransmitFailed += nRF24Click_OnTransmitFailed;
   nRF24Click.OnTransmitSuccess += nRF24Click_OnTransmitSuccess;
   nRF24Click.Enable();

   // Configure the weather click
   WeatherClick weatherClick = new WeatherClick(Hardware.SocketOne, WeatherClick.I2CAddresses.Address0);
   weatherClick.SetRecommendedMode(WeatherClick.RecommendedModes.WeatherMonitoring);

   Thread.Sleep(XivelyUpdateDelay);

   while (true)
   {
      string temperatureMessage = XivelyGatewayChannelIdTemperature + weatherClick.ReadTemperature().ToString("F1");
      Debug.Print(temperatureMessage);
      MBN.Hardware.Led1.Write(true);
      nRF24Click.SendTo(gatewayAddress, Encoding.UTF8.GetBytes(temperatureMessage));

      Thread.Sleep(XivelyUpdateDelay);

      string humidityMessage = XivelyGatewayChannelIdHumidity + weatherClick.ReadHumidity().ToString("F1");
      Debug.Print(humidityMessage);
      MBN.Hardware.Led1.Write(true);
      nRF24Click.SendTo(gatewayAddress, Encoding.UTF8.GetBytes(humidityMessage));

      Thread.Sleep(XivelyUpdateDelay);
   }
}

static void nRF24Click_OnTransmitSuccess()
{
   MBN.Hardware.Led1.Write(false);
   if (MBN.Hardware.Led2.Read())
   {
      MBN.Hardware.Led2.Write(false);
   }

   Debug.Print("nRF24Click_OnTransmitSuccess");
}

static void nRF24Click_OnTransmitFailed()
{
   MBN.Hardware.Led2.Write(true);

   Debug.Print("nRF24Click_OnTransmitFailed");
}

I need to have a look at interfacing some more sensors and soak testing the solution.

The MikroBus.Net team have done a great job with the number & quality of the drivers they have available.

Some fun with a Netduino Plus and the icndb

A chat with some co-workers about displaying the status of the team’s Jenkins build process led to bit of research into calling RESTful services and JSON support on NetMF devices. Previously this had required a bit of hand crafted code but now it looks like the library support has matured a bit. I don’t run Jenkins at home so I decided to build a NetduinoPlus client for the internet Chuck Norris database which has a RESTful API.

This API returns Chuck Norris “facts”…

“Chuck Norris doesn’t read books. He stares them down until he gets the information he wants.”
“There is no theory of evolution, just a list of creatures Chuck Norris allows to live.”
“Some people wear Superman pajamas. Superman wears Chuck Norris pajamas.”
“Chuck Norris can slam a revolving door.”

The icndb API returns JSON

{ "type": "success", "value": { "id": 109, "joke": "It takes Chuck Norris 20 minutes to watch 60 Minutes.", "categories": [] } }

I used the NetMF system.HTTP libraries to initiate the request and Json.NetMF to unpack the response. This snippet illustrates how I processed the request/response


using (HttpWebRequest request = (HttpWebRequest)WebRequest.Create(@"http://api.icndb.com/jokes/random"))
{
//request.Proxy = proxy;
request.Method = "GET";
request.KeepAlive = false;
request.Timeout = 5000;
request.ReadWriteTimeout = 5000;

using (var response = (HttpWebResponse)request.GetResponse())
{
if (response.StatusCode == HttpStatusCode.OK)
{
byte[] buffer = new byte[response.ContentLength];

using (Stream stream = response.GetResponseStream())
{
stream.Read(buffer, 0, (int)response.ContentLength);

string json = new string(Encoding.UTF8.GetChars(buffer));

Hashtable jsonPayload = JsonSerializer.DeserializeString(json) as Hashtable;

Hashtable value = jsonPayload["value"] as Hashtable ;

Debug.Print(value["joke"].ToString());
}
}
}
}

icndb Netduino client

Bill of materials

FEZ Spider NetMF 4.2 Wifi with Designer Support

I now have a GHI Wifi RS21 Module which I needed get working with a FEZ Spider running NetMF 4.2 (I have upgraded both my FEZ Spiders to 4.2 so no 4.1 vs. 4.2 comparison this time). Other developers seemed to be struggling to get connectivity with various earlier versions of the NetMF going working robustly.

(http://www.tinyclr.com/forum/topic?id=9404)
(http://www.tinyclr.com/forum/topic?id=9388)
(http://www.tinyclr.com/forum/topic?id=9502)
(http://www.tinyclr.com/forum/topic?id=9538)

So after flashing my device to 4.2.9.0 I built a quick and dirty demo to illustrate how I got my RS9110 based Wifi module working with designer support. For a real application I would move the initialisation out of the ProgramStarted and improve the exception handling but this sample code should be enough to get you started. I have checked and this code works after both a device reset or re-flashing.

FezSpider + Wifi

FEZ Spider NetMF 4.2 Networking revisited

I was determined to get the J11D Ethernet module working in the graphical Designer so after a lot of reading + trial and error….

http://www.tinyclr.com/forum/topic?id=9438
http://www.tinyclr.com/forum/topic?id=9661
http://www.tinyclr.com/forum/topic?id=9816
http://www.tinyclr.com/forum/topic?id=9845
http://www.tinyclr.com/forum/topic?id=10120

Making the J11D work after both reflashing the firmware & reboot was critical

void ProgramStarted()
{
Debug.Print("Program Started");

ethernet_J11D.Interface.Open();

if (!ethernet_J11D.Interface.IsActivated)
{
NetworkInterfaceExtension.AssignNetworkingStackTo(ethernet_J11D.Interface);
}
ethernet_J11D.Interface.NetworkAddressChanged += new NetworkInterfaceExtension.NetworkAddressChangedEventHandler(NetworkAddressChanged);

// The code below (Dynamic configuration or static configuration) could be removed once the MFDeploy fixed.
// This is a known issue see (http://wiki.tinyclr.com/index.php?title=NETMF4.2_developer)

// For networks with dynamic configuration
ethernet_J11D.Interface.NetworkInterface.EnableDhcp();
ethernet_J11D.Interface.NetworkInterface.EnableDynamicDns();

// For networks with static IP
//Ethernet.NetworkInterface.EnableStaticIP("x.x.x.x", "y.y.y.y", "z.z.z.z");
//Ethernet.NetworkInterface.EnableStaticDns(new[] { "x.x.x.x", "y.y.y.y" });

ipAddressReady.WaitOne();

// Display network config for debugging
Debug.Print("Network configuration");
Debug.Print(" Network interface type: " + ethernet_J11D.Interface.NetworkInterface.NetworkInterfaceType.ToString());
Debug.Print(" MAC Address: " + BytesToHexString(ethernet_J11D.Interface.NetworkInterface.PhysicalAddress));
Debug.Print(" DHCP enabled: " + ethernet_J11D.Interface.NetworkInterface.IsDhcpEnabled.ToString());
Debug.Print(" Dynamic DNS enabled: " + ethernet_J11D.Interface.NetworkInterface.IsDynamicDnsEnabled.ToString());
Debug.Print(" IP Address: " + ethernet_J11D.Interface.NetworkInterface.IPAddress.ToString());
Debug.Print(" Subnet Mask: " + ethernet_J11D.Interface.NetworkInterface.SubnetMask.ToString());
Debug.Print(" Gateway: " + ethernet_J11D.Interface.NetworkInterface.GatewayAddress.ToString());
foreach (string dnsAddress in ethernet_J11D.Interface.NetworkInterface.DnsAddresses)
{
Debug.Print(" DNS Server: " + dnsAddress.ToString());
}
}

void NetworkAddressChanged(object sender, EventArgs e)
{
Debug.Print("NetworkAddressChanged");
Debug.Print(" IP Address: " + ethernet_J11D.Interface.NetworkInterface.IPAddress.ToString());

if (ethernet_J11D.Interface.NetworkInterface.IPAddress != IPAddress.Any.ToString())
{
ipAddressReady.Set();
}
}

FEZ Spider MF 4.1 and 4.2 Networking differences

I upgraded one of the two FEZ Spider boards I have to Version 4.2 of the .NETMF and this has caused some problems with the MF Deploy Network Configuration and also broke some networking code.

The MFDeploy Network configuration save fails with “Invalid configuration data from Plug-In” which others in the GHI Forums have also encountered e.g. http://www.tinyclr.com/forum/topic?id=9661

When I ran up my code the client IP address, gateway address etc. weren’t getting setup properly, My home network uses DHCP and this was fixed with .EnableDhcp(). I then noticed that the DNS address was not what I was expecting. It was pointing to one of the OpenDNS project servers. This was fixed by the .EnableDynamicDns();

This code works with V4.1

// This could be configured via MFDeploy
networkInterface.EnableDhcp();
networkInterface.EnableDynamicDns();

// error checking etc. removed

Debug.Print("Client IP address:" + networkInterface.IPAddress.ToString());
Debug.Print("MAC Address: " + BytesToHexString(networkInterface.PhysicalAddress));
Debug.Print("IP Address: " + networkInterface.IPAddress.ToString());
Debug.Print("Subnet Mask: " + networkInterface.SubnetMask.ToString());
Debug.Print("Gateway: " + networkInterface.GatewayAddress.ToString());
foreach (string dnsAddress in networkInterface.DnsAddresses)
{
Debug.Print("DNS Server: " + dnsAddress.ToString());
}

After some mucking around I found this code works for a Fez SPider running V4.2
static readonly EthernetBuiltIn Ethernet = new EthernetBuiltIn();


void ProgramStarted()
{
Ethernet.Open();

if (!Ethernet.IsActivated)
{
NetworkInterfaceExtension.AssignNetworkingStackTo(Ethernet);
}

// This code could be removed once the MFDeploy issue is sorted
Ethernet.NetworkInterface.EnableDhcp();
Ethernet.NetworkInterface.EnableDynamicDns();

// error checking etc. removed

Debug.Print("Client IP address:" + Ethernet.NetworkInterface.IPAddress.ToString());
Debug.Print("MAC Address: " + BytesToHexString( Ethernet.NetworkInterface.PhysicalAddress));
Debug.Print("IP Address: " + Ethernet.NetworkInterface.IPAddress.ToString());
Debug.Print("Subnet Mask: " + Ethernet.NetworkInterface.SubnetMask.ToString());
Debug.Print("Gateway: " + Ethernet.NetworkInterface.GatewayAddress.ToString());
foreach( string dnsAddress in Ethernet.NetworkInterface.DnsAddresses )
{
Debug.Print("DNS Server: " + dnsAddress.ToString());
}