Até agora sempre definíamos as propriedades como o nome da porta e BaudRate no projeto, para fins de testes funciona muito bem. Porém isso deixa o programa pouco flexível, já que a porta que o arduino usa pode mudar dependendo do PC onde ele tem os drives instalados.
Neste tutorial estarei mostrando como dar o poder de escolha ao usuário de qual porta e baud rate usar, e para aqueles que usam o arduino, a escolha de habilitar ou não o reset via serial.
Vou aproveitar e mostrar também o como salvar essas configurações para que da próxima vez que o programa for executado ele “lembre” delas e as tome como default.
Primeiro passo: adicionar novos itens.
Depois de criar um novo projeto, no menu projeto escolham a opção adicionar novo item.
Adicionem um novo formulário e coloquem o nome de “Config_Serial.cs”.
Depois adicionem um novo arquivo de configurações e coloquem o nome de “Minhas_Config.settings”.
Antes trabalhar com esses novos itens adicionem os seguintes controles no formulario1(Form1).
Alterei o nome de serialPort1 para Porta fiz algumas modificações no menuStrip1 para que ficasse assim:
Apenas troquei a cor atribuindo a propriedade BackColor a cor GradientActiveCaption e criei um menu conexão adicionei as opções configurar e conectar.
Dando um duplo click na opção configurar teremos acesso ao evento dele (Click).
Qual é a ideia? Configurar qual porta e velocidade que vamos usar. Só que eu preferi fazer esse procedimento em outro formulário pra ganhar mais espaço no principal, pra isso adicionamos o formulário Config_Serial anteriormente.
Bom, precisamos chamar esse novo formulário através do menu então façam o seguinte:
private void configurarToolStripMenuItem_Click(object sender, EventArgs e)
{
Config_Serial janela2 = new Config_Serial(this);
janela2.ShowDialog();
}
Primeiro declaramos uma nova variável do tipo Config_serial, que corresponde ao nome que demos ao segundo formulário, com o nome janela2 e inicializamos ela passando este formulário (Form1) como parâmetro usando a palavra this. Na segunda linha o segundo formulário é exibido.
É importante entender porque passar o Form1 como parâmetro neste caso. O que acontece é que as variáveis de um formulário não podem ser acessadas por outro. Como vamos mudar duas propriedade do objeto Porta através do segundo formulário, e aquele esta no primeiro, com esse procedimento poderemos mudar campos desse objeto. Também é importante que mudem a propriedade Modifiers do objeto Porta para public.
No evento da opção Conectar do menu deixem parecido com isso:
private void conectarToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
if (Porta.IsOpen)
{
Porta.Close();
conectarToolStripMenuItem.Text = "Conectar";
}
else
{
Porta.Open();
if (reset)
{
Porta.DtrEnable = true;
Porta.DtrEnable = false;
}
conectarToolStripMenuItem.Text = "Desconectar";
}
}
catch(SystemException erro)
{
MessageBox.Show(erro.Message, "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Traduzindo: se estiver conectado, desconecta e muda o texto do menu para “Conectar”.
Senão, conecta e muda o texto para “Desconectar”.
Se ocorrer algum erro mostra a descrição dele, que esta na variável erro.Message num formulário com titulo “Erro”, que tem um botão de ok e um ícone de Error.
Assim podemos iniciar e encerrar a comunicação quando quisermos.
Abro um parêntese para falar do seguinte trecho:
if (reset)
{
Porta.DtrEnable = true;
Porta.DtrEnable = false;
}
Aqueles que usam o arduino, devem ter notado que o Serial Monitor é capaz de resetar o arduino assim que é aberto.
Esse trecho de código faz o mesmo, se a variável reset for verdadeira, reseta o arduino ao conectar.
Declarem essa variável com antecedência:
public bool reset = false;
public porque vamos acessa-la também no segundo formulário.
2º passo: segundo formulário.
Agora que terminamos o formulário principal, vamos trabalhar o segundo que é onde faremos as configurações da porta.
Adicionem os seguintes controles:
Redimensionem e mudem os text para que fique dessa forma:
Esse timer vai servir para atualizar a lista de portas que o PC tem disponível.
No comboBox correspondente ao baud rate, no meu caso o comboBox2, coloquei as velocidades padrão do Serial Monitor na propriedade items.
Vejam o resultado:
Como nós não sabemos de inicio quantas e qual porta o arduino esta conectado devemos usar uma função que pelo menos nos retorne os nomes das portas existentes. Essa função é usada nesse trecho:
void busca_de_portas(bool x)
{
int num = portas.Length;
portas = SerialPort.GetPortNames();
if (num != portas.Length || x)
{
comboBox1.Items.Clear();
for (int i = 0; i < portas.Length; i++)
{
comboBox1.Items.Add(portas[i]);
}
}
}
O segredo esta nesta função: SerialPort.GetPortNames(). Ela retorna um array do tipo string contendo os nomes das portas existentes. Tendo posse dos nomes, basta preencher o comboBox1 com eles, e é isso que a rotina busca_de_portas fará. Mas fará somente se o número de portas variar. O campo Length quer dizer o tamanho de um determinado array.
Não esquecer de declarar portas antes de usar:
string[] portas = {""};
Para poder usar SerialPort.GetPortNames() é necessário incluir uma classe fazendo .
using System.IO.Ports;
Ok, agora no evento de Load do formulário e no Tick do timer1 é só chamar a rotina acima:
private void Config_Serial_Load(object sender, EventArgs e)
{
busca_de_portas(true);
}
private void timer1_Tick(object sender, EventArgs e)
{
busca_de_portas(false);
}
Assim será feita uma pesquisa pelos nomes ao carregar e também num intervalo de 1000 ms.
Ao carregar é importante passar o true porque mesmo no caso de o número de portas ser 1(numero inicial de elementos do array portas)ele possa atualizar o comboBox1.
No meu caso só existe a porta que o arduino está, mas quem tiver mais de uma, pode acontecer de os nomes ficarem fora de ordem. Pra corrigir isso basta mudar a propriedade Sorted do comboBox1 para true.
No evento checkBox1_CheckedChanged façam o mesmo que o exemplo abaixo:
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if(checkBox1.Checked)
{
reset2 = true;
}
else
{
reset2 = false;
}
}
Declarem antes a variável bool reset2 = false; que será responsável por habilitar o reset do arduino ao conectar.
Ok, o usuário escolheu, qual porta, qual velocidade, e até se deseja resetar o arduino. Agora resta passar essa informações pro Form1 já que é nele que está o objeto Porta. Arbitrei que iria passar esses dados quando fechasse as configurações.
Lembrem se que passamos o Form1 como parâmetro quando fizemos:
Config_Serial janela2 = new Config_Serial(this);
Para usar esse parâmetro faremos o seguinte:
Form1 janela1;
public Config_Serial(Form1 x)
{
InitializeComponent();
janela1 = x;
}
Logo que clicamos em algum controle para ter acesso a algum evento esse método já é automaticamente gerada para nós logo no começo do código. Ele originalmente vem sem parâmetros. O que fizemos aqui foi declarar um objeto do tipo Form1 com nome janela1 e recebeu o valor x passado pelo formulário anterior.
Agora podemos passar as informações para o formulário anterior fazendo:
private void Config_Serial_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
janela1.Porta.BaudRate = Convert.ToInt32(comboBox2.Text);
janela1.Porta.PortName = comboBox1.Text;
janela1.Text = comboBox1.Text + "/" + comboBox2.Text;
janela1.reset = reset2;
}
catch
{
DialogResult escolha;
escolha = MessageBox.Show("Prencha todos os campos ", "Aviso", MessageBoxButtons.OKCancel, MessageBoxIcon.Exclamation);
if (escolha == System.Windows.Forms.DialogResult.OK)
{
e.Cancel = true;
}
}
}
O código acima tenta passar os dados para o formulário anterior, caso não consiga ele mostra uma mensagem que diz: "Prencha todos os campos corretamente", e dá duas opções ao usuário:
Passo 3: Configurar definições.
Ufa! Conseguimos, por aqui termina para quem se deu por satisfeito com o resultado.
Porém é um pouco chato sempre ter que ir no menu e escolher de novo os parâmetros para configurar a conexão serial, seria interessante que o programa guardasse essas informações mesmo depois de fechado.
Pra isso mesmo que adicionamos no começo do projeto um arquivo de configurações com o nome de minhas_config.settings. Ele vai guardar dados que serão usados na próxima vez que o programa for executado.
Ele deve ter essa cara:
Aqui já defini alguns valores que eu desejo guardar.
A ideia é atualizar e salvar esses valores quando fecharmos o programa, logo devemos usar o evento FormClosing do Form1
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
try
{
Minhas_Config.Default.Nome_Porta = Porta.PortName;
Minhas_Config.Default.Baud_Rate = Porta.BaudRate;
Minhas_Config.Default.restart_arduino = reset;
Minhas_Config.Default.Save();
}
catch
{
MessageBox.Show("Erro ao salvar!Reconfigure quando executar novamente","Erro");
}
}
E quando abrirmos novamente o programa, carregar os valores guardados:
private void Form1_Load(object sender, EventArgs e)
{
try
{
Porta.PortName = Minhas_Config.Default.Nome_Porta;
Porta.BaudRate = Minhas_Config.Default.Baud_Rate;
reset = Minhas_Config.Default.restart_arduino;
Text = Porta.PortName + "/" + Convert.ToString(Porta.BaudRate);
}
catch
{
MessageBox.Show("Erro ao carregar! Reconfigure", "Erro");
}
}
Pronto, com isso termino mais um tutorial, adaptem a suas necessidades. Até a próxima.
Código Form1:
Código Config_Serial:
Tags:
Parábens!!!
Ficou muito claro e didático.
Abraço
Yure, tá muito legal!
Vc tá deixando todos os passos num único tutorial pra gente acessar depois? É q como eu tenho emprego, laboratorio, curso de linux, curso de infoseg, familia, bichos de estimacao, casa em reforma e 400 alunos, tá dificil acompanhar na mesma velocidade...
Eu estou colocando no blog tambem, vc pode encontra-los na lista de tutoriais (artigos e outros) na pagina inicial do Lab.
Opa, daí é legal! Ultimamente meu tempo ta uma bagunca, muita coisa pra fazer e nenhum tempo de sobra, to me reorganizando geral aqui. Daí vou pegando as coisas pra estudar passo a passo, etapa por etapa, pra aprender bem cada uma antes de prosseguir.
Bem-vindo a
Laboratorio de Garagem (arduino, eletrônica, robotica, hacking)
© 2024 Criado por Marcelo Rodrigues. Ativado por