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.
Aprovecharemos para actualizarnos a la última versión de .NET MicroFramework, Gadgeteer y el SDK de GHI de los siguientes enlaces:
Jose Bonnin nos colocó un excelente post con las instrucciones para actualizar el Firmware.
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:
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}