Forum: PC-Programmierung Octave und Serial Port / USB Port unter Windows


von branadic (Gast)


Lesenswert?

Hallo und guten Abend,

wie der Titel schon sagt suche ich nach einer Möglichkeit via Octave 
(QTOctave unter Windows, da es der Matlabumgebung recht ähnlich ist) auf 
die serielle Schnittstelle oder auch auf eine USB-Schnittstelle 
zuzugreifen.
Für Matlab steht da die serial.m zur Verfügung, nicht jedoch in Octave.

Das Internet habe ich schon durchsucht, bin bei einer Lösung bisher 
jedoch nicht fündig geworden. Einziger Hinweis bisher war dieser hier:

https://www-old.cae.wisc.edu/pipermail/help-octave/2009-July/015194.html

jedoch ist dieses ominöse Programm net2com nirgends zu finden. Die 
Projektseiten sind leer gefegt, im Download-Bereich steht nichts mehr 
zur Verfügung.
Hat da jemand eine Idee wie man das angehen kann?

Für Hinweise wäre ich euch sehr dankbar. Vielleicht hat ja jemand eine 
Implementierung für Windows?

branadic

: Verschoben durch Admin
von branadic (Gast)


Lesenswert?

Hallo,

ich hab die letzten Tage weiter das Netz durchforstet, bin aber bisher 
noch immer nicht fündig geworden. Hat niemand eine Idee oder nutzt 
Octave schlichtweg niemand?

brandic

von Ronny (Gast)


Lesenswert?

> Hat niemand eine Idee oder nutzt
> Octave schlichtweg niemand?

Ich benutze Octave eigentlich sogar ziemlich häufig, aber für dein 
spezielles Problem habe ich leider auch noch keine Lösung gefunden. 
Einige Male habe ich genau diese Funktion aber auch schon vermisst. :(

Hast du mal probiert, auf "COMx" per Dateizugriff zu lesen/zu schreiben?

von branadic (Gast)


Lesenswert?

Hallo Ronny,

Ronny schrieb:
> Hast du mal probiert, auf "COMx" per Dateizugriff zu lesen/zu schreiben?

Um genau zu sein wüsst ich nicht mal wie ich das veranstalten sollte. 
Für Linux habe ich folgenden Ansatz gefunden:

f = fopen ("/dev/ttySL0", "r+")
  f =
  {
    id = 3
    name = /dev/ttySL0
    mode = r+b
    arch = ieee_little_endian
    status = open
  }
fcntl (f, F_SETFL, O_NONBLOCK)
ans = 0
fputs (f, "AT\n")
ans = 0
fgetl (f)
ans = AT
fgetl (f)
ans =
fgetl (f)
ans = OK
fgetl (f)
ans = -1
fputs (f, "AT\r")
ans = -1
fclear (f)
fputs (f, "AT\r")
ans = 0
fgetl (f)
ans = AT
fgetl (f)
ans = OK
fgetl (f)
ans = -1
fclose (f)
ans = 0

Quelle: 
http://octave.1599824.n4.nabble.com/fgetl-hangs-reading-serial-port-td1665589.html#a1665590

Ich nutze jedoch Windows, also müsste man den Zugriff auf den COM-Port 
irgendwie anders gestalten. Der direkte Zugriff auf die serielle 
Schnittstelle soll aber nicht so trivial sein wie unter Linux. Da ich 
nicht gerade mit übermäßigen Programmierkenntnissen ausgestattet bin tu 
ich mich da zugegebenermaßen schwer. Hast du eine Idee?

Ich lade mir gerade die letzte Octave Version herunter, das QT-Interface 
habe ich schon. Die graphische Umgebung ist dann doch irgendwie 
gewohnter, wenn man Matlab auf Arbeit nutzen kann.

branadic

von branadic (Gast)


Lesenswert?

So, ich hab jetzt mal den ersten Versuch vorgenommen auf eine meiner 
vorhandenen COM-Schnittstellen zuzugreifen. Dazu habe ich an einen 
meiner USB-Anschlüsse das FT232-Board von Sparkfun.com und an einen 
anderen einen Seriell-USB-Umsetzer von Vivanco gehängt. Der 
Gerätemanager verrät die COM-Port-Bezeichnung.

Nun wähle ich entsprechend der Vorgabe:

[fid, msg] = fopen (name, mode, arch)

mit 'r' zum Lesen und 'native' als arch

und bekomme beim ersten Senden des Befehls:

>>> [FID, MSG] = fopen ("COM5","r")
FID =  3
MSG =

und beim zweiten mal Senden:

>>> [FID, MSG] = fopen ("COM5","r")
FID = -1
MSG = Permission denied

(Octave-Hilfe: If an error occurs, FID is set to -1 and MSG contains the 
corresponding system error message.)

Will ich nun auf den anderen Anschluss zugreifen schreibe ich:

>>> [FID, MSG] = fopen ("COM7","r")
FID =  4
MSG =

>>> FID_LIST = fopen ("all")

liefert nun den Wert:

FID_LIST =

   3   4

Wie ich diesen Rückgabewert interpretieren soll ist mir noch nicht ganz 
klar.

War klar, dass ein einfacher Zugriff nicht möglich ist. Aber was nun?

branadic

von Ernestus P. (malzeit) Benutzerseite


Lesenswert?

Warum öffnest du die serielle Schnittstelle mehrmals? Folglich nach dem 
Senden mit fclose() den Port wieder schließen, beziehungsweise einmal am 
Porgrammanfang öffnen und am Ende schließen.

von branadic (Gast)


Lesenswert?

Hallo Ernestus,

zu dieser Frage ein Auszug aus der Octave-Hilfe zu diesen Build-in 
Functions:

"...Opening a file that is already open simply opens it again and 
returns a separate file id. It is not an error to open a file several 
times, though writing to the same file through several different file 
ids may produce unexpected results..."

Und das wollte ich schlichtweg testen.

branadic

von branadic (Gast)


Lesenswert?

Vielleicht dazu noch meine Quellenangabe, auf die sich meine beiden 
letzten Postings stützen:

http://www.network-theory.co.uk/docs/octave3/octave_137.html

branadic

von Ernestus P. (malzeit) Benutzerseite


Lesenswert?

Dachte auch, dass das mehrmals öffnen kein Problem sein sollte. Aber 
nach deinen vorangegangenen Postings war das ja nicht die Fragestellung. 
Vielleicht hat das mit der Implementierung zu tun und in Windows ist es 
API-mäßig nicht möglich, das ein COM-Port mehrmals geöffnet wird.

Da kenn ich mich jetzt nicht so aus.

von branadic (Gast)


Lesenswert?

Ernestus Pastell schrieb:
> und in Windows ist es
> API-mäßig nicht möglich, das ein COM-Port mehrmals geöffnet wird

Das kann natürlich der Grund sein.

Worauf ich eigentlich hinziele ist eine Möglichkeit der Datenerfassung 
in Octave, doch leider scheint es in der Richtung noch nichts als 
Pendant zur Data Aquisition Toolbox von Matlab zu geben.

Hier:

http://www.mail-archive.com/octave-dev@lists.sourceforge.net/msg04146.html

scheint jemand zumindest eine Implementierung begonnen zu haben und die 
Post sind mit Juni/2010 noch vergleichsweise jung.

Es ist wirklich schade, dass es da noch kein Modul zu geben scheint. 
Matlab oder LabView sind für den privaten Geldbeutel doch eine echte 
Belastung.

branadic

von branadic (Gast)


Lesenswert?

Noch ein Nachtrag.
Während meiner Suche im Netz bin ich auch über das "BioSig for Octave 
and Matlab"-Projekt gestolpert.

Grundsätzlich sehr interessant, doch leider ist auch hier der für mich 
interessante Teil

biosig/t100/*: Data acquisition

noch vollständig leer.

branadic

von branadic (Gast)


Lesenswert?

Hallo mittlerweile gab es Post vom Octave-Projekt:

"...Unfortunately at the moment, the serial com port have not been 
supported octave on windows.
Some volunteer persons need to write serial device functions using the 
win32 api libraries..."

Vielleicht findet sich ja doch noch eine Möglichkeit?!

branadic

von Ernestus P. (malzeit) Benutzerseite


Lesenswert?

Tut octave denn zeichen senden und empfangen? Der Workaround wäre dann 
halt nur einmal öffnen bzw. jedesmal schließen.

von branadic (Gast)


Lesenswert?

Mir ist momentan noch nicht klar, wie ich Zeichen senden muss. Da bin 
ich noch auf der Suche nach Verständnis. Zumindest gab es Antwort vom 
Octave-Forum. Hier die Mailantwort, vielleicht hilft es ja jemand 
anderem weiter:

"Another option involve(s) using the ser2net library.  Octave already 
has a sockets package and the ser2net server allows you to connect over 
a socket and then send and receive over the serial port.  I know that 
this package used to be available on Cygwin (I haven't used cygwin in 
5-6 years so don't know whether it is still available).  I also know of 
one lab that had a very old PC that they put a tiny Linux distribution 
on whose sole purpose was to run ser2net and connect to their device 
over serial.  Then they could control the device from any networked 
machine."

branadic

von Ernestus P. (malzeit) Benutzerseite


Lesenswert?

Neben ser2net gibts noch das com0com-Projekt. 
http://com0com.sourceforge.net/

Aber wenn COMx öffnen möglich ist, dann begutachte doch einfach nochmal 
das obige Beispiel. Meine Vermutung ist nach wie vor, das die 
Windows-API den COM-Port nur einmal öffnen lässt.

Zum Code falls der dir nicht voll klar ist:

fcntl (f, F_SETFL, O_NONBLOCK) // eine Initialisierung; auch mal ohne 
probieren

status = fputs (f, "AT\n") // Zeug senden

aw = fgetl (f) // Zeile empfangen und in aw speichern bzw. bei einem 
Fehler oder Timeout den numerischen Wert -1.

(EOL-Zeichen/Terminator könnte kritisch sein kenn ich mich aber nicht 
aus)


Der hier hatte ja trotzdem probleme:

https://www-old.cae.wisc.edu/pipermail/help-octave/2008-April/008820.html

Wenn du Zugang zu einer Matlab-Installation hast dann schau dir mal an 
was der Rückgabewert von serial() ist. Letztlich muss das ja auch nur 
ein String sein, der an fopen() geht.

s = serial('COM1');
s
fopen(s);

von branadic (Gast)


Lesenswert?

Ich habe mal in Matlab versucht eine Kommunikation mit einem Gerät 
herzustellen.
Dabei handelt es sich um ein Multimeter (ein anderes Gerät hab ich 
gerade nicht da, das mit mir kommunizieren könnte), dem ich in hex 89 
(bin 10001001) schicken muss, um ein Datenpaket mit dem aktuellen 
Messwert zu empfangen.
Dazu verwende ich die Funktion serial.m in Matlab. Ich meine die 
Konfiguration korrekt durchgeführt zu haben, jedoch bekomme ich in 
Matlab keinen Wert zurück. Mit get(s) kann man ja die Port-Einstellungen 
anzeigen lassen und die scheinen zumindest mit denen in Hterm überein zu 
stimmen. Und unter Hterm empfange ich auch den aktuell auf dem Display 
dargestellten Wert.
Anbei noch mein Code. Wenn ich es schon in Matlab nicht hinbekomme, dann 
seh ich schwarz für Octave.

1
>> delete(instrfindall);
2
s = serial('COM3', 'BaudRate', 9600, 'Parity', 'none', 'DataBits', 8,...
3
           'StopBits', 1);
4
get(s)                  %Port-Einstellungen abrufen
5
fopen(s);               %Connect serial port object to device
6
get(s, 'Status')
7
    ByteOrder = littleEndian
8
    BytesAvailable = 0
9
    BytesAvailableFcn = 
10
    BytesAvailableFcnCount = 48
11
    BytesAvailableFcnMode = terminator
12
    BytesToOutput = 0
13
    ErrorFcn = 
14
    InputBufferSize = 512
15
    Name = Serial-COM3
16
    ObjectVisibility = on
17
    OutputBufferSize = 512
18
    OutputEmptyFcn = 
19
    RecordDetail = compact
20
    RecordMode = overwrite
21
    RecordName = record.txt
22
    RecordStatus = off
23
    Status = closed
24
    Tag = 
25
    Timeout = 10
26
    TimerFcn = 
27
    TimerPeriod = 1
28
    TransferStatus = idle
29
    Type = serial
30
    UserData = []
31
    ValuesReceived = 0
32
    ValuesSent = 0
33
34
    SERIAL specific properties:
35
    BaudRate = 9600
36
    BreakInterruptFcn = 
37
    DataBits = 8
38
    DataTerminalReady = on
39
    FlowControl = none
40
    Parity = none
41
    PinStatus = [1x1 struct]
42
    PinStatusFcn = 
43
    Port = COM3
44
    ReadAsyncMode = continuous
45
    RequestToSend = off
46
    StopBits = 1
47
    Terminator = LF
48
49
50
ans =
51
52
open
53
54
>> send = 10001001;     %Write HEX:89 to DMM for receiving data package
55
fwrite(s,  send)        %Write binary data to device
56
s.BytesAvailable
57
58
value = fscanf(s)
59
60
ans =
61
62
     0
63
64
Warning: A timeout occurred before the Terminator was reached. 
65
66
value =
67
68
     ''

Ich gebe aber noch nicht auf. Leider habe ich bisher noch zu wenig 
Code-Beispiele gefunden, in denen jemand sauber mit einem Gerät aus 
Matlab heraus kommuniziert.

branadic

von Justus S. (jussa)


Lesenswert?

branadic schrieb:
> send = 10001001;     %Write HEX:89 to DMM for receiving data package
> fwrite(s,  send)        %Write binary data to device

damit schickst du aber afaik den String "10001001" und nicht den 
ASCII-Wert 0x89...

von Ernestus P. (malzeit) Benutzerseite


Lesenswert?

fscanf arbeitet Zeilenbasiert, braucht also ein EOL-Zeichen bzw. einen 
Terminator ala '\r' oder '\n'. Das muss dein Multimeter dann auch 
senden. Ansonsten müsste es noch Low-Level-Funktionen (bspw. fread()) 
geben.

send = 0x89; fänd ich auch eleganter

von branadic (Gast)


Lesenswert?

Justus Skorps schrieb:
> damit schickst du aber afaik den String "10001001" und nicht den
> ASCII-Wert 0x89...

Gut, aber auch die andere Variante funktioniert nicht:
1
fprintf(s,'%X','89','async')

'%X' steht hier für das Format HEX

Ernestus Pastell schrieb:
> fscanf arbeitet Zeilenbasiert, braucht also ein EOL-Zeichen bzw. einen
> Terminator ala '\r' oder '\n'. Das muss dein Multimeter dann auch
> senden.

Das tut es, wenn ich mit Hterm 0x89 sende, kommt als Antwort:

Ascii: ??????0137[<\n>
bzw. HEX: 89 F8 82 80 80 3F 30 31 33 37 5B 0A

Irgendwo hab ich noch einen Fehler, entweder gedanklicher Seite oder auf 
der Umsetzungsseite.

branadic

von Ernestus P. (malzeit) Benutzerseite


Lesenswert?

Nach den obigen Angaben wartet s.BytesAvailable bis der Terminator LF 
kommt. Also muss es irgendwie an fscanf() liegen, denn erst danach 
scheitert das Script.

Da könnte man jetzt noch das ausprobieren:

line = fgetl(s)
line

Ein bisschen komisch kommt mir dein fscanf() noch vor. Probiers bei 
Erfolg noch mit:

a = fscanf(s, "%s")
a

Oder mal nur s.BytesAvailable damit der Ort des Fehler enger eingekreist 
wird.

von branadic (Gast)


Lesenswert?

So, man ist ein Stück weiter, dem Admin sei Dank. Man nehme zwei 
USB-RS232-Umsetzer, schicke über Hterm -1 den HEX-Wert 89 und schaue an 
HTERM -2 was dort ankommt, nämlich HEX: 89 0A oder ASCII: □ <\n>
Danach versuche man zu verstehen, was Matlab sendet und ändere 
entsprechend den zu sendenden Wert, bis in HTerm -2 das gleiche von 
Matlab empfangen wird.
1
close all; clear all;
2
delete(instrfindall);
3
s = serial('COM3');
4
s.BaudRate = 9600;
5
s.DataBits = 8;
6
s.DataTerminalReady = 'on';
7
s.FlowControl = 'none';
8
s.Parity = 'none';
9
s.ReadAsyncMode = 'continuous'; %continuous/manual
10
s.RequestToSend = 'off';
11
s.StopBits = 1;    
12
s.Terminator = 'LF';
13
get(s)                          %Port-Einstellungen abfragen
14
fopen(s);                       %Connect serial port object to device
15
get(s, 'Status')                %Port-Status abfragen: closed/open
16
fwrite(s,137)                   %Write binary data to device dec:137 = hex:89
17
fwrite(s,10)                    %LF dec:10 = ascii: \n
18
s.BytesAvailable
19
fclose (s)
20
delete(s)
21
clear s

Wenn ich nun jedoch das Multimeter anspreche kommt nichts zurück:

    ByteOrder = littleEndian
    BytesAvailable = 0
    BytesAvailableFcn =
    BytesAvailableFcnCount = 48
    BytesAvailableFcnMode = terminator
    BytesToOutput = 0
    ErrorFcn =
    InputBufferSize = 512
    Name = Serial-COM3
    ObjectVisibility = on
    OutputBufferSize = 512
    OutputEmptyFcn =
    RecordDetail = compact
    RecordMode = overwrite
    RecordName = record.txt
    RecordStatus = off
    Status = closed
    Tag =
    Timeout = 10
    TimerFcn =
    TimerPeriod = 1
    TransferStatus = idle
    Type = serial
    UserData = []
    ValuesReceived = 0
    ValuesSent = 0

    SERIAL specific properties:
    BaudRate = 9600
    BreakInterruptFcn =
    DataBits = 8
    DataTerminalReady = on
    FlowControl = none
    Parity = none
    PinStatus = [1x1 struct]
    PinStatusFcn =
    Port = COM3
    ReadAsyncMode = continuous
    RequestToSend = off
    StopBits = 1
    Terminator = LF


ans =

open


ans =

     0

Verstehe ich s.BytesAvailable richtig, dass mir hier angezeigt wird 
wieviele Bytes als Antwort zurück gekommen sind? Das Format wäre ja 
grundsätzlich erst einmal egal, aber das gar nichts zurück kommen soll 
ist doch seltsam.

entsprechend liefert:

line = fgetl(s)

dann auch die Meldung:

Warning: A timeout occurred before the Terminator was reached.

line =

     ''

branadic

von branadic (Gast)


Lesenswert?


von Ernestus P. (malzeit) Benutzerseite


Lesenswert?

Drahtbrücke zwischen Pin2 und Pin3 am COM-Port, dann kommt alles zu 
Matlab zurück. Dann hast du garantiert Daten.

Der Timeout dauert 10 Sekunden. Braucht fgetl&co auch solange bis ein 
Fehler kommt?

s.BytesAvailable liefert die Zahl der Bytes im Puffer. Laut 
Online-Referenz¹ könnte readasync(g) aber noch erforderlich sein. Jedoch 
dauert es seine Zeit bis Seriell etwas übertragen ist. Besser vor der 
Abfrage noch ne Sekunde warten mit pause()&co.

So wirklich kann ich dir jetzt nicht mehr weiterhelfen, da ich nur 
gelegentlich was mit octave mache.

¹http://www.mathworks.com/help/toolbox/instrument/f14-16706.html#f14-18481

von A. B. (branadic)


Lesenswert?

Hallo Ernestus,

Drahtbrücke könnte ich mal machen, probier ich morgen mal aus. Daheim 
hab ich kein Matlab.

readasync(g) werde ich dann ebenfalls mal probieren.

Ernestus Pastell schrieb:
> So wirklich kann ich dir jetzt nicht mehr weiterhelfen, da ich nur
> gelegentlich was mit octave mache.

Immerhin hast du dafür gesorgt das ich keinen Monolog führe und unter 
Umständen kommen wir ja doch noch zu einer Lösung?

Es ist immer wieder schade, wenn man nicht die richtigen Leute erreicht. 
Octave ist ein wirklich starkes Tool, auch wenn es langsamer als Matlab 
sein soll. Dennoch kann ich mir nicht vorstellen, dass sich viele Matlab 
leisten wollen.
Es könnte daher der Eindruck entstehen, dass es hauptsächlich die Linux 
User sind die Octave verwenden, weiterentwickeln und sich mit 
Signalverarbeitung beschäftigen. Das kann so natürlich nicht der 
Realität entsprechen. Programmieren sich alle Leute alles selbst neu 
obwohl ein Tool wie Octave zur Verfügung steht und man nur eine 
Möglichkeit schaffen müsste die Daten in Octave hinein zu bekommen?
Auch schade, dass eine GUI-Toolbox wie guide nicht unter Octave zur 
Verfügung steht, könnte doch QT grundsätzlich ein vielversprechender 
Ansatz sein.

branadic

von Ernestus on XP (Gast)


Lesenswert?

Linux hat eine sehr gute Console, von der aus kann man mühelos auch 
Texteditor und Grafik(nach)bearbeitung starten. Von der Seite denke ich 
ist der Drang nach einer GUI bei den Entwicklern nicht all zu groß.

Linux ist eben die Heimat von Opensource und passt sich halt nicht immer 
an Windows an.

BTW: Serielle Schnittstelle unter Linux funktioniert bestens. (Baudrate 
verstellen ginge noch irgendwie mit stty)
1
printf("hello octave\n\n");
2
3
4
f = fopen("COM1")
5
6
fcntl (f, F_SETFL, O_NONBLOCK)
7
8
fputs(f, "hello serial port\n")
9
10
11
printf("Press any key to continue");
12
13
pause()
14
15
fgetl(f)
16
17
18
fclose(f)
19
printf("end\n");

von A. B. (branadic)


Lesenswert?

Ernestus on XP schrieb:
> Serielle Schnittstelle unter Linux funktioniert bestens.

Das glaub ich schnell, aber wenn man nun mehrere Jahre mit einem OS 
gearbeitet hat, mag man sich einfach nicht umstellen. Die Software 
sollte sich immer an den User anpassen, nicht umgekehrt. Zugleich 
unterstütze ich aber den OpenSource-Gedanken und nutze soweit 
irgendmöglich OpenSource Softwrae, wenn ich mit Windows auch nicht 
gerade die optimale Plattform habe. Daher muss es unter Octave und 
Windows einfach einen Weg geben ;)
Gerade schaue ich mir die Sourcen von oben genanntem Link an und 
überlege, wie sich das an Windows anpassen lässt.

branadic

von Ernestus P. (malzeit) Benutzerseite


Lesenswert?

Kleine Korrektur. Es heißt:

f = fopen ("/dev/ttyUSB1", "r+"); % read and write

Das andere war schon an Experimente für Windows angepasst.

von branadic (Gast)


Lesenswert?

Guten Morgen,

ich habe jetzt wie empfohlen eine Brücke zwischen Pin 2 und 3 und noch 
einmal meinen Code geprüft. Da ich weiß was ich durch die Brücke 
zwischen Pin 2 und 3 empfangen werde kann ich den fread-Befehl auch 
gleich richtig schreiben:
1
close all; clear all;
2
delete(instrfindall);
3
s = serial('COM3');
4
s.BaudRate = 9600;
5
s.DataBits = 8;
6
s.DataTerminalReady = 'on';
7
s.FlowControl = 'none';
8
s.Parity = 'none';
9
s.ReadAsyncMode = 'continuous'; %continuous/manual
10
s.RequestToSend = 'off';
11
s.StopBits = 1;    
12
s.Terminator = 'LF';
13
get(s)                          %Port-Einstellungen abfragen
14
fopen(s);                       %Connect serial port object to device
15
get(s, 'Status')                %Port-Status abfragen: closed/open
16
fwrite(s,137)                   %Write binary data to device dec:137 = hex:89
17
fwrite(s,10)                    %LF dec:10 = ascii: \n
18
%pause(2)                       %Pause zwischen Senden und Statusabfrage
19
get(s)
20
s.BytesAvailable
21
line = fread(s,[2,1])
22
fclose (s)
23
delete(s)
24
clear s

Zumindest mit dieser Methode kommen die Daten wieder in Matlab rein. Mit 
dem Multimeter klappt das jedoch nicht. Selbst nicht, wenn ich ein 
pause(2) oder mehr zwischen Senden und Statusabfrage einfüge. Woran das 
liegt kann ich nicht sagen. Immerhin schon mal ein kleiner Teilerfolg.

branadic

von A. B. (branadic)


Angehängte Dateien:

Lesenswert?

Hallo,

weiter oben hatte ich ja den nachfolgenden Link schon mal gepostet:

http://libertadhack.blogspot.com/2010/08/puerto-serie-para-octave-serial-port.html?showComment=1285261679189_AIe9_BHPVlFe__ktI4HUn_QBP3ioJ2PqhL_4C16YJcQ1Zd8PjkVXz6m1Cla9OHEjqt6fG_Gui9UHSS6YOYvPPo-zB2tFdUQlvLctCSzqNP5YXfRZHgxulDLeG5ONyBJS0Ftm4nFLheAhGKNbPlC8jV-FGuwCzu8xlO8VadOqHkm8UvNluT1NkCuRzab5XuGt9jOsevKuJd3dtksSBGUOBvGDeMBa5xxvzrHoe45qALbGex07wS4GV500Cz4cvGrEsJyxRFM3y2ZlDMEs6Q9NUpO7BPTFNc52NT1hyuCI7Du0UwJg0mScPfulRHkG-pdLKehKWz-UVRXoErKDEl403cI-cU1-gFfuCg35bPwyOYi3IkYQEWauS1b9SJrHz8odRMRSziQvV4yc6wJRPcVg0RqT1jtVTf7C3gT2J3lJqi2l_s6rHrdxtJHQ9Qr6GjI5WJ5AlwSBrCpNhh6N9gsubL86tf54NafyF0nRLJHxJXcoTfr76oJ72jSI1TsclLJaD5K3YrAp5CPsDDsllHUSpcHWRutW9xHLSkLKNToVCteZZvkXtBXxPvmGYjKp-0EiuqsFUGbIXcVrPvnI__oF3x57cmnBXfm0xCjsmyLSfI910n7VyJSoc7g8OhEB-8OlzDJ1opkQ2ha2LtGjy-Qup_O8GZYrrM6cWdp5NtumInzvMUJEiFzInXk#c1693255940804691753

Ich hatte mit dem Programmierer Kontakt aufgenommen und er hat in der 
Zwischenzeit das Skript geändert und nun läuft es unter Windows.

Die Vorgehensweise ist recht einfach:

1. Octave-3.2.4_i686-pc-mingw32_gcc-4.4.0_setup.exe installieren:
http://sourceforge.net/projects/octave/files/Octave_Windows%20-%20MinGW/Octave%203.2.4%20for%20Windows%20MinGW32%20Installer/Octave-3.2.4_i686-pc-mingw32_gcc-4.4.0_setup.exe/download

1a. Bei Bedarf noch die aktuelle Qt-Oberfläche, ähnlich Matlab, 
downloaden:

http://www.outsch.org/wp-content/uploads/2010/04/qtoctave-win32-0.9.1-3.zip

und in das Octave Installationsverzeichnis entpacken. Dabei werden der 
\bin und \share -Ordner überschrieben. Nun müsst ihr noch den Pfad der 
Verknüpfung ändern, schließlich muss nun die qtoctave.exe gestartet 
werden.

2. Python downloaden und installieren

http://www.python.org/ftp/python/2.7/python-2.7.msi

3. PySerial downloaden und installieren

http://pypi.python.org/packages/any/p/pyserial/pyserial-2.5.win32.exe#md5=ea4579b9ad39a4f0171c3ec3da0a8212

4. Die oben angehängte sockets.tar.gz abspeichern

5. Octave bzw. QtOctave starten und dort in das Verzeichnis wechseln, in 
das ihr die sockets.tar.gz abgespeichert habt

cd "Verzeichnis" z.B. cd C:

6. nun das Socket-Paket installieren

> pkg install sockets.tar.gz

7. octave-serialport-windows.zip abspeichern und im Octave-Verzeichnis 
bei den m-Files entpacken

C:\Programme\Octave\share\octave\3.2.4\m\octave-serialport-windows\

8. Octave neustarten

Nun sollte es euch möglich sein einen Test durchführen zu können.
1
close all;
2
clear all;
3
% In das Verzeichnis wechseln, wo die Datei sport_client.py liegt
4
cd "C:/Programme/Octave/share/octave/3.2.4/m/octave-serialport-windows"
5
s=serial('COM1');
6
data_out='test'; %sendet das Wort test als binäre Zeichenfolge
7
spwrite(s,data_out);
8
bytesAvailable(s)
9
data_in=spread(s,4)
10
spclose(s);

Ich hab es mit einem FT232 erfolgreich ausprobiert. Brücke zwischen Rx 
und Tx rein, dann sollten nach dem Sendevorgang Daten in data_in liegen, 
bzw. bytesAvailable sollte ans = 4 liefern.

Schönen Sonntag, branadic

von Michael L. (micha2010)


Lesenswert?

Hi!

ich bin gerade auch auf Suche nach einer Möglichkeit mittels Octave über 
die COM-Schnittstelle Daten einzulesen. Bin auf euren sehr lobenswerten 
Austausch gestoßen (vielen Dank schonmal nur dafür ;)

Ich bin der "Anleitung" aus dem letzten Post gefolgt. Nur bekomme ich 
beim Punkt 6.
---6. nun das Socket-Paket installieren
---
---> pkg install sockets.tar.gz
die folgende Meldung im Qtoctave Terminal:
1
sockets.cc: In member function 'bool octave_socket::is_data_available()':
2
sockets.cc:136: warning: no return statement in function returning non-void
3
sockets.cc: In function 'octave_value_list Fsend(const octave_value_list&, int)':
4
sockets.cc:524: warning: comparison between signed and unsigned integer expressions
5
sockets.cc: In function 'octave_value_list Faccept(const octave_value_list&, int)':
6
sockets.cc:688: warning: unused variable 'retval'

Ist das i.O., oder läuft da was schief?

Kann ich irgendwie verfolgen, ob der COM-Port geöffnet wurde? Oder ist 
die generelle Funktionsprüfung über die Brücke zw. Tx und Rx die 
"einfachste" Methode?

ML

von Michael L. (micha2010)


Lesenswert?

Okay, hab meinen Fehler gefunden.

Habe aus dem Testcode in der "Anleitung" die "" in der Pfadangabe 
gelöscht:
1
close all;
2
clear all;
3
% In das Verzeichnis wechseln, wo die Datei sport_client.py liegt
4
cd C:/Programme/Octave/share/octave/3.2.4/m/octave-serialport-windows
5
s=serial('COM1');
6
data_out='test'; %sendet das Wort test als binäre Zeichenfolge
7
spwrite(s,data_out);
8
bytesAvailable(s)
9
data_in=spread(s,4)
10
spclose(s);

Werde mal weiter damit "rumprobieren" mal sehen, was dabei raus kommt!

ML

von Ben (Gast)


Lesenswert?

Moin,

ich möchte mit Freemat die serielle Schnittstelle (RS232) ansprechen. 
Unter 
http://markmail.org/message/a4hagyd534t6fxqt#query:serial%20com%20port%20freemat+page:1+mid:a4hagyd534t6fxqt+state:results 
habe ich gefunden, wie das gehen soll. Mein Testcode:
1
system ('MODE COM1: BAUD=115200 PARITY=n DATA=8 STOP=1')
2
f = fopen('COM1','w+b');
3
in = fread(f)
4
fwrite(f, 111);
5
fclose(f)

Wenn ich diesen Code unter Octave einsetze, so funktioniert das Senden 
und Empfangen, wobei das Senden nur beim Schließen (fclose) erfolgt.

Unter Freemat produziert "f = fopen('COM3','w+b')" jedoch den Fehler:
"Error: Die Syntax für den Dateinamen, Verzeichnisnamen oder die 
Datenträgerbezeichnung ist falsch. for fopen argument COM3"

Also ergeben sich für mich zwei Fragen:
-Ich kann mir denken, dass fopen immer nur Daten speichert/sendet, wenn 
"fclose" ausgeführt wird. Ist dies richtig? Bzw. wie kann man dies 
ändern?

-Warum funktioniert der Befehl unter Freemat nicht? Bzw. was muss ich 
abändern?

Gruß
Ben
(Win 7 Pro 64bit, ATmega32, STK 500, AVRISP mkII)

von Ernestus P. (malzeit) Benutzerseite


Lesenswert?

Warum "f = fopen('COM3','w+b')" unter FreeMat einen Fehler porduziert 
weiß ich nicht.

Damit GNU Octave Daten nicht unmittelbar nach fwrite sendet liegt 
wahrscheinlich daran, das die Funktion asynchron arbeitet. Sofern die 
ganze POSIX-"API" vorhanden ist sollte "fflush()" den Puffer unmittelbar 
(synchron) leeren.

von Schaf (Gast)


Lesenswert?

Um direct zu senden und nicht auf fclose zu warten muss noch ein null 
angehängt werden ('fwrite(f, [111 0])') damit der 'string' terminiert 
ist.

von Alexander (Gast)


Lesenswert?

Die Installation des Packages sockets.tar.gz funktioniert bei mir nicht.
Immerhin werden es weniger Fehler, wenn ich das sockets.1.0.8.tar.gz 
verwende aber sockets bleibt nach wie vor uninstalliert.
Habe Python 3.3, PySerial 2.5 und Octave 3.6.1 in GUIoctave 1.7 
verwendet.

Kann das an Versionskonflikten liegen? In Octave.sourceforge.net steht 
überhaupt nichts davon, daß man Python braucht um Packages zu 
installieren.

vor 1.0.8 Fehler:
sockets.cc: In function 'octave_value_list FAF_UNIX(const 
octave_value_list&, int)':
sockets.cc:209:1: error: 'AF_UNIX' was not declared in this scope
usw...

bei 1.0.8
sockets.o: In function `ZN13octave_socket14remove_sock_fdEv':
...\AppData\Local\Temp\oct-14\sockets\src/sockets.cc:332: undefined 
reference to `closesocket@4'

Kann jemand helfen und sagen, ob die Fehler von Octave oder von Python 
herrühren? Danke!

Alex

von Krapao (Gast)


Lesenswert?

Beide Fheler rühren wahrscheinlich von sockets her.

Der erste Fehler sieht nach einem Konfigurationsfehler aus. Wenn die 
Konstante bzw. das Makro AF_UNIX unbekannt ist, fehlt wahrscheinlich die 
Angabe für welche Maschine sockets übersetzt wird.

Der zweite Fehler sieht ebenfalls nach einer falschen 
Maschinendefinition aus. Schaut man in sockets.cc rein, sieht man eine 
Stelle an der closesocket aufgerufen wird.
1
void octave_socket::remove_sock_fd(void)
2
{
3
#ifndef __WIN32__
4
  ::close( sock_fd );
5
#else
6
  ::closesocket( sock_fd );
7
#endif
8
  socket_map.erase( sock_fd );
9
  sock_fd = -1;
10
}

Es handelt sich um den Fall wenn _WIN32_ definiert ist, d.h. dieses 
File wird für eine Windows-Maschine übersetzt. Die Funktion closesocket 
kommt dann über Winsock (#1) von Windows rein, vorausgesetzt die 
Toolchain linkt Winsock dazu. Check mal ab, ob du für WIN32 übersetzen 
willst und wenn nicht schau nach wer oder was dir _WIN32_ definiert.

Es wäre schlauer gewesen, wenn du einen eigenen Thread gestartet 
hättest, statt dich hier anzuhängen.

#1: 
http://msdn.microsoft.com/en-us/library/windows/desktop/ms737582%28v=vs.85%29.aspx

von Alexander (Gast)


Lesenswert?

Also danke für die Mühe!
Jetzt gehts wenn ich Octave 3.4.3 verwende. Selbst mit dem alten Python 
2.7 gings unter Octave 3.6.1 nicht. sport_client.py muss halt noch ins 
Verzeichnis des m-Files. Der USB-Serial Adapter blinkt zumindest schon 
mal.

Octave macht hin und wieder mit neuen Versionen Zicken, GUI Octave 
ebenso.

Ich schreibe lieber hier, dann finden die 'Abo'-Leute, also die sich 
damit eher auskennen, gleich die Frage.

von branadic (Gast)


Lesenswert?

Warum ist der Thread eigentlich verschoben worden? Octave gehört doch 
eher in den DSP-Bereich.

Stimmt, im aktuellen Octave bekomme ich das auch alles nicht mehr zum 
Laufen. Das ist wieder ein echter Rückschritt.
Schön wäre, wenn das mal richtig in Octave implementiert würde (für alle 
Betriebssysteme) und man nicht über Krücken Zugriff auf so etwas simples 
wie die COM-Schnittstelle realisieren müsste. So macht das keinen Spaß.

branadic

von ING-O (Gast)


Lesenswert?

Ich kenne ocatave nicht, aber kann man das nicht in ein Terminal 
schreiben?

Mit einer Art stdout gelangt man doch mit anderen Programmen auch immer 
auf eine Console, die man dann auf einen Port umleiten kann.

Oder man tut sich zusammen und setzt den octace Proggern das Ding auf 
die todo-List :-)

von branadic (Gast)


Lesenswert?

ING-O schrieb:
> Oder man tut sich zusammen und setzt den octace Proggern das Ding auf
> die todo-List :-)

Druck ausüben dürfte hier nicht viel bringen, da die Programmierer in 
aller Regel zugleich Linux-User sind. Zudem führt massiver Druck 
bekanntermaßen eher zu Resignation. Leider fehlen mir die Fertigkeiten 
mich der Sache selbst anzunehmen.

branadic

von Chris (Gast)


Lesenswert?

Hi!
Vielen Dank für die Lösung! Ich glaube, dass ist noch imme die einzige 
Lösung für SerialPorts mit Octave unter Windows.

Ich habe trotzdem noch eine (Laien-)Frage...: Wie sende ich Hex-Code? 
spwrite sheint das ganze ja grundsätzlich in binär umzuwandeln?
Möglicherweise ist dsa eine blöde Frage, aber ich bin recht neu in der 
Com-Port-Kommunikation und bin überglücklich, dass ich endlich mit dem 
Brücken von Rx und Tx sehen konnte, dass etwas passiert - bloß mein 
Geröt versteht nichts ;)
Ich würde mich daher sehr freuen, wenn mir jemand erklärt, wie ich mit 
dem Code z.B. "AA 0E 0D 00 00 00" als Hex Code senden kann.
Besten Dank!
Chris

von branadic (Gast)


Lesenswert?

Hat jemand schon einmal die Toolbox zum Laufen bekommen?

http://wiki.octave.org/Instrument_control_package

Ich war mit QTOctave Protable leider bisher noch nicht erfolgreich, 
wollte aber dennoch mal darauf aufmerksam machen.

von Chris (Gast)


Lesenswert?

Naja... da steht ja auch recht deutlich, dass das unter Windows nicht 
läuft. Sehr schade... Hab grade gesehen, dass 97% der Nutzer Octave 
unter Windows laufen haben. Trotzdem geht gerade da der SerialPort 
nicht.
Ich hoffe, da kommt demnächst was. 3.8.0 hat in dieser Richtung keine 
Besserung gebracht.

von J. K. (jo_ku)


Lesenswert?

Guten Tag!

Ich habe hier ein Problem, das genau zu diesem Thread passt und hoffe 
auf eure Erfahrungen und Hilfe dabei.

Ich habe mich dagegen entschieden einen neuen Thread aufzumachen und 
statt dessen diesen hier wiederzubeleben. Hoffe das ist OK.

============

*Ziel:* Sensordaten vom µC mit Octave unter Windows empfangen.
*Problem:* Zugriff auf die serielle Schnittstelle mit Octave unter 
Windows

Beschreibung des Aufbaus:
- STM32F4-Discovery Eval-Board
- Virtueller COM-PORT über USB-CDC
  mit diesem Beispiel: 
http://mikrocontroller.bplaced.net/wordpress/?page_id=1263
  und diesem Treiber: http://www.st.com/web/en/catalog/tools/PF257938
- Octave 3.8.1 unter Windows 7

Was ich bisher probiert und geschafft habe:
1.
"Serial Port for Octave" wie in diesem Thread beschrieben habe ich nicht 
zum laufen gebracht: Beitrag "Re: Octave und Serial Port / USB Port unter Windows"
Ich habe hier mit Kompilierungsproblemen am Firmenrechner zu kämpfen. 
Ich habe es nicht weiter verfolgt, da ich mit einem anderen Ansatz 
weiter gekommen bin:

2.
Zugriff auf den COM-Port über die Ovtave-Dateizugriffsfunktionen. Das 
sieht dann etwa so aus:
1
% Schnittstelle öffnen
2
f = fopen("COM6", "r+");
3
4
% Direkt am Anfang gibt feof 0 aus.
5
y = feof(f);
6
7
% Bytes lesen, maximal read_size Stück. x wird ein uint8-Array.
8
x = fread(f, read_size, "*uint8");
9
10
% Nach dem Schreiben ist ein frewind notwendig
11
frewind(f);
12
13
% Schreiben: z.B Byte "0000001" binär. Arrays/Strings ebenso möglich.
14
fwrite(f, 1);
15
16
% Jetzt lesen bis EOF
17
while (!feof(f))
18
  fread(f, read_size, "*uint8");
19
endwhile
20
21
% Damit sofort geschrieben wird ist ein fflush notwendig
22
fflush(f);
23
24
% Schnittstelle schließen
25
fclose(f);

Damit habe ich eine schnelle, bytebasierte Kommunikation (fast) wie 
gewünscht realisiert. Nur fast deshalb:
a)
Zustand und Einstellungen der Schnittstelle nicht zugreifbar (Bei der 
virtuellen COM-Schnittstelle aber auch eigentlich nicht benötigt).

b)
Das große Problem hier ist jedoch folgendes: Ich muss die 
Schnittstelle einmalig mit einem anderen Programm öffnen, ansonsten 
bleibt Octave immer im ersten fread hängen. Auch mit einem frewind 
und/oder fflush nach dem Öffnen der Schnittstelle konnte ich nichts 
erreichen. Ich hatte echt viel probiert und kam lange nicht darauf, 
warum es mal klappt und mal nicht.....
Lösung: In meinem Fall genügt ein kurzer Klick auf Connect/Disconnect in 
HTerm (das ich sonst zum debuggen der Kommunikation benutze). Ab dann 
läuft auch der Zugriff in Octave.

Ich habe versucht etwas Vergleichbares auf der Kommandozeile 
nachzubilden, um dann diesen Befehl direkt im Octave-Skript auszuführen 
(kein klicken mehr). Ich habe also versucht mit dem Befehl mode etwas 
zu erreichen, aber es führte zu dem gleichen Verhalten, Hängenbleiben in 
fread. (für mode siehe 
http://batchloaf.wordpress.com/2013/02/12/simple-trick-for-sending-characters-to-a-serial-port-in-windows/)


Also, es läuft aber es fehlt noch was um es perfekt nennen zu können.

Jetzt meine Schlussfragen:
Hat das jemand schon mal so realisiert?
Insbesondere interessiert mich, ob es auch zu dem seltsamen Verhalten 
kommt, dass die Schnittstelle zunächst nicht ansprechbar ist.
Der Fehler könnte in der Implementierung des virtuellen COM-Ports auf 
µC- oder Treiberseite liegen. Vielleicht ist irgendein Puffer am Anfang 
noch nicht so weit...so viel zu meiner Einschätzung.

Ich denke die Kette Sensor-STM32F4DISCOVERY-USB-Octave ist eine 
interessante Sache mit dicker Performance zum Datenschaufeln...
Unter Windows wohl problematisch. Wie macht ihr das sonst?

Ich würde mich freuen, wenn jemand Ideen hat und sich da durchbeißen 
mag. Alleine das Nachvollziehen der beschriebenen Probleme wäre schonmal 
super.

Viele Grüße,

Jonas

von Chris (Gast)


Lesenswert?

Schön, dass der Thread wiederbelebt wird... Das Thema ist ja immer noch 
aktuell, bis Octave da was von Haus aus mitliefert.
Bei mitr läufts zum Glück über diesen umständlichen Weg über Python...
Ich kann Dir nicht konkret helfen - trotzdem vieleicht ein Kommentar / 
Denkanstoß:
Würde Dir ein Timeout helfen, nicht hängen zu bleiben? Ich weiß jetzt 
nicht wie man das realisiert, aber vermutlich bleibt das erste fread 
aktiv, weil nocht nicht "read_size" viele Zeichen angekommen sind?

von J. K. (jo_ku)


Lesenswert?

Danke für den Denkanstoß, Chris. Bringt mich leider nicht weiter. Hier 
ist es so, dass bis zu read_size Werte gelesen werden. Ich hatte dort 
mal 1000 stehen, jetzt einfach Inf.

Dazu die Dokumentation von fread: 
https://www.gnu.org/software/octave/doc/interpreter/Binary-I_002fO.html

So weit ich das sehe wird immer gelesen, bis der Puffer leer ist. Im 
nächsten Lesezyklus kommen die neuen Werte rein.

(Abbruchkriterium ist bei mir eine bestimmte Anzahl an Werten. Dann 
setze ich bestimmte Bytes zusammen, mache Umrechnungen, forme ich mir 
meine Matrix zurecht und plotte meine Sensordaten.)

Ich versuche nochmal eine genauere Beschreibung des Verhaltens:
Schnittstelle (bei mir COM6) nicht einmalig mit HTerm geöffnet:
feof(f) gibt 0 zurück
fread bleibt hängen, kehrt nicht mehr zurück

Schnittstelle einmalig mit HTerm geöffnet:
feof(f) gibt 0 zurück
fread gibt leeres oder gefülltes Array zurück, je nachdem ob etwas 
empfangen wurde.

@Chris: Kannst du vielleicht doch mal einen Versuch starten und deine 
COM-Schnittstelle über die Octave-IO-Funktionen ansprechen?

von Chris (Gast)


Lesenswert?

Bei  mir (Win7) klappt das auch nicht. Bleibt auch im ersten fread 
hängen...
Ich kenne mich mit diesen file-Funktionen aber auch wirklich nicht gut 
aus.

von J. K. (jo_ku)


Lesenswert?

Danke fürs Testen!

Was passiert, wenn du den Port vorher einmal kurz mit HTerm öffnest und 
wieder schließt? Und dann so vorgehst wie ich es 4 Beiträge weiter oben 
beschrieben habe? Bei mir klappts dann mit dem fread.

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.