Un primer proyecto en nanoFramework es la aplicación mínima que comprueba que el entorno, el firmware y la placa funcionan.
Si en el mundo de la programación de escritorio el “Hola Mundo” es imprimir un texto en pantalla, en el mundo de la electrónica el equivalente es hacer parpadear un LED. Es el test definitivo de que el hardware funciona, el compilador compila y el código se está ejecutando.
En esta entrada vamos a crear nuestro primer proyecto desde cero. Veremos que, aunque el código final es sencillo, la estructura que rodea al proyecto es mucho más profesional y organizada que un simple sketch .ino de Arduino.
Crear la solución en Visual Studio
Lo primero es crear el proyecto. Abre Visual Studio y selecciona “Crear un nuevo proyecto”.
En el buscador de plantillas, escribe nanoFramework. Si instalaste la extensión correctamente, verás varias opciones. Nosotros elegiremos Blank Application (nanoFramework).
Dale un nombre (por ejemplo, HolaMundoNano) y una ubicación. Al pulsar “Crear”, Visual Studio generará la estructura de archivos.
Estructura de la solución
Si vienes de Arduino, la estructura puede resultar extraña al principio. No tenemos un único archivo de código, sino una solución .sln que contiene un proyecto .csproj.
Echemos un vistazo al explorador de soluciones:
Properties/AssemblyInfo.cs
Información del ensamblado (versión, autor, copyright).
Referencias
Aquí no se hace #include. Aquí se añaden referencias a librerías compiladas (DLLs).
packages.config
El archivo que gestiona los paquetes NuGet. Indica qué librerías externas estamos usando y sus versiones.
Program.cs
Nuestro archivo de código principal. Aquí está el punto de entrada.
A diferencia de Arduino, donde setup() y loop() están ocultos en el core, en C# tenemos una función Main(). Nosotros tenemos el control total del flujo de ejecución desde el milisegundo cero.
Hola Mundo por consola
Antes de encender luces, vamos a saludar. Abre el archivo Program.cs. Verás algo parecido a esto:
using System;
using System.Diagnostics;
using System.Threading;
namespace HolaMundoNano
{
public class Program
{
public static void Main()
{
Debug.WriteLine("Hello from nanoFramework!");
Thread.Sleep(Timeout.Infinite);
}
}
}Fíjate en Debug.WriteLine. Esto es importante.
En Arduino usábamos Serial.print y necesitábamos inicializar el puerto serie (Serial.begin). Aquí no.
nanoFramework redirige la salida de depuración directamente a la ventana de “Salida” de Visual Studio a través del mismo cable USB, sin que tengas que configurar puertos UART manualmente.
- Asegúrate de que tu placa está conectada y seleccionada en el Device Explorer.
- Pulsa F5 (o el botón de “Iniciar”).
Visual Studio compilará el código, lo subirá al microcontrolador y adjuntará el depurador. En la ventana de “Salida” (Output) verás:
Hello from nanoFramework!
Blinky: hacer parpadear un LED
Ahora vamos a lo bueno. Queremos controlar un pin GPIO.
En .NET “full” o en Arduino, las funciones de hardware suelen venir incluidas. En nanoFramework, para ahorrar memoria, el núcleo es mínimo. Si quieres usar GPIO, tienes que instalar la librería correspondiente.
Instalar el paquete NuGet
Haz clic derecho en tu proyecto (en el Explorador de Soluciones) -> Administrar paquetes NuGet.
Ve a la pestaña Examinar.
Busca: nanoFramework.System.Device.Gpio.
Instala la última versión estable.
Acostúmbrate a esto. ¿Quieres usar I2C? NuGet. ¿Quieres conectar a Wi-Fi? NuGet. Esto mantiene tu firmware ligero, incluyendo solo lo que realmente usas.
El código
Ahora vamos a modificar Program.cs para hacer parpadear el LED integrado de la placa.
En la mayoría de ESP32 DevKit, el LED azul integrado está en el GPIO 2.
using System;
using System.Device.Gpio; // <--- Importante: El namespace del hardware
using System.Threading;
namespace HolaMundoNano
{
public class Program
{
public static void Main()
{
// 1. Definimos el pin (GPIO 2 es común en ESP32)
int pinNumber = 2;
// 2. Instanciamos el controlador
GpioController gpio = new GpioController();
// 3. Abrimos el pin y lo configuramos como SALIDA
GpioPin led = gpio.OpenPin(pinNumber, PinMode.Output);
// 4. Bucle infinito (equivalente al loop de Arduino)
while (true)
{
// Encendemos (Write recibe un valor PinValue)
led.Write(PinValue.High);
Console.WriteLine("LED Encendido");
// Esperamos 1000ms (1 segundo)
Thread.Sleep(1000);
// Apagamos
led.Write(PinValue.Low);
Console.WriteLine("LED Apagado");
Thread.Sleep(1000);
}
}
}
}Fíjate en la orientación a objetos:
GpioController: No manipulamos registros directamente. Creamos un objeto que representa al controlador de entradas/salidas del chip.OpenPin: Pedimos al controlador que nos “reserve” el pin 2. Esto devuelve un objetoGpioPin.led.Write(...): Actuamos sobre el objetoled, no sobre un número global.Thread.Sleep(1000): Esto detiene el hilo actual durante 1000ms. A diferencia dedelay()en Arduino, que bloquea el procesador, en un sistema multihilo esto simplemente “duerme” esta tarea, permitiendo que el sistema haga otras cosas (como mantener la conexión Wi-Fi) en segundo plano.
Despliegue y depuración
Dale a F5 otra vez.
Verás cómo el LED de tu placa empieza a parpadear. Pero lo mejor no es eso. Lo mejor es lo siguiente:
Ve a la línea led.Write(PinValue.High);.
Haz clic en el margen izquierdo para poner un punto rojo (Breakpoint).
El LED dejará de parpadear y Visual Studio se iluminará. El programa se ha pausado en el chip.
Pasa el ratón por encima de la variable pinNumber. ¡Verás su valor!
Puedes pulsar F10 para avanzar paso a paso y ver cómo se ejecuta cada línea. Esto es lo que diferencia a un juguete de una herramienta profesional. Poder depurar el hardware paso a paso te ahorrará cientos de horas de frustración adivinando por qué algo no funciona.
Hemos creado una solución, instalado una librería vía NuGet y escrito código orientado a objetos para manejar hardware básico.
La estructura puede parecer más verbosa que digitalWrite(2, HIGH), pero es infinitamente más escalable. Cuando tengas 50 sensores y 3 hilos de ejecución, agradecerás este orden.