Thermometer LM92, MAX7219, Ansteuerung

    Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

    Aufgrund technischer Veränderungen ist der Mailverkehr innerhalb des Forums (Private Nachrichten) nur noch eingeschränkt möglich. Die Einschränkung ist notwendig, um zusätzliche Betriebskosten für das Forum zu vermeiden. Näheres zu den Hintergründen im Thread "Aktuelles zum Forum".Wir bitten um Verständnis.

    Hinweis kann nach Kenntnisnahme deaktiviert werden!

    • Thermometer LM92, MAX7219, Ansteuerung

      Hallo,
      nachdem die Sache mit den max / min Werten für mein neues Thermometer zur Zufriedenheit geklärt wurde, nun ein paar neue Fragen.
      Die LED Anzeige wird mit DDR-Anzeigen vom Typ VQB28, VQB27 und VQB200 realisiert.
      Die VQB200 sind 16-Segment Anzeigen für die anzeige von AKT, MIN, MAX, DEL.
      Ich find halt diese "alten" DDR-LED-Anzeigen gut, von der Optik her. Bilder anbei.
      Die 7-Segment mit dem MAX7219 sind ja nicht das Problem. 5 Stellen alles gut.
      Die 16-Segment würde ich jeweils aufteilen auf 2x CC vom MAX7219 (2x8 Segmente), da die 16-Segment Anzeigen nur einen Common Anschluß haben.
      Bissel umständlich, aber würde funktionieren. Oder wäre es besser, z.B. den MAX6954 dafür zu nehmen, der auch 16-Segment direkt steuern kann ?

      Im Programm bin ich nicht glücklich über die Ansteuerung der MAX7219 z.Z..
      Würde es Sinn machen, die Max7219 einzeln über CS anzusteuern, da ja einmal 7-Segment und dann 16-Segment ?
      Auch mein hin und her springen im Programm mit gosub und return ist sicherlich nicht ganz elegant gelöst.
      Aber aus einer If/Then in eine gosub zu springen, es funktioniert zwar, aber so richtig gefällt mir das nicht.
      Vielleicht hat jemand eine andere Idee.

      Gruß Dago1
      Dateien
      • VQB27.jpg

        (79,33 kB, 7 mal heruntergeladen, zuletzt: )
      • VQB200.jpg

        (129,91 kB, 6 mal heruntergeladen, zuletzt: )
      • VQBxxx.jpg

        (94,65 kB, 9 mal heruntergeladen, zuletzt: )
      • DTM_08_Test.bas

        (26,15 kB, 18 mal heruntergeladen, zuletzt: )
    • Dago1 schrieb:

      Aber aus einer If/Then in eine gosub zu springen
      ist kein Problem. Subs sind ja dazu da nicht immer das selbe schreiben zu müssen.
      Stell Dir vor: die halbe Main würde mit einem if entschieden und man dürfte nicht rausspringen.
      Wie immer könnte man einiges ändern, muß man aber nicht.

      in den kurzen If z.B. Zeile 266-274 kann das Gosub in Zeile 275 und bräuchte dann nur einmal geschrieben werden.

      Anstelle von Label (Anzeigen:) könnte eine Sub deklariert werden die im Aufruf Ihre Variablen bekommt
      dann würde Zeile 267-269 nur noch: Call Anzeigen( 0 , Zeichen1(3) , 2 , Zeichen1(3) )
      erheblich weniger Schreibarbeit, jedoch weniger Übersichtlich und belastender für den Avr (mehr Takte,Stack)


      Dago1 schrieb:

      Im Programm bin ich nicht glücklich über die Ansteuerung der MAX7219 z.Z..
      Würde es Sinn machen, die Max7219 einzeln über CS anzusteuern, da ja einmal 7-Segment und dann 16-Segment ?
      Weshalb?
      Das brächte einen Pin mehr, hätte jedoch den Vorteil das der Anzeigetext nur bei Änderung geschrieben werden muß. Die Ziffern könnten sie selber codieren, könnten anstelle der Zeichen gleich die Zahl bekommen - weniger Arbeit für den Avr (Verschiedene Init)

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Pluto25 ()

    • Dago1 schrieb:

      Auch mein hin und her springen im Programm mit gosub und return ist sicherlich nicht ganz elegant gelöst.
      Da hast du recht.
      Ich würde anstelle dem Gosub ein Call mit Sub-Routinen verwenden.
      Das macht den Code deutlich lesbarer und hat den Vorteil, dass man Parameter übergeben kann.
      Das spart globale Variablen.

      BASCOM-Quellcode: Beispiel Lesarkeit mit Gosub

      1. ' Hauptschleife
      2. Do
      3. Gosub Temp_lesen
      4. Loop
      5. Temp_lesen:
      6. ' Hier Code
      7. Return




      BASCOM-Quellcode: Beispiel Lesbarkeit mit Sub

      1. ' Hauptschleife
      2. Do
      3. Call Temp_lesen() ' Aufruf ohne Parameter
      4. Loop
      5. Sub Temp_lesen()
      6. ' Hier Code
      7. End Sub

      In deinem Programm findet sich immer wieder ein solches Konstrukt:

      BASCOM-Quellcode: Gosub Anzeige

      1. display_adress1 = &H0C : Display_daten1 = &H00 'Shutdown On
      2. display_adress2 = &H0C : Display_daten2 = &H00
      3. Gosub Anzeigen
      4. display_adress1 = &H0A : Display_daten1 = &H00 'Helligkeit 0-F
      5. display_adress2 = &H0A : Display_daten2 = &H00
      6. Gosub Anzeigen
      7. ' ----------------------------------------------------
      8. Anzeigen:
      9. ' Code
      10. Return
      Alles anzeigen
      Kann man besser machen:

      BASCOM-Quellcode: Call Anzeige mit Parameter

      1. Call Anzeigen(&H0C, &H00) 'Shutdown On
      2. Call Anzeigen(&H0C, &H00)
      3. ' ----------------------------------------
      4. Sub Anzeigen(Byval Adresse as Byte, Byval Wert as Byte) 'senden der anzuzeigenden Daten an den einzelnen 7-Segmentanzeigen
      5. Display_CS=0 'SPi Schreiben freigegeben
      6. Spiout Adresse , 1 '8 Bit Adresse des letzten (zweiten) MAX7219 in der Kette
      7. Spiout Wert , 1 '8 Bit Daten des letzten
      8. Display_CS=1 'SPi Schreiben stopp
      9. End Sub
      Alles anzeigen
      So in der Art.

      Das ist jetzt keine Kritik, sondern ein Tip. Dein Programm funktioniert ja.
      Aber so wäre es besser lesbar (zumindest im Bascom-Editor) und Resourcen-Schonender.
    • Pluto25 schrieb:

      Über das lesbar kann man geteilteter Meinung sein. (Welche Werte sind in den Klammern?)
      In den Klammern stehen die Adresse und der Wert, was gesendet werden soll.
      Das ist doch aus dem Code ersichtlich.


      Pluto25 schrieb:

      Ressourcen verbraucht es erheblich mehr. Takte sowie Flash und Stack
      Das ist für mich erst mal nur eine Behauptung.
      Beim Stack gebe ich dir recht, der wird aber nur Temporär verwendet für die Parameter.
      Während ohne Parameter du globale Variablen brauchst, die permanent Speicher belegt sind.
      Bei mehreren Routinen läppert sich das.
      Und ob das ein paar Takte mehr braucht, was nicht geprüft ist, spielt bei der Anwendung sowieso keine Rolle.
    • Noch ein Tip zur Umrechnung des Rohwertes vom Sensor in einen Temperaturwert.

      BASCOM-Quellcode: Umrechnung Rohwert in Temperatur

      1. Dim Rohwert as Integer ' hier steht der Rohwert vom Sensor drin
      2. Dim Temperatur as Single ' hier steht die berechnete Temperatur in °C drin
      3. Rohwert = &h1E70 ' Nach Datenblatt ist das -25°C
      4. If Rohwert.12=1 then Rohwert = Rohwert OR &hF000 ' bei neg. Werten Bits 15-15 auf 1 setzen
      5. Temperatur = Rohwert / 16
      6. Print Temperatur
      Alternativ kann man Temperatur auch mit Rohwert * 0,0625 berechnen
      Im wesentlichen ist das die Umrechnung:
      If Rohwert.12=1 then Rohwert = Rohwert OR &hF000
    • Der Rohwert enthält die Daten, so wie sie vom Sensor kommen.
      Durch die Abfrage des Bit 12 wird getestet, ob es eine negative Zahl ist, und wenn ja, werden die Bits darüber (Bit 13 bis 15) auch gesetzt.
      Damit ist das ein gültiger negativer Integer mit 16 Bit, so wie ihn Bascom intern verwendet.

      Hier sind Beispiel-Rohwerte aus dem Datenblatt
      Bildschirmfoto vom 2021-04-04 10-36-49.png
    • Mitch64 schrieb:

      Der Rohwert enthält die Daten, so wie sie vom Sensor kommen.
      und dort ist Bit 15 das Sign Bit, wie man es von 16Bit Integer erwartet.
      Da die 3 LSBs nicht nötig sind, muss man einfach 3 mal durch 2 teilen, also durch 8 und hat die Rohdaten 12Bit rechtsbündig, wobei Bit 15 immernoch das Sign Bit ist.
      LM92_raw.png

      (Datenblatt Ausschnitt von Texas Instruments, Seite 13)
    • Für gradgenaue Ausgabe braucht es auch die aufwendige Single Berechnung nicht.
      Anzeigewert = Lm92tempint_integer/128
      Das Vorzeichen bleibt dann bit 15
      If Lm92tempint_integer.15 = 1 Then....
      Zeichen1(4) = Bimu(13) 'Minus-Zeichen ausgeben
      Else 'wenn nicht, dann
      Zeichen1(4) = Bimu(14) 'Plus-Zeichen ausgeben
      End If
      Die einzelnen Stellen lassen sich einfacher erfassen:
      100er=wert/100
      10er =(wert-100*hunderter)/10
      einer = 10er mod 10
    • Hallo,

      ich wieder.
      Nun, nachdem mich so ein schönes Max7219 Modul mit der 8-stelligen roten Led Anzeigen, welches die kleinen chinesischen Kinder zusammengeschustert haben, wohl zu flink, geärgert hat, gut lassen wir das....
      Modul komplett nachgelötet und alles gut.
      Das Mosi-Signal muss natürlich auch parallel an die 2 Max7219 angelegt werden.
      Wollte schon den Max7221 nehmen, da der wohl eine echte SPi Schnittstelle hat.
      Habe mich nun entschieden, wie Mitch64 vorgeschlagen hatte, mit Call zu arbeiten. Muss sagen gefällt mir. Die Springerei ist zwar immernoch, aber durch die Parameterübergabe doch einfacher, wie ich finde.
      Habe mich auch entschieden die 2 Max7219 getrennt anzusteuern über den Load-Eingang.
      Wo ich mich schwer tue, ist bei der Zifferzerlegung mit MOD. Da komm ich irgendwie nicht klar. Vielleicht kann mir Pluto25 da etwas auf die Sprünge helfen.
      Michael, ja, Abs() ist auch nicht schlecht. Ich brauche halt immermal geistig einen Schubser in eine Richtung wo und wie es einfacher gehen kann.

      Habe halt Elektroniker gelernt und nie wirklich was mit Programmierung zu tun gehabt. Seit ein paar Jahren mache ich nun mit Bascom rum und erarbeite mir mein Wissen darüber Stück für Stück.

      So, anbei noch die akt. Datei.

      Gruß
      Dago
      Dateien
      • Test_03.bas

        (23,49 kB, 14 mal heruntergeladen, zuletzt: )
      • images29D1NFVF.jpg

        (11,81 kB, 11 mal heruntergeladen, zuletzt: )
    • Dem Avr wird nicht langweilig :D
      Das Mod ergibt praktischerweise den Rest:
      Lm92tempi = Lm92temperature (Das Lm92tempi ist eine Integer um von den Singles wegzukommen)
      Singles <X brauchen viel Rechenleistung, haben Rundungsfehler und Bandwurmreste (Mod)
      Hundeterstelle = Lm92tempi /100
      Zehner=Lm92tempi mod 100 (in Zehner kommt der Rest wenn Lm92tempi durch 100 geteilt wird)
      Zehnerstelle = Zehner/10
      Einerstelle = Zehner Mod 10 (wieder der Rest)
      Bei Dir ist es immer Ziffer daher die neuen Namen

      Weshalb wird der LM92 gefragt wenn sein Ergebnis nicht benutzt wird (vor der Main ) ?
      Zum "Warmlaufen" a_448_c66dc889 ?
      "Sreg.7 = 1" = "!SEI" = "Enable Interrrupts" sollte besser kurz vor der Main ausgeführt werden damit die Inits ungestört durcharbeiten können
    • Danke für Mod Erläuterung. Ich setze mich bei dieser Baustelle auch nochmal hin.
      Also nehme ich dann für die Zerlegung als Ausgangswert den Integerwert des Sensors.

      Der LM92 bringt bei der ersten Abfrage eine 0.
      Damit nicht beim "Kaltstart" der gespeicherte min-Wert 0 ist, sondern die akt. Temperatur enthält, dreht der LM92 bei mir eine Ehrenrunde.
      Hab mich aber auch noch nicht weiter mit den Konfigregistern des LM beschäftigt, da beim "nur" die akt. Temperatur anzeigen, das nicht stört.

      Gruß
      Dago
    • Dann fragst Du falsch. So hab ich hier Vier kleinere Brüder LM72 die schon lange Falsch befragt wurden.
      Nach dieser Methode ist der Highwert von der letzten Messung (Also keine nach dem, Einschalten.
      Das fällt weniger auf wenn sie oft gefragt werden. Die billigste Methode ist das highbyte nochmal zu fragen: Start, Leseadresse,(altes)Highbyte,Lowbyte,Highbyte,Stop. Eleganter ist Ihm mitzuteilen, daß man was wissen will: Start, Schreibadresse,Stop (oder Registeradresse (z.B. 0 für Themperaturwerte),Stop),
      Wieder Start, Leseadresse,Highbyte (Jetzt aktuell), Lowbyte , Stop

      Dago1 schrieb:

      als Ausgangswert den Integerwert des Sensors.
      Was hervorragend klappen würde wenn Du nur ganzzahlige Themperaturen bräuchtes. Die zehntel Grad sind binär. Möglich sollte sein (nicht versucht) den integerwert Durch 16 Mal 10 und noch Durch 8. a_56_df238249
    • Hallo,

      ich wieder.
      Ich brauche bitte nochmal Hilfe.
      Die ganze Sache soll ja ein Thermometer werden. Außen- und Innentemperatur umschaltbar auf eine LED-Anzeige.
      Bei beiden Temperaturen werden die jeweiligen max und min Werte gespeichert und per Tasten abgerufen. Die Außentemperatur soll über Funk mit den HC-12 Modulen, angesteuert per RS-232, übertragen werden.
      Die ganze Mimik mit der Umschalterei, Speicherei, Anzeigerei, Reset max / min funktioniert soweit.
      Mein Problem ist das Einlesen der Außentemp per RS-232.
      Ich verwende auf Sender- und Empfängerseite die Hardware Uart des Atmega8.
      Ich sende einfach mit printbin die 2 Byte als integer des Temp-Sensors. Mit While/Wend lege ich den "Sende-Intervall" fest (z.B. nach jeder 10. Temp-Messung). Funktioniert.
      Mit inputbin empfange ich die Daten, Das funktioniert auch.
      Jedoch wartet ja inputbin auf die kompletten Daten und der Programmablauf bleibt dann stehen. IsCharWaiting funktioniert wohl nur mit Inkey oder Waitkey.
      Config serialin, config com, und, und, und.... Recherche hier, Rechereche da, ich blick da nicht mehr durch.
      Ziel ist: Programm läuft, "nebenbei" die Außen-Temp-Daten per RS232 binär empfangen.
      Danke für die Hilfe.

      Gruß
      Dagobert

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Dago1 ()

    • Oder du machst es in einer eigenen ISR, die jedesmal aufgerufen wird, wenn ein Zeichen empfangen wurde.
      Wenig Aufwand, volle Kontrolle. Da kannst du auch abbrechen, wenn das zweite Byte aus irgendeinem Grund nicht kommt.
      Config SerialIn ist immer dann leicht anzuwenden, wenn am Ende der Übertragung ein fest definiertes Zeichen kommt, was sonst in den Daten nicht vorkommen kann. Das geht bei Printbin Integer nicht, im Normalfall nur, wenn du Ascii Zeichen überträgst. Die dirkete Abfrage der internen Variablen wird von MCS nicht empfohlen und ist auch fast nie nötig.
    • Dago1 schrieb:

      Wo ich mich schwer tue, ist bei der Zifferzerlegung mit MOD. Da komm ich irgendwie nicht klar.
      Ich hab´s erst jetzt gelesen :( Unser Lexikon hätte Dir helfen können. Dann für alle die noch danach suchen:

      MOD

      Übrigens lohnt ab und zu doch der Blick in´s Lexikon. Hier z.B. unter dem Buchstaben M :D

      Bei der Gelegenheit: Wenn Ihr Zeit und Lust habt: im Lexikon ist noch Platz :thumbsup:
      Wenn das die Lösung ist, möchte ich mein Problem wieder haben.
    • Hallo,

      wie realisiere ich denn nun die Zeit für die Anzeige der max und min Werte?
      Wait ist ja Mist. Mit einer Schleife, Timer, oder weiteren Taster zum Umschalten wieder auf die aktuelle Temperatur?
      Anbei das bisherige Programm.

      Gruß
      Dago
      Dateien
      • Test_09.bas

        (26,18 kB, 14 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Dago1 ()

    • Deine Main ist schon eine Schleife die eine gewisse Zeit braucht. Einfach einen Wert vorgeben der bei jedem Durchlauf reduziert wird. Z.B. Wait_Display_max
      In der Temp_max_in (520) Wait_Display_max = 1000
      Dann in der Main (314) if Wait_Display_max > 0 then
      Und (338) if Wait_Display_max > 0 then incr Wait_Display_max
      Damit zeigt er es 1000 Durchläufe an.
      Damit es kein Chaos gibt wenn die nächste Taste gerückt wird solange noch der letzt angeforderte Wert angezeigt wird könnte die Sub die anderen killen (520..)
      Wait_Display_min = 0
      Wait_Display_del = 0

      PS Flackert die aktuelle Temperatur nicht immer mit?

      Da die Anzeige behalten wird muß sie nicht die ganzen tausend mal beschrieben werden. So könnte die Abfrage auch (338) if Wait_Display_min = 1000 then
      und dann (351) else : waitms 10