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("http://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}

http://msmvps.com/blogs/peplluis/

http://savecomm.net/bloghttp://savecomm.net/boards

Comments (0)

Skip to main content