Motorshield mehrere Motoren per Funktion ansprechen

Hallo

ich habe ein arudino uno und ein motorshield von adafruit und zwei motoren.
ich habe mir den code-beispiel für einen dc-motor genommen und wollte daraus eine Funktion machen, da ich mehrere Motoren nutzen möchte.

/* 
This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
It won't work with v1.x motor shields! Only for the v2's with built in PWM
control

For use with the Adafruit Motor Shield v2 
---->  http://www.adafruit.com/products/1438
*/

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61); 

// Select which 'port' M1, M2, M3 or M4. In this case, M1
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
Adafruit_DCMotor *myMotor2 = AFMS.getMotor(2);


// These variables store the flash pattern
// and the current state of the motor
 

int motorState = 0;             // ledState used to set the motor
unsigned long previousMillis = 0;        // will store last time motor was updated
long OnTime = 0;           // milliseconds of on-time
long OffTime = 0;          // milliseconds of off-time
char MotorNumber = 0;  
void setup() 
{

  
  //Motor
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Adafruit Motorshield v2 - DC Motor test!");

  AFMS.begin();  // create with the default frequency 1.6KHz

  
  // Set the speed to start, from 0 (off) to 255 (max speed)
  myMotor->setSpeed(150);
  myMotor->run(FORWARD);
  // turn on motor
  myMotor->run(RELEASE);
   myMotor2->setSpeed(150);
  myMotor2->run(FORWARD);
  // turn on motor
  myMotor2->run(RELEASE);       
}

//Funktion Motor
void motor(char MotorNumber, long onTime, long offTime){
  // check to see if it's time to change the state of the LED
  unsigned long currentMillis = millis();
 
  if((motorState == 1) && (currentMillis - previousMillis >= OnTime))
  {
    motorState = 0;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    MotorNumber->run(FORWARD);
  }
  else if ((motorState == 0) && (currentMillis - previousMillis >= OffTime))
  {
    motorState = 1;  // turn it on
    previousMillis = currentMillis;   // Remember the time
    MotorNumber->run(RELEASE);
  }
}

void loop()
{
  motor(mymotor,250,750);
  motor(mymotor2,500,500);
}

jedoch bekomme ich den Fehler bei MotorNumber->run(RELEASE);:

exit status 1
base operand of '->' is not a pointer

Aber wie kann ich ansonsten definieren welcher Motor angesteuert werden soll?

Die Meldung ist doch klar und eindeutig, oder?

Vielleicht solltest du deine Motorzeiger in ein Array stopfen.

Dazu gehört auch das Problem hier in loop:

motor(mymotor,250,750 );

Wie bist du auf die Idee gekommen, dass deine Funktion motor als ersten Parameter ausgerechnet ein char
erwartet? mymotor ist ein Adafruit_DCMotor* Das ist ein Zeiger, keine Nummer...

Hallo,

nun habe muss ich aber auch motorState und previousMillis mit in die function übergeben, sobald ich mehrere Motoren ansteuern möchte.
Aber die Motoren bewegen ishc gar nicht.

/* 
This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
It won't work with v1.x motor shields! Only for the v2's with built in PWM
control

For use with the Adafruit Motor Shield v2 
---->  http://www.adafruit.com/products/1438
*/

#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61); 

// Select which 'port' M1, M2, M3 or M4. In this case, M1
Adafruit_DCMotor *myMotor = AFMS.getMotor(1);
Adafruit_DCMotor *myMotor2 = AFMS.getMotor(2);


// These variables store the flash pattern
// and the current state of the motor
 

int motorState = 0;             // ledState used to set the motor
unsigned long previousMillis = 0;        // will store last time motor was updated
long OnTime = 0;           // milliseconds of on-time
long OffTime = 0;          // milliseconds of off-time

void setup() 
{

  
  //Motor
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Adafruit Motorshield v2 - DC Motor test!");

  AFMS.begin();  // create with the default frequency 1.6KHz

  
  // Set the speed to start, from 0 (off) to 255 (max speed)
  myMotor->setSpeed(150);
  myMotor->run(FORWARD);
  // turn on motor
  myMotor->run(RELEASE);
   myMotor2->setSpeed(150);
  myMotor2->run(FORWARD);
  // turn on motor
  myMotor2->run(RELEASE);       
}

//Funktion Motor
void motor(Adafruit_DCMotor *motor, long onTime, long offTime, int motorState, int previousMillis)
{
  // check to see if it's time to change the state of the LED
  unsigned long currentMillis = millis();
 
  if((motorState == 1) && (currentMillis - previousMillis >= OnTime))
  {
    motorState = 0;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    motor->run(FORWARD);
  }
  else if ((motorState == 0) && (currentMillis - previousMillis >= OffTime))
  {
    motorState = 1;  // turn it on
    previousMillis = currentMillis;   // Remember the time
    motor->run(RELEASE);
  }
}
void loop()
{
  motor(myMotor, 1000, 2000, 0, 0);
  motor(myMotor2 , 2000, 4000, 0, 0);
}

Ist dass das erste mal dass du Funktionen schreibst? Schau dir mal den Unterschied zwischen "call by value" und "call by reference" an. Ganz wichtig.

Wenn du so eine Variable übergibst wird in der Funktion eine Kopie angelegt. Diese bearbeitest du und alle Änderungen gehen am Ende verloren.

Was du willst ist das:

void motor(Adafruit_DCMotor *motor, long onTime, long offTime, int& motorState, int& previousMillis)

Durch das & wird eine Referenz übergeben. Also ähnlich einem Zeiger nur die Adresse und Änderungen in der Funktion sind nach außen sichtbar

Dann ist es völliger Quatsch dass du die Zustände der Motoren in Variablen verwalten willst (soweit richtig), aber dann beim Funktionsaufruf 0, 0 statt diese Variablen übergibst.

Du brauchst auch für jeden Motor eigene Variablen und nicht die gleichen für verschiedene Motoren. Am übersichtlichsten ist es wenn man alle Variablen die zu einem Motor gehören in einem struct zusammenfasst und dass für jeden Motor ein Objekt anlegt. Dann kann man auch beim Funktionsaufruf einfach eine Referenz auf das Objekt übergeben (wobei man da den Prototyp der Funktion dann explizit oben hinschreiben muss, sonst spinnt die IDE!)