Eingangsfrequenz

Hallo Forum,

ich bin neu auf dem Gebiet Microcontroller, habe jedoch eine abgeschlossene Berufsausbildung als Elektroniker für Automatisierungstechnik und bin Momentan auf einer Technikerschule um mich weiter zu bilden.

Ich bastle momentan ein wenig mit einem UNO Board und versuche seit gestern einen Drehgeber auszuwerten.

Zu den Fakten:

Drehgeber --> 500 Pulse/Umdrehung
Motor --> 1300 1/min

Problem:

Drehe ich den Drehgeber von Hand genau um 360° bekomme ich exakt 500 Pulse. Sobald ich meinen Motor anhänge verschluckt er sich.

Daraus ergeben sich auch die Fragen:

Wie hoch ist die mögliche Eingangsrequenz der Eingänge des Arduino Uno Boards?
Ich zähle die Impulse und gebe sie per Serial auf den Rechner weiter. (115200)
Ist nun die Frequenz am Eingang zu hoch oder verschluckt er sich erst bei der Übertragung.

Vielen Dank im voraus für eure Antworten .

Hallo FTE11

Die serielle Schnittstelle bremst den Controller aus.
Ca 11kHz müßten kein Problem für den Arduino sein. Das Problem liegt in Deinem Code.
Poste mal den Kode.

Viele Grüße Uwe

Hey Uwe,

dass ist ja schon mal beruhigend!
Anbei mein Code.

Weist du auch gerade die maximale Obergrenze der Eingagsfrequenz?

Grüße

int pin1 = 2;
int pin2 = 3;
int counter;
boolean goingUp = false;
boolean goingDown = false;
void setup()
{
  counter = 0;
  
  Serial.begin(115200);

  
  pinMode(pin1, INPUT); // Pin 2
  pinMode(pin2, INPUT); // Pin 4 

 
  attachInterrupt(0, decoder, FALLING);

}

void loop()
{
  
  while(goingUp==1) 
  {
    goingUp=0; 
    counter ++;
    Serial.println(counter);
  }

  while(goingDown==1)
  {
    goingDown=0; // clear the flag
    counter --;
    Serial.println(counter);
  }
}

void decoder()

{
  if (digitalRead(pin1) == digitalRead(pin2))
  {
    goingUp = 1; 
  }
  else
  {
    goingDown = 1; 
  }
}

Interruptfunktionen sollen so kurz wie möglich sein!!

void decoder()
{
  if (digitalRead(pin1) == digitalRead(pin2))
  {
    goingUp = 1; 
  }
  else
  {
    goingDown = 1; 
  }
}

Da die Interruptroutine nur bei der fallenden Flanke von pin1 angesprungen wird hat diese Kontrolle wenig Sinn
Ich nehme mal an, daß der Motor in beide Richtungen drehen kann.
anstatt:

if (digitalRead(pin1) == digitalRead(pin2))

genügt:

if (digitalRead(pin2))

Außerdem würde ich nicht 2 Variablen für die Drehrichtung verwenden sondern nur eine; zB: 1 rechtsdrehend, 0 linksdrehend
dann vereinfacht sich alles auf:

void decoder()
{
drehrchtung = digitalRead(pin2);
}

oder noch einfacher:

void decoder()
{
counter --;
counter += 2*digitalRead(pin2); 
}

Mußt Du bei jedem Impuls den Zählerstand an den PC übertragen?
Wenn Ja, auf diese Weise könntest Du Übertragungen verlieren aber keine Impulse.

Grüße Uwe

Hey Uwe,

habe es gerade ausprobiert.
Sieht gut aus.
Ich übergebe jetzt nur noch jeden 500sten Puls an den Rechner. Also pro Umdrehung einen. Dann komme ich relativ genau hin!

Meinst das klappt auch noch bei 3000 1/min?

Grüße

FTE11:
Meinst das klappt auch noch bei 3000 1/min?

Locker
Muß der Motor sich in beide Richtungen drehen?
Grüße Uwe

Davon abgesehen gehört vor die Variablen die in der ISR gesetzt werden bei der Deklaration ein "volatile". Ansonsten kann es unerwartet passieren, daß der Compiler Zugriffe auf die Variablen wegoptimiert. Das führt dann in der Regel zu langen verwirrenden Fehlersuchen.

uwefed:
Locker

Auch wenn ich noch weitere Eingänge auslesen und zum Beispiel einen Analogausgang (um den Moto selbst an zu steuern) verwende?
Ja er muss in beide RIchtigen drehen können.

@Udo, danke gut zu wissen!

Was für ein Motor ist das?
Ein Aynchron-Drehstrom-Käfig-Läufer?
Mit Frequenzumrichter?
Grüße Uwe

@FTE11: gerne, ich habe den Fehler schon mal selber gemacht und 2 Wochen wie doof gesucht ...

uwefed:
Was für ein Motor ist das?
Ein Aynchron-Drehstrom-Käfig-Läufer?
Mit Frequenzumrichter?
Grüße Uwe

Gleichstrommtor(1A 24V 30001/min) über eine H-Brücke angesteuert.

Grüße

H Brücke und PWM?
Grüße Uwe

uwefed:
H Brücke und PWM?
Grüße Uwe

genau.

Leider muss ich diesen Thread noch mal benutzen.

Bedingungen sind die gleichen geblieben:

  • Gleichtstrommotor gekoppelt an Drehgeber
  • Gleichstrommotor wird mittels PWM und H Brücke geregelt
  • Drehgeber gibt 500 Impule/Umdrehung
  • Gleichstrommotor bringt bei 24V 3000 1/min

Gebe ich der Regelung einen possitiven Sollwert funktioniert alles einwand frei.
Gebe ich der Regelung einen negativen Sollwert (Motor dreht in die andere Richtung) rasst der Motor leider los ohne die Pulse auszuwerten.

Mein bisheriges vorgehen:

Umdrehen der Drehgebereingänge
Hat zur Folge dass das ganze nun gerade umgekeht funktioniert. Also mit nagativen Sollwert ist alles ok, mit possitiven rasst der Motor

Flanken mittels Osszi beobachtet
Die Pulse kommen beide sauber, auch bei hoher Drehzahl

Verminderung der Spannung
Fällt die Versorgungsspannung des DC-Motors unter 20V funktioniert es.

Nun woran kann es liegen, meine erste Vermutung, die Frequenz an den Eingängen, die wird jedoch mit dem Versuch des Umdrehen der Drehgebereingänge wiederlegt. Momentan stehe ich ein wenig auf dem Schlauch.

Anbei noch mal den Code zu Auswertung der Impulse vom Drehgeber:

void decoder()
{
  counter --;
  counter += 2*digitalRead(pin2);
}

Ich steh auch etwas daneben.

Bitte Schaltbild; Modell des Drehgebers, des Motortreibers (H Brücke) und des gesamten Sketches.

Grüße Uwe

Hey Uwe,

Der Drehgeber:

H Brücke und Elektrische Übersicht, siehe Anhang.

Grüße

Übersicht Elektrisch.pdf (16.6 KB)

Ansteuerung mit L620x.docx (192 KB)

Was mir einfällt ist:

void decoder()
{
counter --;
counter += 2*digitalRead(pin2);
}

Das ist die Interruptroutine durch eine Flanke an Phase 1 des Drehgebers aufgerufen wird. Es könnte sein daß die Anweisung "counter --;" zuviel Zeit in Anspruch nimmt und die 2. Phase bereits wieder Status geändert hat bevor Du deren Zusatand in "counter += 2*digitalRead(pin2);" ausliest.
Bei 20V läuft der Motor dann langsam genug, daß es nicht passiert.

Versuch mal die Sache umzukehren:

void decoder()
{
counter += 2*digitalRead(pin2);
counter --;
}

Grüß Uwe

Einen Integer runterzuzählen kostet maximal 2-3 Takte. Bei 16 Mhz sollte man davon so gut wie nichts merken. digitalRead hingegen ist laaaaannnnngggsssaaaaaammmm. Wenn das wirklich unter Verdacht steht würde ich vorschlagen die Ports direkt auszulesen. Im Playground steht wie: Arduino Reference - Arduino Reference.

Und nur zur Sicherheit: ist der counter jetzt "VOLATILE" deklariert oder fehlt das noch? Zeig uns doch bitte mal das komplette Programm.

Ich denke wenn man auszüge aus dem Sketch hier verwendet:
Und die Funktion read_encoder anpasst an die Pins die man verwendet und die Funktion über einen Interrupt ausführt könnte das alles um einiges schneller werden
http://www.circuitsathome.com/mcu/reading-rotary-encoder-on-arduino