quarta-feira, 28 de setembro de 2016

Integração via Porta Paralela - parte 1

Porta Paralela

As portas paralelas já tiveram em melhores momentos para fazerem interface entre diversos periféricos e o computador, mas engana-se quem acha que esse tipo de comunicação ainda não pode ser útil para diversas aplicações.



fonte: http://www.eletroaquila.net/cabo-db25m-macho-x-db25f-femea-5-0-mt.html

Criada pela IBM para tornar-se um canal exclusivo de comunicação com as impressoras, as portas paralelas com o passar dos anos foram sendo mais do que isso, conquistando confiança e performance em acionamentos de diversos outros periféricos como: scanners, câmeras, unidades de disco, entre outras.
Na indústria foi, e pasmem, ainda é bastante usada para comunicação devido a sua capacidade de transferência de grupos de bits simultaneamente (byte a byte) a cada ciclo, fazendo com que uma grande taxa de transferência de dados ocorra por meio de diversas linhas condutoras de sinais.
Mas, como nem tudo são flores o que restringe o uso dos cabos paralelos em diversas funções são a necessidade de conectores com 25 vias (DB25) e cabos de no máximo 10 metros de comprimento, onde a comunicação com cabo serial utiliza cabos de formação físicas menor e mais simples e comprimentos maiores.
Com dito anteriormente os diversos periféricos que foram conectando com o computador via porta paralela foi possível com o surgimento da porta paralela bidirecional (EPP/ECP) além da original (SPP), para entender melhor:

SPP (standard parallel port): é a porta com características originais, com comunicação unilateral e mais lenta, é esse tipo de porta que saiu para comunicação com as impressoras mais antigas;
EPP (enharced parallel port): utilizado em periféricos tipo pass through, com conectores diretos, que não são impressoras;
ECP (enhanced capability port): é o melhor tipo de porta, principalmente para impressoras com entrada tipo paralela.

Acionando dispositivo via comunicação paralela

Hoje em dia o uso da porta paralela está ficando obsoleto, mas ainda é possível usá-la para aprender um pouco mais sobre acionamentos de dispositivos por meio de um sinal (ALTO/BAIXO) com elas.
O computador nomeia as portas paralelas como LPT1, LPT2 e assim por diante, mas a porta física padrão é denominada LPT1 com os endereços: 378h (no envio de um byte de dados) 378+1h (para receber um valor) e, 378+2h (para enviar dados).
A porta paralela padrão utiliza um conector tipo DB25, por onde envia e recebe os dados. É importante salientar que para essa conexão um pino encontra-se em nível lógico 0 quando a tensão elétrica dele se encontra entre 0V à 0,4V e em nível lógico 1 quando atenção se encontra acima de 3.1V à 5V.



fonte: http://theclub.com.br/Restrito/Revistas/200905/intr0905.aspx

No site http://www.rogercom.com/pparalela/introducao.htm existem três projetos interessantes sobre acionamentos de equipamentos via porta paralela. Baseado eles eu fiz um acionamento de leds via portas paralelas e o código fonte segue abaixo:

Código compilado em DEV C++

#include <stdio.h>   // Biblioteca Standard Input/Output
#include <stdlib.h>
#include <conio.h>   // Biblioteca necessária para o uso da função getch();
#include <windows.h> // Biblioteca necessária para o carregamento da inpout32.dll
#include <time.h>

#define LPT1 0x378

/*Inpout32*/
//Declaração dos ponteiros para função.
typedef short _stdcall (*inpfuncPtr)(short portaddr);
typedef void _stdcall (*oupfuncPtr)(short portaddr, short datum);


int main()

{
            //system ("color 18");
            printf("\n\t\tDATA : %s HORA: %s\n\n",__DATE__,__TIME__);
            
HINSTANCE hLib; //Instância para a DLL inpout32.dll.
inpfuncPtr inportb;     //Instância para a função Imp32().
oupfuncPtr outportb;  //Instância para a função Out32().
/*Inpout32*/
   //Carrega a DLL na memória.
   hLib = LoadLibrary("inpout32.dll");
   if(hLib == NULL)
   {
      printf("\n\aErro. O arquivo inpout32.DLL nao foi encontrado.\nO programa vai terminar apos digitar qualquer tecla.");
      return-1;
   }

   inportb = (inpfuncPtr) GetProcAddress(hLib, "Inp32");
   if(inportb == NULL)
   {
      printf("\n\aErro. Erro ao endereçar a função Inp32.");
   }
   //Obtém o endereço da função Out32 contida na DLL.
   outportb = (oupfuncPtr) GetProcAddress(hLib, "Out32");
   if(outportb == NULL)
   {
      printf("\n\aErro. Erro ao endereçar a função Out32.");
        return-1;
   }
/*Inpout32*/
//Interface//
                
        

    
        {
            
            printf("=============================================================\n");
                


        

        
//Programa de Controle//

                            char teclado=' ';
                            puts("\n\tAcionamento de controle de equipamentos externos.");
                            printf("\n=============================================================\n");
                            puts("Ligar ou desligar equipamentos acoplados na porta paralela.\nAperte as teclas referentes a eles:\n");
                            puts("0 - LED VERMELHO \n1 - LED AMARELO \n2 - LED VERDE \n3 - LED VERMELHO \n4 - LED VERDE \n5 - LED AMARELO \n6 - LED VERMELHO \n7 - LED AMARELO ");
                            puts("8 - *TESTA TODOS OS LEDS*");
                            puts("9 - *TESTA TODOS OS LEDS SEQUENCIAL*");
                            puts("\n\n\n(**Quando quiser terminar o programa digite p para parar.**)");
                            puts("(***==========================================mecatronizar.blogspot.com.br***)");
                            teclado=getch();
                            while(teclado!='p')
                        {
                         switch(teclado)
                              { 
                               case '0':
                               outportb(0x378,1);  /* A função que manda um byte para a porta paralela no caso o número 1 ou 0000 0001 em binário*/
                               //system ("colorc8");
                                  break;
                               case '1':
                               outportb(0x378,2); /* Novamente a função que manda um dado a porta paralela*/
                               //system ("color e8");
                                  break;
                               case '2':
                               outportb(0x378,4);
                               //system ("color a8");
                                  break;              
                               case '3':
                               outportb(0x378,8);
                               //system ("color c8");
                                  break;              
                               case '4':
                               outportb(0x378,16);
                               //system ("color a8");
                                  break;              
                               case '5':
                               outportb(0x378,32);
                               //system ("color e8");
                                  break;              
                               case '6':
                               outportb(0x378,64);
                               //system ("color c8");
                                  break;              
                               case '7':
                               outportb(0x378,128);
                               //system ("color e8");
                                  break;
                               case '8':
                               outportb(0x378,0XFF); 
                               //system ("color e8");
                                  break; 
                               case '9':
                               outportb(0x378,1);
                                sleep(2000);
                               outportb(0x378,2);
                                sleep(2000); 
                               outportb(0x378,4);
                                sleep(2000); 
                               outportb(0x378,8);
                                sleep(2000); 
                               outportb(0x378,16);
                                sleep(2000); 
                               outportb(0x378,32);
                                sleep(2000); 
                               outportb(0x378,64);
                                sleep(2000);
                               outportb(0x378,128);
                                sleep(1000);
                               outportb(0x378,0X00);
                                sleep(1000); 
                               outportb(0x378,0XFF);
                                sleep(1000); 
                               outportb(0x378,0X00);
                                sleep(1000); 
                               outportb(0x378,0XFF);
                                sleep(1000); 
                               outportb(0x378,0X00);
                                sleep(1000); 
                               outportb(0x378,0XFF);
                                sleep(1000); 
                               outportb(0x378,0X00);
                                sleep(1000); 
                               outportb(0x378,0XFF);
                                sleep(1000);
                               outportb(0x378,128);
                                sleep(100);  
                               outportb(0x378,64); 
                                sleep(100); 
                               outportb(0x378,32);
                                sleep(100); 
                               outportb(0x378,16);
                                sleep(100);
                               outportb(0x378,8);
                                sleep(100);
                               outportb(0x378,4);
                                sleep(100);
                               outportb(0x378,2);
                                sleep(100);
                               outportb(0x378,1); 

                               //system ("color e8");
                                  break;           
                              }
                              teclado=getch();
                        }
                        
                                                                    
                    
   
                        outportb(0x378,0);
                        FreeLibrary (hLib);
                
                    
        }
                                            
 
                            
                        return 0;
                
        }
//fim do else pertencente ao if que testa se carregou a dll
    
//fim da função main e do programa

Para realizar o projeto você vai precisar de:
1 cabo paralelo;
8 leds de várias cores;
8 resistores de 220 ohms;
1 protoboard.


fonte: próprio autor

Desmontar o conector de um dos lados do cabo e seguir a sequência:
pino 2 - marrom;
pino 3 - vermelho;
pino 4 - laranja;
pino 5 - amarelo;
pino 6 - verde;
pino 7 - azul;
pino 8 - roxo;
pino 9 - banco;
pino 25 - rosa/preto (GND).



fonte: próprio autor

Seguindo os passos abaixo para fazer as ligações necessárias para o funcionamento correto da interface.



fonte: rogercom.com.br


fonte:próprio autor

É importante ressaltar que para o correto funcionamento do programa, um arquivo tipo .dll deve estar inserido no seu computador e a habilitação da porta paralela pode ser necessária, mesmo em sistemas operacionais mais antigos.

Sendo necessário os arquivos ou o projeto completo, clique AQUI para baixá-los.

Para esse projeto foi utilizado um notebook Evo N150 COMPAQ, nesse computador existem portas paralelas e seriais, mas pode ser qualquer outro que tenha disponível porta paralela.



fonte: próprio autor

No vídeo a seguir esta sendo demonstrado como devem ser inseridos os arquivos e a execução do código, gerando o executável para comandar os leds ou qualquer periférico acoplado à porta paralela.



Bons estudos!






sábado, 17 de setembro de 2016

Partida de motor com Arduino e C#

Relés


Relés eletromecânicos são componentes simples formados por um eletroímã e diversos contatos. O conceito de sinal discreto dos primeiros computadores usava relé para implementar as funções booleanas.
De composição simples, os relés de contato são formados basicamente por 4 partes: eletroímã, mola, armadura e contatos.


fonte: http://www.pearltrees.com

Os circuitos que compõe os reés são formados por circuitos independentes e isolados, sem contato em seu estado de repouso. Um switch controla a potência sobre o eletroimã que quando ligado atrai a armadura abrindo ou fechando (depende de sua configuração N/A ou N/F) o circuito para ativar uma carga. Com o eletroimã desenergizado, a mola puxa a armadurae o circuito não se completa.
Por meio do relé é possível controlar diversas variáveis do processo de chaveamento:
·        Tensão e corrente necessárias para ativar armadura;
·        Número de armaduras;
·        Número de contatos da armadura;
·        Se o contato está Normalmente Aberto (NA) ou Normalmente Fechado (NF).

Funcionamento


Quando uma chave ou interruptor é acionado, uma pequena quantidade de energia elétrica transforma a bobina em um eletroímã que move a armadura, permitindo a passagem de uma tensão muito maior do que a usada somente para chaveamento. Essa capacidade suportada pelo mecanismo, e o valor de trabalho da bobina, está geralmente descrito na face do componente.


fonte: http://www.tallertecno.com


fonte: http://engenheirando.com/eletronica/reles/

Acionamento com Arduino Uno

O acioamento de relés com o Microcontrolador Arduino é muito fácil, onde deve ser alterado os estados das portas digitais do Modulo Relé: IN1 e IN2.


fonte: blog.filipeflop.com

fonte: blog.filipeflop.com

Controlando o acionamento e desacionamento de uma lâmpada:

O controle do relé é feito pela saída 3 da placa Arduino, alternando entre acionar e desacionar a carga (lâmpada).

fonte: próprio autor


/*
Projeto Arduino controlando uma lampada via relé
by: TonY EmersoN MariM
--------------------------------------------
--=<| www.mecatronizar.blogspot.com.br |>=--
--------------------------------------------
*/
 
//Porta ligada ao pino IN1 do modulo
int rele1 = 3;

  
void setup()
{
  //Define pinos para o rele como saida
  pinMode(rele1, OUTPUT); 

}
   
void loop()
{
  digitalWrite(rele1, LOW);  //Liga rele 1
  delay(2000);
  digitalWrite(rele1, HIGH); //Desliga rele 1
  delay(2000);
}

O código tem um tempo pré-estabelecido de dois segundos que o estado do relé comuta, até o desligamento do usuário.

Acionamento e controle de um motor monofásico (via serial e C#)


Também é possível acionar outro dispositivo com os relés e implementar junto um controle de supervisão por meio de um aplicativo construído no Visual Studio, conforme os códigos abaixo:
Inserido todos os componentes para elaboração do Form, as funções devem ser aplicadas:

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 Motor_AppArduino
{
    public partial class Form1 : Form
    {
        int Data = 0;

        public Form1()
        {
            InitializeComponent();
            textBox3.Text = "Motor Desligado!";
            pictureBox1.Visible = true;
            timer1.Enabled = true;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            byte[] mensagem = new byte[1];

            mensagem[0] = 0x4C; //L

            try
            {
                serialPort.Write(mensagem, 0, mensagem.Length);
                rtHistorico.AppendText("Ligado:");
                rtHistorico.AppendText(mensagem[0].ToString());
                rtHistorico.AppendText("\n");
            }
            catch (Exception erro)
            {
                rtHistorico.AppendText(erro.Message);
                rtHistorico.AppendText("\n");
            }
            if (textBox1.BackColor == Color.Red && textBox2.BackColor == Color.Red)
            {
                Data += 1;
                textBox2.BackColor = Color.Green;
                textBox3.Text = "Motor Ligado: Horário!";
                pictureBox2.Visible = false;
                pictureBox3.Visible = true;
                pictureBox1.Visible = false;
                button2.Visible = false;
            }
       
        }


        private void button2_Click(object sender, EventArgs e)
        {
            byte[] mensagem = new byte[1];

            mensagem[0] = 0x44; //D

            try
            {
                serialPort.Write(mensagem, 0, mensagem.Length);
                rtHistorico.AppendText("Ligado:");
                rtHistorico.AppendText(mensagem[0].ToString());
                rtHistorico.AppendText("\n");
            }
            catch (Exception erro)
            {
                rtHistorico.AppendText(erro.Message);
                rtHistorico.AppendText("\n");
            }

            if (textBox2.BackColor == Color.Red && textBox1.BackColor == Color.Red)
            {
                Data += 2;
                textBox1.BackColor = Color.Green;
                textBox3.Text = "Motor Ligado: Anti-horário!";
                pictureBox1.Visible = false;
                pictureBox3.Visible = false;
                pictureBox2.Visible = true;
                button1.Visible = false;

            }

        }

            private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {

            this.Invoke(new EventHandler(leituraPorta));
        }


        public void leituraPorta(object sender, EventArgs e)
        {
            //leitura da porta

            byte[] dados = new byte[1];
            int retorno;

            try
            {
                retorno = serialPort.Read(dados, 0, 1);

                if (retorno != 0)
                {
                    rtHistorico.AppendText("Recebido:");
                    rtHistorico.AppendText(dados[0].ToString());
                    rtHistorico.AppendText("\n");

                    if (dados[0] == 76)
                        toolStripStatusLabel1.Text = "Status Atual: Motor ligado";
                    else if (dados[0] == 68)
                        toolStripStatusLabel1.Text = "Status Atual: Motor desligado";
                    else
                        toolStripStatusLabel1.Text = "Status Atual: Desconhecido";

                    serialPort.DiscardInBuffer();
                    serialPort.DiscardOutBuffer();
                }
            }
            catch (Exception erro)
            {
                rtHistorico.AppendText(erro.Message);
                rtHistorico.AppendText("\n");
            }

    }

        private void sairToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Data = 0;
            textBox1.BackColor = Color.Red;
            textBox2.BackColor = Color.Red;

            DialogResult atencao;
            MessageBoxButtons bot = MessageBoxButtons.OKCancel;
            MessageBoxIcon icon = MessageBoxIcon.Warning;
            atencao = MessageBox.Show("Deseja realmente sair?", "ATENÇÃO!", bot, icon);
            switch (atencao)
            {
                case DialogResult.OK:
                    Application.Exit();
                    break;
                case DialogResult.Cancel:
                    break;
            }
        }

        private void sobreToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Aplicativo de Comunicação Serial com Acionamento de Motor Monofásico");
        }

        private void statusStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void btAbrirFechar_Click(object sender, EventArgs e)
        {
            if (btAbrirFechar.Text == "Abrir")
            {
                try
                {
                    if (txPorta.Text != "")
                    {
                        serialPort.PortName = txPorta.Text;
                        serialPort.Open();
                        btAbrirFechar.Text = "Fechar";
                        txPorta.Enabled = false;
                        gbMotor.Enabled = true;
                        toolStripStatusLabel1.Text = "Status Atual: Comunicação Aberta";
                        rtHistorico.AppendText("Porta Aberta");
                        rtHistorico.AppendText("\n");
                    }
                }
                catch (Exception erro)
                {
                    rtHistorico.AppendText(erro.Message);
                    rtHistorico.AppendText("\n");
                }
            }
            else if (btAbrirFechar.Text == "Fechar")
            {
                try
                {
                    serialPort.Close();
                    btAbrirFechar.Text = "Abrir";
                    txPorta.Clear();
                    txPorta.Enabled = true;
                    gbMotor.Enabled = false;
                    toolStripStatusLabel1.Text = "Status Atual: Comunicação Fechada";
                    rtHistorico.AppendText("Porta Fechada");
                    rtHistorico.AppendText("\n");
                }
                catch (Exception erro)
                {
                    rtHistorico.AppendText(erro.Message);
                    rtHistorico.AppendText("\n");
                }
            }
        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {

        }

       
        private void timer1_Tick(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            byte[] mensagem = new byte[1];

            mensagem[0] = 0x50; //P

            try
            {
                serialPort.Write(mensagem, 0, mensagem.Length);
                rtHistorico.AppendText("Parado:");
                rtHistorico.AppendText(mensagem[0].ToString());
                rtHistorico.AppendText("\n");
            }
            catch (Exception erro)
            {
                rtHistorico.AppendText(erro.Message);
                rtHistorico.AppendText("\n");
            }
            if (textBox1.BackColor == Color.Red && textBox2.BackColor == Color.Green)
            {
                Data -= 1;
                textBox2.BackColor = Color.Red;
                textBox3.Text = "Motor Desligado!";
                pictureBox2.Visible = false;
                pictureBox1.Visible = true;
                pictureBox3.Visible = false;
                button1.Visible = true;
                button2.Visible = true;
            }
            else if (textBox1.BackColor == Color.Green && textBox2.BackColor == Color.Red)
            {
                Data -= 2;
                textBox1.BackColor = Color.Red;
                textBox3.Text = "Motor Desligado!";
                pictureBox1.Visible = true;
                pictureBox2.Visible = false;
                pictureBox3.Visible = false;
                button1.Visible = true;
                button2.Visible = true;
            }

        }
    }
}

Como sugestão o aplicativo pode ficar com essa forma depois de compilado:


fonte: próprio autor

Depois disso deve ser gravado no Arduino o código para que o funcionamento ocorra de forma correta.

/*
Projeto Arduino liga e desliga motor universal
via serial aplicativo C#
by: TonY EmersoN MariM
----------------------------------------
--=<| www.mecatronizar.blogspot.com.br |>=--
----------------------------------------
*/
int RELE1 = 5;//Porta ligada ao pino IN1 do modulo relé
int RELE2 = 7;//Porta ligada ao pino IN2 do modulo relé
int CHAVE = 9;//Porta ligada ao pino IN3 do modulo relé
char dado;// variável que recebe os dados

void setup(){
  Serial.begin(9600);
  
  pinMode(RELE1, OUTPUT);//Definem os pinos do relé como saída
  pinMode(RELE2, OUTPUT);
  pinMode(CHAVE, OUTPUT);
  
  digitalWrite(RELE1,HIGH);//Definem os estado iniciais dos relés
  digitalWrite(RELE2,HIGH);
  digitalWrite(CHAVE,HIGH);
}

void loop(){
  if(Serial.available()){//define comunicação serial da placa
    dado = Serial.read();
    
    switch(dado){ //Faz acionamento dos relés segundo os dados recolhidos
      case 'L':
        digitalWrite(RELE1, HIGH);
        delay(100);
        digitalWrite(CHAVE, LOW);
        delay(100);
        digitalWrite(RELE2, LOW);
        delay(1000);
        Serial.println("L");
      break;
      case 'D':
        digitalWrite(RELE2, HIGH);
        delay(100);
        digitalWrite(CHAVE, LOW);
        delay(100);
        digitalWrite(RELE1, LOW);
        delay(1000);
        Serial.println("D");
      break;
      case'P':
        digitalWrite(RELE1, HIGH);
        digitalWrite(RELE2, HIGH);
        digitalWrite(CHAVE, HIGH);
        Serial.println("P");
        break;  
    }
  }
}

Na montagem do circuito com o motor foi utilizado um motor universal de um processador de alimentos. O importante é que para conseguir que o motor execute movimentos de rotações em dois sentidos, horário e anti-horário, a solda que liga as escovas com o enrolamento deve ser desfeito e sair dois pares de variações diferentes.









fonte: próprio autor

É no momento em que os relés que estão recebendo os sinais da escova que ocorrem as comutações do sentido de rotação e para quando o sinal (tensão) que vem da rede passa de fechado para aberto que o motor para de ser acionado.

O vídeo abaixo demonstra o funcionamento de todo o projeto.




Nesse projeto deixo um agradecimento ao meu amigo Gilmar Léo, pela ajuda com o motor.


Caso necessite, o projeto completo pode ser baixado por esse LINK, se necessário entre em contato, para dúvidas, elogios e críticas.

Bons estudos! 




ATENÇÃO: O relé trabalha com oque chama-se normalmente de lógica inversa, então é necessário que para ser acionado ele receba o sinal baixo (LOW, 0). O recurso de trabalhos realizados com lógica inversa é necessário para que a segurança do acionamento do dispositivo seja garantida, em um ambiente de aterramento prejudicado, ou interferências eletromagnéticas pode fazer com que seja captado um ruído e o sinal seja entendido como sinal alto e o dispositivo atuado, causando funcionamento desnecessário e até mesmo acidentes.




quinta-feira, 8 de setembro de 2016

Projeto com Microcontrolador Pic

Supervisório em C# + Microcontrolador PIC



Vemos hoje em dia uma grande porcentagem de projetos envolvendo sistemas embarcados que tendem ao uso principalmente de plataformas de programação tipo arduino ou similar, mas existem diversas maneiras de construir um sistema eletrônico microcontrolado, e um dos embarcados mais populares para esses projetos são os microcontroladores PIC das mais diversas famílias.
Seguindo nessa linha vamos aprender a criar um sistema de controle com o uso de um Microcontrolador da família  PIC18F4520. É basicamente um acionamento de uma ventoinha por meio da variação de temperatura de um LM35, e informações recebidas e enviadas por meio de um monitor serial, com animações elaborado em linguagem Visual Studio C#.

Então vamos ao projeto!

Eletrônica

Para realização do projeto é necessário os seguintes componentes:

1 Microcontrolador PIC18f4520
2 transistores BC337
1 LM35
2 potenciômetros de 10 Kohms
1 Max 232
4 capacitores de 10uF
2 capacitores 22 pF
1 cristal oscilador 8Mhz
4 resistores de 220 ohms
4 resistores de 10 Kohms
2 resistores de 2K2
1 resistor 56 ohm
4 Leds 
1 visor LCD
1 ventoinha 12vcc
1 conector DB9 fêmea
1 cabo conversor USB/RS-232
1 fonte ajustável com 5vcc/ 12vcc
cabos jumper

Logo abaixo é possível ver o esquemático em software de projetos Proteus:


fonte: próprio autor

Código fonte

O código fonte do funcionamento do microcontrolador foi elaborado no CCS PicC e logo abaixo é possível ver o funcionamento de cada uma das funções aplicadas 

Código fonte elaborado no CCSPICC:

 #include<18F4520.h>      //Inclui arquivo header do PIC 18F4520  
 #device ADC = 10       //Define 10 bits para o resultado da conversão AD  
 #use delay (clock=8000000)  /*Definição da frequência do cristal para cálculo   
                ..dos delays*/  
 #fuses HS, NOWDT, PUT,BROWNOUT, NOLVP //Configuração dos bits de controle  
 //Definições para a comunicação serial  
 #use RS232 (Baud=9600, xmit = PIN_C6, rcv = PIN_C7)  
 #include "LCD4B.c"     //Inclui arquivo de funções do LCD  
 int32 ad0, ad1;       //variáveis para armazenamento da conversão  
 int32 ADC0, ADC1;  
 int l1=0, l2=0, l3=0, l4=0; //variáveis de controle para os leds  
 /******************************************************************************  
 variáveis de controle:  
 vent = ventoinha;  
 aq = aquecedor;  
 cont = controle de índice para recepção serial;  
 tempo = informação de tempo em 2 segundos  
 chg = controle para visualização dos dados no LCD.  
 *******************************************************************************/  
 int vent = 0, aq=0, cont=0, tempo=0, chg = 0;  
 int1 tmp = 0;   /*variável de controle de tempo em 2 segundos para  
           alterarção das informações no LCD*/  
 int rec[5];    //Variável de recepção de dados pela serial  
 #INT_RDA     //Diretiva de identficação p/ int. pela recepção serial  
 void rec_serial() //Funçõa de tratamento da recepção de dados  
 {  
 rec[cont] = getc();   /*Lê o dado vindo pela serial e o armazena em  
              rec na posição (índice) informado por cont*/   
 if (rec[cont] == 0x0D) //Verifica se o dado recebido é igual a CR (0x0D)  
   {  
   //Liga Leds 1, 2 , 3, 4 e Aquecimento    
   if (rec[0]=='L' && rec[1]=='G') //Verifica se os primeiros caracteres são 'LG'  
    {  
    if (rec[2] == '1')      //Verifica se o terceiro caractere é '1'  
      {  
      l1 = 1;          //controle de leds l1 = 1  
      output_bit(PIN_D0,l1);   //Acende Led conectado ao pino RD0  
      }  
    if (rec[2] == '2')      //Verifica se o terceiro caractere é '2'  
      {  
      l2 = 1;          //controle de leds l2 = 1  
      output_bit(PIN_D1,l2);   //Acende Led conectado ao pino RD1  
      }  
    if (rec[2] == '3')      //Verifica se o terceiro caractere é '3'  
      {  
      l3 = 1;          //controle de leds l3 = 1  
      output_bit(PIN_D2,l3);   //Acende Led conectado ao pino RD2   
      }  
    if (rec[2] == '4')      //Verifica se o terceiro caractere é '4'  
      {  
      l4 = 1;          //controle de leds l4 = 1  
      output_bit(PIN_D3,l4);   //Acende Led conectado ao pino RD3  
      }   
    if (rec[2] == 'A')      //Verifica se o terceiro caractere é 'A'  
      {  
      aq = 1;          //controle de aquecimento aq = 1  
      output_bit(PIN_C1,aq);   //Liga o circuito de aquecimento em RC1  
      }     
    }  
   //Desliga Leds 1, 2, 3 e 4    
   if (rec[0]=='D' && rec[1]=='G') //Verifica se os primeiros caracteres são 'DG'  
    {  
    if (rec[2] == '1')      //Verifica se o terceiro caractere é '1'  
      {  
      l1 = 0;          //controle de leds l1 = 0  
      output_bit(PIN_D0,l1);   //Apaga Led conectado ao pino RD0  
      }  
    if (rec[2] == '2')      //Verifica se o terceiro caractere é '2'  
      {  
      l2 = 0;          //controle de leds l2 = 0  
      output_bit(PIN_D1,l2);   //Apaga Led conectado ao pino RD1  
      }  
    if (rec[2] == '3')      //Verifica se o terceiro caractere é '3'  
      {  
      l3 = 0;          //controle de leds l3 = 0  
      output_bit(PIN_D2,l3);   //Apaga Led conectado ao pino RD2  
      }  
    if (rec[2] == '4')      //Verifica se o terceiro caractere é '4'  
      {  
      l4 = 0;          //controle de leds l4 = 0   
      output_bit(PIN_D3,l4);   //Apaga Led conectado ao pino RD3  
      }      
    }   
   /*Após recebido todos os dados da serial, faz a limpeza de toda a  
   variável rec e retorna o controle de índices cont em 0*/  
   for(cont = 0; cont < 5; cont++) rec[cont] = '\0';   
   cont = 0;   
   }  
 else  
   /*Se ainda não foram recebidos todos os dados de controle, incrementa  
   a variável de índice cont*/  
   cont++;    
 }  
 #INT_TIMER0    //Diretiva de indetificação da int. do Timer 0  
 void Trata_t0()  //Função para tratamento do Timer 0  
 {  
 tempo++;     //Incrementa a variável tempo a cada 25ms  
 if (tempo >= 80) //Se tempo >= 80 <=> 2 segundos?  
   {  
   tmp = 1;   //Variável de controle de tempo 2 seg vai para 1  
   tempo = 0;  //Retorna a variável tempo em 0  
   }  
 SET_TIMER0(61);  //Retorna o valor inicial ao Timer 0  
 }  
 //Formato do protocolo = AN0:0000:TMP:0000:00000000  
 void escreve_serial()   //Função de envio do protocolo para a serial  
 {  
 printf("AN0:%04lu",ad0);  //Envia dados de conversão A/D para exibir tensão  
 printf(":");        //Controle do protocolo  
 printf("TMP:%04lu",ad1);  //Envia dados de conversão A/D para exibir temperatura  
 printf(":");        //Controle do protocolo  
 /******************************************************************************  
 Envia dados referentes ao circuito de aquecimento, ventoinha e leds  
 0: desligado  
 1: ligado  
 ******************************************************************************/  
 printf("%d%d00%d%d%d%d",aq, vent, l1, l2, l3, l4);   
 //printf(":");        //Controle do protocolo  
 }  
 //void limpa_leds()  //Função   
 //{  
 //output_low(PIN_D4);  
 //output_low(PIN_D5);  
 //output_low(PIN_D6);  
 //output_low(PIN_D7);  
 //}  
 void main()          //Função principal   
 {  
 //Configura as entradas analógicas AN0 a AN3  
 SETUP_ADC_PORTS(AN0_TO_AN3);    
 //Utiliza o clock interno para tempo de aquisição   
 SETUP_ADC(ADC_CLOCK_Internal);  
 output_low(PIN_C1);  //Desliga circuito de aquecimento  
 output_low(PIN_C2);  //Desliga circuito da Ventoinha  
 //Habilita interrupção global  
 Enable_Interrupts(GLOBAL);  
 //Habilita interrupção por recepção de dados na serial  
 Enable_Interrupts(INT_RDA);  
 //Habilita interrupção pelo overflow do Timer 0  
 ENABLE_INTERRUPTS(INT_TIMER0);  
 /*Configura Timer 0 para incremento pelo ciclo de máquina  
 Prescaler de 1:256 e modo de operação em 8 bits*/  
 SETUP_TIMER_0(RTCC_INTERNAL | RTCC_DIV_256 | RTCC_8_BIT);  
 //Inicia o Timer 0 com o valor 61 - Interrupção a cada 25ms  
 SET_TIMER0(61);  
 lcd_ini(); //Inicia o LCD  
 //Escreve as mensagens iniciais no LCD  
 printf(lcd_escreve,"\f SUPERVISORIO");  
 printf(lcd_escreve,"\nMECATRONIZANDO");  
 output_D(0x00);      //Faz toda a porta D = 0  
 l1 = input_state(PIN_D0); //armazena em l1 o estado do pino RD0  
 l2 = input_state(PIN_D1); //armazena em l2 o estado do pino RD1  
 l3 = input_state(PIN_D2); //armazena em l3 o estado do pino RD2  
 l4 = input_state(PIN_D3); //armazena em l4 o estado do pino RD3  
 /*Faz a limpeza de toda a variável rec e faz o controle  
  de índices cont em 0*/  
 for(cont = 0; cont < 5; cont++) rec[cont] = '\0';   
 cont = 0;  
 while(true)              //Loop principal  
   {   
   if (!input(PIN_B0))   //Se chave conectada ao pino RB0 for pressionada   
    {  
    output_high(PIN_C1); //Liga circuito de aquecimento  
    aq = 1;       //Faz controle de aquecimento aq = 1  
    }  
   SET_ADC_CHANNEL(0);   //Configura o canal de leitura 0  
   delay_us(100);     //Tempo de ajuste do canal (necessário)   
   ad0 = READ_ADC();    //Faz a conversão AD e a salva na variável ad0  
   SET_ADC_CHANNEL(3);   //Configura o canal de leitura 3  
   delay_us(100);     //Tempo de ajuste do canal (necessário)   
   ad1 = READ_ADC();    //Faz a conversão AD e a salva na variável ad0  
   ADC0 = (ad0 * 500) /1023; //Cálculo da conversão AD para o LCD (Tensão)  
   ADC1 = (ad1 * 500) /1023; //Cálculo da conversão AD para o LCD (temperatura)     
   if (ad1>=81)      //Se ad1 >= 81 (aprox. 40 graus)  
   {  
    output_low(PIN_C1); //Desliga circuito de aquecimento  
    output_High(PIN_C2); //Liga circuito da ventoinha  
    aq = 0;       //Faz controle de aquecimento aq = 0  
    vent = 1;      //Faz controle da ventoinha vent = 1  
   }  
   if (ad1<=60)      //Se ad1 <= 60 (aprox. 27 graus)  
   {  
    output_low(PIN_C2); //Desliga circuito da ventoinha  
    vent = 0;      //Faz controle da ventoinha vent = 0;  
   }  
   escreve_serial();    //Envia dados pela serial  
   if (tmp)        //Se tmp = 1 (a cada 2 segundos)  
     {  
     chg++;       //incrementa a variável chg  
     if (chg==1)     //se chg = 1  
       {  
       //Exibe tensão e temperatura no LCD  
       printf(lcd_escreve,"\fAN0 : %lu,%02lu V", ADC0/100, ADC0%100);  
       printf(lcd_escreve,"\nTEMP: %lu%cC",ADC1,0xDF);  
       }  
     if (chg==2)     //Se tmp = 2  
       {  
       /*Exibe as informações dos circuitos de aquecimento e  
       ventoinha*/  
       printf(lcd_escreve,"\fAQ: %d  VENT: %d",aq,vent);  
       }    
    if (chg==3)     //Se tmp = 3  
       {  
       //Exibe as informações do estado dos LEDS  
       printf(lcd_escreve,"\fL1: %d  L2: %d",l1,l2);  
       printf(lcd_escreve,"\nL3: %d  L4: %d",l3,l4);  
       chg = 0;    //Faz chg = 0  
       }  
     //limpa_leds();    
     tmp = 0;      //Retorna tmp em 0  
     }     
   delay_ms(300);     //Atraso de 100ms  
   }  
 }    

Esse código fonte foi baseado em um material extraído do livro Conceitos básicos de Visualização e Controle, Carlos Eduardo Sandrini Luz.

O Aplicativo

O aplicativo feito consiste em um sistema que deve ser logado para pode visualizar o funcionamento correto do sistema, consiste em 4 Forms e uma tela de login, faz-se uso de diversos conceitos vistos anteriormente em nossas vídeo aulas e na elaboração de uma classe do tipo Global, criaçao de um Protocolo e faz uso de uma Porta COM para comunicação Serial.
Pode se considerar esse tipo de aplicativo como um exercício em nível intermediário/ alto de dificuldade.

O funcionamento:

Quando executado, o aplicativo apresenta uma tela de login para que seja inserido um nome de usuário e senha e o sistema entre em funcionamento.
USUÁRIO: mecatronizando
SENHA: 12345


fonte: próprio autor

Uma tela de carregamento mostra o sistema se "preparando", apesar de não trabalhar com nenhuma SQL, mas se houvesse, seria nesse momento em que elas seriam carregadas.

Ao abrir o sistema apresenta a tela de Visualização e Controle


fonte: próprio autor

No cabeçalho do aplicativo é possível navegar e conectar o circuito, na Aba Arquivo, é possível salvar um histórico do funcionamento do circuito em formato. txt, e em Sair é possível fechar o aplicativo.




fonte: próprio autor

Em Comunicação Serial, Configurações, o usuário deve escolher a porta de comunicação ao qual o circuito vai utilizar para o funcionamento, velocidade, paridade, stop e data bits.


fonte:próprio autor

Ao acessar Abrir Porta o sistema passa a comunicar-se com o circuito.
Com o circuito alimentado e conectado ao PC, as informações entre as máquinas começam a ser trocadas via TX/ RX, um gráfico do estado do leitor de temperatura LM35 começa a ser traçado no ambiente gráfico. É possível observar também nos Gauges a tensão variante conforme o movimento no potênciometro e a temperatura no componente.


fonte: próprio autor

Na parte inferior do aplicativo uma região de controle possibilita que por meio da tela do PC o usuário controle os leds inseridos no sistemas, que respondem ao aplicativo em tempo real.


fonte: próprio autor


fonte: próprio autor


Quando o LM 35 sofrer uma variação de temperatura e ultrapassar 40°C, uma ventoinha é acionada até que a temperatura se estabilize e permaneça abaixo dos 27°C, esse procedimento é acompanhado visualmente pela tela do aplicativo.


fonte: próprio autor

Além da praticidade do acompanhamento via remota (pelo PC), existe um visor LCD para acompanhamento local de funcionamento do sistema.




fonte: próprio autor

No vídeo, é possível ver o funcionamento completo do sistema:





Código fonte do aplicativo completo de cada um dos Forms usados no projeto:

Login

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 APLICATIVO
{
    public partial class Login : Form
    {
        public Login()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (textBox1.Text == "mecatronizando" && textBox2.Text == "12345")
            {
                Form0 newForm0 = new Form0();
                newForm0.Show();
                this.Visible = false;
            }

            else
            {
                MessageBox.Show("Loguin e/ou senha Incorretos!", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textBox1.Text = "";
                textBox2.Text = "";
            }
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            textBox2.PasswordChar = '*';
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
    }
}

Carregando...

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 APLICATIVO
{
    public partial class Form0 : Form
    {
        public Form0()
        {
            InitializeComponent();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (progressBar1.Value < 100)
            {
                progressBar1.Value = progressBar1.Value + 2;
            }

            else
            {
                timer1.Enabled = false;
                Form1 newForm1 = new Form1();
                newForm1.Show();
                this.Visible = false;
            }
        }
    }
}

Form1


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;

using System.Drawing.Drawing2D;


namespace APLICATIVO
{
    public partial class Form1 : Form
    {
        //Instanciando a classe 
        SerialPort SerialCom = new SerialPort();

        string bfRecebe = string.Empty;

        //Criando o método(função) Fdelegate que vai receber o parâmetro do tipo string 'a'

        public delegate void Fdelegate(string a);

        List<string> TempList = new List<string>();

        string txt_rec = string.Empty;
        string txt_list = string.Empty;

        int qtde_data = 0;

        float eixo_x = 0;
        float eixo_y = 0;

        bool vent = false, aq = false;
        bool l1 = false, l2 = false, l3 = false, l4 = false;

        private void Form1_Load(object sender, EventArgs e)
        {
            xyGraph1.AddGraph("Temperatura/Tempo", DashStyle.Solid, Color.White, 1, false);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
            button1.Enabled = false;
            button2.Enabled = true;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            button1.Enabled = true;
            button2.Enabled = false;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            TempList.Add(DateTime.Now + " - " + txt_list);
            qtde_data++;

            eixo_y = aGauge2.Value;
            eixo_x++;
            if (eixo_x >= 120)
            {
                timer1.Enabled = false;
                button1.Enabled = true;
                button2.Enabled = false;
            }

            xyGraph1.AddValue(0, eixo_x, eixo_y);
            xyGraph1.DrawAll();
        }

        private void salvarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TextWriter Arq;

            try
            {
                if (saveFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    Arq = File.AppendText(saveFileDialog1.FileName);

                    for (int i = 0; i < qtde_data; i++)
                        Arq.WriteLine(TempList[i]);

                    Arq.Close();
                }

                MessageBox.Show("Cadastro realizado com sucesso!");

            }
            catch (Exception erro)
            {
                MessageBox.Show(erro.ToString());
            }

        }

        private void sairToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            StreamReader Arq;
            string recebe = string.Empty;

            eixo_x = 0;

            xyGraph1.ClearGraph(0);

            try
            {
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    Arq = new StreamReader(openFileDialog1.FileName);


                    while (!(Arq.EndOfStream))
                    {
                        recebe = Arq.ReadLine().Substring(35, 4);

                        eixo_y = (float.Parse(recebe) * 500) / 1023;

                        xyGraph1.AddValue(0, eixo_x, eixo_y);
                        xyGraph1.DrawAll();
                        eixo_x++;
                    }
                }
            }

            catch (Exception erro)
            {
                MessageBox.Show(erro.ToString());
            }
        }

        private void configuraçãoToolStripMenuItem_Click(object sender, EventArgs e)
        {
                Form2 nForm = new Form2();
                nForm.ShowDialog();

                if (!Global.Cancela)
                {

                    try
                    {
                        if (SerialCom.IsOpen) SerialCom.Close();

                        SerialCom.PortName = Global.Porta;
                        SerialCom.BaudRate = int.Parse(Global.BRate);
                        SerialCom.StopBits = (StopBits)Enum.Parse(typeof(StopBits), Global.SBits);
                        SerialCom.DataBits = int.Parse(Global.DBits);
                        SerialCom.Parity = (Parity)Enum.Parse(typeof(Parity), Global.Paridade);

                        button1.Enabled = true;

                        SerialCom.Open();

                    }
                    catch
                    {
                        MessageBox.Show("Não foi possível abrir a Porta Serial!");
                    }
                }
            }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            if (!l1) SerialCom.Write("LG1\r");

            else SerialCom.Write("DG1\r");
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {
            if (!l2) SerialCom.Write("LG2\r");

            else SerialCom.Write("DG2\r");
        }

        private void pictureBox3_Click(object sender, EventArgs e)
        {
            if (!l3) SerialCom.Write("LG3\r");

            else SerialCom.Write("DG3\r");
        }

        private void pictureBox4_Click(object sender, EventArgs e)
        {
            if (!l4) SerialCom.Write("LG4\r");

            else SerialCom.Write("DG4\r");
        }

        private void pictureBox5_Click(object sender, EventArgs e)
        {
            if (!aq) SerialCom.Write("LGA\r");

            else SerialCom.Write("DGA\r");
        }

        private void sobreToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Form3 Fsobre = new Form3();
            Fsobre.ShowDialog();
        }

        private void xyGraph1_Load(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            Close();
        }

        public Form1()
        {
            InitializeComponent();
            SerialCom.DataReceived += new SerialDataReceivedEventHandler(SerialCom_DataReceived);
        }
        void SerialCom_DataReceived(object sender, SerialDataReceivedEventArgs e)

        {
            //throw new NotImplementedException();
            bfRecebe = SerialCom.ReadExisting();

            this.BeginInvoke(new Fdelegate(recebe_serial), new object[] { bfRecebe });
        }

        public void recebe_serial(string a)
        {
            string[] txtSplit;
            int volts, temp;

            txt_rec += a;

            if (txt_rec.Length >= 26)
            {
                txtSplit = txt_rec.Split(':');
                txt_rec = string.Empty;

                if (txtSplit[0] == "AN0")
                {
                    txt_list = txtSplit[0] + ":" + txtSplit[1] + ":" + txtSplit[2] + ":" + txtSplit[3]; 
                    volts = Convert.ToInt32(txtSplit[1]);
                    aGauge1.Value = (volts * 5000) / 1023;
                    aGauge1.Cap_Idx = 1;
                    aGauge1.CapText = aGauge1.Value.ToString() + " mV";

                    temp = Convert.ToInt32(txtSplit[3]);
                    aGauge2.Value = ((temp * 500) / 1023);
                    aGauge2.Cap_Idx = 1;
                    aGauge2.CapText = aGauge2.Value.ToString() + " " + (char) 176 + " C ";


                    //Verifica Led 1
                    if (txtSplit[4].Substring(4, 1) == "1")
                    {
                        pictureBox1.Image = APLICATIVO.Properties.Resources.AMARELO;
                        l1 = true;
                    }
                    else
                    {
                        pictureBox1.Image = APLICATIVO.Properties.Resources.AMARELOAPAGADO;
                        l1 = false;
                    }

                    //Verifica Led 2
                    if (txtSplit[4].Substring(5, 1) == "1")
                    {
                        pictureBox2.Image = APLICATIVO.Properties.Resources.AMARELO;
                        l2 = true;

                    }
                    else
                    {
                        pictureBox2.Image = APLICATIVO.Properties.Resources.AMARELOAPAGADO;
                        l2 = false;
                    }

                    //Verifica Led 3
                    if (txtSplit[4].Substring(6, 1) == "1")
                    {
                        pictureBox3.Image = APLICATIVO.Properties.Resources.LED_ON1;
                        l3 = true;
                    }
                    else
                    {
                        pictureBox3.Image = APLICATIVO.Properties.Resources.LED_OFF1;
                        l3 = false;
                    }

                    //Verifica Led 4
                    if (txtSplit[4].Substring(7, 1) == "1")
                    {
                        pictureBox4.Image = APLICATIVO.Properties.Resources.LED_ON1;
                        l4 = true;
                    }
                    else
                    {
                        pictureBox4.Image = APLICATIVO.Properties.Resources.LED_OFF1;
                        l4 = false;
                    }

                    //Verifica Aquecedor
                    if (txtSplit[4].Substring(0, 1) == "1")
                    {
                        pictureBox5.Image = APLICATIVO.Properties.Resources.LED_ON1;
                        aq = true;
                    }
                    else
                    {
                        pictureBox5.Image = APLICATIVO.Properties.Resources.LED_OFF1;
                        aq = false;
                    }

                    //Verifica Ventoinha
                    if (txtSplit[4].Substring(1, 1) == "1")
                    {
                        pictureBox6.Image = APLICATIVO.Properties.Resources.LED_ON1;
                        vent = true;
                    }
                    else
                    {
                        pictureBox6.Image = APLICATIVO.Properties.Resources.LED_OFF1;
                        if (vent && !aq)
                        {
                            vent = false;

                        }

                    }
                }
            }
        }
    }
}

Form2

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;

namespace APLICATIVO
{
    public partial class Form2 : Form
    {
        SerialPort COMSerial = new SerialPort();

        public Form2()
        {
            InitializeComponent();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            bool setcom = false;

            foreach (string str in SerialPort.GetPortNames())
            {
                cmbPorta.Items.Add(str);
                if (str == "COM1") setcom = true;
            }

            if (setcom)
                cmbPorta.SelectedText = "COM1";
            else
                cmbPorta.SelectedIndex = 0;

            cmbBaud.Text = "9600";

            int i = 0;

            foreach (string str in Enum.GetNames(typeof(Parity)))
            {
                cmbPar.Items.Add(str);

                if (str == "None")
                    cmbPar.SelectedIndex = i;

                i++;
            }

            i = 0;

            foreach (string str in Enum.GetNames(typeof(StopBits)))
            {
                cmbStop.Items.Add(str);

                if (str == "One")
                    cmbStop.SelectedIndex = i;

                i++;
            }
            cmbData.Text = "8";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Global.Porta = cmbPorta.Text;
            Global.BRate = cmbBaud.Text;
            Global.SBits = cmbStop.Text;
            Global.DBits = cmbData.Text;
            Global.Paridade = cmbPar.Text;
            Global.Cancela = false;
            Close();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //Garante o fechamento da porta serial
            if (COMSerial.IsOpen) COMSerial.Close();
            Global.Cancela = true;
            Close();
        }
    }
}

O aplicativo e todo projeto pode ser baixado por esse LINK, continue nos acompanhando.

Bons estudos!




Referências:
LUZ, Carlos E.S. Elaboração de aplicativos. In: Criação de sistemas supervisórios em Visual C# 2010 Express: conceitos básicos, visualização e controle. ed.1. São Paulo, SP: Érica, 2012.

domingo, 4 de setembro de 2016

Controle do Servo motor Arduino + C#

Controlando servo motor com Arduino + C#

Uma maneira bastante prática de controlar um servo motor também pode ser elaborada com uma aplicativo criado no Visual Studio C#, com esses recursos é possível aplicar de uma maneira diferente em um projeto onde envolva programação com Arduino.


fonte: próprio autor

código fonte:

Abaixo segue o código fonte descrito da programação do Arduino e logo abaixo uma vídeo aula explicativa sobre a elaboração do aplicativo no C#.


Bons estudos!


/*
Projeto Arduino controlando um Servo Motor 
via serial aplicativo C#
by: TonY EmersoN MariM
--------------------------------------------
--=<| www.mecatronizar.blogspot.com.br |>=--
--------------------------------------------
*/

#include <Servo.h> // biblioteca do servo motor

Servo myservo;//declaração do servo

int val;//declarando valores como inteiro

void setup(){
  Serial.begin(9600);//uso da porta serial do arduino 
  myservo.attach(9);// indicção do pino de controle do servo motor
}

void loop(){
}

void serialEvent(){
  val=Serial.parseInt();// conversão dos valores para a leitura

  if(val!=0){
    myservo.write(val);// escreve a leitura
    }
}