Sistema de controle com PIC e porta Serial (rs232) parte 2

0saves

Hoje vou mostrar como fazer a parte do PC para se conectar com o PIC , e tem algumas alteraçoes no codigo do pic tambem.
Não vou entrar em muitos detalhes sobre o codigo do PIC pois este era o foco da parte 1
Segue o codigo:

#include "16f628a.h"                           // Inclui o cabeçalho especifico do pic a ser utilizado
#include "stdio.h"                              // Inclui as funçoes padroes de entrada e saida
#fuses HS,NOWDT,NOPROTECT                       // Configuração dos fuses (ver manual)
#use delay(clock=4000000)                       // Seta o clock interno para 4Mhz
#use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1)  // Seta o baud rate para 9600, e define o pino B2 como TX e B1 como RX
 
unsigned char x[4];  //Variavel do tipo char com 4 posiçoes (string de até 3 carateres) ou do tamanho do comando que desejarem utilizar
// lembrando que sempre deve ter um caractere a mais pois tem o '\0' no final da string
unsigned int pino; //Variavel que armazenara o pino que esta sendo utilizado
 
void main(void) // função principal
{
   delay_ms(100); //tempo para inicializar a conexão
   do {
      gets(x); // pega a string e coloca na variavel x
      if(x[0] == 'a' || x[0]=='A') // Fazer isso para todas as portas desejadas, podendo ser A,B,C.. depende do pic
      {
         switch(x[1]) // Ve se qual pino da porta quer controlar
         {
            case '0':
               pino = PIN_A0;
               break;
            case '1':
               pino = PIN_A1;
               break;
            case '2':
               pino = PIN_A2;
               break;
            case '3':
               pino = PIN_A3;
               break;
            default:
               pino = 0; // se não for nenhum, coloca como 0;
               break;
         }
      }
      else if(x[0] == 'b' || x[0]=='B') // mesma coisa que antes, porem agora para a porta B (e assim pode continuar)
      {
         switch(x[1])
         {
            case '0':
               pino = PIN_B0;
               break;
            case '1':
               pino = 0; // pino reservado para RS232
               break;
            case '2':
               pino = 0; // pino reservado para RS232
               break;
            case '3':
               pino = PIN_B3;
               break;
            case '4':
               pino = PIN_B4;
               break;
            case '5':
               pino = PIN_B5;
               break;
            case '6':
               pino = PIN_B6;
               break;
            case '7':
               pino = PIN_B7;
               break;
            default:
               pino = 0;
               break;
         }
      }
      else
      {
       pino=0;
       // Se não existir a porta que foi escolhida, seta o pino para 0 para que não mude o que foi escolhido anteriormente
      }
 
      if(pino != 0) // Se o pino existir (não for 0)
      {
         if(x[2]=='l' || x[2]=='L')// Se o comando for L ou l (de ligar) 
         {
            output_high(pino); // Coloca o valor 1 logico no pino escolhido
            printf("200\n\r");
         }
         else if(x[2]=='d' || x[2]=='D') // Se o comando for D ou d(de desligar) 
         {
            output_low(pino); // Coloca o valor 0 logico no pino escolhido 
            printf("200\n\r");
         }
         else // Se o comando não for de ligar ou desligar
         {
            printf("505\n\r"); //Avisa que o comando é invalido
         }
      }
      else // Se o pino não existir (variavel pino igual a 0)
      {
         printf("505\n\r");
      }
   } while (TRUE); // mantem o laço de repetição rodando em loop infinito
}

Bom, agora vamos ao que interessa, o software que controla o PIC pela porta serial de um PC.
Normalmente a conexão serial é meio chatinha de fazer (seja em linux, windows, mac..) então recomendo que usem a biblioteca que se encontra neste site ( http://www.teuniz.net/RS-232/ ) que facilita bastante o nosso trabalho, e ja deixa portavel para outros OS tambem. Essa biblioteca é extremamente simples de ser utilizada, não vejo sentido em reescrever todo o codigo para a comunicação serial se ja tem uma biblioteca boa que faz isso, a não ser para aprender como funciona (recomendo que leiam o codigo da biblioteca)

Segue o codigo:

#include "stdio.h"
#include "stdlib.h"
#include "conio.h"
#include "windows.h"
#include "string.h"
#include "rs232.h"
 
void loop(); // Declarando a função loop que está la em baixo
 
unsigned char comando[5]; // comando a ser enviado
unsigned char buff[1024]; // comando recebido
 
int main(void) // Função principal
{
    OpenComport(1,9600); // abre a porta desejada (ver documentação)
    loop(); // Chama a função loop
    return 0;
}
 
void loop() // Função loop
{
    int n; // variavel temporaria
    n = PollComport(1,buff,1024); // n != 0  se tiver algo pra ser recebido
    if(n == 0) // se não tiver recebendo nada
    {
        printf("Digite o seu comando: "); //pergunta qual comando quer executar
        gets(comando); // Pega o comando e coloca na variavel comando
        strcat(comando,"\n\r");// adiciona uma quebra de linha (mais por motivos esteticos se for testar em terminal ou quardar log)
        cprintf(1,comando); // manda o comando para a porta serial (ou USB com FTDI)
        _sleep(200); // delay de 200 milisegundos necessario para a sincronização (pode ser de 100)
    }
    else // Se tiver recebido algo
    {
        // Switch para ver o que cada codigo representa, e exibe para o usuario.
        switch(atoi(buff))
        {
            case 200:
                printf("OK!\n\r");
                break;
            case 505:
                printf("Erro!\n\r");
                break;
            default:
                break;
        }
    }
    loop(); // Chama a função novamente, assim mantendo um loop infinito
}

Acho que da pra entender como funciona só pelos comentarios.
Esse codigo foi testado no windows 7 ultimate 64bit, utilizando o code::blocks para programar, e o GNU GCC para compilar. Para funcionar para linux tambem é necessario alterar algumas coisas, mas a logica é a mesma.

Ah, não saiam ligando os fios da serial direto no pic é preciso utilizar um MAX232 para isso, pois o sinal da serial é diferente do TTL utilizado pelo pic. Para saber como ligar o MAX232 é só olhar no datasheet.

Se quiserem testar só a comunicação serial virtualmente, recomendo o uso do virtual serial port driver da eltima, e hyper terminal.

Ainda falta eu colocar aqui a parte dos sockets (para o controle remoto), que ja está pronta só tenho que juntar tudo, e a parte eletro-eletronica tambem, por exemplo um dimmer para uma lampada, como controlar interruptores… e alguns outros exemplos do que fazer. A principio quero montar uma placa que controle varios interruptores.

Qualquer duvida, sugestão ou critica, favor deixar nos comentarios

Tags: , , , ,

27 Responses to “Sistema de controle com PIC e porta Serial (rs232) parte 2”

  1. Lucas disse:

    Grande Armando Keller!!
    tá ficando bonito esse site com enfase na engenharia elétrica!! tá ficando bonito o site… Parabénss
    vou usar de base quando começa a usar PIC
    Abração

  2. Rafael Saude disse:

    Sr,
    muito bom tutorial
    mas nao consegui testar i botar pra funcionar pq nao axei a lib 16f628a.h.

    gostaria de saber onde baixar o arquivo 16f628a.h pois nao encontro ele na internet vc poderia me enviar por e-mail ou link.

    obrigado.

  3. Bah não chama de Sr., parce que sou velho, tenho só 20 anos :P
    Bom, se não funcionou por não achar esta biblioteca, esta usando o compilador errado. Esse codigo é valido para o CCS Compiler ( http://www.ccsinfo.com/content.php?page=compilers ) lembrando que é um compilador para PIC, ele vai gerar um .hex que sera gravado no pic, ou como nesse caso testado direto no simulador (proteus). Existem outros compiladores para PIC como o mikroC, C 18 … mas cada um usa metodos e bibliotecas diferentes. Recomendo o CCS pela quantidade de exemplos disponiveis na internet (o que facilita bastante o aprendizado).
    Qualquer duvida avisa ai.

  4. Bruno Richter disse:

    Armando,
    realmente expetacular o conteudo!!!
    Faz tempo que procuro algum bom manual de porta Serial e não encontro. Esse tutorialzinho me ajudou bastante!!
    Fico aguardando a parte dos Sockets, dimmers…
    Também estou querendo montar uma placa para controlar varios interruptores!!!
    Show de BOLA!!!
    Abração!
    Obrigado

  5. Rui Baptista disse:

    Parabens Armando!! Deu-me imenso jeito!

  6. rebecca disse:

    lol a couple of the reviews bloggers write are silly and unrelated, sometimes i wonder whether they at all read the posts before writing or whether they only look at the subject of the blog post and write the very first idea that drifts to their minds. But it is great to find a well written commentary from time to time in contrast to the exact same, traditional blog crap which I oftentimes notice on the net. Regards

  7. Sergio disse:

    Onde posso conseguir a biblioteca rs232.h

    Abraço!

  8. carlos disse:

    Cara estou fazendo uma cadeira de programação em C, e tambem preciso fazer um projeto utilizando ou a porta paralela ou a porta serial… Porem estou com dificuldades de fazer a comunicação do programa com as mesmas! Eu estou usando o Borland C… Meu projeto eh simples: Envia um sinal-aciona um led,recebe 2 sinais desliga o led e aciona outro; 5s depois desliga o segundo led e liga o primeiro novamente…
    Tem como vc me dar umas dicas de como fazer essa troca de informação???
    Aguardo retorno.
    Grato

    Carlos

  9. Olá Carlos, o mais simples pra essa situação seria utilizar a porta paralela, mas digo para não fazer isso, não sei por que ainda ensinam a utilizar a porta paralela e ainda usam o Borland C, a Serial ainda é bastante utilizada então sugiro que aprenda a utilizar ela, mas tudo são opçoes.
    Opção PARALELA: É Bem mais facil trabalhar com a porta paralela, ela possui mais pinos e é só verificar e setar os valores dos pinos (existe um monte de tutoriais na internet) A vantagem disto é que pode ligar os leds com resistores direto no cabo que vai para a paralela, não precisa nada mais. É simples de fazer mas ja não é mais utilizado, pois para transferir outros tipos de dados é mais complexo.
    Opção Serial: Tem menos pinos e precisa de mais componentes, mas para trabalhar com dados mais complexos é bem mais facil. Vais precisar de um MAX232 para fazer a conversão de tensão, e de um PIC para interpretar o que vem da serial, ja foi explicado no blog como fazer isso, tem o circuito que vai precisar, como se le da serial, e como se liga e desliga um led pelo pic. Da uma lida ai e la no site de teuniz (de onde eu tirei a biblioteca RS232) e coloca as tuas duvidas ai que te ajudo no que puder.
    Ou se tu tiver bastante tempo livre tenta aprender a usar o FTDI no modo bitbang (isso sim é util, mas complicado)

  10. roberto disse:

    Amigo, copiei esse codigo fonte da parte do pc, tentei compilar mas esta dando erro, ja peguei as bibliotecas da rsr232, estou utilizando o codeblocks, tem alguma dica?
    o erro eh este:
    (.text+0x1e): undefined reference to `OpenComport’
    (.text+0x4d): undefined reference to `PollComport’
    (.text+0xac): undefined reference to `cprintf’
    collect2: ld returned 1 exit status

  11. Roberto, só com isso não tenho como te dizer o que pode estar acontecendo, pode ser algo na configuração (por só faltar as funçoes da biblioteca rs232), verifique no codeblocks se esta para pegar os arquivos da pasta onde esta a biblioteca rs232, e o o include deve ter aspas para pegar os arquivos da mesma pasta.

  12. roberto disse:

    Cara, tentei configurar de tudo quanto foi jeito, as bibliotecas estao nos seus devidos lugares, teria como me mandar por email esse projeto salvo? somente a parte da serial o resto ta ok, ate to usando pra outra coisa.

    grato.

  13. wAGNER disse:

    Cara, parabens pelo post,
    tá muito bem esplicado, ainda tenho algumas duvidas de como utlizar a rs232 no w7, mas esse post ja me ajudou muito.
    se puder me ajudar no w7 fico muito grato.
    abraço

  14. Olá Wagner, assim fica meio complicado de te ajudar, o que não esta conseguindo fazer no w7 ? ( simular no proteus, utilizar uma porta virtual, utilizar a porta fisica do computador, compilar o programa ….) precisa passar mais detalhes do que tu precisa de ajuda, ai posso ver se consigo te ajudar.

  15. Olá roberto, não possuo mais os arquivos do projeto (troca de computador, limpeza no hd…..) os arquivos que ainda tenho estão disponiveis nos posts (tem os links ai)

  16. wAGNER disse:

    Desculpe a falta de informação, o que pretendo fazer é enviar informação para o pic, atravéz de um programa que estou desenvolvendo no visual studio. Porem não faço idéia de como enviar essa informação. O que preciso é a linha de comando que eu uso para enviar a string.
    Ja consegui fazer um parecido com o que eu quero, so que fiz no xp, e utilizei a porta paralela.
    Como sabe a paralela já esta em desuso, não se usa mais, entao estou tentando reescrever o programa utilizando a serial.
    andei pesquisando e vi algumas pessoas falando que
    O .NET Framework não da suporte para o controle direto sobre a porta COM, por isto uma classe a parte é usada para fornecer chamadas via API .
    A programação no microcontrolador fica a mesma…
    Não sei mais o que fazer, não acho nada…

  17. wAGNER disse:

    aqui estou tendo o mesmo problema do roberto,
    undefined reference to `OpenComport’
    undefined reference to `PollComport’
    undefined reference to `cprintf’
    e mais uma
    warning: ‘_sleep’ is deprecated (declared at c:\program files (x86)\codeblocks\mingw\bin\../lib/gcc/mingw32/4.4.1/../../../../include/stdlib.h:408)|

  18. ahh ta usanso .NET é cheio dessas coisas chatas, só procurando la no site da microsoft alguma coisa sobre a serial normalmente tem as coisas meio prontas, não consigo gostar de .NET prefiro o ANSI C quando eu fiz o projeto pela primeira vez no windows 7, tive problemas com uma DLL mas não consigo me lembrar qual era, coloquei ela e funcionou tudo perfeito.

  19. Continuo achando que é alguma coisa com a configuração do projeto ou ordem dos imports, se puder me mandar o projeto zipado para dar uma olhada fica mais facil de te dizer o que pode estar acontecendo, sendo o erro relacionado somente as funçoes da biblioteca RS232 significa que o problema esta em encontrar e importar ela.

  20. wAGNER disse:

    tbm acho, até adicionei a biblioteca na pasta include do code blocks, mas não ta funcionando, ja coloquei entre e entre “”, não funciona mesmo.
    abri a biblioteca aqui e parece que ta tudo normal…
    que mistério.. rs

  21. Testei aqui trocando os includes e funcionou tranquilamente, no arquivo principal do projeto troca aquele monte de includes por isso:
    #include
    #include
    #include “rs232.h”

    Abrindo o rs232.h pode ver que ele ja coloca os outros includes que estavam ali, repetir includes da problema, e assim ele ja inclui de acordo com o sistema operacional que tu estiver usando.
    Tenta ai e diz se funcionou.

  22. wAGNER disse:

    não funcionou, não entendi quando vc disse que era para trocar por isso
    #include
    #include
    #include “rs232.h”
    quais são os 2 primeiros include?
    eu tentei assim
    #include “stdlib.h”
    #include “conio.h”
    #include “rs232.h”
    o mesmo erro acontece… pqp

  23. wAGNER disse:

    Sabe de alguma outra biblioteca 232?, eu to tentando aqui com o w7, não conhecia esse codeblock, sera que é alguma configuração do programa? sei la..
    to criando um arquivo em C, e copiando e colando seu codigo…

  24. wAGNER disse:

    dae gente, eu estava procurando como fazer essa comunicação serial com o VB, achei, e foi muito facil.
    para quem quiser aprender em VB, ta ae:

    para enviar vc faz SerialPort1.Write(“a string que vc quer”)
    para receber SerialPort1.ReadExisting()
    vou dar um exemplo:
    SerialPort1.Write(TextBox1.Text) // ou seja tudo o que eu escrever na minha box1 será enviado via serial.

    RichTextBox1.Text = SerialPort1.ReadExisting() // tudo o que eu receber vai aparecer no richtextbox1..
    é isso ae, testado e aprovado.
    so um detalhe, vc deve abrir a porta, mas antes verifique se ela ja esta aberta.
    ex:

    If SerialPort1.IsOpen Then
    SerialPort1.Write(TextBox1.Text)

    Else
    SerialPort1.Open()
    SerialPort1.Write(TextBox1.Text)

    End If
    moleza nao é?
    flw galera, espero que isso possa ajudar alguem :)
    qualquer coisa
    email… wagnerufpr@hotmail.com

  25. I found this article helpful in a paper I am writing at university. Hopefully, I get an A now!

Leave a Reply