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


von derhalt (Gast)


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.
1
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:
1
I = Ischarwaiting()
2
   If I <> 0 Then
3
      Disable Interrupts
4
5
      'blue1
6
      Inputbin I
7
      Rec = Chr(i)
8
      Inputbin I
9
      Rec = Rec + Chr(i)
10
      Inputbin I
11
      Rec = Rec + Chr(i)
12
13
      [usw für die andern farben]
14
15
      Inputbin I
16
      If I = 13 Then
17
         A = Mid(rec , 1 , 3)
18
         Blue1 = Val(a)
19
         A = Mid(rec , 4 , 3)
20
         Green1 = Val(a)
21
         [...usw]
22
23
      End If
24
      Enable Interrupts
25
   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

von Gast (Gast)


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.

von Stefan B. (stefan) Benutzerseite


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_kann_ich_Zahlen_auf_LCD.2FUART_ausgeben.3F

von derhalt (Gast)


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 :)
1
$regfile = "8515def.dat"
2
$crystal = 8000000
3
$baud = 19200
4
$hwstack = 32
5
$swstack = 10
6
$framesize = 40
7
8
Config Serialin = Buffered , Size = 13
9
10
11
Blue_1 Alias Portb.0
12
Config Blue_1 = Output
13
Blue_1 = 0
14
15
Green_1 Alias Portb.1
16
Config Green_1 = Output
17
Green_1 = 0
18
19
Red_1 Alias Portb.2
20
Config Red_1 = Output
21
Red_1 = 0
22
23
Blue_2 Alias Portb.3
24
Config Blue_2 = Output
25
Blue_2 = 0
26
27
Green_2 Alias Portb.4
28
Config Green_2 = Output
29
Green_2 = 0
30
31
Red_2 Alias Portb.5
32
Config Red_2 = Output
33
Red_2 = 0
34
35
Blue_3 Alias Portb.6
36
Config Blue_3 = Output
37
Blue_3 = 0
38
39
Green_3 Alias Portb.7
40
Config Green_3 = Output
41
Green_3 = 0
42
43
Red_3 Alias Portc.3
44
Config Red_3 = Output
45
Red_3 = 0
46
47
Blue_4 Alias Portc.2
48
Config Blue_4 = Output
49
Blue_4 = 0
50
51
Green_4 Alias Portc.1
52
Config Green_4 = Output
53
Green_4 = 0
54
55
Red_4 Alias Portc.0
56
Config Red_4 = Output
57
Red_4 = 0
58
59
60
Dim Pwm_counter As Byte
61
62
Dim Blue1 As Byte
63
Dim Green1 As Byte
64
Dim Red1 As Byte
65
66
Dim Blue2 As Byte
67
Dim Green2 As Byte
68
Dim Red2 As Byte
69
70
Dim Blue3 As Byte
71
Dim Green3 As Byte
72
Dim Red3 As Byte
73
74
Dim Blue4 As Byte
75
Dim Green4 As Byte
76
Dim Red4 As Byte
77
78
Dim Rec As String * 36
79
80
Dim A As String * 3
81
Dim I As Byte
82
83
Blue1 = 0
84
Blue2 = 0
85
Blue3 = 0
86
Blue4 = 0
87
88
Green1 = 0
89
Green2 = 0
90
Green3 = 0
91
Green4 = 0
92
93
Red1 = 0
94
Red2 = 0
95
Red3 = 0
96
Red4 = 0
97
98
99
100
Do
101
   Incr Pwm_counter
102
   If Pwm_counter = 255 Then
103
    Pwm_counter = 0
104
    Portb = 0
105
    Portc = 0                                               ''
106
    Gosub Neuerwert
107
   End If
108
   If Blue1 <= Pwm_counter Then
109
      Blue_1 = 1
110
   End If
111
   If Blue2 <= Pwm_counter Then
112
      Blue_2 = 1
113
   End If
114
   If Blue3 <= Pwm_counter Then
115
      Blue_3 = 1
116
   End If
117
   If Blue4 <= Pwm_counter Then
118
      Blue_4 = 1
119
   End If
120
121
   If Green1 <= Pwm_counter Then
122
      Green_1 = 1
123
   End If
124
   If Green2 <= Pwm_counter Then
125
      Green_2 = 1
126
   End If
127
   If Green3 <= Pwm_counter Then
128
      Green_3 = 1
129
   End If
130
   If Green4 <= Pwm_counter Then
131
      Green_4 = 1
132
   End If
133
134
   If Red1 <= Pwm_counter Then
135
      Red_1 = 1
136
   End If
137
   If Red2 <= Pwm_counter Then
138
      Red_2 = 1
139
   End If
140
   If Red3 <= Pwm_counter Then
141
      Red_3 = 1
142
   End If
143
   If Red4 <= Pwm_counter Then
144
      Red_4 = 1
145
   End If
146
Loop
147
End
148
149
Neuerwert:                                                  ''
150
   I = Ischarwaiting()
151
   If I <> 0 Then
152
      Disable Interrupts
153
154
      'blue1
155
      Inputbin I
156
      Rec = Chr(i)
157
      Inputbin I
158
      Rec = Rec + Chr(i)
159
      Inputbin I
160
      Rec = Rec + Chr(i)
161
162
      'green1
163
      Inputbin I
164
      Rec = Rec + Chr(i)
165
      Inputbin I
166
      Rec = Rec + Chr(i)
167
      Inputbin I
168
      Rec = Rec + Chr(i)
169
170
      'red1
171
      Inputbin I
172
      Rec = Rec + Chr(i)
173
      Inputbin I
174
      Rec = Rec + Chr(i)
175
      Inputbin I
176
      Rec = Rec + Chr(i)
177
178
      'blue2
179
      Inputbin I
180
      Rec = Rec + Chr(i)
181
      Inputbin I
182
      Rec = Rec + Chr(i)
183
      Inputbin I
184
      Rec = Rec + Chr(i)
185
186
      'green2
187
      Inputbin I
188
      Rec = Rec + Chr(i)
189
      Inputbin I
190
      Rec = Rec + Chr(i)
191
      Inputbin I
192
      Rec = Rec + Chr(i)
193
194
      'red2
195
      Inputbin I
196
      Rec = Rec + Chr(i)
197
      Inputbin I
198
      Rec = Rec + Chr(i)
199
      Inputbin I
200
      Rec = Rec + Chr(i)
201
202
      'blue3
203
      Inputbin I
204
      Rec = Rec + Chr(i)
205
      Inputbin I
206
      Rec = Rec + Chr(i)
207
      Inputbin I
208
      Rec = Rec + Chr(i)
209
210
      'green3
211
      Inputbin I
212
      Rec = Rec + Chr(i)
213
      Inputbin I
214
      Rec = Rec + Chr(i)
215
      Inputbin I
216
      Rec = Rec + Chr(i)
217
218
      'red3
219
      Inputbin I
220
      Rec = Rec + Chr(i)
221
      Inputbin I
222
      Rec = Rec + Chr(i)
223
      Inputbin I
224
      Rec = Rec + Chr(i)
225
226
      'blue4
227
      Inputbin I
228
      Rec = Rec + Chr(i)
229
      Inputbin I
230
      Rec = Rec + Chr(i)
231
      Inputbin I
232
      Rec = Rec + Chr(i)
233
234
      'green4
235
      Inputbin I
236
      Rec = Rec + Chr(i)
237
      Inputbin I
238
      Rec = Rec + Chr(i)
239
      Inputbin I
240
      Rec = Rec + Chr(i)
241
242
      'red4
243
      Inputbin I
244
      Rec = Rec + Chr(i)
245
      Inputbin I
246
      Rec = Rec + Chr(i)
247
      Inputbin I
248
      Rec = Rec + Chr(i)
249
250
251
      Inputbin I
252
      If I = 13 Then
253
         A = Mid(rec , 1 , 3)
254
         Blue1 = Val(a)
255
         A = Mid(rec , 4 , 3)
256
         Green1 = Val(a)
257
         A = Mid(rec , 7 , 3)
258
         Red1 = Val(a)
259
260
         A = Mid(rec , 10 , 3)
261
         Blue2 = Val(a)
262
         A = Mid(rec , 13 , 3)
263
         Green2 = Val(a)
264
         A = Mid(rec , 16 , 3)
265
         Red2 = Val(a)
266
267
         A = Mid(rec , 19 , 3)
268
         Blue3 = Val(a)
269
         A = Mid(rec , 22 , 3)
270
         Green3 = Val(a)
271
         A = Mid(rec , 25 , 3)
272
         Red3 = Val(a)
273
274
         A = Mid(rec , 28 , 3)
275
         Blue4 = Val(a)
276
         A = Mid(rec , 31 , 3)
277
         Green4 = Val(a)
278
         A = Mid(rec , 34 , 3)
279
         Red4 = Val(a)
280
      End If
281
      Enable Interrupts
282
   End If
283
Return
Vielen Dank schonmal im Voraus
DerHalt

von Stefan B. (stefan) Benutzerseite


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.

von derhalt (Gast)


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

von Stefan B. (stefan) Benutzerseite


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

von derhalt (Gast)


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.

von Stefan B. (stefan) Benutzerseite


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.

von Karl H. (kbuchegg)


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.

von derhalt (Gast)


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:
1
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?

von Stefan B. (stefan) Benutzerseite


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.

von Gast (Gast)


Lesenswert?

> Müsste jetz nur noch rausfinden was der µC damit tut

Dann starte mal deinen Debugger.

von derhalt (Gast)


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

von derhalt (Gast)


Angehängte Dateien:

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

von derhalt (Gast)


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 :(

von Gast (Gast)


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.

von derhalt (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.