LusoRobótica - Robótica em Português
Sistemas específicos => Arduino / AVR => Tópico iniciado por: The Wolfman em 28 de Abril de 2010, 14:39
-
Olá, boa tarde.
Tenho o seguinte material:
3* Devantech SRF05
2* Mini metal Gear motor
1* SN754410
1* LDR (embora ache que está mal feito).
Tenho de fazer com que o meu robot ande e se desvie de obstáculos, e depois quando encontrar uma certa cor, ele vai acender um LED.
Podem ajudar-me? É que eu sou mesmo muito mau em C, comecei a poucos dias :p
Encontrei isto na net, e consegui por a funcionar:
// written at: luckylarry.co.uk
// variables to take x number of readings and then average them
// to remove the jitter/noise from the SRF05 sonar readings
const int numOfReadings = 10; // number of readings to take/ items in the array
int readings[numOfReadings]; // stores the distance readings in an array
int arrayIndex = 0; // arrayIndex of the current item in the array
int total = 0; // stores the cumlative total
int averageDistance = 0; // stores the average value
// setup pins and variables for SRF05 sonar device
int echoPin = 2; // SRF05 echo pin (digital 2)
int initPin = 3; // SRF05 trigger pin (digital 3)
unsigned long pulseTime = 0; // stores the pulse in Micro Seconds
unsigned long distance = 0; // variable for storing the distance (cm)
// setup pins/values for LED
int redLEDPin = 9; // Red LED, connected to digital PWM pin 9
int redLEDValue = 0; // stores the value of brightness for the LED (0 = fully off, 255 = fully on)
//setup
void setup() {
pinMode(redLEDPin, OUTPUT); // sets pin 9 as output
pinMode(initPin, OUTPUT); // set init pin 3 as output
pinMode(echoPin, INPUT); // set echo pin 2 as input
// create array loop to iterate over every item in the array
for (int thisReading = 0; thisReading < numOfReadings; thisReading++) {
readings[thisReading] = 0;
}
// initialize the serial port, lets you view the
// distances being pinged if connected to computer
Serial.begin(9600);
}
// execute
void loop() {
digitalWrite(initPin, HIGH); // send 10 microsecond pulse
delayMicroseconds(10); // wait 10 microseconds before turning off
digitalWrite(initPin, LOW); // stop sending the pulse
pulseTime = pulseIn(echoPin, HIGH); // Look for a return pulse, it should be high as the pulse goes low-high-low
distance = pulseTime/58; // Distance = pulse time / 58 to convert to cm.
total= total - readings[arrayIndex]; // subtract the last distance
readings[arrayIndex] = distance; // add distance reading to array
total= total + readings[arrayIndex]; // add the reading to the total
arrayIndex = arrayIndex + 1; // go to the next item in the array
// At the end of the array (10 items) then start again
if (arrayIndex >= numOfReadings) {
arrayIndex = 0;
}
averageDistance = total / numOfReadings; // calculate the average distance
// if the distance is less than 255cm then change the brightness of the LED
if (averageDistance < 255) {
redLEDValue = 255 - averageDistance; // this means the smaller the distance the brighterthe LED.
}
analogWrite(redLEDPin, redLEDValue); // Write current value to LED pins
Serial.println(averageDistance, DEC); // print out the average distance to the debugger
delay(100); // wait 100 milli seconds before looping again
}
Alguém me pode dar uma ajuda, ou uns tutoriais que encontrem? Não encontrei nada de um LDR com o arduino.
Obrigado
-
O que é que este código tem de mal?
Este fui eu que fiz, seguindo o exemplo do site do arduino, mas depois adaptei os valores ao devantech srf05.
const int sens = 7;
void setup () {
Serial.begin(9600);
}
void loop()
{
pinMode (sens, OUTPUT);
digitalWrite (sens, LOW);
delayMicroseconds (2);
digitalWrite (sens, HIGH);
delayMicroseconds (5);
digitalWrite (sens, LOW);
duration = pulseIn(sens, HIGH);
cm = microsecondsToCentimeters(duration);
Serial.print(cm);
Serial.print("cm");
Serial.printIn();
delay(100);
}
long microsecondsToCentimeters(long microseconds)
{
return microseconds / 29
}
Quando vai a compilar, dá o seguinte erro:
In function 'void loop()':
error: 'duration' was not declared in this scope In function 'long int microsecondsToCentimeters(long int)':
Qual é o problema? Segui o que estava aqui à risca, só usei centímetros em vez de polegadas...
http://arduino.cc/en/Tutorial/Ping (http://arduino.cc/en/Tutorial/Ping)
-
long microsecondsToCentimeters(long microseconds)
Estás a chamar a função que ele ainda não conhece.
Todas as funções têm que estar definidas antes da sua chamada. Basta meter essa função antes do loop e já deve de funcionar.
_________
A variável "cm" também não está declarada. (não sei se o arduino permite a tal história a cima referida visto poder estar protegido contra erros de iniciantes e fazer automaticamente a declaração da função abaixo definida.
-
Então e em que sitio é que eu tenho de colocar isto?
Suponho que seja ''dentro'' desta coisa do void loop...
-
cm = microsecondsToCentimeters(duration); passa a ser:
long cm = microsecondsToCentimeters(duration);
Ou então no ínicio do código onde tens:
const int sens = 7;
Metes por baixo:
long cm;
-
Continua a dar erro, e experimentei das duas maneiras...
-
Tinhas inúmeros erros desde chavetas a pontos e virgulas ou até declaração das variáveis.
Corrigido:
const int sens = 7;
void setup () {
Serial.begin(9600);
}
void loop()
{
pinMode (sens, OUTPUT);
digitalWrite (sens, LOW);
delayMicroseconds (2);
digitalWrite (sens, HIGH);
delayMicroseconds (5);
digitalWrite (sens, LOW);
long duration = pulseIn(sens, HIGH);
long cm = microsecondsToCentimeters(duration);
Serial.print(cm);
Serial.print("cm");
Serial.println();
delay(100);
}
long microsecondsToCentimeters(long microseconds)
{
return microseconds / 29;
}
-
Assim já funciona, mas o raio do código dá-me no ''debug'' 0cm, e a luz do sensor pisca muito devagar...
Obrigado
-
Não vi código.. só corrigi sintax.
-
Bem, usei os exemplos do arduino.cc, mas parece que aquilo só servia para o PING))) da paralaxx.
Então pesquisei no google, e enconrei um código para o devantech srf05. Configurei aquilo para 3 sensores, e funcionou :D
Mas só postei hoje porque o meu irmão desligou o computador e não tinha gravado o código :p
Aqui está:
int duration_frt;
int distance_frt;
int srf_frt = 4;
int duration_esq;
int distance_esq;
int srf_esq = 5;
int duration_dir;
int distance_dir;
int srf_dir = 6;
void setup(){
Serial.begin(9600);
}
void loop(){
pinMode(srf_frt, OUTPUT);
digitalWrite(srf_frt, LOW);
delayMicroseconds(2);
digitalWrite(srf_frt, HIGH);
delayMicroseconds(10);
digitalWrite(srf_frt, LOW);
pinMode(srf_frt, INPUT);
duration_frt = pulseIn(srf_frt, HIGH);
distance_frt = duration_frt/58;
pinMode(srf_esq, OUTPUT);
digitalWrite(srf_esq, LOW);
delayMicroseconds(2);
digitalWrite(srf_esq, HIGH);
delayMicroseconds(10);
digitalWrite(srf_esq, LOW);
pinMode(srf_esq, INPUT);
duration_esq = pulseIn(srf_esq, HIGH);
distance_esq = duration_esq/58;
pinMode(srf_dir, OUTPUT);
digitalWrite(srf_dir, LOW);
delayMicroseconds(2);
digitalWrite(srf_dir, HIGH);
delayMicroseconds(10);
digitalWrite(srf_dir, LOW);
pinMode(srf_dir, INPUT);
duration_dir = pulseIn(srf_dir, HIGH);
distance_dir = duration_dir/58;
Serial.println(distance_frt);
delay(100);
}
O que acham?
Falta-me agora configurar os motores com a ponte-H, o LDR e o LED para quando encontrar uma vitima.
-
Bem, o LDR já está também...
Neste momento tenho o arduino ligado por USB, mas vou usar 8 pilhas de NiCd.
O LDR tem dois LED's de cada lado para ele ''ver'' melhor, e como esses LED's estão ligados em série, 5V, eles têm uma luz muito fraquinha.
Neste código, defini o pino 13 como saida, e acendi os LED's, mas 5V para dois led's é pouco, pelo que no código final, vou apagar esta parte, e ligar os LED's directamente ao Vin
int duration_frt;
int distance_frt;
int srf_frt = 4;
int duration_esq;
int distance_esq;
int srf_esq = 5;
int duration_dir;
int distance_dir;
int srf_dir = 6;
int ldr = 0;
int valor_ldr = 5;
int led_ldr = 13;
void setup(){
Serial.begin(9600);
}
void loop(){
pinMode(srf_frt, OUTPUT);
digitalWrite(srf_frt, LOW);
delayMicroseconds(2);
digitalWrite(srf_frt, HIGH);
delayMicroseconds(10);
digitalWrite(srf_frt, LOW);
pinMode(srf_frt, INPUT);
duration_frt = pulseIn(srf_frt, HIGH);
distance_frt = duration_frt/58;
pinMode(srf_esq, OUTPUT);
digitalWrite(srf_esq, LOW);
delayMicroseconds(2);
digitalWrite(srf_esq, HIGH);
delayMicroseconds(10);
digitalWrite(srf_esq, LOW);
pinMode(srf_esq, INPUT);
duration_esq = pulseIn(srf_esq, HIGH);
distance_esq = duration_esq/58;
pinMode(srf_dir, OUTPUT);
digitalWrite(srf_dir, LOW);
delayMicroseconds(2);
digitalWrite(srf_dir, HIGH);
delayMicroseconds(10);
digitalWrite(srf_dir, LOW);
pinMode(srf_dir, INPUT);
duration_dir = pulseIn(srf_dir, HIGH);
distance_dir = duration_dir/58;
ldr = analogRead(valor_ldr);
digitalWrite(led_ldr, HIGH);
Serial.println(ldr);
delay(100);
}
Agora vou tratar da ponte H, mas tenho de ver se me safo nas sub-rotinas para depois decidir para que lado anda o bixo.
-
Ora bem, inclui aqui uma parte dos motores.
int duration_frt;
int distance_frt;
int srf_frt = 4;
int duration_esq;
int distance_esq;
int srf_esq = 5;
int duration_dir;
int distance_dir;
int srf_dir = 6;
int ldr = 0;
int valor_ldr = 5;
int led_ldr = 13;
int motor_esq[] = {2, 3};
int motor_dir[] = {7,8};
int i;
void setup(){
Serial.begin(9600);
for(i = 0; i < 2; i++){
pinMode(motor_esq[i], OUTPUT);
pinMode(motor_dir[i], OUTPUT);
}
}
void loop(){
pinMode(srf_frt, OUTPUT);
digitalWrite(srf_frt, LOW);
delayMicroseconds(2);
digitalWrite(srf_frt, HIGH);
delayMicroseconds(10);
digitalWrite(srf_frt, LOW);
pinMode(srf_frt, INPUT);
duration_frt = pulseIn(srf_frt, HIGH);
distance_frt = duration_frt/58;
pinMode(srf_esq, OUTPUT);
digitalWrite(srf_esq, LOW);
delayMicroseconds(2);
digitalWrite(srf_esq, HIGH);
delayMicroseconds(10);
digitalWrite(srf_esq, LOW);
pinMode(srf_esq, INPUT);
duration_esq = pulseIn(srf_esq, HIGH);
distance_esq = duration_esq/58;
pinMode(srf_dir, OUTPUT);
digitalWrite(srf_dir, LOW);
delayMicroseconds(2);
digitalWrite(srf_dir, HIGH);
delayMicroseconds(10);
digitalWrite(srf_dir, LOW);
pinMode(srf_dir, INPUT);
duration_dir = pulseIn(srf_dir, HIGH);
distance_dir = duration_dir/58;
digitalWrite(motor_esq[0], HIGH);
digitalWrite(motor_esq[1], LOW);
digitalWrite(motor_dir[0], HIGH);
digitalWrite(motor_dir[1], LOW);
ldr = analogRead(valor_ldr);
digitalWrite(led_ldr, HIGH);
Serial.println(ldr);
delay(100);
}
Não os posso ligar porque tenho o arduino ligado por USB, mas isto assim não devia dar 5V nos fios que ligam aos motores? Se eu for medir com o multimetro a tensão nos fios que supostamente ligam nos motores, tenho uma tensão de 0,284V...
-
Bem, por hoje não faço mais nada.
Já adicionei um LED com o comando if (fui ver ao site do arduino como funciona).
Se o valor do LDR for maior que 500 acende, se não for apaga. O que achei estranho foi ter de dizer que se o valor for menor, o led fica LOW, não é lógico?
int duration_frt;
int distance_frt;
int srf_frt = 4;
int duration_esq;
int distance_esq;
int srf_esq = 5;
int duration_dir;
int distance_dir;
int srf_dir = 6;
int ldr = 0;
int valor_ldr = 5;
int led_ldr = 13;
int motor_esq[] = {2, 3};
int motor_dir[] = {7,8};
int i;
int led_vitima = 12;
void setup(){
Serial.begin(9600);
for(i = 0; i < 2; i++){
pinMode(motor_esq[i], OUTPUT);
pinMode(motor_dir[i], OUTPUT);
}
}
void loop(){
pinMode(srf_frt, OUTPUT);
digitalWrite(srf_frt, LOW);
delayMicroseconds(2);
digitalWrite(srf_frt, HIGH);
delayMicroseconds(10);
digitalWrite(srf_frt, LOW);
pinMode(srf_frt, INPUT);
duration_frt = pulseIn(srf_frt, HIGH);
distance_frt = duration_frt/58;
pinMode(srf_esq, OUTPUT);
digitalWrite(srf_esq, LOW);
delayMicroseconds(2);
digitalWrite(srf_esq, HIGH);
delayMicroseconds(10);
digitalWrite(srf_esq, LOW);
pinMode(srf_esq, INPUT);
duration_esq = pulseIn(srf_esq, HIGH);
distance_esq = duration_esq/58;
pinMode(srf_dir, OUTPUT);
digitalWrite(srf_dir, LOW);
delayMicroseconds(2);
digitalWrite(srf_dir, HIGH);
delayMicroseconds(10);
digitalWrite(srf_dir, LOW);
pinMode(srf_dir, INPUT);
duration_dir = pulseIn(srf_dir, HIGH);
distance_dir = duration_dir/58;
digitalWrite(motor_esq[0], HIGH);
digitalWrite(motor_esq[1], LOW);
digitalWrite(motor_dir[0], HIGH);
digitalWrite(motor_dir[1], LOW);
ldr = analogRead(valor_ldr);
digitalWrite(led_ldr, HIGH);
if (ldr > 500)
{
pinMode(led_vitima, OUTPUT);
digitalWrite(led_vitima, HIGH);
}
if (ldr < 500)
{
pinMode(led_vitima, OUTPUT);
digitalWrite(led_vitima, LOW);
}
Serial.println(ldr);
delay(100);
}
E pronto, as minhas brincadeiras de hoje acabaram, comentem :D
P.S., TigPT, reparei agora que nestes casos mete-se as tags code e não quote, já não precisas de ter trabalho ;)
-
Até amanha. Não tenhas pesadelos com código. Vai lá com o tempo. ;)
-
Oh pá, as vezes sou mesmo estúpido. Tive dois dias a pensar porque é que a ponte H não funciona, e só hoje é que vi que não a liguei ao ground --'
Já está a funcionar, e já ando a tratar de sub rotinas.
-
Bem, por hoje fico assim. Amanhã vou testar :D
int duration_frt;
int distance_frt;
int srf_frt = 4;
int duration_esq;
int distance_esq;
int srf_esq = 5;
int duration_dir;
int distance_dir;
int srf_dir = 6;
int ldr = 0;
int valor_ldr = 5;
int led_ldr = 13;
int motor_esq[] = {2, 3};
int motor_dir[] = {7,8};
int i;
int led_vitima = 12;
void setup(){
Serial.begin(9600);
for(i = 0; i < 2; i++){
pinMode(motor_esq[i], OUTPUT);
pinMode(motor_dir[i], OUTPUT);
}
}
void loop(){
pinMode(srf_frt, OUTPUT);
digitalWrite(srf_frt, LOW);
delayMicroseconds(2);
digitalWrite(srf_frt, HIGH);
delayMicroseconds(10);
digitalWrite(srf_frt, LOW);
pinMode(srf_frt, INPUT);
duration_frt = pulseIn(srf_frt, HIGH);
distance_frt = duration_frt/58;
pinMode(srf_esq, OUTPUT);
digitalWrite(srf_esq, LOW);
delayMicroseconds(2);
digitalWrite(srf_esq, HIGH);
delayMicroseconds(10);
digitalWrite(srf_esq, LOW);
pinMode(srf_esq, INPUT);
duration_esq = pulseIn(srf_esq, HIGH);
distance_esq = duration_esq/58;
pinMode(srf_dir, OUTPUT);
digitalWrite(srf_dir, LOW);
delayMicroseconds(2);
digitalWrite(srf_dir, HIGH);
delayMicroseconds(10);
digitalWrite(srf_dir, LOW);
pinMode(srf_dir, INPUT);
duration_dir = pulseIn(srf_dir, HIGH);
distance_dir = duration_dir/58;
digitalWrite(motor_esq[0], HIGH);
digitalWrite(motor_esq[1], LOW);
digitalWrite(motor_dir[0], HIGH);
digitalWrite(motor_dir[1], LOW);
ldr = analogRead(valor_ldr);
digitalWrite(led_ldr, HIGH);
digitalWrite(led_vitima, LOW);
if (ldr > 500)
{
pinMode(led_vitima, OUTPUT);
digitalWrite(led_vitima, HIGH);
}
if (distance_frt <= 4)
{
digitalWrite(motor_esq[0], LOW);
digitalWrite(motor_esq[1], LOW);
digitalWrite(motor_dir[0], LOW);
digitalWrite(motor_dir[1], LOW);
delay(1000);
digitalWrite(motor_esq[0], LOW);
digitalWrite(motor_esq[1], HIGH);
digitalWrite(motor_dir[0], LOW);
digitalWrite(motor_dir[1], HIGH);
delay(1000);
digitalWrite(motor_esq[0], LOW);
digitalWrite(motor_esq[1], HIGH);
digitalWrite(motor_dir[0], HIGH);
digitalWrite(motor_dir[1], LOW);
delay(1000);
}
if (distance_frt && distance_esq <= 4)
{
digitalWrite(motor_esq[0], LOW);
digitalWrite(motor_esq[1], LOW);
digitalWrite(motor_dir[0], LOW);
digitalWrite(motor_dir[1], LOW);
delay(1000);
digitalWrite(motor_esq[0], LOW);
digitalWrite(motor_esq[1], HIGH);
digitalWrite(motor_dir[0], LOW);
digitalWrite(motor_dir[1], HIGH);
delay(1000);
digitalWrite(motor_esq[0], HIGH);
digitalWrite(motor_esq[1], LOW);
digitalWrite(motor_dir[0], LOW);
digitalWrite(motor_dir[1], HIGH);
delay(1000);
}
if (distance_frt && distance_dir <= 4)
{
digitalWrite(motor_esq[0], LOW);
digitalWrite(motor_esq[1], LOW);
digitalWrite(motor_dir[0], LOW);
digitalWrite(motor_dir[1], LOW);
delay(1000);
digitalWrite(motor_esq[0], LOW);
digitalWrite(motor_esq[1], HIGH);
digitalWrite(motor_dir[0], LOW);
digitalWrite(motor_dir[1], HIGH);
delay(1000);
digitalWrite(motor_esq[0], LOW);
digitalWrite(motor_esq[1], HIGH);
digitalWrite(motor_dir[0], HIGH);
digitalWrite(motor_dir[1], LOW);
delay(1000);
}
Serial.println(distance_frt);
delay(100);
}
-
Como o é que o projecto ficou?
Fotos da versão final para o pessoal e um pequeno resumo do que aprenderam!? ;D
-
Sim, eu não me esqueci ;)
Eu tratei da programação ao inicio, mas um colega meu depois começou a inventar (pelo que vi dos testes dele, já misturava whiles dentro de if's) LOOL!
O que interessa é que tendo em conta os nossos contratempos, conseguimos meter o motor a funcionar.
Contratempos esses:
-2 Reguladores 7805 queimados;
-2 Pontes H SN754410NE;
-1 Picaxe 28X1;
-1 pololu TB66FNG12 (ainda estou para descobrir como aquilo se queimou --');
-1 Mini metal gearmotor 100:1 com as engrenagens rebentadas;
-Uma carrada de LED's queimados;
Especialmente devido a contratempos como ter de estar a trocar de chassis de um dia para o outro, não vou postar aqui ainda o código, visto que não está ainda tudo funcional :s
De qualquer maneira, o meu trabalho foi dos 3 melhores da escola!!!
Um amigo meu vai-me passar as fotografias TODAS do desenvolvimento do projecto e eu depois posto :D
Queria deixar aqui um agradecimento especial ao TigPT e ao Fifas porque são uns bacanos e a ajuda deles foi muito preciosa, sem a ajuda destas duas pessoas, não conseguiríamos alcançar os nossos objectivos!