Forum: Projekte & Code Programm zur billigen Relaisplatine 8FA


von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

Bei Conrad gibt es eine komplette Relaisplatine 8-fach seriell unter der
Bezeichnung 8FA für relativ günstige 39,95 EUR.
Die Platine hat 8 Relais und es können bis zu 255 Relaiskarten
kaskadiert werden (255 Relaiskarten * 8 Relais = 2040 schaltbare Relais
insgesamt).
Conrad gibt zwar nur eine Belastbarkeit von 24 V und max. 2 A an, aber
die Relais schaffen laut Aufdruck 250 V und 6 A, so dass man damit bis
1380 W schalten kann, was für die meisten Geräte ausreicht.

Im Netzt habe ich dazu diese Seite gefunden:

http://www.netzmafia.de/skripten/hardware/relais/relais.html

aber dem Programm fehlten noch ein paar Sachen wie Überprüfung des
Timings der ausgetauschten Datenpakete, Empfangen der Daten mittels
select, Timeout beim Öffnen des Devices, exklusives Öffnen (damit nicht
mehrere Programme gleichzeitig auf derselben Schnittstelle arbeiten)
usw.. Deshalb habe ich die überarbeitete Version angehängt.
Mit onboard-Ports funktioniert es problemlos, aber über einem noname
USB-RS232-Adapter, den ich von KM habe, funktioniert es nicht
zuverlässig; vermutlich ist die Ausgangsspannung der Karte für den
Adapter zu klein.

Die Hardware-Bilder dazu habe ich hier (bandbreitenbegrenzt):
http://random.linux-site.net/files/unsorted/powerbox2/powerbox2_a.jpg
http://random.linux-site.net/files/unsorted/powerbox2/powerbox2_b.jpg
http://random.linux-site.net/files/unsorted/powerbox2/powerbox2_c.jpg
http://random.linux-site.net/files/unsorted/powerbox2/powerbox2_d.jpg
http://random.linux-site.net/files/unsorted/powerbox2/powerbox2_e.jpg
http://random.linux-site.net/files/unsorted/powerbox2/powerbox2_f.jpg
http://random.linux-site.net/files/unsorted/powerbox2/powerbox2_g.jpg

Durch das Eisenblech-Gehäuse gibt's weder EMV- noch ESD-Probleme und
damit die Masse von der Karte nicht frei driftet, wenn die
Schnittstelle nicht angeschlossen ist, habe ich zur Gehäusemasse einen
Leistungswiderstand von 560 Ohm genommen; dadurch werden auch
Brummströme begrenzt.

Getestet habe ich das Programm nur unter Linux, aber mit mimimalen
Änderungen sollte es unter jedem Posix-Kompatiblem Betriebssystem
funktionieren.

Wegen den Posix-Threads muß man den Sorcecode mit der Option -lpthread

kompilieren. Ich benutze dafür diese Funktion in der
.bashrc:

# Funktion zum Kompilieren. Bsp.: "c bsp" kompiliert bsp.c und
produziert bsp.
function c {
  gcc -Wall -I. -O3 -D_GNU_SOURCE -D__SMP__ -DLINUX
-D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_REENTRANT -lpthread -lrt -mcpu=i686
-fexpensive-optimizations -DCPU=686 -ffast-math -m486 -lm -lz -o $1
$1.c && prelink -fmRv ./$1 && strip $1
}


Übrigens gibt's hier ein größeres Programm, mit dem man mehrere
kaskadierte Karten ansprechen kann, dem aber Sachen wie select und die
anderen oben aufgelisteten Sachen fehlen:

http://www.relaiskarte.thomas-dohl.de/

von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

Weil mir aufgefallen ist, das die Adresse nicht überprüft wird, habe ich
die entsprechende Überprüfung eingebaut (Anhang).
Allerding zeigt sich hier ein Bug der Karte: Laut Kapitel 4.5 der
Bedienungsanleitung sollte die Karte in ihrer Antwort ihre Adresse
verwenden, und die ist laut Kapitel 4.5 bei der ersten Karte immer 1.
Diese Adresse kommt aber nur zu ca. 1 %; zu 99 % kommt als Adresse 2
zurück!
Es funktioniert aber trotzdem; es ist nur ein irgnorierbarer Bug in der
Karten-Firmware.

Bei der Gelegenheit, und weil zu 1 % die Karte keine Antwort schickt,
habe ich auch eingebaut, dass das Programm im Fehlerfall -1 zurück gibt
und 0 bei keinen Fehlern und ignorierbaren Bugs.

von Werner (Gast)


Lesenswert?

Das die Relais 250 V / 6 A können glaub ich Dir ja. Hast du mal
überprüft, ob die Leiterplatte und die Anschlussklemmen das auch
können? Stichwort Leiterbahnabstand, Querschnitt, ...

Ansonsten finde ich 39 Euro für ein Schieberegister nicht sonderlich
günstig.

Werner

von nobody0 (Gast)


Lesenswert?

"Hast du mal
überprüft, ob die Leiterplatte und die Anschlussklemmen das auch
können? Stichwort Leiterbahnabstand, Querschnitt, ..."

Ja, deshalb habe ich die Leiterbahnen an den Relais-Ausgängen mit
Lötzinn verdickt (man kann auch Draht nehmen), so dass 6 A kein Problem
sind. Die Abstände stimmen auch, also über 4 mm Abstand zu Masse und
anderen Niedervolt-Leitungen.
Ich bin ja nicht der einzige, der die Karte problemlos so verwendet (1.
URL).



"Ansonsten finde ich 39 Euro für ein Schieberegister nicht sonderlich
günstig."

Hast Du mal nachgesehen, was Du dafür bekommst?
In dem Karton ist neben der Bedienungsanleitung mit dem
Schnittstellen-Protokoll eine bestückte Platine an der man nichts löten
muß; plug and play! Für die Euro-Platine mit fertig programmierten
Mikrocontroller, 8 Leistungs-Relais mit separater LED, Spannungsregler,
Quarz, RS232-Buchse, 4 Befestigungs-Löchern, zweite Schnittstelle zum
Kaskadieren uws. ist es günstig. Wenn Du sowas selbst machst, werden
allein die Material-Kosten kaum niedriger sein.

von peter dannegger (Gast)


Lesenswert?

"Hast Du mal nachgesehen, was Du dafür bekommst?"


Erstmal können !

"Ihre Suche nach dem Begriff "8FA" in allen Kategorien ergab keine
genauen Treffer."


Und eine Software, die nur zu 99% funktioniert, würde ich gleich
wegschmeißen.


Peter

von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

""Ihre Suche nach dem Begriff "8FA" in allen Kategorien ergab keine
genauen Treffer.""

Dann hast Du nicht auf conrad.de gesucht, denn da bekommt man die Karte
als ersten Treffer:

http://www1.conrad.de/scripts/wgate/zcop_b2c/~flN0YXRlPTI4NzUxOTAwMzE=?~template=PCAT_AREA_S_BROWSE&glb_user_js=Y&shop=B2C&p_init_ipc=X&~cookies=1


"Und eine Software, die nur zu 99% funktioniert, würde ich gleich
wegschmeißen."

Die Software funktioniert zu 100 %; sonst würde die nicht einmal eine
Fehlermeldung ausgeben (so wie die Software, bevor ich sie überarbeitet
habe). Der Rückgabewert des Programms stimmt immer, auch wenn die Karte
nicht antwortet! Gelegentlich antwortet die Karte einfach überhaupt
nicht; es ist ein Bug in der Karte. Deshalb, und wegen der falschen
Adresse in der Antwort, habe ich mal bei Conrad nachgefragt.

Eine Applikation muß ja nur den Befehl über das Programm so lange
wiederholen, bis der Rückgabewert 0 ist oder nach z. B. einer Minute
abbrechen.

Weil ich in der neuesten Version noch die Ausgabe der Firmware-Version
eingebaut habe, anbei die neueste Version. Bei meiner Karte ist die
Version 10 drinn.

von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

Anbei die neueste Version, die 100 % nur dann terminiert, wenn die
Relais erfolgreicht gesetzt/abgefragt werden konnten.
Die Timeouts habe ich auf 2 s reduziert, so dass bei fehlender Karte
alle 2 s versucht wird mit der Karte zu kommunizieren.

Man sieht damit nun, dass während des Einschaltens der MC verwirrt ist
und erstmal dutzende fehlerhafter Pakete schickt. Das ist ein weiterer
Bug. Eine sauber programmierte MS-SW enabelt die UARTs ja erst dann,
wenn sie korrekt verwendet werden können, so dass fehlerhafte
Datenpakete nicht produziert werden können.
Es kann auch an einer quick and dirty-SW liegen, die das Timing nicht
überprüft und dadurch Anfang und Ende eines Datenpakets nicht richtig
erkennt.
Jedenfalls funktioniert's nun auch so und durch die Prüfsumme wird
nichts falsches eingeschaltet.

von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

Gemäß Murphys Law ist mir noch aufgefallen, dass die while-Schleife
falsch war, weil die nur auf Empfang gewartet hat, aber nie gesendet
hat, bei falschem Parameter fälschlich mit return code 0 terminiert
wurde, für's Prettyprinting Klammern bei dem großen else if -Block
fehlten usw. anbei die überarbeitete Version.

von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

Gemäß Murphys Law war in der letzten Version noch ein longjmp zuviel für
den Fall, daß

#define EXIT_ONLY_ON_SUCCESS

auskommentiert wird, für die Variate, die nach einem Versuch in jedem
Fall terminiert (innerhalb 2 s).

von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

So nun habe ich eine Antwort von Conrad und danach soll man die
Beispiel-Programme nehmen. Demnach wird die Adresse in der Antwort
immer ignoriert; d. h. der Bug wird einfach ignoriert!

Und daß die Karte sich zu 1 % nicht initialisieren läßt, auch mit den
Beispiel-Programmen, liegt daran, dass die Karte mindestens 200 ms
Pause braucht; das fehlt in der Bedienungsanleitung einfach.

Anbei deshalb die neueste Version, mit der es nun auch die dutzende
fehlerhafte Pakete nach dem Einschalten der Karte nicht mehr gibt.
Außerdem ist noch pthread_cancel durch pthread_join ersetzt, damit es
keine ständig wachsende Anzahl von Thread-Zombies gibt.

von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

Bei der letzten Version fehlten für den seltenen Fall, daß das device
nicht geöffnet werden kann, Signal-Handler zur korrekten
Interprozesskommunikation.
Anbei die neueste Version bei der die Signal-Handler eingebaut sind.
Außerdem werden nun auch die alte und die neue Schalterstellung
ausgegeben, damit man auch beim Stellen stehen kann, was vorher
eingestellt war.

von Ingo Kertscher (Gast)


Lesenswert?

Hi,
ich habe mir mal die letzte Version des Relais Programms gezogen.
Beim Compilieren kommen aber nur Fehlermeldungen:

audib4@speedy:~/Documents/Relaiskarte/relaisv1> gcc -o relais relais.c
/tmp/ccMWLU2d.o(.text+0x88e): In function `func_timeout':
: undefined reference to `pthread_kill'
/tmp/ccMWLU2d.o(.text+0x9ed): In function `main':
: undefined reference to `pthread_create'
/tmp/ccMWLU2d.o(.text+0xa43): In function `main':
: undefined reference to `pthread_create'
/tmp/ccMWLU2d.o(.text+0xa92): In function `main':
: undefined reference to `pthread_join'
/tmp/ccMWLU2d.o(.text+0xab4): In function `main':
: undefined reference to `pthread_join'
collect2: ld returned 1 exit status

Da ich im C programmieren noch nicht die Ahnung habe könnte mir
jemand helfen diese Fehler wegzubekommen?
Oder habe ich beim Compilieren was falschgemacht?
System Suse 8.2 in einer ziemlichen Standart Installation.

Danke Ingo

von nobody0 (Gast)


Lesenswert?

Das steht ganz oben; bei Dir fehlt die Option -lthread.

von Ingo Kertscher (Gast)


Lesenswert?

Wer lesen kann ist klar im vorteil.
OK compilieren tut er jetzt aber funktioniern tuts immer noch nicht
das Programm bleibt mit:

 Signal 11, program exiting...

einfach stehen. Was habe ich nun wieder falschgemacht?

Danke Ingo

von nobody0 (Gast)


Lesenswert?

Das ist von hier nicht genau feststellbar.
Das Programm wird immer ohne Fehler/Warnungen compiliert und bei mir
läuft das Programm auf mehreren Rechner unter SuSE und Debian und zwar
auch dann problemlos, wenn ich es mit lefence (das findet Signal 11
-Fehler bevor sie das Programm beenden) benutze.
Du solltest mal prelink und strip weglassen und deinen Rechner mit
einem Speichertest checken:

http://www.ayukov.com/essays/signal11.html

von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

Weil ich inzwischen noch ein paar Debugging-Ausgaben (aktiviert wenn
DEBUG per define gesetzt ist) eingebaut habe und noch ein paar
Kleinigkeiten wie const bei read-only-Parametern eingebaut habe, anbei
die aktuelle Version.

Auf einem dritten PC (Supermicro 370DL3, dual P III 1000) mußte ich
aber feststellen, dass es mit den onboard-Ports nicht richtig
funktioniert, obwohl sonst damit alles geht; auch ein Selbst-Update
eines MCs, der die Daten (60 kB) mit einem RAMloader und Bit-Banging
über RS232 einliest (was kritisch ist bezüglich Timing und nicht an
jedem PC/Adapter funktioniert).
Offensichtlich synchronisiert der UART der Karte nicht sauber, weil er
mit dem Timing außerhalb des RS232-Standards liegt!
Bei anderen PCs (z. B. mit Tyan Tiger MPX) funktioniert es und es geht
mit dem USB2.0-Adapter weil die UARTs toleranter sind, aber es geht
schon nicht mit dem USB1.1-Adapter; da geht ungefär die Hälfte der
Bytes verloren. Bei den Adaptern ist es unabhängig vom Rechner.

Bei Gelegenheit werde ich mal versuchen das durch den Austauch des
Quarzes der Karte zu korrigieren ...

von Ingo Kertscher (Gast)


Lesenswert?

Hallo,
hat bisher alles nichts gebracht,
rufe ich Relais ohne Pararmeter auf kommt
die Hilfe seite mit Pararmeter kommt das Signal 11.
Wenn noch jemand andere Ideen hat Bitte melden sonst war das ein netter
versuch.

Danke Ingo

von nobody0 (Gast)


Lesenswert?

Wie genau rufst Du es denn auf?

Und was ist, wenn Du nur "-on" oder "-off" als Parameter
verwendest?

Ich habe die Eingabeprüfung nicht ausgearbeitet, sondern nur
übernommen, so daß da fehlende Eingabeüberprüfungen drinn sein können.

von Ingo Kertscher (Gast)


Lesenswert?

Hallo,

ohne Pararmeter so:

audib4@speedy:~/Documents/Relaiskarte/relaisv1> relais
Ansteuerprogramm fuer die serielle Relaiskarte von Conrad
No Parameters!

mit entsprechender Pararmeter übergabe so:

audib4@speedy:~/Documents/Relaiskarte/relaisv1> relais -on
 Signal 11, program exiting...

so stellt sich das entsprechen der hilfe Seite im ersten Bsp. als
richtig
dar. Gebe ich das /dev/ttyS0 mit an genau
dasselbe auch mit/ohne Relaiskarte.

Relaiskarte funktioniert mit einem WIN rechner eines Bekannten
meine serielle funktioniert mt einem testweise angeschlossenem Modem.

Zur HW ein Tyan Trinity100 AT mit einem K6-2-550, also gut abgehangene
HW älteren Baujahres.

Danke Ingo

von nobody0 (Gast)


Lesenswert?

Was sagt denn Memtest86, wenn Du es ein paar Stunden laufen läßt?

Ohne die Kiste kann ich von hier nichts dazu sagen.
Du kannst ja mal mit der Option -ggdb compilieren und dann mit
gdb relais
run -on
starten.
Mit list sollte angezeigt werden, wo das signal 11 passiert.

von Ingo Kertscher (Gast)


Lesenswert?

Hallo,
hier mal die gewünschten angaben:

audib4@speedy:~/Documents/Relaiskarte/relaisv1> gdb relais
GNU gdb 5.3
Copyright 2002 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and
you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for
details.
This GDB was configured as "i586-suse-linux"...
(gdb) run -on
Starting program: /home/audib4/Documents/Relaiskarte/relaisv1/relais
-on
[New Thread 16384 (LWP 12466)]
[New Thread 32769 (LWP 12467)]

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 32769 (LWP 12467)]
0x40028f5e in pthread_handle_create () from /lib/libpthread.so.0
(gdb) list
410     #ifdef DEBUG
411       printf("g_fd=%d\n", g_fd);
412     #endif
413       pthread_exit ((void *) &retval);
414     }
415
416
417     int
418     main (int argc, char *argv[])
419     {                               // static asserts that all
values are initialized with 0 recursively
(gdb)

also wenn ich die Ausgaben richtig deute
habe ich ein Segmentation fault  von
/lib/libpthread.so.0

die list ausgabe sagt mir aber garnichts (C Programmcode)
hast Du noch Ideen sollte ich mir eine neuere /lib/libpthread.so.0
besorgen?

Danke Ingo

von Ingo Kertscher (Gast)


Lesenswert?

Zu früh gesendet Memtest ist vor ca. 2Wochen ein ganzes Wochenende
gelaufen ohne Fehler.

Danke Ingo

von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

Hm, also wenn der Fehler im Programm wäre, hätte gdb sowas wie

main (argc=2, argv=0xbffff0c4) at relais.c:439

gemeldet; d. h. der Fehler ist wirklich in der lib die Du verwendest.
Das ist merkwürdig, da es Posix Threads seit rund 20 Jahren gibt.

Am Besten machst Du ein Update; damit sollte das Problem beseitigt
sein.

Anbei eine Version, die ich unter SuSE 9.2 compiliert habe.
Ich konnte die aber nicht statisch linken.

von Ingo Kertscher (Gast)


Lesenswert?

Hallo,
Suse und Updates bisher nur schlechte Erfahrung
gemacht.
Am Wochenende werde ich mir mal die sache in Ruhe anschauen.

Danke Ingo

von nobody0 (Gast)


Angehängte Dateien:

Lesenswert?

Gemäß Murphys Law hatte get_time noch einen selten sichtbaren Bug, weil
die Zeit in µs mit zwei getrennten Aufrufen bestimmt wurde.
In der angehängten Version ist dieser Bug mit nur einem Aufruf von
gettimeofday beseitigt.

Inzwischen konnte ich auch das statische Linken mit

gcc -g -Wall -O3 -D_GNU_SOURCE -D__SMP__ -DLINUX -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64 -D_REENTRANT -funroll-loops
-fexpensive-optimizations -ffast-math -DCPU=686 -c -o relais.o
relais.c

gcc -g -static -Wall -O3 -D_GNU_SOURCE -D__SMP__-DLINUX
-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT -lrt
-funroll-loops -fexpensive-optimizations -ffast-math -lm -DCPU=686
-I/usr/lib/ -o relais relais.o /usr/lib/libpthread.a

hinbekommen, aber offenbar durch einen Bug in libpthread.a bewirkt  der
Aufruf von pthread_create ein Segmentation Violation (Signal 11); d. h.
das statisch gelinkte Programm funktioniert nicht. Dabei ist es egal ob
man es unter SuSE oder Debian compiliert und linkt.
Da bleibt nur dynamisches Linken, wie oben beschrieben; damit
funktioniert es unter SuSE wie unter Debian problemlos.

von Rolf F. (Gast)


Angehängte Dateien:

Lesenswert?

Also der Bug ist in der glibc, wie der Debugger (DDD) zeigt:

Core was generated by /home/nobody0/c/8fa/1/relais -on'.
Program terminated with signal 11, Segmentation fault.
#0  0x0804a4fc in __pthread_manager ()

Inzwischen habe ich herausgefunden, daß es auch an den
Thread-Attributen liegt: Laut Man-Page kann man pthread_create als
zweites Argument einen Null-Pointer oder einen Pointer auf eine
Variable vom Typ pthread_attr_t übergeben.
Wird die Variable aber nur mit Null initialisiert indem man sie z. B.
als static deklariert, bewirkt das sowas wie ein nicht abgefangenes
Dereferenzieren eines Null-Pointers beim statisch gelinkten Programm.
Wird die Variable mit pthread_attr_init initialisiert, tritt der Bug
nicht auf.
Wieso der Bug bei dynamisch gelinkten Programmen nicht auftritt, habe
ich noch nicht herausgefunden.

Anbei das Programm im Source mit pthread_attr_init und auch als
statisch gelinktes executable.

Es funktioniert auch ohne die Hardware und gibt dann dies aus:

> ./relais -on
init port
opened port 0, g_fd=0
Connection timeout (select failed).
FAIL: card init failed (0 0 0 255).
init port
...

von Michael Reck (Gast)


Lesenswert?

Es scheint einen weiteren Bug zu geben. Bei mehr als 18 Karten die
Verbunden sind werden alle antworten geschluckt. Es werden die Karten
mit der einfachen stateless ansteuerung von thomas
(http://www.thomas-dohl.de/relaiskarte/) zwar angesteuert aber ich
bekomme einen Timeout und strace zeigt
open("/dev/ttyS0", O_RDWR|O_NONBLOCK|O_NOCTTY) = 4
ioctl(4, TCFLSH, 0)                     = 0
ioctl(4, TCSETS, {B19200 -opost -isig -icanon -echo ...}) = 0
ioctl(4, SNDCTL_TMR_TIMEBASE, {B19200 -opost -isig -icanon -echo ...})
= 0
read(4, 0x804c680, 4)                   = -1 EAGAIN (Resource
temporarily unavailable)

Bei mehr als 12 musste ich bereits die Timeouts auf 10000 usec erhöhen.
Bis 18 gings dann wieder. Jetzt klappts überhaupt nicht mehr mit der
Rückmeldung. Dein Programm liefert bei -stat:

clone(Process 1129 attached
child_stack=0x80ffe90,
flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND) = 1129
[pid  1128] write(4,
"\0\0\0\0\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\20(\363"...,
148) = 148
[pid  1128] rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0
[pid  1128] write(4,
"\240\202\v\10\0\0\0\0\240\252\v\10P\224\4\10\210\252\v"...,
148) = 148
[pid  1128] rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0
[pid  1128] rt_sigsuspend([] <unfinished ...>
[pid  1129] --- SIGSTOP (Stopped (signal)) @ 0 (0) ---
[pid  1129] rt_sigprocmask(SIG_SETMASK, ~[TRAP 33], NULL, 8) = 0
[pid  1129] read(3,
"\0\0\0\0\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\20(\363"...,
148) = 148
[pid  1129] poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 2000) = 1
[pid  1129] getppid()                   = 1128
[pid  1129] read(3,
"\240\202\v\10\0\0\0\0\240\252\v\10P\224\4\10\210\252\v"...,
148) = 148
[pid  1129] old_mmap(0xbf600000, 2097152,
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0xbf600000
[pid  1129] mprotect(0xbf600000, 4096, PROT_NONE) = 0
[pid  1129] clone(Process 1130 attached
child_stack=0xbf7ffbd0,
flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGRT_1) = 1130
[pid  1129] kill(1128, SIGRTMIN)        = 0
[pid  1128] --- SIGRTMIN (Unknown signal 32) @ 0 (0) ---
[pid  1128] <... rt_sigsuspend resumed> ) = -1 EINTR (Interrupted
system call)
[pid  1128] sigreturn()                 = ? (mask now [RTMIN])
[pid  1128] rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0
[pid  1128] write(4,
"\240\202\v\10\0\0\0\0\240\252\v\0100\225\4\10\214\252\v"...,
148) = 148
[pid  1128] rt_sigprocmask(SIG_SETMASK, NULL, [RTMIN], 8) = 0
[pid  1128] rt_sigsuspend([] <unfinished ...>
[pid  1129] poll([{fd=3, events=POLLIN, revents=POLLIN}], 1, 2000) = 1
[pid  1129] getppid()                   = 1128
[pid  1129] read(3,
"\240\202\v\10\0\0\0\0\240\252\v\0100\225\4\10\214\252\v"...,
148) = 148
[pid  1129] old_mmap(0xbf400000, 2097152,
PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) =
0xbf400000
[pid  1129] mprotect(0xbf400000, 4096, PROT_NONE) = 0
[pid  1129] clone(Process 1131 attached
child_stack=0xbf5ffbd0,
flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGRT_1) = 1131
[pid  1129] kill(1128, SIGRTMIN <unfinished ...>

zu mehr bin ich bis jetzt nicht gekommen. Wenn ich später im Büro bin
schicke ich mal die gegenprobe mit 18 karten.( bin per ssh auf der
maschine)

von Rolf F. (Gast)


Lesenswert?

Die Karten brachen einige Zeit zum Verarbeiten, sind nicht fullduplex
fähig und vermutlich gilt das für beide Richtungen (serielle Verbindung
Richtung PC + weitere Karten), da sie quick and dirty programmiert
wurden, wie man am Bug mit falschen Empfangsadresse und der nicht
gerade zuverlässigen Übertragung sieht.
Ich habe für eine Karte 200 ms Wartezeit eingebaut und für 18 Karten
ergäbe das 3,6 Sekunden.

> read(4, 0x804c680, 4) = -1 EAGAIN (Resource temporarily unavailable)

Aus der Man-Page von read:

EAGAIN Non-blocking  I/O has been selected using O_NONBLOCK and no
data
              was immediately available for reading.

D. h. das Programm vom Thomas verwendet kein select, überprüft also
nicht ob etwas empfangen wurde und read liefert durch den leeren Puffer
entsprechend EAGAIN zurück.

Dem Programm vom Thomas fehlt zumindest select.

von Thomas Dohl (Gast)


Lesenswert?

Hi,

wie ich sehe scheint es doch noch ein paar Probleme mit
meinem Programm zu geben.
Hallo Michael, tritt der Fehler nur auf, wenn du massig Karten
dran hängst?
Wie genau ist denn die Fehlermeldung von meinem Programm?

Ich bin gerade am entwerfen eines neuen Relaiskartenprogramms,
aber das wird noch ein weilchen dauern, denn ich bin gerade im
Prüfungsstress.
Ich habe vor es auch mal mit Java zu versuchen. :-)
Wenn du die beiden Programme lesen und schreiben nutzt,
wie verhalten sich dann die Antworten der Relaiskarten?
Also wie lange brauchen die Antworten, bis die erste eintrifft.

Gruß Thomas

von Rolf F. (Gast)


Lesenswert?

Inzwischen habe ich rausgefunden, daß das

tcflush (fd, TCOFLUSH);

nach dem write den Ausgangspuffer nicht leert (flush), wie der Name von
tcflush nahelegt, sondern löscht (discharge)!
Das erklärt den Datenverlust, denn dadurch wurde gelöscht, was noch
nicht abgeschickt werden konnte!
Anbei nun die Version ohne diesed tcflush, bei der es anscheinend
keinen Datenverlust mehr gibt.

von Rolf F. (Gast)


Angehängte Dateien:

Lesenswert?

Anhang

von Michael Reck (Gast)


Lesenswert?

@Thomas:
Das Problem tritt immer auf wenn mehr als 17 Karten kaskadiert werden.
Es werden die Karten zwar angesprochen, aber mit den Rückmeldungen
klappt es nicht mehr. Bis 17 Karten werden alle erkannt beim -i.
Ich hab jetzt auch experimente mit einer 8fach seriell Karte gemacht.
Selbes Problem. Da ich ca. 40 Karten ansteuern muss mache ich jetzt
einen Split nach 17 Karten und verpasse den nächsten 17 einen anderen
ttyS.
Genaue Fehlermeldung beim -i:
Es wurden keine Daten empfangen! (timeout)
Es wurden keine Relaiskarten gefunden! :-(
Das Programm wird auf Grund eines Fehlers beendet.
The programme terminated due to an error.
Ich teste nur ungern im Produktivsystem. Aber die nächsten 30 Karten
warten schon auf einbau.

von Thomas Dohl (Gast)


Lesenswert?

@Michael
Miss doch bitte mal die Zeit, mit dem Programm
lesen.cpp und schreiben.cpp, wie lange die Antworten der
Karten benötigen.
Wenn es immer länger dauert, je mehr Karten
kaskadiert werden ist es klar, dass mein
Programm abbricht.

Gruß Thomas Dohl

von Rolf F. (Gast)


Angehängte Dateien:

Lesenswert?

Die Ursache ist sicherlich, daß nicht lange genug auf die Antwort
gewartet wird, denn die Antwort von der Karte X dauert ja um so länger
je weiter hinten sie ist (je größer X ist), da die Daten ja 2X-1 mal
komplett empfangen werden müssen, dekodiert werden und dann weiter
geschickt werden müssen. Die Wartezeit auf die Antwort muß proportional
2X-1 sein. Bei 100 bis 200 ms pro Karte braucht man für die 18. Karte
also 3,5 bis 7 Sekunden.

Übrigens kann man nach dem write noch ein

  tcdrain(fd); // wait till the output has been transmitted

einfügen, damit die Software danach erst dann, und genau immer nur dann
weiterläuft, wenn wirklich alle Daten rausgeschickt wurden. Damit kann
man die Wartezeit auf die Antwort genauer einstellen.
Anbei meine Version damit.

von Michael Reck (Gast)


Lesenswert?

endlos :) ein strace zeigt auch warum:

open("/dev/ttyS0", O_RDWR|O_NOCTTY)     = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B19200 -opost -isig -icanon
-echo ...}) = 0
ioctl(3, TCFLSH, 0)                     = 0
ioctl(3, SNDCTL_TMR_START or TCSETS, {B19200 -opost -isig -icanon -echo
...}) = 0
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, {B19200 -opost -isig -icanon
-echo ...}) = 0
read(3, 0xbffff270, 255)                = ? ERESTARTSYS (To be
restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
read(3, 0xbffff270, 255)                = ? ERESTARTSYS (To be
restarted)
--- SIGWINCH (Window changed) @ 0 (0) ---
read(3,  <unfinished ...>

wie soll ich bei schreiben die Zeit messen ?
Das Programm möchte eine eingabe und ich seh jetzt auch keine
commandline options im source um einen time ./senden sinnvoll laufen zu
lassen.
Die befehler werden sofort ausgeführt. Wenn ich -r0 -s rrrrrrrr mache
geht das recht flott ( unter 3 sekunden) bis alle ihren status geändert
haben. Nur das lesen macht probleme.

von Thomas Dohl (Gast)


Lesenswert?

Mich würde einfach interessieren,
ob die Nachrichten nacheinander immer
etwas zeitlich verstetzt eintreffen,
oder ob alle nach eine immer längeren Zeit
(je nach dem, wie viele Karten angehängt sind)
eintreffen.


Gruß Thomas

von Rolf F. (Gast)


Angehängte Dateien:

Lesenswert?

@ Michael Reck:

In meinem Programm sind zwei Zeitmessungen drinn, unter anderem einmal
(Zeit des Empfangs des ersten Bytes) - (Zeit direkt nach dem Senden),
also die Ping-Zeit, die ich mit Minimum, Maximum und Durchschnitt sowie
Fehler-Statistik von einem anderen Programm (für andere Hardware)
ausgeben lasse.
Du kannst den Code ja einfach übertragen und dann die Ping-Zeit
ausgeben.

Übrigens habe ich mein Programm nun so angepaßt, daß bei unvollständig
empfangenen Paketen noch auf die letzten Bytes gewartet wird, denn ich
hatte über einen USB-RS232-Adapter das Problem, daß nach dem select
zwar etwas im Puffer war, aber die zweite Hälfte des Datenpaketes noch
nicht angekommen war.

von Michael Reck (Gast)


Lesenswert?

@ Rolf: mit deinem Programm bekomme ich gar keine ansteuerung hin.
Es scheint durch die verschiedenen checks alles zu unterbinden.
linux:/usr/src # ./relais /dev/ttyS0 -off
got file descriptor fd=3
frame warning
Firmware-Version 10
frame warning
FAIL: second part of card init failed (254 2 10 0).
An der Kasakade hängen 17 Karten.

Die andere hat immo 6:

linux:/usr/src # ./relais /dev/ttyS14 -off
got file descriptor fd=3
Connection timeout (select failed).
FAIL: card init failed (0 0 0 255).

@thomas:

An der 17er kaskade ist mir was aufgefallen. Ein -i schlägt fehl wenn
bereits ein relais angesteuert wude:
resetter -d /dev/ttyS0 -i
COM Port: "/dev/ttyS0"
Es wurden keine Daten empfangen! (timeout)
Es wurden keine Relaiskarten gefunden! :-(
Das Programm wird auf Grund eines Fehlers beendet.
The programme terminated due to an error.

Aber:
linux:/usr/src # resetter -d /dev/ttyS0 -r0 -s 00000000
COM Port: "/dev/ttyS0"
OK
oder:

linux:/usr/src # resetter -d /dev/ttyS0 -r1 -s 00000001
COM Port: "/dev/ttyS0"
OK
linux:/usr/src # resetter -d /dev/ttyS0 -r1 -s 00000000
COM Port: "/dev/ttyS0"
OK

von Thomas Dohl (Gast)


Lesenswert?

@Michael

hm, interessant.
Versuche mal mit -s 00000001 eine Karte höher 17 anzusprechen.
Mich würde interessieren, ob dann vielleicht wieder ein
Timeout kommt.

Bei -s habe ich eine kleine Optimierung eingebaut.
Und zwar wird erst bei "x,t" der aktuelle Zustand der
Karte abgefragt, ansonsten wird einfach rausgeschrieben.

Gruß Thomas

von Rolf F. (Gast)


Lesenswert?

@Michael Reck:
Mein Programm ist für EINE Karte!
Daß die Checks jede Aktion verhindern stimmt also.

Für mehrere Karten muß man das Programm vom Thomas nehmen.

von F.H. (Gast)


Lesenswert?

Hier kann man sich eine günstige Platine bauen
http://www.ees-hartz.de/P64_HLP/




10 Bit 4 Kanal AD Wandler in Vorbereitung
1 Befehl senden 4 Ergebnisse zurück
mfg F.Hartz

von Norbert (Gast)


Lesenswert?

Wenn Probleme auftretten mit
relais -on    alle setzen
relais -r5    relais 5 ausschlaten

und dann steht alles kein zugriff mehr möglich

Das liegt dann das als crc byte eine 0x13 uebertragen wird.
Diese loest im Input Buffer des ioctl ein XON / XOFF aus.


Abhilfe: Die Schnittstelle so bearbeiten.

stty -ixon -ixoff  -F /dev/ttyS0


Mgf

Norbert

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.