De todo un poco.

Mostrando entradas con la etiqueta C#. Mostrar todas las entradas
Mostrando entradas con la etiqueta C#. Mostrar todas las entradas

31/1/21

nanoFramework es una plataforma para programar dispositivos embebidos utilizando C#. No confundir con .Net Micro Framework este es para dispositivos más grandes (Tipo RaspberryPi), que tienen sistema operativo (generalmente Linux). 

Al no requerir sistema operativo, puede utilizarse hardware más modesto y por lo tanto más barato. Yo para las pruebas he utilizado una placa de desarrollo basado en el chip ESP32 que cuesta sobre 6.5€ o incluso más barato si lo buscamos en páginas chinas.

Es posible utilizar tanto el Visual Studio Code, como el Visual Studio. Yo me decanté por el segundo ya que estoy acostumbrado a utilizarlo.

Primeros pasos con Visual Studio

Descargamos el Visual Studio Community 2019. Yo siempre lo instalo en inglés ya que es más facil buscar información sobre errores por internet.

Una vez instalado habrá que ir al menú "Tools"->"NuGet Package Manager"->"Package Manager Settings"->"Package Sources" y añadir un origen nuevo:

Name: nanoFrameworkk

Source: https://pkgs.dev.azure.com/nanoframework/feed/_packaging/sandbox/nuget/v3/index.json

Después ir a "Extensions"->"Manage Extensions"->"Online" y buscamos nanoFramework e instalamos esa extensión.

Preparando el hardware ESP32

Para poder trabajar con el hardware primero tenemos que cargarle un firmware con el Core de nanoFramework y que así Visual Studio lo detecte como dispositivo válido.

Para ello debemos conectar el ESP con el cable USB al PC. A continuación vamos al "Administrador de dispositivos" de windows dentro del apartado "Puertos (COM y LPT)" y tomamos nota del puerto asignado al ESP32. En mi caso el COM3.

El siguiente paso en el Visual Studio es ir al menú "Extensions"->"Tools"->"NuGet Package Manger"->"Package Manager console" y ejecutar lo siguiente:

nanoff --serialport COM3 --target ESP32_WROOM_32 --update -d v

 Tras ejecutar ese comando mantener presionado el botón BOOT en la placa para que se inicie la escritura del firmware.

Si devuelve el error E4005 puede ser que el Visual Studio esté bloqueando el puerto, para evitarlo hay que ir al menú del Visual Studio "View"->"Other Windows"->"Device Explorer" y darle al botón "Disable scan device in Visual Studio"

Una vez que se cargó el firmware en el ESP32 debemos asegurarnos que el Visual Studio ya reconoce el dispositivo, para ello vamos a "View"->"Other Windows"->"Device Explorer" Si no aparece tenemos que asegurarnos que no está activo el botón "Disable scan device in Visual Studio"

 


En este punto ya estamos preparados para hacer nuestro primer desarrollo.

Hola Mundo en ESP32

Para hacer nuestro primer programa tendremos que ir al Visual Studio y crear un nuevo proyecto de tipo "Blank Application (nanoFramework)" y ya nos creará nuestra primera aplicación.

public class Program
    {
        public static void Main()
        {
            Debug.WriteLine("Hello from nanoFramework!");

            Thread.Sleep(Timeout.Infinite);
        }
    }

Si ya tenemos seleccionado el ESP32 en la ventana "Device Explorer", dándole al botón de play el Visual Studio se encargará de compilar el código, desplegarlo en el dispositivo e iniciar la depuración.


Podremos poner interrupciones en el código y podremos ir depurando paso a paso o incluso ver el valor de variables como haríamos normalmente con cualquier otra aplicación desarrollada en C#.

Accediendo al hardware desde C#

Las placas de desarrollo ESP32 suelen tener un led conectado al pin 2, así que con el siguiente código podemos hacer parpadear dicho led sin necesidad de tener nada más.

using System.Device.Gpio;
using System.Threading;

namespace Blinky
{
	public class Program
    {
        private static GpioController _gpioController;
        public static void Main()
        {
            _gpioController = new GpioController();

            GpioPin led = _gpioController.OpenPin(2,PinMode.Output);

            led.Write(PinValue.Low);

            while (true)
            {
                led.Toggle();
                Thread.Sleep(125);               
            }
        }
    }
}


Si además conectamos un led a dicho pin (con su correspondiente resistencia de 100Ω) podremos ver cómo parpadean a la vez el led de la placa y el conectado al pin 2.


 ¿Donde conseguir más ejemplos?

El mejor sitio para obtener un montón de ejemplos es el propio github repositorio Samples del proyecto nanoFramework. 

Muchos de esos proyectos son independientes del hardware utilizado, por lo que algunos requieren pequeñas modificaciones para funcionar con nuestro ESP32.




 



2/11/15


Si te ves en la necesidad de generar puntos aleatorios en una zona en concreta, pero además tienes la restricción de que todos los puntos tienen que ser en una zona donde haya agua, igual la siguiente guía te ayuda. Así es como lo hice yo:


En primer lugar obtener todas las líneas que separan la tierra y el agua (en mi caso con las líneas de costa me llegaba). El lugar con datos libres y con mayor detalle lo he encontrado en la web de OpenStreetMapData en el siguiente enlace: Water polygons

Para recortar la zona que me interesaba utilicé el software libre QGIS. Nunca antes había usado ese software, pero siguiendo el tutorial "Tutorial for creating polygons in QGIS" conseguí mi objetivo muy fácilmente.

En el punto 6  del tutorial, explica como cargar los datos descargados de OpenStreetMapData.

En el punto 8 como dibujar un polígono que delimitará la zona sobre la que se está interesado.

Después utilizando el polígono se puede recortar una zona del mapa generando la forma deseada.

Para exportar la forma obtenida (SHP) a formato WKT solo hay que seguir el siguiente artículo: "Cómo convertir un shapefile en WKT"

Una vez se ha obtenido el WKT ya se puede generar desde .Net puntos aleatorios entre la mínima y la máxima latitud y entre la mínima y máxima longitud de la figura y comprobar si el punto obtenido está dentro de la figura (ya que si la forma es irregular puede que cuadre fuera)

public static double GetRandomDouble(Random rnd, double minimum, double maximum)
{
    return rnd.NextDouble() * (maximum - minimum) + minimum;
}

public static DbGeography GetRandomPointInZone(DbGeography validZone,Random rnd)
{
    DbGeography pos = null;

    double minlat = double.MaxValue;
    double maxlat = double.MinValue;
    double minlon = double.MaxValue;
    double maxlon = double.MinValue;

    for (int i = 1; i <= validZone.PointCount; i++)
    {
        var point = validZone.PointAt(i);
        if (point.Latitude != null && minlat > point.Latitude) minlat = (double)point.Latitude;
        if (point.Longitude != null && minlon > point.Longitude) minlon = (double)point.Longitude;
        if (point.Latitude != null && maxlat < point.Latitude) maxlat = (double)point.Latitude;
        if (point.Longitude != null && maxlon < point.Longitude) maxlon = (double)point.Longitude;
    }

    int retry = 0;
    while (pos == null || !pos.Intersects(validZone)) //Aquí comprobamos que la posición aleatoria está dentro de la zona.
    {
        var latitude = GetRandomDouble(rnd, minlat, maxlat);
        var longitude = GetRandomDouble(rnd, minlon, maxlon);

        var wkt = String.Format("POINT({0} {1})", longitude.ToString(CultureInfo.InvariantCulture), latitude.ToString(CultureInfo.InvariantCulture));
        pos = DbGeography.PointFromText(wkt, 4326);
        retry++;

        if (retry > 1000)
            throw new Exception("Parece un bucle infinito, tras 1000 reintentos no se ha podido obtener una posición dentro de la zona válida");
    }
    return pos;
}

static void Main(string[] args)
{
    var rnd = new Random();

    var validZone = DbGeography.PolygonFromText(ConfigurationManager.AppSettings["ValidZone"], 4326);

    var posRandom = GetRandomPointInZone(validZone, rnd);

    Console.WriteLine("Posición aleatoria dentro de zona: Latitud {0}, Longitud {1}",posRandom.Latitude,posRandom.Longitude);
    Console.ReadKey();
}
En mi caso necesitaba ir generando los puntos aleatorios desde código en C#. Si en tu caso eso no es necesario, utiliza el propio QGIS para generar puntos aleatorios. Seguro que lo hace de una forma mucho más eficiente ;)

13/10/15