Comunicação Serial com C# e Arduino – Parte 2

Comunicação
Este post faz parte da série Comunicação Serial com C# e Arduino

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

Comunicação Serial com C# e Arduino

Comunicação Serial com C# e Arduino – Parte 1
Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
73 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Francisco Dórea
Francisco Dórea
15/01/2021 11:56

Oi Fábio,
Obrigado por disponibilizar conhecimentos úteis e efetivos desse mundo de embarcados. Pode nos dizer como colocar esse programa na bandeja do Windows (acho que é o SystemTray), ali ao lado do relógio para monitorar a comunicação que chega pela porta serial?

vinicyus
vinicyus
12/11/2020 17:06

muito bom amigo, só que

Last edited 5 anos atrás by vinicyus
Vinícius
Vinícius
10/05/2020 16:06

Olá, não é necessário configurar o baudRate?

joao
joao
06/02/2020 02:47

Olá, fiz um programa parecido que necessita de envios constantes (alta frequencia) e embora eu tenha aumentado o baundRate o intervalo de amostragem continua em 45ms aproximadamente. Existe uma forma de diminuir este intervalo?

claudemir
claudemir
16/01/2019 20:21

como faço para quando estiver acusando que a porta analógica esta acionada 5 = on e quando não estiver 0 = off teria como fazer com imagens ou até mesmo como escrita ?? ficaria grato por essa ajuda , e outra duvida o serial não funciona direto fazendo comunicação não era pra ficar direto ?? alguém disposto em me ajudar estou fazendo um trabalho e só falta isso !!

Mariana
Mariana
12/11/2018 17:39

Ótima explicação Fábio! Apos a comunicação entre o arduino e C#, gostaria de plotar um gráfico de acordo com as informações vindas do arduino, como se fosse um osciloscópio digital. Como devo prosseguir?

Yan
Yan
Reply to  Mariana
27/12/2018 11:41

Oi Mariana, tenho um projeto pronto usando o WPF para receber dados vindos do SerialPort e plotar gráfico. Qualquer coisa entre em contato por e-mail.

yan.m.esteves@gmail.com

Mateus
Mateus
Reply to  Yan
18/04/2019 20:05

podes me enviar este projecto
tiagomat200@gmail.com

CLAUDEMIR JUNIOR
CLAUDEMIR JUNIOR
05/09/2018 02:57

Eu queria uma ajuda a respeito do Sensor , em vez de medir tensão eu queria medir um valor do UTRASONIC tem como me ajudar ??? estou com dificuldades , eu só queria ler o valor do sensor em uma Label !!

Reinaldo Teixeira de Paula
Reinaldo Teixeira de Paula
Reply to  CLAUDEMIR JUNIOR
22/10/2018 00:33

// VA EM EVENTOS DO SERIALPORT E CHAME ESSE EVENTO
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{

RxString = serialPort1.ReadExisting(); //LE O DADO DISPONÍVEL NA SERIAL PORTA..
this.Invoke(new EventHandler(tratadoRecebido)); //CHAMA OUTRA THREAD PARA ESCREVER O DADO NO LABEL)

}
catch (Exception ERRO)
{
MessageBox.Show(ERRO.Message);
}

}

//METODO TRATA OS DADOS RECEBE ENVIA …
private void tratadoRecebido(object sender, EventArgs e)
{

txtultrassonico.AppendText(RxString);

}

//ESCREVA ESSE CODIGO NO LOAD DO FORM
if (serialPort1.IsOpen == true) // PORTA ESTÁ ABERTA
serialPort1.Write(“distance”);

claudemir
claudemir
Reply to  Reinaldo Teixeira de Paula
16/01/2019 20:20

obrigado me ajudou muito , agora eu precisava de outra ajuda , como faço para quando estiver acusando que a porta analógica esta acionada 5 = on e quando não estiver 0 = off teria como fazer com imagens ou até mesmo como escrita ?? ficaria grato por essa ajuda , e outra duvida o serial não funciona direto fazendo comunicação não era pra ficar direto ??

Anderson
Anderson
06/06/2018 20:52

ao executar o programa ele não lista as portas seriais, já coloquei portas virtuais, conectei o arduino e nada. o que pode ser?

victor matos
victor matos
08/02/2018 12:30

olá Fabio e todos os leitores do site. gostaria de saber se alguém pode me indicar um tutorial de como enviar os arquivos .hex para o microcontrolador usando o visual. agradeço desde já!

Marcio
Marcio
05/02/2018 12:29

Olá Fábio, muito obrigado pelo tutorial. Eu segui todos os passos do segundo, mas a parte que exibe a tensão não funciona no meu. Eu testei com o download que vc disponibilzou e o arduino funciona direitinho. O que pode estar errado?

Home » Hardware » Placas de desenvolvimento » Comunicação Serial com C# e Arduino – Parte 2

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: