mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Schnittstelle USB->RS232 und C++


Autor: derhalt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
ich hab mich, nachdem ich auf arbeit was kleines mit PWM+LED Ansteuerung 
machen musste mal im Internet schlau gemacht und dabei Ambi/MoMo-Lights 
entdeckt.
Habe das für ne ganz gute Übung gehalten und mal angefangen das zusammen 
zu tragen.
Mittlerweile existiert ein C++ Programm welches mir die Farbwerte aus 
verschiedenen Bildschirm bereichen (gradientenmässig) ausrechnet und 
eine Platine mit einem Atmega 8515 drauf, die theoretisch 4 RGB LEDs 
ansprechen kann.
Dazu ein in BASCOM verfasster Code welcher mir aus dem über FT232RL 
umgewandeltes RS232 Signal auf 12 Soft PWM Kanäle umparsed.

Da ich bis vor 3 Wochen noch absolute PWM/ATmega Jungfrau war und auch 
keine Ahnung hatte wie C++ mit COM-ports oder Bildschirminhalten umgeht 
war das ne ganz schöne Arbeit.

Nun wäre denn soweit alles zusammen was man braucht. Nur irgendwie finde 
ich keine Refferenzen dazu WAS und WIE GENAU ich meine RGB werte rüber 
schicken soll.

Die Funktion ist mir klar, nur der Inhalt der Bufferdatei schleierhaft. 
Habe zur Zeit ein Chararray in dem ich aus einer Zahl wie 213 ein "byte" 
mache, also "11010101" und dieses dann übertrage.
WriteFile(hComm,wBuf,dwBytesToWrite,&lpdwBytesRead,NULL);

auf der Seite des Atmegas dann polle ich einzelne bytes. Der bisherige 
Code  etwa eine Kopie vom Code eines Kollegen der schon öfters mal was 
mit Atmegas gemacht hat und sieht zur zeit etwa so aus:
I = Ischarwaiting()
   If I <> 0 Then
      Disable Interrupts

      'blue1
      Inputbin I
      Rec = Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      [usw für die andern farben]

      Inputbin I
      If I = 13 Then
         A = Mid(rec , 1 , 3)
         Blue1 = Val(a)
         A = Mid(rec , 4 , 3)
         Green1 = Val(a)
         [...usw]

      End If
      Enable Interrupts
   End If

Mein eigentliches Problem is jetz dass ich keine Ahnung habe was der 
Atmega für Inputs erwartet, oder was ich in C++ für Outputs über den 
Comport schicken kann so dass die beiden einander verstehen.

Wäre unheimlich dankbar weil ich irgendwo kurz vorm verzweifeln bin ;)

DerHalt

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Mein eigentliches Problem is jetz dass ich keine Ahnung habe was der
> Atmega für Inputs erwartet, oder was ich in C++ für Outputs über den
> Comport schicken kann so dass die beiden einander verstehen.

Hä wie jetzt, du sendes ein Byte vom PC und der AVR empfängst genau 
dieses Byte.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Inputbin
http://avrhelp.mcselec.com/inputbin.htm

Chr
http://avrhelp.mcselec.com/chr.htm

Mid
http://avrhelp.mcselec.com/mid.htm

Val
http://avrhelp.mcselec.com/val.htm

So wie das aussieht werden für jede Grundfarbe drei Bytes (Ziffern im 
ASCII-Code) gesendet. Das Telegramm wird mit 13(dez) abgeschlossen. Die 
Bytes werden in einen String umgeformt und wieder auseinandergepflückt:

Empfang von 49 50 51   52 53 54   55 56 57   13 (Lücken nur zur 
verdeutlichung, keine Beschränkung auf sinnvolle Werte 0...255 o.ä.)
String "123456789"
blue1  123
green1 456
red1   789

> aus einer Zahl wie 213 ein "byte" mache

Machst du nicht. Du machst drei Bytes draus. 213 wird als '2', '1' und 
'3' gesendet. Zum Umwandeln von Zahlen in Strings gint es Funktionen
http://www.mikrocontroller.net/articles/FAQ#Wie_ka...

Autor: derhalt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke für deine Antwort.
Habe in der Zeit bis jetz grad noch kurz ne eigene Itao geschrieben.
Der PC sendet jetz über USB ein 37byte langen Datenstrom 
3Farben*4LED*3Zeichen + '\0' endbyte.
Der Atmega scheint sich aber immer noch zu schade sein mit den hübschen 
Daten was anzufangen. Ich weiss ist vll bissl viel verlangt, aber ich 
post hier ma den Bascom source code. Vll hat ja jemand ein bisschen Zeit 
über, die er mir opfern würde :)
$regfile = "8515def.dat"
$crystal = 8000000
$baud = 19200
$hwstack = 32
$swstack = 10
$framesize = 40

Config Serialin = Buffered , Size = 13


Blue_1 Alias Portb.0
Config Blue_1 = Output
Blue_1 = 0

Green_1 Alias Portb.1
Config Green_1 = Output
Green_1 = 0

Red_1 Alias Portb.2
Config Red_1 = Output
Red_1 = 0

Blue_2 Alias Portb.3
Config Blue_2 = Output
Blue_2 = 0

Green_2 Alias Portb.4
Config Green_2 = Output
Green_2 = 0

Red_2 Alias Portb.5
Config Red_2 = Output
Red_2 = 0

Blue_3 Alias Portb.6
Config Blue_3 = Output
Blue_3 = 0

Green_3 Alias Portb.7
Config Green_3 = Output
Green_3 = 0

Red_3 Alias Portc.3
Config Red_3 = Output
Red_3 = 0

Blue_4 Alias Portc.2
Config Blue_4 = Output
Blue_4 = 0

Green_4 Alias Portc.1
Config Green_4 = Output
Green_4 = 0

Red_4 Alias Portc.0
Config Red_4 = Output
Red_4 = 0


Dim Pwm_counter As Byte

Dim Blue1 As Byte
Dim Green1 As Byte
Dim Red1 As Byte

Dim Blue2 As Byte
Dim Green2 As Byte
Dim Red2 As Byte

Dim Blue3 As Byte
Dim Green3 As Byte
Dim Red3 As Byte

Dim Blue4 As Byte
Dim Green4 As Byte
Dim Red4 As Byte

Dim Rec As String * 36

Dim A As String * 3
Dim I As Byte

Blue1 = 0
Blue2 = 0
Blue3 = 0
Blue4 = 0

Green1 = 0
Green2 = 0
Green3 = 0
Green4 = 0

Red1 = 0
Red2 = 0
Red3 = 0
Red4 = 0



Do
   Incr Pwm_counter
   If Pwm_counter = 255 Then
    Pwm_counter = 0
    Portb = 0
    Portc = 0                                               ''
    Gosub Neuerwert
   End If
   If Blue1 <= Pwm_counter Then
      Blue_1 = 1
   End If
   If Blue2 <= Pwm_counter Then
      Blue_2 = 1
   End If
   If Blue3 <= Pwm_counter Then
      Blue_3 = 1
   End If
   If Blue4 <= Pwm_counter Then
      Blue_4 = 1
   End If

   If Green1 <= Pwm_counter Then
      Green_1 = 1
   End If
   If Green2 <= Pwm_counter Then
      Green_2 = 1
   End If
   If Green3 <= Pwm_counter Then
      Green_3 = 1
   End If
   If Green4 <= Pwm_counter Then
      Green_4 = 1
   End If

   If Red1 <= Pwm_counter Then
      Red_1 = 1
   End If
   If Red2 <= Pwm_counter Then
      Red_2 = 1
   End If
   If Red3 <= Pwm_counter Then
      Red_3 = 1
   End If
   If Red4 <= Pwm_counter Then
      Red_4 = 1
   End If
Loop
End

Neuerwert:                                                  ''
   I = Ischarwaiting()
   If I <> 0 Then
      Disable Interrupts

      'blue1
      Inputbin I
      Rec = Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'green1
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'red1
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'blue2
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'green2
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'red2
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'blue3
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'green3
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'red3
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'blue4
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'green4
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)

      'red4
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)
      Inputbin I
      Rec = Rec + Chr(i)


      Inputbin I
      If I = 13 Then
         A = Mid(rec , 1 , 3)
         Blue1 = Val(a)
         A = Mid(rec , 4 , 3)
         Green1 = Val(a)
         A = Mid(rec , 7 , 3)
         Red1 = Val(a)

         A = Mid(rec , 10 , 3)
         Blue2 = Val(a)
         A = Mid(rec , 13 , 3)
         Green2 = Val(a)
         A = Mid(rec , 16 , 3)
         Red2 = Val(a)

         A = Mid(rec , 19 , 3)
         Blue3 = Val(a)
         A = Mid(rec , 22 , 3)
         Green3 = Val(a)
         A = Mid(rec , 25 , 3)
         Red3 = Val(a)

         A = Mid(rec , 28 , 3)
         Blue4 = Val(a)
         A = Mid(rec , 31 , 3)
         Green4 = Val(a)
         A = Mid(rec , 34 , 3)
         Red4 = Val(a)
      End If
      Enable Interrupts
   End If
Return
Vielen Dank schonmal im Voraus
DerHalt

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der PC sendet jetz über USB ein 37byte langen Datenstrom
> 3Farben*4LED*3Zeichen + '\0' endbyte.

Warum machst du sowas ;-)

Von einem '\0' war nie die Rede. Ein ASCII-Zeichen Carrige Return CR 13 
(dez.) muss da hin. das ist in C oder C++ ein '\r'

Ohne dieses Endezeichen wertet die BASCOM Routine den empfangenen Text 
nicht aus.

Autor: derhalt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hehe, sry, da war ich wohl noch zu sehr in c und hab das ganze als 
char-array richtig abschliessen wollen ^^
selbst so zeigt sich der uC leider unbeeindruckt am Kopf kratz

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du es schon mal geschafft, irgendwas an den µC zu senden?

Nicht dass es in deinem Hardwareaufbau (Taktrate AVR, RX-TX Kreuzung), 
dem Bascom Programm (der Eingangspuffer von nur 13 Zeichen bei 19200 
Baud kommt mir knapp vor) oder in deinem C++ Programm hapert.

Ich würde zum Testen der Hardware ein ordinäres Terminalprogramm 
benutzen und Handeingaben machen. Ideal ist z.B. das Bray-Terminal unter 
Windows, bei dem man Texte auf Makrotasten legen kann.
http://www.mikrocontroller.net/articles/RS-232#Windows

Autor: derhalt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also das Empfangs-LED blinkt fröhlich im Gleichtakt mit den gesendeten 
Daten. Müsste jetz nur noch rausfinden was der µC damit tut grins
achja, der Einganspuffer war noch falsch eingetragen. Mein Fehler. Wer 
ma schaun was ich tun kann.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In dem Bascom-Programm ist keine Empfangs-LED eingerichtet.

Eine /analog spionierende LED/ an der seriellen Leitung zeigt nur, dass 
was auf der Leitung ist, aber noch nicht, ob es von der Empfangs-UART 
mit der richtigen Baudrate und ohne Frameerror erkannt wird.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ALso irgendwie kommt mir vor, du zäumst das Pferd
hier viel zu kompliziert auf.

BASCOM kann doch einen String empfangen
http://www.rowalt.de/mc/avr/avrboard/06/avrb06.htm

D.h. von der PC Seite aus schickst du dem AVR einen
String
"123,50,80\n"
(oder wieviele Zahlen es dann auch immer sein sollen,
auf BASCOM Seite wird dieser String auch als String empfangen,
danach die einzelnen Zahlen mittels MID und VAL rausgeholt
und verarbeitet.

Autor: derhalt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habe ne Veranlagung zum Rückwärts aufzäumen.
Ich denke aber auch das die jetzige Situation eher so ist: Das Pferd ist 
bereits rückwärts aufgezäumt und ich muss nur noch rausfinden wie man es 
so rum reitet.
Das die LED nur anzeigt dass da überhaupt was ist, ist mir klar. Es ging 
aber drum um zumindest mal sagen zu können was denn funktioniert. Und 
das ist ganz klar der Weg "Porgramm->USB-Comport->RS232-Konverter mit 
LED" :)
Hab mal Free Comport Monitor mitlaufen lassen. Mein Programm schickt 
solche Datenpakete:
3,IRP_MJ_WRITE,UP,TRUE,0x0,30 37 36 30 37 36 30 37 37 30 33 33 30 33 35 30 33 38 30 31 30 30 31 30 30 31 31 30 36 33 30 36 34 30 36 34 0D ,076076077033035038010010011063064064.,
 076076 usw wären dabei die invertierten Farbwerte (also 255-179=076).

Habe jetz versucht kurz ne Print Funktion reinzupacken damit ich auch 
Rückmeldung oder so kriege. Leider tut sich in der Hinsicht gar nichts. 
Ich frage mich schon ob der µC überhaupt programmiert ist. Benutze zum 
ersten mal nen STK500 von nem Freund. Aber eigentlich krieg ich da 
keinen Fehler von.

Wenn ich wneigstens wüsste wo der Fehler liegt dann könnt ich was tun.
Ahjo, Stack hab ich auf 37 erhöht damit ein ganzer input reinpasst und 
hab noch gemerkt dass ich die baudraute vom Comport noch falsch 
eingestellt hatte. ist jetz alles 19200.

Finde es einfach komisch dass der meine Print s ignoriert. Jemand nen 
Vorschlag?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schreib ein neues Bascom Programm, welches eine LED im Sekundentakt 
blinken lässt. Warten kannst du mit DELAYY, WAIT oder WAITMS

Wenn das eine andere (8x langsamere) Blinkfrequenz hat, ist es 
verdächtig und die Taktquelle und die AVR Fuses müssen gecheckt werden.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Müsste jetz nur noch rausfinden was der µC damit tut

Dann starte mal deinen Debugger.

Autor: derhalt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen Community
Hab in der Zwischnezeit mal meine Empfangsroutine in das vorgeschlagene 
String-mit-Interrupt-füllen umgeändert. Muss jetz noch schauen ob ich 
den Output von meinem C Progy entsprechend anpassen kann.
Die sende routine schickt ganz offensichtlich ja das richtige los, die 
Empfangsroutine muss jetz nur noch das richtige damit anstellen ;)

Was den Debugger angeht. Hm, wie gesagt bin Neuling in der ganzen 
Geschichte und ich denke nicht dass ich sowas habe(?)
Halte euch auf dem laufenden und bin immer für Tipps zu haben ;)
DerHalt

Autor: derhalt (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Schönen Montag Mprgen wünsche ich.
Ich denke ich habe das Problem soweit verfolgt dasses wohl irgendwo 
Hardwaremäsig (erstmal) ist. Denn die LED auf dem STK500 leuchtet, 
wärend die auf meinem eigenen auch bei einfachsten LED-blink/leucht 
Anweisungen nicht reagiert. Die Seite PWM->LED funktioniert, denn 
schalte ich das PWM-Signal einfach auf 5V hoch, leuchtet die Diode ohne 
Probleme.
Müsste also irgendwo zwischen USB-Anschluss und AtMega irgendwas faul 
sein.
Wäre euch sehr dankbar wenn ihr mal nen kurzen Blick hier drauf werfen 
könntet.
Danke :)
DerHalt

Autor: derhalt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vergesst was ich sagte...das Problem mit dem LED Testprogramm war nicht 
die Hardware sondern der User hust
also jetz wieder Software tüfteln :(

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Was den Debugger angeht. Hm, wie gesagt bin Neuling in der ganzen
> Geschichte und ich denke nicht dass ich sowas habe(?)

Dann wirds höchste Zeit dich darum zu kümmern. Helfen dabei kann ich dir 
leider nicht, da ich keine AVRs verwende.

Autor: derhalt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Werd mich ma umschaun ;)
Also war heute fleissig. Programm auf dem µC jetz soweit umgebaut dasses 
mit nem viertel des Speicherplatzes endlich was kluges macht ;) (PWMs 
und Inputs handlen).
Kann jetz per Terminal die Farben au frisch-fröhlich ändern. Nur scheint 
ein unterschied zwischen dem Terminal und meiner Software zu bestehen, 
denn diese bringt die Lichter entweder zum ausflippen oder zum 
dauerleuchten  :)

werd mich morgen nochmals dahinter hängen. Bin aber für jegliche 
Vorschläge offen WARUM es nicht genau so klappt

PS: Terminal überträgt einfach 3x4 Zahlwerte (direkt als bytes) ohne 
delay...mein Programm macht das selbe . keine endbytes oder so und auch 
kein unterschied in baudrate.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.