Envoyer & Recevoir des données sur le serial sans faire buger le programme.

Bonjour à tous,

J'aimerais envoyer des données via le serial sans le faire buger.

Je reçois des données de Processing, lesquelles me servent à contrôler la positon de plusieurs moteurs pas à pas.

Tous fonctionnent à merveille, sauf quand je decide d'envoyer des données sur le serial avec Serial.println.

Aussi, comme je lis les données de Processing peut-être qu'il y a un conflit avec l'envoie des données via le même serial.

Je me dis à l'instant que j'ai une Arduino Due, si je recevais les données de Processing avec le serial et que j'envoyais les données de l'Arduino sur l'autre port de la Due, est ce que cela fonctionnerait?

Où puise je rester sur la Uno?

Merci à vous. Mon code est dessous

//***********  Variable de Processing
int w0, w1, w2, w3, w4; // position à recevoir de la simulation Processing

#include <AccelStepper.h>

// Define a stepper and the pins it will use
#define NBMOTEURS 5

#define NBPASPARTOUR 200

// Define a stepper and the pins it will use
#define STEP 1//-->Mode pas complet

#define PINDIRECTION0  12
#define PINSPEED0  13

#define PINDIRECTION1  10
#define PINSPEED1  11

#define PINDIRECTION2  8
#define PINSPEED2  9

#define PINDIRECTION3  6
#define PINSPEED3  7

#define PINDIRECTION4  4
#define PINSPEED4  5

/*
const uint8_t PINDIRECTION[NBMOTEURS] =  {8, 12};
const uint8_t PINSPEED[NBMOTEURS] =  {9, 13};
*/
//int stepper[] = NBMOTEURS;
//AccelStepper stepper[i](STEP, PINSPEED0, PINDIRECTION0);  


AccelStepper stepper[ NBMOTEURS] = {
AccelStepper (STEP, PINSPEED0, PINDIRECTION0), 
AccelStepper (STEP, PINSPEED1, PINDIRECTION1), 
AccelStepper (STEP, PINSPEED2, PINDIRECTION2), 
AccelStepper (STEP, PINSPEED3, PINDIRECTION3), 
AccelStepper (STEP, PINSPEED4, PINDIRECTION4),  
};

#define ANALOG_IN A0

int analog_in;
int positionX;

void setup()
{  
    Serial.begin (115200);

    
  for(uint8_t i = 0; i < NBMOTEURS; i++) {      
  stepper[i].setMaxSpeed(500);
  stepper[i].setAcceleration(150);
   }
   /*
  stepper0.setMaxSpeed(100);
  stepper0.setAcceleration(20);
  stepper1.setMaxSpeed(100);
  stepper1.setAcceleration(20);
  stepper2.setMaxSpeed(100);
  stepper2.setAcceleration(20);
  */
   
}

void loop()
{ 
   
//  testStepMotors();
  
  receiveData(); // receive data from Processing
 

     for(uint8_t i = 0; i < NBMOTEURS; i++) {    

  stepper[i].setMaxSpeed(300);
  stepper[i].setAcceleration(150);

  stepper[4].moveTo(w4);
  stepper[3].moveTo(w3);
  stepper[2].moveTo(w2);
  stepper[1].moveTo(w1);
  stepper[0].moveTo(w0);

  stepper[i].run(); // beaucoup plus rapide
//  stepper[i].runSpeedToPosition(); // fonctionne dans les deux cazs
/*

      Serial.print ("A "); Serial.println (w4);     
      Serial.print ("B "); Serial.println (w3);        
      Serial.print ("C "); Serial.println (w2);  
      Serial.print ("D "); Serial.println (w1);
      Serial.print ("E "); Serial.println (w0);
    //  Serial.print ("F "); Serial.println (i-2);

    */
  }
}
void receiveData() {

  if (Serial.available() > 0) { 

    w0 = Serial.parseInt(); 
    w1 = Serial.parseInt(); 
    w2 = Serial.parseInt();
    w3 = Serial.parseInt();
    w4 = Serial.parseInt(); // La dernière donnée qui figure sur le serial de Processing arrive en premier sur Arduino

    Serial.read();

    } 
  }

Aussi, comme je lis les données de Processing peut-être qu'il y a un conflit avec l'envoie des données via le même serial.

Aucune chance que cela génère un conflit.
Sinon, il y a longtemps que personne n'utiliserait cette liaison.

Tous fonctionnent à merveille, sauf quand je decide d'envoyer des données sur le serial avec Serial.println.

Mais comme tu ne donnes pas plus d'infos sur les problèmes, difficile d'en dire plus.

Mes moteurs suivent tous bien ma simulation de Processing, mais dès que je rajoute dans la loop

      Serial.print ("A "); Serial.println (w4);     
      Serial.print ("B "); Serial.println (w3);        
      Serial.print ("C "); Serial.println (w2);  
      Serial.print ("D "); Serial.println (w1);
      Serial.print ("E "); Serial.println (w0);

Mes moteurs bougent quasi aléatoirement.

Je ne suis pas connaisseur en moteur PAP.
Probablement un rapport avec le temps d'exécution de Serial.print(), ou les interruptions que cela génère.
Avec un autre Serial, l'effet sera le même.

hbachetti:
Probablement un rapport avec le temps d'exécution de Serial.print(), ou les interruptions que cela génère.
Avec un autre Serial, l'effet sera le même.

J'ai déjà piloté des moteurs avec encodeurs et j'envoyais des serial.println et çà perturbait pas leur contrôle.

Pourquoi, si j'envoyais les serial.print sur l'autre port usb de l'Arduino Due, ça fonctionnerait pas?

Entre autres possibilités de problèmes avec les moteurs pap, je contrôle leur position via Processing et j'envoie une vitesse constante dans void loop comme ceci

stepper*.setMaxSpeed(300);*
_ stepper*.setAcceleration(150);_
quand je rajoute une ligne en dessous, ça tourne sans discontinué avec ou sans les Serial.println dans le void loop
_ stepper.setMaxSpeed(300);
stepper.setAcceleration(150);
stepper.setSpeed(250);*_

Il se peut que je me trompe dans la manière d'assigner la vitesse ou la position aux moteurs pap

J'ai déjà piloté des moteurs avec encodeurs et j'envoyais des serial.println et çà perturbait pas leur contrôle.

Je ne vois pas ce qui serait différent dans ce cas. Envoyer à processing ou à un terminal de change rien.

hbachetti:
Envoyer à processing ou à un terminal de change rien.

Je renvoie rien à Processing, je veux envoyer des infos différentes de celles de Processing à une autre logiciel, Max Msp, via le même serial port ou l'autre de l'Arduino Due, ça devrait marcher non?

Oui, ça devrait marcher, en utilisant une seule ligne série.

Je renvoie rien à Processing, je veux envoyer des infos différentes de celles de Processing à une autre logiciel, Max Msp, via le même serial port ou l'autre de l'Arduino Due, ça devrait marcher non?

Si tu disais tout dès le début on ne tournerait pas en rond.

Processing envoie des commandes à l'ARDUINO.
Un autre logiciel reçoit des infos de l'ARDUINO.

Donc cela fait deux lignes série. Tu n'as même pas le choix.
Une ligne série ne se partage pas.

biggil:
Oui, ça devrait marcher, en utilisant une seule ligne série.

Ok, mais c'est contradictoire avec hbachetti, j' essaye demain avec les deux port série de la Arduino Due.

hbachetti:
Si tu disais tout dès le début on ne tournerait pas en rond.

Processing envoie des commandes à l'ARDUINO.
Un autre logiciel reçoit des infos de l'ARDUINO.

Donc cela fait deux lignes série. Tu n'as même pas le choix.
Une ligne série ne se partage pas.

bvking:
Tous fonctionnent à merveille, sauf quand je decide d'envoyer des données sur le serial avec Serial.println.

Aussi, comme je lis les données de Processing peut-être qu'il y a un conflit avec l'envoie des données via le même serial.

Pardon, je pensais que c'était clair, désolé, donc on ne peut pas envoyer et recevoir via le même port. Merci

bvking:
Pardon, je pensais que c'était clair, désolé, donc on ne peut pas envoyer et recevoir via le même port

Mais si on peut. Bien sûr qu'on peut.

J'ai parlé un peu vite. hbachetti souligne que la difficulté (dont je n'ai pas tenu compte) est que à un bout de ligne (côté PC), il y a 2 processus qui veulent utiliser la même ligne.
L'un pour y écrire (Processing), l'autre pour y lire.
Il faut donc que 2 processus "ouvrent" le périphérique série en même temps.
J'ai fait un test très rapide sous macOS, c'est possible.
Pas testé sous Linux.

Techniquement, un processus peut-il réussir un open() sur un device déjà ouvert par un autre processus ?

biggil:
Mais si on peut. Bien sûr qu'on peut.
.
J'ai fait un test très rapide sous macOS, c'est possible.

Techniquement, un processus peut-il réussir un open() sur un device déjà ouvert par un autre processus ?

Je veux bien le test rapide, je suis sous mac osx aussi :wink:

J'ai fait un test très rapide sous macOS, c'est possible.

Tiens. Ce n'est pas courant, étonnant même.
Sous Linux : non.

hbachetti:
Donc cela fait deux lignes série. Tu n'as même pas le choix.
Une ligne série ne se partage pas.

Je viens de brancher mon système sur l'Arduino Due.
Maintenant, j'arrive à lire les données de Processing sur le port USB natif de la Due.

Sauf que maintenant quand je démarre mon programme, mes moteurs ne suivent plus du tout les données de Processing.

Je remets mon programme ci dessous, où l'on voit que j'ai juste ajouté le SerialUSB.print.
Je comprends pas du tout mon problème.

//***********  Variable de Processing
int w0, w1, w2, w3, w4; // vitesse à recevoir en nombre de pas /seconde

#include <AccelStepper.h>

// Define a stepper and the pins it will use
#define NBMOTEURS 5

#define NBPASPARTOUR 200 // Number of step

// Define a stepper and the pins it will use
#define STEP 1//-->Mode pas complet

#define PINDIRECTION0  12
#define PINSPEED0  13

#define PINDIRECTION1  10
#define PINSPEED1  11

#define PINDIRECTION2  8
#define PINSPEED2  9

#define PINDIRECTION3  6
#define PINSPEED3  7

#define PINDIRECTION4  4
#define PINSPEED4  5

/*
const uint8_t PINDIRECTION[NBMOTEURS] =  {8, 12};
const uint8_t PINSPEED[NBMOTEURS] =  {9, 13};
*/
//int stepper[] = NBMOTEURS;
//AccelStepper stepper[i](STEP, PINSPEED0, PINDIRECTION0);  


AccelStepper stepper[ NBMOTEURS] = {
AccelStepper (STEP, PINSPEED0, PINDIRECTION0), 
AccelStepper (STEP, PINSPEED1, PINDIRECTION1), 
AccelStepper (STEP, PINSPEED2, PINDIRECTION2), 
AccelStepper (STEP, PINSPEED3, PINDIRECTION3), 
AccelStepper (STEP, PINSPEED4, PINDIRECTION4),  
};

#define ANALOG_IN A0

int analog_in;
int positionX;

void setup()
{  
     pinMode(LED_BUILTIN, OUTPUT);
    Serial.begin (115200);
    SerialUSB.begin(115200);

    
  for(uint8_t i = 0; i < NBMOTEURS; i++) {      
  stepper[i].setMaxSpeed(500);
  stepper[i].setAcceleration(150);
   }
}

void loop() { 
 //testStepMotors();
   receiveData(); // receive data from Processing
     for(uint8_t i = 0; i < NBMOTEURS; i++) {    

  stepper[i].setMaxSpeed(300);
  stepper[i].setAcceleration(150);
  stepper[i].setSpeed(250);
  

  stepper[4].moveTo(w4);
  stepper[3].moveTo(w3);
  stepper[2].moveTo(w2);
  stepper[1].moveTo(w1);
  stepper[0].moveTo(w0); // premiere donnée envoyée dansla chaine de String de Processing = virtualPositon4

  stepper[i].run(); // beaucoup plus rapide

      SerialUSB.print ("A "); SerialUSB.println (w4);     
      SerialUSB.print ("B "); SerialUSB.println (w3);        
      SerialUSB.print ("C "); SerialUSB.println (w2);  
      SerialUSB.print ("D "); SerialUSB.println (w1);
      SerialUSB.print ("E "); SerialUSB.println (w0);
    //  Serial.print ("F "); Serial.println (i-2);
  }
}
void receiveData() {

  if (Serial.available() > 0) { // Ne pas redeclarer w1

    w0 = Serial.parseInt(); // FONCTIONNE AVEC SPEED0 dans Processing et le reste commenté dans Arduino
    w1 = Serial.parseInt(); 
    w2 = Serial.parseInt();
    w3 = Serial.parseInt();
    w4 = Serial.parseInt(); // La dernière donné qui figure sur le serial de Processing arrive en premier sur Arduino

    Serial.read();
    }
  }
void testStepMotors() {
  

    for(uint8_t i = 0; i < NBMOTEURS; i++) {      
     stepper[i].setCurrentPosition(0);
SerialUSB.println (stepper[0].currentPosition());
  // Run the motor forward at 400 steps/second until the motor reaches 600 steps (3 revolutions):
  while (stepper[i].currentPosition() != 400)  {
     
    stepper[i].setMaxSpeed(300);
    stepper[i].setSpeed(200);
    stepper[i].setAcceleration(150);
    stepper[i].runSpeed();  
}
 //delay(1);
  // Reset the position to 0:
  stepper[i].setCurrentPosition(0);
  // Run the motor backwards at 600 steps/second until the motor reaches -200 steps (1 revolution):
  while (stepper[i].currentPosition() != -400)   {
    stepper[i].setSpeed(-200);
    stepper[i].setAcceleration(1);
    stepper[i].run();
  // stepper[i].runSpeedToPosition(); /NE FONCTIONNE PAS
  }
  }
}

C'est ce que je disais en #3. Changer de port produit le même effet.

hbachetti:
Probablement un rapport avec le temps d'exécution de Serial.print(), ou les interruptions que cela génère.

J'en suis pas vraiment sûr, car maintenant sur la Due, même quand, je ne fais pas de Serial.print(), et que je n'imprime pas des données dans la void loop comme ceci

      SerialUSB.print ("A "); SerialUSB.println (w4);     
      SerialUSB.print ("B "); SerialUSB.println (w3);        
      SerialUSB.print ("C "); SerialUSB.println (w2);  
      SerialUSB.print ("D "); SerialUSB.println (w1);
      SerialUSB.print ("E "); SerialUSB.println (w0);

Mes moteurs tournent aléatoirement. Alors que la Uno, j'avais pas ce problème. La librairie stepper est elle bien là meme sur la Due?
Pourquoi le fait de lire les données depuis le Programming Port de la DUE et d'en écrire d'autres avec le Native USB Port ne serait pas possible? Puisque c'est deux ports USB différents, en quoi lire les données d'un port USB générait l'écriture sur un autre port USB. D'autant que j'arrive très bien à le faire. J'arrive à lire les données de Processing sur le moniteur série de l'Arduino IDE, mais les infos envoyés aux moteurs ne semblent pas bon.

bvking:
Je veux bien le test rapide, je suis sous mac osx aussi :wink:

Mon test ne fait rien qui puisse t'aider.
Mais si tu as déjà les deux programmes (Processing et l'autre, qui reçoit des octets), et si tu arrives à les lancer simultanément, c'est bon signe. A condition bien sûr qu'il travaillent tous les deux avec le même port série.
Si l'OS interdit à deux progs d'ouvrir le même port série, le second ne pourra pas démarrer.