Nesta seção estão os projetos considerados para intermediários. Utilizamos como critério tempo gasto para montar (mais de 1 hora), programação (números de caracteres), eletrônica utilizada e a utiliza
Nesta seção estão todos os tutoriais sobre motores, servomotores e etc.
Arduino
Tutorial Arduino - Motor de passo NEMA 17 + driver A4988 por José Gustavo Abreu Murta
Tutorial Arduino
(0); e direita(160); (Do servomotor) e caso ele ache uma distância a menos de 10 cm seja ele para a direita ou esquerda do sentido que o servomotor girou ele faça uma novabusca até que a condição (novabusca > 10) para ele seguir em frente (Chama a função "frente();")
OBS : O servomotor quando acha um obstaculo ele vira pro sentido que achou o obstaculo mas fica "voltando" pra posição inicial ( 90º) gostaria de saber o porque dele ficar assim,sendo que não estou usando DELAY;
CODE :
// FUNCAO SERVOMOTOR//Inicializa a posiçao do servomotor int distancia;int distanciae;int distanciad;int novabusca;#include <Servo.h>Servo meuservo;#define motor1A 4#define motor2A 5#define motor1B 6#define motor2B 7int pwma = 3;int pwmb = 9;#include "Ultrasonic.h"// Portas do Arduino que vou utilizar para programar o sensorUltrasonic ultrasonic(12,13);void setup (){ Serial.print("Lendo dados dos sensores:"); Serial.begin(9600); pinMode(motor1A,OUTPUT); pinMode(motor2A,OUTPUT); pinMode(motor1B,OUTPUT); pinMode(motor2B,OUTPUT); pinMode(pwma,OUTPUT); pinMode(pwmb,OUTPUT); meuservo.attach(8); //Centraliza Servomotor :) meuservo.write(90); }void loop () {busca();if (distancia < 10) { parado(); // Vira o servo para a direita (busca) meuservo.write(160); nbusca(); } if ( novabusca < 10) { // Vira para a esquerda meuservo.write(0); parado(); nbusca(); // Faz uma nova busca para ver se o sensor eh menor que 10 cm // Condicao para verificar se o sensor da esquerda eh menor que 10 if ( novabusca < 10) { parado(); nbusca(); } else { parado(); nbusca(); esquerda(); //Centralizar o motor } } if ( novabusca < 10) { parado(); nbusca(); meuservo.write(145); }else{ parado(); nbusca(); direita(); } if (novabusca > 10) { parado(); esquerda(); nbusca(); } else{ parado(); direita(); nbusca(); } if (novabusca > 10) { frente(); }}void frente () { digitalWrite(motor1A,LOW); digitalWrite(motor2A,HIGH); analogWrite(pwma,130); digitalWrite(motor1B,LOW); digitalWrite(motor2B,HIGH); analogWrite(pwmb,130);}void tras(){ digitalWrite(motor1A,HIGH); digitalWrite(motor2A,LOW); analogWrite(pwma,100); digitalWrite(motor1B,LOW); digitalWrite(motor2B,HIGH); analogWrite(pwmb,100);}void direita(){ digitalWrite(motor1A,HIGH); digitalWrite(motor2A,LOW); analogWrite(pwma,100); digitalWrite(motor1B,HIGH); digitalWrite(motor2B,LOW); analogWrite(pwmb,100);}void esquerda () { digitalWrite(motor1A,LOW); digitalWrite(motor2A,LOW); analogWrite(pwma,100); digitalWrite(motor1B,HIGH); digitalWrite(motor2B,HIGH); analogWrite(pwmb,100);}void parado () { digitalWrite(motor1A,LOW); digitalWrite(motor2A,LOW); analogWrite(pwma,0); digitalWrite(motor1B,LOW); digitalWrite(motor2B,LOW); analogWrite(pwmb,0);}/*void desvio_direita(){ parado(); delay(1000); direita(); delay(1000); frente();}*/void busca(){ // Funçao para Fazer leituras de Sensor Ultrasonico t distancia = (ultrasonic.Ranging(CM)); Serial.print(distancia); Serial.println("cm de distancia"); }void nbusca(){ // Funçao para Fazer leituras de Sensor Ultrasonico t novabusca = (ultrasonic.Ranging(CM)); Serial.print(distancia); Serial.println("cm de distancia"); }…
sou. Mas antes de falar sobre esta implementação, seguem algumas considerações:
a) vc não informou qual placa Arduino está usando. Baseado nos seus tópicos anteriores, eu acredito que seja um ESP8266 ou ESP32. Tranquilo, pois o código que implementei irá funcionar para ambos e também para as demais placas (UNO, Nano, Mega, STM32, etc).
b) embora vc esteja usando LCD 16x2, o código pode ser facilmente usado para LCDs com outras "dimensões" para colunas e linhas (se suportado pela Biblioteca utilizada para o LCD).
c) no seu código original, vc exibiu textos no Display com uma "printagem" de caracter por caracter. Evite isso, porque sempre há como printar estes textos de forma "normal" ou seja, com o texto "completo" na linha de código. Da forma que vc fez, dificulta ver o que está sendo printado, e aumenta o código de uma forma desnecessária, além de ser extremamente mais trabalhoso. Além disso, vc printou os caracteres via código ASCII em decimal, o que não é necessário, pois bastaria usar o "write" com os caracteres entre apóstrofes, como neste exemplo: write('A') ao invés de write( byte(65) ). Ainda sobre isto, parece que vc usou o caracter ASCII de número "128" para printar um espaço em branco, o que está "incorreto". O caracter que vc deveria ter usado é o "32" (ou 0x20, em Hexadecimal), que é o caracter ASCII oficial do "espaço em branco". Ocorre que o "128" poderá ser um caracter diferente do espaço em branco, dependendo do Controlador do Display usado na placa do módulo LCD.
Falando agora sobre as funcionalidades do seu código. Vc implementou três efeitos "animados" na exibição no Display. Vejamos quais são eles:
1) efeito de exibição "gradual" do texto, caracter por caracter, com estes caracteres sendo printados em um intervalo de tempo especificado. E para isso vc printou cada caracter de forma sequencial no código, com uma função delay entre cada print para cadenciar a exibição do texto completo, e claro: isto causa seu código ficar preso nestas operações até que todo o texto seja printado.
2) efeito de exibição "correndo" na linha do Display, da direita para a esquerda, com uma velocidade determinada por um intervalo de tempo entre cada printagem (em coluna anterior à que acabou de ser printada). Da mesma forma que no efeito anterior (o "gradual"), isto também causa seu código ficar preso nestas operações até que o texto seja printado na coluna final, pois vc também usou a função delay para cadenciar a sequência de prints.
3) efeito "pisca/pisca" (ou "Blynk") do Display, com a visualização do mesmo "desligando" e "ligando" por intermédio das funções "lcd.noDisplay()" e "lcd.display()", executadas de forma intercalada em intervalos de tempo que determinam a velocidade do "pisca/pisca". E isto também prende a execução do seu código, até que sejam executados todos os ciclos do "pisca/pisca", entre os quais também estão funções delay.
Então implementei estes três efeitos ("gradual", "correndo", e "Blynk"), porém sem prender o código. Além disso para printar qualquer texto usando os efeitos, vc pode fazer isso especificando o texto completo, como no exemplo mostrado a seguir:
set_MSG_gradual_LINHA_n( linha_0, F("Marcela"), 0.25, 4.6 );
Neste exemplo, é requisitado que seja exibido na linha "0" do Display o texto "Marcela", de forma "gradual", ou seja, caracter por caracter, com intervalo de 0.25 segundos (ou 250 mili-segundos). O tempo de exibição (mínimo) é de 4.6 segundos a contar quando todo o texto está completo na linha. Também, o texto será automaticamente centralizado na linha (ou seja, vc não precisa ficar calculando a coluna inicial de acordo com comprimento do texto).
Outro exemplo, neste caso com efeito "correndo":
set_MSG_running_LINHA_n( linha_1, F("Robotica"), 0.2, 3.5 );
onde o texto "Robotica" começa "correndo" na linha "1" da direita para a esquerda, com velocidade determinada pelo intervalo de 0.2 segundos, até que o texto esteja centralizado na linha. O tempo de exibição (mínimo) é de 3.5 segundos, a contar a partir do término do efeito "correndo".
Exemplo de uso do efeito "Blynk" (ou "pisca/pisca") do Display:
set_Display_Blynk( 0.4, 3 );
Neste caso, o Display "pisca" na velocidade determinada pelo intervalo de tempo de 0.4 segundos, sendo que no total serão 3 piscadas (e ao final das piscadas, o Display fica sempre no "modo visível").
Para cada efeito, foi implementa uma Máquina de Estados para gerenciamento do efeito. Para os efeitos "gradual" e "correndo" as Máquinas tem apenas 4 estados (sendo que um deles é apenas ficar esperando até que uma requisição de printagem seja feita). E a Máquina de Estados que faz o "Blynk" tem apenas 3 estados (onde um deles também é apenas ficar esperando).
Vc poderá implementar outros efeitos facilmente, se entender como estas Máquinas funcionam no código. Todas as três Máquinas implementadas funcionam do mesmo jeito, e qualquer outro efeito implementado também deverá funcionar do mesmo jeito.
Para que as Máquinas gerenciem corretamente os efeitos, vc NÃO deve "travar" o restante do seu código, ou seja, não use delays nem execute loops intermináveis ou de longa duração. Se vier a usar sensor DS18B20, use o modo de leitura "assíncrona" para impedir que o código fique longamente esperando uma resposta do Sensor. Se vc tiver alguma dificuldade com estas coisas, avise aqui para que eu possa te ajudar.
Vamos dar uma olha nas configurações básicas do código implementado, começando pela opção de escolha da Interface de Hardware usada para acesso ao módulo do Display LCD, conforme mostrado na figura a seguir:
(clique na figura para "zoom")
Sim, vc pode escolher o tipo da Interface, entre a tradicional Interface Paralela de 4 bits, e a concisa Interface I2C (que é a que vc está usando no seu código original). Na figura está selecionada a Interface I2C, conforme marcado na cor verde. Mude conforme seu Projeto.
E claro, se vc usar o I2C, deve especificar o endereço do módulo no Barramento I2C, conforme mostrado e marcado na cor laranja na figura a seguir:
(clique na figura para "zoom")
Para estas Interfaces, há outros settings que podem ser facilmente alterados no código (se selecionar a Interface Paralela de 4 bits, certamente isso será necessário, para especificar os pinos do Arduino usados na Interface).
A printagem dos textos, é feita em uma Máquina de Estados "principal", que é praticamente sequencial. Por motivos didáticos, esta Máquina "principal" é implementada dentro da função "loop" do Arduino. Para imprimir um texto, vc deve "requisitar" a operação desejada, pois esta operação será posteriormente executada por uma das Máquinas de Estados que implementam os efeitos no Display. Assim, há uma lógica simples a ser seguida para cada printagem de texto, e que se constitui de duas etapas:
Etapa 1: requisitar a printagem especificando o texto e parâmetros relacionados ao efeito.
Etapa 2: aguardar que a printagem seja concluída, chamando uma função que retorna "true" quando a operação de exibição terminar.
E para cada uma destas etapas, implementa-se um estado na Máquina de Estados "principal". Para o código da Marcela, estes estados podem ser vistos na lista no trecho de código mostrado na figura a seguir:
(clique na figura para "zoom")
Cada cor na figura anterior (exceto as cores amarela e a roxa), corresponde a um processo de exibição no Display, onde nas linhas "0" e "1" do Display são exibidas informações relacionadas entre si. Exemplo: na região laranja é exibida de forma gradual na linha "0", o texto "Marcela", e logo em seguida é exibido "correndo" na linha "1" o texto "Automatização", e em seguida é feito um "pisca/pisca" no Display, e depois o Display é apagado (ou "limpo"). Cada um dos estados é executado, e após cada execução, segue para um dos estados marcados na área em amarelo do código, onde é esperado que seja concluída a exibição que foi requisitada. Ou seja, logo após executar o estado "Exibe_MSG_Marcela", é executado o estado "Aguarda_FIM_MSG_linha_0" (pois a printagem da mensagem foi na linha "0"). E então a execução segue para o estado "Exibe_MSG_Automatizacao" que printa na linha "1" e por isso segue para o estado "Aguarda_FIM_MSG_linha_1", seguindo para o estado "Pisca_MSG_Automatizacao", e assim por diante.
Se em um determinado estado forem exibidas mensagens em ambas as linhas do Display, então o estado seguinte deve ser o "Aguarda_FIM_MSG_Display" que aguarda o fim das exibições em todas as linhas do Display.
Em suma, a sequência de execução dos estados é sempre printando no Display, e então aguardando que a operação de printagem termine (estados na área marcada em amarelo).
O estado marcado na cor roxa, simplesmente aguarda um período de tempo (para isso ele printa uma mensagem "vazia" que demora o tempo desejado), e então reinicia todo o processo a partir do primeiro estado (neste caso o "Exibe_MSG_Bem_vindo", marcado em azul na figura anterior).
Notar que printagens sem efeitos de animação do texto, são feitas especificando-se um intervalo de tempo nulo (igual a zero) na determinação da velocidade da animação do texto. É isso que é feito nos estados "Exibe_MSG_Bem_vindo" e "Exibe_MSG_Casa_Robotica", ambos na área marcada em azul na figura anterior.
A princípio, o processo pode parecer complexo, mas na realidade é simples, como pode ser visto na figura a seguir que mostra toda a Máquina de Estados "principal" sendo executada dentro do "loop" do Arduino:
(clique na figura para "zoom")
Notar que os estados estão marcados individualmente para facilitar a identificação dos mesmos, e que a cor da marcação correspondem às mesmas cores usadas na figura que mostrou a definição destes estados. Observar que nos estados de printagem de mensagens, as operações são simples e seguem sempre o mesmo padrão. Da mesma forma, nas áreas marcadas em amarelo, que são os estados que esperam a conclusão das operações de printagem, também são muito simples e também seguem um padrão.
Importante: se forem acrescentados mais estados de printagem no Display, os estados nas áreas em amarelo permanecem os mesmos, pois já contemplam todas as possibilidades de aguardar a conclusão das operações implementadas neste Sistema (printagem na linha "0", na linha "1", em ambas as linhas, e "pisca/pisca").
Então como criar um estado de printagem? Simples: dê um nome ao estado, e então acrescente este nome à lista onde está a definição dos estados (pode ser em qualquer ordem na lista, mas tente manter uma organização lógica pra seu próprio benefício). Então, na Máquina de Estados "principal", acrescente a execução do estado seguindo o mesmo padrão usado para aqueles já implementados (acrescente a execução do estado conforme a ordem que vc deseja que seja executado dentro da Máquina de Estados). Dentro do estado, não "invente" nenhuma lógica maluca (principalmente usando loops). Claro, também não devem ser usados delays convencionais dentro dos estados.
É possível tornar ainda mais simples todo o mecanismo de exibição das mensagens. Por exemplo, sem precisar usar os estados para verificar se a exibição foi concluída (estados nas áreas em amarelo). Mas isto requer um pouco mais de memória RAM, e como esta memória é preciosa em alguns Arduinos (como UNO, Nano, etc), não fiz esta implementação para esta versão do código, para garantir que haja no Sistema RAM suficiente para uso com outros dispositivos e suas respectivas estruturas de dados.
Para a demonstração do funcionamento dos efeitos, implementei Simulações no Proteus usando os dois tipos de Interface para o LCD, ou seja, Paralela e I2C. Isto foi feito para com Arduino UNO, mas pode ser usado qualquer outro Arduino que esteja disponível no Proteus. O circuito para a Interface I2C é mostrado na figura a seguir:
(clique na figura para "zoom")
E para a Interface Paralela de 4 bits, mostrado na figura a seguir:
(clique na figura para "zoom")
Também capturei estas Simulações em vídeo, e elas podem ser vistas nos links a seguir, onde é possível também fazer o download dos vídeos:
Vídeo da Simulação com Interface I2C: "simul LCD I2C"
Vídeo da Simulação com Interface Paralela: "simul LCD Paralelo"
Notar que as Simulações feitas, seguem o código original da Marcela, que tem intervalos de tempo de 5 segundos entre algumas etapas de exibição no Display e por isso mesmo em alguns momentos parece que nada está ocorrendo. E claro: lembrar que as Simulações ocorrem em um tempo "virtual" que é sempre mais lento que o tempo real, principalmente no caso da versão com Interface I2C.
O código implementado está neste link: "LCD_16_x_2_Views_02.zip"
E os arquivos para Simulação no Proteus estão aqui: "Simulacao_Proteus.zip"
Qualquer dúvida, não deixe de perguntar.
Espero ter ajudado.
Abrçs,
Elcids…
Adicionado por Elcids Chagas ao 14:18 em 14 julho 2021
Colocamos aqui todos os tutoriais onde foram utilizados shields para Arduino ou Garagino.
Arduino
Tutorial: Controlando a potência dissipada de uma lâmpada com Dimmer Shield e Módulo Bluetooth
stou apanhando com o código C
17:59
EuDo Arduino?
Leonardo Borges da Silvasim
EuQue tipo de robo?
Leonardo Borges da Silvamontei ele com duas rodas com motores DC
com uma ponte h
e um sonar
fiz os motores funcionarem
e o sonar tambem
mais não consigo criar a variavel que faz ele desviar das coisas
18:01
Leonardo Borges da Silvacriei um tópico
EuCom o sensor é possível saber a que distância está o obstáculo?
Leonardo Borges da Silvasim
fiz um topico com algumas fotos e o código que estou tentando utilizar
Primeiro Projeto Arduino, Dúvidas
18:04
EuEntão vc. precisa de 2 variáveis para controle a atual e a anterior, quando a atual for menor que a anterior, você deve comparar com o outro sensor. Se as variaveis atuais dos 2 sensores estiverem menores que a anterior, significa que o robo está se aproximando de um obstáculo sem chance de desviar. você deve retornar os 2 motores, se um dos lados estiver a atual maior que a anterior, significa que ali há um espaço de escape. deve acionar o motor do lado contrário e vice-versa.
18:06
EuVocê está usando sensores sonares?
Leonardo Borges da Silvasim
entendi o que vc me explicou
EuConsegue ter a medida de distância com eles?
Leonardo Borges da Silvamais não consigo colocar isso em C
consigo
EuVocê tem quantos sensores?
Leonardo Borges da Silva1 só
18:08
EuEntão o máximo que pode fazer é tentar desviar para um só lado, e torcer para que haja espaço, ou então refazer o teste de distância e virar para o outro lado, ou dar marcha a ré.
Leonardo Borges da Silvaé esse aqui o sensor
http://www.robocore.net/modules.php?name=GR_LojaVirtual&prod=190
você pode me mostrar um exemplo ?
se não for te trapalhar é claro
EuEu tenho um sensor desses aqui, mas ainda não o usei para este tipo de aplicação. Mas vc. entendeu a lógica que lhe expliquei?
Espere que vou lá ver se é igual ao meu.
Leonardo Borges da Silvaentendi a lógica
mais como não entendo muito da linguagem
tenho dificuldades em digitar o código
18:12
EuEspere que vou dar uma olhada no manual.
Leonardo Borges da SilvaOk muito Obrigado
18:14
EuA conecção com o Arduino está TTL ou PWM?
Leonardo Borges da SilvaPWM
18:16
EuEntre os motores e as rodas qual está sendo a redução?
18:18
Leonardo Borges da Silvanão esta especificado
eu comprei a base pronta
http://lojabrasilrobotics.blogspot.com.br/2011/10/plataforma-robotica-w-r14500.html
é essa aqui
eu abri um topico e coloquei algumas fotos
18:20
EuVc. chegou a ver isso: http://letsmakerobots.com/node/5629
Leonardo Borges da Silvaolhei sim
18:22
Leonardo Borges da Silvamais não entedi
entendi**
18:22
EuEste é o exemplo indicado lá no site do sensor. O meu é diferente do seu, não tem tantos pinos.
Leonardo Borges da Silvahummm entendi
você viu o código que eu fiz e não deu certo ?
EuAinda não vc. não passou o link. Veja como este tipo de robo e comporta:http://blog.makezine.com/2009/03/05/mr-green-an-arduino-robot/
18:27
Leonardo Borges da Silvaaqui o post
http://labdegaragem.com/forum/topics/primeiro-projeto-arduino-d-vidas?commentId=6223006%3AComment%3A173742&xg_source=msg_com_forum
EuVeja que o sensor é movido de um lado para o outro para que ele "veja" se há escapatória quando está em vias de se chocar com algo.
Leonardo Borges da Silvaeu vi esse video
EuColocou isso no seu?
Leonardo Borges da Silvaestava focando nesse projeto porem sem o LCD e o Buzzer
http://ferpinheiro.wordpress.com/2012/03/09/criando-robo-com-arduino-parte-iv-montando-o-robo/
EuIsso poupa ter que colocar mais de um sensor no robo.
Vou lá no link que me passou.
Leonardo Borges da Silvaok obrigado
18:30
Leonardo Borges da Silvaum rapaz deixou um exemplo vc viu ?
18:42
EuSe vc. não alterou este código, está tentando usar o pino 5 para 2 coisas diferentes:
int URTRIG=5; // PWM trigger pin int E1 = 4; int M1 = 5;
URTRIG e M1 são diferentes certo?
Pode ser por isso que seu motor não está parando de girar.
Leonardo Borges da Silvasim o M1 é o motor
URTRIG é do sonar
verdade não tinha reparado nisso
EuAltera lá e testa.
Leonardo Borges da Silvaok vou fazer issoagora
18:45
EuOutra, procure usar um padrão de nomes que inclua o uso do IO. Tipo variáveis de pinos de entrada inicie com "I_" (input) e variáveis de pinos de saídas inicie com "O_" (outputs), isso evita estas dúvidas.
I_Sensor = Input do sensor.
O_M1 = Saída de acionamento do motor 1.
Entendeu?
Leonardo Borges da Silvaentendi
18:49
EuIsolando o que cada pino faz, acho que agora fica mais fácil. Leia novamente o que o Jonatas escreveu. Não dá para pular etapas, se não começar pelo Blink...vai faltar coisas no meio do caminho.
18:51
EuLeia a distância do sensor, e acione os motores de acordo com a lógica que vc. deseja que seja executada para que o robo não saia "batendo" em tudo por aí.
Leonardo Borges da Silvavou tentar aqui
EuMas importante: Os delays entre leituras e acionamentos tem que ser bem pensados, verifique as reduções entre os motores e as rodas e "equilibre" de acordo.
18:53
EuTipo: Leia o sensor, mostre a distância, execute um delay( tempo) e faça um acionamento "lento" para que vc. possa entender em que parte do programa o que está ocorrendo está sendo executado. quando tiver tudo redondo, aí retire ou remarque os delays. Já que o Arduino é "pobre" em debug.
Acha que daqui pra frente vai?
Leonardo Borges da Silvaeu alterei o pino mais não aconteceu nada
acho que vou começar do zero
como eu consigo "testar" tipo
18:56
Leonardo Borges da Silvauma variavel
que eu consiga falar para o motor ligar com certa distancia
que o sonar me retornar
acho que assim eu entendendo um exemplo consiga o restante
18:56
Euif ( position <= 50){ faça alguma coisa...// delay(10);
};
verifique se vc. não está "mandando" sinal digital onde se espera um acionamento analógico.
Leonardo Borges da Silvaok vou tentar fazer esse teste
19:01
EuAfinal o controle dos motores está por PWM né?
19:02
EuEntão nos pinos dos motores tem que ser AnalogWrite!
Leonardo Borges da Silvanossa verdade
EuAí se uma hora vc. manda Digital outra hora vc. manda Analog fica difícil...
Leonardo Borges da Silvanão preciso do PLL
EuAí o motor não para, ou despara...ou repara...
19:05
EuIsso são "detalhezinhos" que todo programador deve ter no "sangue"....senão imagine quando aparecer coisas "complicadas"????....rsrsrsss...
Leonardo Borges da Silvahauhauahuauh verdade
to terminando aqui ai posso te enviar para vc dar uma olhada ?
19:07
EuNão tenho como testar aqui. Vou ver se copio este tópico lá e vc. coloca como resposta.
…
Nesta seção estão todos os tutoriais que podem ser considerados para aqueles que tem um conhecimento em Arduino, eletrônica e programação mais avançados. Analisamos o tempo gasto para construir o circ