Datum:
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:
require "serialport.so"
sp = SerialPort.new(0, 115200) # Öffnet /dev/ttyUSB0
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?
Datum:
Also hier: http://ruby-serialport.rubyforge.org/ Wir zumindest der Name des Port benötigt als erster Parameter, was macht den die 0 da? Wenn ich die Doku verstehe mappt die nämlich defaultmäßig nach /dev/ttyS0 und nicht nach /dev/ttyUSB0
Datum:
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.
Datum:
So siehts aus, wenn man versucht den SerialPort mit String im irb zu öffnen:
$ irb
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'serialport.so'
=> true
irb(main):003:0> sp=SerialPort.new("/dev/ttyUSB0", 9600)
TypeError: can't convert String into Integer
from (irb):3:in `initialize'
from (irb):3:in `new'
from (irb):3
irb(main):004:0>
|
Datum:
Uhu Uhuhu schrieb: > 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 Auch unter neueren Windows-Versionen geht es z.B. mit CrtDbgBreak() mit VC++.
Datum:
Und mit gcc unter Linux?
Datum:
Wenn ich das aus dem Stegreif wüsste, hätte ich es dir verraten...
Datum:
Klaus Wachtler schrieb: > Auch unter neueren Windows-Versionen geht es z.B. mit CrtDbgBreak() mit > VC++. Demgegenüber hatte der int 3 - Trick den Vorteil, daß der Debugger auch wirklich in meinem Quelltext auf dem int 3 stand. Mit CrtDbgBreak() findet man sich irgendwo ein paar Etagen tiefer und muß sich dort erst wieder rauswurschteln.
Datum:
Soviel ich bisher mit gdb herausgefunden habe, wird aus irgenwelchen komischen Gründen create nicht aufgerufen, der Port ist also nicht offen. Irgendwo ist da der Oberwurm drin...
Datum:
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).
Datum:
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:
/* * :nodoc: This method is private and will be called by SerialPort#new or SerialPort#open. */ |
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.
Datum:
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.... http://stackoverflow.com/questions/1093598/pyseria... http://stackoverflow.com/questions/676172/full-exa... .. 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.
Datum:
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.
Datum:
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...
Datum:
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
Datum:
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
Datum:
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
Datum:
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.
Datum:
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.