Drawbot

Bonjour à tous,
Nous essayons actuellement de réaliser un drawbot grâce au logiciel Arduino.
Mais nous nous retrouvons toujours face au même problème (voir ci-dessous)
Merci d’avance pour votre aide!!! :slight_smile:

Voici la partie du code concernée (on a mis en rouge la ligne de code qui nous pose problème ) :

// retourne l’angle de dy/dx comme une valeur comprise entre 0…2PI*
static float atan3(float dy,float dx) {
float a=atan2(dy,dx);
if(a<0) a=(PI*2.0)+a;
return a;
}

Voici le code d’erreur:

C:\Users\Art3fact Lab\Desktop\drawbot\drawbot ART3FACTLAB\GcodeCNCjulien\GcodeCNCjulien.ino: In function ‘float atan3(float, float)’:

GcodeCNCjulien:150: error: ‘float atan3(float, float)’ was declared ‘extern’ and later ‘static’ [-fpermissive]

static float atan3(float dy,float dx) {

^

GcodeCNCjulien:56: error: previous declaration of ‘float atan3(float, float)’ [-fpermissive]

^

C:\Users\Art3fact Lab\Desktop\drawbot\drawbot ART3FACTLAB\GcodeCNCjulien\GcodeCNCjulien.ino: In function ‘void arc(float, float, float, float, float, float)’:

GcodeCNCjulien:164: error: ‘void arc(float, float, float, float, float, float)’ was declared ‘extern’ and later ‘static’ [-fpermissive]

static void arc(float cx,float cy,float x,float y, float z, float dir) {

^

GcodeCNCjulien:57: error: previous declaration of ‘void arc(float, float, float, float, float, float)’ [-fpermissive]

// Changer l’état du stylo.

^

Multiple libraries were found for “Adafruit_MotorShield.h”
Used: C:\Users\Art3fact Lab\Documents\Arduino\libraries\Adafruit_MotorShield
Not used: C:\Users\Art3fact Lab\Documents\Arduino\libraries\Adafruit_Motor_Shield_V2_Library-master
exit status 1
‘float atan3(float, float)’ was declared ‘extern’ and later ‘static’ [-fpermissive]

Bonjour,

Tu as deux librairies Adafruit_MotorShield

Used: C:\Users\Art3fact Lab\Documents\Arduino\libraries\Adafruit_MotorShield
Not used: C:\Users\Art3fact Lab\Documents\Arduino\libraries\Adafruit_Motor_Shield_V2_Library-master

Supprime la plus ancienne 'C:\Users\Art3fact Lab\Documents\Arduino\libraries\Adafruit_MotorShield' pour ne garder que la V2

Bonjour,
Merci pour votre réponse très rapide!!
Nous avons bien pris en compte votre conseil, mais au début de notre programme, trois librairies s’affichent :

#include <Adafruit_MotorShield.h>

#include <Adafruit_PWMServoDriver.h>

#include <utility/Adafruit_PWMServoDriver.h>

On ne comprend pas pourquoi la librairie V2 ne s’affiche pas. Lorsqu’on l’inclue au programme elle se met sous la forme de Adrafruit_MotorShield.h

Pouvez-vous nous expliquer plus précisément ce qu’il faut faire?

Mais maintenant nous avons un second soucis!!!

Voici le message d’erreur:
sketch\Adafruit_MotorShield.cpp:25:40: fatal error: Adafruit_MS_PWMServoDriver.h: No such file or directory

#include <Adafruit_MS_PWMServoDriver.h>

Or lorsque sur internet nous cherchons à télécharger cette librairie, le moteur de recherche cherche à nous corriger pour nous rediriger vers une librairie que nous avons déjà, c’est à dire: Adafruit_Motor_Shield_V2_Library

Est-ce que ces deux librairies sont les mêmes mais avec 2 noms différents?
Si oui, pourquoi le programme nous reproche ceci??
Merci encore!
:slight_smile:

Je ne comprend rien à cette réponse.
De quelle librairie parlez vous? Dans les librairies, il y a des fichiers et pas des #include

Je répète:
Supprime le répertoire ‘C:\Users\Art3fact Lab\Documents\Arduino\libraries\Adafruit_MotorShield’ pour ne garder que la librairie V2

oups! Nous avons eu un petit soucis et le message ne s'est pas envoyé en entier! aha
Où faut il supprimer la librairie? Dans les documents? Dans le programme?

Comme c'est écrit!
C:\Users\Art3fact Lab\Documents\Arduino\libraries\Adafruit_MotorShield

ok c’est fait!
Voilà encore un message d’erreur…
Nous avons ajouté la librairie en question , mais nous avons eu le même type de message que précédemment, on a donc supprimé la première librairie.
Que faut-il donc faire?
Merci de votre patience et de votre aide ! :slight_smile:

Voici le message :
C:\Users\Art3fact Lab\Desktop\drawbot\drawbot ART3FACTLAB\GcodeCNCjulien\GcodeCNCjulien.ino:5:45: fatal error: utility/Adafruit_PWMServoDriver.h: No such file or directory

#include <utility/Adafruit_PWMServoDriver.h>

^

compilation terminated.

exit status 1
Error compiling.

En fait, où pouvons nous trouver à télécharger cette librairie? Connaissez-vous un site?

je ne comprend pas pourquoi vous avez 2 includes du même fichier dans des répertoires différents

#include <Adafruit_PWMServoDriver.h>

#include <utility/Adafruit_PWMServoDriver.h>

Essayez de supprimer la 2ème ligne

Nous l'avons supprimée.
Nous avons toujours le message d'erreur :

C:\Users\Art3fact Lab\Desktop\drawbot\drawbot ART3FACTLAB\GcodeCNCjulien\ams2.ino:18:45: fatal error: utility/Adafruit_PWMServoDriver.h: No such file or directory

#include "utility/Adafruit_PWMServoDriver.h"

^

compilation terminated.

exit status 1
Error compiling.

Le message d'erreur fait référence à la ligne
#include "utility/Adafruit_PWMServoDriver.h"

Si vous êtes sur d'avoir supprimer la ligne, il y a peut être un 2eme include du même fichier. Recherchez cette ligne et supprimer la

Aucune des deux ne fait référence au même dossier

voilà ce que nous avons:

#include <Adafruit_MotorShield.h>

#include <Adafruit_PWMServoDriver.h>

C'est incompréhensible. Postez votre code

Voici notre code :

#include <Adafruit_MotorShield.h>

#include <Adafruit_PWMServoDriver.h>

#include “config.h”
#include <Servo.h>

#define PEN_UP_ANGLE (170)
#define PEN_DOWN_ANGLE (0)
#define PEN_DELAY (250)

static Servo s1;

char buffer[MAX_BUF];
int sofar;
float px, py, pz;

float fr=0;
long step_delay;

char mode_abs=1;


/**

  • delai pour le nombre approprié de ms
  • le nombre entré est le temps qu’on veut attendre en ms
    */
    void pause(long ms) {
    delay(ms/1000);
    delayMicroseconds(ms%1000);
    }

void setPenAngle(int pen_angle) {
if(pz!=pen_angle) {
pz=pen_angle;

if(pz<PEN_DOWN_ANGLE) pz=PEN_DOWN_ANGLE;
if(pz>PEN_UP_ANGLE ) pz=PEN_UP_ANGLE;

s1.write( (int)pz );
delay(PEN_DELAY);
}
}

/**

  • Configurer le feedrate (vitesse à laquelle les moteurs vont bouger)
  • le nombre entré est la nouvelle vitesse en steps/sec
    */
    void feedrate(float nfr) {
    if(fr==nfr) return;

if(nfr>MAX_FEEDRATE || nfr<MIN_FEEDRATE) {
Serial.print(F("Le nouveau feedrate doit etre plus grand que "));
Serial.print(MIN_FEEDRATE);
Serial.print(F("steps/s et moins que "));
Serial.print(MAX_FEEDRATE);
Serial.println(F(“steps/s.”));
return;
}
step_delay = 1000000.0/nfr;
fr=nfr;
}

/**

  • Configurer la position logique
  • l’entrée npx sera la nouvelle position x
  • l’entrée npy sera la nouvelle position y
    */
    void position(float npx,float npy) {
    // ici est un bon endroit pour ajouter des tests de sanité :slight_smile:
    px=npx;
    py=npy;
    }

/**

  • Utilise l’algorithme de la ligne de bresenham pour bouger les deux moteurs
  • l’entrée newx sera la destination d’x
  • l’entrée newy sera la destination d’y
    **/
    void line(float newx,float newy, float z) {
    long dx=newx-px;
    long dy=newy-py;
    int dirx=dx>0?1:-1;
    int diry=dy>0?-1:1;
    dx=abs(dx);
    dy=abs(dy);

long i;
long over=0;

setPenAngle((int)z);

if(dx>dy) {
for(i=0;i<dx;++i) {
m1step(dirx);
over+=dy;
if(over>=dx) {
over-=dx;
m2step(diry);
}
pause(step_delay);
}
} else {
for(i=0;i<dy;++i) {
m2step(diry);
over+=dx;
if(over>=dy) {
over-=dy;
m1step(dirx);
}
pause(step_delay);
}
}

px=newx;
py=newy;
}

static float atan3(float dy,float dx) {
float a=atan2(dy,dx);
if(a<0) a=(PI*2.0)+a;
return a;
}

static void arc(float cx,float cy,float x,float y, float z, float dir) {

float dx = px - cx;
float dy = py - cy;
float radius=sqrt(dxdx+dydy);

float angle1=atan3(dy,dx);
float angle2=atan3(y-cy,x-cx);
float theta=angle2-angle1;

if(dir>0 && theta<0) angle2+=2PI;
else if(dir<0 && theta>0) angle1+=2
PI;

theta=angle2-angle1;

float len = abs(theta) * radius;

int i, segments = ceil( len * MM_PER_SEGMENT );

float nx, ny, nz, angle3, scale;

for(i=0;i<segments;++i) {
scale = ((float)i)/((float)segments);

angle3 = ( theta * scale ) + angle1;
nx = cx + cos(angle3) * radius;
ny = cy + sin(angle3) * radius;
nz = ( z - pz ) * scale + pz;

line(nx,ny,nz);
}

line(x,y,z);
}

/**

  • Chercher le caractère /code/ dans le buffer et lire le float qui le suit immédiatement après.
  • retourne la valeur trouvée. Si rien n’est trouvé, /val/ est retourné.
  • l’entrée code est le caractère qu’on cherche.
  • l’entrée val est la valeur de retour si /code/ n’est pas trouvé.
    **/
    float parsenumber(char code,float val) {
    char *ptr=buffer;
    while(ptr && *ptr && ptr<buffer+sofar) {
    if(*ptr==code) {
    return atof(ptr+1);
    }
    ptr=strchr(ptr,’ ')+1;
    }
    return val;
    }

/**

  • envoyer une chaîne suivie d’un float à la ligne série. Pratique pour débugger .
  • l’entrée code est la chaîne.
  • l’entrée val est le float.
    */
    void output(char *code,float val) {
    Serial.print(code);
    Serial.println(val);
    }

/**

  • envoyer la position actuelle, le feedrate, et le mode absolu.
    */
    void where() {
    output(“X”,px);
    output(“Y”,py);
    output(“Z”,pz);
    output(“F”,fr);
    Serial.println(mode_abs?“ABS”:“REL”);
    }

/**

  • affiche des informations utiles
    */
    void help() {
    Serial.print(F(“GcodeCNCDemo2AxisV”));
    Serial.println(VERSION);
    Serial.println(F(“Commandes:”));
    Serial.println(F(“G00 [X(steps)] [Y(steps)] [F(feedrate)]; - ligne”));
    Serial.println(F(“G01 [X(steps)] [Y(steps)] [F(feedrate)]; - ligne”));
    Serial.println(F(“G02 [X(steps)] [Y(steps)] [I(steps)] [J(steps)] [F(feedrate)]; - arc de cercle direction horaire”));
    Serial.println(F(“G03 [X(steps)] [Y(steps)] [I(steps)] [J(steps)] [F(feedrate)]; - arc de cercle direction anti-horaire”));
    Serial.println(F(“G04 P[secondes]; - delai”));
    Serial.println(F(“G90; - mode absolu”));
    Serial.println(F(“G91; - mode relatif”));
    Serial.println(F(“G92 [X(steps)] [Y(steps)]; - change la position logique”));
    Serial.println(F(“M18; - desactiver les moteurs”));
    Serial.println(F(“M100; - re-afficher ce message”));
    Serial.println(F(“M114; - donne la position actuelle et le feedrate”));
    Serial.println(F(“Toutes les commandes finissent par un retour a la ligne.”));
    }

/**

  • Lit le buffer d’entrée et cherche n’importe quelle commande reconnaissable. Un seul G OU M par ligne.
    */
    void processCommand() {
    int cmd = parsenumber(‘G’,-1);
    switch(cmd) {
    case 0: {
    feedrate(parsenumber(‘F’,fr));
    line( parsenumber(‘X’,(mode_abs?px:0)) + (mode_abs?0:px),
    parsenumber(‘Y’,(mode_abs?py:0)) + (mode_abs?0:py),
    parsenumber(‘Z’,(mode_abs?pz:0)) + (mode_abs?0:pz));
    break;
    }
    case 1: {
    feedrate(parsenumber(‘F’,fr));
    line( parsenumber(‘X’,(mode_abs?px:0)) + (mode_abs?0:px),
    parsenumber(‘Y’,(mode_abs?py:0)) + (mode_abs?0:py),
    parsenumber(‘Z’,(mode_abs?pz:0)) + (mode_abs?0:pz));
    break;
    }
    case 2: {
    feedrate(parsenumber(‘F’,fr));
    arc(parsenumber(‘I’,(mode_abs?px:0)) + (mode_abs?0:px),
    parsenumber(‘J’,(mode_abs?py:0)) + (mode_abs?0:py),
    parsenumber(‘X’,(mode_abs?px:0)) + (mode_abs?0:px),
    parsenumber(‘Y’,(mode_abs?py:0)) + (mode_abs?0:py),
    parsenumber(‘Z’,(mode_abs?pz:0)) + (mode_abs?0:pz),
    (cmd==2) ? -1 : 1);
    break;
    }
    case 3: {
    feedrate(parsenumber(‘F’,fr));
    arc(parsenumber(‘I’,(mode_abs?px:0)) + (mode_abs?0:px),
    parsenumber(‘J’,(mode_abs?py:0)) + (mode_abs?0:py),
    parsenumber(‘X’,(mode_abs?px:0)) + (mode_abs?0:px),
    parsenumber(‘Y’,(mode_abs?py:0)) + (mode_abs?0:py),
    parsenumber(‘Z’,(mode_abs?pz:0)) + (mode_abs?0:pz),
    (cmd==2) ? -1 : 1);
    break;
    }
    case 4: pause(parsenumber(‘P’,0)*1000); break;
    case 90: mode_abs=1; break;
    case 91: mode_abs=0; break;
    case 92:
    position( parsenumber(‘X’,0),
    parsenumber(‘Y’,0) );
    break;
    default: break;
    }

cmd = parsenumber(‘M’,-1);
switch(cmd) {
case 18:
disable();
break;
case 100: help(); break;
case 114: where(); break;
default: break;
}
}

/**

  • prépare le buffer d’entrée à recevoir un nouveau message et dire à la liaison série que nous sommes prêt pour plus.
    */
    void ready() {
    sofar=0;
    Serial.print(F(">"));
    }

/**

  • Première chose que la machine exécute au démarrage. Ne se lance qu’une seule fois.
    */
    void setup() {

s1.attach(10);
setPenAngle(PEN_UP_ANGLE);

Serial.begin(BAUD);

setup_controller();
feedrate((MAX_FEEDRATE + MIN_FEEDRATE)/2);

help();
ready();
}

/**

  • Après setup() cette machine répètera le loop() indéfinniment.
    */
    void loop() {

while(Serial.available() > 0) {
char c=Serial.read();
Serial.print(c);
if(sofar<MAX_BUF-1) buffer[sofar++]=c; // enregistre le
if(c==’\n’) {

buffer[sofar]=0; // arrête le buffer comme ça les fonctions chaînes fonctionnent correctement
Serial.print(F("\r\n")); // retourne un écho pour les humains
processCommand(); // faire quelque chose avec la commande
ready();
}
}
}

/**

  • This file is part of GcodeCNCDemo.
  • GcodeCNCDemo is free software: you can redistribute it and/or modify
  • it under the terms of the GNU General Public License as published by
  • the Free Software Foundation, either version 3 of the License, or
  • (at your option) any later version.
  • GcodeCNCDemo is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  • GNU General Public License for more details.
  • You should have received a copy of the GNU General Public License
  • along with Foobar. If not, see http://www.gnu.org/licenses/.
    */

Voici notre de code d’erreur:

C:\Users\Art3fact Lab\Desktop\drawbot\drawbot ART3FACTLAB\GcodeCNCjulien\ams2.ino:18:45: fatal error: utility/Adafruit_PWMServoDriver.h: No such file or directory

#include “utility/Adafruit_PWMServoDriver.h”

^

compilation terminated.

exit status 1
Error compiling.
A library named Adafruit-PWM-Servo-Driver-Library-master already exists

mettez votre code entre balises voir ici.
c'est quoi ce fichier config.h? vous pouvez le poster?

#include <Adafruit_MotorShield.h>

#include <Adafruit_PWMServoDriver.h>



#include "config.h"
#include <Servo.h>

#define PEN_UP_ANGLE    (170)
#define PEN_DOWN_ANGLE  (0)  
#define PEN_DELAY       (250)

static Servo s1;


char buffer[MAX_BUF];
int sofar;
float px, py, pz;

float fr=0;
long step_delay;


char mode_abs=1;


-------------

/**
* delai pour le nombre approprié de ms
* le nombre entré est le temps qu'on veut attendre en ms
*/
void pause(long ms) {
delay(ms/1000);
delayMicroseconds(ms%1000);
}



void setPenAngle(int pen_angle) {
if(pz!=pen_angle) {
 pz=pen_angle;
 
 if(pz<PEN_DOWN_ANGLE) pz=PEN_DOWN_ANGLE;
 if(pz>PEN_UP_ANGLE  ) pz=PEN_UP_ANGLE;

 s1.write( (int)pz );
 delay(PEN_DELAY);
}
}



/**
* Configurer le feedrate (vitesse à laquelle les moteurs vont bouger)
* le nombre entré est la nouvelle vitesse en steps/sec
*/
void feedrate(float nfr) {
if(fr==nfr) return;

if(nfr>MAX_FEEDRATE || nfr<MIN_FEEDRATE) {
 Serial.print(F("Le nouveau feedrate doit etre plus grand que "));
 Serial.print(MIN_FEEDRATE);
 Serial.print(F("steps/s et moins que "));
 Serial.print(MAX_FEEDRATE);
 Serial.println(F("steps/s."));
 return;
}
step_delay = 1000000.0/nfr;
fr=nfr;
}


/**
* Configurer la position logique
* l'entrée npx sera la nouvelle position x
* l'entrée npy sera la nouvelle position y
*/
void position(float npx,float npy) {
// ici est un bon endroit pour ajouter des tests de sanité :)
px=npx;
py=npy;
}


/**
* Utilise l'algorithme de la ligne de bresenham pour bouger les deux moteurs
* l'entrée newx sera la destination d'x
* l'entrée newy sera la destination d'y
**/
void line(float newx,float newy, float z) {
long dx=newx-px;
long dy=newy-py;
int dirx=dx>0?1:-1;
int diry=dy>0?-1:1;
dx=abs(dx);
dy=abs(dy);

long i;
long over=0;

setPenAngle((int)z);

if(dx>dy) {
 for(i=0;i<dx;++i) {
   m1step(dirx);
   over+=dy;
   if(over>=dx) {
     over-=dx;
     m2step(diry);
   }
   pause(step_delay);
 }
} else {
 for(i=0;i<dy;++i) {
   m2step(diry);
   over+=dx;
   if(over>=dy) {
     over-=dy;
     m1step(dirx);
   }
   pause(step_delay);
 }
}

px=newx;
py=newy;
}

static float atan3(float dy,float dx) {
float a=atan2(dy,dx);
if(a<0) a=(PI*2.0)+a;
return a;
}


static void arc(float cx,float cy,float x,float y, float z, float dir) {

float dx = px - cx;
float dy = py - cy;
float radius=sqrt(dx*dx+dy*dy);


float angle1=atan3(dy,dx);
float angle2=atan3(y-cy,x-cx);
float theta=angle2-angle1;

if(dir>0 && theta<0) angle2+=2*PI;
else if(dir<0 && theta>0) angle1+=2*PI;

theta=angle2-angle1;


float len = abs(theta) * radius;

int i, segments = ceil( len * MM_PER_SEGMENT );

float nx, ny, nz, angle3, scale;

for(i=0;i<segments;++i) {
 scale = ((float)i)/((float)segments);
 
 angle3 = ( theta * scale ) + angle1;
 nx = cx + cos(angle3) * radius;
 ny = cy + sin(angle3) * radius;
 nz = ( z - pz ) * scale + pz;

 line(nx,ny,nz);
}

line(x,y,z);
}


/**
* Chercher le caractère /code/ dans le buffer et lire le float qui le suit immédiatement après.
* retourne la valeur trouvée.  Si rien n'est trouvé, /val/ est retourné.
* l'entrée code est le caractère qu'on cherche.
* l'entrée val est la valeur de retour si /code/ n'est pas trouvé.
**/
float parsenumber(char code,float val) {
char *ptr=buffer;
while(ptr && *ptr && ptr<buffer+sofar) {
 if(*ptr==code) {
   return atof(ptr+1);
 }
 ptr=strchr(ptr,' ')+1;
}
return val;
} 


/**
* envoyer une chaîne suivie d'un float à la ligne série. Pratique pour débugger .
* l'entrée code est la chaîne.
* l'entrée val est le float.
*/
void output(char *code,float val) {
Serial.print(code);
Serial.println(val);
}


/**
* envoyer la position actuelle, le feedrate, et le mode absolu.
*/
void where() {
output("X",px);
output("Y",py);
output("Z",pz);
output("F",fr);
Serial.println(mode_abs?"ABS":"REL");
} 


/**
* affiche des informations utiles
*/
void help() {
Serial.print(F("GcodeCNCDemo2AxisV"));
Serial.println(VERSION);
Serial.println(F("Commandes:"));
Serial.println(F("G00 [X(steps)] [Y(steps)] [F(feedrate)]; - ligne"));
Serial.println(F("G01 [X(steps)] [Y(steps)] [F(feedrate)]; - ligne"));
Serial.println(F("G02 [X(steps)] [Y(steps)] [I(steps)] [J(steps)] [F(feedrate)]; - arc de cercle direction horaire"));
Serial.println(F("G03 [X(steps)] [Y(steps)] [I(steps)] [J(steps)] [F(feedrate)]; - arc de cercle direction anti-horaire"));
Serial.println(F("G04 P[secondes]; - delai"));
Serial.println(F("G90; - mode absolu"));
Serial.println(F("G91; - mode relatif"));
Serial.println(F("G92 [X(steps)] [Y(steps)]; - change la position logique"));
Serial.println(F("M18; - desactiver les moteurs"));
Serial.println(F("M100; - re-afficher ce message"));
Serial.println(F("M114; - donne la position actuelle et le feedrate"));
Serial.println(F("Toutes les commandes finissent par un retour a la ligne."));
}


/**
* Lit le buffer d'entrée et cherche n'importe quelle commande reconnaissable.  Un seul G OU M par ligne.
*/
void processCommand() {
int cmd = parsenumber('G',-1);
switch(cmd) {
case  0:  {
 feedrate(parsenumber('F',fr));
 line( parsenumber('X',(mode_abs?px:0)) + (mode_abs?0:px),
       parsenumber('Y',(mode_abs?py:0)) + (mode_abs?0:py),
       parsenumber('Z',(mode_abs?pz:0)) + (mode_abs?0:pz));
 break;
 }
case  1: {
 feedrate(parsenumber('F',fr));
 line( parsenumber('X',(mode_abs?px:0)) + (mode_abs?0:px),
       parsenumber('Y',(mode_abs?py:0)) + (mode_abs?0:py),
       parsenumber('Z',(mode_abs?pz:0)) + (mode_abs?0:pz));
 break;
 }
case 2:  {
   feedrate(parsenumber('F',fr));
   arc(parsenumber('I',(mode_abs?px:0)) + (mode_abs?0:px),
       parsenumber('J',(mode_abs?py:0)) + (mode_abs?0:py),
       parsenumber('X',(mode_abs?px:0)) + (mode_abs?0:px),
       parsenumber('Y',(mode_abs?py:0)) + (mode_abs?0:py),
       parsenumber('Z',(mode_abs?pz:0)) + (mode_abs?0:pz),
       (cmd==2) ? -1 : 1);
   break;
 }
case 3:  {
   feedrate(parsenumber('F',fr));
   arc(parsenumber('I',(mode_abs?px:0)) + (mode_abs?0:px),
       parsenumber('J',(mode_abs?py:0)) + (mode_abs?0:py),
       parsenumber('X',(mode_abs?px:0)) + (mode_abs?0:px),
       parsenumber('Y',(mode_abs?py:0)) + (mode_abs?0:py),
       parsenumber('Z',(mode_abs?pz:0)) + (mode_abs?0:pz),
       (cmd==2) ? -1 : 1);
   break;
 }
case  4:  pause(parsenumber('P',0)*1000);  break;
case 90:  mode_abs=1;  break;
case 91:  mode_abs=0;  break;
case 92:
 position( parsenumber('X',0),
           parsenumber('Y',0) );
 break;
default:  break;
}

cmd = parsenumber('M',-1);
switch(cmd) {
case 18:
 disable();
 break;
case 100:  help();  break;
case 114:  where();  break;
default:  break;
}
}


/**
* prépare le buffer d'entrée à recevoir un nouveau message et dire à la liaison série que nous sommes prêt pour plus.
*/
void ready() {
sofar=0;
Serial.print(F(">"));
}


/**
* Première chose que la machine exécute au démarrage. Ne se lance qu'une seule fois.
*/
void setup() {

s1.attach(10);
setPenAngle(PEN_UP_ANGLE);

Serial.begin(BAUD);

setup_controller();
feedrate((MAX_FEEDRATE + MIN_FEEDRATE)/2);

help();
ready();
}

/**
* Après setup() cette machine répètera le loop() indéfinniment.
*/
void loop() {

while(Serial.available() > 0) {
 char c=Serial.read();
 Serial.print(c);
 if(sofar<MAX_BUF-1) buffer[sofar++]=c;  // enregistre le
 if(c=='\n') {


   buffer[sofar]=0;  // arrête le buffer comme ça les fonctions chaînes fonctionnent correctement
   Serial.print(F("\r\n"));  // retourne un écho pour les humains
   processCommand();  // faire quelque chose avec la commande
   ready();
 }
}
}


/**
* This file is part of GcodeCNCDemo.
*
* GcodeCNCDemo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GcodeCNCDemo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/

Voici le code config.h

#ifndef CONFIG_H
#define CONFIG_H
//------------------------------------------------------------------------------
// 2 Axis CNC Demo
// dan@marginallycelver.com 2013-08-30
//------------------------------------------------------------------------------
// Copyright at end of file.
// please see http://www.github.com/MarginallyClever/GcodeCNCDemo for more information.


//------------------------------------------------------------------------------
// CONSTANTES
//------------------------------------------------------------------------------
#define AMS1 (1)
#define AMS2 (2)

// changez cette ligne pour choisir un autre type de carte (motor shield) pour contrôler le CNC.
#define CONTROLLER (AMS2)

#define VERSION        (1)  // version du firmware
#define BAUD           (57600)  // A quelle vitesse l'Arduino parle-t-il ?
#define MAX_BUF        (64)  // Quel est le plus long message que l'Arduino peut enregistrer ?
#define STEPS_PER_TURN (513)  // dépend de votre moteur pas-à-pas. la plupart sont à 200.
#define MIN_STEP_DELAY (50.0)
#define MAX_FEEDRATE   (1000000.0/MIN_STEP_DELAY)
#define MIN_FEEDRATE   (0.01)


// pour les directions des arcs
#define ARC_CW          (1)
#define ARC_CCW         (-1)
// Arcs sont séparés par plusieurs lignes segmentées. Combien de mm sont les segments ?
#define MM_PER_SEGMENT  (10)


//------------------------------------------------------------------------------
// METHODES
//------------------------------------------------------------------------------
extern void m1step(int dir);
extern void m2step(int dir);
extern void disable();
extern void setup_controller();


/**
* This file is part of GcodeCNCDemo.
*
* GcodeCNCDemo is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GcodeCNCDemo is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar. If not, see <http://www.gnu.org/licenses/>.
*/
#endif

chez moi je n'ai pas ce problème, mais il y a d'autres fichiers dans votre projet et je ne peux pas compiler complètement.

ah mince, comme quoi?

le .cpp qui définit les focntions déclarées dans config.h