Crie seu próprio programa de comunicação serial em C# - Tutorial 1

É um anseio entre os iniciantes na área de programação em C, a criação de programas que tenham uma interface amigável, com botões, menus entre outros componentes do windows. Aqueles que ja usam o arduino ou outros microcontroladores já devem ter sentido falta de um aplicativo com essas características e que se comunicasse com o o microcontrolador via serial.

Nesse tutorial, como é o primeiro e em um nível bem básico, será mostrado passo a passo como criar uma GUI que será capaz de enviar dados para o arduino, afim de comandar um LED(ligar e desligar), e um servomotor.

O aplicativo será feito no ambiente do Visual Studio, na linguagem C#.É recomendável o Visual C# no minimo 2010, pois contem um componente novo, que é um tanto interessante para quem deseja plotar de gráficos, o Chart.

Nesse e nos próximos tutoriais,não será exigido grande conhecimento da linguagem C#, basta que se tenha um pouco de conhecimento em C++, e caso, seja necessário o uso de alguma estrutura exclusiva do C#, será feita uma breve explicação.

1º PASSO: Criar um novo projeto em linguagem C#

Após criar um novo projeto,deverão aparecer 3 elementos muito importantes da IDE:

A aba Design onde podemos editar a aparência do programa (formulário).

caixa de ferramentas (ou Toolbox) que contem os elementos que farão parte do nosso programa.Ex:Botões, barras de rolagem, menus, etc.

A aba de propriedades (ou properties) onde podemos predefinir alguns comportamentos que os elementos (controles) terão.Ex:O texto que o formulário exibe, se um botão apresenta alguma imagem, etc.

2º PASSO: Design.

Iremos usar os seguintes componentes:

  • button
  • hScrollBar
  • SerialPort

Após achar cada um na caixa de ferramentas, arrastem-os e soltem no formulário. Redimensionem-os de modo que fique parecido com a figura abaixo.

Naturalmente, para cada controle adicionado é atribuido a ele um nome que corresponde a classe a que pertencem e a um numero.Ex: button1, button2,hScrollBar1,etc.

Neste tutorial, mudei somente o nome do objeto SerialPort1 para Porta, na aba de propriedades.

Mudem também outras propriedades selecionando cada controle no formulário :

Porta:

  • PortName - "COMX"(X = Nº da porta em que o microcontrolador estará conectado)
  • BaudRate - baud rate que está configurado no seu microcontrolador

 

button1:

  • Text - Off

 

hScrollBar1:

  • Maximum - 189 (180 +LargeChange-1)

 

Form1(formulário):

  • FormBorderStyle - FixedSingle (não permite redimencionamento do formulario)
    MaximizeBox - false (desabilita botão de maximizar)


Alguns objetos tem propriedades em comum, por exemplo experimente trocar a forma que o cursor é mostrado quando esta sobre o button1  e o hScrollBar1, selecione os dois ao mesmo tempo e mude a propriedade Cursor para hand.

Após isso apertem F5 para rodar o programa.Ele deve estar com essa cara.

3º PASSO: Programação.

A programação para GUI geralmente é orientada a eventos o que significa que o controle de fluxo é guiado por indicações externas.Ex:Clique do mouse, tecla digitada, um novo dado no buffer serial,etc.

O evento principal de cada controle, é acessado quando se da um duplo clique no elemento.Porém existem vários outros eventos que podem ser vinculados a cada controle, por exemplo nesse projeto usaremos dois eventos do formulário que são: load() e o FormClosing().

Nesse projeto serão usadas apenas três funções do objeto Porta:

  • Open();
  • Write();
  • Close();


Porta.Open() foi colocado dentro do evento de load() do formulário, o que significa que será estabelecida conexão serial a partir do momento que o programa for carregado.

Porta.Close() foi colocado dentro do evento FormClosing(), para que seja encerrada a conexão com a porta serial assim que o programa for fechado.

Porta.Write()  será usado no botão e na barra de rolagem, para enviar pro microcontrolador a informação que queremos.

Ao dar um duplo clique no formulário deverá aparecer uma nova aba contendo alguns códigos, e o evento de Load.

No Load deve ficar assim:

private void Form1_Load(object sender, EventArgs e)
{
     try
     {
          Porta.Open();
     }
     catch
     {
          MessageBox.Show("Cabo desconectado","Erro");
          Close();
     }
}

 try e catch são usados para tratar exceções(erros), que irão aparecer se o programa for executado sem que a porta exista, no caso do arduino a porta só existirá se o cabo estiver conectado.

Funciona da seguinte forma,"tente executar o que estiver dentro do try, caso ocorra a exceção faça o que estiver no catch".Nesse programa, caso não consiga abrir comunicação com a serial, exiba uma mensagem ( MessageBox.Show("Cabo desconectado","Erro") ) e feche o programa usando o método Close().(Não confundir com Porta.Close()).

Indo no evento de FormClosing() devemos encerrar a comunicação:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
     try
     {
          if (Porta.IsOpen)
          {
               Porta.Close();
          }
     }
     catch 
     { }
}

A estrutura  try e catch se faz presente novamente,sempre que houver risco de desconexão do cabo de comunicação ela deve ser usada, sob pena de ver seu programa travar.

Nesse evento uma condição simples, caso a porta esteja "aberta", feche-a.

Dando um duplo clique no botão abrirá o evento de click.

private void button1_Click(object sender, EventArgs e)
{ 
     try
     {
          if (button1.Text == "Off")
          {
               Porta.Write(comando, 1, 1);
               button1.Text = "On";
          }
          else
         {
          Porta.Write(comando, 2, 1);
          button1.Text = "Off";

          }

     }
     catch 
     {
     MessageBox.Show("Cabo desconectado", "Erro");
     Close();
     }
}

Antes de falar deste código, um array do tipo byte deve ser declarado pois a função Porta.Write() exige um array de bytes ou chars, então façam a declaração da seguinte forma:

byte[] comando = { 0, 200, 201 }; antes de public Form1()

O primeiro elemento iremos usar para comandar o angulo do servo, de 0 a 180.

Como o byte chega até 255, temos um intervalo entre 181 e 255 livre para arbitrarmos um byte para acender e outro para apagar o led. No caso arbitrei 200 para acender e 201 para apagar;

Neste evento iremos acender ou apagar o led," Se o botão estiver como titulo Off mande pela serial o 200" pois é o elemento 1do array comando. o terceiro parâmetro da Porta.Write(comando, 1, 1) se refere a quantos bytes serão enviados, no caso só um o 200.Com isso o led deverá acender.

Depois de enviar reescreva o Texto do botão para "On";

Quando o usuário clicar de novo será enviado um byte equivalente a 201 desligando o led e reescrevendo o texto do botão para "Off".

No evento Scroll da barra de rolagem ocorre o seguinte:

private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
{
     try
     {
          comando[0] = (byte)hScrollBar1.Value;
          Porta.Write(comando, 0, 1);
          Text = Convert.ToString(hScrollBar1.Value);
     }
     catch
     {
          MessageBox.Show("Cabo desconectado", "Erro");
          Close();
     }
}

A linha comando[0] = (byte)hScrollBar1.Value atribui ao primeiro elemento do array o valor atual da barra de rolagem.Logo em seguida o valor é transmitido para o microcontrolador que controla o servomotor.

Depois esse valor é convertido para string e passado para o titulo do formulário para poder ser visualizado pelo usuário. 

O programa do arduino é este:

#include <Servo.h>

Servo servo1;

void setup(){

  Serial.begin(9600);

  pinMode(13,OUTPUT);

  servo1.attach(9);

}

void loop(){

  if(Serial.available()){

    byte dado = Serial.read();

   

    if(dado <= 180)

    servo1.write(dado);

   

    if(dado == 200)

    digitalWrite(13, HIGH);

   

    if(dado == 201)

    digitalWrite(13, LOW);

  }

}

E o do aplicativo deve ficar assim:

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;

 

namespace Exemplo1

{

    public partial class Form1 : Form

    {

        byte[] comando = { 0, 200, 201 };

 

        public Form1()

        {

            InitializeComponent();

        }

 

        private void Form1_Load(object sender, EventArgs e)

        {

            try

            {

                Porta.Open();

            }

            catch

            {

                MessageBox.Show("Cabo desconectado","Erro");

                Close();

            }

        }

 

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)

        {

            try

            {

                if (Porta.IsOpen)

                {

                    Porta.Close();

                }

            }

            catch

            { }

        }

 

        private void button1_Click(object sender, EventArgs e)

        {           

            try

            {

                if (button1.Text == "Off")

                {

                    Porta.Write(comando, 1, 1);

                    button1.Text = "On";

                }

                else

                {

                    Porta.Write(comando, 2, 1);

                    button1.Text = "Off";

                }

            }

            catch

            {

                MessageBox.Show("Cabo desconectado", "Erro");

                Close();

            }

        }

 

        private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)

        {

            try

            {

                comando[0] = (byte)hScrollBar1.Value;

                Porta.Write(comando, 0, 1);

                Text = Convert.ToString(hScrollBar1.Value);               

            }

            catch

            {

                MessageBox.Show("Cabo desconectado", "Erro");

                Close();

            }

        }

    }

}

Com isso concluímos o nosso aplicativo, adaptem a suas necessidades.Até a próxima.

 

Exibições: 7290

Responder esta

Respostas a este tópico

Muito Massa.........Parabens PEla iniciativa 

Valeu Yure !!!! Cara vc podia ter me passado antes...brincadeira...imagino que não tivesse tempo...

caraca agora vai ficar maneiro vou tentar adaptar pra ascender uma lampada em casa através do software, depois te falo se deu certo.

Abração..

Valeu Yure! Eu tava precisando muito aprender alguma coisa de programacao em GUI, só não achava nada legal pra quem ta muito no comeco.

Vai me ajudar muuuuuuuito!

Olá Yuri, vc teria alguma coisa em C puro?

Algum exemplo de como fazer a comunicação entre o Arduino e um programa em C, não precisa ter botão, só algo q ping em alguns segundos um dado no Arduino e receba algo dele também! 

Abraço e esse em C Sharp ficou interessante, só não consigo aplicar no q estou desenvolvendo. Valew.

Estarei fazendo um sobre a recepção em breve.Em C puro não conheço forma de acessar a porta serial. 

Olá Judenilson.

Em C puro tem como fazer sim, mas é importante saber para qual sistema você está programando.

Caso esteja usando Linux, você irá se deparar com o famoso TTY (Teletype), que foram os primeiros terminais remotos de escrita. 

Caso esteja usando Window$, você irá utilizar um Handle para comunicação, usando a API do Sistema Operacional.

A idéia nos dois sistemas é que você estará trabalhando com um arquivo. Sim, é verdade. rs

A sua interface de comunicação serial seria como trabalhar com programas que escrevem e lêem de um arquivo. Então, para transmitir algo você estaria escrevendo no arquivo. E para receber algo, estaria lendo de um arquivo.  A diferença é que você pode ter eventos para te informar que houve uma recepção por exemplo. E caso não seja interessante os eventos, você estaria trabalhando com "pooling" de algum flag de evento.

Ficam os links para ajudar no conceito:

Linux:  http://stackoverflow.com/questions/6947413/how-to-open-read-and-wri...

Windows: http://msdn.microsoft.com/en-us/library/ms810467.aspx

Procure também pelas bibliotecas do Qt (Nokia). Geralmente elas são crossplataform. Isso significa que poderia reaproveitar um código escrito para um sistema em outro. Mas como tudo não são 100% maravilhas, uma mudança ou outra é necessária, mas pouca coisa. 

Um exemplo legal é o terminal serial que vem junto com a IDE do Arduino, o famoso "debugger". Ele é jeito em JAVA se não me engano.

Não se assuste se procurar por algo em C e aparecer que é para C++, geralmente é a mesma coisa, o que muda são algumas declarações e acessos, mas em geral são parecidos.

Boa sorte no projeto.

Att.

Obrigado Daniel e Yuri, estava até desistindo de programar em C e partir para C# mesmo! Pois, parece que tem mais adeptos! Na net é mais fácil de achar explicações e turoriais em C#. 

Vou dar uma olhada nessa biblioteca Daniel.

Estou querendo fazer um controle para Simulador de Vôo (rwindows mesmo) e para interação preciso de um software entre o arduino e o simulador. Das 4 etapas de comunicação, só consegui 3:

ARDUINO TX -> RX Software (OK) 

ARDUINO RX <- TX Software (Desde segunda (05/08) tentando exaustivamente!!!)

Software TX -> RX Simulador (OK)

Software RX <- TX Simulador (OK)

Vou estudar mais e vê se consigo em C, se não, vou começar do ZERO e tentar com C#!!!

Quando conseguir, com certeza colocarei a disposição dos colegas tudo q aprendi no caminho!

Abraço

Ótima contribuição, tanto pelo tema quanto pelo didatismo.

Só uma sugestão, que vale para todos que postam código fonte. Usem serviços como Pastebin. Vejam como fica mais claro nesse exemplo também em C#.

Obrigado

Obrigado e parabéns por seu tutorial.

Valeu pelo tuto, estou iniciando com uma comunicação entre um programa e o Arduíno. Esse tuto foi de grande ajuda.

Off-topic : "Passei uns 20 min brincando de ficar virando o servo de um lado para o outro ushsuhsushus"

Cara Parabéns!!! Estou usando este exemplo para estudar!!! Valeu!!!!

Buscando por uma solução para um projeto encontrei este tutorial no google.

Criei este projeto seguindo o tutorial em C#.

Tenho um sensor de umidade e outro de temperatura e ambos com conexão USB/RS485, ou seja Serial.

No Form1 do projeto, coloquei duas SerialPort.

Uma para o sensor de umidade e outro para o sensor de temperatura.

No manual do sensor de umidade diz para enviar o comando (P01) e no de temperatura diz para enviar o comando (#,D,1006,1,) para ligar a coleta de informações e (#,D,1006,0,) para desligar.  

Como enviar estes comandos para os aparelhos?

P01 para a SerialPort Name:COMM_UMID  PortName:COM7 e

#,D,1006,1, para a SerialPort Name:COMM_TEMP  PortName:COM2?

Como receber estes dados e coloca-los em uma label?

Muito agradecido pela ajuda.

Silvio

RSS

© 2024   Criado por Marcelo Rodrigues.   Ativado por

Badges  |  Relatar um incidente  |  Termos de serviço