Hallo Leute,
ich bin gerade dabei simple Zeichenketten von Matlab an den
Mikrocontroller zu senden und der soll das wieder zurücksenden.
Habe das ganze schon in HTerm versucht und da klappt es soweit ganz gut.
Verwende ein Mega2560 Board und die Bibliothek von Peter Fleury für
UART.
Der folgende C-Code ist am Mikrocontroller:
1
#include<avr/io.h>
2
#include<stdlib.h>
3
#include<avr/io.h>
4
#include<avr/interrupt.h>
5
#include<avr/pgmspace.h>
6
#include<util/delay.h>
7
8
#include"uart.h"
9
10
#define F_CPU 16000000UL
11
12
/* define CPU frequency in Hz in Makefile */
13
#ifndef F_CPU
14
#define F_CPU 16000000UL
15
#endif
16
17
/* Define UART buad rate here */
18
#define UART_BAUD_RATE 9600
19
20
uint8_tuart_getc_wait()
21
{
22
unsignedintc;
23
24
do{
25
c=uart_getc();
26
}while(c==UART_NO_DATA);
27
28
return(uint8_t)c;
29
}
30
31
voiduart_gets(char*Buffer,uint8_tMaxLen)
32
{
33
uint8_tNextChar;
34
uint8_tStringLen=0;
35
36
NextChar=uart_getc_wait();// Warte auf und empfange das nächste Zeichen
Wenn ich das ganze versuche bekomme ich als Fehlermeldung:
Warning: Unexpected Warning: A timeout occurred before the Terminator
was reached.
Ergo es muss ja iwie am Terminator liegen.
Habs aber bisher nicht hinbekommen.
Seh ich den Wald vor lauter Bäumen nicht oder warum funktioniert das bei
mir nicht?
Was steht denn in received drin? Enthält der String 'Hallo Welt\n' ein
LF? Kannst Du mit double('Hallo Welt\n') überprüfen.
Evtl. macht ein fprintf(MEga2560,'\n') das, was Du erwartest.
>> Was steht denn in received drin?
Es wird der oben genannte Fehler ausgegeben und dann kommt:
received = 0x0 empty char array
>> Evtl. macht ein fprintf(MEga2560,'\n') das, was Du erwartest.
Wie meinst du das genau? einfach nach dem 'Hallo Welt' extra den Befehl
Du schickst die Zeichenkette char([72 97 108 108 111 32
87 101 108 116 92 110]) über den seriellen Port, d.h. \n wird
als ['\' 'n'] geschickt. Du willst aber \n per printf interpretieren als
char([10]).
Steff G. schrieb:> Steh ich grad voll am Schlauch?
Ja.
Tipp: Installier Dir ein Nullmodem-Device und schau Dir die Sachen, die
Matlab verschickt, in einem Terminal an.
> Tipp: Installier Dir ein Nullmodem-Device und schau Dir die Sachen, die> Matlab verschickt, in einem Terminal an.
Hab ich gerade installiert und wenn ich folgenden Code mit Matlab
eingebe:
1
clc
2
close all;
3
clear all;
4
5
// Aktive Ports löschen
6
delete(instrfindall);
7
8
// USB Port initialisieren
9
10
Mega2560=serial('COM5');
11
disp('Kommunikation aufgebaut')
12
set(Mega2560,'BaudRate',9600);
13
set(Mega2560,'Terminator','LF');
14
set(Mega2560,'DataBits',8);
15
set(Mega2560,'Parity','none');
16
set(Mega2560,'StopBits',1);
17
18
// Verbindung zum Mikrocontroller
19
20
fopen(Mega2560);
21
fprintf(Mega2560,'Hallo Welt');
22
received = fgetl(Mega2560)
23
fclose(Mega2560);
Hab also den fwrite-Befehl abgeändert zu fprintf und kein "\n"
angehängt,
dann zeigt er mir bei Hterm an:
Hallo Welt\n
Müsste somit doch eigentlich passen.
Ich bin jetzt wirklich bisschen überfragt, warum das ganze nicht klappt.
Wenn ich von Hterm zeichen zurücksende, dann empfängt die Daten Matlab
auch einwandfrei.
Sobald ich das am Board sehen kannn blinkt die RX-LED beim senden, aber
es kommt anscheinend nichts zurück.
Kann mir bitte jemand helfen?
> Was kommt denn zurück, wenn Du aus dem Terminal-Programm ans Board> sendest?
Wenn ich in Hterm
Hallo
eingeben bekomme ich zurück:
'Hallo'
Also es sollte alles rund um funktionieren - sobald ich jedoch mein
Board anstecke bekomme ich nichts zurück??
> Was kommt denn zurück, wenn Du aus dem Terminal-Programm ans> Board> sendest?
Wenn ich in Hterm
Hallo
eingeben bekomme ich zurück:
received = 'Hallo'
Also es sollte alles rund um funktionieren - sobald ich jedoch mein
Board anstecke bekomme ich nichts zurück??
Jetzt habe ich die Übersicht verloren.
Du kannst ja jetzt testen:
Board <-> Terminalprogramm
Terminalprogramm <-> Matlab
Welches von beidem hast Du getestet? Wie sehen die "Echo"-Einstellungen
des Terminalprogramms aus?
Steff G. schrieb:> while(1)> {> uart_gets (Line, sizeof(Line));>> uart_puts(Line);> uart_puts( "\n" );> }
Du lässt vom uC lauter leere Zeilen zurücksenden, wenn nicht gerade ein
Zeichen reinkommt... Da wundert es nicht, wenn beim Empfänger auch nix
ankommt....
Wie wäre es, wenn du in der While Schleife so vorgehst:
- Liegt ein Zeichen an?
=> Ja, dann lese das aus und schicke es wieder zurück... (Und nur
dieses... kein \n hintendran)
Reiner_Gast schrieb:
>Du lässt vom uC lauter leere Zeilen zurücksenden, wenn nicht gerade ein>Zeichen reinkommt... Da wundert es nicht, wenn beim Empfänger auch nix>ankommt....
Ich habe doch im Code das
1
uint8_tuart_getc_wait()
2
{
3
unsignedintc;
4
5
do{
6
c=uart_getc();
7
}while(c==UART_NO_DATA);
8
9
return(uint8_t)c;
10
}
welches so lange wartet bis ein Zeichen anliegt?
Oder irre ich mich da?
Steff G. schrieb:> Ich habe doch im Code dasuint8_t uart_getc_wait()> {> unsigned int c;>> do {> c=uart_getc();> }while (c == UART_NO_DATA);>> return (uint8_t)c;> }>> welches so lange wartet bis ein Zeichen anliegt?> Oder irre ich mich da?
Also ich interpretiere das so, dass der solange Zeichen einliest, bis
keines mehr anliegt und diesen "Es liegt nix mehr an Code" zurückgibt,
weil ja die Variable c immer wieder überschrieben wird....
Mach's doch erstmal einfacher in dem du Zeichen für Zeichen ausliesst
und wieder zurücksenden lässt.... Wenn das sicher läuft, kannst du immer
noch das ganze als Zeichenkette versuchen....
Steff G. schrieb:> welches so lange wartet bis ein Zeichen anliegt?
Tut es. Das wird Dir später noch Probleme bereiten (wenn der µC
zusätzlich etwas anderes als Texte senden und empfangen können sollte),
aber für den Moment reicht es.
Hast Du an Deinem Mega-Boards irgendeine Ausgabemöglichkeit außer dem
UART? LCD? LED-Reihe oder so?
Walter Tarpan schrieb:
> Tut es. Das wird Dir später noch Probleme bereiten (wenn der µC> zusätzlich etwas anderes als Texte senden und empfangen können sollte),> aber für den Moment reicht es.
Genau - das will ich für meinen Ansatz erreichen.
In Matlab werden mehrere Werte eingegeben und diese sollen dann an den
µC gesendet werden.
Der µC soll so lange warten bis diese Werte alle angekommen sind und
dann mit dem eigentlichen Programmablauf starten.
> Hast Du an Deinem Mega-Boards irgendeine Ausgabemöglichkeit außer dem> UART? LCD? LED-Reihe oder so?
Du meinst irgendwie eine LED dranbasteln, damit ich sehe, ob der µC
zumindest die Daten empfängt?
Steff G. schrieb:> Du meinst irgendwie eine LED dranbasteln, damit ich sehe, ob der µC> zumindest die Daten empfängt?
Oder noch besser: Die Daten, die er empfängt, direkt anzeigen.
Ich habe dazu an jedem µC-Board ohne Debuggerzugriff zumindest während
der Entwicklungszeit zumindest ein kleines LCD.
> Oder noch besser: Die Daten, die er empfängt, direkt anzeigen.
Da hab ich leider momentan nichts zur Hand.
Ich versuche es dann mal mit der LED - meld mich dann nochmal.
Ich hatte sowas ähnliches letztens in Python. Die Daten scheinen vom
controller ja richtig zurück zu kommen, aber triggern keine neue Zeile
in matlab und daher gibt er dir ein time out, obwohl er eigentlich schon
alles empfangen haben sollte.
Bei uns war komischerweise eine Lösung, den Empfang buffer auf 1 Zeichen
zu setzen, dann hat er was angezeigt.
Wenn ich nun über das Terminalprogramm "123" an das Board schicken geht
die LED an - schicke ich "456" geht die LED aus.
Versuche ich das gleiche mit Matlab - passiert wieder mal garnix.
Im Terminalprogramm wird aber die von Matlab verschickte Zeichenfolge
angezeigt.
???
a) Wie sieht denn die Matlab-Zeile zum Senden aus?
b) Wie sieht das Ergebnis im Terminal aus?
Evtl. sendet Matlab nach jedem einzelnen Zeichen schon einen
String-Terminator.
Walter Tarpan schrieb:
> a) Wie sieht denn die Matlab-Zeile zum Senden aus?
1
clc
2
close all;
3
clear all;
4
5
t=[123];
6
7
% Aktive Ports löschen
8
delete(instrfindall);
9
10
% USB Port initialisieren
11
Mega2560=serial('COM1');
12
13
disp('Kommunikation aufgebaut')
14
15
set(Mega2560,'BaudRate',9600);
16
%set(Mega2560,'Terminator','LF');
17
set(Mega2560,'DataBits',8);
18
set(Mega2560,'Parity','none');
19
set(Mega2560,'StopBits',1);
20
21
% Verbindung zum Mikrocontroller
22
fopen(Mega2560);
23
24
25
fprintf(Mega2560,'%d\n',t);
26
27
fclose(Mega2560);
28
disp('Kommunikation abgebrochen')
Ob ich die Zeile
1
%set(Mega2560,'Terminator','LF');
auskommentiere oder nicht macht im Terminal keinen Unterschied.
Walter Tarpan schrieb:
> b) Wie sieht das Ergebnis im Terminal aus?
hab ich gerade angehängt.
Ich weiss einfach nicht was ich hier falsch mache ...
Ok es ist jetzt nochmal etwas komisches passiert.
Ich hab mit dem Terminal die LED angeschaltet.
Nun habe ich zu Matlab gewechselt und egal ob ich hier "123" oder "456"
versende geht die LED aus.
Dan in meinem C-Code defaultmäßig die LED ausgeschaltet ist würde ich
jetzt drauf schließen, dass sich das Board iwie abschaltet und wieder
anschaltet, sobald ich mit Matlab irgendwas sende.
Aber wieso???
Steff G. schrieb:> auskommentiere oder nicht macht im Terminal keinen Unterschied.
Das ist in Ordnung. Matlab merkt sich die Einstellung des COM-Ports. LF
ist zudem der Default-Wert.
Ich habe mal versucht, Dein Setting nachzubauen. Matlab schickt den
String-Terminal erst als letztes Zeichen. Von Matlab in die Konsole und
zurück geht einwandfrei mit Deinem Quelltext.
Sprich: Die Matlab-Seite funktioniert.
Für eine Ferndiagnose bin ich auch mit meinem Latein am Ende, wenn Du in
HTERM und Matlab das Gleiche sendest, aber unterschiedliche Sachen
interpretiert werden.
Noch ein kleiner Test: Versuch mal, die Zeichenkette mehrmals zu senden.
1
fprintf(Mega2560,'%d\n',t);
2
fprintf(Mega2560,'%d\n',t);
Eventuell ist noch ein Rest im Serial-Puffer, daß das erste
Datentelegramm noch Müll am Anfang enthält.
Ich habe es versucht mehrmals zum versenden, aber es hat sich wieder
nichts geändert.
Vielen Dank für deine bisherigen Mühen.
Ich glaube ich kann meinen Fehler jetzt auf die Folgende frage
eingrenzen:
Warum resetet sich das Mega Board, wenn ich via Matlab etwas an das
Board versende?
Ich hoffe es hat sonst noch jemand eine Idee??
Oder soll ich lieber einen neuen Beitrag dafür aufmachen, weil sich
nicht jeder das ganze bisherige durchlesen wird?
Hm du hast ein Arduino-Board, richtig?
Der Arduino verwendet den DTR-Pin am Usb-Serial chip (nach den
Schematics wird beim Mega Board hierfür ein kleinerer Atmega verwendet,
https://www.arduino.cc/en/uploads/Main/arduino-mega2560_R3-sch.pdf) als
RESET Leitung um den großen Mega in den Bootloader zu bringen.
Vielleicht triggered Matlab den irgendwie im Gegensatz zu HTerm.
Versuche mal in Matlab FlowControl auszuschalten. Sollte möglicherweise
gehen mit:
Anstatt da irgendwo LEDs dranzu basteln, wuerde ich einfach mal gucken
was wirklich ueber die Leitung geht.
Besorg dir einen USB-UART-Wandler (z.B. sowas:
https://shop.in-circuit.de/product_info.php?cPath=38&products_id=80 ),
und klemm den an die Leitung. Dann machst du HTerm auf, und verbindest
dich damit mit dem Wandler. Dann machst du Matlab auf, und startest dein
Programm. Dann sieht du exakt was da ueber die Leitung geht, und ob das
auch das ist, was du erwartest. Dann siehst du auch, ob das Problem am
Matlabcode, oder am C-Code liegt.
Lenny D. schrieb:> Vielleicht triggered Matlab den irgendwie im Gegensatz zu HTerm.
Das kann tatsaechlich sein. Kann passieren, wenn das Programm den
serielle Port schliesst.
Steff G. schrieb:> Du meinst das ganze in Matlab rein und den Arduino ansteuern?
Ja, aber nur kurz. Zum Testen. Das ist ja in 2 Minuten gemacht. Wenn es
funktioniert, sind sowohl die LED als auch die serielle Verbindung
hardwareseitig ausreichend zuverlässig.
Lenny D. schrieb:> Versuche mal in Matlab FlowControl auszuschalten. Sollte möglicherweise> gehen mit:
Die Idee ist gut. Bei mir:
1
>> get(Mega2560,'FlowControl')
2
3
ans =
4
5
none
aber: Die Default-Einstellung ist die aus dem Gerätemanager.
Oje, ich hatte mal das selbe Problem. Probiere mal folgenden
Lösungsvorschlag.
Hinweis: Diese ist aus meiner GUI, als ich Bilddaten eines ADNS-Sensors
über eine USART ausgelesen habe, daher muss diese angepasst werden.
Erstelle eine Funktion:
1
function serialPort = initSerialPort(hObject, eventdata, handles, portName)
Hallo nochmal - vielen Dank für eure weiteren Tipps.
Hab das mit dem float control probiert und war leider auch nix.
Über die Arduino Software auf Matlab hat es funktioniert.
Hab jetzt nochmal weiter recherchiert und bin auf die Lösung gekommen:
Der Fehler:
1
fopen(Mega2560);
2
pause(2);
Anscheinend benötigt Matlab eine Weile den Com-Port einzurichten und
wenn ich in dieser Zeit schon Zeichen rüber schicke, dann erhält es das
Mega-Board nicht.
Jetzt funktioniert es!
Vielen vielen Dank an die Leute, die mir geholfen haben und ihre Zeit
investierten.
Danke für die Rückmeldung. Das wird in Zukunft sicher nur nicht dir
passieren und dann ist es schön wenn man hier eine Lösung über Google
nachlesen kann.