4 – se comunicar com o mundo exterior (ler e escrever na porta serial)

A idéia dessa parte é aprender a fazer com que o Arduino responda a comandos externos, além das portas digitais. Na parte 3, vimos como ler o interruptor atraves do estado da porta digital, ou seja, lemos 1 bit (0 ou 1, 0v ou 5v, LOW ou HIGH). Contudo, atrevés da comunicação serial, podemos ler strings, ou seja, cadeias de caracters ou bytes.

Resumindo, a comunicação serial facilita a passagem de dados entre o arduino e qualquer outro microcontrolador habilitado a conversar nos parametros da comunicação serial.

Podia aqui passar toda a teoria de como se tranfere bytes utilizando somente duas portas digitais a taxas de até 115200 bits por segundo (quem é velho vai lembrar das taxas famosas dos modens, 9600, 14400, 57600bps) Mas não vou primeiro pq não sei completamente a teoria por trás da comunicação (qual o padrão de 0s e 1s para enviar e receber bytes) e pq não é necessário saber essa teoria para sair usando a porta serial. Se quiser ler a teoria, http://pt.wikipedia.org/wiki/Comunica%C3%A7%C3%A3o_serial

Até a parte 3, o arduino praticamente não se comunicava. Ele lia sensores e decidia o que fazer usando a logica interna. O que vamos fazer é passar comandos, como “ligar”e “desligar” e também receber mensagens de feedback do arduino, como por exemplo “liguei o LED”, “desliguei o LED”. Logo, nosso exemplo dessa vez terá essa configuração:
pwm, interrupções) mas não vamos tratar desses recursos nessa serie de tutoriais.
4-1
Figura 4.1 configuração do exemplo.

O arduino tem 2 portas separadas para comunicação serial, a porta 0 e 1, (rx e tx respectivamente, ou seja, rx de receive e tx de transfer). Caso quiséssemos fazer com que o Arduino conversasse com outro arduino via porta serial, por exemplo, era só ligar a porta 0 de um na 1 do outro e a mesma coisa na outra porta, como na figura abaixo:
4-2_bb
Figura 4.2 – Exemplo de comunicação serial entre 2 arduinos. A porta TX de um é ligada na RX do outro e vice-versa

Mas nesse exemplo, vamos fazer com que o computador se comunique com o Arduino via porta serial. Antigamente, os computadores tinham portas seriais, que se municavam com voltagem -11v – 11v e, para ligar com um microcontrolador, era preciso traduzir isso para 0v e 5v através de um chip max232. Enfim, hoje os computadores nao tem mais porta serial e o pessoal que criou o arduino facilitou nossa vida, eles fizeram com que a comunicação serial com o arduino se desse via porta USB. \o/ Não sei se você já percebeu, mas quando você espeta um arduino a porta serial do windows, ele designa uma porta COMx para o arduino. É através dessa porta que a comunicação serial acontece.
Bom, dito isso, que da parte fisica só precisamos por enquanto ligar o arduino na porta serial, vamos ver o que é necessario fazer para configurar e usar a comunicação serial no código (software). A primeira coisa a se fazer é, na função setup, configurar a taxa de transmissão de dados. Não precisa se preocupar se é rapido ou lento, o importante é os 2 lados estarem conversando na mesma taxa/velocidade, ou seja, o arduino e o pc. (note que estou complementando os programas criados nas etapas anteriores. O que for especificio dessa etapa eu destaco com negrito).

void setup() {                

  pinMode(4, OUTPUT); // inicializa a porta 4 como porta de saída / escrita.
  digitalWrite(4, LOW); // escreve o estado da porta 4 como LOW / desligado
  pinMode(7, INPUT); // inicializa a porta 4 como porta de entrada / leitura.
    Serial.begin(9600); //inicializa a comunicação serial em uma vel. de 9600bps
}

Quadro 4.3 – Iniciando a porta serial com o comando Serial.begin. Detalhes em http://arduino.cc/en/Serial/begin

No nosso loop, vamos codificar duas funcionalidades. A primeira é, a cada loop, informar se o LED está aceso ou apagado. Ou seja, iremos utilizar a escrita da porta serial, através da função Serial.println. Para isso, vamos usar uma variavel global que indica se o estado do LED, chamada “isOn”. Como o LED inicia desligado, o valor dessa variável booleana será false.

boolean isOn = false; //variavel global com o estado do led

void loop(){
  if (isOn)
    Serial.println ("LIGADO"); //envia a string via porta serial
  else
    Serial.println ("DESLIGADO"); //envia a string via porta serial
  delay (500); //pause de meio segundo 
}

Quadro 4.4 – Testando o estado do LED e imprimindo-o via porta serial, usando o comando println (http://arduino.cc/en/Serial/println). Vamos ver o que o programa está escrevendo em um terminal, por isso a pausa de meio segundo, caso contrario não conseguiremos ler direito.

Se executarmos o código do jeito que está, nosso programa só imprimirá “DESLIGADO”. Isso porque falta alguma lógica que altere o estado do LED. Vamos alterar o estado do LED lendo da porta serial, ou seja, o computador irá enviar um comando, vamos interpreta-lo e agir de acordo. Nossos comandos serão letras, “L”, “D” e “I”, L para ligar o LED, D para desligar e I para funcionar como um interruptor, ou seja, se estiver ligado, desliga e vice versa. Para ser da porta serial, iremos usar duas funções: Serial.available (informa se tem bytes disponíveis para serem lidos) e Serial.read (lê um byte / char). Logo, nosso loop ficaria assim:

boolean isOn = false; //variavel global com o estado do led

void loop(){
   if (Serial.available() > 0) { //informa se tem bytes para serem lidos da porta serial
      char comando = 0;
      comando = (char) Serial.read(); //le um byte da porta serial
      if (comando == 'L')
        isOn = true; //liga o led
      if (comando == 'D')
        isOn = false; //desliga o led
      if (comando == 'I')
        isOn = !isOn; //inverte o valor do estado
  }

  if (isOn)
    Serial.println ("LIGADO"); //envia a string via porta serial
  else
    Serial.println ("DESLIGADO"); //envia a string via porta serial
  delay (500); //pause de meio segundo 
}

Quadro 4.5 – exemplo da leitura da porta serial e execução de lógica dependendo dos valores lidos. Foram utilizadas as funçoes Serial.avaliable (http://arduino.cc/en/Serial/available) e Serial.read (http://arduino.cc/en/Serial/read)

Bom, já escrevemos e lemos da porta serial e alteramos o valor da variável que indica o estado do LED. Porem, ainda não usamos essa variavel para fisicamente ligar ou desligar o led, através das portas digitais, como fizemos na etapa 2. É só ajustar o código.

boolean isOn = false; //variavel global com o estado do led

void loop(){
   if (Serial.available() > 0) { //informa se tem bytes para serem lidos da porta serial
      char comando = 0;
      comando = (char) Serial.read(); //le um byte da porta serial
      if (comando == 'L')
        isOn = true; //liga o led
      if (comando == 'D')
        isOn = false; //desliga o led
      if (comando == 'I')
        isOn = !isOn; //inverte o valor do estado
  }

  if (isOn)
    Serial.println ("LIGADO"); //envia a string via porta serial
  else
    Serial.println ("DESLIGADO"); //envia a string via porta serial

  //liga o LED de acordo com o valor do seu estado.
  if (isOn) {     
    // liga o LED   
    digitalWrite(4, HIGH);  
  } 
  else {
    // desliga o LED
    digitalWrite(4, LOW); 
  }

  delay (500); //pause de meio segundo 
}

Quadro 4.6 – Ligando e desligando o LED fisicamente, atraves da porta digital.

Veja que também estamos ignorando a entrada do interruptor (leitura da porta digital, vista na etapa 3). Ela deveria funcionar como o comando “I”, que programamos na leitura dos comandos da porta serial. Para isso, vamos utilizar uma outra variavel global, para armazenar o estado da porta digital na qual o interruptor está ligada. Quando detectarmos que essa variável mudou de estado, mudamos também o estado do LED. O código ficaria assim (esse é o código final):

//variaveis globais
boolean isOn = false; //variavel global com o estado do led
int buttonState = 0;// variável para armazenar a leitura da porta digital

void setup() {                

  pinMode(4, OUTPUT); // inicializa a porta 4 como porta de saída / escrita.
  digitalWrite(4, LOW); // escreve o estado da porta 4 como LOW / desligado
  pinMode(7, INPUT); // inicializa a porta 4 como porta de entrada / leitura.
  buttonState = digitalRead(7);   // le o estado da porta digital 7
    Serial.begin(9600); //inicializa a comunicação serial em uma vel. de 9600bps
}

void loop(){
   //lendo comandos da porta serial
   if (Serial.available() > 0) { //informa se tem bytes para serem lidos da porta serial
      char comando = 0;
      comando = (char) Serial.read(); //le um byte da porta serial
      if (comando == 'L')
        isOn = true; //liga o led
      if (comando == 'D')
        isOn = false; //desliga o led
      if (comando == 'I')
        isOn = !isOn; //inverte o valor do estado do LED
  }

  //lendo comando da porta digital
  int newButtonState = 0; // variável para armazenar a leitura da porta
  newButtonState = digitalRead(7); // le o estado da porta digital 7

  //checa se o estado do interruptor mudou
  if (newButtonState != buttonState) {
     buttonState = newButtonState; //atualiza o valor do estado do botao
     isOn = !isOn; //inverte o valor do estado do LED
  }

  if (isOn)
    Serial.println ("LIGADO"); //envia a string via porta serial
  else
    Serial.println ("DESLIGADO"); //envia a string via porta serial

  //liga o LED de acordo com o valor do seu estado.
  if (isOn) {     
    // liga o LED   
    digitalWrite(4, HIGH);  
  } 
  else {
    // desliga o LED
    digitalWrite(4, LOW); 
  }

  delay (500); //pause de meio segundo 
}

Quadro 4.7 – Código completo. Lendo da porta digital e da porta serial.

Por ultimo, precisamos ver o retorno da porta serial e se comunicar com o arduino, enviando os comandos através do PC. Existem varias formas de se comunicar, através do PC, pela porta serial (simulada via USB no arduino). Mas vamos utilizar a propria IDE do arduino. Clique no “Serial Monitor” no canto superior direito da IDE. Abrirá uma janela, escolha a velocidade da comunicação (usamos 9600 no exemplo) e você verá as mensagens que o arduino está mandando, ou seja, o estado do LED. Na parte superior, você pode enviar comandos para o arduino, no nosso exemplo L, D ou I. Note também que se você apertar o interruptor que montamos na etapa 3, o estado vai mudar.

4.8
Imagem 4.8 – Serial Monitor da IDE do Arduino, se comunicando de forma serial.

Veja o vídeo de tudo funcionando:

Anúncios

Deixe um comentário

Arquivado em Arduino, Automação Doméstica, Desenvolvimento, Eletrônica, Geek, Tutorial

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s