ruby-serialport unter Ubuntu

#2322814
Lesenswert?

Ich möchte unter Ubuntu Daten mit ruby über /dev/ttyUSB0 austauschen.

Nach viel Gemurkse und einer Quelltext-Änderung in serialport.c habe ich 
es endlich geschafft, mit Serialport.new den Port zu öffnen.

Nun ist schon die nächste Klippe aufgetaucht:
1
require "serialport.so"
2

3
sp = SerialPort.new(0, 115200)          # Öffnet /dev/ttyUSB0
4

5
sp.putc('#')

Schmiert bei sp.putc mit "Uncaught exception: not opened for writing" 
ab.

/dev/ttyUSB0 hat rw-Permissions für alle und kann mit GTK-Term ohne 
Probleme geschrieben und gelesen werden.

Hat jemand eine Idee, was da faul ist?
#2322968
Lesenswert?

Laut Beschreibung kann der erste Parameter eine Device-Nummer (0 für 
/dev/ttyS0, oder COM1:) sein oder ein String, wie z.B. "/dev/ttyUSB0" 
sein. Der Code unterscheidet intern an dieser Stelle auch zwischen einem 
Int-Wert und einem String. Nur funktioniert das mit dem String aus mir 
im Moment undurchsichtigen Gründen nicht - er will dort keinen String 
sehen.

Umschifft habe ich das, indem ich im Posix-Implementierungsmodul die 
Devicenamen von /dev/ttyS* nach /dev/ttyUSB* geändert habe. Damit 
funktioniert wenigstens das Serialport.new(0, 115200).

So viel zur Vorgeschichte. Jetzt darfst du dich zum eigentlichen Problem 
äußern ;-)

Gleich noch eine Randfrage:
Gibts für gcc irgendwas, womit man einen Debugger-Breakpoint fest 
eincodieren kann? Unter der verfluchten Windows 9x-Linie konnte man das 
sehr bequem mit asm int 3 machen - zumindest mit den 
Nicht-GNU-Compilern.
#2323020
Lesenswert?

So siehts aus, wenn man versucht den SerialPort mit String im irb zu 
öffnen:
1
$ irb
2
irb(main):001:0> require 'rubygems'
3
=> true
4
irb(main):002:0> require 'serialport.so'
5
=> true
6
irb(main):003:0> sp=SerialPort.new("/dev/ttyUSB0", 9600)
7
TypeError: can't convert String into Integer
8
  from (irb):3:in `initialize'
9
  from (irb):3:in `new'
10
  from (irb):3
11
irb(main):004:0>
#2323364
Lesenswert?

So etwas herauszufinden geht mit strace einfacher und zuverlässiger als 
mit dem gdb.
Z.B. Debian:
apt-get install strace
strace irgendein Kommando....


Abgesehen davon, daß es nicht create heißt, sondern creat, und 
vielleicht auch das nicht aufgerufen wird, sondern open (aus OS-Sicht 
bzw. in der C-Lib; von ruby rede ich nicht mangels jeglichen Wissens).
#2323412
Lesenswert?

Klaus Wachtler schrieb:
> Abgesehen davon, daß es nicht create heißt, sondern creat, und
> vielleicht auch das nicht aufgerufen wird, sondern open (aus OS-Sicht
> bzw. in der C-Lib; von ruby rede ich nicht mangels jeglichen Wissens).

Der Quelltext gibt das nicht her. Dort heißt die betreffende Routine 
sp_create, ein Berakpoint darauf triggert nicht und ein Kommentar 
darüber sagt:
1
/*
2
 * :nodoc: This method is private and will be called by SerialPort#new or SerialPort#open.
3
 */

Die Modul-Initialisierung Init_serialport kann ich per GDB fangen. Ich 
werde mal versuchen, nach der Initialisierung weiter zu debuggen...

strace ergibt zwar 1,3 MB Daten, aber auch keine andere Erkenntnis. 
/dev/tty* kommt darin nicht vor.
#2325234
Lesenswert?

geht es dir um eine Lösung in ruby oder suchst du
eine pragmatische Lösung für ein Problem?

ich habe auf die schnelle immer Python genommen
http://pyserial.sourceforge.net/pyserial_api.html

ist schon etwas her, aber ich meine das die Lösung
sogar zwischen win <-> lin portabel war.

btw, wenn ich mir gerade code Stücke anschaue, die
google ausspuckt, scheinen alle Möglichkeiten
im Konstruktor zu gehen
http://www.python-forum.org/pythonforum/viewtopic.php?f=3&t=27500

http://stackoverflow.com/questions/1093598/pyserial-how-to-read-last-line-sent-from-serial-device

http://stackoverflow.com/questions/676172/full-examples-of-using-pyserial-package

.. eine saubere ruby Lösung würde mich übrigens auch interessieren
Hoffentlich bekommt die ruby community eine reiche und durchdacht
strukturierte Bib auf die Beine.
#2326012
Lesenswert?

Ich bin der Ursache des Problems ein Stückchen näher gekommen: 
SerialPort.new ruft nicht SerialPort#create, (die ist in ruby definiert) 
sondern gleich IO#create.

Letztere akzeptiert nur eine File-Nummer als ersten Parameter.

Im Moment weiß ich leider noch nicht, wie das passieren kann. Er scheint 
aus irgend welchen komischen Gründen serialport.rb zu ignorieren.

Vorher muß ich aber erst mal mein Ruby-System wieder flott kriegen. Ich 
hatte mir den Quellbaum von Github geholt, 1.8.7 ausgecheckt und 
installiert, nachdem ich das Ruby von Ubuntu im Paketmanager 
deinstalliert hatte.

Seither scheitert Ruby schon an require 'rubygems' und require 'tk'. 
Weiß der Henker, was da verbogen ist.
#2332623
Lesenswert?

So, ich habs unter Ubuntu zum Laufen bekommen, und zwar so:

- SerialPort gemaket, wie es in der README beschrieben ist
- require '<vollständiger pfad zu serialport.so (das so kann man
  weglassen)
- Die Definition von class SerialPort aus lib/serialport.rb in meinen
  Quelltext kopieren.

Es ist mir bisher noch nicht gelungen, Ruby dazu zu bewegen, den 
.rb-Text automatisch per require, oder include in mein Programm 
hinein zu bekommen.

Irgend was muß da an der Extension faul sein. Ich habe noch nicht 
versucht, das Teil unter Windows zu installieren - vielleicht gehts ja 
dort...
Gast #2332628
Lesenswert?

Hallo,

ich setze ruby-serialport schon eine Zeitlang unter Debian und Ubuntu 
ein
und hatte bisher keine großen Probleme.

Anbei ein Schnipsel von der Initialisierung der "seriellen" 
Schnittstelle.

===== SCHNIPP =====
require 'serialport'
require 'thread'
require 'io/nonblock'

@device = "/dev/ttyUSB0"
@baudrate = 9600

@port = SerialPort.new( @device, @baudrate, 8, 1, SerialPort::NONE)

@port.nonblock = true
@port.sync = true

@port.flow_control = SerialPort::SOFT
===== SCHNAPP =====

Einzig der Wechsel von Ruby1.8 auf Ruby1.9 war nicht ganz 
unproblematisch, dort hat sich die Schnittstelle ein wenig geändert.


Gruss

    Micha
Gast #2332660
Lesenswert?

Hallo,

> Wo und wie hast du das Teil gezogen?
>
> Das was ich mir von github heruntergeladen habe, scheint im Quelltext
> schon für 1.9 modifiziert zu sein. Ich benutze es aber mit 1.8.7
für Ruby 1.8 habe ich einfach das angebotene Paket direkt von 
Debian/Ubuntu installiert. Für Ruby 1.9 habe ich das Paket aus den 
Debian/Ubuntu-Quellen selbst erstellt. Beide Pakete basieren noch auf 
der Version 0.7.0 von ruby-serialport.

Bei Ruby 1.8.7 sollte eigentlich das von Debian/Ubuntu angebotene Paket 
tun.


Gruss

    Micha
#2332663
Lesenswert?

Das, was ich hier habe, hat die Version 1.0.4

Nachtrag:
Na super, bei Ubuntu heißt das Paket libserialport-ruby. Ich hab immer 
brav nach ruby-serialport gesucht...

Danke für den Hinweis.

2. Nachtrag:
Mit libserialport-ruby bekomme ich wieder den alten Fehler, daß er als 
ersten Parameter keinen String akzeptieren will - warum er die 
class-Definition nicht findet, wenn ich sie nicht im eigenen Quelltext 
habe, bleibt rätselhaft.
#2334638
Lesenswert?

Mittlerweile habe ich serialport.rb in das Verzeichnis kopiert, in dem 
nach der Installation des Ubuntu-Paketes serialport.so liegt und in 
meinem Quelltext das require-Statement nach

     require 'serialport'

geändert. Nun gehts, denn das require 'serialport.so' steht in der .rb 
und lädt so die Extension. Sieht also erst mal so aus, als sei da im 
Installationspaket irgendwas nicht so, wie es sein sollte.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren