Arduino Direct Control

Bonjour tous,j'ai une question pour vour.Je suis en train de construire une Desktop CNC a partir de 3 imprimantes jet d'encre (reste pas grand chose des imprimantes en fait) et j'suis en train de monter un programme en VB pour gerer la cnc et la question est:

Comment je fait pour que dans le loop du arduino il attende une ligne de code qui arriverais d emon programme ??

Ex:

J'utilise le Motor shield de ladyada;;

#include <AFMotor.h>


AF_Stepper motor(48, 2);


void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Stepper test!");

  motor.setSpeed(10);  // 10 rpm   

  motor.step(100, FORWARD, SINGLE); 
  motor.release();
  delay(1000);
}

void loop() {
  motor.step(100, FORWARD, SINGLE); 
  motor.step(100, BACKWARD, SINGLE); 
}

s'arranger pour que le programme envoi qlque chose genre exactement ca

motor.step(100, FORWARD, SINGLE);

et que arduino l'utilise sans poser de question??

J'ai penser a;
envoyer un chiffre indiquant le nombre de steps et par une formule mathématique déterminer dans quel sens aller MAIS...ca gere qun stepper.

J'ai penser intégrer les différentes commandes dans arduino et les activer en sendant un ASCI mais ca limite la chose aux incréments déterminés

Ce que je vise comme but final ;

Un programme qui le controle;plus précisement une console dans laquelle on peut tapper x+500 et laxe x fait 500 steps,apres on met y-23 et etc.

des suggestions?
merci

Tu peux regarder comment celui-ci a fait, c'est en java :

slice & dice

deja vu et pas tres fameux =\

Je ne dis pas qu'il est fameux... ou pas, mais c'est un point de départ et ça reste toujours intéressant de voir comment d'autres ont pensé faire ce que tu veux faire.

Je trouve intéressant par exemple que celui ci utilise une validation par CRC.

Il est à noter également qu'il traite l'interpolation linéaire / circulaire, peut-être pas de la façon dont tu voudrais le faire,mais lui l'a fait et c'est également intéressant...

Je n'ai pas besoin que ce soit CNC, ou que ca utilise le CRC.

Ce que je demande c'est une facon basic de dire a arduino:

attend qu'on envoi une ligne de code
execute la 1 seule fois
attend de nouveau

Comme ca le software gere tout alors que larduino ne fait que relier le pc a la machine...de cette facon on est pas limité par les capacités de l'arduino.

Et secundo; j'ai préciser que j'utilisais un Motor Shield de Ladyada pour controller els steppers,de fait..son raisonement m'est totalement inutile puisque tout ce que je cherche a accomplir c'Est:

void Loop()
Attend une commande
Execute la 1 fois
goto void loop()

et le software envoie une ligne de code comprenable pour arduino via le serial

ex:
motor.step(100, BACKWARD, SINGLE);

Voici ce qui correspond à ta demande (que j'ai trouvé très impolie au passage).

// pour stocker la chaine de caractère envoyée par la liaison série
byte commande[32];

// enregistre la chaine de caractère et indique le nombre de caractères lus
int readCommand()
{
  if(!Serial.available()) 
  {
    return 0;
  }
  int i = 0;
  // il faut lire chaque caractère 1 par 1
  while(Serial.available()) 
  {
    commande[i] = Serial.read(); 
    i++;
  }
  commande[i] = 0;  // toujours terminer par un 0
  return i;
}

void executeCommande()
{
  if (commande[0] == 'X')
  {
    motorX.step(commande[1], commande[2], commande[3]); 
  } 
  if (commande[0] == 'Y')
  {
    motorY.step(commande[1], commande[2], commande[3]); 
  }
}

void loop()
{
  if (readCommande() != 0)
  {
    // si une commande complète est arrivée, on l'exécute
    executeCommande();
  }
}

Merci bcp pour ton code..ca semble etre exactement ce que je cherche.
et desolé si ce que j'ecrit semble impolit,je suis militaire et de fait...j'utilise un ton impératif dans l'ensemble de mes activités,c'est qu'une habitude qui s'enleve pas tres facilement mais l'intention n'était point de faire du tord.

Pourrais-tu s'il te plait décrire le fonctionnement détaillé de ton code?
Je suis tres callé en Mécanique,
bien renseigné en électronique,
je me debrouille quand meme tres bien avec visual basic..
mais pour coder en C brute...j'ai de grandes lacunes.
merci :sunglasses:

La différence entre ce code et le code "habituel" (i.e. celui qu'on trouve dans les exemples Arduino), c'est que celui-ci va construire une chaine de caractère complète avant de la traiter, alors que d'habitude on traite chaque octet au fur et à mesure.

// pour stocker la chaine de caractère envoyée par la liaison série
byte commande[32];

// enregistre la chaine de caractère et indique le nombre de caractères lus en retour 
// pour savoir si on doit faire quelque chose ou pas
int readCommand()
{
  // s'il n'y a rien, on ne lit pas la liaison série
  if(!Serial.available())
  {
    return 0;
  }
  // on commence à compter
  int i = 0;
  // il faut lire chaque caractère 1 par 1
  while(Serial.available())
  {
    // stocke le caractère reçu dans le tableau de caractères
    commande[i] = Serial.read();
    i++;
  }
  commande[i] = 0;  // toujours terminer par un 0 la chaine
  // le nombre de caractères lus (pour vérifier que c'est bien ce qu'on attendait
  return i;
}

// traitement de la commande caractère par caractère, 
// en supposant que l'on envoit des consignes composées de 4 caractères (exemple de ton post ci-dessus).
void executeCommande()
{
  if (commande[0] == 'X')
  {
    motorX.step(commande[1], commande[2], commande[3]);
  }
  if (commande[0] == 'Y')
  {
    motorY.step(commande[1], commande[2], commande[3]);
  }
}

// boucle Arduino principale, appelée en permanence
void loop()
{
  // traitement d'une éventuelle commande
  // si aucune commande n'a été reçue, la boucle continue
  if (readCommande() != 0)
  {
    // si une commande complète est arrivée, on l'exécute
    executeCommande();
  }
}

merci énormément,ca ressemble exactement a ce que je cherchais.

Je me demandais...si au lieu d'avoir une partie de la commande écrite et de la compléter avec les caracteres lus,est-il possible qu'il en recoive une complete du style;

if (commande[0] == 'K')
{
(commande[1], commande[2], commande[3],etc...);
}

?

K étant le trigger pour une commande hors normes.

au fait....j'ai tester et adapter ton code mai il semble manquer quelquechose....

Voici le code complet;

#include <AFMotor.h>


AF_Stepper motor(48, 2);
int commande[32];


void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Stepper test!");

  motor.setSpeed(250);  // 10 rpm   
  motor.release();
  delay(1000);
}
int readCommande()
{
  // s'il n'y a rien, on ne lit pas la liaison série
  if(!Serial.available())
  {
    return 0;
  }
  // on commence à compter
  int i = 0;
  // il faut lire chaque caractère 1 par 1
  while(Serial.available())
  {
    // stocke le caractère reçu dans le tableau de caractères
    commande[i] = Serial.read();
    i++;
  }
  commande[i] = 0;  // toujours terminer par un 0 la chaine
  // le nombre de caractères lus (pour vérifier que c'est bien ce qu'on attendait
  return i;
}

void execCommande()
{
  if (commande[0] == 'x')
  {
    Serial.println("x has been detected");
    motor.step((commande[1] , commande[2] , commande[3] ),FORWARD, SINGLE);
    Serial.println("x has been moved");
 
  }
  if (commande[0] == 'y')
  {
    motor.step((commande[1], commande[2], commande[3]) ,BACKWARD, SINGLE);
  }
}
void loop()
{
  // traitement d'une éventuelle commande
  // si aucune commande n'a été reçue, la boucle continue
  if (readCommande() != 0)
  {
    // si une commande complète est arrivée, on l'exécute
    execCommande();
    Serial.println((commande[0] , commande[1], commande[2], commande[3]));
      motor.release();
    }
  }

-Il détecte sans probleme lorsque c'est x ou y le premier charactere
-Il effectue le mouvement
-Mais quand il me remontre les valeurs (supposons que je lui ai donner x150) il me redonne :

[ch9608]
[ch9608]
0

et ca..ca me pose probleme..parceque je suppose que la library du Mshield execute bien un move mais de [ch9608][ch9608] steps qui est a vrai dire rien. La varriable commande etait au depart en byte,j'ai esasiller en int et rien n'a changer.Des suggestions?

Bon..j'ai travailler comme un dingu pour tenter de trouver le probleme et je n'y arrive toujours pas...

voici le code;

#include <AFMotor.h>


AF_Stepper motor(48, 2);
byte commande[4];
int stp ;
int a;
int b;
int c;



void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Stepper test!");

  motor.setSpeed(250);  // 10 rpm   
  stp = 0;
  motor.release();
  delay(1000);
}
int readCommande()
{
  // s'il n'y a rien, on ne lit pas la liaison série
  if(!Serial.available())
  {
    return 0;
  }
  // on commence à compter
  int i = 0;
  // il faut lire chaque caractère 1 par 1
  while(Serial.available())
  {
    // stocke le caractère reçu dans le tableau de caractères
    commande[i] = Serial.read();
    i++;
  }
  commande[i] = 0;  // toujours terminer par un 0 la chaine
  // le nombre de caractères lus (pour vérifier que c'est bien ce qu'on attendait
  return i;
}

void execCommande()
{
  if (commande[0] == 'x')
  {
    Serial.println("x has been detected showing variable values");
    a= (commande[1]);
        Serial.println(a);
    b=(commande[2]);
        Serial.println(b);
    c=(commande[3]);
        Serial.println(c);

    (stp = (a * 100) + (b * 10) + c);
    Serial.println("Valeure de steps");
    Serial.println(stp);
    motor.step((stp),FORWARD, SINGLE);
    Serial.println("x has been moved");

  }
  if (commande[0] == 'X')
  {
    Serial.println("-x has been detected");
    stp = (((commande[1])*100)+(commande[2])*10+(commande[3]));
    motor.step((stp),BACKWARD, SINGLE);
    Serial.println("-x has been moved");
  }
}
void loop()
{
  // traitement d'une éventuelle commande
  // si aucune commande n'a été reçue, la boucle continue
  if (readCommande() != 0)
  {
    // si une commande complète est arrivée, on l'exécute
    execCommande();
    motor.release();
    stp=0;
  }
}

le probleme est...(vous le verrez vous meme sans probleme si vous uploader ceci sur votre arduino et que vous le faite fonctionner...simplement enlever toute référence au motorshield et a ses commandes) que j'envoi par exemple;

x050
la premiere fois je recoit que des 0 dans la console et rien ne bouge

la 2eme fois que je le renvoi j'obtient;

x has been detected showing variable values
0
49
0
Valeure de steps
490
x has been moved

et le moteur bouge effectivement de 490 steps...mais je lui en ai demander 50...pas 490...

J'ai cru a un probleme de variable mais je n'arrive toujours pas a trouver le probleme...

merci d'y jeter un coup d'oeil

EDIT
je croit que la source du probleme est la conversion du chiffre qui est lu en chiffre utilisable par arduino...pourriez vous verifier?

Je confirme que si tu envoies les valeurs depuis la console série, effectivement ça ne peut pas fonctionner.

Si tu envoies x050, la carte considère qu'elle a reçu 4 caractères : x puis 0 puis 5 puis 0.

Je regarderai ce soir le code à écrire pour faire la conversion.

merci bcp!

char cmdChar;
int cmdValeur;

int flagNombre = false;

[...] 

while (serialAvailable())
{
  cmdChar = Serial.read ();
  switch (cmdChar)
  {
  case 'x' : 
  case 'y' :
  case 'z' :
    //
    if (flagNombre)
    {
       // rectifier i après le nombre qu'on vient d'accumuler
       // pour pouvoir enchainer "x 125 y 250" par exemple
       i++;      
    }
    // on indique qu'on n'est pas en train d'accumuler un nombre
    flagNombre = false;
    // stocke le caractère reçu dans le tableau de caractères
    commande[i] = cmdChar;
    i++;
    // remet à zéro l'accumulateur de nombre
    cmdValeur = 0;
    break;
  case '0' : 
  case '1' : 
  case '2' : 
  case '3' : 
  case '4' : 
  case '5' : 
  case '6' : 
  case '7' : 
  case '8' : 
  case '9' : 
    //
    flagNombre = true;
    // explication : les chiffres commencent à partir du caractère ASCII 48
    cmdValeur = cmdValeur * 10 + (cmdChar-48);
    // comme on ne sait pas quand on s'arrêtera, on met à jour la valeur dans notre tableau des commandes
    commande[i] = cmdValeur;
    // mais bien sûr on n'incrémente pas i car pour l'instant on reste
    break;
  default:
    Serial.print("> valeur non reconnue : ");
    Serial.println(cmdChar);
  }
}

if (flagNombre)
{
 // rectifier le dernier i++ qui n'a pas été pris en compte
 i++;  
}

[...]

j'vais etre honete avec toi sur ce point la...j'comprend absolument rien du code que ta écrit =\

J'ai tenter de l'intégrer dans mon code existant (posté ci-bas) mais je voit pas comment faire ca puisque je ne sais pas a quoi ca sert ligne par ligne.. y'aurais moyen de reposter le code,a l'endroit ou il va?

Aussi: j'avais réeussit a trouver pour le -48 et il ne faut aps oublier d'ajouter des condtions qui ramenent a 0 si ce n'est pas un chiffre qui est entré.

#include <AFMotor.h>


AF_Stepper motor(48, 2);
byte commande[4];
int stp ;
int a;
int b;
int c;



void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Stepper test!");

  motor.setSpeed(250);  // 10 rpm   
  stp = 0;
  motor.release();
  delay(1000);
}
int readCommande()
{
  // s'il n'y a rien, on ne lit pas la liaison série
  if(!Serial.available())
  {
    return 0;
  }
  // on commence à compter
  int i = 0;
  // il faut lire chaque caractère 1 par 1
  while(Serial.available())
  {
    // stocke le caractère reçu dans le tableau de caractères
    commande[i] = Serial.read();
    i++;
  }
  commande[i] = 0;  // toujours terminer par un 0 la chaine
  // le nombre de caractères lus (pour vérifier que c'est bien ce qu'on attendait
  return i;
}

void execCommande()
{
  if (commande[0] == 'x')
  {
    Serial.println("x has been detected showing variable values");
    a= (commande[1] - 48);
    if (a <= 0) a=0;
    Serial.println(a);
    b=(commande[2] - 48);
    if (b <= 0) b=0;
    Serial.println(b);
    c=(commande[3] - 48);
    if (c <= 0) c=0;
    Serial.println(c);

    (stp = (a * 100) + (b * 10) + c);
    Serial.println("Valeure de steps");
    Serial.println(stp);
    motor.step((stp),FORWARD, SINGLE);
    Serial.println("x has been moved");

  }
  if (commande[0] == 'X')
  {
    Serial.println("-x has been detected");
    a= (commande[1] - 48);
    if (a <= 0) a=0;
    Serial.println(a);
    b=(commande[2] - 48);
    if (b <= 0) b=0;
    Serial.println(b);
    c=(commande[3] - 48);
    if (c <= 0) c=0;
    Serial.println(c);
   x stp = (((commande[1])*100)+(commande[2])*10+(commande[3]));
    motor.step((stp),BACKWARD, SINGLE);
    Serial.println("-x has been moved");
  }
}
void loop()
{
  // traitement d'une éventuelle commande
  // si aucune commande n'a été reçue, la boucle continue
  if (readCommande() != 0)
  {
    // si une commande complète est arrivée, on l'exécute
    execCommande();
    motor.release();
    stp=0;
  }
}

ps:avec ce code je suis en mesure de bouger de 1 step,5 steps,10 mais pas 100 et ils sont a délais..:

J'entre x0001-->rien se passe
j'entre x0005-->bouge de 1
J'entre x0010-->bouge de 5

J'ai l'impression qu'une etape nécéssaire est sautée lors du premier tour et ca l'empeche d'etre fonctionnel directement.

Est-ce que ya qlqun?
j'ai l'impression que vous m'avez abandonner =/

pourtant vous etes si proche de la solution et en plus j'ai déja commencer a concevoir le chassis de la CNC..alors ca serais qd meme gentil de finir ce code^^

merci,qlqun? ^^

Je pensais que tu avais résolu le problème :slight_smile:

Cela m'étonne qu'il n'y ait pas déjà une lib pour faire ça. Sur myAvr, j'utilise AVRlib et il y a la possibilité de faire une commande type "terminal".

Je regarde ça bientôt.

J'ai rpesque réeussit mais il y a encore un delais d'une commande et aussi le fait que c'est aps toute els commandes qui fonctionnent

ex: x0010 fonctione
x0100 fonctionne pas =\

merci d'y jeter un oeil et de rendre le tout bcp plus convivial! ;D

tjrs aucune solution viable? ^^

Si, regarde là : http://blog.makezine.com/archive/2008/10/bitlash_arduino_command_l.html