Sunteți pe pagina 1din 45

Comunicao Serial com

C# e Arduino - Parte 1
Uma interface entre o arduino e um computador muitas vezes
importante durante o desenvolvimento de projeto ou para
controle de dispositivos atravs de uma interface grfica.
Pode-se usar uma aplicao no computador para Aquisio e
exibio de dados em forma de grfico durante algum
experimento em laboratrio ou estudo. Como j foi visto aqui
no artigo sobre o Arduino Uno e sobre comunicao Serial
com Arduino, a comunicao entre a placa e o computador
feira atravs de uma porta serial emulada atravs do driver
da USB. J foi exibido aqui uma aplicao de comunicao
serial desenvolvida com a plataforma JAVA. Neste artigo
vamos ensinar como desenvolver uma aplicao para
Windows usando a plataforma .Net usando o ambiente Visual
Studio da Microsoft, com a linguagem C#. Ser desenvolvido
um terminal simples, onde se poder enviar e receber
caracteres atravs de uma interface grfica. Esse artigo
tambm servir de base para desenvolvermos uma aplicao
envolvendo botes e outros elementos visuais.
Voc pode baixar a verso express dessa ferramenta
diretamente no site da plataforma. Selecione a opo Express
2013 for Windows Desktop. Aps o download faa a
instalao, que um processo bem simples porm um pouco
demorado, basta seguir os passos de instalao.
Ao Iniciar o Visual Studio ser exibida sua tela inicial e para
iniciar um novo projeto deve-se acessar o menu FILE > New
Project. Como vamos trabalhar com a linguagem C#, deve-se
selecionar a opo Visual C# no menu lateral. Agora vamos
iniciar o passo a passo pra criar nossa aplicao:

Figura 2 - Iniciando um novo projeto


Primeiro passo iniciar um novo projeto Windows Forms
Application em C#:

Figura 2 - Configurando um novo projeto


Agora vamos inserir os componentes no Form. O primeiro a
ser inserido ser um boto e deve-se mudar a sua
propriedade Name para
btConectar
e
a
sua
propriedade Text para Conectar, conforme exibido a seguir:

Figura 3 - Inserindo um boto para conexo


Inserir um comboBox logo a frente do boto btConectar,
inserido anteriormente:

Figura 4 - Inserindo uma comboBox


Inserir outro boto, logo abaixo do btConectar, e mudar a sua
propriedade Text para Enviar e Name para btEnviar:

Figura 5 - Inserindo um boto para envio de dados


Agora vamos inserir um textBox, que receber os dados a
serem enviados. Aps ser inserido, mudar a sua
propriedade Name para textBoxEnviar:

Figura 6 - Inserindo um textbox para inserir dados para envio


Agora vamos inserir um textBox maior, que exibir os dados
recebidos.
Mudar
as
propriedades Name para
textBoxReceber, Multiline para
True
e ScrollBar para
Vertical. A aparncia do Form ficar da seguinte forma:

Figura 7 - Textbox para recpo de dados


Prximo passo inserir um componente timer que ser
responsvel pela atualizao das portas COM disponveis no
PC. Selecione o componente timer e clique dentro do Form.
Ser exibido logo abaixo o componente timer1. Troque a
propriedade Name para timerCOM e Interval para 1000,
conforme exibido a seguir:

Figura 8 - timer para atualizao de COMs disponveis

Por ltimo vamos inserir o componente de comunicao


serial, o SerialPort. Selecione o componente SerialPort e
depois clique dentro do Form. Ser exibido este componente
ao lado do timerCOM:

Figura 9 - Inserindo o componente SerialPort responsvel pela


comunicao serial

Com os componentes inseridos no Form, vamos para a


codificao.
Antes de conectar a porta Serial, necessrio verificar as
portas COMs disponveis para uso, e qual a porta o usurio
deseja conectar. Para isso vamos atualizar a cada segundo a
ComboBox com as portas disponveis. Vamos criar um mtodo
privado dentro da classe Form1, que ser chamado de
atualizaListaCOMs. Clique com o boto direito no Form e
selecione
a
opo
View
code.
Insira
o
mtodo
atualizaListaCOMs(), conforme exibido no cdigo a seguir:

1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
3

using
using
using
using
using
using
using
using
using
using

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

namespace interfaceArduinoVS2013
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
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 no foi detectado diferena
if (quantDiferente == false)
{
return;
//retorna
}
//limpa comboBox
comboBox1.Items.Clear();
//adiciona todas as COM diponveis na lista
foreach (string s in SerialPort.GetPortNames())
{

4
3
5
3
6
3
7
3
8
3
9
4
0
4
1
4
2
4
3
4
4
4
5
4
6
4
7
4
comboBox1.Items.Add(s);
8
}
4
//seleciona a primeira posio da lista
9
comboBox1.SelectedIndex = 0;
5
}
0 }
5 }
1
5
2
5
3
5
4
5
5
5
6
5
7
5
8
5
9
6
0
6
1
6
2
6
3
6
4

Para testar a aplicao necessrio clicar no boto Start ou


pressionar a tecla F5. Se tiver alguma porta disponvel para

comunicao, esta ser listada dentro da comBox, conforme


exibido a seguir:

Figura 10 - Teste de atualizao das portas COMs disponveis


Na imagem acima nota-se que apenas a COM5 estava
disponvel. Caso uma placa Arduino seja inserida, necessrio
que atualize automaticamente a lista. Para isso vamos usar o
timerCOM que est configurado para gerar um evento a cada
segundo. Inicialmente deve-se habilitar o timer logo aps a
inicializao do Form e colocar o mtodo de atualizao
dentro do evento timerCOM_tick, conforme exibido a seguir:
Obs.: Para gerar o evento timerCOM_tick basta dar duplo
clique no componente timerCOM na aba design.

1
2
3
4
5
6
7
8
9
1
0
1
1

using
using
using
using
using
using
using
using
using
using

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

namespace interfaceArduinoVS2013
{

1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
3
4
3
5
3
6
3
7
3
8
3
9
}
4
}
0
4
1
4
2
4
3
4
4

public partial class Form1 : Form


{
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 no foi detectado diferena
if (quantDiferente == false)
{
return;
//retorna
}
//limpa comboBox
comboBox1.Items.Clear();
//adiciona todas as COM diponveis na lista
foreach (string s in SerialPort.GetPortNames())
{
comboBox1.Items.Add(s);
}
//seleciona a primeira posio da lista
comboBox1.SelectedIndex = 0;
}
private void timerCOM_Tick(object sender, EventArgs e)
{
atualizaListaCOMs();
}

4
5
4
6
4
7
4
8
4
9
5
0
5
1
5
2
5
3
5
4
5
5
5
6
5
7
5
8
5
9
6
0
6
1
6
2
6
3
6
4
6
5
6
6
6
7
6
8
6
9

Insira outro Arduino ou crie uma porta COM virtual para


verificar que atualizado automaticamente o comboBox:

Figura 11 - teste de atualizao de porta COM do Arduino e


portas virtuais
No exemplo acima foi criada uma COM virtual com o auxlio
do programa VSPE, que pode ser baixado aqui.
Agora j se pode escolher em qual porta a aplicao vai
conectar. O evento click do btConectar ser usado para fazer
a conexo. Para criar esse evento, selecione a aba de design
do Form e d um duplo clique no boto conectar. Ser gerado
o evento e agora deve-se inserir o cdigo para conexo. O
boto conectar tambm servir para desconectar quando a
porta j estiver conectada, confira o cdigo a seguir:

1
2
3
4
5
6
7
8
9
10
11

using
using
using
using
using
using
using
using
using
using

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

12 namespace interfaceArduinoVS2013
13 {
14
public partial class Form1 : Form
15
{
16
public Form1()
17
{
18
InitializeComponent();
19
timerCOM.Enabled = true;
20
}
21
22
private void atualizaListaCOMs()
23
{
24
int i;
25
bool quantDiferente; //flag para sinalizar que a quantidade de portas mudou
26
27
i = 0;
28
quantDiferente = false;
29
30
//se a quantidade de portas mudou
31
if (comboBox1.Items.Count == SerialPort.GetPortNames().Length)
32
{
33
foreach (string s in SerialPort.GetPortNames())
34
{
35
if (comboBox1.Items[i++].Equals(s) == false)
36
{
37
quantDiferente = true;
38
}
39
}
40
}
41
else
42
{
43
quantDiferente = true;
44
}
45
46
//Se no foi detectado diferena
47
if (quantDiferente == false)
48
{
49
return;
//retorna
50
}
51
52
53
//limpa comboBox
54
comboBox1.Items.Clear();
55
56
//adiciona todas as COM diponveis na lista
57
foreach (string s in SerialPort.GetPortNames())
58
{
59
comboBox1.Items.Add(s);
60
}
61
//seleciona a primeira posio da lista
62
comboBox1.SelectedIndex = 0;
63
}
64
65
private void timerCOM_Tick(object sender, EventArgs e)
66
{
67
atualizaListaCOMs();
68
}
69
70
private void btConectar_Click(object sender, EventArgs e)
71
{
72
if (serialPort1.IsOpen == false)
73
{
74
try
75
{
76
serialPort1.PortName =
77

78
79
80
comboBox1.Items[comboBox1.SelectedIndex].ToString();
81
serialPort1.Open();
82
83
}
84
catch
85
{
86
return;
87
88
}
89
if (serialPort1.IsOpen)
90
{
91
btConectar.Text = "Desconectar";
92
comboBox1.Enabled = false;
93
94
95
}
96
}
97
else
98
{
99
10
try
0
{
10
serialPort1.Close();
1
comboBox1.Enabled = true;
10
btConectar.Text = "Conectar";
2
}
10
catch
3
{
10
return;
4
}
10
5
}
10
}
6
}
10
}
7
10
8

Figura 12 - Teste de conexo

necessrio colocar uma proteo para que o programa no


seja fechado e deixe a porta COM aberta, dessa forma
impedindo que outros programas possam us-la. Para isso
vamos fechar a porta dentro do evento Form1_FormClosed:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50

using
using
using
using
using
using
using
using
using
using

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

namespace interfaceArduinoVS2013
{
public partial class Form1 : Form
{
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 no foi detectado diferena
if (quantDiferente == false)
{
return;
//retorna

51
}
52
53
//limpa comboBox
54
comboBox1.Items.Clear();
55
56
//adiciona todas as COM diponveis na lista
57
foreach (string s in SerialPort.GetPortNames())
58
{
59
comboBox1.Items.Add(s);
60
}
61
//seleciona a primeira posio da lista
62
comboBox1.SelectedIndex = 0;
63
}
64
65
private void timerCOM_Tick(object sender, EventArgs e)
66
{
67
atualizaListaCOMs();
68
}
69
70
private void btConectar_Click(object sender, EventArgs e)
71
{
72
if (serialPort1.IsOpen == false)
73
{
74
try
75
{
76
serialPort1.PortName =
77
78 comboBox1.Items[comboBox1.SelectedIndex].ToString();
serialPort1.Open();
79
80
81
}
82
catch
83
{
84
return;
85
86
}
87
if (serialPort1.IsOpen)
88
{
89
btConectar.Text = "Desconectar";
90
comboBox1.Enabled = false;
91
92
}
93
}
94
else
95
{
96
97
try
98
{
99
serialPort1.Close();
10
comboBox1.Enabled = true;
0
btConectar.Text = "Conectar";
10
}
1
catch
10
{
2
return;
10
}
3
10
}
4
}
10
5
10
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
6
{
10
if(serialPort1.IsOpen == true) // se porta aberta
7
serialPort1.Close();
//fecha a porta
10
}

8
10
9
11
0
11
}
1
}
11
2
11
3
11
4

O processo para conexo e fechamento da porta serial j est


feito, e o prximo passo fazer o programa enviar para o
Arduino o que for digitado dentro do textBoxEnviar. Para isso,
dentro do evento btEnviar_Click, deve-se inserir o seguinte
cdigo:

1 private void btEnviar_Click(object sender, EventArgs e)


2
{
3
if(serialPort1.IsOpen == true)
//porta est aberta
4
serialPort1.Write(textBoxEnviar.Text); //envia o texto presente no textbox Enviar
5
}

A recepo de dados requer um pouco mais de ateno.


Inicialmente
deve-se
criar
um
evento
serialPort1_DataReceived e uma varivel global do tipo String.
O processo de recepo acontece em uma Thread diferente
da atualizao dos componentes. A atualizao do
textBoxRebecer deve ser feita fora do evento de recepo da
serial. Para isso criamos uma funo trataDadoRecebido.
Confira como ficar o cdigo completo da aplicao:

1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

using
using
using
using
using
using
using

System.Data;
System.Drawing;
System.Linq;
System.Text;
System.Threading.Tasks;
System.Windows.Forms;
System.IO.Ports; // necessrio 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 no foi detectado diferena
if (quantDiferente == false)
{
return;
//retorna
}
//limpa comboBox
comboBox1.Items.Clear();
//adiciona todas as COM diponveis na lista
foreach (string s in SerialPort.GetPortNames())
{
comboBox1.Items.Add(s);
}
//seleciona a primeira posio da lista
comboBox1.SelectedIndex = 0;
}
private void timerCOM_Tick(object sender, EventArgs e)
{
atualizaListaCOMs();

70
}
71
72
private void btConectar_Click(object sender, EventArgs e)
73
{
74
if (serialPort1.IsOpen == false)
75
{
76
try
77
{
78
serialPort1.PortName =
79 comboBox1.Items[comboBox1.SelectedIndex].ToString();
80
serialPort1.Open();
81
82
}
83
catch
84
{
85
return;
86
87
}
88
if (serialPort1.IsOpen)
89
{
90
btConectar.Text = "Desconectar";
91
comboBox1.Enabled = false;
92
93
}
94
}
95
else
96
{
97
98
try
99
{
10
serialPort1.Close();
0
comboBox1.Enabled = true;
10
btConectar.Text = "Conectar";
1
}
10
catch
2
{
10
return;
3
}
10
4
}
10
}
5
10
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
6
{
10
if(serialPort1.IsOpen == true) // se porta aberta
7
serialPort1.Close();
//fecha a porta
10
}
8
10
private void btEnviar_Click(object sender, EventArgs e)
9
{
11
if(serialPort1.IsOpen == true)
//porta est aberta
0
serialPort1.Write(textBoxEnviar.Text); //envia o texto presente no textbox Enviar
11
}
1
11
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs
2 e)
11
{
3
RxString = serialPort1.ReadExisting();
//le o dado disponvel na serial
11
this.Invoke(new EventHandler(trataDadoRecebido)); //chama outra thread para
4 escrever o dado no text box
11
}
5
11
private void trataDadoRecebido(object sender, EventArgs e)
6
{
11
textBoxReceber.AppendText(RxString);
7
}

11
8
11
9
12
0
12
1
12
2
12
3
12
4
12
5
12
}
6 }
12
7
12
8
12
9
13
0
13
1
13
2
13
3
13
4

Para testar a aplicao junto ao Arduino, vamos fazer o upload


do seguinte sketch:

1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
3

void setup()
{
Serial.begin(9600); //inicia comunicao serial com 9600
}
void loop()
{
if(Serial.available())
//se algum dado disponvel
{
char c = Serial.read(); //le o byte disponivel
Serial.write(c);
//retorna o que foi lido
}
}

Nesse programa o Arduino simplesmente retornar o dado


que ele receber. Dessa forma, quando enviarmos dados pelo
programa, estes sero exibidos no computador por meio do
textBoxRecebe. A figura abaixo exibe os dados enviados e
recebidos pela aplicao:

Figura 13 - Teste de envio recebimento de dados do Arduino


Agora que a aplicao est completa, ou seja, j conseguimos
enviar e receber dados, vamos a um exemplo funcional.
Conforme foi exibido no Artigo sobre comunicao serial no
Arduino, vamos aproveitar o exemplo que acender o led
atravs do comando vindo pela serial. Carregue o seguinte
exemplo no Arduino:

1
2
3
4
5
6
7
8
9
1

/*
* comandos via serial
* inverte o estado do led conctado a sada 13 do arduino quando recebe o caracter 'A'
pela serial
*/
const int LED = 13;
void setup() {
Serial.begin(9600); //configura comunicao serial com 9600 bps
pinMode(LED,OUTPUT); //configura pino do led como sada
}

0
1
1
1
2
1 void loop() {
3 if (Serial.available()) //se byte pronto para leitura
1 {
4
switch(Serial.read())
//verifica qual caracter recebido
1
{
5
case 'A':
//caso 'A'
1
digitalWrite(LED,!digitalRead(LED)); //inverte estado do LED
6
break;
1
}
7 }
1 }
8
1
9
2
0

Execute a aplicao, conectando a porta na qual o Arduino


est ligado e envie o caractere A. Verifique o resultado no
LED conectado ao pino 13 da placa Arduino:

Figura 14 - Envio de comando apra o Arduino


O download da aplicao completa pode ser feito atravs do
link: Aplicao C# para interface serial com Arduino.
Lembre-se, voc deve ser registrado e estar logado no site
para fazer o download.

Concluso sobre a
Serial C# e Arduino

Comunicao

A ferramenta Visual Studio da Microsoft permite criar


facilmente uma interface de comunicao Serial entre o
Arduino e um computador (com sistema operacional
Windows). A partir do exemplo apresentado, pode-se fazer
aplicaes para enviar e receber comandos para o Arduino ou
outro dispositivo conectado a uma porta serial. No prximo
artigo vamos fazer uma aplicao envolvendo botes e outros
componentes que deixaro nossa interface mais elegante.
Continue lendo sobre o mesmo assunto no artigo Parte 2 de
Comunicao Serial com C# .

Para aprender mais


Arduino - Primeiros Passos
Arduino - O documentrio
Placas Arduino - trajetria at o UNO
Arduino UNO
Arduino - Entradas/Sadas digitais
Arduino - Entradas Analgicas
Arduino - Sadas PWM
Arduino - Comunicao Serial
Arduino - ArduBlock
Arduino no Proteus 8.1
Simulador de Arduino: Virtual Breadboard
Arduino Leonardo
Arduino MEGA 2560
Acionamento de uma lmpada com Arduino
Arduino - Controle de uma lmpada com LDR
Placa Arduino da Robocore - BlackBoard
Criando suas prprias bibliotecas para Arduino

Arduino UNO - Taxa de amostragem do conversor A/D


Arduino UNO - Sensor de temperatura interno
Medindo o nvel de gua com Arduino
Comunicao Serial com C# e Arduino - Parte 1
Comunicao Serial com C# e Arduino - Parte 2
Arduino: Expandindo os I/Os - Parte 1
Arduino Esplora
Arduino - Teclado touch capacitivo
Arduino - Interface com acelermetro e giroscpio
Arduino: RS-232/RS-485 - Hardware
Trinket - Uma pequena poderosa placa compatvel com
Arduino
Nova Arduino Zero Pro - Disponvel no site arduino.org
Embrio: Uma ferramenta de programao visual para Arduino
Comunicao serial com Arduino utilizando Qt5 Console
Application
Utilizando microcontroladores para controle de conversores
DC-DC personalizados, parte II
Mveis de escritrio + IoT - Uma impressora de recibo com
NFC e Wifi
LightBlue Bean - Placa compatvel com Arduino
BR-Arduino.org: Sua nova fonte de conhecimento sobre
Arduino
Shield Arduino YN
Arduino Yn
Novo Shield Arduino Wi-Fi com controlador Atmel
Python + Arduino - Comunicao Serial
Arduino vs Raspberry Pi: entenda as diferenas
Papilio - Arduino + FPGA
Intel Galileo Gen 2 - Placa Arduino
Arduino TRE Developer Edition - Lanamento!
Novo Arduino - Arduino Zero lanado
Intel Galileo - Placa Arduino
Arduino TRE
Arduino Due
Comunicao Serial Java + Arduino
UDOO - Arduino, Linux e Android em uma mesma placa

Referncias
SerialPort Class
Classe SerialPort

Comunicao Serial com C# e Arduino - Parte 1 por Fbio


Souza. Esta obra est sob a licena Creative Commons
Atribuio-CompartilhaIgual 4.0 Internacional.

Sobre o Autor:

Fbio Souza

Engenheiro eletricista com experincia no desenvolvimento


de projetos eletrnicos. Atua com desenvolvimento de
projetos eletrnicos, consultoria e treinamentos na rea de
sistemas embarcados.

Postagens Relacionadas

Novas placas Arduino: PRIMO e STAR-OTTO


20/05/2016| 2 Comments

Comunicao entre tarefas no FreeRTOS: Filas


18/05/2016| 2 Comments

Usando servios de nuvem para coletar business intelligence

Comunicao Serial com


C# e Arduino - Parte 2
Incio/Arduino, Contedo, Placas, Software/Comunicao Serial com C# e
Arduino - Parte 2

Por Fbio Souza| 18/08/2014|Arduino, Contedo, Placas, Software

Na primeira parte dessa srie, Comunicao 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 programao da
aplicao para funcionar parecida com o terminal serial que
vem no programa Arduino.

Neste artigo vamos construir uma aplicao de comunicao


serial para ligar/desligar um LED no Arduino atravs de um
boto e exibir o valor da tenso presente no pino analgico
(A0). Para facilitar o desenvolvimento vamos aproveitar a
estrutura desenvolvida na parte 1 desta srie.

O
primeiro
passo

retirar
o textBoxEnviar e
o textBoxReceber, deixando a interface da seguinte forma:

Figura 1 - Alterando o exemplo Comunicao Serial com C# e


Arduino - Parte 1

Agora vamos aproveitar o btEnviar para servir como o boto


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:

Figura 2 - Boto para ligar/desligar o LED atravs da


comunicao Serial

Para exibir a tenso na entrada analgica do Arduino vamos


inserir um label logo abaixo do boto Ligar. Trocar a
propriedade Name para lbValor e em Text inserir Tenso: 0,0
V. Para ficar mais visvel 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:

Figura 3 - Label para indicao da tenso

Para ficar melhor a disposio das informaes no Form,


vamos alinhar os componentes ao centro, conforme figura
abaixo:

Figura 4 - Ajustes finais no Form para comunicao serial

Note que foi adicionado um label, logo acima do btLigar,


com a propriedade Text igual a LED, que servir para indicar
que o boto acionar o LED.

Esse layout servir para nossa aplicao, para ser lida a


tenso no pino analgico do Arduino. Vamos inserir um
componente Timer que ser responsvel para enviar o dado
de leitura do valor analgico em tempo em tempos. Deve ser
alterada
a
propriedade Name para timerLeitura e Interval
para 500, conforme exibido a seguir:

Figura 5 - Alterao no intervalo do Timer

Programao para
comunicao serial

aplicao

de

Com os componentes inseridos podemos passar para a


codificao da nossa aplicao. Deve ser criado o evento do
boto Ligar, e para isso basta dar um duplo clique no boto.
Insira o seguinte cdigo neste evento:

1
2
3
4

private void btLigar_Click(object sender, EventArgs e)


{
if(serialPort1.IsOpen == true)

serialPort1.Write("A");

if(btLigar.Text== "Ligar")

btLigar.Text = "Desligar";

1
0

1
1

else
{

1
2

btLigar.Text = "Ligar";

1
3

}
}

1
4 }
1
5

Para enviar o comando de leitura para o arduino necessrio


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 cdigo:

1 private void timerLeitura_Tick(object sender, EventArgs e)


2

if(serialPort1.IsOpen == true)

serialPort1.Write("T");

Sempre que enviado o caractere T o Arduino retornar o


valor lido no pino analgico A0 convertido para digital. O
cdigo com a formatao do valor a ser exibido, assim como
todo o cdigo da aplicao, exibido a seguir:

1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using System.Data;
5 using System.Drawing;
6 using System.Linq;
7 using System.Text;
8 using System.Threading.Tasks;
9 using System.Windows.Forms;
10 using System.IO.Ports; // necessrio para ter acesso as portas
11
12 namespace interfaceArduinoVS2013
13 {
14

public partial class Form1 : Form

15

16
17

string RxString;

18
19

public Form1()

20

21

InitializeComponent();

22

timerCOM.Enabled = true;

23

24
25

private void atualizaListaCOMs()

26

27

int i;

28

bool quantDiferente;

//flag para sinalizar que a quantidade de portas mudou

29
30

i = 0;

31

quantDiferente = false;

32
33

//se a quantidade de portas mudou

34

if (comboBox1.Items.Count == SerialPort.GetPortNames().Length)

35

36

foreach (string s in SerialPort.GetPortNames())

37

38

if (comboBox1.Items[i++].Equals(s) == false)

39

40

quantDiferente = true;

41

42

43

44

else

45

46
47
48

quantDiferente = true;
}

49

//Se no foi detectado diferena

50

if (quantDiferente == false)

51

52

return;

53

//retorna

54
55

//limpa comboBox

56

comboBox1.Items.Clear();

57
58

//adiciona todas as COM diponveis na lista

59

foreach (string s in SerialPort.GetPortNames())

60

61

comboBox1.Items.Add(s);

62

63

//seleciona a primeira posio da lista

64

comboBox1.SelectedIndex = 0;

65

66
67

private void timerCOM_Tick(object sender, EventArgs e)

68

69
70

atualizaListaCOMs();
}

71
72

private void btConectar_Click(object sender, EventArgs e)

73

74

if (serialPort1.IsOpen == false)

75

76

try

77

78
79

serialPort1.PortName =
comboBox1.Items[comboBox1.SelectedIndex].ToString();
serialPort1.Open();

80
81

82

catch

83

84

return;

85
86

87

if (serialPort1.IsOpen)

88

89

btConectar.Text = "Desconectar";

90

comboBox1.Enabled = false;

91
92

93

94

else

95

96
97

try

98

99

serialPort1.Close();

10
0

comboBox1.Enabled = true;
btConectar.Text = "Conectar";

10
1

}
catch

10
2

10
3

return;
}

10
4
10
5
10
6
10

}
}

private void Form1_FormClosed(object sender, FormClosedEventArgs e)

10
8

{
if(serialPort1.IsOpen == true) // se porta aberta

10
9

serialPort1.Close();
}

11
0
11
1
11
2

//fecha a porta

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs


e)
{
RxString = serialPort1.ReadLine();

11
3

//le o dado disponvel na serial

this.Invoke(new EventHandler(trataDadoRecebido)); //chama outra thread para


escrever
o dado no text box
11
4
}
11
5
11
6

private void trataDadoRecebido(object sender, EventArgs e)


{

11
7
11
8

Double tensao = Convert.ToDouble(RxString)*5/1023;


lbValor.Text = "Tenso: " + Convert.ToString(Math.Round(tensao, 1)) + " V";
}

11
9
12
0
12
1
12
2
12
3

private void btLigar_Click(object sender, EventArgs e)


{
if(serialPort1.IsOpen == true)
{
serialPort1.Write("A");
if(btLigar.Text== "Ligar")
{

12
4
12
5
12
6
12
7

btLigar.Text = "Desligar";
}
else
{
btLigar.Text = "Ligar";

12
8

}
}

12
9
}

13
0
13
1

private void timerLeitura_Tick(object sender, EventArgs e)


{

13
2

if(serialPort1.IsOpen == true)

13
3
13
4
13 }
5
13
6
13
7
13
8
13
9
14
0
14
1
14
2
14
3
14
4
14
5
14
6
14
7
14

serialPort1.Write("T");
}
}

8
14
9
15
0
15
1
15
2

O cdigo para o upload no Arduino exibido a seguir:

1 const int LED = 13;


2
3 int valor_AD = 0;
4 int valor_leituras = 0;
5 byte i = 0;
6
7 void setup() {
8

Serial.begin(9600);

//configura comunicao serial com 9600 bps

pinMode(LED,OUTPUT); //configura pino do led como sada

1 }
0
void loop() {
1
1 if (Serial.available()) //se byte pronto para leitura
1
2
1
3
1

{
switch(Serial.read())
{

//verifica qual caracter recebido

case 'A':

1
5

//caso 'A'

digitalWrite(LED,!digitalRead(LED)); //inverte estado do LED


break;

1
6
case 'T':

1
7

Serial.println(valor_AD);

1
8
1
9

break;
}
}

2
0
2
1
2
2
2
3
2
4

//MEDIA DE LEITURAS
valor_leituras += analogRead(A0);
i++;

if(i==16)
{
i = 0;

2
5
2
6

valor_AD = valor_leituras>>4;
valor_leituras = 0;
}

2
7
2 }
8
2
9
3
0
3
1
3
2
3
3
3

4
3
5
3
6
3
7

Note no cdigo acima que foi feita uma mdia de 16 leituras


do sinal analgico.

Depois de feito o upload para o Arduino e iniciada a


aplicao, com a correta conexo com o Arduino o resultado
vai ser bem semelhante ao da imagem a seguir:

Figura 6 - Teste da aplicao final

Variando o valor da entrada analgica com um potencimetro,


ser exibido o valor da tenso presente no pino. Caso o

boto Ligar seja pressionado, o LED no pino 13 ser ligado e,


se pressionado novamente, ser desligado.

O Download desta aplicao junto com o programa Arduino


pode ser feita atravs do link: Aplicao.

Lembre-se, voc deve ser registrado e estar logado no site


para fazer o download.

Concluso
Desenvolver uma interface grfica para comunicao serial e
controle com Arduino bem simples utilizando a
plataforma .Net. Voc pode criar botes 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 fcil e rpida.

Aproveite o exemplo, crie novos botes para ligar/desligar


dispositivos em outros pinos e leia as outras entradas
analgicas.

Espero que este artigo possa ser a porta de entrada para suas
aplicaes grficas interagindo com o Arduino. Conte para ns
as suas experincias com essa plataforma.