Verfasst am: 04.02.2012, 20:13
Titel: Serielle Schnittstelle über S-Fucntion auslesen
Guten Abend zunächst mal,
also zunächst der Hintergrund meines Problems:
Ich habe einen Roboter und will seine Liniendaten via Bluetooth verschicken/verarbeiten.
Die Kommunikation läuft über einen COM-Port sollte also relativ leicht sein.
Ich habe zum verbinden, senden, empfangen je ein kurzes script geschrieben welches in Matlab auch wunderbar funktioniert.
Jedoch will ich, um das ganze später regeln zu können, die Daten in Simulink via s-function einlesen und da zunächst mal plotten lassen.. das klappt nur gar nicht da meine scripts anscheinend nicht dafür geeignet sind und ich finde keine vernünftige anleitung wie ich einen user-defined-block so anlegen kann.
Den Block Serial Receive kann ich nicht verwenden, da dort der relevante Com-Port nicht gefunden wird.
Was ich mittlerweile ergooglet hab ist ein Code für eine S-Function der die Verbindung intialisiert.. das empfangen von daten klappt immer noch nicht..
Dazu sei noch gesagt, dass ich das ganze noch nie gemacht habe und mit der Aufgabe ziemlich ins kalte wasser geworfen wurde.. Hoffe also mir kann jemand in irgend einer Form weiterhelfen.
Beste Grüße und schonmal Danke im vorraus
emuuu
Gastredner
Gast
Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
Verfasst am: 05.02.2012, 15:19
Titel: RS232 mit Win API
Also ich stand vor Kurzem genau vor demselben Problem: RS232 über eine S-Function. Ich hab das mit Hilfe der Win API gelöst, d.h. über eine Microsoft Bibliothek. Diese bietet einen großen Funktionsumfang, unter anderem auch die Nutzung der COM-Ports. Ich bin nicht ganz sicher, aber Voraussetzung für die Nutzung der Win API ich die Installation von VC Express (kostenlos bei MS). Die notwendigen Code-Zeilen sind dann relativ übersichtlich.
Am Code-Anfang einfügen:
Code:
% Win API verfügbar machen
#include "windows.h"
#include "Strsafe.h"
In der Mdlstart-Funktion erfolgt das Öffnen des COM-Ports:
Code:
% COM-Port öffnen char pcCommPort[10]; // nimmt Name des Ports auf (z.B. 'COM1:')
HANDLE hCom; // handle um den COM-Port anzusprechen
DCB dcb; // 2 x Datenstruktur um die COM-Port-Parameter zu setzen
COMMTIMEOUTS uCtm;
BOOL fSuccess;
uint8_T comport=1; // Nummer des Ports
//aus der Port-Nummer den Namen zusammenstellen
StringCbPrintfA((STRSAFE_LPSTR)&pcCommPort, sizeof(pcCommPort),"COM%d:",comport);
//Port öffnen
hCom = CreateFileA( pcCommPort,
GENERIC_READ | GENERIC_WRITE,
0, // must be opened with exclusive-access
NULL, // default security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0, // not overlapped I/O
NULL); // hTemplate must be NULLfor comm devices
if(hCom == INVALID_HANDLE_VALUE){
ssSetErrorStatus(S,"Der COM-Port konnte nicht geöffnet werden!! Abbruch!");
return;
}
//jetzt müssen die COM-Einstellungen(dcb) und Lese-/Schreib-Timeouts(uCtm) eingestellt werden
// initialisieren der dcb-Struktur und der Timeout-Struktur durch Auslesen der aktuellen Konfig.
SecureZeroMemory(&dcb, sizeof(DCB));
dcb.DCBlength = sizeof(DCB);
fSuccess = GetCommState(hCom, &dcb) & GetCommTimeouts(hCom, &uCtm);
if(!fSuccess){
CloseHandle(hCom);
ssSetErrorStatus(S,"Fehler bei der Konfiguration des COM-Ports! Abbruch!");
return;
}
// neue COM-Einstellungen setzen
dcb.BaudRate = (uint16_T)75600; // baud rate
dcb.ByteSize = 8; // data size, xmit and rcv
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
//Timeout-Einstellungen anpassen: Leseoperation sofort beenden, wenn keine Daten im Puffer sind(nicht auf Daten warten!)
uCtm.ReadIntervalTimeout = MAXDWORD;
uCtm.ReadTotalTimeoutMultiplier = 0;
uCtm.ReadTotalTimeoutConstant = 0;
uCtm.WriteTotalTimeoutMultiplier = 0;
uCtm.WriteTotalTimeoutConstant = 0;
//beide Einstellungen nun auf den COM-Port anwenden
if(!SetCommState(hCom, &dcb) | !SetCommTimeouts(hCom, &uCtm)){
CloseHandle(hCom);
ssSetErrorStatus(S,"Fehler bei der Konfiguration des COM-Ports! Abbruch!");
return;
}
// den handle des COM-Ports im PWorkVector ablegen
// (diese muss dafür natürlich mind. die Länge 1 haben!)
ssSetPWorkValue(S, 0, &hCom);
In der mdlOutputs-Funktion kann nun wahlweise lesend oder schreibend auf den Port zugegriffen werden:
Code:
% Lesen/Schreiben
//handle aus dem PWorkVector ermitteln
HANDLE hCom = (HANDLE*)ssGetPWorkValue(S, 0);
uint32_T read_cnt; // Anzahl gelesener Bytes für die ReadFile-Funktion
uint32_T write_cnt; // Anzahl zu sendender Bytes für die WriteFile-Funktion
BOOL erfolg;
char getbuffer[255];
char putbuffer[255];
//lesen über ReadFile
if(ReadFile(hCom, getbuffer, sizeof(getbuffer), &read_cnt, NULL)){
//Daten auswerten, read_cnt enthält die Anzahl gelesener Bytes
}else{
//keine Daten empfangen
//z.B. Fehlermeldung oder nix machen
}
//schreiben über WriteFile
//putbuffer enthält die zu sendenden Daten & write_cnt die Anzahl an Bytes
if(!WriteFile(hCom, putbuffer, write_cnt, &read_cnt, NULL);
//Fehlermeldung, weil die Daten nicht verschickt werden konnten
}
hallo alle zusammen.
irgendwie funktioniert die geschichte nicht bei mir.
habe mir das modell aufgebaut mit einem constant-eingang, der s-function und einem display.
habe den code in der mdlStart nun etwas verändert. so müsste nun auch die parameterübergabe in der s-function mit der entsprechenden comport-nummer funktionieren.
ich habe das gefühl, dass die öffnung des comports nicht klappt. ich glaube, dass pcCommPort in der der mdlStart ein Problem bei der CreateFileA-geschichte hat. Denn ich kann mir da noch nicht mal den ssSetErrorStatus ausgeben lassen. was muss denn im pcCommPort stehen, wenn ich mit dem COM4 arbeiten mag?
was muss ich denn noch verändern, sodass ich gesendete signale auf dem display sehe?
und nebenbei habe ich noch eine frage zur anwendung in rtwt. sobald ich das modell mit der s-function in den external modus versetze klick ich auf "build model". dann bekomme ich im command window aber die folgende meldung:
Code:
fatal error: 'windows.h' file not found #include "windows.h"
jemand ne ahnung warum sie kommt? wo sollte die windows.h denn sein? ich dachte er greift automatisch darauf zu. ich weiß nicht ob es zudem noch eine rolle spielt, aber ich nutze windows7 x64.
wäre super, wenn mir jemand weiter helfen könnte. ich stochere zurzeit etwas planlos im code rum.
______________________________________________________________
hier noch der code zum include, zu mdlStart, mdlOutputs und mdlTerminate:
Du kannst Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen. Du kannst Dateien in diesem Forum posten Du kannst Dateien in diesem Forum herunterladen
MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.