LusoRobótica - Robótica em Português
Electrónica => Electrónica Geral => Tópico iniciado por: dvdt em 14 de Maio de 2011, 21:13
-
boa tarde queria saber como e que eu posso comandar um robot com comando rc eu quria controlar dois motores dc com o este comando (http://www.rtr-modelismo.com/loja/protech/764-radio-avenger-4-35mhz-fm-modo-2-protech.html) que por acaso tras ja o receiver
-
Sim, trás, mas se queres usar esse comando com um Arduino por exemplo tens de aprender a suar Pin Change interrupts para descodificar o sinal ppm para algo util, se for para motores dc, terás de usar um micro-controlador porque não podes ligar directamente uma ponte H a um receptor RC.
-
obrigado pela resposta mas sera que poderiam me explicar entam como e que eu teria que ligar o reciver ao arduino???
-
Massa com massa, 5v com 5v e ligas os sinais a pinos digitais e depois é google e procuras por arduino ppm decoder ou arduino rc decoder, mas não é algo assim muito simples, podes sempre fazer tu um comando com dois joysticks de ps2 que a sparkfun tem á venda e dois módulos sem fios, por exemplo Xbee para distancias bem grandes ou uns simples transceivers de433Mhz que custam meia duzia de € cada.
-
entao de que me maneira e que ficaria mais barato??
-
Depende, se perderes duas ou três semana a meter o comando de RC a funcionar e o tempo te sair "caro" pode ficar mais caro o comando RC, mas o comando feito por ti deve ficar mais ou menos ao mesmo preço, mas é mais simples de se fazer em termos de código, mas pode ser mais propenso a erros de transmissão.
-
fala me desses
transceivers de433Mhz
de que falaste como e que se ligaria
-
São coisas destas:
http://www.sparkfun.com/products/10153 (http://www.sparkfun.com/products/10153)
Podes ler mais sobre eles no link.
-
eu ontem estava a ver tv e vi a resposta aos meus problemas e essa responta foi por um joystick e mexelo com os servos o codigo seria mais facil nao?
-
Hum?
Mexer joystick com servos?
Mas afinal o que é que queres comandar?
-
e um robot de lagartas
-
mas sera que o codigo seria muito dificil assim alguem me poderia explicar o codigo e postar uns esquemas
-
Código e esquemas para fazer o que?
-
para ligar o rc directamente ao arduino
-
Have fun:
http://diydrones.com/profiles/blog/show?id=705844:BlogPost:38418 (http://diydrones.com/profiles/blog/show?id=705844:BlogPost:38418)
-
obrigado
-
no fim de ver o site com atençao verifiquei que nao tinha grande informaçao mas eu queria saber em que pinos e que ligaria os cabos do sinal
-
Tendo em conta que até lá tens código fonte pronto a meter no IDE do Arduino e comentado tudo certinho, mais que isso não sei...
-
no fim de procurar muito encontrei o codigo so que apenas liga um motor quando eu movo um (nao sei nome verdadeiro ) joystick. Entao eu estive a tentar alterar o codigo de maneira que quando eu movo o joystick para a frente ele ligue os dois motores para a frente, quando eu puxo para tras ele liga os dois motores em reverse e quando puxo para a esquerda ele ligue o motor da direita para a frente e o da esquerda em reverse e vice versa.
Eu penso que mesmo assim mal explicado da para perceber mas pronto fica aqui tambem o codigo caso queira ver as alterações feitas e que so esta a responder um motor mas o arduino esta a receber sinal pois ele liga e desliga um led quando se move os joyticks .
int motor1Pin1 = 5; // Ponte H
int motor1Pin2 = 6; // Ponte H
int motor2Pin1 = 10; // Ponte H
int motor2Pin2 = 11; // Ponte H
int ledPin1 = 13; // led indicator lights
int ledPin2 = 12;
int ledPin3 = 14;
int servo1 = 2; // r/c channel 1
int servo2 = 3; // r/c channel 2
//int servo3 = 7;
int power = 4; // power for R/C receiver, stays HIGH (5v).
//int relay_Pin = 8;
unsigned int relay_val;
volatile unsigned long servo1_startPulse; //values for channel 1 signal capture
volatile unsigned servo1_val;
volatile int adj_val1;
volatile int servo1_Ready;
volatile unsigned long servo2_startPulse; //values for channel 2 signal capture
volatile unsigned servo2_val;
volatile int adj_val2;
volatile int servo2_Ready;
int deadband_high = 275;
int deadband_low = 235;
int pwm_ceiling = 256;
int pwm_floor = 255;
int low1 = 1100; // adjust these values if your R/C readings are above or below these for channels 1 and 2.
int high1 = 1900;
int low2 = 1100;
int high2 = 1900;
int n = 0;
void setup() {
//TCCR0B = TCCR0B & 0b11111000 | 0x03;
//TCCR1B = TCCR1B & 0b11111000 | 0x01;
Serial.begin(9600);
//motor1 pins
pinMode(motor1Pin1, OUTPUT);
pinMode(motor1Pin2, OUTPUT);
pinMode(motor2Pin1, OUTPUT);
pinMode(motor2Pin2, OUTPUT);
//pinMode(relay_Pin, OUTPUT);
pinMode(power, OUTPUT);
//led's
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
//pinMode(ledPin3, OUTPUT);
//PPM inputs from RC receiver
pinMode(servo1, INPUT); //Pin 2 as input
pinMode(servo2, INPUT); //Pin 3 as input
//pinMode(servo3, INPUT); //Pin 3 as input
digitalWrite(power, HIGH);
//digitalWrite(relay_Pin, LOW);
delay(1200);
attachInterrupt(0, rc1_begin, RISING); // catch interrupt 0 (digital pin 2) going HIGH and send to rc1()
attachInterrupt(1, rc2_begin, RISING); // catch interrupt 1 (digital pin 3) going HIGH and send to rc2()
}
////////// attach servo signal interrupts to catch signals as they go HIGH then again as they go LOW, then calculate the pulse length.
void rc1_begin() { // enter rc1_begin when interrupt pin goes HIGH.
servo1_startPulse = micros(); // record microseconds() value as servo1_startPulse
detachInterrupt(0); // after recording the value, detach the interrupt from rc1_begin
attachInterrupt(0, rc1_end, FALLING); // re-attach the interrupt as rc1_end, so we can record the value when it goes low
}
void rc1_end() {
servo1_val = micros() - servo1_startPulse; // when interrupt pin goes LOW, record the total pulse length by subtracting previous start value from current micros() vlaue.
detachInterrupt(0); // detach and get ready to go HIGH again
attachInterrupt(0, rc1_begin, RISING);
}
void rc2_begin() {
servo2_startPulse = micros();
detachInterrupt(1);
attachInterrupt(1, rc2_end, FALLING);
}
void rc2_end() {
servo2_val = micros() - servo2_startPulse;
detachInterrupt(1);
attachInterrupt(1, rc2_begin, RISING);
}
/////// servo interrupts end
/////// MAIN LOOP
void loop() {
///// channel 1 bom sinal confirmado
if (servo1_val < 600 || servo1_val > 2400) { // only set the servo1_Ready flag if the value is a valid Servo pulse between 600-2400 microseconds.
servo1_Ready = false;
servo1_val = 1500;
}
else {
servo1_Ready = true; // se nao for os valor nao sao processados
}
///// channel 1 bom sinal confirmado
if (servo2_val < 600 || servo2_val > 2400) {
servo2_Ready = false;
servo2_val = 1500;
}
else {
servo2_Ready = true;
}
////////// channel 1
if (servo1_Ready) {
servo1_Ready = false;
adj_val1 = map(constrain(servo1_val, 600, 2400), low1, high1, 0, 511);
constrain(adj_val1, 0, 511);
if (adj_val1 < 0) {
adj_val1 = 0;
}
if (adj_val1 > 511) {
adj_val1 = 511;
}
if (adj_val1 > deadband_high) {
//Frente
digitalWrite(motor1Pin2,LOW);
digitalWrite(motor2Pin2, LOW);
analogWrite(motor1Pin1, adj_val1 - pwm_ceiling);
analogWrite(motor2Pin1, adj_val1 - pwm_ceiling);
digitalWrite(ledPin1, LOW);
}
else if (adj_val1 < deadband_low) {
//Marcha Atras
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor2Pin1, LOW);
analogWrite(motor1Pin2, pwm_floor - adj_val1);
analogWrite(motor2Pin2, pwm_floor - adj_val1);
digitalWrite(ledPin1, LOW);
}
else {
//parar
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor2Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin2, LOW);
digitalWrite(ledPin1, HIGH); // liga o led neutro e para o carro
}
}
///////////// channel 2
if (servo2_Ready) {
servo2_Ready = false;
adj_val2 = map(constrain(servo2_val, 600, 2400), low1, high1, 0, 511);
constrain(adj_val2, 0, 511);
if (adj_val2 < 0) {
adj_val2 = 0;
}
if (adj_val2 > 511) {
adj_val2 = 511;
}
if (adj_val2 > deadband_high) {
//curva
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1, LOW);
analogWrite(motor1Pin1, adj_val2 - pwm_ceiling);
analogWrite(motor2Pin2, adj_val2 - pwm_ceiling);
digitalWrite(ledPin2, LOW);
}
else if (adj_val2 < deadband_low) {
//curva
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor2Pin2, LOW);
analogWrite(motor1Pin2, pwm_floor - adj_val2);
analogWrite(motor2Pin1, pwm_floor - adj_val2);
digitalWrite(ledPin2, LOW);
}
else {
//parar
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1,LOW);
digitalWrite(motor2Pin2, LOW);
digitalWrite(ledPin2, HIGH); // liga o led de neutro e para o carro
}
}
//mostras as acçoes no Serial monitor do Arduino IDE
Serial.print("ch1: ");
Serial.print(adj_val1);
Serial.print(" ");
Serial.print("rc1: ");
Serial.print(servo1_val);
Serial.print(" ");
Serial.print("ch2: ");
Serial.print(adj_val2);
Serial.print(" ");
Serial.print("rc2: ");
Serial.print(servo2_val);
Serial.print(" ");
Serial.print("loop counter: ");
Serial.print(n);
Serial.println(" ");
//n++;
}
-
Primeiro, fazer isso do Rising e Falling separado é um enorme erro, usa interrupções que detectam o rising e o fall, ou seja CHANGE, assim só tens uma ISR e é muito mais bem feito assim.
-
eu nao percebi maior parte do codigo pois nao fui eu que o escrevi na totalidade sera que podias mostrar como e que se faz?
-
o meu problema e que so o codigo que fica no fim e que funciona ou seja neste caso o da direcção se eu meto o da direcçao em primeiro começa a funcionar o de avançar e o de marcha atras.
Qual sera o problema no codigo
Eu precisava de uma soluçao para poder prosseguir com o projecto
-
Provavelmente estás a usar as variaveis erradas, copy paste de funções e if's costuma dar nisso.
-
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor2Pin2, LOW);
Isto é sempre sempre low, logo qual o sentido de estar dentro dos if's quase todos, depois para que serve isso, não seria para controlar o sentido de rotação dos motores e tal?
-
o LOW e para manter o sinal desligado penso eu sera quae nao faz diferença se eu os apagar?
-
Eia, então tu fazes low's e logo a seguir pwm's?
E controlo de direção, é que só a dar pwm nos motores não os fazes andar para trás, ou são servos modificados, se forem é melhor usares a biblioteca servo.
-
nao eu quero usar motores de cadeira de rodas ligadas e uma ponte H daquelas que o xico desenhou
e eu faço LOW num pino e PWM noutroou seja ao mudar de pinos ou ando para tras ou para a frente
mas o meu problema e que apenas a codigo que fica em ultimo e que funciona ou seja o que fica escrito por cima desse e esquecido pelo arduino isto os led's respondem mas o PWM nao o que e que estara mal e que se eu movo um codigo de cima para o fim ele começa a funcionar mas o que estava a funcionar antes deixa de funcionar :o ???
-
Isso é por teres if's dentro de if's e provavelmente mau condicionamento das variaveis, agora estou meio cansado para ver isso com atenção.
-
ok hoje tambem nao vou fazer mais nada mas se amanha podes-ses dar uma vista de olho e descobrisses o problema ficava te muito grato
-
boas tardes pessoal eu ando aqui ainda com o problema do codigo sera que alguém me podia ajudar a ver o que e que esta mal?
eu perciso de ajuda rapido
-
Se estás a usar pwm e se o pwm no máximo é 255, para quê isto:
adj_val1 = map(constrain(servo1_val, 600, 2400), low1, high1, 0, 511);
constrain(adj_val1, 0, 511);
Estás a fazer map ao valor entre 0 e 511 e depois estás a fazer 255 ou 256 conforme calha menos esse valor, isso vai dar numeros negativos, aliás o 256 dependendo se o analogWrite usa signed ou unsigned vai ser interpretado como 0 ou -1....
Muda lá o map para 0,255 e usa os valores directos da variavel adj_val1 e faz o mesmo para o adj_val2 e tira essas subtrações todas que estás a fazer, possivelmente o problema são overflows e passares basicamente lixo para a função analogWrite.
-
como?
opah nao estou a perceber sera que podias exemplificar?
por favor
-
Isto:
adj_val1 = map(constrain(servo1_val, 600, 2400), low1, high1, 0, 511);
constrain(adj_val1, 0, 511);
Passa a isto:
adj_val1 = map(constrain(servo1_val, 600, 2400), low1, high1, 0, 255);
constrain(adj_val1, 0, 255);
Isto é para saltar fora que está a fazer precisamente o mesmo que a função constrain.....
if (adj_val2 < 0) {
adj_val2 = 0;
}
if (adj_val2 > 511) {
adj_val2 = 511;
}
E depois nestas linhas todas que tens:
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1, LOW);
analogWrite(motor1Pin1, adj_val2 - pwm_ceiling);
analogWrite(motor2Pin2, adj_val2 - pwm_ceiling);
digitalWrite(ledPin2, LOW);
fica só:
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1, LOW);
analogWrite(motor1Pin1, adj_val2);
analogWrite(motor2Pin2, adj_val2);
digitalWrite(ledPin2, LOW);
Repetes para o adj_val2 e o adj_val1 e alteras tudo e testas.
-
ok obrigado vou alterar agora e carregar para experimentar
-
int motor1Pin1 = 5; // Ponte H
int motor1Pin2 = 6; // Ponte H
int motor2Pin1 = 10; // Ponte H
int motor2Pin2 = 11; // Ponte H
int ledPin1 = 13; // led indicator lights
int ledPin2 = 12;
int ledPin3 = 14;
int servo1 = 2; // r/c channel 1
int servo2 = 3; // r/c channel 2
//int servo3 = 7;
int power = 4; // power for R/C receiver, stays HIGH (5v).
//int relay_Pin = 8;
unsigned int relay_val;
volatile unsigned long servo1_startPulse; //values for channel 1 signal capture
volatile unsigned servo1_val;
volatile int adj_val1;
volatile int servo1_Ready;
volatile unsigned long servo2_startPulse; //values for channel 2 signal capture
volatile unsigned servo2_val;
volatile int adj_val2;
volatile int servo2_Ready;
int deadband_high = 275;
int deadband_low = 235;
int pwm_ceiling = 256;
int pwm_floor = 255;
int low1 = 1100; // adjust these values if your R/C readings are above or below these for channels 1 and 2.
int high1 = 1900;
int low2 = 1100;
int high2 = 1900;
int n = 0;
void setup() {
//TCCR0B = TCCR0B & 0b11111000 | 0x03;
//TCCR1B = TCCR1B & 0b11111000 | 0x01;
Serial.begin(9600);
//motor1 pins
pinMode(motor1Pin1, OUTPUT);
pinMode(motor1Pin2, OUTPUT);
pinMode(motor2Pin1, OUTPUT);
pinMode(motor2Pin2, OUTPUT);
//pinMode(relay_Pin, OUTPUT);
pinMode(power, OUTPUT);
//led's
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
//pinMode(ledPin3, OUTPUT);
//PPM inputs from RC receiver
pinMode(servo1, INPUT); //Pin 2 as input
pinMode(servo2, INPUT); //Pin 3 as input
//pinMode(servo3, INPUT); //Pin 3 as input
digitalWrite(power, HIGH);
//digitalWrite(relay_Pin, LOW);
delay(1200);
attachInterrupt(0, rc1_begin, RISING); // catch interrupt 0 (digital pin 2) going HIGH and send to rc1()
attachInterrupt(1, rc2_begin, RISING); // catch interrupt 1 (digital pin 3) going HIGH and send to rc2()
}
////////// attach servo signal interrupts to catch signals as they go HIGH then again as they go LOW, then calculate the pulse length.
void rc1_begin() { // enter rc1_begin when interrupt pin goes HIGH.
servo1_startPulse = micros(); // record microseconds() value as servo1_startPulse
detachInterrupt(0); // after recording the value, detach the interrupt from rc1_begin
attachInterrupt(0, rc1_end, FALLING); // re-attach the interrupt as rc1_end, so we can record the value when it goes low
}
void rc1_end() {
servo1_val = micros() - servo1_startPulse; // when interrupt pin goes LOW, record the total pulse length by subtracting previous start value from current micros() vlaue.
detachInterrupt(0); // detach and get ready to go HIGH again
attachInterrupt(0, rc1_begin, RISING);
}
void rc2_begin() {
servo2_startPulse = micros();
detachInterrupt(1);
attachInterrupt(1, rc2_end, FALLING);
}
void rc2_end() {
servo2_val = micros() - servo2_startPulse;
detachInterrupt(1);
attachInterrupt(1, rc2_begin, RISING);
}
/////// servo interrupts end
/////// MAIN LOOP
void loop() {
///// channel 1 bom sinal confirmado
if (servo1_val < 600 || servo1_val > 2400) { // only set the servo1_Ready flag if the value is a valid Servo pulse between 600-2400 microseconds.
servo1_Ready = false;
servo1_val = 1500;
}
else {
servo1_Ready = true; // se nao for os valor nao sao processados
}
///// channel 1 bom sinal confirmado
if (servo2_val < 600 || servo2_val > 2400) {
servo2_Ready = false;
servo2_val = 1500;
}
else {
servo2_Ready = true;
}
if (servo2_Ready) {
servo2_Ready = false;
adj_val2 = map(constrain(servo2_val, 600, 2400), low1, high1, 0, 255);
constrain(adj_val2, 0, 255);
if (adj_val2 > deadband_high) {
//curva
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1, LOW);
analogWrite(motor1Pin1, adj_val2);
analogWrite(motor2Pin2, adj_val2);
digitalWrite(ledPin2, LOW);
}
else if (adj_val2 < deadband_low) {
//curva
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor2Pin2, LOW);
analogWrite(motor1Pin2, adj_val2);
analogWrite(motor2Pin1, adj_val2);
digitalWrite(ledPin2, LOW);
}
else {
//parar
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin1,LOW);
digitalWrite(motor2Pin2, LOW);
digitalWrite(ledPin2, HIGH); // liga o led de neutro e para o carro
}
}
if (servo1_Ready) {
servo1_Ready = false;
adj_val1 = map(constrain(servo1_val, 600, 2400), low1, high1, 0, 255);
constrain(adj_val1, 0, 255);
if (adj_val1 > deadband_high) {
//Frente
digitalWrite(motor1Pin2,LOW);
digitalWrite(motor2Pin2, LOW);
analogWrite(motor1Pin1, adj_val1);
analogWrite(motor2Pin1, adj_val1);
digitalWrite(ledPin1, LOW);
}
else if (adj_val1 < deadband_low) {
//Marcha Atras
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor2Pin1, LOW);
analogWrite(motor1Pin2, adj_val1);
analogWrite(motor2Pin2, adj_val1);
digitalWrite(ledPin1, LOW);
}
else {
//parar
digitalWrite(motor1Pin1, LOW);
digitalWrite(motor2Pin1, LOW);
digitalWrite(motor1Pin2, LOW);
digitalWrite(motor2Pin2, LOW);
digitalWrite(ledPin1, HIGH); // liga o led neutro e para o carro
}
}
//mostras as acçoes no Serial monitor do Arduino IDE
Serial.print("ch1: ");
Serial.print(adj_val1);
Serial.print(" ");
Serial.print("rc1: ");
Serial.print(servo1_val);
Serial.print(" ");
Serial.print("ch2: ");
Serial.print(adj_val2);
Serial.print(" ");
Serial.print("rc2: ");
Serial.print(servo2_val);
Serial.print(" ");
Serial.print("loop counter: ");
Serial.print(n);
Serial.println(" ");
//n++;
}
O codigo ficou assim mas agora nao funciona nada
-
Muda isto:
int deadband_high = 275;
int deadband_low = 235;
Para isto:
int deadband_high = 137;
int deadband_low = 117;
-
eu tirei o codigo do serial monitor e simplesmente começou tudo a funcionar
-
Mas altera o que te disse.
-
ok vou alterar agora