I have a Raspberry Pi with a web server where there is a joystick. I have programmed a python script that is responsible for translating the position of the joystick to the speed that the DC motors must have so that the car turns as indicated by the joystick. This is the script:
#! /usr/bin/python
import cgi, cgitb
import socket
cgitb.enable()
socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
form = cgi.FieldStorage()
x = float(form.getvalue('grados'))
y = float(form.getvalue('distancia'))
if 0 <= x and x <= 90:
derecha = int(round((y/100)*((2*x/90)-1)*255))
izquierda = int(round((y/100)*255))
print(derecha, izquierda)
sent = socket.sendto(str(derecha) + "5", ('127.0.0.1', 31113))
sent = socket.sendto(str(izquierda) + "6", ('127.0.0.1', 31113))
if 90 < x and x <= 180:
derecha = int(round((y/100)*255))
izquierda = int(round(((-2*(x-90)/90)+1)*255))
print(derecha, izquierda)
sent = socket.sendto(str(derecha) + "5", ('127.0.0.1', 31113))
sent = socket.sendto(str(izquierda) + "6", ('127.0.0.1', 31113))
if 180 < x and x <= 270:
derecha = int(round((y/100)*((-2*(x-180)/90)+1)*255))
izquierda = int(round((y/100)*-255))
print(derecha, izquierda)
sent = socket.sendto(str(derecha) + "5", ('127.0.0.1', 31113))
sent = socket.sendto(str(izquierda) + "6", ('127.0.0.1', 31113))
if 270 < x and x <= 270:
derecha = int(round((y/100)*-255))
izquierda = int(round((y/100)*((2*(x-270)/90)-1)*255))
print(derecha, izquierda)
sent = socket.sendto(str(derecha) + "5", ('127.0.0.1', 31113))
sent = socket.sendto(str(izquierda) + "6", ('127.0.0.1', 31113))
In the script I think there are no errors. It tells me a value between -255 or 255 that indicates the speed. The sign is responsible for indicating whether the wheels go forward or backward. Behind this number a 5 (right motor) or a 6 (left motor) was added to be able to differentiate them later in the Arduino.
I think the Arduino code is well written because if I send the data by hand, everything goes perfectly, but if the joystick does it, it doesn't go well. It is this (there are some things of some servos that I control with the same Arduino but it has nothing to do with it):
#include<Servo.h>
//Creamos los objetos servo
Servo servo;
Servo servo2;
Servo servo3;
Servo servo4;
int DV = 5;
int DA = 12;
int DR = 8;
int IV = 4;
int IA = 7;
int IR = 3;
int enviado; //Aqui enviamos el numero completo
int num; //Numero del servo
int posicion; //Posicion del servo
void setup()
{
//Inicializamos los Servos
servo.attach(9);
servo2.attach(10);
servo3.attach(11);
servo4.attach(6);
pinMode (DV, OUTPUT);
pinMode (DA, OUTPUT);
pinMode (DR, OUTPUT);
pinMode (IV, OUTPUT);
pinMode (IA, OUTPUT);
pinMode (IR, OUTPUT);
//Inicializamos la comunicacion por Serial
Serial.begin(9600);
}
void loop()
{
/*
1- Leer un numero entero por serial
2- Calculamos su modulo por 10 (sera el numero del motor)
3- Dividir el entero inicial por 10
4- Lo que quede, sera la posicion del motor
*/
enviado = Serial.parseInt();
num = enviado%10;
enviado = enviado/10;
posicion = enviado;
//Hora de mover los servos!
if(num == 1)
{
servo.write(posicion);
}
else if(num == 2)
{
servo2.write(posicion);
}
else if(num == 3)
{
servo3.write(posicion);
}
else if(num == 4)
{
servo4.write(posicion);
}
else if(num == 5 || num == -5)
{
if (posicion > 0)
{
digitalWrite(DA, HIGH);
digitalWrite(DR, LOW);
analogWrite(DV, posicion);
}
if (posicion == 0)
{
analogWrite(DV, 0);
}
if (posicion < 0)
{
digitalWrite(DA, LOW);
digitalWrite(DR, HIGH);
analogWrite(DV, abs(posicion));
}
}
else if(num == 6 || num == -6)
{
if (posicion > 0)
{
digitalWrite(IA, HIGH);
digitalWrite(IR, LOW);
analogWrite(IV, posicion);
}
if (posicion == 0)
{
analogWrite(IV, 0);
}
if (posicion < 0)
{
digitalWrite(IA, LOW);
digitalWrite(IR, HIGH);
analogWrite(IV,abs(posicion));
}
}
}
I think the error is that the motors have a delay when moving, so a queue is created and it does not move as it should. What I don't understand is why there is a delay when I haven't programmed it.
EDIT: Consigo makes the motor on the right move by sending the values apart, with the script they move randomly. The one on the left I can't control or send the values by hand or using the script with which it also moves randomly.
EDIT2: I have already solved the left motor. I thought it didn't make sense that it wasn't the one on the left and the one on the right was, and the problem is that the outputs were wrong.
It is very likely that you are suffering from the unwanted effect of sending entire data without any separator through the serial port.
Problem in interpreting the data
As you can see in the Serial.parseInt documentation :
Which means that:
What you are suffering from is the effect of continuously sending through the serial port integer data that cannot be differentiated from each other, so only when there is a pause of a second or more is the content of the integer parsed or you add a new negative sign, etc.
Example:
If you send the data "543" (move 54 to motor 3) and "1234" (move 123 to motor 4) in less than a second, the Arduino code will understand that you have sent "5431234" (move 543123 to motor 4).
That would explain why they move you in a seemingly random way. As you can see, "it has eaten" the movement of motor 3 and, however, a corrupt movement has arrived at motor 4.
Proposed solution
In the following code I add a ";" at the end of each number to force the analysis of the chain received by the serial port:
Good afternoon, try placing delay(1) for arduino stability.
If you can, make a dump of the received data.