SerialCominstruments 4 und Bascom

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

  • SerialCominstruments 4 und Bascom
    Will man mit serialcominstruments.com/instrument4.php seine Mess-oder Zählwerte grafisch auf dem PC-Monitor darstellen, bietet sich als Interface ein kleiner AVR an. Mit diesem Programm lassen sich auf einfachste Weise mehrere Werte gleichzeitig darstellen, wobei man die Anzahl, Größe, Auflösung und das Design der verschiedenen Messinstrumente selbst festlegen kann. Es lassen sich mehrere Werte gleichzeitig mit einstellbarem Messintervall als Verlauf grafisch darstellen und auch aufzeichnen. Ebenso ist es möglich, Texte vom MC zu empfangen und anzuzeigen. Auch einfache LED-Status-Anzeigen lassen sich in verschiedenen Formen vom MC aus steuern. Doch die Kommunikation funktioniert auch in die andere Richtung, die Software kann dem MC Werte von Schiebereglern schicken, verschiedene Schalter, natürlich in Größe und Design einstellbar, teilen ihren Status mit und nicht zuletzt kann man Befehle per Eingabefeld als Text senden("Licht an!"). Somit ist der MC komplett fernsteuerbar, ohne eine einzige Taste anzuschließen. Ein Terminal-Fenster lässt sich ebenfalls öffnen.
    Daraus ergeben sich vielfältige Anwendungsmöglichkeiten. Angefangen von der Möglichkeit, z.B. mehrere Spannungen gleichzeitig zu messen und darzustellen, oder die Lade/Entladekurve eines Akku's grafisch aufzuzeichnen. Man überlege, mit wie viel Aufwand gerade letzteres zu realisieren wäre(Anzeige,Speicher etc.).


    Ebenfalls denkbar, eine Riesen Anzeige, z.B. für Schulungen u.s.w.:


    Und noch weitere Darstellungen


    Diese Oberflächen sind alle mit ein paar Klick's erstellt. Es besteht auch die Möglichkeit, als Hintergrund ein(z.B. mit Paint erstelltes) Bild einzufügen.

    Was noch fehlt, ist die Verbindung zur Aussenwelt. Die Kommunikation erfolgt über LAN oder eine Serielle Schnittstelle. Da diese an den wenigsten Rechnern noch zu finden sein dürfte, funktioniert das ganze auch über den USB-Anschluss per USB-RS232 Adapter.
    Ich benutzte ein Adapterkabel, in welchem die Elektronik im Stecker verbaut ist. Es handelt sich dabei um den Chip PL2303, welcher von WIN7 sofort erkannt wurde. Nur WIN10 haderte mit dem Adapter, nach der Installation eines alten Treiber's(für WIN7/WIN8.1) funktioniert es aber zuverlässig ohne Aussetzer.
    Neben RXD und TXD hat man auch gleich die 5 Volt Stromversorgung aus dem PC dabei. Ein 100nF Kondensator am MC, mehr braucht es nicht, da die interne Spannungsreferenz von 2.56 Volt des ATMega8 zum messen genutzt wird. Eine Hand voll Bauteile werden noch für den Spannungsteiler am ADC Eingang benötigt. Für den 100 Volt Bereich verwende ich: Messeingang - 180 KOhm - Trimmer 220 Ohm - 4,7 kOhm an GND. Die Mittelanzapfung des Trimmers über einen 12 kOhm Widerstand direkt an einen der sechs Ad-Wandler Eingänge legen. So lässt sich der Messwert ganz genau einjustieren. Am Mess-Eingang noch eine Diode in Sperrrichtung nach GND für den Verpolungsschutz. Aber hier muss jeder die Eingangsbeschaltung nach seinen Bedürfnissen ausrichten.

    Die COM-Schnittstelle ist fest eingestellt auf 8 Data Bits, 1 Stop Bit und No Parity, wir brauchen also in unserem Bascom Code nichts einstellen.
    Die Kommunikation erfolgt nun folgendermaßen: Der ATMega sendet seine gemessenen Werte als String über den UART mit 115200 kb an den PC. Für einen Kanal sieht das dann so aus:

    Print "#1M" ; Str(i1) ; "<"

    wobei # = Start Übertragung
    1 = Kanalnummer
    M = Start Messwert
    String = Messwert
    < = Ende Messwert
    bedeuten.
    Jetzt zeigen alle Messinstrumente, bei denen der Kanal 1 eingestellt ist, unseren Messwert schon an. Über eine Skalierung kann jedes Instrument noch an unseren Wert angepasst werden.
    Mehrere Werte werden so übertragen:

    Print "#1M" ; Str(i1) ; "<" ; "#2M" ; Str(i2) ; "<" ; "#3M" ; Str(i3) ; "<" ; "#4M" ; Str(i4) ; "<" ; "#5M" ; Str(i5) ; "<" ; "#6M" ; Str(i6) ; "<"

    Eine LED darstellen:

    Print "#40M" ; 2 ; 1 ; "<"

    würde eine grüne(2), rechteckige(1) LED auf dem Icon mit Kanal 40 darstellen. Die Farben und Formen kann man dem sehr guten deutschen Manual entnehmen.

    Mit:

    Print "#40M" ; "Fehler21" ; "<"

    erhält man im Textfeld mit der Kanalnummer 40 fortlaufend die Meldung "Fehler 21" mit Uhrzeit und Datum(Fehlerspeicher). Im Textfeld "Text Shape" erscheint die Meldung einmalig bis zur nächsten Meldung, aber man kann zusätzlich vom MC aus die Text und Background Farbe senden, bitte dem Manual entnehmen.

    Zur Steuerung des MC durch die Software: Für einen Schalter mit Kanal 20 sendet das Programm #20Ms< wobei s=Status (0=Aus, 1=Ein) ist. Das ganze wird wieder als String gesendet, so dass man sich nun die einzelnen Byte's raus angeln muss.
    Ich habe das so gelöst:
    INT für jedes empfangene Byte:

    Enable Urxc
    On Urxc Uart0 'ISR
    Enable Interrupts 'generell Interrupts einschalten

    In der ISR zu einem String zusammen fügen:

    Dat = Inkey() 'empfangenes Byte einlesen
    S = S + Chr(dat) 'zum String dazu fügen

    Das CRLF auswerten:

    If Dat = 10 Then 'ENDE-Zeichen von UART auswerten
    ' Print S 'String zurück schicken zu Kontrolle im Terminal
    Gosub Ausführen
    S = "" 'String löschen
    Dat = 0 'zuletzt empfangenes Byte löschen
    End If

    und die Aktion ausführen:


    Aktor = Mid(s , 2 , 2) 'Aktoren(DAC und Schalter) müssen 2-Stellige Kanalnummern haben
    Status = Mid(s , 5 , 1)
    If Aktor = "20" Then 'Schalter1
    If Status = "0" Then 'Aus
    Led1 = 0
    Elseif Status = "1" Then 'Ein
    Led1 = 1
    End If
    Elseif Aktor = "21" Then 'Schalter2
    If Status = "0" Then 'Aus
    Led2 = 0
    Elseif Status = "1" Then 'Ein
    Led2 = 1
    End If
    Elseif Aktor = "10" Then 'DAC Kanal 10 auf Format"000" stellen, damit immer 3-stellig
    Stellwert = Mid(s , 5 , 1)
    Pwm_wert = Stellwert - 48 'wegen ASCII im String
    Pwm_wert = Pwm_wert * 100 ' Hunderter
    Stellwert = Mid(s , 6 , 1)
    Byte_wert = Stellwert - 48
    Byte_wert = Byte_wert * 10 'Zehner
    Pwm_wert = Pwm_wert + Byte_wert
    Stellwert = Mid(s , 7 , 1)
    Byte_wert = Stellwert - 48 'Einer
    Pwm_wert = Pwm_wert + Byte_wert
    Print "#7M" ; Str(pwm_wert) ; "<" 'für eine Kontroll-Anzeige (Kanal 7)
    Pwm1b = Pwm_wert
    End If

    Da das ganze bisher nur ein Test war, ist der Code noch nicht optimal. Eine CASE Anweisung ist bei mehreren Aktoren sicherlich übersichtlicher und die einzelnen Byte's lassen sich besser als Overlay des eingelesenen String auslesen.
    Hier mal der gesamte,funktionierende Code für 6 ADC, 2 LED Ausgänge und ein PWM Ausgang mit Rückmeldung:


    BASCOM-Quellcode

    1. $regfile = "m8def.dat"
    2. $crystal = 8000000
    3. $hwstack=40
    4. $swstack=16
    5. $framesize=32
    6. $baud = 115200
    7. '----------------------------------------------------------------------------------------------------------------------
    8. 'AD-Wandler einschalten
    9. Config Adc = Single , Prescaler = Auto , Reference = Internal
    10. Start Adc
    11. '----------------------------------------------------------------------------------------------------------------------
    12. 'INT UART-Empfang Int nach jedem empfangenen Byte
    13. Enable Urxc
    14. On Urxc Uart0 'ISR
    15. Enable Interrupts 'generell Interrupts einschalten
    16. '----------------------------------------------------------------------------------------------------------------------
    17. Config Timer1 = Pwm , Pwm = 8 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up , Prescale = 64
    18. '----------------------------------------------------------------------------------------------------------------------
    19. Config Portd.7 = Output
    20. Config Portb.0 = Output
    21. Led1 Alias Portd.7
    22. Led2 Alias Portb.0
    23. '----------------------------------------------------------------------------------------------------------------------
    24. Dim I1 As Single
    25. Dim I2 As Single
    26. Dim I3 As Single
    27. Dim I4 As Single
    28. Dim I5 As Single
    29. Dim I6 As Single
    30. Dim Z As Byte
    31. Dim N As Byte
    32. Dim U As Word
    33. Dim Tabelle1(50) As Word
    34. Dim Tabelle2(50) As Word
    35. Dim Tabelle3(50) As Word
    36. Dim Tabelle4(50) As Word
    37. Dim Tabelle5(50) As Word
    38. Dim Tabelle6(50) As Word
    39. Dim Index As Byte
    40. Dim Median As Word
    41. Dim S As String * 13
    42. Dim Dat As Byte
    43. Dim Byte_wert As Byte
    44. Dim Pwm_wert As Byte
    45. Dim Stellwert As String * 3
    46. Dim Status As String * 1
    47. Dim Aktor As String * 2
    48. Pwm1b = 0
    49. Led1 = 1
    50. Waitms 200
    51. Led2 = 1
    52. Waitms 200
    53. Led1 = 0
    54. Led2 = 0
    55. Do
    56. If Dat = 10 Then 'ENDE-Zeichen von UART auswerten
    57. Print S 'String zurück schicken zu Kontrolle im Terminal
    58. Gosub Ausführen
    59. S = "" 'String löschen
    60. Dat = 0 'zuletzt empfangenes Byte löschen
    61. End If
    62. Index = Index + 1
    63. U = Getadc(0)
    64. Waitus 300
    65. Tabelle1(index) = U
    66. U = Getadc(1)
    67. Waitus 300
    68. Tabelle2(index) = U
    69. U = Getadc(2)
    70. Waitus 300
    71. Tabelle3(index) = U
    72. U = Getadc(3)
    73. Waitus 300
    74. Tabelle4(index) = U
    75. U = Getadc(4)
    76. Waitus 300
    77. Tabelle5(index) = U
    78. U = Getadc(5)
    79. Waitus 300
    80. Tabelle6(index) = U
    81. If Index = 50 Then
    82. Gosub Median50
    83. Print "#1M" ; Str(i1) ; "<" ; "#2M" ; Str(i2) ; "<" ; "#3M" ; Str(i3) ; "<" ; "#4M" ; Str(i4) ; "<" ; "#5M" ; Str(i5) ; "<" ; "#6M" ; Str(i6) ; "<"
    84. End If
    85. Loop
    86. Ausführen:
    87. Aktor = Mid(s , 2 , 2) 'Aktoren(DAC und Schalter) müssen 2-Stellige Kanalnummern haben
    88. Status = Mid(s , 5 , 1)
    89. If Aktor = "20" Then 'Schalter
    90. If Status = "0" Then 'Aus
    91. Led1 = 0
    92. Elseif Status = "1" Then 'Ein
    93. Led1 = 1
    94. End If
    95. Elseif Aktor = "21" Then 'Schalter
    96. If Status = "0" Then 'Aus
    97. Led2 = 0
    98. Elseif Status = "1" Then 'Ein
    99. Led2 = 1
    100. End If
    101. Elseif Aktor = "10" Then 'DAC Kanal 10 auf Format"000" stellen, damit immer 3-stellig
    102. Stellwert = Mid(s , 5 , 1)
    103. Pwm_wert = Stellwert - 48 'wegen ASCII im String
    104. Pwm_wert = Pwm_wert * 100 ' Hunderter
    105. Stellwert = Mid(s , 6 , 1)
    106. Byte_wert = Stellwert - 48
    107. Byte_wert = Byte_wert * 10 'Zehner
    108. Pwm_wert = Pwm_wert + Byte_wert
    109. Stellwert = Mid(s , 7 , 1)
    110. Byte_wert = Stellwert - 48 'Einer
    111. Pwm_wert = Pwm_wert + Byte_wert
    112. Print "#7M" ; Str(pwm_wert) ; "<" 'für eine Kontroll-Anzeige (Kanal 7)
    113. Pwm1b = Pwm_wert
    114. End If
    115. Return
    116. '---------------------------------------------------------------------------------------
    117. Median50:
    118. For N = 1 To 24 '24mal kleinsten Wert in Tabelle suchen und auf 65000 setzen
    119. Min(tabelle1(1) , Median , Index)
    120. Tabelle1(index) = 65000
    121. Next
    122. Min(tabelle1(1) , Median , Index) 'der 25. minwert ist der Median
    123. I1 = Median / 10
    124. For N = 1 To 24
    125. Min(tabelle2(1) , Median , Index)
    126. Tabelle2(index) = 65000
    127. Next
    128. Min(tabelle2(1) , Median , Index)
    129. I2 = Median / 10
    130. For N = 1 To 24
    131. Min(tabelle3(1) , Median , Index)
    132. Tabelle3(index) = 65000
    133. Next
    134. Min(tabelle3(1) , Median , Index)
    135. I3 = Median / 10
    136. For N = 1 To 24
    137. Min(tabelle4(1) , Median , Index)
    138. Tabelle4(index) = 65000
    139. Next
    140. Min(tabelle4(1) , Median , Index)
    141. I4 = Median / 10
    142. For N = 1 To 24
    143. Min(tabelle5(1) , Median , Index)
    144. Tabelle5(index) = 65000
    145. Next
    146. Min(tabelle5(1) , Median , Index)
    147. I5 = Median / 10
    148. For N = 1 To 24
    149. Min(tabelle6(1) , Median , Index)
    150. Tabelle6(index) = 65000
    151. Next
    152. Min(tabelle6(1) , Median , Index)
    153. I6 = Median / 10
    154. Index = 0
    155. Return
    156. Uart0:
    157. Dat = Inkey() 'empfangenes Byte einlesen
    158. S = S + Chr(dat) 'zum String dazu fügen
    159. Return
    Alles anzeigen
    Weil der ATMega Platz und Zeit hatte, habe ich für die ADC's je einen Medianfilter mit eingebaut, somit stören keine Ausreißer.
    Der ATMega8 ist damit noch nicht halb gefüllt, da gibt es noch Reserven. Für aufwändigere Programme muss man dann einen anderen MC benutzen, wobei dann zu beachten ist, dass sich die UART Register, die Timer für die PWM und auch die interne Referenzspannung ändern können.

    218 mal gelesen