WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Serielle Schnittstelle über S-Fucntion auslesen

 

emuuuu

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 04.02.2012, 20:13     Titel: Serielle Schnittstelle über S-Fucntion auslesen
  Antworten mit Zitat      
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..

Mein Code mit dem ich in Matlab empfangen kann:
Code:

if(obj1.BytesAvailable>0)
            receivedData = fread(obj1,obj1.BytesAvailable);
fprintf('%c', receivedData);
 


Code mit dem ich in Simulink eine Verbindung herstellen kann:
Code:

%%%%%%%%%% Embeded matlab function %%%%%%%%
function out = fcn(in)
eml.extrinsic('serial','pause', 'fopen', 'set', 'fprintf');
persistent s

pause(5);

if isempty(s)
    s = serial('COM4')
    set(s, 'BaudRate', 9600)
    fopen(s);
end

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: ---
     Beitrag Verfasst am: 05.02.2012, 15:19     Titel: RS232 mit Win API
  Antworten mit Zitat      
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 NULL for 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));
 
klatsche84
Forum-Newbie

Forum-Newbie


Beiträge: 1
Anmeldedatum: 15.07.13
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 18.07.2013, 14:49     Titel:
  Antworten mit Zitat      
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:

include:
Code:

#include "simstruc.h"
#include "windows.h"
#include "strsafe.h"
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
 



mdlStart:
Code:

static void mdlStart(SimStruct *S)
{
    HANDLE hCom;
    DCB dcb;
    COMMTIMEOUTS uCtm;    
    char pcCommPort[10];
    //char pcCommPort[10]="COM4";
    uint8_T comport = mxGetScalar(ssGetSFcnParam(S, 0));
   
    StringCbPrintfA((STRSAFE_LPSTR)&pcCommPort, sizeof(pcCommPort), "COM%d:", comport);
    //---------------------------------------------------------------
    hCom = CreateFileA (pcCommPort,
               GENERIC_READ | GENERIC_WRITE,
               0,
               NULL,
               OPEN_EXISTING,
               0,
               NULL);
                 
    if (hCom == INVALID_HANDLE_VALUE)
    {
   ssSetErrorStatus(S,"COM-Port konnte nicht geoeffnet werden!");
        return;
    }
    //---------------------------------------------------------------
    SecureZeroMemory(&dcb, sizeof(dcb));
    memset(&dcb, 0, sizeof(dcb));
    dcb.DCBlength = sizeof(dcb);
    dcb.BaudRate = (uint16_T)9600;
    dcb.ByteSize = 8;
    dcb.Parity = NOPARITY;
    dcb.StopBits = ONESTOPBIT;
    //dcb.fDtrControl = 0X01; //ENABLE
    //dcb.fRtsControl = 0x01; //ENABLE
    //---------------------------------------------------------------  
    uCtm.ReadIntervalTimeout = MAXDWORD;
    uCtm.ReadTotalTimeoutMultiplier = 0;
    uCtm.ReadTotalTimeoutConstant = 0;
    uCtm.WriteTotalTimeoutMultiplier = 0;
    uCtm.WriteTotalTimeoutConstant = 0;
    //---------------------------------------------------------------
    if ((!SetCommState(hCom, &dcb)) | (!SetCommTimeouts(hCom, &uCtm)))
    {
        CloseHandle(hCom);
        ssSetErrorStatus(S,"Konfigurationsfehler des COM-Ports!");
        return;
    }
    //---------------------------------------------------------------
    ssSetErrorStatus(S,"Konfigurationsfehler des COM-Ports!");
    ssSetPWorkValue(S, 0, &hCom);
}
 



mdlOutputs:
Code:

static void mdlOutputs(SimStruct *S, int_T tid)
{
    const real_T   *u0 = (const real_T*)ssGetInputPortSignal(S, 0);
    real_T           *y0 = (real_T *)ssGetOutputPortRealSignal(S, 0);

    uint32_T read_cnt;
    uint32_T write_cnt;
    char getbuffer[255] = {0};
    char putbuffer[255] = {0};
   
    HANDLE hCom = (HANDLE*)ssGetPWorkValue(S, 0);

    //++++++++++++++++++++++++++++++++++++++++++++++
    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
    }    
     //++++++++++++++++++++++++++++++++++++++++++++++
    if (!WriteFile(hCom, putbuffer, write_cnt, &read_cnt, NULL));
    {
        // Fehlermeldung, weil die Daten nicht verschickt werden konnten
    }
    //++++++++++++++++++++++++++++++++++++++++++++++
}
 



mdlTerminate:
Code:

static void mdlTerminate(SimStruct *S)
{
    CloseHandle((HANDLE*)ssGetPWorkValue(S, 0));
}
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

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
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

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.