Arduino, potenciómetro, puerto serial y C#

Había leído en varios sitios que un Arduino puede comunicarse con todo tipo de software por medio del puerto serial y me pareció interesante intentarlo con C#. Al final de varios experimentos hice un programita interesante: controlar una barra (ASCII) en una consola por medio de un potenciómetro.

Arduino-Volumen-F1

Se que parece muy sencillo pero esto es lo básico que se necesita para controlar cualquier programa con cualquier tipo de sensor (de luz, de movimiento, de temperatura), botones, potenciómetros, etc. La verdad es que las posibilidades son ilimitadas. Pero ahora sí, vamos a lo bueno.

¿Qué se necesita?

  • Un Arduino (y su cable USB y su IDE claro)
  • Un potenciómetro (cualquier tamaño es bueno)
  • Una computadora
  • Visual C# 2010 Express. Es para PC, es gratis y lo pueden bajar del link que acabo de poner.

Si han experimentado o al menos visto como funcionan los ‘sketches’ que trae como ejemplo el IDE de arduino ya sabrán un poco como funciona el Serial Monitor. Si en nuestro programa escribimos una línea como Serial.print(“a”); y luego abrimos el Serial Monitor, veremos en algún momento una a en pantalla dependiendo del código que ‘rodee’ a la línea.

Antes de hacer el programa del post, vamos a hacer un Serial Monitor como el que trae el IDE de arduino pero en C#. Una simple ventana de consola que nos muestre lo que sea que arduino esté mandado por el puerto serial.

Serial Monitor en C#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using System;
using System.IO.Ports;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            SerialPort port = new SerialPort("COM6", 9600);
            port.Open();
            if (port.IsOpen)
            {
                while (true)
                    Console.Write(port.ReadExisting());
            }
            port.Close();
        }
    }
}

Lo primero nuevo es la línea 2. Simplemente estamos ‘abriendo’ las herramientas que tiene .NET para trabajar con el puerto serial.

La línea 10 puede parecer bastante confusa si nunca has programado con clases. En pocas palabras estamos declarando una variable (port) que contiene la configuración del puerto paralelo que vamos a usar. Dentro del paréntesis tiene que ir primero el nombre del puerto donde está trabajando nuestro Arduino (para saber esto abran su Administrador de Dispositivos y luego busquen algo que diga arduino en el apartado de Puertos), en mi caso COM6, y enseguida el Baud Rate (señales por segundo) que para trabajar con arduino es siempre 9600 (¿Recuerdan como se empieza a trabajar con Serial?: Serial.begin(9600);).

La línea 11 se explica por sí sola: abrir el puerto.

Luego, en la línea 12, una condición para comprobar que se haya abierto el puerto.

Luego un ciclo infinito dentro del cual hay una instrucción para imprimir en pantalla dentro de la cual hay una instrucción port.ReadExisting() que lee lo que sea que le esté llegando al puerto serial.

Para compilarlo copien este código, abran Visual C#, Nuevo proyecto, Console Aplication, pegan el código y listo. Verán que no hace absolutamente nada jaja, porque no hemos puesto nuestro arduino a mandar alguna señal a través del puerto serial. Así que vamos ahora a usar uno de los ejemplos que hay en la página oficial de Arduino: AnalogReadSerial. Vayan a ese link y armen el circuito que les muestran (es el que vamos a usar durante todo el post), copien el código a un sketch en su IDE de arduino y súbanlo a su arduino. Luego corran el programa que acabamos de hacer en C#. Si todo salió bien deben de estar viendo un chorro de números ‘cayendo’ por su pantalla que varían de 0 a 1023 al mover su potenciómetro.

Arduino-Volumen-F2

Ya estando seguros que nuestro puerto serial se está comportando correctamente podemos hacer nuestro dos programas:

SerialPot, para que el Arduino nos mande los datos

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int pot = A0;
int potval = 0;
 
void setup()
{
  Serial.begin(9600);
}
 
void loop()
{
  potval = analogRead(pot);
  if(Serial.available() > 0)
  {
    int in = Serial.read();
    if(in == 'a')
    {
      Serial.println(map(potval, 0, 1023, 0, 80));
      delay(100);
      in = 0;
    }
  }
}

La línea 6 es con la que iniciamos la comunicación por serial en nuestro arduino. Como les decía antes, para trabajar con arduino el Baud Rate raramente no es 9600.

En la línea 11 leemos el valor del potenciómetro y lo guardamos en la variable potval.

Luego hay una condición para asegurarnos que hay algún otro software que quiera intercambiar datos por medio del puerto serial.

Luego, en la variable in vamos a guardar lo que sea que el otro software nos esté mandando a través del puerto serial.

Si lo que nos mandó es una simple a, entonces procedemos a mandarle los datos. Esto es una forma de que nuestro programa en C# le diga a Arduino “hey, ya estoy listo, mándame los datos“.

Luego mandamos vía puerto serial el valor de potval pero ‘mapeado‘ de tal forma que su valor mínimo sea 0 y su máximo 80. ¿Porqué de 0 a 80? pues porque la pantalla de consola tiene 80 caracteres de ancho y la idea es que nuestro potenciómetro simbolize una barra ASCII a lo largo de esos 80 caracteres.

Luego un delay para ‘calmar’ los envíos un poco. Y finalmente igualamos in a 0 para que arduino no vuelva a mandar los datos hasta que nuestro programa en C# esté listo nuevamente.

SerialArduinCom, para recibir los datos y convertirlos a una barra ASCII

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using System;
using System.IO.Ports;
 
namespace SerialArduinoCom
{
    class Program
    {
        static void Main(string[] args)
        {
            SerialPort port = new SerialPort("COM6", 9600);
            port.Open();
            if (port.IsOpen)
            {
                while (true)
                {
                    port.Write("a");
                    string t = port.ReadLine();
                    int n = int.Parse(t);
                    Console.SetCursorPosition(0, 4);
                    Console.Write(n);
                    for (int i = 0; i < n; i++)
                    {
                        Console.SetCursorPosition(i, 5);
                        Console.Write("-");
                    }
                    for (int i = n; i < 80; i++)
                    {
                        Console.SetCursorPosition(i, 5);
                        Console.Write(" ");
                    }
                }
            }
            port.Close();
        }
    }
}

Una cosa importante: los datos que mandamos por el puerto serial siempre viajan en forma de cadenas (strings, palabras, no números). No estoy seguro si esto es siempre, pero en mi experiencia así ha sido.

Así que la primera línea diferente al programa anterior es la 16, donde mandamos el mensaje que mencioné antes: ”hey, ya estoy listo, mándame los datos“.

Dicho eso, en la línea 17 guardamos en la variable t lo que sea que nuestro arduino nos esté mandando.

En 18, convertimos esa variable tipo string t en una variable tipo int n.

Luego simplemente la mostramos en determinado punto de la pantalla (0, 4).

Luego tenemos dos ciclos, uno va de 0 a n e imprime guiones (-), el otro va de n a 80 e imprime espacios ( ). Con esto nuestra barra se imprime en pantalla teniendo el largo que valga n, que a fin de cuentas es el valor de nuestro potenciómetro.
Arduino-Volumen-C1
No se a ustedes pero a mí me pareció genial :D

  1. *-* dice:

    Estuvo bastante entretenido el post…
    buen uso de un potenciometro jeje

  2. Marco dice:

    hola necesito ayuda en un proyecto es el siguiente:
    Realice un programa para controlar el alumbrado eléctrico de una vivienda, mediante el computador y utilizando el lenguaje C. Debe diseñar la maqueta de la vivienda, el circuito eléctrico con led´s, debe programar el puerto de la impresora para que controle todo el circuito y lógicamente el programa que maneja todo.
    porfa si pudieras ayudarme lo agradeceria much.

  3. reynaldo dice:

    deberias colocar tambien el circuito en la proxima

  4. san dice:

    como hago esa salida por la terminal de ubuntu 11.10

  5. BaAby dice:

    Hola estoy haciendo una aplicacion en c sharp 2010 para imprimir recibos en una terminal por puerto COM, el problema es que no se como empezar. Soy nueva en esto y se me complica mucho.

  6. Rodofo dice:

    Genial, mi primera comunicación por puerto serial. Gracias

Hola, escribe aquí tu comentario: