Hola mi nombre es Oscar Bocchino soy ingeniero civil, vivo en italia, es mi primera vez en este forum.
Estoy aqui porque estoy desarrollando algunos proyectos relacionados con la electronica, la domotica y la robotica.
Ultimamente he estado desarrollando un pequeno "rovers" como prototipo en pocas palabras, un pequeno carrito telecomandado, cuenta con:
-
Cuatro (4) ruedas impulsadas por motores de 6v (4) a 280rpm alimentados por una bateria de 6v a 2400mAh.
-
Dos (2) controladores L298N por cada dos (2) ruedas. (aunque estoy pensando en conectar las cuatro a un solo controlador).
-
Un (1) modulo bluetooth 4.0 HM-10 programado en modo esclavo para la recepcion de datos.
-
Algunos otros sensores complementarios.
-Un (1) arduino MEGA 2560 alimentada por una bateria de 9v 850 mAh recargable. para procesar toda la informacion.
El control de comando consiste en:
- Un (1) arduino uno. alimentado por bat 9v 850mAh rec.
- Un (1) modulo Joystick
- Un (1) modulo bluetooth 4.0 HM-10, progrmado en modo maestro para la emision de datos.
La logica es simple y funciona bien.
El arduino uno lee los datos de Joystick y a traves del modulo bluetooth envia un paquete de datos arreglados en un array de 3 puestos, ya que son tres los datos que necesito por ahora.
la forma en la cual envio los datos tiene la siguiente forma
Serial.write(RVar,3);
Donde Rvar es un arreglo que contiene los tres parametros que quiero enviar.
Rvar[0] = Direccion (adelante, atras, izquierda, derecha, diagonales)
Rvar [1] = Valor analogico mapeado en direccion X
Rvar[2] = Valor analogico mapeado en direccion Y
como los valores analogicos van desde 0 a 1023 me conviene realizar el mapeado para obtener valores compatible a PWM es decir de 0 a 255. de esta forma mi receptor recibe los valores que necesito sin necesidad de aplicar mas codigo y mejorar asi la velocidad. ya que no quiero congestionar los tiempos de reaccion del rover.
por otro lado, el modulo bluetooth esclavo recibe los datos y los envia al arduino mega 2560 y desde alli proceso toda la informacion para controlar los movimientos.
con un un serial.println() veo en el monitor serial el valor y el orden de los datos que estoy recibiendo, esto es importante ya que de esta manera extraigo cada dato los cuales me serviran para establecer condicionales.
Mi problema empieza "aqui" en la recepcion de datos. Anteriormente enviaba los datos como cadenas tipo strings, luego recibia la cadena y la descomponia, para ese momento usaba los modulos bluetooth 2.0 HC-05, y la verdad la velocidad era precaria ademas la descomposicion de los parametros era perfecta pero tomaba su proceso, el resultado era un retardo de entre 4 y 6 segundo en el control de rovers para tomar direcciones y velocidad era algo que debia mejorar. asi que decidi por introducir el HM y simplificar el codigo al envio y recepcion por bytes. los resultados fueron satisfactorios y los tiempos se redujeron por debajo del segundo, yo diria que casi instantaneo. bueno al menos en un rango inferior a los 10 metros.
El problema que estoy presentando al recibir los datos, es que mi arreglo ya en el rover y entiendase en el arduino mega, los parametros me cambian de posicion esto es:
EL valor Rvar[0], Rvar[1] y Rvar[2] deben llegar en ese orden, pero no es asi, se intercambian de puesto, por lo que puedo tener el primer parametro en el puesto 2 o en el 1, y esto hace que no funcione correctamente mis condiciones y por lo tanto mi codigo, mi rovers se queda quieto.
el problema lo soluciono momentaneamente cuando desconecto los pines de RX y RY entre el arduino uno y el bluetooth, asi se vuelve todo como deberia, sin embargo cuando utilizo los sensores (como el sensor ultranosonico), todo se vuelve a distorsionar.
No entiendo por cual razon, los valores de mi arreglo se intercambian de puesto, nunca me habia pasado algo asi.
no se si sera que no es la forma correcta de programar este tipo de mecanismo, o sera por la velocidad de transmision ocurre interferencia, no entiendo el motivo de esta inestabilidad.
queria saber, que opciones tengo para programar mas eficazmente una recepcion y emision de datos que lleve almenos 3 parametros entre uno y el otro o si bien alguien entienda este problema y me ayude a mejorar el codigo.
adjunto el codigo.
Control - Arduino uno
//CODIGO MAESTRO
int xPin = A0;
int yPin = A1;
int RxVal;
int RyVal;
byte RVar[3] = {9,0,0}; // {1° Direccion, 2° Lectura en X, 3° Lectura en Y}
//String datos;
//int del = 8;
void setup() {
// put your setup code here, to run once:
Serial.begin(38400);
Serial.println("Inicializando sistema...");
delay(2500);
pinMode(xPin, INPUT);
pinMode(yPin, INPUT);
delay(2500);
Serial.println("Dispositivo Listo");
}
void loop() {
// put your main code here, to run repeatedly:
//LECTURA DE DATOS DESDE RESISTENCIA VARIABLE
RxVal = analogRead(xPin);
RyVal = analogRead(yPin);
//CONDICIONES PARA EL CONTROL JOYSTICK Y ENVIO DATOS AL MODULO BLUETOOTH HC-05
if (RyVal >= 520 && RxVal > 480 && RxVal < 520) { //AVANZAR
RVar[0] = 1;
RVar[1] = 0;
RVar[2] = map(RyVal, 520, 1023, 0, 255);
delay(5);
//Serial.write(RVar,3);
} else if (RyVal <= 480 && RxVal > 480 && RxVal < 520) { //RETROCEDER
RVar[0] = 2;
RVar[1] = 0;
RVar[2] = map(RyVal, 480, 0, 0, 255);
delay(5);
//Serial.write(RVar,3);
} else if (RxVal >= 520 && RyVal > 480 && RyVal < 520) { //GIRO IZQUIERDA
RVar[0] = 3;
RVar[1] = map(RxVal, 520, 1023, 0, 255);
RVar[2] = 0;
delay(5);
//Serial.write(RVar,3);
} else if (RxVal <= 480 && RyVal > 480 && RyVal < 520) { //GIRO DERECHA
RVar[0] = 4;
RVar[1] = map(RxVal, 480, 0, 0, 255);
RVar[2] = 0;
delay(5);
//Serial.write(RVar,3);
} else if (RxVal >= 520 && RyVal >= 520) { //ROTACION GRADUAL IZQUIERDA ADELANTE
RVar[0] = 5;
RVar[1] = map(RxVal, 520, 1023, 0, 255);
RVar[2] = 0;
delay(5);
//Serial.write(RVar,3);
} else if (RxVal >= 520 && RyVal < 480) { //ROTACION GRADUAL IZQUIERDA RETROCESO
RVar[0] = 6;
RVar[1] = map(RxVal, 520, 1023, 0, 255);
RVar[2] = 0;
delay(5);
//Serial.write(RVar,3);
} else if (RxVal <= 480 && RyVal >= 520) { //ROTACION GRADUAL DERECHA ADELANTE
RVar[0] = 7;
RVar[1] = map(RxVal, 480, 0, 0, 255);
RVar[2] = 0;
delay(5);
//Serial.write(RVar,3);
} else if (RxVal <= 480 && RyVal < 480) { //ROTACION GRADUAL DERECHA RETROCESO
RVar[0] = 8;
RVar[1] = map(RxVal, 480, 0, 0, 255);
RVar[2] = 0;
delay(5);
//Serial.write(RVar,3);
} else { //DETENER
RVar[0] = 9;
RVar[1] = 0;
RVar[2] = 0;
delay(5);
//Serial.write(RVar,3);
}
Serial.write(RVar,3);
//millis();
//Serial.println(datos);
//Leer informacion disponible en el Modulo y lo envia al arduno
//if (BT.available()){
//Serial.write(BT.read());
//}
//Lee Informacion disponible de Arduino y lo envia al Modulo
//if (Serial.available()){
//BT.write(Serial.read());
//}
}
Codigo esclavo - Arduino Mega 2560 - Rover
//CODIGO ESCLAVO
//Rotacion derecha
int IN1 = 23;
int IN2 = 22;
int ENA = 2;
int IN12 = 48;
int IN22 = 49;
int ENA2 = 3;
//Rotacion izquierda
int IN3 = 25;
int IN4 = 24;
int ENB = 8;
int IN32 = 46;
int IN42 = 47;
int ENB2 = 9;
//Variables de lectura analogica
int speedmotor; //Velocidad de ambos motores
int LSPM; //Velocidad motores izquierdo
int RSPM; //Vecocidad motores derecho
//Comando operacional movimiento
byte dato;
int Rx;
int Ry;
//Sensores
//Sensor Ultrasonico HC-SR04
int trig = 35;
int eco = 34;
int duracion;
float distancia;
//Zumbador Buzzer
int buzz = 29;
void Avanzar(int vy);
void Retroceder(int vy);
void Izquierda(int vx);
void Derecha(int vx);
void Izq_avanzar(int vx);
void Izq_retro(int vx);
void der_avanzar(int vx);
void der_retro(int vx);
void detener();
float distance();
void buzzer(float zx);
void DatosRecibidos();
//void zumb(float v);
byte InData[3] = { 9, 0, 0 };
void setup() {
// put your setup code here, to run once:
Serial1.begin(38400);
Serial.begin(38400);
Serial.println("Esperando comunicacion: ");
delay(2500);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(IN12, OUTPUT);
pinMode(IN22, OUTPUT);
pinMode(ENA2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(IN32, OUTPUT);
pinMode(IN42, OUTPUT);
pinMode(ENB2, OUTPUT);
pinMode(trig, OUTPUT);
pinMode(eco, INPUT);
pinMode(buzz, OUTPUT);
delay(1500);
}
void loop() {
DatosRecibidos();
delay(5);
distancia = distance();
buzzer(distancia);
if (InData[0] == 1) {
Avanzar(Ry);
} else if (dato == 2) {
Retroceder(Ry);
} else if (dato == 3) {
Izquierda(Rx);
} else if (dato == 4) {
Derecha(Rx);
} else if (dato == 5) {
Izq_avanzar(Rx);
} else if (dato == 6) {
Izq_retro(Rx);
} else if (dato == 7) {
der_avanzar(Rx);
} else if (dato == 8) {
der_retro(Rx);
} else {
detener();
}
//Lee Informacion disponible de Arduino y lo envia al Modulo
//if(Serial.available()){
//s = Serial.read();
//Serial1.print(s);
//}
}
//void separa(String comando) {
//int L_String = comando.length();
//for (int i = 0; i <= L_String; i++) {
//if (comando.charAt(i) == ',') {
//Pos_i[suma] = i;
//suma = suma + 1;
//}
//}
//String dir = comando.substring(0);
//String x = comando.substring(Pos_i[0] + 1, Pos_i[1]);
//String y = comando.substring(Pos_i[1] + 1, L_String);
//dato = dir.toInt();
//Rx = x.toInt();
//Ry = y.toInt();
//Serial.println(Rx);
//Pos_i[0] = 0;
//Pos_i[1] = 0;
//suma = 0;
//}
void DatosRecibidos(){
//Comunicacion Modulo HC-05 y Arduino
//Leer informacion disponible en el Modulo y lo envia al arduino
//Informacion de entra en el modulo bluetooth y se procesa en arduino
while (Serial1.available() > 0) {
//DECODIFICANDO
//Command = Serial1.readStringUntil('\n');
//Command = Command.substring(0, Command.length() - 1);
//Command = Serial1.read();
Serial1.readBytes(InData, 3);
Serial.println(String(InData[0]) + ',' + String(InData[1]) + ',' + String(InData[2]));
dato = InData[0];
Rx = InData[1];
Ry = InData[2];
}
}
float distance(){
digitalWrite(trig, HIGH);
delay(1);
digitalWrite(trig, LOW);
duracion = pulseIn(eco, HIGH);
return duracion / 58.2;
}
void buzzer(float zx){
if (zx <= 20 && zx >= 0){
digitalWrite(buzz, HIGH);
delay(zx * 10);
digitalWrite(buzz, LOW);
}
}
//AVANZAR
void Avanzar(int vy) {
//Control de velocidad
//speedmotor = map(vy, 520, 1023, 0, 255);
speedmotor = vy;
analogWrite(ENA, speedmotor);
analogWrite(ENB, speedmotor);
analogWrite(ENA2, speedmotor);
analogWrite(ENB2, speedmotor);
//Control de direccion
//Motor delantero izquierdo
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
//Motor delantero derecho
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
//Motor trasero derecho
digitalWrite(IN12, LOW);
digitalWrite(IN22, HIGH);
//Motor trasero izuierdo
digitalWrite(IN32, LOW);
digitalWrite(IN42, HIGH);
}
//RETROCEDER
void Retroceder(int vy) {
//speedmotor = map(vy, 480, 0, 0, 255);
speedmotor = vy;
analogWrite(ENA, speedmotor);
analogWrite(ENB, speedmotor);
analogWrite(ENA2, speedmotor);
analogWrite(ENB2, speedmotor);
//Motor delantero izquierdo
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
//Motor delantero derecho
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
//Motor trasero derecho
digitalWrite(IN12, HIGH);
digitalWrite(IN22, LOW);
//Motor trasero izuierdo
digitalWrite(IN32, HIGH);
digitalWrite(IN42, LOW);
}
//GIRO IZQUIERDA
void Izquierda(int vx) {
//Control de velocidad
//speedmotor = map(vx, 520, 1023, 0, 255);
speedmotor = vx;
analogWrite(ENA, speedmotor); //ENCENDIDO MOTOR DELANTERO DERECHO
analogWrite(ENB, speedmotor); //ENCENDIDO MOTOR DELANTERO IZQUIERDO
analogWrite(ENA2, speedmotor); //ENCENDIDO MOTOR TRASERO IZQUIERDO
analogWrite(ENB2, speedmotor); //ENCENDIDO MOTOR TRASERO DERECHO
//Control de direccion
//Motor delantero izquierdo
digitalWrite(IN3, HIGH); // Anti - Horario HIGH
digitalWrite(IN4, LOW); // Horario
//Motor trasero izquierdo
digitalWrite(IN12, HIGH); // Anti - Horario HIGH
digitalWrite(IN22, LOW); // Horario
//Motor delantero derecho
digitalWrite(IN1, LOW); //Giro Anti Horario
digitalWrite(IN2, HIGH); //Giro Horario
//Motor trasero derecho
digitalWrite(IN32, LOW); //Giro Anti Horario
digitalWrite(IN42, HIGH); //Giro Horario
}
//GIRO DERECHA
void Derecha(int vx) {
//Control de velocidad
//speedmotor = map(vx, 480, 0, 0, 255);
speedmotor = vx;
analogWrite(ENA, speedmotor); //ENCENDIDO MOTOR DELANTERO DERECHO
analogWrite(ENB, speedmotor); //ENCENDIDO MOTOR DELANTERO IZQUIERDO
analogWrite(ENA2, speedmotor); //ENCENDIDO MOTOR TRASERO IZQUIERDO
analogWrite(ENB2, speedmotor); //ENCENDIDO MOTOR TRASERO DERECHO
//Control de direccion
//Motor delantero izquierdo
digitalWrite(IN3, LOW); // Anti - Horario
digitalWrite(IN4, HIGH); // Horario HIGH
//Motor trasero izquierdo
digitalWrite(IN12, LOW); // Anti - Horario
digitalWrite(IN22, HIGH); // Horario HIGH
//Motor delantero derecho
digitalWrite(IN1, HIGH); //HIGH
digitalWrite(IN2, LOW);
//Motor trasero derecho
digitalWrite(IN32, HIGH); //HIGH
digitalWrite(IN42, LOW);
}
//ROTACION GRADUAL IZQUIERDA ADELANTE
void Izq_avanzar(int vx) {
//Control de velocidad
//LSPM = map(vx, 520, 1023, 0, 255);
LSPM = vx;
RSPM = 0.3 * LSPM;
analogWrite(ENA, LSPM);
analogWrite(ENB, RSPM);
analogWrite(ENA2, RSPM);
analogWrite(ENB2, LSPM);
//Control de direccion
//Motor delantero izquierdo
digitalWrite(IN3, LOW); // Anti - Horario
digitalWrite(IN4, HIGH); // Horario
//Motor trasero izquierdo
digitalWrite(IN12, LOW); // Anti - Horario
digitalWrite(IN22, HIGH); // Horario
//Motor delantero derecho
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
//Motor trasero derecho
digitalWrite(IN32, LOW);
digitalWrite(IN42, HIGH);
}
//ROTACION GRADUAL IZQUIERDA RETROCESO
void Izq_retro(int vx) {
//Control de velocidad
//LSPM = map(vx, 520, 1023, 0, 255);
LSPM = vx;
RSPM = 0.3 * LSPM;
analogWrite(ENA, LSPM);
analogWrite(ENB, RSPM);
analogWrite(ENA2, RSPM);
analogWrite(ENB2, LSPM);
//Control de direccion
//Motor delantero izquierdo
digitalWrite(IN3, HIGH); // Anti - Horario
digitalWrite(IN4, LOW); // Horario
//Motor trasero izquierdo
digitalWrite(IN12, HIGH); // Anti - Horario
digitalWrite(IN22, LOW); // Horario
//Motor delantero derecho
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
//Motor trasero derecho
digitalWrite(IN32, HIGH);
digitalWrite(IN42, LOW);
}
//GIRO GRADUAL DERECHA ADELANTE
void der_avanzar(int vx) {
//Control de velocidad
//LSPM = map(vx, 480, 0, 0, 255);
LSPM = vx;
RSPM = 0.3 * LSPM;
analogWrite(ENA, RSPM);
analogWrite(ENB, LSPM);
analogWrite(ENA2, LSPM);
analogWrite(ENB2, RSPM);
//Control de direccion
//Motor delantero izquierdo
digitalWrite(IN3, LOW); // Anti - Horario
digitalWrite(IN4, HIGH); // Horario
//Motor trasero izquierdo
digitalWrite(IN12, LOW); // Anti - Horario
digitalWrite(IN22, HIGH); // Horario
//Motor delantero derecho
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
//Motor trasero derecho
digitalWrite(IN32, LOW);
digitalWrite(IN42, HIGH);
}
//GIRO GRADUAL DERECHA RETROCESO
void der_retro(int vx) {
//Control de velocidad
//LSPM = map(vx, 480, 0, 0, 255);
LSPM = vx;
RSPM = 0.3 * LSPM;
analogWrite(ENA, RSPM);
analogWrite(ENB, LSPM);
analogWrite(ENA2, LSPM);
analogWrite(ENB2, RSPM);
//Control de direccion
//Motor delantero izquierdo
digitalWrite(IN3, HIGH); // Anti - Horario
digitalWrite(IN4, LOW); // Horario
//Motor trasero izquierdo
digitalWrite(IN12, HIGH); // Anti - Horario
digitalWrite(IN22, LOW); // Horario
//Motor delantero derecho
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
//Motor trasero derecho
digitalWrite(IN32, HIGH);
digitalWrite(IN42, LOW);
}
void detener() {
analogWrite(ENA, LOW);
analogWrite(ENB, LOW);
analogWrite(ENA2, LOW);
analogWrite(ENB2, LOW);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
digitalWrite(IN12, LOW);
digitalWrite(IN22, LOW);
digitalWrite(IN32, LOW);
digitalWrite(IN42, LOW);
}
Agradezco enormemente su ayuda como comunidad... estoy a disposicion tambien en compartir conocimientos. El codigo lo estoy mejorando constantemente.
