Hallo Zusammen,
ich versuche derweil ein USB-Messgerät dazu zu bewegen, mit meiner Software zu sprechen 🙂 Ich scheitere und hoffe, dass jemand mir sagen kann, was ich (vermutlich) falsch mache.
Bestandsaufname- was ich hier habe
[root@DEVIL cone]# uname -a
Linux DEVIL 3.0-ARCH #1 SMP PREEMPT Tue Aug 30 07:32:23 UTC 2011 i686 Intel(R) Pentium(R) 4 CPU 3.00GHz GenuineIntel GNU/Linux
Dann gibt es da das USB-Gerät, welches an sich nur ein Wandler von USB to RS232 ist. Der Sollte also nichts weiter senden, da er keine Box dran hat- ergo nur ein kurzer wandler
[root@DEVIL cone]# dmesg
...
[7796292.560389] usb 3-1: new full speed USB device number 6 using uhci_hcd
...
[root@DEVIL cone]# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 006: ID 0403:c6a1 Future Technology Devices International, Ltd <----- Das Gerät ist da!
Gut ... das Gerät ist also im System angebunden ... Ich binde es dann mit folgendem Kommando an einen USB-Port:
[root@DEVIL cone]# modprobe usbserial vendor=0x0403 product=0xc6a1
[root@DEVIL cone]# dmesg
...
[8210028.972925] usbcore: registered new interface driver usbserial
[8210028.972960] USB Serial support registered for generic
[8210028.972992] usbserial_generic 3-1:1.0: generic converter detected
[8210028.973538] usb 3-1: generic converter now attached to ttyUSB0
[8210028.973579] usbcore: registered new interface driver usbserial_generic
[8210028.973584] usbserial: USB Serial Driver core
So, eingebunden! Der Hersteller möchte gern eine Geschwindigkeit von 9600Baud 8n1 haben ... und ich setze es mal ...
[root@DEVIL cone]# stty -F /dev/ttyUSB0 9600
[root@DEVIL cone]# stty -F /dev/ttyUSB0 -a
speed 9600 baud; rows 0; columns 0; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R;
werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 hupcl -cstopb cread clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
Das ist der Punkt, wo ich denke, ich habe das Gerät erfolgreich eingebunden!
Software
Ich möchte gern mit der Schnittstelle sprechen und schauen, was von da kommt. Als Software nutze ich folgenden C Code.
/*
terminal.c - Ein- und Ausgabe ueber die serielle
Schnittstelle
*/
# include <stdio.h>
# include <unistd.h>
# include <fcntl.h>
# include <termios.h>
# define TERM_DEVICE "/dev/ttyUSB0"
# define TERM_SPEED B9600 /* Bit/Sek */
int main()
{
int fd, old_flags;
ssize_t length;
char buffer[16];
struct termios term_attr;
fd_set input_fdset;
if ((fd = open(TERM_DEVICE, O_RDWR)) == -1)
{
perror("terminal: Can't open device " TERM_DEVICE);
return(1);
}
/* RS232 konfigurieren */
if (tcgetattr(fd, &term_attr) != 0)
{
perror("terminal: tcgetattr() failed");
return(1);
}
term_attr.c_cflag = TERM_SPEED | CS8 | CRTSCTS | CLOCAL;
term_attr.c_iflag = 0;
term_attr.c_oflag = OPOST | ONLCR;
term_attr.c_lflag = 0;
if (tcsetattr(fd, TCSAFLUSH, &term_attr) != 0)
perror("terminal: tcsetattr() failed");
/* Std.-Eingabe anpassen */
if (tcgetattr(STDIN_FILENO, &term_attr) != 0)
{
perror("terminal: tcgetattr() failed");
return(1);
}
/* alte Einst. sichern */
old_flags = term_attr.c_lflag;
term_attr.c_lflag &= ~(ICANON | ECHO);
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attr) != 0)
perror("terminal: tcsetattr() failed");
while (1)
{
FD_ZERO(&input_fdset);
FD_SET(STDIN_FILENO, &input_fdset);
FD_SET(fd, &input_fdset);
if (select(fd+1, &input_fdset, NULL, NULL, NULL) == -1)
perror("terminal: select() failed");
if (FD_ISSET(STDIN_FILENO, &input_fdset))
{
if ((length = read(STDIN_FILENO, buffer, 16)) == -1)
perror("terminal: read() failed");
else
if (buffer[0] == '\33') /* Abbruch mit ESC */
break;
else
write(fd, buffer, length);
}
if (FD_ISSET(fd, &input_fdset))
{
if ((length = read(fd, buffer, 16)) == -1)
perror("terminal: read() failed");
else
write(STDOUT_FILENO, buffer, length);
}
}
/* Std.-Eingabe wie vorher */
term_attr.c_lflag = old_flags;
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &term_attr) != 0)
perror("terminal: tcsetattr() failed");
printf("Aborted.\n");
close(fd);
return(0);
}
Der Code lässt sich einfach und sauber kompilieren und stammt aus einem Buch. Der Spannende Teil kommt allerdings jetzt. Irgendwie meldet das Programm, dass Daten von ttyUSB0 kommen ... und das wiederholt:
[root@DEVIL cone]# c++ steinwald.c -osteinwald
[root@DEVIL cone]# ./steinwald
`````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
Ich hatte das mal in PERL probiert, nachdem ich nicht sicher war, ob der Code so schick sei. Die Sequenz ist in Zahlen 1-96-1-96-1-96 ....
In PERL sieht die Schleife dann so aus:
my @vString = split("",$port_obj->read(2048));
my $vHex = "";
for (my $x=0; $x <= $#vString;$x++) {
$vHex .= unpack('C*',$vString[$x] ) ."-";
}
Was ist das und woran liegt das? Hat jemand einen Tipp für mich? Ich verstehe es einfach (noch) nicht?! Woher kommen die Werte? Und wieso kommt nicht einfach NICHTS, weil nichts kommen dürfte? Die Geräte wurde unter Windows getestet und laufen sauber. Daran liegt es schon mal nicht.
Besten Dank