Softwareentwickler MATLAB/Simulink (w/m) Erarbeitung von Lösungen im Bereich der Schnittstelle zum Simulink-Modell und der Benutzeroberfläche von TargetLinkdSPACE GmbH - Paderborn
Verfasst am: 04.02.2012, 21: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..
out = in
%%%%%%% end of embeded matlab function %%%%%%%%%%%
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, 16: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
}
In der mdlTerminate nicht vergessen den Port zu schließen, sonst kann er beim nächsten Mal nicht geöffnet werden:
Code:
% Port schließen
CloseHandle((HANDLE*)ssGetPWorkValue(S, 0));
Options and Permissions
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.