Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

knopjes aan seriele poort in linux

Pagina: 1
Acties:

  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
Ik heb uit de FAQ het schema gemaakt waarmee je 15 knoppen aan je seriele poort kunt hangen. Die opstelling werkt nu succesvol aan mijn mp3 bak, maar wat me nog niet lukt is om events te genereren uit het drukken van knopjes.
Ik heb wel wat software gevonden die de status van de poort bijhoudt, maar die kijken maar 1x per seconde en dat is niet zo handig. Er moet gewoon realtime bijgehouden worden of een knopje ingedrukt is of niet. De 15 knopjes zijn allemaal verschillende combinaties van hoge signalen op pinnen 1,6,8 en 9.
Ik heb me helemaal suf gegoogled naar hoe ik iets met de status van de poort kan doen, maar alleen dingen gevonden over data heen en weer sturen en niet sec de poort status checken en aktie ondernemen.
Heeft iemand hier enig idee hoe dit moet? Dit is voor een MP3 speler en ik wil als ik dit klaar heb een tutorial/howto maken om op internet te zetten.
Shell scripts hebben de voorkeur, omdat je dan lekker makkelijk kunt debuggen en functies toevoegen.

[ Voor 6% gewijzigd door VROEM! op 29-06-2004 12:33 ]

ieeeepppppp :P


  • Biglines
  • Registratie: September 2003
  • Laatst online: 28-02-2011

Biglines

Biglines.nl

ik zou dit ff in software vragen, ik ben zoiets ook aant zoeken, voor delphi (wat een linux variant heeft..) als je het nog vind, laat ff weten

Konica Minolta Dynax 7D | Mijn foto gallery | Biglines.nl


  • frickY
  • Registratie: Juli 2001
  • Laatst online: 24-11 15:02
Jij wilt dus niet pollen, jij wilt een interupt genereren.
Ik ben er zelf helaas ook nog niet achter hoe ik dit kan doen (maar dan op met de lpt)

  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
Ik heb iets gevonden dat redelijk bruikbaar lijkt :)
Je kunt met statserial -d een nummer genereren uit de status van je seriele poort. Als ik nu een scriptje draai dat elke .1s (of .01s) de status uitleest en een commando uitvoert indien het nummer anders is dan het vorige nummer kom ik denk ik een heel eind.
Ik weet alleen niet hoe ik heel snel achter elkaar een commando kan laten loopen. De enige die ik vond (wait en sleep) moeten minstens een seconde wachten, wat natuurlijk veel te lang is als je een knopje gewoon effe aan wil tikken.

ieeeepppppp :P


  • bille
  • Registratie: Mei 2000
  • Laatst online: 20-11 16:38

bille

Don't call me Buff

:) kijk maar eens hoe je de input van een toetsenbord verwerkt, die wordt uiteraard ook niet de hele tijd gepolled als je op input wacht.

Ultra Pilammo 6666Mhz AMD, 4251Mbit/s RAM, Gefors V6666 MegaTurbo, 43" TFS, Ultra 80Gig Firewire netwerkkaart en 5D geluid met 66 speakers in 5 dimensies


  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
bille schreef op 29 juni 2004 @ 15:02:
:) kijk maar eens hoe je de input van een toetsenbord verwerkt, die wordt uiteraard ook niet de hele tijd gepolled als je op input wacht.
Gaat dat niet met een interrupt en data streams? Ik heb namelijk geen data streams, alleen botte hoog/laag signalen. Ik heb me eerlijk gezegd helemaal suf gegoogled en gelezen door allerlei documenten die niet relevant waren voor wat ik zocht, vandaar deze (wellicht domme) vraag voor ik in die materie ga duiken.
Wat wel vereist is is dat het met een shell script gedaan kan.

[ Voor 6% gewijzigd door VROEM! op 29-06-2004 15:08 ]

ieeeepppppp :P


  • Biglines
  • Registratie: September 2003
  • Laatst online: 28-02-2011

Biglines

Biglines.nl

in delphi kan je commandline apps schrijven, die zullen ook wel werken in linux (als je ze met kylix of zoiets compiled) mss dat je daar iets mee kan?

Konica Minolta Dynax 7D | Mijn foto gallery | Biglines.nl


  • Cassettebandje
  • Registratie: Juli 2002
  • Laatst online: 24-11 15:29

Cassettebandje

SA-C90 TDK

je kunt onder linux een progje schrijven waar je inb() en outb() gebruikt
zie voor meer info de Linux I/O port programming mini-HOWTO
mail me anders vanavond even

  • Buffy
  • Registratie: April 2002
  • Laatst online: 26-12-2024

Buffy

Fire bad, Tree pretty

VROEM! schreef op 29 juni 2004 @ 15:07:
[...]


Gaat dat niet met een interrupt en data streams? Ik heb namelijk geen data streams, alleen botte hoog/laag signalen. Ik heb me eerlijk gezegd helemaal suf gegoogled en gelezen door allerlei documenten die niet relevant waren voor wat ik zocht, vandaar deze (wellicht domme) vraag voor ik in die materie ga duiken.
Wat wel vereist is is dat het met een shell script gedaan kan.
UART's kunnen geconfigureerd worden om Modem Status interrupts te geven. Even vlug gekeken in de serial.c van linux en daar staat:

C:
1
2
3
4
5
6
        
       /*
        * Finally, enable interrupts
        */
        info->IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
        serial_outp(info, UART_IER, info->IER); /* enable interrupts */


Waarbij UART_IER_MSI volgens mij voor Modem Status Interrupt staat.
Met de ioctl(fd, TIOCMIWAIT, TIOCM_RNG | TIOCM_CTS | TIOCM_DSR | TIOCM_CD) kan je dan wachten op de interrupt en met de ioctl(fd, TIOCMGET, &serial) kan je dan de waarden van de status line opvragen (zie man tty_ioctl).

Je moet wel even een klein programma'tje maken dat je vanuit een script kan gebruiken.

Disclaimer: nog niet zelf getest :)

That which doesn't kill us, makes us stranger - Trevor (AEon FLux)
When a finger points at the moon, the imbecile looks at the finger (Chinese Proverb)


  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
ik heb een programma genaamd sleepenh gevonden in debian. Een howto had het over een progje "nanosleep" die hetzelfde doet. Ik ga daar eerst even mee proberen, omdat de andere oplossingen hier volgens mij vragen dat er gecompileerd wordt en dat ga ik op die machine nog even niet doen ivm benodigde software en geklooi en ehhh nou ja, ik ben een beetje bash freak :) . Als het bash script werkt ga ik eens kijken of het allemaal naar C overgezet kan.

Okeej....toch maar aan de C :P Als ik dat sleepenh gebruik gaan de MP3-tjes stotteren :) Jammer maar helaas.

[ Voor 21% gewijzigd door VROEM! op 29-06-2004 17:20 ]

ieeeepppppp :P


  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
Cassettebandje schreef op 29 juni 2004 @ 15:51:
je kunt onder linux een progje schrijven waar je inb() en outb() gebruikt
zie voor meer info de Linux I/O port programming mini-HOWTO
mail me anders vanavond even
Wat je je adres? Het staat niet in je profiel.

Ik ben trouwens even door de howto aan het snuffelen, die lijkt ook gewoon met loopjes te werken...Dan kom ik waarschijnlijk van de regen in de drup, tenzij ik het loopen door iets anders dan de CPU kan laten doen :?

Verder: Heeft iemand een link naar hoe keyboard in/output verwerkt wordt?

ieeeepppppp :P


  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
Ik heb de serial programming how-to doorgekeken en de relevante stukken overgenomen, maar ben niet tegen gekomen hoe je zonder loopen een event kunt halen uit de modem bits. Ik heb wel dingen om die bits uit te lezen, daar zul je vast ook aktie uit kunnen ondernemen, maar er moet nog steeds vaak geloopt worden om maar niet zo'n knop-indruk-momentje over te slaan.
Zo'n poort heeft op zich een interrupt, dus daar zou denk ik iets mee moeten kunnen.
Wat ik tot nu toe heb is het volgende:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*Het programma toegang tot de seriele poort geven*/
ioperm(BASEPORT, 1, 1)
#include <stdio.h>   /* Standard input/output definitions */
#include <string.h>  /* String function definitions */
#include <unistd.h>  /* UNIX standard function definitions */
#include <fcntl.h>   /* File control definitions */
#include <errno.h>   /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
                                                                                                  
        /* Trek attributen uit /dev/ttyS0, nog geen idee wat dat precies doet*/
        int ioctl( int fd, int tcgetattr ) ;
        /* Zet pin 4, ofwel Data Terminal Ready hoog*/
         int fd;
         int status;
                                                                                                  
         ioctl(fd, TIOCMGET, &status);
                                                                                                  
         status &= TIOCM_DTR;
                                                                                                  
         ioctl(fd, TIOCMSET, &status);
        /* Verkrijg "modem status bits", deze zet je met de knopjes op de print*/
        /* Hiervoor is wel nodig dat eerst pin 4 op hoog gezet is*/
        int fd;
        int status;
                                                                                                  
        ioctl(fd, TIOCMGET, &status)

Hiermee wordt dus eerst toegang verkregen tot de poort (dit programma wordt straks door init automatisch bij startup geladen en draait dus effectief als root user)
Dan wordt DTR (pin 4) op hoog gezet en daarmee de print gevoed.
Vervolgens worden de status bits uit gelezen.
Waar ik nu naar zoek is hoe je zonder continue hoogfrequent pollen kortdurende veranderingen waar kunt nemen in de poort.

ieeeepppppp :P


  • Buffy
  • Registratie: April 2002
  • Laatst online: 26-12-2024

Buffy

Fire bad, Tree pretty

Ik heb m.b.v. van de modemstat source het volgende in elkaar gezet. Er zit wel een loop in alleen gebruik ik i.p.v. sleep() de ioctl TIOCMIWAIT die op een interrupt wacht.

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>


int main(int argc, char **argv)
{
    int fd;
    int status, button;
    unsigned int serial;

    fd = open(argc == 2 ? argv[1] : "/dev/ttyS0", O_RDONLY|O_NONBLOCK|O_NOCTTY);
    if (fd < 0) {
        perror("Cannot open serial device");
        exit(1);
    }

    while (1) {
        ioctl(fd, TIOCMIWAIT, TIOCM_RNG|TIOCM_CTS|TIOCM_DSR|TIOCM_CD);
        status = ioctl (fd, TIOCMGET, &serial);
        if (status != 0) {
            perror ("TIOCMGET failed");
            continue;
        }
        button = 0;
        if (serial & TIOCM_CD) {
            button |= 1;
        }
        if (serial & TIOCM_DSR) {
            button |= 2;
        }
        if (serial & TIOCM_CTS) {
            button |= 4;
        }
        if (serial & TIOCM_RI) {
            button |= 8;
        }
        if (button) {
            printf("Button %d pressed\n", button);
        }
        else {
            printf("Button released\n");
        }
    }
    return 0;
}


Het nadeel van interrupt "polen" is dat de status lijnen tegelijkertijd omgezet moeten worden om te voorkomen dat er per lijn een interrupt wordt gegenereerd wat dus tot false button press events zou leiden. Met de dip-switch schakelaar waarmee ik deze code heb getest is het me niet gelukt om twee lijnen tegelijkertijd om te zetten. Ik kreeg dus telkens twee button press events waarvan de eerste een verkeerde "knop" aangaf.
Geen flauw idee hoe nauw dit luistert en of bij impuls switches dit ook optreed.

[ Voor 12% gewijzigd door Buffy op 29-06-2004 23:47 . Reden: tijpos + bugje ]

That which doesn't kill us, makes us stranger - Trevor (AEon FLux)
When a finger points at the moon, the imbecile looks at the finger (Chinese Proverb)


  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
De schakeling die ik heb is een switch en die is dan met een of meerdere lijnen tegelijk verbonden. Maw na de switch wordt het draadje gesplitst. Bij meer lijnen tegelijk zitten er diodes in voor de veiligheid. Als je dus een switch omzet zet je dus met 1 keer schakelen signalen op 2/3/4 pinnen tegelijk. Wil het dan wel?

Dit is trouwens het schema:
Afbeeldingslocatie: http://www.tweakers.net/ext/f/26148/full.gif

[ Voor 25% gewijzigd door Verwijderd op 29-06-2004 23:19 ]

ieeeepppppp :P


Verwijderd

Bij meer lijnen tegelijk zitten er diodes in voor de veiligheid
Nee, als matrix-encoder.

Zelfde schema, alternatieve tekenwijze zodat hij wat beter in de GoT-layout past:

Afbeeldingslocatie: http://www.tweakers.net/ext/f/26147/full.gif

Zie ook: [rml][ How-to] Winamp poort control[/rml]

[ Voor 59% gewijzigd door Verwijderd op 29-06-2004 23:18 ]


  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
Hehe, wilde net zelf editten: Nou ja, dan maar zo. Het moge duidelijk zijn dat het de rechter van de 2 is. Misschien kan hij als thumbnail oid in mijn vorige reaktie?
Thank you Euss ;)

[ Voor 6% gewijzigd door VROEM! op 29-06-2004 23:27 ]

ieeeepppppp :P


  • Buffy
  • Registratie: April 2002
  • Laatst online: 26-12-2024

Buffy

Fire bad, Tree pretty

Er zat nog een kleine foutje in mijn code welke ik vergeten was te verwijderen uit de versie die ik postte (status is 0 indien gelukt ipv != 0).
VROEM! schreef op 29 juni 2004 @ 23:01:
De schakeling die ik heb is een switch en die is dan met een of meerdere lijnen tegelijk verbonden. Maw na de switch wordt het draadje gesplitst. Bij meer lijnen tegelijk zitten er diodes in voor de veiligheid. Als je dus een switch omzet zet je dus met 1 keer schakelen signalen op 2/3/4 pinnen tegelijk. Wil het dan wel?
Waarschijnlijk wel, maar meten is weten :)

[ Voor 192% gewijzigd door Buffy op 29-06-2004 23:51 ]

That which doesn't kill us, makes us stranger - Trevor (AEon FLux)
When a finger points at the moon, the imbecile looks at the finger (Chinese Proverb)


  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
Ik heb je code ook even uitgeprobeerd, het geeft bij mij 2 outputs: Eentje bij het indrukken van de knop (om het even welke) en eentje bij het loslaten.
Ziet er als volgt uit:
code:
1
2
3
4
5
6
mp3box:~# ./mp3player
TIOCMGET failed: Success
TIOCMGET failed: Illegal seek
TIOCMGET failed: Illegal seek
TIOCMGET failed: Illegal seek
TIOCMGET failed: Illegal seek

Elke volgende push/release laat een extra melding zien. Alleen de eerste is iets met success, de latere zijn met Illegal seek. Het lijkt niet te boeien welke knop als eerste gedrukt wordt.

ieeeepppppp :P


  • Buffy
  • Registratie: April 2002
  • Laatst online: 26-12-2024

Buffy

Fire bad, Tree pretty

Check mijn vorige post. Dat krijg je als je op twee computers werkt, een om te schrijven, en een andere om te debuggen.

That which doesn't kill us, makes us stranger - Trevor (AEon FLux)
When a finger points at the moon, the imbecile looks at the finger (Chinese Proverb)


  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
Dawns_sister schreef op 29 juni 2004 @ 23:45:
Er zat nog een kleine foutje in mijn code welke ik vergeten was te verwijderen uit de versie die ik postte (status is 0 indien gelukt ipv != 0).

[...]

Waarschijnlijk wel, maar meten is weten :)
Is dat de waarde onderaan bij return 0? Die heb ik al.
--update: Hij stond bij status, nu werkt het wel :)

[ Voor 7% gewijzigd door VROEM! op 30-06-2004 00:04 ]

ieeeepppppp :P


  • Buffy
  • Registratie: April 2002
  • Laatst online: 26-12-2024

Buffy

Fire bad, Tree pretty

Overigens is deze methode ook niet helemaal veilig. Als tussen de return van de TIOCGIWAIT ioctl en het ophalen van de waarden van de status lijnen en vertraging op treed (door bv heavy load), dan kan er intussen een nieuwe interrupt plaats vinden waarna de waarden die hoorde bij de eerste interrupt, verloren gaan.
Dit is alleen te voorkomen door de waarden uit te lezen tijdens het afhandelen van de interrupt maar dan zou je de serial driver moeten aanpassen zodat (een copy van) de TIOCMIWAIT ioctl deze waarde teruggeeft (en tegelijkertijd de delta waarde uit de "Modem Status" register zodat je voor het release event kan bepalen welke button werd gereleased).

Zou opzich niet zo moeilijk zijn (zie functie rs_ioctl in serial.c, heb overigens geen flauw idee hoe je een nieuwe ioctl defineerd) maar je moet wel je kernel patchen.

That which doesn't kill us, makes us stranger - Trevor (AEon FLux)
When a finger points at the moon, the imbecile looks at the finger (Chinese Proverb)


  • VROEM!
  • Registratie: Februari 2000
  • Laatst online: 18-05 16:41

VROEM!

broembroem!

Topicstarter
Het ergste dat kan gebeuren is dat iemand dan het knopje nog eens moet induwen. Ik zie niet zo een twee drie gebeuren dat de uitgelezen waarden een verkeerde knop geven.
Ik ga denk ik eens knopjes zoeken die wat beter kontakt maken dan wat ik nu heb. Van die dingen met een 'klikje' erin oid. De output is soms wel wat raar, wat denk ik komt door half kontakt.
Ik heb voor mijn eigen exemplaar de source een beetje gewijzigd, zodat uit de output of alleen het nummer van de ingedrukte knop komt of het woord "released". Dat verwerkt wat makkelijker in een ander progamma.

Update:
Ik probeer de output van je programma te verwerken in een bash script, maar krijg eigenlijk niets.
die \n zorgt er toch voor dat je een newline aan het eind van elke output krijgt?
Wat ik probeer is het volgende:
code:
1
2
3
for i in `/root/mp3play`
   do echo "$i"
done

Ik kan knopjes duwen wat ik wil, maar geen output.
Ook
code:
1
 ./mp3player > knopjes.txt
leidt tot een leeg bestand.

[ Voor 58% gewijzigd door VROEM! op 30-06-2004 12:31 ]

ieeeepppppp :P


  • chromeeh
  • Registratie: Oktober 2001
  • Laatst online: 13:00

chromeeh

the Gnome

Ik heb een bijna soort gelijk probleem, ik wil een aantal Hex commando's sturen naar de seriele poort (Voor een bonnen printer)
Ik heb echter de hex commando's wel, maar ik moet weten hoe ik het naar het printertje kan sturen....

"Some day, I hope to find the nuggets on a chicken."


Verwijderd

crashoverride,

De volgende code laat zien hoe je naar een LCD aan de serieele poort hex codes stuurt.

/*
*
* http://wildsau.idv.uni-li...rp/Crystalfontz/lcdtest.c
*
* lcdtest.c
*
*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>

char ch;
int fd;
int command = 0xFE;
int clear = 0x01;

int cfontz = 0x11;
int cfontz_1 = 0x00;
int cfontz_2 = 0x01;
int cfontz_3 = 0x02;
int cfontz_4 = 0x03;
int cfontz_pos = 0x00;

int line_0 = 0x80;
int line_1 = 0xC0;
int line_2 = 0x94;
int line_3 = 0xD4;

void die(char *s) {
if (errno) perror(s);
else fprintf(stderr,"%s\n",s);
exit(-1);
}

void lcdtest() {
struct {
char cust_char[10];
char charno;
} seq;
int i,j;

seq.cust_char[0]=25;
seq.charno=128;
for (i=0;i<8;i++) {
seq.cust_char[1]=(char)i;
for(j=0;j<8;j++) seq.cust_char[2+j]=(char)(i+j);
write(fd,(char *)&seq,sizeof(seq));
seq.charno++;
}
write(fd,"\r\nABCDEFGH",10);
pause();
}

int main() {
struct termios termios;

fd=open("/dev/ttyS1",O_WRONLY|O_EXCL);
if (fd==-1) die("open");
if (tcgetattr(fd,&termios)==-1) die("tcgetattr");
cfmakeraw(&termios);
cfsetospeed(&termios,B9600);
if (tcsetattr(fd,TCSANOW,&termios)==-1) die("tcsetattr");
usleep(350000);

write(fd,("%x",&command),1); /* clear display */
write(fd,("%x",&clear),1); /* clear display */
write(fd,("%x",&cfontz),1); /* send cfontz command */
write(fd,("%x",&cfontz_pos),1); /* cursor position 0 */
write(fd,("%x",&cfontz_1),1); /* line 1 */
write(fd,"Line_1",6); /* write Line_1 to display */
ch = getchar(); /* Druk een toets */

write(fd,("%x",&command),1); /* clear display */
write(fd,("%x",&clear),1); /* clear display */
write(fd,("%x",&cfontz),1);
write(fd,("%x",&cfontz_pos),1);
write(fd,("%x",&cfontz_2),1);
write(fd,"Line_2",6);
ch = getchar();

write(fd,("%x",&command),1); /* clear display */
write(fd,("%x",&clear),1); /* clear display */
write(fd,("%x",&cfontz),1);
write(fd,("%x",&cfontz_pos),1);
write(fd,("%x",&cfontz_3),1);
write(fd,"Line_3",6);
ch = getchar();

write(fd,("%x",&command),1); /* clear display*/
write(fd,("%x",&clear),1); /* clear display */
write(fd,("%x",&cfontz),1);
write(fd,("%x",&cfontz_pos),1);
write(fd,("%x",&cfontz_4),1);
write(fd,"Line_4",6);

write(fd,("%x",&command),1); /* clear display */
write(fd,("%x",&clear),1); /* clear display */
write(fd,("%x",&command),1);
write(fd,("%x",&line_0),1);
write(fd,"Line_1",6);

ch = getchar();
write(fd,("%x",&command),1); /* clear display */
write(fd,("%x",&clear),1); /* clear display */
write(fd,("%x",&command),1);
write(fd,("%x",&line_1),1);
write(fd,"Line_2",6);
ch = getchar();
write(fd,("%x",&command),1); /* clear display */
write(fd,("%x",&clear),1); /* clear display */
write(fd,("%x",&command),1);
write(fd,("%x",&line_2),1);
write(fd,"Line_3",6);
ch = getchar();
write(fd,("%x",&command),1); /* clear display */
write(fd,("%x",&clear),1); /* clear display */
write(fd,("%x",&command),1);
write(fd,("%x",&line_3),1);
write(fd,"Line_4",6);
ch = getchar();

/* lcdtest(); */
}
/*
* end of file
*/
Pagina: 1