0 Membros e 1 Visitante estão a ver este tópico.
/*********************************** * Project: XMasRoBOT * * Created by: Ricardo Dias (2009) * ***********************************/ /* BIBLIOTECAS NECESSARIAS */ #include <Servo.h> /* VARIAVEIS DE CONFIGURACAO */ // Sensores const int numSensors = 5; const int TWO_SENSORS_EQUAL_DELTA = 25; // Diferenca maxima entre 2 sensores para os considerar iguais const int sensor[] = {5,4,3,2,1}; // Array que tem os pinos dos sensores // Servos const int lServoPin = 9; // Pino do servo esquerdo (PWM) const int rServoPin = 10; // Pino do servo direito (PWM) const int MAX_SERVO_VEL = 7; // Velocidade maxima do Servo (entre 0 e 90) const int MAX_TIME_WITHOUT_LINE_MS = 2000; // Tempo maximo sem linha (ou tempo de chegar ao centro do circulo) Servo lServo; // Servo rServo; // /* VARIAVEIS AUXILIARES */ int senVal[] = {0,0,0,0,0}; // Array que tem os valores lidos pelos sensores int targetVelL = 0; // Velocidade pretendida para o servomotor esquerdo int targetVelR = 0; // Velocidade pretendida para o servomotor direito int nowVelL = 0; // Velocidade actual do servomotor esquerdo int nowVelR = 0; // Velocidade actual do servomotor direito int cStart = 0; // Vai funcionar como timer boolean stop = false; double lineErrorVal = 0.0; void setup(){ Serial.begin(9600); pinMode(lServoPin, OUTPUT); pinMode(rServoPin, OUTPUT); lServo.attach(lServoPin); rServo.attach(rServoPin); Serial.println("ready!");}void loop(){ stop = false; // Primeiro lemos os valores dos sensores readAllSensors(); //Serial.println("readVals"); for(int i = 0; i < numSensors; i++){ Serial.print(senVal[i]); Serial.print(" - "); } double average = sensorAverage(senVal); if(average > 30){ stop = true; } // Vemos se os valores lidos sao todos iguais if(stop){ cStart++; if(cStart >= 17){ Serial.println("Start Point"); targetVelL = 0; targetVelR = 0; } }else{ if(foundLine(senVal)){ lineErrorVal = lineError(senVal); } cStart = 0; // Depois, determinamos as velocidades pretendidas para os motores // Os motores irao ter uma velocidade entre 0 e "MAX_SERVO_VEL" if(lineErrorVal < 0.0){ targetVelL = (int)(MAX_SERVO_VEL*(1-fabs(lineErrorVal))); targetVelR = (int)(MAX_SERVO_VEL); if(nowVelL <= 0.0) targetVelL = -MAX_SERVO_VEL; }else if(lineErrorVal > 0.0){ targetVelL = (int)(MAX_SERVO_VEL); targetVelR = (int)(MAX_SERVO_VEL*(1-lineErrorVal)); if(nowVelR <= 0.0) targetVelR = -MAX_SERVO_VEL; }else{ targetVelL = (int)(MAX_SERVO_VEL); targetVelR = (int)(MAX_SERVO_VEL); } } // Atenuar os arranques e travagens if(targetVelL > nowVelL){ nowVelL += 1; }else if(targetVelL < nowVelL){ nowVelL -= 1; } if(targetVelR > nowVelR){ nowVelR += 1; }else if(targetVelR < nowVelR){ nowVelR -= 1; } // cropping - ter a certeza que os valores se mantêm entre os pretendidos if(nowVelL > MAX_SERVO_VEL){ nowVelL = MAX_SERVO_VEL; } if(nowVelR > MAX_SERVO_VEL){ nowVelR = MAX_SERVO_VEL; } // Fazer actuar os motores lServo.write(90+nowVelL); rServo.write(90-nowVelR); delay(10);}//--- FUNCOES ---//void readAllSensors(){ for(int i=0; i < 5; i++) { senVal[i] = analogRead(sensor[i]); }}boolean foundLine(int senVal[]){ boolean found = false; double average = sensorAverage(senVal); for(int i = 0; i < numSensors; i++){ if(senVal[i] - TWO_SENSORS_EQUAL_DELTA/4 > average) found = true; } return found;}// Escolhe o sensor que esta mais proximo da linhint bestSensor(int senVal[]){ int best = 1; int maxim = 0; for(int i=0; i < 5; i++) { if(senVal[i] > maxim){ best = i+1; maxim = senVal[i]; } } return best;}// Retorna um valor real entre -1.0 e 1.0, correspondente ao erro da posicao da linha// Retorna 0.0 quando a linha esta ao centrodouble lineError(int senVal[]){ int best = bestSensor(senVal); Serial.print(" :: BEST: "); Serial.print(best); Serial.print(" :: "); double error = 0.0; // Se o que tem a linha mais proxima esta na ponta, só podemos comparar com 1 if(best == 1){ error = -1.0; if(fabs(senVal[0] - senVal[1]) <= TWO_SENSORS_EQUAL_DELTA){ error += 0.25; } }else if(best == 2){ error = -0.5; if(fabs(senVal[1] - senVal[0]) <= TWO_SENSORS_EQUAL_DELTA){ error -= 0.25; } else if(fabs(senVal[1] - senVal[2]) <= TWO_SENSORS_EQUAL_DELTA){ error += 0.25; } }else if(best == 3){ error = 0.0; if(fabs(senVal[2] - senVal[1]) <= TWO_SENSORS_EQUAL_DELTA){ error -= 0.25; } else if(fabs(senVal[2] - senVal[3]) <= TWO_SENSORS_EQUAL_DELTA){ error += 0.25; } }else if(best == 4){ error = 0.5; if(fabs(senVal[3] - senVal[2]) <= TWO_SENSORS_EQUAL_DELTA){ error -= 0.25; } else if(fabs(senVal[3] - senVal[4]) <= TWO_SENSORS_EQUAL_DELTA){ error += 0.25; } }else if(best == 5){ error = 1.0; if(fabs(senVal[4] - senVal[3]) <= TWO_SENSORS_EQUAL_DELTA){ error -= 0.25; } } return error;}// Retorna a media dos valores de todos os sensoresdouble sensorAverage(int senVal[]){ double avg = 0.0; double soma = 0.0; //int numSensors = sizeof(senVal); for(int i=0; i < numSensors; i++){ soma += senVal[i]; } avg = soma/numSensors; return avg;}// Retorna TRUE se os sensores lerem todos aproximadamente o mesmo valorboolean allEqual(int senVal[]){ double average = sensorAverage(senVal); boolean result = true; for(int i=0; i < numSensors; i++){ if(fabs(senVal[i] - average) <= TWO_SENSORS_EQUAL_DELTA){ result = false; break; } } return result;}
#include <Tone.h>Tone tone1;#define OCTAVE_OFFSET 0int notes[] = { 0,NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7};char *song = "JingleBells:d=8,o=5,b=112:32p,a,a,4a,a,a,4a,a,c6,f.,16g,2a,a#,a#,a#.,16a#,a#,a,a.,16a,a,g,g,a,4g,4c6";void setup(void){ Serial.begin(9600); tone1.begin(11);}#define isdigit(n) (n >= '0' && n <= '9')void play_rtttl(char *p){ // Absolutely no error checking in here byte default_dur = 4; byte default_oct = 6; int bpm = 63; int num; long wholenote; long duration; byte note; byte scale; // format: d=N,o=N,b=NNN: // find the start (skip name, etc) while(*p != ':') p++; // ignore name p++; // skip ':' // get default duration if(*p == 'd') { p++; p++; // skip "d=" num = 0; while(isdigit(*p)) { num = (num * 10) + (*p++ - '0'); } if(num > 0) default_dur = num; p++; // skip comma } Serial.print("ddur: "); Serial.println(default_dur, 10); // get default octave if(*p == 'o') { p++; p++; // skip "o=" num = *p++ - '0'; if(num >= 3 && num <=7) default_oct = num; p++; // skip comma } Serial.print("doct: "); Serial.println(default_oct, 10); // get BPM if(*p == 'b') { p++; p++; // skip "b=" num = 0; while(isdigit(*p)) { num = (num * 10) + (*p++ - '0'); } bpm = num; p++; // skip colon } Serial.print("bpm: "); Serial.println(bpm, 10); // BPM usually expresses the number of quarter notes per minute wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds) Serial.print("wn: "); Serial.println(wholenote, 10); // now begin note loop while(*p) { // first, get note duration, if available num = 0; while(isdigit(*p)) { num = (num * 10) + (*p++ - '0'); } if(num) duration = wholenote / num; else duration = wholenote / default_dur; // we will need to check if we are a dotted note after // now get the note note = 0; switch(*p) { case 'c': note = 1; break; case 'd': note = 3; break; case 'e': note = 5; break; case 'f': note = 6; break; case 'g': note = 8; break; case 'a': note = 10; break; case 'b': note = 12; break; case 'p': default: note = 0; } p++; // now, get optional '#' sharp if(*p == '#') { note++; p++; } // now, get optional '.' dotted note if(*p == '.') { duration += duration/2; p++; } // now, get scale if(isdigit(*p)) { scale = *p - '0'; p++; } else { scale = default_oct; } scale += OCTAVE_OFFSET; if(*p == ',') p++; // skip comma for next note (or we may be at the end) // now play the note if(note) { Serial.print("Playing: "); Serial.print(scale, 10); Serial.print(' '); Serial.print(note, 10); Serial.print(" ("); Serial.print(notes[(scale - 4) * 12 + note], 10); Serial.print(") "); Serial.println(duration, 10); tone1.play(notes[(scale - 4) * 12 + note]); delay(duration); tone1.stop(); } else { Serial.print("Pausing: "); Serial.println(duration, 10); delay(duration); } }}void loop(void){ play_rtttl(song); Serial.println("Done."); delay(100);}
...vi que a biblioteca Tone usa os timers todos do Arduino e a biblioteca dos servos necessita do timer 2 (se não estou em erro). Ainda andei a tentar alterar o Tone library para ver se conseguia torná-los compatíveis, mas andar a mexer nos timers fez com que a música ficasse toda maluca, sem tempo.Solução: 2 arduinos - um para a música e outro para as decisões (sensores + servos).
Muito bom, mas olha as regras das prendas enquanto tens tempo
3. O desafio consiste na criação de um robot capaz de transportar no mínimo uma prenda, cada prenda deve ter as seguintes dimensões mínimas:a. Altura: 10cmb. Comprimento: 10cmc. Largura: 10cm
ficou muito bom! acho ser dos mehlores até agora, senão o melhor!tiveste problemas com alfandega e a deal extreme?
ObjectivosO objectivo é ajudar o Pai Natal daqui a 12 meses
Citação de: microbyte em Janeiro 05, 2010, 02:55ObjectivosO objectivo é ajudar o Pai Natal daqui a 12 meses O Pai Natal hoje ainda anda a entregar as prendas em Espanha