Introdução ao Arduino Bruno Silvério Costa Arduino O que é? (1) É um sistema embarcada de placa única que, juntamente com um conjunto de softwares e frameworks, tornam fácil o desenvolvimento de hardware; Definido pelos criadores como Open Source Electronics Prototyping Plataform, em português Plataforma Open Source de Prototipagem Eletrônica. 1
Arduino O que é? (2) Plataforma possui os seguintes componentes principais: Placa base (microcontrolada); IDE de desenvolvimento (juntamente com mecanismos para upload de código); Framework Arduino; Shields de expansão (que implementam funções diversas controladas pela placa) Preparando o computador Primeiramente, é necessário obter a versão mais recente do software, disponível em www.arduino.cc; Instalar o software, seguindo as instruções apresentadas em tela; Plugar a placa Arduino no computador; Caso o driver da placa não seja localizado automaticamente pelo sistema, indicar ao plug and play o caminho C:\Program Files (x86)\arduino\drivers (Para windows); 2
Testando a comunicação Abra o software Arduino (atalho disponível no desktop); Vá ao Menu File->Examples->1.Basics e escolha o projeto Blink; Vá até o menu File->Upload para iniciar o processo de compilação e transferência para a placa; Obs.: Pode ocorrer um erro caso a placa não esteja instalada corretamente ou a porta serial virtual escolhida seja inválida. Placa UNO rev 3 uc megau2 Comunicação USB com o Computador Pinos de I/O 8-13: Digital 13: Led Pinos de I/O 0-1: Porta Serial 2-7: Digital/PWM Conector USB Botão RESET Programação ICP (Chips externos em circuito) Conector de alimentação externa (0-30V) uc atmega328p Pinos de Alimentação Reset / IOREF Pinos de I/O 10-15: Digital/Analógico 3
Microcontroladores AVR (1) Chamados de Computadores de Único Chip, os microcontroladores ( C) são pequenos computadores com seus respectivos componentes necessários embutidos no mesmo chip; Por exemplo, estão incluídos no chip microcontrolador: Memória RAM (volátil); Memória EEPROM (persistente); Unidades de I/O; Controladores de Barramento; Microcontroladores AVR (2) Os C AVR seguem a arquitetura de Harvard de processadores, ou seja, possuem memória de dados distinta da memória de programa; Suas portas de I/O podem ser programadas como entrada ou saída indistintamente; 4
Microcontroladores AVR (3) Para utilização de uma porta qualquer, é necessário indicar qual a porta será trabalhada, qual a direção dos dados (entrada ou saída), realizar um input ou output; Exemplo: Porta utilizada: Port B Direção dos dados: DDRB = saída Output: output(portb, valor) Conhecendo o Framework (1) A programação do Arduino é realizada em linguagem C; Existem três sessões básicas disponibilizadas pelo framework no código para a programação: Área de inclusões / declarações: espaço no código destinado a declarações de variáveis e include de bibliotecas; Função de setup: ajuste das configurações básicas antes da execução propriamente dita: Função de loop: conjunto de códigos que são executados ininterruptamente. 5
Conhecendo o Framework (2) int led = 13; void setup() { pinmode(led, OUTPUT); void loop() { digitalwrite(led, HIGH); delay(1000); digitalwrite(led, LOW); delay(1000); Área de inclusão/declaração Função de Setup Função de Loop Compreendendo o código Conhecendo o Framework (3) int led = 13;//det. qual pino será usado void setup() { //Função de Setup pinmode(led, OUTPUT);//Determiando que o pino 13 será de saída (OUTPUT) void loop() {//Função de loop digitalwrite(led, HIGH);//Escrevendo o valor digital HIGH (1) no pino 13 delay(1000);//aguardando 1000 ms digitalwrite(led, LOW); //Escrevendo o valor digital LOW (0) no pino 13 delay(1000); //Aguardando 1000 ms //retorna para loop 6
Comandos Arduino (1) O código feito em Arduino segue as diretrizes do Framework, mas é desenvolvido em linguagem C; Dessa forma, muitos dos comandos C são válidos para o desenvolvimento em Arduino; A seguir serão apresentados os comandos iniciais válidos para o desenvolvimento; Comandos Arduino (2) Não se utiliza a estrutura de programa principal do C. O próprio framework faz o preenchimento. Comandos de seleção If Switch-case Comandos de repetição For While Do while 7
Comandos Arduino (3) Os pinos podem ser: de 1 a 13 e de A0 a A5, conforme apresenta a placa Arduino UNO; Comandos de entrada de dados pinmode(pino, INPUT); variavel=digitalread(pino); variavel=analogread(pino); Comandos de saída de dados pinmode(pino, OUTPUT); digitalwrite(pino, HIGH/LOW); analogwrite(pino, VALOR[0-255]); Comandos Arduino (4) Em alguns momentos, para viabilização da entrada de dados, é necessário configurar resistores de pull-up ou pull-down ligados aos pinos do microcontrolador; 8
Comandos Arduino (5) Para os microcontroladores AVR, isso pode ser feito diretamente em software; O pull-up pode ser feito com o comando: digitalwrite(pino, HIGH); O pull-down pode ser feito com o comando: digitalwrite(pino, LOW); Comandos Arduino (6) Comando de temporização delay(tempo_ms);//aguarda um determinado tempo em ms millis();// retorna o tempo em ms desde o inicio do sistema 9
Comandos Arduino (7) Comando de temporização delay(tempo_ms);//aguarda um determinado tempo em ms millis();// retorna o tempo em ms desde o inicio do sistema Comandos Arduino (8) Operações aritméticas Funcionam de forma análoga ao C A = B + C; A = B C; A = B * C; A = B / C; A = B % C; As precedências inerentes às operações funcionam normalmente. É possível a determinação externa através de parentização; 10
Comandos Arduino (9) Operações aritméticas Funcionam de forma análoga ao C A = B + C; A = B C; A = B * C; A = B / C; A = B % C; As precedências inerentes às operações funcionam normalmente. É possível a determinação externa através de parentização; Exercício 1 Modifique o código do Projeto Blink para que o led pisque de rápido a lento continuamente; Obs.: adote o delay inicial de 10 ms; 11
Resposta Exercício 1 int led = 13; int count =0; int delay2 = 10; void setup() { pinmode(led, OUTPUT); void loop() { for(int j=1;j<=15;j++) for(int i=0;i<5;i++) { digitalwrite(led, HIGH); delay(delay2*j); digitalwrite(led, LOW); delay(delay2*j); PWM (1) PWM (Pulse With Modulation) é uma técnica que permite a geração de resultados analógicos partindo de sinais digitais. A média da potência do sinal digital determina o sinal analógico médio; Muito utilizado na alteração de brilho de lâmpadas e leds, bem como no controle de motores CC; 12
PWM (2) Utilizar uma saída digital para valores analógicos, possibilita a conversão do sinal analógico em PWM; Por exemplo, pode-se construir um código para o led L de maneira que ele fique com um brilho pulsante. Para isso, basta gerar uma onda senoidal lenta; Esse código é visto a seguir: PWM (3) int ledpin = 11;//led a pulsar float sinval;//valor do seno int ledval;//valor a ser escrito no pino 11 void setup(){ pinmode(ledpin, OUTPUT);///pino 11 como saida void loop(){ for(int x=0; x<180; x++){//varia de 0º a 180º sinval=(sin(x*(3.14159/180)));//calcula valor do seno ledval=int(sinval*255);//valor entre 0 e 255 analogwrite(ledpin, ledval);//escreve na porta pwm delay(20);//aguarda 20 ms 13
Display LCD (1) Existem diversos displays LCDs comercializados. Dentre eles o mais comum é o 1602 (16 colunas x 2 linhas); O Arduino possui um driver apropriado para tramalhar com uma grande quantidade de displays, bastando configurar a instância do mesmo para o tipo correto a ser trabalhado; Utilizaremos o display MGD1602B; Display LCD (2) 14
Display LCD (3) É necessário definir inicialmente quais serão os pinos utilizados no Arduino como interface para o display; Display LCD (4) #include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 2);//pinos a serem usados pelo display no Arduino int posicao=15; void setup() { lcd.begin(16, 2);//Número de colunas x linhas do display void loop() { lcd.setcursor(0, 0);//Aponta cursor para coluna 0 x linha 0 lcd.print(" ");//Apaga linha lcd.setcursor(0, 1);//Aponta cursor para coluna 0 x linha 1 lcd.print(" ");//Apaga linha 15
Display LCD (5) for(int i=15;i>=0;i--)//desliza a string "Display LCD" da direita para a esquerda no display { lcd.setcursor(i, 0);//Aponta cursor para coluna 0 x linha 1 delay(300);//aguarda 300 ms lcd.print("display LCD ");//escreve no display for(int i=0;i<=15;i++)//preenche progressivamente a linha inferior com "+" { lcd.setcursor(i, 1);//Aponta cursor para coluna 0 x linha 1 delay(100);//aguarda 100 ms lcd.print("*");//escreve no display delay(1000);//aguarda 1000 ms para recomeçar Comunicação Serial Determinação da taxa de transmissão/recepção Serial.begin(9600);//valor em bps Envio de dados Seria.print( String );//envia uma string sem o caracter de return Serial.println( String ); //envia uma string com o caracter de return 16
Teclado Matricial(1) Todo teclado funciona como uma grande matriz, onde as teclas correspondem a intersecções entre linhas e colunas; Teclado Matricial(2) De forma análoga ao display, também existe um driver a ser utilizado com o teclado disponível no Arduino; Como o driver é genérico, também precisa ser configurado para trabalhar corretamente; São utilizados 7 pinos, dos quais, três correspondem às colunas e 4 às linhas; 17
Teclado Matricial(3) #include <Keypad.h> const byte ROWS = 4; //quatro linhas const byte COLS = 3; //três colunas char keys[rows][cols] = { //Define a aparência do teclado {'1','2','3', {'4','5','6', {'7','8','9', {'#','0','*' ; byte rowpins[rows] = {A0, A1, A2, A3; //conectar aos pinos das linhas do teclado byte colpins[cols] = {8, 7, 6; //conectar aos pinos das colunas do teclado Teclado Matricial(4) Keypad keypad = Keypad( makekeymap(keys), rowpins, colpins, ROWS, COLS );//criando instância do teclado void setup(){ Serial.begin(9600);//Ajustando taxa de comunicação serial void loop(){ char key = keypad.getkey();//lendo uma tecla if (key!= NO_KEY){//caso alguma tecla tenha sido apertada Serial.println(key);//envie qual foi a tecla para o computador 18
SHIELDs Placas de expansão/interface disponibilizadas para Arduino; Sensores (1) Os sensores, de maneira geral, são componentes eletrônicos sensíveis a eventos da natureza; Existem sensores para uma grande gama de aplicações. Destacam-se: Sensores de luminosidade (LDRs, Fototransistores); Sensores de som (capsulas de eletreto); Sensores de obstáculos e presença (IR, reflexivos, ultrasônicos, reed NA); Sensores de temperatura (RDT); Sensores de umidade; Sensores de posição (bússola eletrônica, GPS); Sensores de movimento (IR, acelerômetro, relè de mercúrio); 19
Sensores (2) Todos os sensores apontados podem ser utilizados com o Arduino; Alguns depende de um conhecimento mais aprofundado de eletrônica; Existe uma grande quantidade de sensores disponível em SHIELDs Arduino; Sensores (3) Sensor IR reflexivo Identifica obstáculos que reflitam a radiação IR; Muito utilizado para dar ao Arduino uma capacidade limitada de visão, já que é possível perceber o objeto, sem tocá-lo (pode-se utilizar ultrasom também); 20
Sensores (4) O sensor oferece uma saída digital, possibilitando seu tratamento facilitado no Arduino, conforme código a seguir: int sensor=2; digitalwrite(sensor, HIGH); //pull-up para sensor pinmode(sensor, INPUT);//pino 2 como entrada valor_sensor = digitalread(sensor);//leitura do valor do pino Servo motores (1) Motores CC com circuitos associados, permitindo o controle da movimentação angular do mesmo, além do ganho em torque; Servo motores podem ser adaptados para permitir apenas a indicação de sentido (horário, anti-horário) e o estado parado; 21
Servo motores (2) Para manipulação de servo motores no Arduino, é preciso apenas de um código bastante simples, além da utilização da biblioteca apropriada; #include <Servo.h> const int parado=90; const int horario=0; const int antihorario=180; const int pino=2; Servo motor; motor.attach(pino); motor.write(horario); delay(5000); motor.write(horario); delay(5000); motor.write(parado); delay(5000); Robô seguidor de linha (1) Desloca-se sobre uma linha preta no solo, convergindo o centro do robô para cima da linha. Muito utilizado na indústria; 22
Robô seguidor de linha (2) Interligações: Robô seguidor de linha (3) Sensor IR reflexivo Alimentação (+) Led IR Comum (-) Saída FT 23
Robô seguidor de linha (4) #include <Servo.h> const int sensor_dir = 7; // sensor esquerdo const int sensor_esq = 8; // sensor esquerdo const int mdir=6; const int mesq=5; const int buzzer=3; int status_sensor_esq=0;//monitor de mudança de status int status_sensor_dir=0;//monitor de mudança de status //Variáveis para acumulação dos valores dos sensores int s_esq=1, s_dir=1; //Servo-motores Servo motordir; Servo motoresq; Robô seguidor de linha (5) int posdir=0; int posesq=0; const int paradoe=86; const int paradod=89; const int frentee=0; const int frented=179; const int atrase=180; const int atrasd=0; void aviso_som(){ for (int i=0;i<1;i++){ digitalwrite(buzzer, HIGH); delay(10); digitalwrite(buzzer, LOW); 24
Robô seguidor de linha (6) int status(){ // Verificando resultado pela porta serial s_esq = digitalread(sensor_esq); s_dir = digitalread(sensor_dir); if(status_sensor_esq!=s_esq){ Serial.print("\nSensor Esquerdo=" ); Serial.print(s_esq); status_sensor_esq=s_esq; aviso_som(); return 1; if(status_sensor_dir!=s_dir){ Serial.print("\nSensor Direito=" ); Serial.print(s_dir); status_sensor_dir=s_dir; aviso_som(); return 1; return 0; Robô seguidor de linha (7) void agente_reativo_simples(servo motor_dir, Servo motor_esq, int sesq, int sdir){ int se = digitalread(sesq); int sd = digitalread(sdir); int temp=status(); if ((se==1)&&(sd==1)){ motor_dir.write(paradod); motor_esq.write(paradoe); else if ((se==0)&&(sd==0)){ motor_dir.write(frented); motor_esq.write(frentee); else if((se==0)&&(sd==1)){ motor_dir.write(frented); motor_esq.write(paradoe); else if((se==1)&&(sd==0)){ motor_dir.write(paradod); motor_esq.write(frentee); 25
Robô seguidor de linha (7) void setup() { // Inicializando a comunicação serial em 9600 bps: Serial.begin(9600); digitalwrite(sensor_dir, HIGH); //pull-up para sensor direito digitalwrite(sensor_esq, HIGH); //pull-up para sensor esquerdo motordir.attach(mdir); motoresq.attach(mesq); void loop() { agente_reativo_simples(motordir, motoresq, sensor_esq, sensor_dir); status(); Shield de rede (1) Permite a comunicação entre o Arduino e um computador, utilizando para isso o protocolo Ethernet. O Arduino implementa a pilha TCP/IP; 26
Shield de rede (2) #include <SPI.h> #include <Ethernet.h> // Enter a MAC address and IP address for your controller below. // The IP address will be dependent on your local network: byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED ; IPAddress ip(192,168,1,177); EthernetServer server(80); void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only // start the Ethernet connection and the server: Ethernet.begin(mac, ip); server.begin(); Serial.print("server is at "); Serial.println(Ethernet.localIP()); Shield de rede (3) void loop() { // listen for incoming clients EthernetClient client = server.available(); if (client) { Serial.println("new client"); // an http request ends with a blank line boolean currentlineisblank = true; while (client.connected()) { if (client.available()) { char c = client.read(); Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply if (c == '\n' && currentlineisblank) { // send a standard http response header client.println("http/1.1 200 OK"); client.println("content-type: text/html"); client.println("connection: close"); // the connection will be closed after completion of the response 27
Shield de rede (4) client.println("refresh: 5"); // refresh the page automatically every 5 sec client.println(); client.println("<!doctype HTML>"); client.println("<html>"); // output the value of each analog input pin for (int analogchannel = 0; analogchannel < 6; analogchannel++) { int sensorreading = analogread(analogchannel); client.print("analog input "); client.print(analogchannel); client.print(" is "); client.print(sensorreading); client.println("<br />"); client.println("</html>"); break; Shield de rede (5) if (c == '\n') { currentlineisblank = true; // you're starting a new line else if (c!= '\r') { // you've gotten a character on the current line currentlineisblank = false; delay(1); // give the web browser time to receive the data client.stop(); // close the connection: Serial.println("client disonnected"); 28
29