Themabewertung:
  • 0 Bewertung(en) - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
FAQ zum Einsteigerkurs uC-Programmierung
(08.02.2020, 00:13)Larry67 schrieb: jaaaaa, die geschweifte Klammer hab ich vergessen, nur mitgedacht


for (int i=0;i<4;i++) {
  pinMode(ModulPins[i],OUTPUT);
  digitalWrite(ModulPins[i],HIGH);
}

so dachte ich es mir


digitalWrite(k, Decod[k - 2][Zahl[i - 9]]);


k ist das Segment A - G        Decod[k - 2]     eigendlich Decod[0]    aber da k bei 2 anfängt muss k-2   um auf 0 zu kommen

K zählt hoch bis                                                         Decod[7]    aber da k= 9 ist  mussss        [k-2]

zweiter Bereich für mein 2 dimensionales Feld namens Decod:

[Zahl[i - 9]]       greift auf mein Feld namens Zahl zu,      i ist die Pin Nr für die einzelnen 7Segmentanzeigen beginnend mit Pin 9

[i - 9] bedeutet dass beim ersten Segment ( pin 9)  das nullte Element aus dem Feld ZAHL ausgelesen wird

wird i=10             kommt durch  [i - 9]  das erste Element aus dem Feld Zahl drann   u.s.w.

ist das schwer zu beschreiben


Ich würde es jetzt nicht genauso sagen wie Otto, aber wahrscheinlich ist das Programm in 5 Minuten nochmal sauber neu geschrieben/aufgesetzt, als sich durch den ganzen Wust ( hier mal -2 damit es funktioniert, dort mal ein k eingeführt was gleichzeitig als Index und als PinNummer dienen soll) zu debuggen!
Mach ich auch manchmal, ich schmeiße den Code der zu umständlich geschrieben ist weg und fange neu an oder ich gehe eine Stufe zurück! Das ist nichts wofür man sich schämen müsste, manchmal ist der erste Weg der einen einfällt nicht immer der Beste.
Die Vorversion zur 7-Seg.Anzeige ohne Multiplexing! Hatte die schon die Performance-Probleme? Lade mal den Code hoch.

Den Code in der setup() würde ich auch nochmal überarbeiten:


PHP-Code:
 for (int P 213P++) {                   //Segmente Pins
 
   pinMode(OUTPUT);                           // Ausgang schalten
 
   pinMode(13INPUT_PULLUP);                // Tasten Pins
 
   pinMode(14INPUT_PULLUP);
 
 


Die Tastenpins musst Du nicht zig mal auf INPUT_PULLUP setzen, also raus aus der Schleife und dann  P = 2; P<13;P++ durch eine richtige(!) Datenstruktur mit den Anschlußpins ersetzen! Wir müssen aktuell nicht so mit Speicher geizen, das wir einen Zählindex auch noch als Pinnummer benutzen müssen und wenn, dann nennen wir die Variable im ganzen Programm gleich! Nicht mal P dann mal k, sonst bekommt man irgendwann eine Macke und weiß nicht welche Variable was eigentlich darstellen soll. Ich baue deine Schaltung auch gern nochmal nach und dann schauen wir beide wo es klemmt.
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
Ja, im Kopfe kann ich da den Elektronen hinterherrennen, da ist das schon klar,
diese Konstruktion sollte die ganze Sache komprimieren deshalb ist das Konstrukt ja nur ein paar wenige Zeilen lang.
Ich denke, dass durch diese Verschachtelung der Arduino ausgebremst wird.
Die einzelnen Anzeigestellen werden korrekt dargestellt, nur das Ein - Ausschalten der Segmente A-G geschieht zu langsam, wahrscheinlich wegen der mathematischen Berechnungen innerhalb der digitalWrite Anweisung.
Eine einstellige Anzeige läuft prima und schnell.
Na ich bin da eben noch Anfänger mit all seinen Ecken und Kanten. Ein Falscher Weg lehrt ja auch.
Ich war auf jeden Fall überrascht, dass es überhaupt lief ohne extremes Wissen über die ganzen Klammern.
Sven
Zitieren
(08.02.2020, 10:20)Larry67 schrieb: Die einzelnen Anzeigestellen werden korrekt dargestellt, nur das Ein - Ausschalten der Segmente A-G geschieht zu langsam, wahrscheinlich wegen der mathematischen Berechnungen innerhalb der digitalWrite Anweisung.

Die paar +/- Sachen sind nicht das Problem, das ist nur Mist für die Codeverständnis! Auch die 28 Iterationen in der Schleife sitzt der Controller einfach aus.

Das hier:

void loop() {
  int Zahl [4] {0, 2, 7, 3};                          // Beispielzahl
  int Decod [7] [10] {                                // decodierung der Zahlen
    {0, 1, 0, 0, 1, 0, 0, 0, 0, 0,},
    {0, 0, 0, 0, 0, 1, 1, 0, 0, 0,},
    {0, 0, 1, 0, 0, 0, 0, 0, 0, 0,},
    {0, 1, 0, 0, 1, 0, 0, 1, 0, 0,},
    {0, 1, 0, 1, 1, 1, 0, 1, 0, 1,},
    {0, 1, 1, 1, 0, 0, 0, 1, 0, 0,},
    {1, 1, 0, 0, 0, 0, 0, 1, 0, 0,},
  };
...


}

Wird ja dann auch zig mal in der Sekunde neu angelegt weil die Definition in der loop steht und dort eigentlich nichts zu suchen hat, glaube nicht das der Compiler das wegoptimiert, aber auch bei 16 MHz ist das wohl nichts für einen Arduino, dennoch würde ich das mal rausnehmen und testen! Hatte Dir(?) ja schon bei der Ampel geschrieben das solche Definitionen nichts in der loop zu suchen haben, da loop -wie der Name schon sagt- eine Schleife darstellt!

Da der Arduino/ATmega keine richtige Debug-Funktion hat und Du das Programm mit der IDE nicht bis zu einem Breakpoint durchsteppen kannst, würde ich auch einfach mal um den "verdächtigen" Code zwei millis() oder micros() setzen und mir die Zeit
ausgeben lassen, die der Arduino für diese Codestrecke benötigt. Darauf kann man dann auch schließen wo es zu Problemen kommt. Allerdings ist ein komplettes Neuaufsetzen des Programms und der zwei Schleifen wahrscheinlich deutlich schneller als eine Analyse des alten Codes.

Gruß Bernhard
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
(08.02.2020, 10:20)Larry67 schrieb: Ich denke, dass durch diese Verschachtelung der Arduino ausgebremst wird.
Die einzelnen Anzeigestellen werden korrekt dargestellt, nur das Ein - Ausschalten der Segmente A-G geschieht zu langsam, wahrscheinlich wegen der mathematischen Berechnungen innerhalb der digitalWrite Anweisung.

So, also ich habe deinen Code jetzt mal auf dem Prozessor mit Zeitmessung (durch micros()) durchlaufen lassen,  das einzige was bremst ist der delay-Befehl! Wenn der weg ist, hat das Programm auf jeden Fall keine(!) Performanceprobleme die Erklären warum deine Anzeige angeblich langsam läuft!

Für das ständige Neuanlegen deines Feldes am Anfang der loop braucht das Programm bei 16 MHz genau 68 Microsekunden.
Für die ganzen Schleifen inklusive der Ausgabe bei 16 MHz zwischen 204 und 208 Microsekunden!

Wie gesagt Microsekunden, nicht Millisekunden! 
Ich habe nicht kontrolliert was der Controller da an den I/Os rausschießt, für eine Performanceanalyse auch erstmal nebensächlich! Ich hoffe nur das Du die Anzeige nicht mit der vollen Geschwindigkeit die der Prozessor bei 16 MHz hat ansteuerst, denn das wäre zu schnell. 

Prüfe mal in deinem Programm wie lange der Prozessor für die einzelnen Teile braucht:

PHP-Code:
void loop() {
 
 time1 micros();
 
 int Zahl [4] {0273};                          // Beispielzahl
 
 int Decod [7] [10] {                                // decodierung der Zahlen
 
   {0100100000,},
 
   {0000011000,},
 
   {0010000000,},
 
   {0100100100,},
 
   {0101110101,},
 
   {0111000100,},
 
   {1100000100,},
 
 };

 
 time2micros();
 
 
  for 
(int i 913i++) {                   // Stellen 1 bis 4
 
   digitalWrite(i1);                                // einschalten
 
   {
 
     for (int k 29k++) {              //Segmente ohne Punkt

 
       digitalWrite(kDecod[2][Zahl[9]]);      // diese Anweisung scheint zu Komplex
 
            
        
//delay (100);                                   // verzögerung
 
     }
 
     digitalWrite(iLOW);                         // aktive Stelle aus
 
   }
 
 }
 
 time3=micros();

 
 Serial.print("Zeitverbrauch in der Ansteuerung: "); Serial.println(time3-time2);
 
 Serial.print("Zeitverbrauch in der Reallocation: "); Serial.println(time2-time1);
 
 delay(5000);





Gruß 
Bernhard
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
Hallo Bernhard,

die Zeiten sind bei mir genauso 208 und 68 ms.
Na wie auch immer, eine Analyse wird wohl nichts bringen.
Ich versuche etwas anderes. Handtuch wird nicht geworfen.

Sven
Zitieren
(08.02.2020, 17:55)Larry67 schrieb: Hallo Bernhard,

die Zeiten sind bei mir genauso 208 und 68 ms.

Hallo Sven,

us nicht ms! Dann läuft dein Nano auf jeden Fall mit der vorgesehenen Geschwindigkeit bzw. Takt und das Programm hat keine Performance-Probleme!
Kann es vielleicht sein das dein Multiplexing einfach zu schnell für die Anzeige ist und es deshalb so aussieht als würde sich alles nur sehr langsam aufbauen? Mache doch mal zwischen dem Umschalten der einzelnen Anzeigestellen ein delay von 5 oder 10 ms (Millisekunden)rein! Wie sieht die Sache dann aus?
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
Hallo Bernhard,

die Felder habe ich aus der LOOP hinausbefördert, kein Unterschied

ABER :

mein delay hatte ich falsch gesetzt. Es war innerhalb der Schleife, in der die Segmente A-G beschrieben wurden
das hat gebremst !
Nun ist es eine geschweifte Klammer tiefer in der Schleife für die 4 Stellen.
Es geht!!
Bei leichtem Flackern aller 4 Stellen bei delay(2);
noch nicht optimal aber schon wesentlich besser

wie sollte die Anzeige sein? komplett flackerfrei bei satter Helligkeit?

Sven
Zitieren
(08.02.2020, 22:06)Larry67 schrieb: Hallo Bernhard,

die Felder  habe ich aus der LOOP hinausbefördert,  kein Unterschied

ABER  :

mein delay hatte ich falsch gesetzt. Es war innerhalb der Schleife, in der die Segmente A-G beschrieben wurden
das hat gebremst !

Ja dein delay steht direkt beim setzen der einzelnen Segmente, aber ich denke Du hast das final immer raus genommen! Als ich darauf hingewiesen habe das das eine Bremse ist

Zitat:Bernhard45
Also erst mal das delay(100); in deinem Code oben ist eine (die?) Bremse! Auf jeden Fall ist der Prozessor dadurch ausgebremst um überhaupt etwas flackerfrei darstellen zu können! In deinem Code braucht er ja fast eine Sekunde für eine Anzeigenstelle!

hast Du geantwortet:

(08.02.2020, 22:06)Larry67 schrieb: das delay bei mir dient dem bremsen, damit ich optisch sehen kann, ob die einzelnen stellen richtig arbeiten.

Damit war ich der Meinung das delay ist im finalen Test dort nicht mehr aktiv und auskommentiert! Smiley7 Dann können wir uns ja auch totsuchen!

(08.02.2020, 22:06)Larry67 schrieb: Es geht!!

Amen!  Wink


(08.02.2020, 22:06)Larry67 schrieb: Bei leichtem Flackern aller 4 Stellen bei delay(2);
noch nicht optimal aber schon wesentlich besser

wie sollte die Anzeige sein? komplett flackerfrei bei satter Helligkeit?

Aber definitiv flackerfrei! Über das Timing bzw. eine Verzögerung zwischen den Anzeigestellen kannst Du das Flackern beseitigen und auch etwas die Helligkeit verändern.
Sollte schon optimal eingestellt sein, flackerfrei und normal hell.

Und dann gieße den Code aus der jetzigen loop (ohne die ständige Deklarierung des 2D-Arrays!)  in besagte  void siebenseg(int zahl) mit einer(!) Zahl zur Übergabe.

Bilde also den Einer, Zehner, .... in der Funktion selbst. Die Taster zum Hoch/Runter-Schalten kannst Du dann ja noch extern dran bauen, nach Lektion 4 meinetwegen auch per Interrupt. Deine Funktion siebenseg kannst Du dann für weitere Ausgaben nutzen.

Gruß Bernhard
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
ich werde noch den Punkt mit hineinbringen, die Zahl als alleinig mit rein, ja das klappt dann schon denk ich. etwas spielen mit der Verzögerung erbrachte eine flackerfreie Anzeige nun.
Pfffffffff, das war eine schwere Geburt .
Zitieren
Thumbs_up
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
Hallo Bernhard,

kannst du mir mal die Abfrage Drehencoder aufschlüsseln? Ich bekomme das nicht auf die Reihe.

void AbfrageDrehencoder(void)
{
 Last_RoB_Status = digitalRead(PIN_B);
 while (!digitalRead(PIN_A)) {
   Current_RoB_Status = digitalRead(PIN_B);
   flag = 1;
 }

Soweit ich das verstanden habe gibt der Drehgeber je nach Richtung 1 oder 0 aus.
Die Funktion der whileschleife mit dem negierten PIN A verstehe ich nicht.
sicheres Auftreten bei völliger Ahnungslosigkeit
Zitieren
jeh nach Drehrichtung Phasenverschoben,
wenn die Phase gegenüber PIN A negativ verschoben ist, wird die flag gesetzt, so lese ich das, leider habe ich keinen Drehencoder kann das nicht testen

Sven
Zitieren
Hallo,

ein Encoder liefert immer über zwei(!) Leitungen ein Signal, im Programm an PIN_A und PIN_B.

   

Jetzt behält man kontinuierlich (Polling) das Signal am PIN_A und B im Auge und schaut was bei dem Flankenwechsel von PIN_A passiert.

Wechselt PIN_A von H nach L notiert man sich den Zustand des PIN_B als "alten" Zustand , geht dann in eine Fangschleife in der man nach Wechsel von L nach H des PIN_A"sucht". Ist der gefunden notiert man sich wieder den Zustand von PIN_B und setzt ein Flag das man alle Daten für die Untersuchung der Drehrichtung hat.

Ermittlung der Drehrichtung:

Hier vergleicht man nur die notierten Zustände von PIN_B.
War der alte Zustand von Pin_B HIGH und der "neue" ist LOW dreht man in die eine Richtung, war der alte Zustand LOW und der "neue" ist HIGH dreht man in die andere Richtung.

Die while-Schleife ist hier also die Schleife mit der man beide Flankenwechsel von PIN_A erkennen kann. Durch digtialRead(PIN_A) erhalten wir als Rückgabe ja den logischen Zustand am PIN_A und eine while-Schleife bleibt solange aktiv, wie die Bedingung wahr ist. Und wahr = true ist ein Ergebnis ungleich 0. Die Negation dient dann nur aus einem FALSE = 0 = LOW ein TRUE = ungleich 0 = HIGH zu machen.

Wie im PDF geschrieben ist das der Programmcode eines gpiod-Prozesses vom iRadio. Das iRadio kann mehrere dieser Prozesse gleichzeitig laufen lassen und in jedem Prozess eine andere Funktion implementieren. Das kann der Programmwechsel oder eine Lautstärkenänderung sein. Durch die Multitasking-Fähigkeit und Leistung der Hardware auf der gewöhnlich ein iRadio läuft, macht das Polling (also die Suche nach dem Flankenwechsel) keine Probleme. Da können dutzende Drehencoder simultan im Pollingverfahren überwacht werden!

Auf dem Arduino klappt das auch, unter der Bedingung das dem Polling der größte Teil der Rechenzeit zugeschrieben wird bzw. sich das Polling diese Zeit einfach nimmt. Um auf dem Arduino aber vielleicht auch noch
eine andere rechenintensive Aufgaben zu erledigen, Displayaktualisierung usw., müssen wir das Polling durch ein Interrupt-Verfahren ersetzen und das ist eine Aufgabe der aktuellen Lektion.

Gruß Bernhard

PS: Die Encoder sind beim iRadio HW-Entprellt und im Idealfall auch geschirmt angeschlossen! Für die Arduino-Lösung setzen wir voraus das die Encoder genauso angeschlossen sind, dann wird es im Code übersichtlicher/einfacher! Ihr müsst in der Hausaufgabe also nicht noch eine Software-Entprellung implementieren, die Umstellung von Polling auf Interrupt ist absolut ausreichend. Um Interrupts dreht es sich ja in der aktuellen Lektion.
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
Ist das Prinzip so halbwegs klar Tubefan?

@Alle: Also wir können innerhalb der 4 Wochen gern auch die erste Hausgabe mal gemeinsam hier "live" im FAQ machen wenn Ihr das wollt?! Sprich den vorgegeben Code Stück für Stück hinsichtlich Interrupt-Betrieb übersetzen.

Gruß Bernhard
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
So ganz habe ich es noch nicht, habe erst morgen wieder Zeit dafür. Die Rastpunkte hängen nicht zwingend mit der Zustandsänderung zusammen oder ist das grundsätzlich so?
Der Grafik nach hätte ich nach dem 4. Rastpunkt wieder eine Flanke von Low auf High. Pin A wird für das Inkrement und Pin B für die Richtung ausgewertet.

Grundsätzlich finde ich das gut wenn wir dein Lösung zum Ende der Lektion mal Punkt für Punkt durchgehen.

Guß
Frank
sicheres Auftreten bei völliger Ahnungslosigkeit
Zitieren
Es gibt einfach 4 Zustände: 0-1, 1-0, 0-0 und 1-1 und die kannst Du beim Flankenwechsel von PIN_A durch Abtasten der Leitung PIN_B erhalten. Die Drehrichtung ergibt sich aus oben bereits gesagten. Wo der Encoder dabei einrastet ist für den Zustandsautomaten unerheblich, da sich nach Drehbegin automatisch wieder die richtige Zustandsabfolge einstellt.
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
Na gut, entwickeln wir das Programm doch mal zusammen:


Das alte Programm steht ja in der PDF, also hier im FAQ nur der Code der Lösung:

Ein neues leeres Programm hat diese Struktur;

PHP-Code:
void setup() {
 
 // put your setup code here, to run once:

}

void loop() {
 
 // put your main code here, to run repeatedly:





Fangen wir von vorne an. 
Im alten Programm hängt der Encoder an Pin D4 und D5 am Controller?
Kann das so bleiben wenn wir mit den Arduino-Libs arbeiten oder nicht, begründe? 
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
Nein, der Interrupt funktioniert beim Nano über die Lib nur an Pin 2/3.
sicheres Auftreten bei völliger Ahnungslosigkeit
Zitieren
Das ist richtig! Mit den Arduino-Bibliotheken haben wir Interrupts nur an Pin D2 und D3.

In #235 wird der im PDF gelistete Algorithmus nochmal erklärt. Brauchen wir nun ein oder zwei Interrupts? 
Und auf was muss der/die Interrupt/Interrupts "lauschen"?
Ansprechpartner für Umbau oder Modernisierung von Röhrenradios mittels SDR,DAB+,Internetradio,Firmwareentwicklung. 
Unser Open-Source Softwarebaukasten für Internetradios gibt es auf der Github-Seite! Projekt: BM45/iRadio (Google "github BM45/iRadio")
Zitieren
Der Interrupt braucht eigentlich nur auf irgendein Signal des Drehgebers lauschen, demnach müsste ein Interrupt ausreichen.
sicheres Auftreten bei völliger Ahnungslosigkeit
Zitieren


Möglicherweise verwandte Themen…
Thema Verfasser Antworten Ansichten Letzter Beitrag
  Einsteigerkurs Microcontrollerprogrammierung Bernhard45 13 10.059 23.05.2020, 23:55
Letzter Beitrag: Bernhard45

Gehe zu: