hallo botty,
Zitat Zitat von botty Beitrag anzeigen
aus Deinem Beispiel mit den mehreren Motoren hast folgende Variablen definiert gehabt:

Code:
AF_DCMotor motor_1(1);
AF_DCMotor motor_2(2);
AF_DCMotor motor_3(3);
AF_DCMotor motor_4(4);
die Zahl n, die Du hier in motor_x(n) benutzt hast, muß in der ersten Spalte des Arrays in AF_DCMotor(n) eingetragen werden.
so?

Code:
struct motor motoren[M_MAX] = 
{ 
  { AF_DCMotor(1), 4, 18, 0, 0 }, // M_VL
  { AF_DCMotor(2), 1, 19, 0, 0 }, // M_HL
  { AF_DCMotor(3), 3, 20, 0, 0 }, // M_VR
  { AF_DCMotor(4), 2, 21, 0, 0 }  // M_HR
};
Zitat Zitat von botty Beitrag anzeigen
Probier doch bitte mal aus,wenn Du die Initialisierung von oben nimmst, ob
Code:
void loop() {
  motoren[M_VL].mot.setSpeed(130);
  motoren[M_VL].mot.run(FORWARD);

  delay(3000);

  motoren[M_VL].mot.setSpeed(0);
  motoren[M_VL].mot.run(RELEASE);

  delay(3000);
}
den linken vorderen Motor alle drei Sekunden an bzw aus schaltet.
der - so wie ich Dich verstanden habe geänderte code sieht so aus:
Code:
#include <AFMotor.h>

/*
 * Benamte Indexe. Wichtig: Alle Schleifen basieren auf der
 * Annahme, dass M_VL das erste Element und mit 0 initialisiert
 * ist. M_MAX muss ausserdem _immer_ das letzte Element sein da
 * es die Groesse des Arrays s.u. bestimmt.
 */
enum motoren_e 
{
  M_VL = 0,   // Motor vorne links
  M_HL,
  M_VR,
  M_HR,
  M_MAX 
};

/* 
 *  Infos zu einem Motor zusammenfassen.
 */
struct motor 
{
  AF_DCMotor mot;
  uint8_t enc_pin;
  // volatile damit der Compiler keine 'dummen' Optimierung macht.
  volatile uint32_t ticks;  

  unsigned long start_time; 
  unsigned long stop_time;
};

/*
 * Hier werden die PWM Channel - Encoder Pin Paare gesetzt.
 * Restliche Elemente muessen ebenfalls initialisiert werden.
 * Werte pruefen ob sie zu den Namen oben passen.
 * Fuer die externen Interrupts sind die Pins 2,5,18-21
 * erlaubt. Hardware anpassen.
 */
struct motor motoren[M_MAX] = 
{ 
  { AF_DCMotor(1), 4, 18, 0, 0 }, // M_VL
  { AF_DCMotor(2), 1, 19, 0, 0 }, // M_HL
  { AF_DCMotor(3), 3, 20, 0, 0 }, // M_VR
  { AF_DCMotor(4), 2, 21, 0, 0 }  // M_HR
};

 // Anzahl der Encoderstriche fuer eine Umdrehung
const static double ticks_per_rev = 40;
const static double durchmesser  = 6.5; // in cm;
const static double u_per_tick   = (3.1415926535897932384626433832795 * durchmesser) / ticks_per_rev;

/*
 * Interruptroutinen mit der gleichen Namenskonvention wie
 * oben.
 */
void motor_isr_m_vl(void) { motoren[M_VL].ticks++; }
void motor_isr_m_vr(void) { motoren[M_VR].ticks++; }
void motor_isr_m_hl(void) { motoren[M_HL].ticks++; }
void motor_isr_m_hr(void) { motoren[M_HR].ticks++; }


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

  for(uint8_t idx = M_VL; idx < M_MAX; idx++) 
  {
    pinMode(motoren[idx].enc_pin, INPUT_PULLUP);
//    motor_init_pos(idx);
  }

  /*
   * Hier wird die Verbindung hergestellt zwischen Pin und Interruptroutine.
   * Die Namen muessen zueinander passen.
   * Durch CHANGE werden beide Uebergaenge beruecksichtigt.
   */
  attachInterrupt(digitalPinToInterrupt(motoren[M_VL].enc_pin), motor_isr_m_vl, CHANGE);
  attachInterrupt(digitalPinToInterrupt(motoren[M_HL].enc_pin), motor_isr_m_hl, CHANGE);
  attachInterrupt(digitalPinToInterrupt(motoren[M_VR].enc_pin), motor_isr_m_vr, CHANGE);
  attachInterrupt(digitalPinToInterrupt(motoren[M_HR].enc_pin), motor_isr_m_hr, CHANGE);
}

/*
 * Alle Motoren an, bis eine Umdrehung erreicht ist. Es wird alle 
 * halbe Sekunde der Zustand der Ticks pro Motor ausgeben.
 */
 
void loop() {
  motoren[M_VL].mot.setSpeed(130);
  motoren[M_VL].mot.run(FORWARD);

  delay(3000);

  motoren[M_VL].run(RELEASE);

  delay(3000);
}

 /*
void loop() 
{
  unsigned long log_time = 0;
  unsigned long ticks_tmp = 0;
  unsigned long all_ticks_tmp[M_MAX] = { 0, 0, 0, 0 };
  String out_s = "";
  bool alle_aus = false;

  // Alle Motoren an.
  for(uint8_t idx = M_VL; idx < M_MAX; idx++) 
  {
    if( ! motor_laeuft(idx) )
      motor_start(idx, 200/2+3, FORWARD);
  }

  while( ! alle_aus ) 
  {
    // Wenn die Anzahl der Ticks fuer eine Umdrehung
    // erreicht ist - Motor aus.
    for(uint8_t idx = M_VL; idx < M_MAX; idx++) {
      if(motor_laeuft(idx) && motor_hole_ticks(idx) >= ticks_per_rev) 
      {
        motor_stop(idx);
      }
    }

    // Ticks und Strecke ausgeben
    static const int wtime = 250;
    if(log_time + wtime <= millis() ) 
    {
      out_s = "";
      out_s += millis() + ": ";

      for(uint8_t idx = M_VL; idx < M_MAX; idx++) 
      {
        out_s += idx + " ";
        out_s += motoren[idx].ticks + " ";  // Hier koennte jetzt ein Interrupt unterbrechen!
        out_s += motor_strecke_gefahren(idx);

        ticks_tmp = 0;
        motor_ticks_per_milli(idx, &ticks_tmp);
        out_s += " " + ticks_tmp;

        if(idx == M_MAX - 1)
          out_s += "\n";
        else
          out_s += ", ";
      }

      for(uint8_t idx = 0; idx < M_MAX; idx++)
        all_ticks_tmp[idx] = 0;
        
      motor_ticks_per_milli_fuer_alle(all_ticks_tmp, M_MAX);

      for(uint8_t idx; idx < M_MAX; idx++)
        out_s += all_ticks_tmp[idx] + " ";

      Serial.println(out_s);

      log_time = wtime + millis();
    }

    // pruefen ob alle Motoren aus sind.
    for(uint8_t idx = M_VL, alle_aus = true; alle_aus && idx < M_MAX; idx++) 
    {
      alle_aus = alle_aus && ( ! motor_laeuft(idx) );
    }
  }

  while(1);
  // Oder nach 2sec geht's von vorne los.
  // delay(2000);
}*/

/*
 * Faehrt den Motor auf den ersten HIGH Level des Encoderpins.
 * Falls er schon HIGH ist wird erst in ein LOW gefahren und
 * beim naechsten HIGH gestoppt.
 */
void motor_init_pos(uint8_t idx) 
{
  if(idx >= M_MAX)
    return;

  if(motor_laeuft(idx))
    motor_stop(idx);
    
  // Wenn wir bereits eine 1 haben, dann fahren wir erstmal bis zur
  // naechsten 0.
  if(digitalRead(motoren[idx].enc_pin)) 
  {
    motoren[idx].mot.setSpeed(255/3);
    motoren[idx].mot.run(FORWARD);
    
    while(digitalRead(motoren[idx].enc_pin));
  }

  // Wir sind in ner 0, wissen aber nicht ob sich der Motor schon dreht.
  if( ! digitalRead(motoren[idx].enc_pin) ) 
  {
    motoren[idx].mot.setSpeed(255/4);
    motoren[idx].mot.run(FORWARD);

    while( ! digitalRead(motoren[idx].enc_pin) );

    motoren[idx].mot.setSpeed(0);
    motoren[idx].mot.run(RELEASE);

    // Bremsen evtl. nicht noetig oder muss angepasst werden.
    /*
    delayMicroseconds(75);
    motoren[idx].mot.setSpeed(255/5);
    motoren[idx].mot.run(BACKWARD);
    delayMicroseconds(100);
    motoren[idx].mot.setSpeed(0);
    motoren[idx].mot.run(RELEASE);
    */
  }
}

/*
 * 
 */
bool motor_laeuft(uint8_t idx) 
{
  if(idx >= M_MAX)
    return false;

  return motoren[idx].start_time > 0 && motoren[idx].start_time == motoren[idx].stop_time;
}

/*
 * idx - der Motor Index
 * pwm und dir wie in AF_DCMotor.
 */
void motor_start(uint8_t idx, uint8_t pwm, uint8_t dir) 
{
  if(idx >= M_MAX)
    return;

  motor_setze_ticks(idx, 0);
  motoren[idx].start_time = motoren[idx].stop_time = millis();
  motoren[idx].mot.setSpeed(pwm);
  motoren[idx].mot.run(dir);
}

/*
 * Fuer den Fall das zwischen motor_start und motor_stop die pwm nicht 
 * geaendert wird liesse sich aus der Zeit und der Strecke s.u. grob die
 * Geschwindigkeit ermitteln (Be- und Entschleunigung vernachlaessgt).
 */
void motor_stop(uint8_t idx) 
{
  if(idx >= M_MAX)
    return;

  motoren[idx].mot.setSpeed(0);
  motoren[idx].mot.run(RELEASE);
  motoren[idx].stop_time = millis();
}

/*
 * Liesst den ticks Wert interrupt safe.
 */
inline uint32_t motor_hole_ticks(uint8_t idx) 
{ 
  if(idx >= M_MAX)
    return 0;
    
  noInterrupts();
  uint32_t tmp = motoren[idx].ticks;
  interrupts();

  return tmp;
}

/*
 * Setzt den ticks Wert interrupt safe.
 */
inline void motor_setze_ticks(uint8_t idx, uint32_t val) 
{
  if(idx >= M_MAX)
    return;
    
  noInterrupts();
  motoren[idx].ticks = val;
  interrupts();
}

/*
 * 
 */
void motor_ticks_per_milli(uint8_t idx, unsigned long *res) 
{
  if(idx >= M_MAX) 
  {
    *res = 0;
    return;  
  }
  
  *res = motor_hole_ticks(idx) / (millis() - motoren[idx].start_time);
}

/*
 * Zu _einem_ Zeitpunkt werden alle Ticks/Milli ausgerechnet.
 */
void motor_ticks_per_milli_fuer_alle(unsigned long *res, uint8_t n) 
{
  unsigned long *b = 0;
  unsigned long tstamp = 0;
  
  if(n != M_MAX)
    return;

  b = res;
  noInterrupts();
  tstamp = millis();
  while(b < res + n) 
  {
    *b = motoren[b - res].ticks;
    b++;
  }
  interrupts();

  for(b = res; b < res + n; b++) {
    *b = *b / (tstamp - motoren[b - res].start_time);
  }
}

/*
 * Rechnet die gefahrenen Zentimeter anhand der Ticks aus.
 */
double motor_strecke_gefahren(uint8_t idx) 
{
  if(idx >= M_MAX)
    return 0.0;
    
  return motor_hole_ticks(idx) * u_per_tick;
}

/*
 * Rechnet fuer alle Motoren zu _einem_ Zeitpunkt die Strecke 
 * aus.
 */
void motor_strecke_fuer_alle(double *res, int n) 
{
  if(n != M_MAX)
    return;
  
  double *b = 0;
  unsigned long tmps[M_MAX];
  uint8_t idx = 0;

  noInterrupts();
  while(idx < M_MAX) {
    tmps[idx] = motoren[idx].ticks;
    idx++;
  }
  interrupts();

  for(b = res; b < res + n; b++) 
  {
    *b = tmps[b-res] * u_per_tick;
  }
}
und lässt sich nicht kompilieren (ich sagte es schon, sehr sportlich der code für meine programmierkünste )

Arduino: 1.6.6 (Linux), Board: "Arduino Mega ADK"
Code:
/home/georg/Arduino/sainsmart_car/fahren_mit timer/botty_4_motoren_1/botty_4_motoren_1.ino: In function 'void loop()':
botty_4_motoren_1:95: error: 'struct motor' has no member named 'run'
   motoren[M_VL].run(RELEASE);
                 ^
exit status 1
'struct motor' has no member named 'run'

  Dieser Report hätte mehr Informationen mit
  "Ausführliche Ausgabe während der Kompilierung"
  aktiviert in Datei > Einstellungen.