Paar Probleme mit analogWrite beim wechsel von Mega auf Due

Hallöchen, ich bin noch relativ frisch in der Arduino Thematik und habe die letzte Woche ein wenig mit einem Mega rumprobiert. Ich steuere drei DC Motoren über PWM. Weil ich mit der Ausleseauflösung nicht zufrieden war bin ich jetzt auf einen DUE gewechselt um 12 bit zu nutzen. Leider zeigt mein code jetzt auf ein mal einiger sehr merkwürdige Fehler/Verhaltensweisen.

Fehler 1: Ich initialisiere im Setup meine Motoren und setze den PWM jeweils auf null. Wenn ich das bei Motor 1 und 3 mache kein Problem, aber bei Motor 2 gibt er mir auf ein mal eine scheinbar Due spezifische Fehlermeldung: assertion "duty <= pPwm->PWM_CH_NUM[ul_channel].PWM_CPRD" failed: file "../source/pwmc.c", line 272, function: PWMC_SetDutyCycle

Fehler 2: Ich lese testweise einen Poti aus, um alle 3 Motoren speedtechnisch zu steuern. Beim Mega kein Problem, beim Due scheint das Board sich nach ein paar Sekunden aufzuhängen, wenn ich die PWM Ausgänge im Loop verändere..

Hier der ein bisschen abgespeckter Code:

//define motor pins
#define m1p1 2
#define m1p2 3
#define m1pwm 4
#define m1fdb 3

#define m2p1 5
#define m2p2 6
#define m2pwm 7
#define m2fdb 4

#define m3p1 8
#define m3p2 9
#define m3pwm 12
#define m3fdb 5

int mspeed[] = { 0, 0, 0 };
bool mdir[] = { false, false, false };

void setup() {
//initialise motors
  //motor01
  pinMode(m1p1, OUTPUT);
  pinMode(m1p2, OUTPUT);
  pinMode(m1pwm, OUTPUT);
  setMotorDir(0, mdir[0]);
  setMotorSpeed(0, mspeed[0]);
  delay(200);

  //motor02
  pinMode(m2p1, OUTPUT);
  pinMode(m2p2, OUTPUT);
  pinMode(m2pwm, OUTPUT);
  setMotorDir(1, mdir[1]);
  setMotorSpeed(1, mspeed[1]);  //Fehler 1: Wenn ich diese Zeile ausklammer funktioniert alles..!?
  delay(200);
  //motor03
  pinMode(m3p1, OUTPUT);
  pinMode(m3p2, OUTPUT);
  pinMode(m3pwm, OUTPUT);
  setMotorDir(2, mdir[2]);
  setMotorSpeed(2, mspeed[2]);
  delay(200);
}
//set the direction of a motor
void setMotorDir(int index, bool dir) {
  if (index == 0) {
    if (dir) {
      digitalWrite(m1p1, LOW);
      digitalWrite(m1p2, HIGH);
    } else {
      digitalWrite(m1p1, HIGH);
      digitalWrite(m1p2, LOW);
    }
  } else if (index == 1) {
    if (dir) {
      digitalWrite(m2p1, LOW);
      digitalWrite(m2p2, HIGH);
    } else {
      digitalWrite(m2p1, HIGH);
      digitalWrite(m2p2, LOW);
    }
  } else {
    if (dir) {
      digitalWrite(m3p1, LOW);
      digitalWrite(m3p2, HIGH);
    } else {
      digitalWrite(m3p1, HIGH);
      digitalWrite(m3p2, LOW);
    }
  }
  mdir[index] = dir;
}

//set the speed of a motor
void setMotorSpeed(int index, int speed) {
  if (index == 0) {
    analogWrite(m1pwm, speed);
  } else if (index == 1) {
    analogWrite(m2pwm, speed);
  } else {
    analogWrite(m3pwm, speed);
  }
  mspeed[index] = speed;
}

void loop(){
  int pRead = analogRead(0);
  int pWrite = map(pRead, 0, 1023, 0, 255);
  for (int i = 0; i < 3; i++)
  //setMotorSpeed(i, 255); //Fester Wert funktioniert
setMotorSpeed(i,pWrite); //  Fehler 2: Dynamischer Wert crasht nach ein paar Sekunden
}

Ich hoffe ihr könnt mir hier ein wenig weiterhelfen..

Wenn du eine 12bit Auflösung beim DUE analogRead haben willst, solltest du die Sache mit dem map nochmal überdenken.
So ist es übrigens nur die etwas krumme Version einer Division durch 4. (bzw die eigentlich gemeinte Bitschieberei >>2 , von 10 auf 8 bit).

Oder verwendest du analogReadResolution gar nicht in deiner Original-Version?

Die Pins scheinen auch teilweise doppelt belegt?

Fehler oder Absicht?

Ah ja noch Fehler. die fdb benutze ich im moment nicht und habe noch alte Nummern drin..

Hallo,
hab Deinen Sketch mal in die IDE geladen. Der Compiler gibt bei mit keinen Fehler aus

Arduino IDE 1.8.19
SAM Boards Ver. 1.6.12

Teste kann ich leider nicht, habe keinen Due.

Mal einen andere Frage , warum legst Du die pins nicht auch in einem Array an dann sparst Du dir die Abfrage mit dem Index.
so in der Art

const byte pwmpin[] = {4, 7, 12};
const byte p1[] = {2, 5, 8};
const byte p2[] = {3, 6, 9};

void setup() {

  for ( byte i = 0; i < 3; i++) {
    pinMode(p1[i], OUTPUT); // zugriff auf den Pin
    pinMode(p2[i], OUTPUT);
    analogWrite(pwmpin[i],0);
  }
}
  void loop() {
    // put your main code here, to run repeatedly:

  }

Wieso Benutzt Du nicht einen externen ADC?
zB ADS1115 / 4 Kanäle 16 Bit. I2C.
Auch gibt es externe PWM mit mehr Auflösung
zB PCA9685 16 Kanäle 12 Bit I2C

Grüße Uwe

jo gute Idee. Bin mittlerweile komplett auf arrays umgestiegen..

Ah cool! Wie gesagt ich fange gerade erst mit der Materie an.. Habe mal einen ADS1115 bestellt..

Vieleicht hätte ich prezisieren sollen um nicht unklahr zu sein:
Arduino MEGA 2560 und externen ADC / externes PWM.
Grüße Uwe

Moin UWE,

habe den 1115 verbaut und bin begeistert von der Auflösung!

Habe nur ein kleines Problemchen.. Ich nutze die Adafruit library dazu und lese meine 2 Sensoren im main loop aus. Leider wird dadurch mein loop (in dem auch meine motoren fahren) sehr langsam. Mit beiden auslese-calls kommt er nur auf 14 Durchläufe die Sekunde. Gibt es hier Tricks/ Möglichkeiten den die Sensoren evtl asynchron auszulesen?

I2C?
Mega?

Dann:
In der Theorie: Ja!

Im Prinzip kann die gesamte Kommunikation im ISR Betrieb laufen.
Und damit asynchron zum Hauptprogramm.

Leider steht da Wire und auch Adafruit quer im Wege rum.

I2C Due in meinem Fall. Könnte aber zum Mega zurückwechseln. War eigentlich auf den Due umgestiegen wegen den 12 bit, welche ich mit dem 1115 jetzt gar nicht brauche..

Den kenne ich nicht so gut!
Aber auch da sollte ein reiner Interruptbetrieb möglich sein.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.