Servo Messfehler bei Interrupts

Hallo ich bin neu hier und auch neu in Sachen Mikrokontroller sowie Programmieren unterwegs.
Ich heiße Christian bin 35.
Ich "programmiere" seit ca. 14 Tagen.

Ich möchte mein Blockheizkraftwerk mit einen Mega 2550 steuern.

Problem:

In meinen Programm, wird für das Einlesen von Pulsen, eine Sekunde ein Interrupt aktiviert, welcher mir dann die Umdrehungen errechnet. Ist der Servo jedoch physikalisch angeschlossen, stört er bei der Messung rein und mogelt mir viele Pulse bei. Ohne Servo alles super. Auch ein Wechsel auf andere Interrupts brachte nichts. (Der Servo steuert die Drosselklappe)
Ich dachte mir, als Lösung, ich trenne vor der Messung den Servo mit : myservo.detach(); und nach der Messung möchte ich ihn wieder einhängen mit attach..(Was generell schon doof ist)
Das Einhängen/ Reaktivieren des Servos kappt nicht. Trennen klappt super, Messung ist dann auch ok. Normal steht attach auch im Setupteil, welcher nie wieder ausgeführt wird…

Ich weis im Moment nicht weiter als einen zweiten Controller zu nehmen und diesen nur zum Messen benutze....
Kennt jemand das Problem mit den Servos ? ( Auch andere Servomodelle machen den gleichen Fehler)
Wäre super wenn Ihr mir helfen könnt.

Liebe Grüße und einen guten Rutsch
Christian

Wenn das Problem wirklich nur bei angeklemmtem Servo auftritt, dann ist es ein elektrisches (irgendwelche Störungen, Versorgungsspannung...).

Andernfalls tippe ich mal auf Probleme mit einem gemeinsam verwendeten Timer, für unterschiedliche Zwecke, oder sonst einem Softwareproblem, das sich sicher irgendwie lösen läßt. Aber ohne weitere Informationen oder Code geht das schlecht.

Eifelchris:
Ich möchte mein Blockheizkraftwerk mit einen Mega 2550 steuern.

Das halte ich für gewagt :slight_smile: Ich hoffe, es geht nur um ein kleines Kraftwerk und Du bist der Einzige, der friert, wenn der Arduino nicht tut, was er soll.

Mein aktuelles Gebastel enthält ebenfalls einen Servo. Mein Problem mit ihm war, dass er auch im Stillstand nicht ganz ruhig war. Nach einem „detach()“ ist er allerdings wirklich stumm.
Ich habe daher detach()/attach() entsprechend in meinen Sketch eingebaut. Nach einem attach() pausiere ich eine Zehntelsekunde, dann funktioniert alles wie gewohnt.

Es mag doof sein, den Servo an- und abzustöpseln, aber wenn es zum Ziel führt, ist das eben so (meine ich). Meistens denke ich beim Programmieren nicht an Dinge wie die Versorgungsspannung usw. und versuche, „schön“ zu programmieren. Wenn allerdings Probleme auftauchen, die sich (aus meiner Sicht) nur durch eigentlich „doofe“ Programmierereien beheben lassen, dann handle ich auch mal nach dem Motto „nimm, was funktioniert“.

HTH

Gregor

Hallo,

ein Servo wird wohl immer etwas zappeln. Wie stark hängt von seiner Last ab die an ihm hängt und/oder ob er unterdimensioniert ist. Er will ja immer die vorgegeben Position halten. Dazu muß er intern regeln.

Wenn man ihn detach, sollte er seine Position nicht mehr halten können. Bekommt dann im Normalfall keine per PWM Positionsdaten mehr.

Auf jeden Fall benötigt er stabile 5V. So ein Servo zieht immer kurz höhere Ströme wenn nötig.
Die 5V würde ich auch nicht vom Arduinoboard nehmen.
Massen sind zusammen?
Was haste für ein Servo?

Hallo vielen Dank für Eure Beiträge.

@Gregor: Ja bei mir zappelt der Servo auch ab und zu OHNE Last etwas, ca. alle 20 sek. hört man etwas, ohne sichtbare Armbewegung. Verwendet habe ich einmal den SG90 zum experimentieren und für den tatsächlichen Einbau den RS2MG/BB. Beide machen das Problem.

Abkoppeln ist suboptimal, da die Drosselklappe dann für einen Moment undefiniert ist und in jede Richtung schwingen könnte. 500 bis 1000 milis dauert die Messung...

Der Fehler tritt auch mit Netzteil auf.

Off Topic :
Die BHKWs die ich baue sind klein (ca 30kw elek.) Ich baue in meiner Freizeit auch Holzvergaser und betreibe die BHKW's damit. Mache auch mit Wasserstoff, Geet etc rum. Gibt viele Videos unter www.eifelchris.de
Das zweite BHKWs steure ich derzeit mit einen Tempomaten. Ich will es mit einen Arduino halt eleganter und vollständig lösen.

@DrDiettrich
Code für das reine Messen habe ich im Web gefunden, klappt super ist im Anhang dieses Posts.

Danke Euch!
Grüße
Christian

Hall.txt (1.78 KB)

Vermutlich macht das delay(1000) Ärger, und damit ist dieser einfache Ansatz unbrauchbar.

Vermutlich? Längere delays machen über kurz oder lang fast immer Ärger.

Hallo,
ja das habe ich auch vermutet und auch das Delay auf 100 milis mal gestellt, dass Messen wird dann ungenauer. (klar weniger Pulse) Kurzes Delay ist in der Messmethode leider nicht anwendbar. 500 mils müssen es schon sein. Störfaktor bleibt aber der Selbe, bzw. wird noch schlechter. Der Servos pulst ja sporadisch nach Lust und Laune rein.

Ich werde den Weg gehen und über einen zweiten Mega oder Uno das reine messen übernehmen lassen und mir dann die Werte, Zu schnell, zu langsam, Drehzahl ok über Pins dem Hauptboard übermitteln.

Gibt es denn eine Möglichkeit, das zwei Boards miteinander kommunizieren können?
Ich meine hier, dass Daten Wörter ausgetauscht werden. Beispiel Drehzahl = 1500

Danke Euch!

LG Christian

wenn ich das richtig verstanden habe, willst du mit dem Interrupt die Impulse eines Hallgebers für die Drehzahl auslesen?

Hi genau, habe eine Hallsensor Modul welches ich auswerten muss. Ziel sind Umdrehungen pro Minute.

zu meinen vorherigen Post Nachtrag:
Ich habe auch gerade gelesen, dass man via I2C Bus auch Daten von Board zu Board übertragen kann.

Das wäre dann Plan B.

@ardubu hast du eine andere Idee wie ich Pulse einlesen / auswerten kann außer über Interrupts?

Danke und Grüße
Christian

nein, auch mit Interrupt, aber ohne delay, im Prinzip ein einfaches Tacho Programm

[/ 
#define READPIN 2       // Pin für Reed-Kontakt, Digital-2 für Interrupt 0
#define REEDINTERRUPT 0 // Hardware-Interrupt für den Reed-Pin (Tacho)
volatile int reedCountSum;
volatile long reedMillisSum;
float impulse;
unsigned long letzteSekunde=0;
unsigned long lastReedMillis;

void Setup()
{
Serial.begin(9600);
  attachInterrupt(REEDINTERRUPT, reedISR, FALLING);// prüfen des Signals auf fallende Flanke
  }

void loop()
{
    
    // Anzeige wird einmal pro Sekunde aktualisiert
    if (millis()-letzteSekunde>1000) 
   {tacho();
     Serial.print(Impulse); //Impulse je Sekunde
     impulse=0;
    reedCountSum = 0;
    reedMillisSum = 0;
    letzteSekunde=millis(); 


  

  void reedISR()
  {
      reedCountSum++;                           // Impulse addieren
      reedMillisSum+=millis()-lastReedMillis;   // Zeit addieren
      lastReedMillis=millis();                  // Zeit merken
    }
  
  void tacho()
{
  if (reedMillisSum >0 && reedCountSum>2) // Division durch null abfangen
      detachInterrupt(REEDINTERRUPT); // Interrupt deaktivieren um das Rechnen nicht zu unterbrechen.
      impulse = reedCountSum*1000.0/reedMillisSum;
      attachInterrupt(REEDINTERRUPT, reedISR, FALLING);
  if (millis()-lastReedMillis>150) impulse=0;    // wenn 150 ms kein Signal kommt Impulszähler auf null setzen 
 }code]

Oh Vielen Dank.

ich bekomme es aber nicht Kompiliert, bin noch nicht so Codesicher. Habe noch ein paar Klammern und groß Kleinschreibungen bei Impulse geändert. Die letzten Fehler finde ich aber nicht.

Arduino: 1.7.8 (Windows 8.1), Platine: "Arduino Mega or Mega 2560, ATmega2560 (Mega 2560)"

Tachoprogramm.ino: In function 'void loop()':

Tachoprogramm.ino:32:3: error: a function-definition is not allowed here before '{' token

Tachoprogramm.ino:39:1: error: a function-definition is not allowed here before '{' token

Tachoprogramm.ino:45:2: error: expected '}' at end of input

Fehler beim Kompilieren.

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

Eifelchris:
In meinen Programm, wird für das Einlesen von Pulsen, eine Sekunde ein Interrupt aktiviert, welcher mir dann die Umdrehungen errechnet. Ist der Servo jedoch physikalisch angeschlossen, stört er bei der Messung rein und mogelt mir viele Pulse bei. Ohne Servo alles super. Auch ein Wechsel auf andere Interrupts brachte nichts. (Der Servo steuert die Drosselklappe)

Wie ist den das Zeitverhalten der zu messenden Impulse? Dauer, Verhältnis?

sorry, hatte noch beim Zusammenstricken ein paar Fehler eingebaut, hier nochmal, hoffentlich fehlerfrei

[/

#define READPIN 2       // Pin für Reed-Kontakt, Digital-2 für Interrupt 0
#define REEDINTERRUPT 0 // Hardware-Interrupt für den Reed-Pin (Tacho)
volatile int reedCountSum;
volatile long reedMillisSum;
float impulse;
unsigned long letzteSekunde=0;
unsigned long lastReedMillis;

void setup()
{
  Serial.begin(9600);
  attachInterrupt(REEDINTERRUPT, reedISR, FALLING);// prüfen des Signals auf fallende Flanke
  }

void loop()
{
    
    // Anzeige wird einmal pro Sekunde aktualisiert
    if (millis()-letzteSekunde>1000) 
    { 
     tacho();
     Serial.print(impulse); //Impulse je Sekunde
     impulse=0;
     reedCountSum = 0;
     reedMillisSum = 0;
     letzteSekunde=millis(); 
    }
}


  

  void reedISR()
  {
      reedCountSum++;                           // Impulse addieren
      reedMillisSum+=millis()-lastReedMillis;   // Zeit addieren
      lastReedMillis=millis();                  // Zeit merken
    }
  
  void tacho()
{
  if (reedMillisSum >0 && reedCountSum>2) // Division durch null abfangen
      detachInterrupt(REEDINTERRUPT); // Interrupt deaktivieren um das Rechnen nicht zu unterbrechen.
      impulse = reedCountSum*1000.0/reedMillisSum;
      attachInterrupt(REEDINTERRUPT, reedISR, FALLING);
  if (millis()-lastReedMillis>150) impulse=0;    // wenn 150 ms kein Signal kommt Impulszähler auf null setzen 
}
code]

Irgendwie fehlt ein Post von mir....
Vielen Dank ich bekomme nun Werte.
Ich muss nur noch Impulse in RPM Umrechnen und in mein Hauptprogramm integrieren. Mal schauen wie es sich verhält.

Schon mal vielen Dank :smiley:

Ich muss nur noch Impulse in RPM Umrechnen

einfach Impulse/sek X 60 = RPM

Ja das klappt auch :smiley:
Habe noch auf Pin 18 und Interrupt 5 umgeschrieben.
werde es gleich mal in das Hauptprogramm integrieren.
Mal schauen was der Servo bzw die Messung dann macht.

LG Christian

was hat dein Hallsensor Modul für einen Ausgang? Hast du einen Link zu dem Modul?

Hallo,

habe es mit Servo versucht, leider exakt das selbe Problem. Servo stört rein.

Hallsensor: Arduino Raspberry kompatible Linear Hall Magnetic Sensor Module KY-024

http://www.ebay.de/itm/262183864307?_trksid=p2057872.m2749.l2649&ssPageName=STRK%3AMEBIDX%3AIT

Ich benutze den A0 auf der kleinen Platine des Hallsensors.

LG Christian

Ich benutze den A0 auf der kleinen Platine des Hallsensors

Ich denke du solltest den D0 nehmen. da der A0 ein Analogen Signal rausgibt.