<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Unhandled Exception: MissingTitleException</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/robep/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/robep/feed.xml</link>
    <description>Programación, información técnica y tips en general... en español!</description>
    <lastBuildDate>Tue, 16 Apr 2019 06:21:07 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Visual Studio Dev Essentials</title>
      <link>https://docs.microsoft.com/archive/blogs/robep/visual-studio-dev-essentials</link>
      <pubDate>Sun, 22 Jul 2018 23:22:33 GMT</pubDate>
      <dc:creator><![CDATA[robep]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/robep/?p=775</guid>
      <description><![CDATA[Dev Essentials es una colección de herramientas y servicios gratuitos para desarrolladores que lleva...]]></description>
      <content:encoded><![CDATA[Dev Essentials es una colección de herramientas y servicios gratuitos para desarrolladores que lleva ya algunos años disponible; los elementos incluidos han cambiado con el tiempo y muchos de los servicios no necesariamente requieren uno se suscriba al programa.
Aún así, la suscripción es una forma conveniente de acceder a todos los beneficios.

Los beneficios exclusivos (al menos al momento de este artículo) están relacionados a las ofertas de entrenamiento, entre ellas:

<a href="https://www.pluralsight.com">Pluralsight </a>– Suscripción de 3 meses
<a href="https://www.opsgility.com">Opsgility </a>– Suscripción de 3 meses
<a href="https://www.wintellectnow.com">WintellectNow </a>– Suscripción de 3 meses

Si aún no has tomado ventaja de estos beneficios recomiendo que accedas al portal <a href="https://visualstudio.microsoft.com/dev-essentials/">https://visualstudio.microsoft.com/dev-essentials/</a> y empieces cuanto antes!

Hasta la próxima!
--Rp]]></content:encoded>
    </item>
    <item>
      <title>Microsoft vs Work or School Accounts</title>
      <link>https://docs.microsoft.com/archive/blogs/robep/microsoft-vs-work-or-school-accounts</link>
      <pubDate>Mon, 16 Jul 2018 00:09:48 GMT</pubDate>
      <dc:creator><![CDATA[robep]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/robep/?p=755</guid>
      <description><![CDATA[La mayoría de los servicios en Microsoft solicitan una cuenta para ingresar dándonos la elección...]]></description>
      <content:encoded><![CDATA[La mayoría de los servicios en Microsoft solicitan una cuenta para ingresar dándonos la elección entre usar una Cuenta Microsoft o una Cuenta de Escuela o Trabajo (algunos servicios incluso permiten utilizar cuentas de otros proveedores como Facebook, GitHub, etc.); muchas personas piensan que simplemente se trata de un correo más que nunca va a ser utilizado, pero realmente hay mucho más involucrado.
<h2>Work or School Accounts</h2>
Este tipo de cuentas están respaldadas por un directorio en Azure y tienen mecanismos avanzados de administración; los usuarios o credenciales son gobernados por organizaciones y es posible asignar permisos o suscripciones a servicios como Office 365 y PowerBI entre otros.
Todos los directorios cuentan con la forma predeterminada dominio.onmicrosoft.com pero también pueden tener dominios personalizados como cualquier correo electrónico.
<h2>Microsoft Account</h2>
Las personas normalmente asocian estas cuentas con cuentas de correo de Hotmail o Outlook, pero no es necesario tener un correo electrónico de estos dominios; una Cuenta Microsoft es una credencial asociada a un correo electrónico, puede ser un correo corporativo o un correo de un proveedor público como Gmail o Yahoo.
<h2>Múltiples cuentas para un correo</h2>
Algo que confunde a muchas personas es el hecho que es posible tener una cuenta de escuela o trabajo y una cuenta Microsoft utilizando un mismo correo; se tratan de credenciales diferentes, con contraseñas, suscripciones y pertenencia a servicios diferentes. Al iniciar sesión con un correo con múltiples cuentas aparece un cuadro de diálogo pidiendo que escojamos cual cuenta deseamos utilizar, es fácil diferenciarlas a partir del ícono utilizado, las cuentas de escuela o trabajo están representadas con una imagen de una identificación como las utilizadas en las empresas.

<a href="https://msdnshared.blob.core.windows.net/media/2018/07/accounts.png"><img width="300" height="294" class="aligncenter size-medium wp-image-765" alt="" src="https://msdnshared.blob.core.windows.net/media/2018/07/accounts-300x294.png" /></a>

Este es un artículo simple pero importante para otros que están por venir, hasta la próxima!
--Rp]]></content:encoded>
    </item>
    <item>
      <title>DevOps Self-Assessment</title>
      <link>https://docs.microsoft.com/archive/blogs/robep/devops-self-assessment</link>
      <pubDate>Tue, 07 Nov 2017 10:54:20 GMT</pubDate>
      <dc:creator><![CDATA[robep]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/robep/?p=735</guid>
      <description><![CDATA[Hola a todos

He estado un poco ocupado últimamente y no he podido escribir, pero quería...]]></description>
      <content:encoded><![CDATA[Hola a todos

He estado un poco ocupado últimamente y no he podido escribir, pero quería compartirles un recurso que acabo de encontrar! El DevOps Self-Assessment es un cuestionario para evaluar la estrategía actual de DevOps para sus compañías, una excelente oportunidad para determinar nuestro siguiente paso en nuestro estado de madurez en los equipos!

Pueden acceder el assessment en el siguiente enlace:<a href="https://www.devopsassessment.net/"> https://www.devopsassessment.net/</a>

<a href="https://msdnshared.blob.core.windows.net/media/2017/11/devops.png"><img width="377" height="350" class="aligncenter size-mediumlarge wp-image-745" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/11/devops-377x350.png" /></a>

Espero que les sea útil, hasta la próxima!
--Rp]]></content:encoded>
    </item>
    <item>
      <title>Usando Azure IoT hubs con ESP8266</title>
      <link>https://docs.microsoft.com/archive/blogs/robep/usando-azure-iot-hubs-con-esp8266</link>
      <pubDate>Sun, 10 Sep 2017 02:14:22 GMT</pubDate>
      <dc:creator><![CDATA[robep]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/robep/?p=715</guid>
      <description><![CDATA[Después de probar durante bastante tiempo puedo finalmente empezar con una serie de artículos sobre...]]></description>
      <content:encoded><![CDATA[Después de probar durante bastante tiempo puedo finalmente empezar con una serie de artículos sobre cómo usar un Azure IoT Hub desde Arduino! Este proyecto resultó un poco más complicado de lo que pensaba, estaba acostumbrado a trabajar con Raspberry PI que cuenta con un sistema operativo completo y es capaz de ejecutar código basado en .Net, pero Arduino es más simple y tiene un par de detalles interesantes que vale la pena compartir.
<h3>SDK para Arduino</h3>
Lo primero que debemos ubicar es el SDK para Arduino, Azure provee kits de desarrollo para <a target="_blank" href="https://docs.microsoft.com/es-es/azure/iot-hub/iot-hub-devguide-sdks" rel="noopener noreferrer">múltiples lenguajes de programación</a>, del enlace anterior podemos revisar la información para el <a target="_blank" href="https://docs.microsoft.com/es-es/azure/iot-hub/iot-hub-device-sdk-c-intro" rel="noopener noreferrer">SDK de C</a>, estos enlaces nos darán suficiente información para empezar a trabajar con los IoT Hubs pero no son específicos a Arduino y más importante no nos indica cómo podemos obtener las librerías para Arduino!

Finalmente, al revisar la referencia podemos encontrar un <a target="_blank" href="https://docs.microsoft.com/es-es/azure/iot-hub/iot-hub-get-started-physical" rel="noopener noreferrer">enlace</a> que discute cómo utilizar los IoT hubs con dispositivos físicos, este enlace contiene 3 dispositivos basados en Arduino de los cuales el basado en el<a target="_blank" href="https://docs.microsoft.com/es-es/azure/iot-hub/iot-hub-sparkfun-esp8266-thing-dev-get-started" rel="noopener noreferrer"> Sparkfun ESP8266 Thing Dev</a> creo que es el más fácil de seguir.
<h3>Ejemplo de Código</h3>
El ejemplo de código es el mismo para todos los dispositivos basados en Arduino, sin embargo, al ser genérico lleva muchas condicionales y puede ser complicado de entender, mi objetivo era tener un ejemplo mucho más simple y es aquí donde empecé a tener algunas sorpresas.
<h4>Epoch Time</h4>
Hay un detalle que no encontré en la documentación y es que los IoT Hubs requieren que los mensajes sean enviados con la hora del evento como uno de los campos obligatorios, en Raspberry PI esto no es un problema porque asume que el sistema operativo tiene la hora correcta y utiliza esta para llenar esta información... pero Arduino no cuenta con esta funcionalidad! Por esta razón los ejemplos tienen una función para obtener el tiempo Epoch, internamente la librería utiliza este valor cada vez que se envía un mensaje. Es muy importante inicializar este valor, si no se hace, el mensaje parece que fuera entregado correctamente pero nunca ingresa al hub, este detalle me dio un par de problemas, ya que aunque sabía que era necesario borré la llamada sin percatarme y tarde mucho en darme cuenta de esto.
<h4>iotHubClientHandle</h4>
Otra de las sorpresas al experimentar con el código es que el objeto iotHubClientHandle de tipo <em><strong>IOTHUB_CLIENT_LL_HANDLE</strong></em> es creado dentro del método <strong><i>l</i><em>oop</em> </strong>en los ejemplos, a pesar que no parece óptimo no pensé que sería mucho problema, lo que descubrí es que la creación de este objeto dentro de ese método tarde o temprano causa un excepción dentro del ESP8266 y luego un reinicio; este es otro problema que me mantuvo investigando un tiempo, sin embargo, al sacar la definición y luego inicializarlo dentro del método <strong><em>setup</em> </strong>todo funcionó sin problema.
<h4>Low Level</h4>
La librería cuenta con dos tipos de funciones, las "normales" y las de "bajo nivel" las cuales se pueden identificar fácilmente gracias a que contienen <em><strong>_LL_ </strong></em>dentro del nombre; fuera del nombre, la diferencia principal de entre los dos tipos de funciones es el manejo del buffer que contiene los mensajes, al enviar un mensaje, este no es depositado directamente en Azure, es primero almacenado en un buffer local que será utilizado para luego enviar la información a Azure. Si deciden utilizar las funciones de bajo nivel, cómo se ha hecho en el ejemplo simplificado, es importante recordar que debe llamarse la función <strong><em>IoTHubClient_LL_DoWork </em></strong>para procesar el buffer y envíar la información a la nube.
<h4>Librerías</h4>
Este es uno de los puntos que menos me gustaba los ejemplos en GitHub, con el objetivo de ser genéricos habían muchas secciones que no eran realmente necesarias, yo quería un ejemplo fácil de leer y comprender por lo que era necesario incluir sólo las librerías necesarias y eliminar todo el código condicional, para un ejemplo simple como el mostrado en este artículo sólo se requieren 3 librerías:
<ol>
 	<li>AzureIoTHub (para interactuar con Azure)</li>
 	<li>AzureIoTProtocol_HTTP (esta dependerá de nuestra elección de protocolo)</li>
 	<li>ESP8266WiFi (para conectarnos a la red inalámbrica)</li>
</ol>
<h4>Serialización</h4>
Aun cuando es posible utilizar los IoT hubs sin esta funcionalidad, el código terminará siendo mucho más legible, la declaración de modelos es una forma fácil de ahorrarnos la complejidad de manejar cadenas de texto para enviar nuestra información. El único punto clave es que deben recordar incluir la función <em><strong>IoTHubMessage</strong></em>, esta puede ser copiada directamente de los ejemplos de GitHub y no necesitan realizar ningún cambio en ella; aun cuando la función no es llamada directamente en el ejemplo, la librería la utilizará para enviar la información a la nube de forma correcta.
<h4>Finalmente... El código simplificado!</h4>
El siguiente listado de código es un ejemplo simplificado para usar con un ESP8266 genérico, con el objetivo de mantener su simplicidad no se obtiene información de ningún sensor, si se requiere un ejemplo más real basta con llenar la propiedad data con la lectura de un pin o sensor.
<pre style="font-family: Consolas;font-size: 13;color: black"><span style="color: gray">#include</span> <span style="color: #a31515">&lt;AzureIoTHub.h&gt;</span>
<span style="color: gray">#include</span> <span style="color: #a31515">&lt;AzureIoTProtocol_HTTP.h&gt;</span>
<span style="color: gray">#include</span> <span style="color: #a31515">&lt;ESP8266WiFi.h&gt;
</span>
<span style="color: #6f008a">BEGIN_NAMESPACE</span>(SampleNamespace);
<span style="color: #6f008a">DECLARE_MODEL</span>(<span style="color: #2b91af">SampleModel</span>,
<span style="color: #6f008a">WITH_DATA</span>(<span style="color: #2b91af">ascii_char_ptr</span>, DeviceId),
<span style="color: #6f008a">WITH_DATA</span>(<span style="color: blue">int</span>, data)
);
<span style="color: #6f008a">END_NAMESPACE</span>(SampleNamespace);
<span style="color: blue">const</span> <span style="color: blue">char</span>* cn = <span style="color: #a31515">"[Device ConnectionString]"</span>;
<span style="color: #2b91af">IOTHUB_CLIENT_LL_HANDLE</span> iotHubClientHandle;
<span style="color: blue">void</span> setup()
{
        Serial.begin(9600);
	WiFi.begin(<span style="color: #a31515">"WirelessNetwork"</span>, <span style="color: #a31515">"Password"</span>);
	<span style="color: blue">while</span> (WiFi.status() != <span style="color: darkslategray">WL_CONNECTED</span>) {
		delay(500);
	}
	initTime();
	iotHubClientHandle = IoTHubClient_LL_CreateFromConnectionString(cn, HTTP_Protocol);
}
<span style="color: #2b91af">SampleModel</span>* model;
<span style="color: blue">void</span> loop()
{
	delay(15000);
	serializer_init(<span style="color: #6f008a">NULL</span>);
	model = <span style="color: #6f008a">CREATE_MODEL_INSTANCE</span>(SampleNamespace, <span style="color: #2b91af">SampleModel</span>);
	<span style="color: blue">unsigned</span> <span style="color: blue">char</span>* destination;
	<span style="color: #2b91af">size_t</span> destinationSize;
	model-&gt;DeviceId = <span style="color: #a31515">"device"</span>;
	model-&gt;data = 1;
	<span style="color: blue">if</span> (<span style="color: #6f008a">SERIALIZE</span>(&amp;destination, &amp;destinationSize, model-&gt;DeviceId, model-&gt;data) != <span style="color: darkslategray">CODEFIRST_OK</span>)
	{
		Serial.println(<span style="color: #a31515">"Failed to serialize\r\n"</span>);
	}
	<span style="color: blue">else</span>
	{
		<span style="color: #2b91af">IOTHUB_MESSAGE_HANDLE</span> messageHandle = IoTHubMessage_CreateFromByteArray(destination, destinationSize);
		<span style="color: blue">if</span> (messageHandle == <span style="color: #6f008a">NULL</span>)
		{
			printf(<span style="color: #a31515">"unable to create a new IoTHubMessage\r\n"</span>);
		}
		<span style="color: blue">else</span>
		{
			<span style="color: blue">if</span> (IoTHubClient_LL_SendEventAsync(iotHubClientHandle, messageHandle, sendCallback, (<span style="color: blue">void</span>*)1) != <span style="color: darkslategray">IOTHUB_CLIENT_OK</span>)
			{
				Serial.println(<span style="color: #a31515">"failed to hand over the message to IoTHubClient"</span>);
			}
			<span style="color: blue">else</span>
			{
				Serial.println(<span style="color: #a31515">"IoTHubClient accepted the message for delivery\r\n"</span>);
			}
			IoTHubClient_LL_DoWork(iotHubClientHandle);
			IoTHubMessage_Destroy(messageHandle);
		}
		free((<span style="color: blue">void</span>*)destination);
	}
}
<span style="color: blue">void</span> sendCallback(<span style="color: #2b91af">IOTHUB_CLIENT_CONFIRMATION_RESULT</span> <span style="color: gray">result</span>, <span style="color: blue">void</span>* <span style="color: gray">userContextCallback</span>)
{
 
}
<span style="color: blue">static</span> <span style="color: #2b91af">IOTHUBMESSAGE_DISPOSITION_RESULT</span> IoTHubMessage(<span style="color: #2b91af">IOTHUB_MESSAGE_HANDLE</span> <span style="color: gray">message</span>, <span style="color: blue">void</span>* <span style="color: gray">userContextCallback</span>)
{
	<span style="color: #2b91af">IOTHUBMESSAGE_DISPOSITION_RESULT</span> result;
	<span style="color: blue">const</span> <span style="color: blue">unsigned</span> <span style="color: blue">char</span>* buffer;
	<span style="color: #2b91af">size_t</span> size;
	<span style="color: blue">if</span> (IoTHubMessage_GetByteArray(<span style="color: gray">message</span>, &amp;buffer, &amp;size) != <span style="color: darkslategray">IOTHUB_MESSAGE_OK</span>)
	{
		Serial.println(<span style="color: #a31515">"unable to IoTHubMessage_GetByteArray\r\n"</span>);
		result = <span style="color: darkslategray">IOTHUBMESSAGE_ABANDONED</span>;
	}
	<span style="color: blue">else</span>
	{
		<span style="color: blue">char</span>* temp = (<span style="color: blue">char</span>*)malloc(size + 1);
		<span style="color: blue">if</span> (temp == <span style="color: #6f008a">NULL</span>)
		{
			Serial.println(<span style="color: #a31515">"failed to malloc\r\n"</span>);
			result = <span style="color: darkslategray">IOTHUBMESSAGE_ABANDONED</span>;
		}
		<span style="color: blue">else</span>
		{
			<span style="color: #2b91af">EXECUTE_COMMAND_RESULT</span> executeCommandResult;
 
			(<span style="color: blue">void</span>)memcpy(temp, buffer, size);
			temp[size] = <span style="color: #a31515">'\0'</span>;
			executeCommandResult = <span style="color: #6f008a">EXECUTE_COMMAND</span>(<span style="color: gray">userContextCallback</span>, temp);
			result =
				(executeCommandResult == <span style="color: darkslategray">EXECUTE_COMMAND_ERROR</span>) ? <span style="color: darkslategray">IOTHUBMESSAGE_ABANDONED</span> :
				(executeCommandResult == <span style="color: darkslategray">EXECUTE_COMMAND_SUCCESS</span>) ? <span style="color: darkslategray">IOTHUBMESSAGE_ACCEPTED</span> :
				<span style="color: darkslategray">IOTHUBMESSAGE_REJECTED</span>;
			free(temp);
		}
	}
	<span style="color: blue">return</span> result;
}
<span style="color: blue">void</span> initTime() {
	<span style="color: #2b91af">time_t</span> epochTime;
 
	configTime(0, 0, <span style="color: #a31515">"pool.ntp.org"</span>, <span style="color: #a31515">"time.nist.gov"</span>);
 
	<span style="color: blue">while</span> (<span style="color: #6f008a">true</span>) {
		epochTime = time(<span style="color: #6f008a">NULL</span>);
 
		<span style="color: blue">if</span> (epochTime == 0) {
			Serial.println(<span style="color: #a31515">"Fetching NTP epoch time failed! Waiting 2 seconds to retry."</span>);
			delay(2000);
		}
		<span style="color: blue">else</span> {
			Serial.print(<span style="color: #a31515">"Fetched NTP epoch time is: "</span>);
			Serial.println(epochTime);
			<span style="color: blue">break</span>;
		}
	}
}</pre>
Aun cuando el listado parece complejo, es mucho más simple que los ejemplos oficiales. Eso es todo por ahora, espero que les sea de utilidad, hasta la próxima!
–Rp]]></content:encoded>
    </item>
    <item>
      <title>Restricciones de IP en Azure WebApps</title>
      <link>https://docs.microsoft.com/archive/blogs/robep/restricciones-de-ip-en-azure-webapps</link>
      <pubDate>Fri, 25 Aug 2017 00:50:01 GMT</pubDate>
      <dc:creator><![CDATA[robep]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/robep/?p=695</guid>
      <description><![CDATA[Ahora estaba realizando unas pruebas con Azure cuando me di cuenta que ya están disponibles...]]></description>
      <content:encoded><![CDATA[Ahora estaba realizando unas pruebas con Azure cuando me di cuenta que ya están disponibles restricciones de IP por medio del portal de Azure, esto era posible hacerlo antes pero por medio de configuración, no estoy del todo seguro pero creo que esta es una de las más recientes adiciones al portal :)

<a href="https://msdnshared.blob.core.windows.net/media/2017/08/ip-restrictions.png"><img width="315" height="350" class="aligncenter size-mediumlarge wp-image-705" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/08/ip-restrictions-315x350.png" /></a>

Hasta la próxima!
--Rp]]></content:encoded>
    </item>
    <item>
      <title>Leyendo desde un servidor Web con ESP8266</title>
      <link>https://docs.microsoft.com/archive/blogs/robep/leyendo-desde-un-servidor-web-con-esp8266</link>
      <pubDate>Tue, 25 Jul 2017 00:39:50 GMT</pubDate>
      <dc:creator><![CDATA[robep]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/robep/?p=676</guid>
      <description><![CDATA[Este día me pidieron ayuda para leer información desde una página Web alojada en una Azure Webapp...]]></description>
      <content:encoded><![CDATA[Este día me pidieron ayuda para leer información desde una página Web alojada en una Azure Webapp por medio de un Arduino, el formato de la información era muy simple, el cuerpo de la página siempre serían cuatro números enteros cada uno en su propia línea, como se muestra a continuación:
<pre>2
1
0
5</pre>
El problema puede resolverse fácilmente por medio de la clase <em>WiFiClient</em>, esta clase contiene toda la funcionalidad para poder realizar una petición http, https no está soportado por esta clase; generalmente se dice que Arduino no soporta https, pero esto no necesariamente es cierto, en el caso de actualizaciones OTA es posible acceder a los firmwares por medio de https pero eso queda para ser mostrado en otro artículo :) Lo primero que debe conocerse es la estructura de una petición http, esta consta de varias líneas de texto que proveen información, la primera y más importante de ellas esta compuesta por <strong>verbo recurso protocolo/versión</strong>, en algunas ocasiones se acostumbra definir el host dentro del recurso, sin embargo es más apropiado agregarlo como un header separado en otra línea, el request más básico que podemos es hacer es el siguiente:
<pre>GET /data.aspx HTTP/1.1
Host: someapp.azurewebsites.net</pre>
A lo que nuestra página Web respondería con algo como:
<pre>HTTP/1.1 200 OK
Cache-Control: private
Content-Length: 7
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/8.0
X-AspNetMvc-Version: 5.2
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Set-Cookie: ARRAffinity=fa2c800b0235ac66fafa2c8de8663dc33057be0e5a83277ac66faac66fa9ad4dc;Path=/;HttpOnly;Domain=someapp.azurewebsites.net
Date: Tue, 25 Jul 2017 03:55:03 GMT

2
1
0
5</pre>
El código necesario para leer esa respuesta se lista a continuación:
<pre style="font-family: Consolas;font-size: 13;color: black"><span style="color: green">//Definición de variables</span>
<span style="color: #2b91af">String</span> buffer;
<span style="color: #6f008a">bool</span> flag = <span style="color: #6f008a">false</span>;
<span style="color: blue">int</span> count = 0;
<span style="color: blue">int</span> values[4];
<span style="color: #2b91af">WiFiClient</span> c;
<span style="color: green">//Conectando al servidor</span>
<span style="color: blue">if</span> (c.connect(<span style="color: #a31515">"someapp.azurewebsites.net"</span>, 80))
{
	<span style="color: green">//Ejecutando petición</span>
	c.println(<span style="color: #a31515">"GET /data.aspx HTTP/1.1"</span>);
	c.println(<span style="color: #a31515">"host: someapp.azurewebsites.net"</span>);
	c.println();
	<span style="color: green">//Leyendo resultados línea por línea</span>
	buffer <span style="color: teal">=</span> c.readStringUntil(<span style="color: #a31515">'\n'</span>);
	<span style="color: blue">while</span> (buffer.length() &gt; 0)
	{
		<span style="color: blue">if</span> (flag &amp;&amp; count &lt; 4)
		{
			<span style="color: green">//Al finalizar los headers leer cada uno de los 4 valores</span>
			values[count] = c.parseInt();
			count++;
		}
		<span style="color: blue">else</span>
		{
			<span style="color: green">//Leyendo las líneas con los headers</span>
			buffer <span style="color: teal">=</span> c.readStringUntil(<span style="color: #a31515">'\r'</span>);
			<span style="color: green">//Verificando si finalizaron los headers</span>
			<span style="color: blue">if</span> (buffer.length() == 1)
			{
				flag = <span style="color: #6f008a">true</span>;
				count = 0;
			}
		}
	}
}
<span style="color: green">//Los valores están almacenados dentro del arreglo values</span>
</pre>
Eso es todo por ahora, espero que les sea de utilidad, hasta la próxima!
--Rp]]></content:encoded>
    </item>
    <item>
      <title>Administrando VSTS/TFS con PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/robep/administrando-vststfs-con-powershell</link>
      <pubDate>Tue, 18 Jul 2017 02:28:58 GMT</pubDate>
      <dc:creator><![CDATA[robep]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/robep/?p=665</guid>
      <description><![CDATA[De las múltiples cosas interesantes que pude aprender este día, una de las que estoy obligado a...]]></description>
      <content:encoded><![CDATA[De las múltiples cosas interesantes que pude aprender este día, una de las que estoy obligado a compartir es el módulo de PowerShell dedicado a la administración de VSTS y TFS creado por <a href="https://twitter.com/DonovanBrown">Donovan Brown</a>; había buscado algo similar anteriormente pero sólo había encontrado formas para utilizar la RestAPI desde PowerShell; esta característica simplifica mucho las tareas y abre un mundo de posibilidades para trabajar con la plataforma ALM.

Si quieren instalarla lo primero que necesitan es abrir PowerShell como administrador, esto debido a que vamos a instalar un nuevo módulo en nuestras máquinas, una vez en la consola sólo deben digitar el siguiente comando:
<pre>Install-Module Team

NuGet provider is required to continue
PowerShellGet requires NuGet provider version '2.8.5.201' or newer to interact with NuGet-based repositories. The NuGet
 provider must be available in 'C:\Program Files\PackageManagement\ProviderAssemblies' or
'C:\Users\ROBEP\AppData\Local\PackageManagement\ProviderAssemblies'. You can also install the NuGet provider by running
 'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force'. Do you want PowerShellGet to install and
import the NuGet provider now?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): Y

Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its
InstallationPolicy value by running the Set-PSRepository cmdlet. Are you sure you want to install the modules from
'PSGallery'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): Y</pre>
Una vez instalada, deben crear un <a href="https://www.visualstudio.com/en-us/docs/setup-admin/team-services/use-personal-access-tokens-to-authenticate">Personal Access Token</a> para poder registrar la cuenta en la sesión actual, el proceso es simple, lo primero que deben hacer es invocar el cmdlet
<pre>Add-TeamAccount</pre>
El cmdlet preguntará por su cuenta de VSTS/TFS, deben considerar que si su cuenta de VSTS es <strong>algunnombre.visualstudio.com</strong> deberán proporcionar la url completa incluyendo el protocolo o únicamente el valor <strong>algunnombre</strong>, si proporcionan todo el fqdn sin el protocolo la extensión tratará de agregar <strong>visualstudio.com </strong>otra vez y tendrán un error de DNS; después de proporcionar su cuenta deberán incresar su PAT y listo! La sesión ha sido configurada para interactuar con su cuenta de VSTS. Pueden hacer <em><strong>Get-Command -Module Team </strong></em>para obtener todos los cmdlets en este módulo o bien pueden ir directo al <a href="https://github.com/DarqueWarrior/team">sitio de GitHub </a>de Donovan y ver cómo está implementado el módulo.

Espero les sea de utilidad, hasta la próxima!
--Rp]]></content:encoded>
    </item>
    <item>
      <title>Usando hilos en Arduino</title>
      <link>https://docs.microsoft.com/archive/blogs/robep/usando-hilos-en-arduino</link>
      <pubDate>Wed, 05 Jul 2017 22:16:45 GMT</pubDate>
      <dc:creator><![CDATA[robep]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/robep/?p=655</guid>
      <description><![CDATA[Uno de los problemas al empezar a programar con Arduino es acostumbrarse a la estructura del...]]></description>
      <content:encoded><![CDATA[Uno de los problemas al empezar a programar con Arduino es acostumbrarse a la estructura del programa, principalmente del método <em>loop()</em> que se ejecuta continuamente; muchos de los ejemplos en Internet hacen uso del método <em>delay()</em> o alguna de sus variantes para poder tener control sobre la ejecución, pero esta técnica bloquea la ejecución de toda instrucción y nada más puede ocurrir, si quieren hacer múltiples tareas en paralelo esto no es una buena opción.

En mi <a href="https://blogs.msdn.microsoft.com/robep/2017/07/03/menu-de-opciones-para-arduino/">artículo anterior</a> mostré un ejemplo muy fácil de como leer desde un keypad basándome en esta <a href="https://playground.arduino.cc/Code/Keypad">librería<span>;</span></a> si leen la referencia verán que también estaba disponible una función llamada <em>waitForKey()</em> que podría haber simplificado mucho el código ya que eliminaría la necesidad de los ciclos <em>while()</em>, yo decidí no usar esta función a propósito para que pudiera jugar bien con otras acciones que estuvieran ejecutándose en paralelo, esto normalmente se conoce como hilos o threads; la plataforma Arduino no soporta thread reales pero este funcionamiento puede ser emulado con algunas técnicas, una de las más sencillas es la que provee a librería <a href="https://github.com/ivanseidel/ArduinoThread">Thread</a>.

Este es un pequeño ejemplo introductorio; supongamos que necesitamos un led intermitente a un intervalo de 1 segundo, normalmente escribiríamos un fragmento de código como el siguiente:
<pre style="font-family: Consolas;font-size: 13;color: black"><span style="color: blue">void</span> loop() {
	blink();
	delay(1000);
}
 
<span style="color: blue">void</span> blink() {
	digitalWrite(PIN, !digitalRead(5));
}
</pre>
Mientras no tengamos que realizar otra tarea, nuestro ejemplo funcionará sin problemas pero al agregar más cosas, rápidamente veremos que nuestro led ya no se comporta como esperamos, por ejemplo, si queremos leer al mismo tiempo de nuestro keypad; acá es donde la case <em>Thread</em> entra en acción, primero es necesario crear y configurar nuestro <em>Thread</em>:
<pre style="font-family: Consolas;font-size: 13;color: black"><span style="color: gray">#include</span> <span style="color: #a31515">&lt;Thread.h&gt;</span>
 
<span style="color: #2b91af">Thread</span> thrBlink = <span style="color: #2b91af">Thread</span>();
 
<span style="color: blue">void</span> setup() {
	pinMode(5, <span style="color: #6f008a">OUTPUT</span>);
	digitalWrite(5, <span style="color: #6f008a">HIGH</span>);
	
	thrBlink.enabled = <span style="color: #6f008a">true</span>;
	thrBlink.setInterval(1000);
	thrBlink.onRun(blink);
}
 
<span style="color: blue">void</span> blink() {
	digitalWrite(5, !digitalRead(5));
}</pre>
Una vez configurado sólo debemos colocar llamadas dentro de nuestro método loop para que verificar si el código debe correr o no, la llamada se ejecutará pero no bloqueará el resto del programa, el código requiere que primero verifiquemos si la tarea debe correr y de ser así, luego la ejecutemos, para el ejemplo del keypad en el artículo anterior esto sería una vez dentro de cada ciclo <em>while</em>, lo pueden poner en cualquier lugar siempre y cuando esté dentro del ciclo como se muestra a continuación:
<pre style="font-family: Consolas;font-size: 13;color: black"><span style="color: blue">void</span> loop() {
	quantity = 0;
	Serial.println(<span style="color: #a31515">"Seleccione una opcion (A-D):"</span>);
	flag = <span style="color: #6f008a">true</span>;
	<span style="color: blue">while</span> (flag) {
		<span style="color: blue">if</span>(thrBlink.shouldRun())
		{
			thrBlink.run();
		}
		key = keypad.getKey();
		<span style="color: blue">if</span> (key) {
			<span style="color: blue">switch</span> (key)
			{
			<span style="color: blue">case</span> <span style="color: #a31515">'A'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'B'</span>:
<span style="color: green">//...</span></pre>
Estos ejemplos básicos están sirviendo como una base para mostrar cosas más interesantes en el futuro, como envío de mensajes a la nube o integración continua con despliegue a múltiples sensores desde la plataforma Visual Studio Team Services que les tendré listo muy pronto.

Hasta la próxima!
--Rp]]></content:encoded>
    </item>
    <item>
      <title>Menu de opciones para Arduino</title>
      <link>https://docs.microsoft.com/archive/blogs/robep/menu-de-opciones-para-arduino</link>
      <pubDate>Mon, 03 Jul 2017 16:38:02 GMT</pubDate>
      <dc:creator><![CDATA[robep]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/robep/?p=615</guid>
      <description><![CDATA[El fin de semana me solicitaron ayuda para crear un menú de opciones para Arduino, la idea es usar...]]></description>
      <content:encoded><![CDATA[El fin de semana me solicitaron ayuda para crear un menú de opciones para Arduino, la idea es usar un teclado de entrada (en este caso un keypad 4x4) y permitir ingresar una opción y a continuación una cantidad; el código es bastante fácil pero muchas veces se tiene problemas para expresarlo dentro del método loop. Dado que este parece ser un problema común les comparto el código de ejemplo, quizás le pueda servir a alguien más.

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/IMG_20170703_160110.jpg"><img width="467" height="350" class="size-mediumlarge wp-image-616 aligncenter" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/07/IMG_20170703_160110-467x350.jpg" /></a>
<pre style="font-family: Consolas;font-size: 13;color: black"><span style="color: gray">#include</span> <span style="color: #a31515">&lt;Keypad.h&gt;</span>
 
<span style="color: blue">const</span> <span style="color: #2b91af">byte</span> ROWS = 4;
<span style="color: blue">const</span> <span style="color: #2b91af">byte</span> COLS = 4;
 
<span style="color: blue">char</span> keys[ROWS][COLS] = {
	{ <span style="color: #a31515">'1'</span>,<span style="color: #a31515">'2'</span>,<span style="color: #a31515">'3'</span>,<span style="color: #a31515">'A'</span> },
	{ <span style="color: #a31515">'4'</span>,<span style="color: #a31515">'5'</span>,<span style="color: #a31515">'6'</span>,<span style="color: #a31515">'B'</span> },
	{ <span style="color: #a31515">'7'</span>,<span style="color: #a31515">'8'</span>,<span style="color: #a31515">'9'</span>,<span style="color: #a31515">'C'</span> },
	{ <span style="color: #a31515">'*'</span>,<span style="color: #a31515">'0'</span>,<span style="color: #a31515">'#'</span>,<span style="color: #a31515">'D'</span> }
};
<span style="color: #2b91af">byte</span> rowPins[ROWS] = { 9, 8, 7, 6 };
<span style="color: #2b91af">byte</span> colPins[COLS] = { 5, 4, 3, 2 };
<span style="color: #2b91af">Keypad</span> keypad = <span style="color: #2b91af">Keypad</span>(<span style="color: #6f008a">makeKeymap</span>(keys), rowPins, colPins, ROWS, COLS);
<span style="color: blue">char</span> key, option;
<span style="color: blue">int</span> quantity;
<span style="color: #6f008a">bool</span> flag;
 
<span style="color: blue">void</span> setup() {
	Serial.begin(9600);
	Serial.print(<span style="color: #a31515">"Iniciando menu..."</span>);
}
 
<span style="color: blue">void</span> loop() {
	quantity = 0;
	Serial.println(<span style="color: #a31515">"Seleccione una opcion (A-D):"</span>);
	flag = <span style="color: #6f008a">true</span>;
	<span style="color: blue">while</span> (flag) {
		key = keypad.getKey();
		<span style="color: blue">if</span> (key) {
			<span style="color: blue">switch</span> (key)
			{
			<span style="color: blue">case</span> <span style="color: #a31515">'A'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'B'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'C'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'D'</span>:
				Serial.println(key);
				option = key;
				flag = <span style="color: #6f008a">false</span>;
				<span style="color: blue">break</span>;
			<span style="color: blue">default</span>:
				<span style="color: blue">break</span>;
			}
		}
	}
	Serial.println(<span style="color: #a31515">"Ingrese una cantidad :"</span>);
	Serial.println(<span style="color: #a31515">"(Presione '#' para finalizar)"</span>);
	flag = <span style="color: #6f008a">true</span>;
	<span style="color: blue">while</span> (flag) {
		key = keypad.getKey();
		<span style="color: blue">if</span> (key) {
			<span style="color: blue">switch</span> (key)
			{
			<span style="color: blue">case</span> <span style="color: #a31515">'0'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'1'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'2'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'3'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'4'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'5'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'6'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'7'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'8'</span>:
			<span style="color: blue">case</span> <span style="color: #a31515">'9'</span>:
				Serial.print(key);
				quantity = quantity * 10 + key - <span style="color: #a31515">'0'</span>;
				<span style="color: blue">break</span>;
			<span style="color: blue">case</span> <span style="color: #a31515">'#'</span>:
				Serial.println();
				flag = <span style="color: #6f008a">false</span>;
			<span style="color: blue">default</span>:
				<span style="color: blue">break</span>;
			}
		}
	}
}
</pre>
Hasta la próxima!
--Rp]]></content:encoded>
    </item>
    <item>
      <title>Tutorial ELL</title>
      <link>https://docs.microsoft.com/archive/blogs/robep/tutorial-ell</link>
      <pubDate>Sun, 02 Jul 2017 22:27:13 GMT</pubDate>
      <dc:creator><![CDATA[robep]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/robep/?p=595</guid>
      <description><![CDATA[En el último artículo les hablé de la nueva tecnología Embedded Learning Library, después de un par...]]></description>
      <content:encoded><![CDATA[En el último artículo les hablé de la nueva tecnología Embedded Learning Library, después de un par de  problemas con las referencias logré correr el ejemplo en mi PC :) aún debo trabajar un poco para correr la demo en mi Raspberry Pi, pero debo reconocer que ha sido divertido, he probado con un par de objetos y el reconocimiento funciona de forma intermitente, algunas veces muy bien, otras no tanto; intenté con algunos objetos que el modelo debería reconocer como teclados, mouse, reloj de arena, etc.

Mi mejor resultado fue con un teclado de computadora, los otros intentos tuvieron un porcentaje muy bajo y por alguna razón muchas cosas fueron identificadas como un modem, de donde sacan suficientes imágenes de un modem para entrenar un modelo en esta época? y aun peor, vale la pena hacerlo? ¯\_(ツ)_/¯

En fin, muchos de los elementos que reconoce el modelo son animales, en cuanto logre montarlo en mi Raspberry lo probaré con mi vieja enciclopedia!

<a href="https://msdnshared.blob.core.windows.net/media/2017/07/ell.png"><img width="500" height="271" class="aligncenter size-mediumlarge wp-image-605" alt="" src="https://msdnshared.blob.core.windows.net/media/2017/07/ell-500x271.png" /></a>

Hasta la próxima!
--Rp]]></content:encoded>
    </item>
  </channel>
</rss>