PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Led über serielle Schnittstelle ansteuern



linuxnoob:-)
11.10.04, 19:55
Hallo

Ich möchte mit einem kleinen Programm unter Suse Linux 9.1 mithilfe eines Crontabs alle 24 Stunden für 2 Sekunden eine LED an der Seriellen Schnittstelle aufleuchten lassen.
Auch nach zig Stunden googeln fand ich leider keine gute anleitung um das zu realisieren :(. Ich bin kompletter Linux-Beginner und habe auch keine grosse erfahrung mit C.
Währe froh wenn jemand ein gutes Tutorial dafür hätte. Am liebsten wäre mir aber doch n kompletter Code, welchen ich nur noch kompillieren müsste.
Das Programm müsste nur eine Signalleitung für die besagten 2 Sekunden auf High und dann wider auf Low setzen.

THX im voraus

derguteweka
11.10.04, 20:23
Moin,

Das muesst' auch komplett ohne was in C zu programmieren gehen. Haeng' deine LED an die DTR oder RTS Leitung und fertig isses.
Kopier dann einfach irgendne Datei nach /dev/ttyS0; schon geht die LED an...Wenn fertig kopiert ist, geht sie wieder aus.

Die 2 Sekundendauer kannst du grob durch die Groesse der Datei einstellen...
Die serielle scheint mir defaultmaessig auf 9600 Baud eingestellt zu sein, damit sollte die Datei 1920 Byte gross sein, damits 2 sec. dauert.

Ist natuerlich nicht so elegant, wie einen eigenen Devicedriver und eine Applikation dafuer zu schreiben, aber dafuer viel schneller realisiert :)

Gruss
WK

linuxnoob:-)
11.10.04, 20:36
Danke für die schnelle Antwort.

Ist n guter Tipp, habs grad ausprobiert und es funkt, doch leider sollten die 2 Sekunden schon einigermassen stimmen und irgendwie leuchtet die Diode manchmal etwas länger und manchmal etwas kürzer, jenachdehm wie stark mein System belastet is. Gibts da nicht noch ne andere Lösung ??

derguteweka
11.10.04, 20:50
Moin,

Also was genaueres bei vergleichbarem Aufwand faellt mir momentan nicht ein. Die naechste Stufe waer dann tatsaechlich ein kleines
(C) Programm (evtl. plus eigenes Kernelmodul fuer die Ansteuerung der UART Register), dass die Handshakeleitungen setzt (Habbich aber grad nix abschreibfertiges da :( ).
Bloss ist bei einem System, dass richtig unter Last steht, auch nicht so ohne weiteres gewaehrleistet, dass die 2 sec. immer genau eingehalten werden und nicht mal zu 2+Epsilon sec. werden. Da gaebs dann diverse "harte"-Realtime-patches fuer den Kernel, oder noch abgefahrenere Loesungen, aber um ein bisschen mehr Genauigkeit zu gewinnen, muss dann der Aufwand fast ins Unermessliche getrieben werden...
Muessen die 2 sec wirklich so genau sein?

Gruss
WK

linuxnoob:-)
11.10.04, 21:09
Eigentlich handelt es sich bei der Idee um einen Signalgeber welchen ich zusätzlich mit der Internetzeit abgleichen möchte.
Wenn du aber sagst dass das ein zu grosser Aufwand wäre, ist das kein problem. Ich kann ja die 2 Sekunden extern nochmal abgleichen.

Danke mal für die schnellen Postings

derguteweka
11.10.04, 21:25
Moin,

Ob der Aufwand _zu_ gross ist, musst du entscheiden ;) Er ist nur um vieles groesser, als mit der cp 1920 byte Loesung. Wenn dir nach Kerneltreiberprogrammierung in C der Sinn steht und du vielleicht auch schon mal unter DOS oder auf nem 8bitter einen UART programmiert hast, isses sicher 'n gutes Projekt zum Einsteigen.

Kleine Feierabendlektuere:

* Alessandro Rubini, Writing Linux Devicedrivers (muessts auch als pdf fuer umme geben)
* PC16550D.pdf (Datenblatt vom UART, z.b. bei National Semiconductor)


Gruss
WK

RTSX
11.10.04, 21:32
ich hab zwar momentan keinen besseren lösungsvorschlag, jedoch würde ich gerne wissen was alle 24 stunden für exakt 2 sekunden aktiviert werden soll? ;)

cu

xmarvel
11.10.04, 21:37
Anderer Vorschlag du machst das über den Parallelport da ist es kinderleicht ein kleines C Programm zu schreiben.

MFG
xmarvel

linuxnoob:-)
11.10.04, 21:38
Das wäre egal ob Paralell oder Seriell. Hättste da den n Code ?

xmarvel
11.10.04, 21:55
jo klar hier.
Ist aber ne Dauerschleife drin ! Also wenn du abrechen willst habe ich dir schon hinter der while Schleife die nötigen Befehle hingeschrieben.
Und das Programm braucht root access da es auf dem Parallelport zugreift oder du veränderst die Berechtigungen des Parallelportes



#include <stdio.h>
#include <unistd.h>
#include <asm/io.h>

#define BASEPORT 0x378 /* lp1 */

int main()
{
int i=0;
/* Get access to the ports */
if (ioperm(BASEPORT, 3, 1)) {perror("ioperm"); exit(1);}

/* Set the data signals (D0-7) of the port to all low (0) */
outb(0, BASEPORT);

while (i==1)
{
/* Set signal to high */
outb(0x01, BASEPORT);

/* Sleep for a while (2s) */
sleep(2);

/* Set the data signals (D0-7) of the port to all low (0) */
outb(0, BASEPORT);
}
/* We don't need the ports anymore */
if (ioperm(BASEPORT, 3, 0)) {perror("ioperm"); exit(1);}

exit(0);
}


MFG
xmarvel

linuxnoob:-)
11.10.04, 21:57
OK
genau das was ich gesucht habe :D
thx

tell
15.10.04, 08:55
Evtl. gibt es hier wohl auch eine Python Library, wo man den Port auf einer etwas "höheren" Ebene als in C ansprechen kann. Nichts gegen C, aber ich kann's halt auch nicht.

http://pyserial.sourceforge.net/

MHage
15.10.04, 12:38
Vielleicht hilft dir ja mein Anhang weiter...




/* Uebersetzen mit: gcc -O2 -o led-demo led-demo.c */
/* */
/************************************************** *************************/

//### Abschnitt 1
#include <stdio.h>
#include <string.h>
#include <asm/io.h>

#define D_LPT1_DATA 0x378
#define D_LPT2_DATA 0x278
#define PAR_CTRL_EPP 0x20

//### Abschnitt 2
int main( int argc, char *argv[] )
{
int I_port;
char *pC_port;

if ( argc != 2 ) {
printf( "\nusage: %s <LPT1|LPT2>\n\n", argv[0] );
exit( 1 );
}

pC_port = argv[1];

if ( strncmp( pC_port, "LPT2", 4 ) == 0 ) {
I_port = D_LPT2_DATA;
} else {
I_port = D_LPT1_DATA;
}

//### Abschnitt 3
if ( ioperm( I_port, 3, 1) != 0 ) { /* get IO/perm */
perror( "ERROR: can't open LPT device for read/write" );
return(-1);
}
/* LPT auf AUSGANG stellen */
outb( inb(I_port+2) & ~PAR_CTRL_EPP, I_port+2 );

//### Abschnitt 4
printf( "\nStart writing to %s. Press ^C to stop program.\n", pC_port );
while ( 1 == 1 ) {
/* Diese Endlosschleife kann mit ^C abgebrochen werden */
outb( 0x00, I_port );
printf( "." ); fflush( stdout );
sleep( 1 );
outb( 0xff, I_port );
printf( "." ); fflush( stdout );
sleep( 1 );
}

return( 0 );
}

/************************************************** *************************/
/* End of file */
/************************************************** *************************/


Der Widerstand hat 330 Ohm, die LED (Rot 1,8V)


Gruß
MHage

Pinky
16.10.04, 11:04
MHage , der ausschnitt is aus "Steuerungsaufgaben unter Linux lösen" , oder ?
Kämpf mich auch gerade durch das Buch

Gho
16.10.04, 14:48
Ich hab das Buch schon gelesen und kann dir nur empfehlen weiterzukämpfen, das lohnt sich!

Andy1988
17.10.04, 09:36
Ach du Kacke!

Ises wirklich so schwer unter Linux die serielle Schnittstelle anzusteuern?
Ich hab vor nen selbst gebauten Roboter über die serielle Schnittstelle Fernzusteuern. Das ganze Ding wir auf nen paar mit BASIC Programmierten Mikrocontrollern basieren, die halt nur die Steuerungsbefehle umsetzen werden. Und wenn ich das über den Parallelport machen will, muss ich wieder nem Mikrocontroller das Protokoll und den Kam beibringen, wie der Port arbeitet!

Und ich möcht das ganze gern unter Linux machen. Die Controller kann ich mit BASIC zwar auch nur unter Win proggen, aber irgendwann wird das ding auf den avrgcc umgestellt ;)

MHage
18.10.04, 08:14
Moin,

ja ja... ist ein auszug aus dem Buch!



Gruß
MHage