Post invitado: Serie .NET Gadgeter conectándonos a Mobile Services

Como en anteriores ocasiones, hoy volvemos a abrir el blog a un post invitado.

Esta vez nos llega de la mano de Pep Lluis Bano, el cual nos habla acerca de sistemas embebidos y Mobile Services.

 

Hace más de un año y a cuerda del Megathon algunos de vosotros tuvisteis la suerte de haceros con el hardware necesario para implementar un MiniWeb Server en un pequeño procesador ARM, utilizando Visual Studio y C# o VB.

Concretamente se trataba de un hardware “Cerbuino” (con bornes para shields compatibles con arduino, 3 conectores para albergar modulos Gadgeteer de Microsoft y otro para un bee). El kit se completaba con un módulo ENC28 que nos aportaba la imprescindible conectividad de cualquier dispositivo IoT que se precie.

Pues bien un año y medio después os propongo tunear vuestro “Cerbuino” y experimentar con los Mobile Services de Azure.

01

Aprovecharemos para actualizarnos a la última versión de .NET MicroFramework, Gadgeteer y el SDK de GHI de los siguientes enlaces:

· Microsoft .NET Micro Framework 4.3 (QFE1)

· Microsoft .NET Gadgeteer Core

· NETMF and Gadgeteer Package 2014 R5

Jose Bonnin nos colocó un excelente post con las instrucciones para actualizar el Firmware.

· Configuracion del entorno de trabajo.

Y para no hacerlo más largo de lo necesario, a continuación os paso código!... solo Código.

Solo un par de comentaros, necesitareis uCloudy de codeplex, contiene todo lo necesario para no tener que reinventar la lib. Para la parte de configuración de los mobile services encontraras multitud de tutoriales… lo cierto es que es muy sencillo.

El mismo código os servirá para Cerbuino o un G120.

  1: // Subiendo datos de nuestros sensores a mobile services
  2: //
  3: // Visual Studio 2013
  4: // MicroFramework SDK 4.3R2 (Beta)
  5: // 
  6: // Initial Prototype 25/10/2014 - PepLluis
  7:  
  8: using System;
  9: using Microsoft.SPOT;
  10: using Microsoft.SPOT.Hardware;
  11: using System.Threading;
  12:  
  13: // GHI Librerias para el modulo ENC28
  14: using GHI.Networking;
  15: using GHI.Pins;
  16:  
  17: using uPLibrary.Cloud.WindowsAzure.MobileService;
  18:  
  19: namespace CerbG120
  20: {
  21:     public class Program
  22:     {
  23:         /// <summary>
  24:         /// Uri / Key para Nuestros mobile services, Nombre de nuestra Tabla/Dispositivo
  25:         /// </summary>
  26:         static string       _appName;
  27:         static string       _AzureTableName = "tableName";
  28:         static string       _appKey = "appKey";
  29:         static readonly Uri _appUri = new Uri("https://yourapp.azure-mobile.net/");
  30:         /// <summary>
  31:         /// Definicion del Hardware y System.Timer 10Sec primer tick, 60Secs periodicos.
  32:         /// </summary>
  33:         static Timer sendDataTimer = new Timer(new TimerCallback(añadirRegistro), null, 10000, 60000);
  34:         static EthernetENC28J60 networkAdapter;
  35:         static OutputPort mainBoarLed;
  36:         /// <summary>
  37:         /// Nuestro entry point
  38:         /// </summary>
  39:         public static void Main()
  40:         {
  41:             // Determinar tipo de hardware utilizado (Cerb Family o Bases con modulo G120)
  42:             // Asignar la base donde se encuentra conectado el modulo ENC28
  43:             // Zocalo SPI2 Para G120 . MainBoard Led Pin4 en PortC
  44:             // Zocalo 6 Para Cerberus - MainBoard Led en Cpu.pin 37
  45:             switch ((int)SystemInfo.SystemID.Model)
  46:             {
  47:                     // Para G120
  48:                 case (int)GHI.Processor.DeviceType.G120:
  49:                     Debug.Print("Hardware para : G120 Mainboard, On SPI Socket");
  50:                     networkAdapter = new EthernetENC28J60(SPI.SPI_module.SPI2, G120.P1_17, G120.P0_5, G120.P1_14);
  51:                     mainBoarLed = new OutputPort((Cpu.Pin)37,false);
  52:                     _appName = "G120HDR";
  53:                     break;
  54:                     // Para Cerb o STM32F4
  55:                 case (int)GHI.Processor.DeviceType.CerbFamily:
  56:                     Debug.Print("Hardware para : Cerberus Mainboard. ENC28 on Socket 6");
  57:                     networkAdapter = new EthernetENC28J60(SPI.SPI_module.SPI1, Generic.GetPin('A', 13), Generic.GetPin('A', 14), Generic.GetPin('B', 10));
  58:                     mainBoarLed = new OutputPort(Generic.GetPin('C',4), false);
  59:                     _appName = "Cerberus";
  60:                     break;
  61:                 default:
  62:                     break;
  63:             }
  64:             // Abrir el Adaptador
  65:             networkAdapter.Open();
  66:             // Si no disponemos de ninguna IP asignada y DHCP no esta habilitado
  67:             // Habilitar DHCP/DNS para obtener nuestra IP
  68:             while (networkAdapter.IPAddress == "0.0.0.0")
  69:             {
  70:                 if (networkAdapter.IsDhcpEnabled == false)
  71:                 {
  72:                     networkAdapter.EnableDhcp();
  73:                     networkAdapter.EnableDynamicDns();
  74:                 }
  75:                 Debug.Print("...esperando respuesta del DHCP");
  76:                 System.Threading.Thread.Sleep(5000);
  77:             }
  78:             Debug.Print("IP obtenida para este adaptador :" + networkAdapter.IPAddress);
  79:  
  80:             // Mantener el hilo principal vivo/tareas (parpadear el MainBoardLed)
  81:             while (true)
  82:             {
  83:                 // Tus Tareas o Sleep Infinite 
  84:                 mainBoarLed.Write(true);
  85:                 Thread.Sleep(200);
  86:                 mainBoarLed.Write(false);
  87:                 Thread.Sleep(1000);
  88:             }
  89:         }
  90:  
  91:         static int _secuencia;
  92:         /// <summary>
  93:         /// Añadir una nueva entrada a nuestra tabla en Azure Mobile Services 
  94:         /// </summary>
  95:         /// <param name="status"></param>
  96:         static void añadirRegistro(object status)
  97:         {
  98:             _secuencia++;
  99:             var mobileServiceClient = new MobileServiceClient(_appUri, null, _appKey);
  100:             IMobileServiceTable amsTable = mobileServiceClient.GetTable(_AzureTableName);
  101:             var deviceRow = new datosDispositivo();
  102:             // rellenar columnas con los nuevos datos
  103:             deviceRow.SensorID = _appName +"-"+ SystemInfo.SystemID.OEM.ToString();
  104:             deviceRow.Secuencia = _secuencia;
  105:             deviceRow.Memoria = (int)Debug.GC(false);
  106:             try
  107:             {
  108:                 // ams = azure mobile service ;-)
  109:                 // Insertar registro
  110:                 string result = amsTable.Insert(deviceRow);
  111:                 Debug.Print(result);
  112:             }
  113:             catch (Exception ex)
  114:             {
  115:                 Debug.Print(ex.Message);
  116:             }
  117:         }
  118:     }
  119:  
  120:     // data Entity
  121:     class datosDispositivo : IMobileServiceEntity
  122:     {
  123:         /// <summary>
  124:         /// Campos / Registro
  125:         /// </summary>
  126:         public int Id { get; set; }
  127:         public string SensorID { get; set; }
  128:         public int Memoria { get; set; }
  129:         public int Secuencia { get; set; }
  130:         public string ToJson()
  131:         {
  132:             return "{ \"SensorId\" : \"" + SensorID + "\", \"Memory\" : \"" + Memoria +
  133:                    "\", \"Secuencia\" : \"" + Secuencia + "\"}";
  134:         }
  135:         public void Parse(string json)
  136:         {
  137:             // ToDO();
  138:         }
  139:  
  140:     }
  141: }

Y esta es la prueba:

02

Espero que esto os sirva para emplear el tiempo que os quede disponible entre medio de las comidas y cenas de las próximas vacaciones de navidad!!

Por cierto… Feliz Navidad.

 

Pep Lluis Bano

Microsoft MVP – Visual Developer

netMF y Gadgeteer {Compartir, Aprender, Aportar, Debatir}

https://msmvps.com/blogs/peplluis/

https://savecomm.net/blog https://savecomm.net/boards