Jump to content

Der deutsche DCS-BIOS-Thread: Für Simpit-Bastler und solche, die es werden wollen


FSFIan

Recommended Posts

Diese beiden Zahlenkombinationon kommen verdreht raus " 21 statt 12 " und " 57 statt 75 ".

Dann bin ich mal in die LedControll.cpp gegangen und habe mir diese Zeilen mal angeschaut:

Die rot Markierte Stelle habe ich mal verstauscht und das Led Display blieb dunkel. Ich bin jetzt nicht der Arduino Programmierprofi. Kannst du mir nicht kurz und knapp sagen was ich verändern muss?

 

Ich habe keine Ahnung, wie du darauf kommst, dass das Verändern des "if(digit<0 || digit>7)"-Teils irgendetwas mit deinem Problem zu tun hat. Ich habe in beiden meiner Posts gesagt, du solltest dir mal for-Schleifen ansehen. Das hast du offensichtlich nicht (gründlich genug) getan, sonst hättest du verstanden, warum die beiden Ziffern falsch herum angezeigt werden (und wüsstest, wie du es fixt).

 

Ich bekomme den Eindruck, dass du kein Interesse daran hast, C++ zu lernen, sondern einfach nur Ergebnisse haben willst. Dagegen ist nichts einzuwenden, aber mit dieser Einstellung ist DCS-BIOS bei allem, was über Kopieren aus der Dokumentation hinausgeht, das falsche Produkt für dich.

 

So wie ich das sehe, habe ich zwei Möglichkeiten:

 

1) Ich beantworte Anfängerfragen mit einem Stück Code, was ohne es zu verstehen direkt übernommen werden kann. Das muss ich dann fairerweise bei jedem so machen, und das kostet eine Menge Zeit, insbesondere weil ich mir ziemlich sicher sein muss, dass der Code auch funktioniert, da ich den ja i.d.R. ohne die Schaltung auf dem Schreibtisch nicht testen kann. Dazu kommt, dass man durch Copy+Paste nicht Programmieren lernt. Anfänger bleiben also Anfänger und die nächste Frage lässt nicht lange auf sich warten (und ist auch nicht komplexer als die erste).

 

2) Ich beantworte Anfängerfragen mit Hinweisen, die dem Fragesteller dabei helfen, das Problem selbst zu lösen. Das kostet mich deutlich weniger Zeit. Der Fragesteller hat nachher verstanden, wie der Fehler entstanden ist, wird den gleichen Fehler nicht wieder machen und kann anderen helfen, die ähnliche Probleme haben. Langfristig sinkt also die Anzahl der Fragen, die gestellt werden, und die Anzahl der Leute, die Fragen beantworten können, steigt.

 

Ich habe mich für Option 2) entschieden, da ich einerseites für 1) keine Zeit habe und andererseits Option 2) auch aus Sicht der Community für die bessere Wahl halte.

Link to comment
Share on other sites

Nach langem suchen und lernen habe ich endlich das Problem mit den verdrehten Zahlen gefunden und behoben. Im lc.setChar(0,i+4,newValue,false); muss man lediglich einen "!" in "newValue[!i] hinzufügen.

newValue[i]  = 01
newValue[!i] = 10

Aircrafts: F-16C | TF-51 | M2000C | F/A-18C | AV-8B | Viggen | KA-50 | A-10C | UH-1 | Mi-8 |

Maps: Caucasus | Persian Gulf | NTTR | Normandy | Syria

System: AMD Ryzen 3700X | 32GB Ram | AMD Radeon RX 5700 XT | Win10 64Bit | 1TB 970 EVO M.2 SSD

Equipment: TrackIR 5_Trackclip Pro |TM Warthog HOTAS | Oculus Rift S

Link to comment
Share on other sites

  • 1 month later...

Hey Leute!

 

Habe 3 LCD - Anzeigen verbaut und lasse darauf die Radios, ILS usw. anzeigen. Funktioniert bis jetzt richtig gut!

Jetzt würde ich gerne die Frequenzen über Buttons ändern können, aber leider sind lediglich Encoder dafür vorgesehen.

Kennt von Euch wer einen Trick wie dies mit Push-Buttons umsetzen kann?

 

Viele Grüße

 

-Steffen-

Link to comment
Share on other sites

Das geht mit der ActionButton-Klasse:

 

DcsBios::ActionButton vhfamFreq1Dec("VHFAM_FREQ1", "DEC", 5);
DcsBios::ActionButton vhfamFreq1Inc("VHFAM_FREQ1", "INC", 6);

 

Wenn du mit diesem Code einen Taster zwischen Pin 5 und GND und einen zwischen Pin 6 und GND schaltest, sollten die den ersten Frequenzknopf vom VHF AM-Radio bedienen.

 

PS: Bitte in Zukunft nur an einer Stelle nachfragen, das führt sonst nur zu unnötigem Mehraufwand (da ich nicht den Eindruck erwecken will, dass Fragen irgendwo unbeantwortet bleiben). Wobei das jetzt noch nicht so schlimm war, den Rekord hält der Typ, der innerhalb von einer Stunde hier im öffentlichen Forum, bei mir per PM, bei GitHub und als YouTube-Kommentar gefragt hat...

Link to comment
Share on other sites

  • 3 weeks later...

Hallo zusammen.

Ich habe mir die Tage ein Warning Light Panel zusammengelötet.

Läuft allse super wenn ich am Boden bin, aber sobal ich anfange zu rollen oder fliege ist das Ding wie wild in Mustern am Blinken.

Ich habe das an einem Arduino Mega und jede Led ist einzeln mit einem Pin verbunden.

Einer eine Ahnung warum das so ist und wie ich das abstellen kann?

 

 

edit:

Hier Bilder von meinem Prototypen.

cwp1.jpg

cwp2.jpg


Edited by contie
Link to comment
Share on other sites

Einer eine Ahnung warum das so ist und wie ich das abstellen kann

 

Warum passiert das?

Dazu muss ich ein klein bisschen ausholen. DCS-BIOS sendet die Daten in zwei-Byte-Blöcken (also je 16 Bits) an den Arduino. Dabei versuchen wir die Daten so effizient wie möglich zusammenzupacken. Die Auslenkung eines analogen Zeigers wird mit einer 16-Bit-Zahl übertragen, um genau genug zu sein. Es wäre aber eine riesige Verschwendung, für den Status einer einzelnen LED 16 Bit zu belegen. Also benutzen wir dafür nur ein Bit.

 

Wenn so ein 16-Bit-Block an Daten am Arduino ankommt, muss er es verarbeiten. Dazu gibt es intern eine Liste aller Klasseninstanzen (DcsBios::LED, DcsBios::ServoOutput, etc), die sich für sowas interessieren; die bekommen jeweils die Gelegenheit, diese Daten zu verarbeiten. Die LED-Klasse holt sich z.B. das für sie interessante Bit raus und setzt den GPIO-Pin entsprechend. Während diese Verarbeitung läuft, landen weitere Daten, die vom PC reinkommen, in einem Empfangspuffer, anstatt in zwei-Byte-Blöcke zerlegt zu werden.

 

Wenn dieser Zustand zu lange anhält, ist der Puffer irgendwann voll, weitere Daten werden ignoriert und die Software ist nur noch verwirrt.

 

Die Daten für die 48 Caution Lights in der A-10C liegen in drei aufeinanderfolgenden 16-Bit-Blöcken. Wenn die in schneller Folge aktualisiert werden (z.B. weil du auf SIGNAL LIGHTS TEST drückst oder weil DCS-BIOS auch ab und zu Daten sendet, wenn sie sich nicht geändert haben, damit man ein Panel auch später noch anschließen kann), dann landen bei deinem Sketch relativ viele Daten im Empfangspuffer, denn für jeden der drei Datenblöcke interessieren sich jeweils 16 Instanzen von DcsBios::LED.

 

Auf dem Boden geht das noch klar, weil sich so gut wie nichts ändert. Ein gesamtes Datenupdate von DCS-BIOS, was ca. alle 30 ms gesendet wird, passt komplett in den Puffer, und wenn das komplett empfangen wurde, hat der Arduino alle Zeit der Welt (ca. 25 ms), um den Puffer wieder leerzuarbeiten.

 

In der Luft (oder schon beim Rollen auf dem Boden) sieht das anders aus. Es gibt viel mehr analoge Instrumente (Triebwerksanzeigen, ADI, HSI, etc) die ihre Werte jetzt ständig ändern, und sei es nur um ein paar Nachkommastellen. Die 30-ms-Updates werden zu groß für den Empfangspuffer auf dem Arduino, und er läuft voll.

 

 

Wie kann man das abstellen?

Bisher gab es da nur einen Workaround: lass den PC die Daten langsamer senden, so dass der Puffer nicht ganz so schnell vollläuft.

Dazu musst du in connect-serial-port.cmd die BAUDRATE von 500000 auf z.B. 115200 runtersetzen, und das gleiche im Arduino-Sketch mit dem Parameter für Serial.begin() machen.

Das kann in manchen Fällen helfen, beseitigt aber das eigentliche Problem nicht.

 

Die vernünftige Lösung des Problems wird in der nächsten Version der Arduino-Library drin sein (die ich hoffentlich in den nächsten Tagen veröffentliche, es fehlen hier und da noch etwas Feinschliff und vor allem Dokumentation). Hier wird weitgehend auf einen Empfangspuffer verzichtet, stattdessen wird die Verarbeitung eingehender Daten priorisiert (die meisten können sowieso schnell verworfen werden, weil sich ein einzelner Arduino nie für die Daten des kompletten Cockpits interessiert).

 

Der Code ist schon im rs485-Branch auf GitHub verfügbar. Eine wichtige Änderung ist, dass die neue Standard-Ubertragungsrate auf dem seriellen Port 250000 bps statt 500000 bps ist, du musst also die BAUDRATE in connect-serial-port.cmd anpassen.

 

Die weiteren Änderungen sind hier knapp beschrieben, es sollte aber reichen, wenn du den neuen IRQSerial-Template-Sketch benutzt und deine DcsBios::LED-Zeilen reinkopierst.

 

Leider unterstützt diese Version noch nicht den Arduino Mega, das werd ich vor Release aber noch einbauen (sollte nicht weiter schwierig sein, ich hatte nur auf einen zweiten Mega zum Testen gewartet, der ist mittlerweile angekommen).

Link to comment
Share on other sites

Aller besten Dank für die super schnelle aus extrem ausführliche Antwort.

Ich werde dein Workaround gleich mal ausprobieren.

Ich habe mir schon 74HC595 Schieberigister gekauft, da ich die Anzeige zu einer Matrix umlöten will. Es fehlen aber noch die Transistoren damit mir nix abraucht.

Ich weiß nur noch nicht wie ich das in Scriptform umsetzen soll.

Habe das Arduino Hacken mehr so learning bei doing und mit Youtube gelernt.

 

Nachtrag:

So gerade getestet.

Bei 115200 ging gar nix mehr aber bei 250000 Baut ist alles super. Beim Rollen und im Flug.

Danke.


Edited by contie
Link to comment
Share on other sites

  • 1 month later...

Hallo zusammen,

 

hat sich schon mal jemand mit dem Thema Servo im DCS-BIOS beschäftigt? Ich benötige da bitte mal Hilfe.

 

Ich wollte mal das APU Panel beim KA50 testen und die APU Temperatur mit einem Servo darstellen.

 

Haben versucht folgenden Code auf das Mega 2560 zu laden:

 

DcsBios::ServoOutput apuTemp(0x191c, 2, 544, 2400);

 

aber es kommt folgende Fehlermeldung:

 

Arduino: 1.6.8 (Windows 7), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

 

test:16: error: 'ServoOutput' in namespace 'DcsBios' does not name a type

 

DcsBios::ServoOutput apuTemp(0x191c, 2, 544, 2400);

 

^

 

exit status 1

'ServoOutput' in namespace 'DcsBios' does not name a type

 

Da ich mich gerade erst mit dem Thema DCS-BIOS beschäftige weiß ich nicht woran der Fehler liegt... :cry:

 

Vielen Danke für Eure Hilfe und VG Tronix

[sIGPIC][/sIGPIC]

 

my DCS World - Ka50 Pit Project: :pilotfly:

http://www.ka50.de

Link to comment
Share on other sites

Um ServoOutput benutzen zu können, muss vor dem "#include <DcsBios.h>" ein "#include <Servo.h>" stehen.

 

Ich sehe gerade, dass das in den aktuellen Beispielen nicht drin steht, das hab ich wohl beim Wechsel auf v0.2 verbockt.

 

Der technische Hintergrund ist der, dass ich vermeiden wollte, den Nutzer zu zwingen, die Servo-Library reinzukompilieren -- die belegt nämlich einen Hardware-Timer, den man vielleicht für was anderes benutzen will. Deshalb wird die von der Servo-Library abhängige ServoOutput-Klasse nur reinkompiliert, wenn die Servo-Library bereits explizit eingebunden wurde, anstatt in der DCS-BIOS Arduino Library das "#include <Servo.h>" zu setzen.

Link to comment
Share on other sites

7 Segment Display

 

Hi,

 

ich probiere derzeit zwei 7-Segement Display die per Multiplexing verbunden sind mit DCS Bios anzusteuern um darauf die UHF Presets der A-10C (A-10C/UHF_PRESET) anzuzeigen.

 

Leider verzweifel ich am Arduino Code. Ich habe das Display erstmal weggelassen und wollte einfach eine LED blinken lassen wenn das Preset wechselt:

 

void onUhfPresetChange(char* newValue) {
   
   digitalWrite(12,HIGH);
   delay(1000);
   digitalWrite(12,LOW);
}

das hat auch schon funktioniert. Nur wenn ich jetzt die LED nur beim Preset 02 blinken lassen will komm ich nicht weiter. Mein Code sieht so aus:

void onUhfPresetChange(char* newValue) {

   if(newValue == "02"){
     digitalWrite(12,HIGH);
     delay(1000);
     digitalWrite(12,LOW);
   }
}

Hat jemand ne Idee? Ich denke nur das ich mich zu doof anstelle :)

 

Danke,

 

Marsy

Ryzen 9 3900X, GeForce RTX 2080 Ti GAMING X TRIO , 32 GB RAM, Valve Index

[sIGPIC][/sIGPIC]

Visit us on Facebook

Link to comment
Share on other sites

Wenn du in C++ zwei Strings mit dem Operator == vergleichst, vergleichst du nur die Speicheradressen. Um den Inhalt zu vergleichen, musst du die strcmp-Funktion verwenden. Die gibt 0 zurück, wenn die Strings gleich sind, ansonsten einen Wert kleiner oder größer als 0, je nachdem, welcher String lexikographisch nach ASCII-Werten sortiert zuerst kommt.

 

Versuch mal folgendes:

 

void onUhfPresetChange(char* newValue) {

   if(!strcmp(newValue, "02")){
     digitalWrite(12,HIGH);
     delay(1000);
     digitalWrite(12,LOW);
   }
}

  • Like 1
Link to comment
Share on other sites

Leider muss ich jetzt einen Doppelpost machen:

 

Ich habe das Beispiel mit der LED wunderbar umsetzten können, danke nochmal!

 

Mein Ziel war es aber 7 Segement Dispalys einzusetzen um bspw das UHF Preset anzuzeigen.

Ich habe dazu zwei 7 Segement Displays verwendet und per Multiplexing an den Ardunino angeschlossen (nach diesem Tutorial).

 

Mein Problem ist jetzt folgendes: Das erste Segement zeigt die Ziffer (z.B. 1 bei preset 19) nur ganz kurz an und verschwindet danach wieder. Die zweite Ziffer wird dauerhaft angezeigt. Das liegt soweit ich es verstehe an der Anschlussart Multipelxing, da sich die beiden Displays ja die Pins zur Ansteuerung der LEDs teilen und nur jeweils der Common Pin einzeln angebunden ist (hoffe das war verständlich, sonst im Tutorial zu sehen).

Wenn jetzt das Preset gewechselt wird, bleibt nur der Common Pin des letztens Dispalys auf High so das er eine Zahl anzeigt. Damit beide Dispalys die Zahlen anzeigen müsste der Codeabschnitt für die Anzeige der Zahl regelmäßig ausgeführt werden. Da habe ich leider keine Idee wie ich das bewerkstellige...

 

Bin ich mit meinem Gedankengang auf dem Holzweg? Lässt sich das so überhaupt Lösen, oder ist der Anschluss per Mulitplexing eine doofe idee? Vorteil für mich ist, dass Multiplexing vom Anschluss und Code bisher recht einfach war.

 

Wäre super wenn ihr mir weiterhelfen könnt!

 

Danke und schönes Wochenende,

 

Marsy

Ryzen 9 3900X, GeForce RTX 2080 Ti GAMING X TRIO , 32 GB RAM, Valve Index

[sIGPIC][/sIGPIC]

Visit us on Facebook

Link to comment
Share on other sites

Das von dir verlinkte Tutorial ist ganz ok, wenn du verstehen willst, wie Multiplexing funktioniert. Der Code ist sehr einfach gehalten, so dass du direkt ablesen kannst, was wann an den Arduino-Pins passiert. Das macht den Code aber auch ungeeignet für eine praktische Anwendung, weil die Details der Ansteuerung nicht vernünftig gekapselt wurden.

 

Eine gut gemachte Library sollte die Details vor dem Benutzer verstecken, so dass nur eine Handvoll Codezeilen übrig bleiben, die abstraktere Dinge wie "das Display hängt an diesen Arduino-Pins" oder "zeige 02 an" ausdrücken -- um das Multiplexing soll sich die Library im Hintergrund selbst kümmern.

 

Die ersten beiden Treffer, die mir Google für "arduino 7 segment multiplexing library" ausspuckt, sehen beide ganz brauchbar aus:

 

Beiden Libraries liegen Beispiele und Dokumentation bei, die zeigen, wie man sie benutzt.

 

Die SevenSeg-Library (erster Link) hat sogar eine "write"-Methode, die einen nullterminierten String als Parameter akzeptiert, so dass du einfach "disp.write(newValue);" schreiben kannst.

 

Es spricht erstmal nichts dagegen, das Display per Multiplexing anzusprechen. Wenn du deutlich mehr 7-Segment-Anzeigen oder anderes Zeugs an den gleichen Arduino hängen willst, gehen dir irgendwann die Arduino-Pins aus oder der Stromverbrauch wird zu hoch, um alles vom Mikrocontroller selbst zu versorgen. Irgendwann wirst du auch an die Grenzen des 16 MHz-Prozessors stoßen. Ich vermute, dass die ersten beiden Limits zuerst greifen, bin mir da aber nicht sicher.

 

Es gibt auch externe Chips, die speziell zum Ansteuern von 7-Segment-Anzeigen gebaut sind und sich um das Multiplexing und die Stromversorgung kümmern. Ein recht bekannter Vertreter ist der MAX7219. Wenn du mit sowas mal rumspielen willst, kann ich dieses Modul empfehlen. Die Arduino-Library "LedControl" macht es recht einfach, die Dinger anzusteuern. Kommunikation mit dem Mikrocontroller erfolgt per SPI, du brauchst also nur drei Arduino-Pins, um mit einem (oder mehreren, die Dinger kann man hintereinanderschalten) MAX7219 zu reden. Ein MAX7219 steuert bis zu acht 7-Segment-Anzeigen an.

Link to comment
Share on other sites

Kurze Frage:

 

wie verhält sich das eigentlich wenn ich mehrer Arduino benützen möchte? können die zusammen kommunizieren? Muss ich dann für jedes Arduino einen eigenen Sketch programmieren und die "connect-serial-port.cmd" öffnen, oder was gibt es hier für Möglichkeiten?! :helpsmilie:

 

Danke!

[sIGPIC][/sIGPIC]

 

my DCS World - Ka50 Pit Project: :pilotfly:

http://www.ka50.de

Link to comment
Share on other sites

Muss ich dann für jedes Arduino einen eigenen Sketch programmieren und die "connect-serial-port.cmd" öffnen, oder was gibt es hier für Möglichkeiten?!

 

Ja, das funktioniert (jeder Arduino braucht eine eigene Kopie von connect-serial-port.cmd, in der der passende COM-Port eingetragen ist).

 

Für mehr als zwei oder drei Panels wird das aber viel zu nervig, wenn Windows sich mal wieder entschließt, die COM-Ports neu zu nummerieren. Ich hab auch schon von Leuten gelesen, die ab ca. 20 USB-Geräten (Joysticks, Leo Bodnar Boards, etc) Probleme bekommen haben und eine weitere USB-Karte in den Rechner stecken mussten, obwohl USB theoretisch bis zu 127 Geräte pro Host Controller erlaubt. Kurz gesagt: das wird mit einem kompletten Cockpit mit geschätzt 40 bis 60 Arduino-Boards nicht gut funktionieren.

 

Deshalb unterstützt die DCS-BIOS Arduino Library ab Version 0.2 auf dem Arduino Mega 2560 sowie auf Unos, Pro Minis, Nanos und anderen Boards mit ATMega328-Controller die Kommunikation über einen RS-485 Bus.

 

Jedes Arduino-Board wird mit einem RS-485 Transceiver-Chip verbunden. Meine Empfehlung ist der MAX487, den bekommt man im DIP-8-Gehäuse für ca. 20 Cent das Stück. Die Transceiver-Chips werden dann hintereinandergeschaltet (der Bus besteht aus zwei Leitungen, die "A" und "B" genannt werden).

 

Ein als "Master" programmierter Arduino Mega 2560 kann bis zu zwei (oder drei, wir sind uns noch nicht sicher) RS-485-Busse mit dem PC verbinden. An jeden RS-485-Bus können mit dem MAX487 bis zu 126 Boards angeschlossen werden. Wenn der Bus länger als ca. 10 Meter wird, braucht man Abschlusswiderstände und die Zahl der möglichen Geräte am Bus sinkt auf ca. 20 bis 24.

 

Leider ist das Ganze noch nicht im User Guide dokumentiert -- die einzige Doku sind die kurzen Kommentare in den RS485Master und RS485Slave Beispielsketchen. Hauptsächlich deshalb, weil die ganzen Angaben in diesem Post auf meinem theoretischen Verständnis beruhen, ich hab selbst bisher nicht mit mehr als drei Boards und ein paar Zentimeter Leitungslänge getestet.

Der Code funktioniert zwar, bevor ich das aber "offiziell" dokumentiere (und damit auch supporte), möchte ich die Grenzen besser verstehen (z.B. mit dem Oszilloskop mal nachmessen, wie das Signal bei 30 m Leitungslänge ohne Abschlusswiderstände denn aussieht) und etwas bessere Diagnosemöglichkeiten schaffen.

Link to comment
Share on other sites

Hi Ian,

 

ich bekomm es mit DCS und der SevenSeg Libary nicht hin. Die libary ohne DCS-BIOS läuft super, aber mit DCS-BIOS habe ich Probleme.

 

Ich habe mal beide Sketches angehängt:

sevseg ist der Sketch ohne DCS-BIOS der bei mir funktioniert.

DCS-7Segements ist der Sketch mit DCS-BIOS der nicht klappt :(

 

Ich bin mit meinem sehr bescheiden Arduino Latein echt am Ende und hoffe das du oder jemand anderes mir hier weiterhelfen könnt.

 

Danke!

sevseg.rar

DCS-7Segements.rar

Ryzen 9 3900X, GeForce RTX 2080 Ti GAMING X TRIO , 32 GB RAM, Valve Index

[sIGPIC][/sIGPIC]

Visit us on Facebook

Link to comment
Share on other sites

Mach mal das #include <Servo.h> weg, vielleicht belegt die Servo-Library den Timer, den die SevSeg-Library benutzen will.

 

Außerdem solltest du auf die aktuelle Version von DCS-BIOS (v0.5) und der Arduino Library (v0.2.3) umsteigen und das IRQSerial-Template benutzen. Ab v0.2.3 wurde der Code für die Kommunikation auf dem Arduino deutlich verbessert, so dass es bei Ausgabeelementen wie (Text)displays, deren Ansteuerung einige Zeit dauern kann, nicht mehr zu Problemen kommt.


Edited by [FSF]Ian
Link to comment
Share on other sites

Hab probiert es zu entfernen, ging bei der alten DCS-BIOS Version von mir nicht. Hab deshalb auf 0.5.0 und Lib 0.2.3. gewechselt.

 

Leider zeigt das Dispaly immer noch nichts an :(

 

Hier mein Code (ich nutze ein Uno):

 

#include <SevenSeg.h>

/*
 Tell DCS-BIOS to use a serial connection and use interrupt-driven
 communication. The main program will be interrupted to prioritize
 processing incoming data.
 
 This should work on any Arduino that has an ATMega328 controller
 (Uno, Pro Mini, many others).
*/
#define DCSBIOS_IRQ_SERIAL

#include "DcsBios.h"

/* paste code snippets from the reference documentation here */
SevenSeg disp(11, 10, 9, 8, 7, 6, 5);
const int numOfDigits = 2;
int digitPins[numOfDigits] = {4, 3};

void onUhfPresetChange(char* newValue) {
 disp.write(newValue);
 
}
DcsBios::StringBuffer<2> uhfPresetBuffer(0x1188, onUhfPresetChange);





void setup() {
 DcsBios::setup();
 disp.setDigitPins(numOfDigits, digitPins);
 disp.setCommonCathode();
 disp.setTimer(2);
 disp.startTimer();
}

void loop() {
 DcsBios::loop();
}

ISR(TIMER2_COMPA_vect){
disp.interruptAction();
}

Ryzen 9 3900X, GeForce RTX 2080 Ti GAMING X TRIO , 32 GB RAM, Valve Index

[sIGPIC][/sIGPIC]

Visit us on Facebook

Link to comment
Share on other sites

Wenn du am Ende deiner setup()-Funktion ein display.write("42") einfügst, zeigt das Display dann die 42 an?

 

Sicherheitshalber kannst du auch nochmal testen, ob die Kommunikation nach dem Upgrade auf v0.5.0 / v0.2.3 noch funktioniert, indem du irgendeine Signallampe auf die an Pin 13 angeschlossene LED des Arduinos legst, z.B. die hier:

DcsBios::LED nmspIlsLed(0x1112, 0x0020, 13);

und dann nachsiehst, ob die angeht, wenn du den SIGNAL LAMP TEST Button in der A-10C benutzt.

 

Ich kenn mich zwar mit der SevenSeg-Library nicht aus, aber nach meinem Verständnis der Dokumentation sollte dein Sketch eigentlich funktionieren.

 

Wenn ich nächste Woche etwas Zeit finde, werd ich mir das mal auf nen Pro Mini flashen und damit rumspielen.

Link to comment
Share on other sites

Ian;2764206']Wenn du am Ende deiner setup()-Funktion ein display.write("42") einfügst' date=' zeigt das Display dann die 42 an?[/quote']

 

Das Klappt wunderbar, das Dispaly zeigt dann dauerhaft 42 an. Leider auch wenn ich das UHF Preset ändere.

 

Ian;2764206']

Sicherheitshalber kannst du auch nochmal testen, ob die Kommunikation nach dem Upgrade auf v0.5.0 / v0.2.3 noch funktioniert, indem du irgendeine Signallampe auf die an Pin 13 angeschlossene LED des Arduinos legst, z.B. die hier:

DcsBios::LED nmspIlsLed(0x1112, 0x0020, 13);

und dann nachsiehst, ob die angeht, wenn du den SIGNAL LAMP TEST Button in der A-10C benutzt.

Funktioniert nur wenn ich den ganzen SevenSeg Kram nicht im Sketch habe.

 

Danke für dein Einsatz und deine Hilfe!

Ryzen 9 3900X, GeForce RTX 2080 Ti GAMING X TRIO , 32 GB RAM, Valve Index

[sIGPIC][/sIGPIC]

Visit us on Facebook

Link to comment
Share on other sites

Funktioniert nur wenn ich den ganzen SevenSeg Kram nicht im Sketch habe.

 

Ich hab mir mal den Code der SevenSeg-Library angesehen, insbesondere, was in display.interruptAction() passiert. Die Library ist einfach zu ineffizient programmiert.

 

Der Arduino muss für die Kommunikation mit dem PC 25000 Zeichen pro Sekunde verarbeiten. Damit hat er für jedes Zeichen nur 1/25000 s Zeit, was bei 16 MHz 640 CPU-Takten entspricht. Wenn ein angekommenes Zeichen also innerhalb von 640 CPU-Takten nicht verarbeitet (also mindestens in den Empfangspuffer geschrieben) wird, geht es verloren und nichts funktioniert mehr.

 

Die SevenSeg-Library benutzt wie viele andere Arduino-Libraries auch digitalWrite(), und das braucht zwischen 50 und 100 CPU-Takte pro Aufruf, je nach dem, welchem Blog-Artikel man glauben will (ich hab selbst noch nicht nachgemessen). Das eigentliche Umschalten des Pins braucht nur zwei Takte, aber digitalWrite() muss erstmal nachsehen, welches Hardwareregister denn jetzt zu "Pin 5" gehört und hat noch ein paar andere Checks drin.

 

 

Wenn du display.interruptAction() aufrufst, passiert folgendes:

 

1. ein bisschen Verwaltungslogik sieht nach, ob das Display gerade an oder aus sein soll (wegen der Helligkeitssteuerung durch PWM). Die nächsten Schritte passieren, wenn das Display gerade an sein soll.

 

2. changeDigit() wird aufgerufen, um den richtigen Digit-Pin einzuschalten. Das ruft erstmal clearDisp() auf, um alle Segment-Pins (7x digitalWrite()) und alle Digit-Pins (2x) abzuschalten. Das verhindert, dass die aktuelle Ziffer auf der nächsten "durchscheint". Dann setzt es den passenden Digit-Pin für die aktuelle Ziffer (1x).

=> 10x digitalWrite() für Schritt 2

 

3. Die aktuelle Ziffer wird aufs Display geschrieben, dafür wird writeDigit() aufgerufen. Da wir einen String schreiben, wird die Character-Variante writeDigit(char digit) genommen. Erste Amtshandlung: alle Segment-Pins ausschalten (7x). Dann stellt writeDigit(char digit) fest, dass es sich um eine Ziffer (und keinen Buchstaben) handelt, und delegiert an writeDigit(int digit), das wiederum erstmal alle Segment-Pins abschaltet (14x) und dann noch die richtigen Segmente wieder anschalten muss...

=> mindestens 14x digitalWrite() für Schritt 3

 

Selbst wenn wir annehmen, dass digitalWrite() nur 30 Takte braucht, benötigt ein Aufruf von display.interruptAction() also mindestens 720 CPU-Takte. Während ein Interrupt abgearbeitet wird, müssen alle anderen warten. Wenn jetzt gerade Daten vom PC reinkommen, gehen Zeichen verloren, weil alle 640 CPU-Takte das nächste Zeichen da ist, es aber nicht in den Empfangspuffer geschrieben wird, weil der Mikrocontroller immer noch mit display.interruptAction() beschäftigt ist.

 

 

Du musst entweder eine besser optimierte Library finden oder den SevenSeg-Code nur aus dem Hauptprogramm aus aufrufen.

 

Versuch mal das hier (ungetestet):

#include <SevenSeg.h>
#define DCSBIOS_IRQ_SERIAL
#include "DcsBios.h"

/* paste code snippets from the reference documentation here */
SevenSeg disp(11, 10, 9, 8, 7, 6, 5);
const int numOfDigits = 2;
int digitPins[numOfDigits] = {4, 3};

DcsBios::StringBuffer<2> uhfPresetBuffer(0x1188, NULL);


void setup() {
 DcsBios::setup();
 disp.setDigitPins(numOfDigits, digitPins);
 disp.setCommonCathode();
}

void loop() {
 DcsBios::loop();
 disp.write(uhfPresetBuffer.getData());
}


Edited by [FSF]Ian
Link to comment
Share on other sites

Hi Ian,

 

dein Codebeispiel klappt. Wenn ich dich jetzt richtig verstehe ist die SevenSeg Libary aber eigentlich ungeignet, weil zu lahm.

Was sind denn die alternativen die man nutzen kann?

Die beiden Displays die ich jetzt befeuere sind eigentlich nur der Anfang.

Ich hatte insgesamt n paar mehr Anzeigen zu betreiben (6-9 Stück).

Das wird dann ja vermutlich mit der bestehenden Bibliothek nicht klappen, oder?

 

Gruß und vielen Dank für deine Hilfe,

 

Marsy

Ryzen 9 3900X, GeForce RTX 2080 Ti GAMING X TRIO , 32 GB RAM, Valve Index

[sIGPIC][/sIGPIC]

Visit us on Facebook

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...