Je viens vous demander de l'aide car je ne comprends pas pourquoi les informations transitent mal entre ordinateur et arduino :
Voici mon code python :
import serial
import time
# Configuration de la communication série
arduino_port = 'COM9' # Port série de l'Arduino
baud_rate = 9600
erreur = -60
# Créer un objet de communication série
ser = serial.Serial(arduino_port, baud_rate, timeout=1)
while True:
ser.write(str(erreur).encode())
time.sleep(2) # Attente d'une seconde avant la prochaine transmission
data = ser.readline() # Lire une ligne complète
erreur = erreur +10
print(erreur)
if data:
# Convertir les données reçues en une chaîne de caractères
received_data = data.decode('utf-8').strip()
# Afficher les données reçues dans la console
print("Données reçues de l'Arduino:", received_data)
# La boucle continuera à s'exécuter jusqu'à ce que vous l'arrêtiez manuellement
et mon code arduino
#include <Sabertooth.h>
Sabertooth ST(128, Serial3);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);; // USB vers PC
Serial3.begin(9600);
}
void loop() {
if (Serial.available() > 0) {
float erreur = Serial.parseFloat();
Serial.print(erreur) ;
if (-3<=erreur<=3){
marche_avant();
}
if (-360<erreur<-3){
tourne_gauche();
}
if (3<erreur<360){
tourne_droite();
}
}
}
Et voila les sorties...
-50
-40
Données reçues de l'Arduino: -50.00
-30
-20
Données reçues de l'Arduino: -40.00
-10
0
Données reçues de l'Arduino: -30.00
10
20
Données reçues de l'Arduino: -20.00
30
40
Données reçues de l'Arduino: -100102032.00
50
60
Données reçues de l'Arduino: 4050.00
70
80
Données reçues de l'Arduino: 6070.00
90
100
Données reçues de l'Arduino: 8090.00
110
120
Données reçues de l'Arduino: 100110.00
130
140
Au début ça fonctionne ...
Il y a de multiples erreurs dans le code arduino (pour le code python, je ne suis pas un expert mais il semble correcte) :
À ce niveau là il y a un ';' en trop, c'est même étonnant que ton code compile ?
Je ne connais pas l'utilité de cette fonction ? À quoi sert-elle ?
Tu ne peux pas faire de double tests de cette manière
Il FAUT remplacer cela par
if ( (erreur >= (-3)) && (erreur <= 3) )
J'ai pour habitude de mettre les nombres négatifs entre parenthèses, et les différentes "sous conditions" également ; mais en théorie elles ne sont pas nécessaire
Apporte les modifications et renvoie le code pour une autre verification stv
N'oublie pas de modifier les autres conditions "if" et de refaire un test
PS : Puisque ta variable erreur est de type float, elle ne sera jamais égale à 3 tout pile. Il faut donc faire attention pour les comparaisons ! (bien qu'ici ça semble ne pas poser de problème)
Il pourrait malgré tout être intéressant de savoir qu'elle est la sortie que tu aimerais avoir et nous dire à partir de quel moment celle que tu as réellement diverge de celle que tu souhaites
Également, à quoi sert le programme ? Quelle est l'utilité de la bibliothèque Sabertooth ?
Après modifications du code, ça à l'air de fonctionner @Anthony_P ! Merci
L'idée est de guider un robot qui suit un cap, l'erreur correspond à la correction du cap.
Par conséquent, lorsque l'erreur est :
==> négative il faut tourner à gauche
==> positive il faut tourner à droite
==> Acceptable c'est à dire comprise entre -3 et +3 on avance tout droit.
La bibliothèque Sabertooth est utilisée pour piloter le module Sabertooth 2x32 avec l'arduino Mega. Par exemple pour tourner à droite :
void tourne_droite()
{
int power;
for (power = 0; power >= -20; power --)
{
ST.motor(1, power);
ST.motor(2, -power);
delay(75);
}
}
Selon vous est il possible d'intégrer la variable erreur à la gestion des rotations?
Par exemple : lorsque la variable erreur est négative et se rapproche de 0 la rotation vers la gauche se réduit proportionnellement.
Avec mon code c'est "sacadé"
Je peux continuer à vous aider pour rendre progressif les changements de direction
Néanmoins, la raison pour laquelle vous êtes venu sur le forum semble résolue. Veuillez signaler que ce dernier est résolu en signalant le post qui vous a aidé
Pour vous aider (sans dire que j'y arriverai)
Pouvez vous mieux expliquer comment sont commandés les moteurs (transistor, relais, etc)
Quand ça tourne (à gauche par exemple), est-ce que les moteurs tournent actuellement en sens inverse ou seul l'un des deux tournes ?
Les deux moteurs tournent en sens inverse lorsqu'une rotation commence.
Il serait peut être préférable de faire tourner les deux roues dans le même sens pour que la rotation soit plus "douce" ? Je n'ai aucune expérience dans la gestion de moteurs...
Premièrement, pour faire une transition plus souple en "seulement" deux niveaux, vous pouvez, au lieu de faire tourner les moteurs dans des sens opposés, arrêter seulement l'un des deux moteurs de sorte à ce que ça tourne un peu moins "fort"
Ensuite, sur le site que vous avez donné il est écrit que la platine peut-être contrôle en "analog"
Pouvez vous confirmer que si vous mettez une tension moins élevée sur l'entrée des pins de commandes, alors les moteurs tournent moins vites ? Ou non ?
La solution qui correspond à mon utilisation est celle de la page 31 user mode avec "Packetized serial mode" avec cet exemple que m'a fourni le constructeur
// Sweep Sample for Packet Serial
// Copyright (c) 2012 Dimension Engineering LLC
// See license.txt for license details.
#include <Sabertooth.h>
Sabertooth ST(128, Serial3);// The Sabertooth is on address 128. We'll name its object ST.
// If you've set up your Sabertooth on a different address, of course change
// that here. For how to configure address, etc. see the DIP Switch Wizard for
// Sabertooth - http://www.dimensionengineering.com/datasheets/SabertoothDIPWizard/start.htm
// SyRen - http://www.dimensionengineering.com/datasheets/SyrenDIPWizard/start.htm
// Be sure to select Packetized Serial Mode for use with this library.
//
// On that note, you can use this library for SyRen just as easily.
// The diff-drive commands (drive, turn) do not work on a SyRen, of course, but it will respond correctly
// if you command motor 1 to do something (ST.motor(1, ...)), just like a Sabertooth.
//
// In this sample, hardware serial TX3 connects to S1.
// See the SoftwareSerial example in 3.Advanced for how to use other pins.
void setup()
{
Serial3.begin(9600);
}
void loop()
{
int power;
// Ramp motor 1 from -127 to 127 (full reverse to full forward),
// waiting 20 ms (1/50th of a second) per value.
for (power = -127; power <= 127; power ++)
{
ST1.motor(1, power);
delay(20);
}
// Now go back the way we came.
for (power = 127; power >= -127; power --)
{
ST1.motor(1, power); // Tip for SyRen users: Typing ST.motor(power) does the same thing as ST.motor(1, power).
delay(20); // Since SyRen doesn't have a motor 2, this alternative can save you typing.
}
}
Finalement je peine à créer à adapter ce code à mon utilisation : toujours orienter/faire avancer le robot en fonction de l'erreur.
Ce qui veut dire que vous échanger avec le module via la liaison série alors ?
Si vous utilisez le code que vous venez de me donner, que fait le moteur ? Il accélère dans un sens puis dans l'autre ? Ou sa vitesse est constante et il change seulement de sens ?
Ok donc puisque qu'on sait faire accélérer le moteur progressivement, cela veut dire que l'on peut le faire tourner à des vitesses différentes en fonction des paramètres de nos choix
Ainsi, ce que vous pouvez faire, c'est faire varier la valeur de power selon la valeur de l'erreur
De ce que j'ai compris, plus power est proche de -127, plus le moteur tourne vite en marche arrière et idem mais en marche avant lorsque que power = 127
Vous pouvez alors, affecté une valeur à power de plus en plus extrême en fonction de la valeur de l'erreur que vous récupérez.
Exemple : si erreur vaut -360, alors on veut tourner fort vers la gauche
Dans ce cas, on va peut-être faire tourner la roue droite à fond (powerD = 127) et la roue gauche à fond mais dans le sens opposé (powerG = -127)
Essayer de passer la valeur de 'erreur' en paramètre de vos fonctions pour tourner et tentez ceci :
void tourne_droite(float erreur)
{
int power = int(erreur);
power = abs(power);
power = map(power, 0, 360, 0, 254);
power = power - 127;
ST.motor(1, power);
ST.motor(2, -power);
}
Veuillez bien vérifier que la fonction "tourner_droite" tourne bien à droite et pas à gauche ; sinon inversez dans le code power et -power lors de la commande des motor
Modifiez aussi la fonction pour tourner à gauche avec le même principe.
Je viens de tester le code il fonctionne !
En revanche, la vitesse est rapide lorsque l'erreur est faible, et lorsque l'erreur est forte le moteur ralenti.
Je ne comprends pas non plus cette sortie dans python :
Données reçues de l'Arduino: -10.00
10
Données reçues de l'Arduino: 0.00
20
30
Données reçues de l'Arduino: 1020.00
40
Données reçues de l'Arduino: 30.00
50
Données reçues de l'Arduino: 40.00
Content d'avoir enfin de vos nouvelles haha !
Si la vitesse réagie inversement à l'erreur, alors il faut changer cette ligne :
power = map(power, 0, 360, 0, 254);
Ici, lorsque l'erreur était de 360, alors power valait 254 ; et 0 si l'erreur valait 0. Il faut semble-t-il faire l'inverse :
power = map(power, 0, 360, 254, 0);
Pensez à changer ça dans toutes les fonctions concernées !
Juste au cas où, avez-vous compris pourquoi j'ai pris 254 comme valeur ?
Lorsque vous postez des lignes de codes ou de retour de moniteur, utilisez les balises de code SVP pour que ce soit plus lisible !
Et d'ailleurs utilisez-les pour me partager tout votre code (python et arduino dans des balises différentes évidemment) pour que j'essaie de comprendre d'où vient le 1020.00
ça fonctionne parfaitement pour la gestion des moteurs ! Merci
Le 254 devrait correspondre au nombre maximal des impulsions pour le moteur?
J'ai poursuivis avec l'ajout d'une boussole CMPS14 sur l'Arduino Mega, celle-ci me renvoi une valeur qui est bonne, après traitement de cette valeur, je la renvoie sous un autre nom de variable à Arduino mais la problème Arduino ne reçoit pas la bonne valeur. Savez-vous s'il est possible de communiquer dans les deux sens? Ou dois je brancher différemment ma boussole numérique ?
Puisque les valeurs vont de -127 à 127, alors je convertie la valeur de 0 à 254 (donc 2 * 127) puis je retranche 127 pour que si la valeur est 0 (donc tourner complètement en sens opposé), on ait -127.
Si la valeur de la boussole est déstinée uniquement à l'arudino, alors la logique serait de la connecter sur l'Arduino (bien que je ne sais pas comment elle communique)
Quoi qu'il en soit, je ne suis pas un spécialiste mais je suis quasi certain (99%) que la communication se fait dans les deux sens car j'ai déjà utilisé python pour envoyer des données à travers un port série (port COM donc)