Bienvenido a un nuevo blog de nuestra serie sobre Coches Robot. Esta vez se trata de determinar la distancia recorrida con la ayuda del número de revoluciones de las ruedas. Este método se denomina odometría. Eso proviene del griego y significa la medición de la distancia.
Para conducir en línea recta, esto es bastante sencillo. Si ambas ruedas giran a la misma velocidad, la distancia recorrida tras una revolución es igual a la circunferencia de la rueda, es decir, con diámetro d
Las revoluciones se pueden determinar con un disco ranurado y un sensor fotoeléctrico en forma de horquilla. Si el disco de la ranura tiene n ranuras, obtendremos n impulsos por revolución. Para determinar la distancia entre dos pulsos, debemos dividir la circunferencia entre los pulsos por revolución. Obtenemos el factor distancia.
Además, la determinación del ángulo de giro también es sencilla para un vehículo de dos ruedas si se supone que ambas ruedas giran en sentidos opuestos a la misma velocidad. En este caso, ambas ruedas describen un círculo alrededor del punto de vista invariable con la distancia de la rueda a como diámetro. Para girar el vehículo en 360 grados, se necesita una distancia de
puede ser cubierto. Para un ángulo α se obtiene una distancia de
Ambas ruedas recorren la misma distancia, pero en direcciones opuestas. Para obtener el número de pulsos, hay que dividir por el factor de distancia.
El recíproco da como resultado el factor angular en grados / pulso
Hardware requerido
A diferencia de la primera parte, en este caso necesitamos el módulo ESP32, porque se necesitan entradas adicionales para las barreras de la luz de la horquilla. También es mejor utilizar el chasis de la impresora 3D, ya que así es mucho más fácil montar las barreras de luz de la horquilla.
Número |
Componente |
Nota |
1 |
|
|
1 |
|
|
6 |
Tornillos m3 x 30 con madre |
|
2 |
Tornillos m3 x 12 con madre |
|
1 |
Chasis de la impresora 3D |
|
1 |
Titular de PowerPack de la impresora 3D |
|
1 |
|
|
1 |
|
|
2 |
Tornillos de estaño 2.2 x 6,5 mm. |
|
Para utilizar el escudo del controlador del motor con los controladores ESP, son necesarias pequeñas modificaciones, ya que los controladores ESP funcionan con un voltaje de funcionamiento de 3,3V.
Desde el pin D7 se debe conectar una resistencia de 10 kOhm a GND. Esto es necesario porque el pin D7 de la pantalla está conectado a 5V a través de una resistencia de pullup de 10 kOhm.
Las conexiones A0 a A5, así como las conexiones de alimentación correspondientes, deben estar equipadas con cabezales de pines. Para que estas conexiones se usen para los sensores, el voltaje de alimentación también debe conectarse en lugar de 5V a 3.3 V. Esto se hace simplemente cortando el cable de conexión a los pines de la parte inferiores. Entonces, puede conectar los pines al pin de 3,3V. Las conexiones para el voltaje de alimentación también deben estar equipadas.
Para conectar los dos motores se utilizan las salidas M2 y M4. Las conexiones del motor se conectan a los terminales de tornillo correspondientes en el escudo del motor. Si el vehículo se suministra a través de la toma USB del microcontrolador, el puente (círculo rojo) se debe retirar y conectar la entrada M + a la conexión de 5V del microcontrolador (se muestra en verde en la figura).
Para la medición de la velocidad de rotación, se coloca una arandela de ranura en el extremo interno de cada eje del motor y se atornillan las barreras luminosas en forma de horquilla al soporte previsto para ello con un tornillo autorroscante.
Ahora conecta VCC, GND y D0 mediante un cable tripolar a las conexiones A2 y A3 del escudo del motor. VCC con + 5V, GND con GND y D0 con A2 o A3.
A continuación, el escudo motor se conecta simplemente a la placa del microcontrolador. No son necesarias más medidas de cableado.
Para la fijación mecánica de las placas, el chasis de la impresora 3D tiene los agujeros correspondientes, a los que se puede atornillar la placa del microcontrolador con espaciadores. Con el kit es posible que tenga que perforar agujeros adecuados.
Software
Para el control remoto del vehículo, se debe utilizar el software gratuito disponible Blynk. Blynk es un proyecto de Kickstarter que permite el control más simple de los microcontroladores con un teléfono inteligente. Elemento esencial es la aplicación con la que se puede crear una aplicación a través de un tipo de kit de construcción. Toda la información sobre esta aplicación se almacena en el servidor Blynk. Cada aplicación recibe un número de identificación único. En el lado del microcontrolador, una librería garantiza que el microcontrolador se comunique con el servidor Blynk y que la aplicación en el teléfono inteligente pueda leer o controlar directamente los pines del microcontrolador. No se requiere más programación en el microcontrolador. La única condición es que el microcontrolador debe tener acceso al servidor Blynk. Dado que no se puede controlar los pines del microcontrolador directamente para el control remoto del vehículo, será necesaria una pequeña programación.
Primero, sin embargo, la aplicación Blynk debe estar instalada en el teléfono inteligente. Después de que la aplicación se haya instalado y comience, aparece la pantalla de inicio de sesión. Para usar Blynk, necesita una cuenta para el servidor Blynk. Esto requiere solo una dirección de correo electrónico y cualquier contraseña.
Después de crear una cuenta, aparece un mensaje sobre la energía. Para crear un proyecto Blynk, necesita una cierta cantidad de energía para cada elemento de pantalla. Con una nueva cuenta, obtendrá automáticamente 2000 puntos de alimentación con los que puede trabajar. Si necesita más puntos de energía para un proyecto, puede comprarlos.
Después de esta ventana de mensajes, aparece la pantalla de inicio. Aquí, el proyecto Coche robot ahora se puede cargar a través del siguiente código QR.
Ahora veas la ventana del proyecto. Si hace clic en el símbolo de la tuerca, se abre la configuración del proyecto. En la configuración del proyecto encontrará el enlace "Email all". Cuando hace clic en él, recibirá un correo electrónico con la clave de que su microcontrolador necesita sketch para comunicarse con el servidor Blynk. Con el icono del triángulo en la ventana del proyecto en la parte superior derecha, inicia la aplicación.
Más información sobre Blynk, se puede encontrar en Internet o en Libro Smarthome. El libro también describe cómo instalar su propio servidor privado Blynk en un Raspberry Pi.
El control se realiza configurando la ruta deseada y el ángulo deseado. Al hacer clic en los botones hacia adelante o hacia atrás, el vehículo recorre la distancia establecida. Al hacer clic en los botones de la izquierda o hacia la derecha, el vehículo gira en el ángulo establecido.
Si hace clic en el botón Aprender, luego cambia al modo de aprendizaje. Cada comando ingresado ahora está grabado y se puede realizar automáticamente más tarde. Recientemente, haga clic en el botón Aprender, finaliza el modo de aprendizaje. Ahora puede ejecutar automáticamente los comandos almacenados haciendo clic en el botón Ejecutar.
En la parte inferior, se muestra tantas líneas de comando se almacenaron. Se pueden almacenar un máximo de 30 líneas de comando. Al cambiar al modo de aprendizaje, el contador de la línea de comandos se restablece a 0.
El Sketch
Además del paquete ESP32, necesita la librería Blynk que se puede instalar a través de la administración de la librería.
// Debe obtener un token de autenticación en la aplicación Blynk. // Ir a la configuración del proyecto (icono de tuerca).
// Tecla de autenticación de Blynk
// ssid de tu wlan
// Passkey para tu WLAN
// Nombre del servidor privado Blynk, o "" Si usa el servidor público de Blynk
// anzahl der befehlszeileilen, die gespeichert werden können
// bits im schieberegister zu motor zuordnung
// motor1 a
// motor1 b
// motor2 a
// motor2 b
// motor3 a
// motor3 b
// motor4 a
// motor4 b
// pins für das drehrichtungs schieberegister
// Dateneingang Arduino D8
// schiebetackt arduino d4
// Speichertakt Arduino D12
// MIT Low Ausgang Aktivieren Arduino D7
// pwm für motoren geschwindigkeit zwischen 0 und 1023
// Pin Für Motor1 Arduino D11
// Pin Für Motor2 Arduino D3
// Pin Für Motor3 Arduino D6
// PIN FUR MOTOR4 Arduino D5
// servo anschlüsse
// PIN FÜR SERVO1 D10
// PIN FUR SERVO2 D9
// motor zuordnung
// konstanten für drehrichtung
// Aktueller Inhalt des Richtungs-SchieBereGisters
uint32_t direcciones = 0;
Typedef
estructura {
carbonizarse cmd;
uint16_t Val;
} Cmdline;
Cmdline comandos[Maxcommands];
uint8_t cmdcnt = 0;
int32_t cn s = 0;
int32_t centa = 0;
uint16_t strecke = 0;
uint16_t winkel = 0;
booleano botón = 0;
flotador winkelfaktor, streckenfaktor;
booleano aprendiendo = falso;
booleano programa = falso;
uint8_t PRGSTEP;
// für interrumpir la sincronización
PORTMUX_TYPE izquierdmux = Portmux_Initializer_Unlocked;
PORTMUX_TYPE RightMux = Portmux_Initializer_Unlocked;
// Rutina de servicio de interrupción Für Enlay SpeedSensor
vacío Iram_attr isrilla() {
PORTENTER_CRÍTICO(&izquierdmux);
cn s--;
Portexit_crítico(&izquierdmux);
Si ((cn s <= 0) && (centa<=0)) {
motores(0,0);
Si (programa) próximo paso();
}
}
// Rutina de servicio de interrupción Für Rechen SpeedSensor
vacío Iram_attr isrright() {
PORTENTER_CRÍTICO(&RightMux);
centa--;
Portexit_crítico(&RightMux);
Si ((cn s <= 0) && (centa<=0)) {
motores(0,0);
Si (programa) próximo paso();
}
}
// füllt das schieberegister zur motoresteuerung
// mit dem Inhalt von direcciones
vacío Senddirections() {
uint8_t I;
escritura digital(Latch_clk, BAJO); // SPEICHER SPERREN
escritura digital(DESPLAZAR EN, BAJO); // eingang auf 0
por (I=0; I<8; I++) {
escritura digital(Shift_clk, BAJO);// bit für bit einlesen
Si (direcciones & un poco(7-I)) {
escritura digital(DESPLAZAR EN, ELEVADO);
} demás {
escritura digital(DESPLAZAR EN, BAJO);
}
escritura digital(Shift_clk, ELEVADO);
}
escritura digital(Latch_clk, ELEVADO); // mit der positiven flanke speichern
}
vacío próximo paso() {
Si (PRGSTEP < cmdcnt) {
cambiar (comandos[PRGSTEP].cmd) {
caso 'F' :
caso 'B' : manejar(comandos[PRGSTEP].cmd,comandos[PRGSTEP].Val);
rotura;
caso 'L' :
caso 'R' : turno(comandos[PRGSTEP].cmd,comandos[PRGSTEP].Val);
rotura;
}
PRGSTEP++;
} demás {
programa = falso;
}
}
// die drehrichtung für einen motor festplegen
vacío SetDirección(uint8_t motor, uint8_t dirección) {
uint8_t a=0, B=0;
// Bitnummern Für Den Gewählten Motor Bestimmen
cambiar (motor) {
caso 1: a=M1A; B=M1b; rotura;
caso 2: a=M2a; B=M2b; rotura;
caso 3: a=M3A; B=M3b; rotura;
caso 4: a=M4A; B=M4b; rotura;
}
// Primero ponga ambos bits para el motor a 0 significa parada
Direcciones &= ~ un poco(a) & ~ un poco(B);
cambiar (dirección) {
cubo Hacia adelante: Direcciones |= un poco(a); rotura; // para el bit hacia adelante de A a 1
cubo Hacia atrás: Direcciones |= un poco(B); rotura;// para bit b hacia atrás b en 1
}
//Serial.printf ("direcciones =% x \ n", direcciones);
Senddirections(); // enviar nueva configuración al registro de desplazamiento
}
//Velocidad
En t Z;
vacío motor(Int16_t izquierda, Int16_t Derecha) {
//Serial.printf( "Links% I, Derecho% I \ N ", izquierda, derecha);
//Dirección
SI (izquierda<0) {
SetDirección(Diario,Hacia atrás);
} Demás SI (izquierda == 0){
SetDirección(Diario,DETENER);
} Demás {
SetDirección(Diario,Hacia adelante);
}
SI (Derecha<0) {
SetDirección(Drick,Hacia atrás);
} Demás SI (Derecha == 0){
SetDirección(Drick,DETENER);
} Demás {
SetDirección(Drick,Hacia adelante);
}
//Velocidad
Ledcwrite(Diario,Sección(izquierda));
Ledcwrite(Drick,Sección(Derecha));
}
vacío manejar(Carbonizarse dirección, uint16_t Val) {
SI (aprendiendo) {
SI (Cmdcnt < Maxcommands) {
comandos[Cmdcnt].Cmd = dirección;
comandos[Cmdcnt].Val = Val;
Cmdcnt++;
}
} Demás {
cn s = Val;
centa = Val;
SI (dirección == 'F') {
motor(Z,Z);
} Demás {
motor(-Z,-Z);
}
}
}
vacío turno(Carbonizarse dirección, uint16_t Val) {
SI (aprendiendo) {
SI (Cmdcnt < Maxcommands) {
comandos[Cmdcnt].Cmd = dirección;
comandos[Cmdcnt].Val = Val;
Cmdcnt++;
}
} Demás {
cn s = Val;
centa = Val;
SI (dirección == "L ') {
motor(-Z,Z);
} Demás {
motor(Z,-Z);
}
}
}
vacío configurar() {
De serie.Empezar(115200);
De serie.Prender();
De serie.Prender("Inicialización");
// Poner todos los pasadores utilizados como salida
mono(Desplazar en,PRODUCCIÓN);
mono(Shift_clk,PRODUCCIÓN);
mono(Latch_clk,PRODUCCIÓN);
mono(OUT_ENABLE,PRODUCCIÓN);
Ledcsetup(Diario, 100, 10);
Ledcsetup(Drick,100, 10);
ledcattachpin(Melancólico,Diario);
ledcattachpin(Mright,Drick);
// Todos los motores paran
Direcciones = 0;
// calcular los parámetros de odometría
// Factor de estiramiento = Diámetro de la rueda * pi / number_schlitze
factor estirado = 67 * 3.14 /20; // = 10.524 mm / pulso
// factor de ángulo = 360 grados / (distancia del eje * pi) * Factor de estiramiento
factor de ángulo = (360 * 67)/(130 * 20); // = 9,277 grado / pulso
Senddirections(); // enviar al cambio de registro
escritura digital(OUT_ENABLE,0); // Salidas de liberación del registro de turnos
Z=1023;
mono(Time,Aporte);
mono(SpeedRight,Aporte);
cn s=0;
centa=0;
Ruptura de adjuntos(Time,Isrilla,Descendente);
Ruptura de adjuntos(SpeedRight,Isrright,Descendente);
De serie.Prender("Iniciar Blynk");
Blenk.Empezar(Auténtico, Ssid, PASAPORTE, Srv, 8080);
Blenk.Empezar(Auténtico, Ssid, PASAPORTE);
botón = 0;
}
// bucle de prueba pequeño
vacío círculo() {
Blenk.correr();
}
Blynk_write(V0)
{ ruta = param[0].asine(); }
Blynk_write(V1)
{ ángulo = param[0].asine(); }
Blynk_write(V2)
{ SI (param[0].asine() == 0) {
botón = falso;
} Demás {
SI (!botón) {
botón = cierto;
manejar('F',ruta / factor estirado);
}
}
}
Blynk_write(V3)
{ SI (param[0].asine() == 0) {
botón = falso;
} Demás {
SI (!botón) {
botón = cierto;
manejar("B ',ruta /factor estirado);
}
}
}
Blynk_write(V4)
{ SI (param[0].asine() == 0) {
botón = falso;
} Demás {
SI (!botón) {
botón = cierto;
turno("L ',ángulo / factor de ángulo);
}
}
}
Blynk_write(V5)
{ SI (param[0].asine() == 0) {
botón = falso;
} Demás {
SI (!botón) {
botón = cierto;
turno("R ',ángulo /factor de ángulo);
}
}
}
Blynk_write(V6)
{
SI (!aprendiendo) {
PRGSTEP=0;
programa = cierto;
Próximo paso();
}
}
Blynk_write(V7)
{
aprendiendo = (param[0].asine() != 0);
SI (aprendiendo) Cmdcnt = 0;
}
Blynk_read(V8)
{
Blenk.lejano virtual(V8,Cmdcnt);
}
2 comentarios
Gerald Lechner
Wenn in Zeile 72 und 73 die Strecke auf 300 und der Winkel auf 90 voreingestellt werden, dann stimmen die Werte nach dem Start mit den Schiebern in der Blynk-App überein. Das Problem mit der Verbindung kommt daher, dass das Board eine relativ schlechte Wlan Empfindlichkeit hat
Walter
Sehr schönes Projekt, und einfacher als erst gedacht. Vor allem die Odometrie ist so ein Kinderspiel.
Umgesetzt mit ein ESP32 Dev Board, motordriver L289N und lokalen Blynkserver.
Ein offenes Problem ist, dass der Blynkserver keine initiale Werte gibt ( oder ich nicht weis wie ). Was bedeutet das erst die Schieber für Distanz und Winkel betätigt werden müssen, sonst ist der Wert der den man im Programm festlegt ( = 0 und dann passiert nichts ).
Der Blynkserver ist für mich sowie so eine Blackbox, wobei manchmal keine Verbindung zu Stande kommt, scheinbar ohne Ursache. Nach einigen Reboots funktioniert es dann auf einmal .