Signale von Graupner GR-12L auslesen

Hallo Michael,
Ich habe gestern den Leseanteil in meine Motorsteuerung eingebaut. Da ergibt sich noch eine Frage:
Auf Seite2 gleich nach dem ersten Anzeigeblock stehen u.a. die Anweisungen

pulslaenge1=channel(0);

Der Compiler reklamiert das und sagt man könne das so nicht zuweisen.

exit status 1
'channel' cannot be used as a function

Warum kann ich im Anzeigeblock channel(0) anzeigen aber der Int-Variablen nicht zuweisen?
Grüße Fiete
 

Anhänge

  • Motorsteuerung SUMD.pdf
    19,2 KB · Aufrufe: 322
Hallo,
Ich bin immer noch am kämpfen und heute total frustriert. Ich hatte Programm und Hardware fertig und wollte alles einbauen. Bei der letzten Prüfung auf der Werkbank liest das Board plötzlich keine Empfänger-Signale mehr. Ich dachte erst der Empfänger wäre verstorben, aber nein, der Ozi zeigt das Summensignal. Nächste Vermutung RX1 wäre tot. Aber auch mit RX2 und RX3 ohne Erfolg probiert. (Natürlich das Programm jeweils angepasst!) Dann anderes Mega-Board geholt und probiert. Gleiche Ergebnisse. Ich habe dann das von Michael geprüfte Basis-Programm geladen. Auch hier kommt nur noch NULL an. Jetzt hatte ich heute morgen die neue Ardu-Version 1.8.10 installiert. Nächste Vermutung, hat vielleicht die noch eine Macke? Also wieder zurück auf 1.8.9. Aber auch hier keine Signalauswertung. Habt Ihr noch eine Idee? Schrottet 1.8.10 wohlmöglich die RX-Eingänge????
Grüße Fiete
 
Hallo,
ich habe weiter gesucht.
1. Frage : Ist das Signal des GR12L-SUMD in Ordnung? 2-2,5V ??

SUMD-OZI.jpg

2. Frage: Ich habe einen minimal-sketch erstellt, der wenn er Signale lesen kann mit der OnBoard LED 13 kurz blinken sollte.

Anhang anzeigen SUMD-1-2.pdf

Alles auf einen fabrikneuen Mega hochgeladen - geht aber nicht!
Kann mir jemand aus meinem Frust helfen?

Grüße vom Fiete
 
Das Problem mit der Anzeige konnte ich lösen.
Man hat im Code "lcd.begin" in "lcd.init" geändert. Sowie "lcd.backlight" zwingend eingeführt. Das muss man erst mal rausfinden.
Bleibt noch das Thema "Empfang auf RX".
 

mha1

User
Ich habe leider gerade keinen Empfänger zum Spielen da, deshalb nur Trockenübung. Was auffällt:

warum #include <wire.h>? brauchst Du für das Beispiel im pdf nicht.
--> keine includes, die Du nicht brauchst

int val = Serial2.read();
der Datentyp int ist ein 16Bit signed integer. Auch wenn die Arduino Beispiele das so machen ist es eigentlich falsch. Über die serielle Schnittstelle werden immer nur Bytes übertragen.Jedes Serial.read() liefert 8Bit.
--> besser uint8_t val = Serial2.read();

delay(50)
SUMD schickt alle 10ms einen Frame. Du stoppst mit dem Delay das Programm und verdonnerst es 50ms nichts zu tun. Nennt man busy wait. Du verpasst nach jedem ordentlich empfangenen Frame immer die nächsten 5.
--> Zeit spielt eine Rolle. Busy waits sind immer schlecht.

Formatierung
Dein Code sieht grauslig aus, ist schwer lesbar und so kaum per Braindebugger zu debuggen. Lerne Code zu strukturieren. Einrücken, Leerzeilen, Kommentare usw. Zum Anfang: Tools/Auto Format in der Arduino IDE drücken.

All das wird wahrscheinlich nicht die Ursache sein warum es nicht funktioniert. Dein Oszillogramm sieht nicht gut aus. Die Pegel sollten sauber zwischen ca. 0V und 3V liegen. So kann das nicht funktionieren. Sieht nach Last auf dem Pin aus, d.h. ich vermute einen Verdrahtungsfehler. Klemm mal das Arduino board ab und schaue Dir direkt am empfänger an, wie das dort aussieht. Kannst ja mal Detailbilder zu Deiner Verdrahtung machen.

VG Michael
 
Guten Morgen Michael,
Danke für Deine Hinweise!! Zwei Fehler gleichzeitig können einen schon zur Verzeiflung bringen.
Ich habe parallel weitergesucht und auch den zweiten Fehler gefunden. Der Empfänger (4 Wochen alt) ist schrott. Mit einem anderen (ausgeborgten) Gr12L läuft alles planmäßig. Hier ein Bild vom korrekten Signal:

GR-12L.jpg

Was die Codestruktur angeht, habe ich mea culpa nur das Forumsmuster um meine Anteile erweitert. Dieses ist auch nicht mein vollständiger Sketch sondern nur eine Testversion.
Ich werde mir Deine Hinweise zu Herzen nehmen! Habe mich eh schon gewundert welche Funktion Wire.h hat.

Nur noch eine Frage: Gibt es einen Grund so einfach von "serial.begin()" zu "serial.init()" zu wechseln? Bis man auf so was kommt -------?

Grüße und Vielen Dank vom Fiete
 

mha1

User
Serial.init() gab und gibt es auch in 1.8.10 nicht. Ist nach wie vor Serial.begin().

Kleine Denksportaufgabe zur Frage, ob Dein Programm nicht nur meistens funktioniert, sondern auch robust ist. Denke mal folgende Situation durch: Du startest Dein Programm und erwischt mit der ersten Abfrage von Serial.available() nicht eine Lücke zwischen den Frames, sondern mitten in den Frame. Und dummerweise ist das erste Byte das Du liest ein Datenbyte, das zufälligerweise, aber völlig berechtigt den Wert 0xA8 hat. Viel Erfolg beim Robustmachen.
 
Guten Abend Michael,
War heute ausser Haus. Ich vermute, das Du an meine Fähigkeiten viel zu hohe Ansprüche stellst. Ich bin hier absoluter Newcomer. Vor vielen Jahren habe ich in "Siemens-Prosa" und dann in "Business-Basic" gearbeitet. Dann nach einer Pause auch mal in "PIC". Vielleicht verstehst Du jetzt meine Strukturprobleme mit diesem Code.
Jetzt zu meinem aktuellen Hobby. Eine ferngesteuerte selbstfahrende Maschine mit Kettenantrieb, Die Ketten werden von BLDC-Motoren angetrieben. Die Controller der Motoren vom Arduino gesteuert. Den Arduino hatte man mir hier im Forum empfohlen. Ich fand und finde ihn auch ganz handlich. Der Arduino bekommt seine Daten aus der Informationskette Graupner MZ-12pro - GR12L SUMD+2T. Bis zur letzten Woche liefen die Versuche auch ganz zufriedenstellend. Die Antriebe stotterten zwar manchmal minimal, ich vermutete Funkstörungen. (könnte auch Deine Denksportaufgabe befeuern) , aber das konnte ich bislang vernachässigen. Dann musste ich aus anderen Gründen die Controller wechseln, Die neuen Controller hatten eine geänderte Ansteuerung für Vorwärts- Rückwärtsfahrt. Also den Sketch auf zwei zugehörige Steuerkanäle abgeändert und neu hochgeladen. Damit fing das Elend an. Im alten Code stand "serial.begin()", mit der erneuten Kompilierung ging dann nichts mehr, Bis ich nach ]angem Suchen herausfand, das jetzt "serial.init()" verlangt wird. Mit diesem "serial.init()" läuft der Kompiler und der Sketch wieder. Soviel zur Vorgeschichte und zum Grund meiner Frage. Ich verstehe immer noch nicht, warum dieser Wechsel (im Kompiler ?) stattgefunden hat und habe größte Bedenken das jetzt bei jedem Programmstart vorgeschlagene Update zu übernehmen.
Die von Dir gestellte Denksportaufgabe kann ich mangels Kenntnissen in diesem Bereich nicht lösen.
Nun ist das Bessere der Feind des Guten und ich bin lernfähig. Wenn Du mir zu einem robusteren "Signal auslesen" Tipps geben kannst, fände ich das super und wäre Dir sehr dankbar. Ebenso suche ich nach einem Hinweis wie ggfs Code hier im Forum leserlicher hochgeladen werden kann. Den Dateityp .ino mag das häusliche Ladeprogramm nicht. Jetzt habe ich Deine Freizeit lange genug "missbraucht". Vielen Dank nochmal für Deine Zeit und Deine Tipps!
Grüße vom Fiete
 
Bin gestern auf die Lösung mit dem lcd.begin() gestossen. Der Compiler wurde offensichtlich geändert. Bislang wurde der vorgenannte Befehl in dieser Form akzeptiert. Jetzt muss er in folgender Form eingegeben werden u.B. lcd.begin(20,4).
 
Aussetzer Störungen oder falsch konfiguriert

Aussetzer Störungen oder falsch konfiguriert

Hallo Michael,
Du hast im letzten Sommer viel Geduld mit mir gehabt. Es lohnte sich aber. Die Maschine lief. Zunächst. Dann musste ich sie mechanisch erheblich umbauen und wollte sie jetzt wieder in Betrieb nehmen.
Sobald ich die Funkstrecke binde, bekommt die Steuerung sporadisch kurze Störimpulse. Die Motore laufen willkürlich kurz an. Ich habe mir jetzt alles als Miniversion für die Werkbank zusammengestellt (Maschine ist wirklich zu groß für den Schreibtisch) und sehe auch hier die gleichen Effekte. Im Prinzip läuft es ja, wenn nur die Störungen nicht wären.
Ich benutze die MZ12-pro und den GR12L (SUMD). Kann ich in Sender und Empfänger da was verbessern? In der Arduino-Software habe ich auf 8 Kanäle erweitert und das Filter etwas verschärft. Hat aber nichts genutzt. Hast Du noch einen Rat für mich?
 

hsh

User
Gibt es einen Schaltplan oder eine Skizze von der Verkabelung?
Wenn du Arduino-Hardware aus der gleichen Versorgung wie die Servos bedienst, sind Probleme durch Spannungseinbrüche naheliegend.
"Echte" Störungen durch HF-Einstrahlung des Rückkanales sind denbar aber eher unwahrscheinlich.

Überprüfe zuerst per Oszi die Qualität der Signalpegel die du auswertest und die Versorgungsspannung des µC.
Wie hast du den Brown-Out-Reset konfiguriert, oder sind da noch die Standardeinstellungen des ArduinoMega gesetzt?
Kannst du den aktuellen SourceCode zeigen (bitte nicht als *.pdf)?
 
Hallo Harald,
Ich füge Dir ein Bild vom Laboraufbau bei. DerCode ist schon etwas umfangreicher. Da weis ich nicht, wie ich den hier posten kann. Der Controller zieht so wenig Strom und hängt vor dem Stannungsregler. Da kann ich mir eine Beeinflussung kaum vorstellen. Den Code habe ich damals von Holger Lambertus bekommen.
 

Anhänge

  • 20200503_134020.jpg
    20200503_134020.jpg
    375,9 KB · Aufrufe: 185

hsh

User
ok. nur, dass ich nicht verkehrt denke...
Motor-Controller Modul hängt direkt am Netzteil bzw. am Akku
Arduino, Display, Empfänger werden über ein Schaltreglermodul mit 5VDC versorgt
Es gehen 6 Steuersignal zum Motor-Controller (ist das ein L298N basiertes BreakoutBoard? gibt es dazu eine Typenbezeichnung/Hersteller/Schaltplan?)

Wie äußern sich das Fehlverhalten bzw. die Störungen?
Wie ist die Verkabelung im Modell ausgeführt (gesteckt, gelötet)?
Hast du Debug-Ausgaben über die USB-UART Schnittstelle des Arduino implementiert?

Wird das Verhalten besser oder schlechter, wenn du GND des Arduino mit GND des L298N Boards verbindest?
Aktuell geht der Rückstrom deiner Steuersignale über die Schleife Motor-Controller, Spannungsregler, Breadboard. Es ist zwar unwahrscheinlich, aber wenn da 1.5V zusammen kommen, kommt der L298N aus dem Konzept.

In erster Linie musst du eingrenzen, ob du mit Programmierfehlern oder echten Störungen/Programmabstürzen kämpfst.
Wie schaut es aus, wenn du den Betrieb über Testsignale und nicht über den Empfänger machst?

Wenn du das OK von Holger Lambertus bekommst, würde sich ein *.zip mit der *.ino und Angaben zu den genutzten Libraries anbieten.
 

hsh

User
ach ja, hast du dir bei der Entwicklung zwischendurch das Zeitverhalten deines Programmes angesehen?
Wie lange blockiert die Display-Aktuallisierung?
 
Hallo Harald,
Ich werde versuchen Deine Fragen zu beantworten. In der Maschine sind natürlich ganz andere Kaliber von Controllern verbaut (2x48V/ 1,5kW). Aber wie auch im Laboraufbau Ist Masse ein durchgängiges Potential. Für Arduino und GR12L sowie die Steuerleitungen der Controller gibt es einen gemeinsamen 5V Spannungsregler. Ich bin darauf bedacht im Massebereich keine "Brummschleifen" zu erzeugen. Der Laborcontroller ist ein Joy-It mit L298N Baustein. Bis auf die Arduino-Pins sind alle Anschlüsse im System gelötet. Es sind für die Steuerung 6 Eingänge vorhanden 1 = PWM Motor li, 2 Drehrichtung Motor li , 3 wie 2 aber invertiert, 4 Drehrichtung Motor re, 5 wie 4 aber invertiert, 6 PWM Motor re.
Die Störung zeigt sich durch sehr kurze und kurze Fahrimpulse. Die Motore zucken oder fahren sogar kurz an. Auf meinem Display kann ich manchmal die Höhe der Fahrpulse (channel[0] oder channel[1] mit 1400 oder auch 1550 sehen. Das sind ja die original Pulse aus der Empfängerroutine. Unter 1500 ist rückwärts. Auch die anderen Empfängerwerte channel[2] bis [6] zeigen solche Ausreisser. Diese machen sich auf Grund ihrer Funktion aber nicht gravierend bemerkbar.
Diese Störungen kommen nur über den Empfänger. Bei abgeklemmten GR12L-Signal läuft alles fehlerfrei.
Da ich nicht weis, wie ich einen Debug implementieren kann, ist auch keiner drin.
Den Empfänger-Sketch hatte Holger Lambertus in einem Forum veröffentlicht. Ich denke er wird keine Probleme damit haben, wenn er in diesem Zusammenhang noch mal offen gelegt wird. Ich werde versuchen ihn zu erreichen und um Freigabe zu bitten.
Es hat mich ein Kollege, der den Sketch kennt, darauf hin gewiesen, das ich da keine CRC-Prüfung drin habe. Ich muss gestehen, ich wüsste auch nicht, wie ich das machen sollte.
Dein letzter Hinweis zum Zeitverhalten scheint der Lösung ein gutes Stück näher zu kommen. Ich kann das Zeitverhalten zwar nicht messen, aber testweise alle LCD-Anzeigen ausser Betrieb nehmen. Und schon ist Ruhe mit den Störungen.
Das erklärt auch, warum in der großen Maschine im Herbst keine Probleme auftraten. Da waren keine Anzeigen im Programm.
Könnte eine Kombination aus Zeitverhalten und fehlender CRC-Prüfung die Ursache sein?
 

hsh

User
hmm. dann suchst du wahrscheinlich eher nach einem Programmfehler.
Als Hilfe zur Selbsthilfe kann ich dir empfehlen, dir Infos zum Zustand deines Systems einfach über die serielle Schnittstelle ausgeben zu lassen, wenn das Hauptprogramm sonst nichts zu tun hat. Auch Zeitmessungen kannst du den µC einfach selber machen lassen. Das ist zwar nicht immer elegant und ohne Seiteneffekt, aber in den meisten Fällen ausreichend [1].

Ohne Speicheroszilloskop und Logik-Analyzer ist die Abklärung, ob da vom Empfänger etwas komisches kommt, der UART die Synchronisation verliert, oder es dir die Daten im Programmablauf zerschießt, nicht so einfach zu beantworten. Als erstes wäre abzuklären, ob sich eine Regelmäßigkeit finden lässt, und wie oft diese Glitches wirklich auftreten. Ich kenne jetzt das Datenformat von Graupner HoTT nicht, aber wenn es mit einer CRC abgesichert, ist solltest du das auf jeden Fall nutzen, um ungültige Pakete einfach aussortieren zu können.
Wenn du Interrupts nutzt, solltest du dir die Bereiche, wo du die Kanalwerte zwischenspeicherst noch hinsichtlich atomarem Zugriff anschauen. Da die meisten I2C-LCD Libraries die ich in der Arduino-Ecke bisher gesehen habe, oft ca. 10-15ms für ein Display-Update brauchen ist es durchaus denkbar, dass sich das nicht ganz mit dem Einlesen der Empfänger-Daten verträgt, sofern die wie die Servoimpulse alle 10ms kommen. Dann wäre aber noch die Frage, wie die Daten eingelesen werden. Arduino Serial(n).read() arbeitet im Hintergrund interruptgesteuert und über Ringbuffer. Da düfte eigentlich nichts böses passieren, solange der Buffer nicht überläuft.


[1] Grundgerüst für einfache Debug-Ausgaben
Code:
Arduino-loop()
{
  long temp = 0;
  static long looptime = 0;
  //long tick = millis();
  long tick_us = micros();

  [...]  dein Code, der dich nicht interessiert

  temp = micros();
  [..]  dein Code, von dem du gerne wissen möchtest, wie lange er dauert
  temp =  micros() - temp;

  [...]  restlicher Programmablauf

  if (debug_flag) 
  {
    //Serial.print("ms: ");Serial.println(millis()-tick);
    Serial.print("loop[us]: ");Serial.println(micros()-tick_us);
    Serial.print("dt[us]: ");Serial.println(temp);
    Serial.print("lastloop[us]: ");Serial.println(looptime);
  }  
  looptime = micros() - tick_us;
}  // end loop
 
Ansicht hell / dunkel umschalten
Oben Unten