Na primeira parte dessa série, Comunicação serial com C# e Arduino, foi exibido como criar um terminal simples usando o Visual Studio com a linguagem C#. Foi explicado passo a passo como inserir os componentes e a programação da aplicação para funcionar parecida com o terminal serial que vem no programa Arduino.

Neste artigo vamos construir uma aplicação de comunicação serial para ligar/desligar um LED no Arduino através de um botão e exibir o valor da tensão presente no pino analógico (A0). Para facilitar o desenvolvimento vamos aproveitar a estrutura desenvolvida na parte 1 desta série.

O primeiro passo é retirar o textBoxEnviar e o textBoxReceber, deixando a interface da seguinte forma:

comunicação-serial
Figura 1 – Alterando o exemplo Comunicação Serial com C# e Arduino – Parte 1

Agora vamos aproveitar o btEnviar para servir como o botão que ligará e desligará o LED na placa Arduino. Vamos trocar a propriedade Name para btLigar e Text para Ligar, e deverá ficar conforme figura abaixo:

comunicação-serial-btLed
Figura 2 – Botão para ligar/desligar o LED através da comunicação Serial

Para exibir a tensão na entrada analógica do Arduino vamos inserir um label logo abaixo do botão Ligar. Trocar a propriedade Name para lbValor e em Text inserir Tensão: 0,0 V. Para ficar mais visível pode-se trocar a fonte e aumentar o seu tamanho. No nosso exemplo foi escolhida a fonte Arial com tamanho 16, conforme exibido na figura abaixo:

comunicação-serial
Figura 3 – Label para indicação da tensão

Para ficar melhor a disposição das informações no Form, vamos alinhar os componentes ao centro, conforme figura abaixo:

comunicação-serial-form-final
Figura 4 – Ajustes finais no Form para comunicação serial

Note que  foi adicionado um label, logo acima  do btLigar, com a propriedade Text igual a LED, que servirá para indicar que o botão acionará o LED.

Esse layout servirá para nossa aplicação, para ser lida a tensão no pino analógico do Arduino. Vamos inserir um componente Timer que será responsável para enviar o dado de leitura do valor analógico em tempo em tempos. Deve ser alterada a propriedade Name para timerLeitura e Interval para 500, conforme exibido a seguir:

comunicação-serial-timer
Figura 5 – Alteração no intervalo do Timer

Programação para aplicação de comunicação serial

Com os componentes inseridos podemos passar para a codificação da nossa aplicação. Deve ser criado o evento do botão Ligar, e para isso basta dar um duplo clique no botão. Insira o seguinte código neste evento:

private void btLigar_Click(object sender, EventArgs e)
{
            if(serialPort1.IsOpen == true)
            {
                serialPort1.Write("A");
                if(btLigar.Text== "Ligar")
                {
                    btLigar.Text = "Desligar"; 
                }
                else
                {
                    btLigar.Text = "Ligar";
                }
            }
 }

Para enviar o comando de leitura para o arduino é necessário criar o evento tick do timerLeitura, e para isso basta dar duplo clique no timer na aba Design. No evento deve ser inserido o seguinte código:

private void timerLeitura_Tick(object sender, EventArgs e)
        {
            if(serialPort1.IsOpen == true)
            serialPort1.Write("T");
        }

Sempre que enviado o caractere ‘T’ o Arduino retornará o valor lido no pino analógico A0 convertido para digital. O código com a formatação do valor a ser exibido, assim como todo o código da aplicação, é exibido a seguir:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;  // necessário para ter acesso as portas

namespace interfaceArduinoVS2013
{
    public partial class Form1 : Form
    {

        string RxString;

        public Form1()
        {
            InitializeComponent();
            timerCOM.Enabled = true;
        }

        private void atualizaListaCOMs()
        {
            int i;
            bool quantDiferente;    //flag para sinalizar que a quantidade de portas mudou

            i = 0;
            quantDiferente = false;

            //se a quantidade de portas mudou
            if (comboBox1.Items.Count == SerialPort.GetPortNames().Length)
            {
                foreach (string s in SerialPort.GetPortNames())
                {
                    if (comboBox1.Items[i++].Equals(s) == false)
                    {
                        quantDiferente = true;
                    }
                }
            }
            else
            {
                quantDiferente = true;
            }

            //Se não foi detectado diferença
            if (quantDiferente == false)
            {
                return;                     //retorna
            }

            //limpa comboBox
            comboBox1.Items.Clear();

            //adiciona todas as COM diponíveis na lista
            foreach (string s in SerialPort.GetPortNames())
            {
                comboBox1.Items.Add(s);
            }
            //seleciona a primeira posição da lista
            comboBox1.SelectedIndex = 0;
        }

        private void timerCOM_Tick(object sender, EventArgs e)
        {
            atualizaListaCOMs();
        }

        private void btConectar_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen == false)
            {
                try
                {
                    serialPort1.PortName = comboBox1.Items[comboBox1.SelectedIndex].ToString();
                    serialPort1.Open();

                }
                catch
                {
                    return;

                }
                if (serialPort1.IsOpen)
                {
                    btConectar.Text = "Desconectar";
                    comboBox1.Enabled = false;

                }
            }
            else
            {

                try
                {
                    serialPort1.Close();
                    comboBox1.Enabled = true;
                    btConectar.Text = "Conectar";
                }
                catch
                {
                    return;
                }

            }
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            if(serialPort1.IsOpen == true)  // se porta aberta 
             serialPort1.Close();            //fecha a porta
        }

        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            RxString = serialPort1.ReadLine();             //le o dado disponível na serial
            this.Invoke(new EventHandler(trataDadoRecebido));   //chama outra thread para escrever o dado no text box
        }

        private void trataDadoRecebido(object sender, EventArgs e)
        {
            Double tensao = Convert.ToDouble(RxString)*5/1023;
            lbValor.Text = "Tensão: " + Convert.ToString(Math.Round(tensao, 1)) + " V";
        }

        private void btLigar_Click(object sender, EventArgs e)
        {
            if(serialPort1.IsOpen == true)
            {
                serialPort1.Write("A");
                if(btLigar.Text== "Ligar")
                {
                    btLigar.Text = "Desligar"; 
                }
                else
                {
                    btLigar.Text = "Ligar";
                }
            }

        }

        private void timerLeitura_Tick(object sender, EventArgs e)
        {
            if(serialPort1.IsOpen == true)
            serialPort1.Write("T");
        }
    }
}

O código para o upload no Arduino é exibido a seguir:

const int LED = 13;

int valor_AD = 0;
int valor_leituras = 0;
byte i = 0;

void setup() {
  Serial.begin(9600);    //configura comunicação serial com 9600 bps
  pinMode(LED,OUTPUT);   //configura pino do led como saída
}
void loop() {
   if (Serial.available()) //se byte pronto para leitura
   {
    switch(Serial.read())      //verifica qual caracter recebido
    {
      case 'A':                  //caso 'A'
        digitalWrite(LED,!digitalRead(LED)); //inverte estado do LED
      break;
      
      case 'T':
        Serial.println(valor_AD);
      break;
    }
  }
  
  //MEDIA DE LEITURAS
  valor_leituras += analogRead(A0);
  i++;
  
  if(i==16)
  {
    i = 0;
    valor_AD = valor_leituras>>4;
    valor_leituras = 0;
  }
  
}

Note no código acima que foi feita uma média de 16 leituras do sinal analógico.

Depois de feito o upload  para o Arduino e iniciada a aplicação, com a correta conexão com o Arduino o resultado vai ser bem semelhante ao da imagem a seguir:

comunicação-serial-teste-aplicação
Figura 6 – Teste da aplicação final

Variando o valor da entrada analógica com um potenciômetro, será exibido o valor da tensão presente no pino. Caso o botão Ligar seja pressionado, o LED no pino 13 será ligado e, se pressionado novamente, será desligado.

O Download desta aplicação junto com o programa Arduino pode ser feita através do link: [wpdm_asset id=’2′].

Lembre-se, você deve ser registrado e estar logado no site para fazer o download.

Conclusão

Desenvolver uma interface gráfica para comunicação serial e controle com Arduino é bem simples utilizando a plataforma .Net. Você pode criar botões e indicadores e facilmente interagir com Arduino. A partir do exemplo apresentado você poderá desenvolver interfaces para controlar o seu Arduino e exibir valores no seu computador de uma forma fácil e rápida.

Aproveite o exemplo, crie novos botões para ligar/desligar dispositivos em outros pinos e leia as outras entradas analógicas.

Espero que este artigo possa ser a porta de entrada para suas aplicações gráficas interagindo com o Arduino. Conte para nós as suas experiências com essa plataforma.

Saiba mais

Arduino – Primeiros Passos

Arduino UNO

Arduino – Comunicação Serial