- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 10 von 33

Thema: C/C++ lib für Sonderzeichenkombinationen (F1-12, +shift, alt, ctrl) als Scancode

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    HaWe
    Gast
    printf("\n") macht in C standardmäßig ein LF und ein CR, sowohl auf Arduinos als auch auf Raspi-LX-Terminals. Das ist der Standard.
    Das ist aber nicht der Punkt, und deinen Historienwissenserguss in allen Ehren - es ist OT und hilft nicht bei der Problemlösung, denn es sind Scancodes gefragt, die man einfach aus einem C Programm heraus zur Sondertastenerkennung benutzen kann.
    Selbst da aber versagt ncurses, unabhängig von dem Terminal-Anzeige-Problem, denn es erkennt ja kaum welche in Kombi mit den modifiern, und ich brauche und will auch gar kein extra-Terminal.

    Auch geht es ja gar nicht um stdout, sondern stdin, denn daraus liest ja auch mein getchar (stdio.h) und mein tcgetattr aus termio.h.


    wie nützt man nun also, alternativ, z.B.
    https://www.kernel.org/doc/Documentation/input/
    oder auch jeden anderen gangbaren und praktikablen Weg?

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    54
    Beiträge
    765
    Hallo,

    man kann alle Tasten in C abfragen. Du kannst sogar auf die Numlock-Taste im Programm reagieren.

    Anbei ein auf das Wesentliche reduzierte Testprogramm:
    Code:
    // Compile with: GCC -o /var/scripte/tastaturtest /var/scripte/tastaturtest.c  -L/usr/local/lib -lpthread
    //nice -1 /var/scripte/tastaturtest < /dev/input/event0 &
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdint.h>
    #include <sys/sysinfo.h>
    #include <time.h>
    #include <linux/input.h>
    #include <pthread.h>
    
    int ziffer=0;
    int beenden=2;
    int zeit=0;
    int shiftl=0;
    int shiftr=0;
    int strgl=0;
    int strgr=0;
    int capsl=0;
    
    
    unsigned char runterfahren(){
        system("halt");
    }
    
    unsigned char zahlentaste()
    {
        printf("Zahlentaste: %d\n", ziffer);
    }
    
    unsigned char tnull()
    {
        ziffer=0;
        zahlentaste();
    }
    
    unsigned char teins()
    {
        ziffer=1;
        zahlentaste();
        
    }
    
    unsigned char tzwei()
    {
        ziffer=2;
        zahlentaste();
        
    }
    unsigned char tdrei()
    {
        ziffer=3;
        zahlentaste();
        
    }
    unsigned char tvier()
    {
        ziffer=4;
        zahlentaste();
        
    }
    unsigned char tfuenf()
    {
        ziffer=5;
        zahlentaste();
        
    }
    unsigned char tsechs()
    {
        ziffer=6;
        zahlentaste();
        
    }
    unsigned char tsieben()
    {
        ziffer=7;
        zahlentaste();
        
    }
    unsigned char tacht()
    {
        ziffer=8;
        zahlentaste();
        
    }
    unsigned char tneun()
    {
        ziffer=9;
        zahlentaste();
        
    }
    unsigned char tdel()
    {
        printf("Delete\n");
    }
    
    unsigned char tnum()
    {
    printf("Numlock\n");    
    }
    
    unsigned char tenter()
    {    printf("Enter\n");
        
    }
    unsigned char tplus()
    {
    printf("Plus\n");    
    }
    unsigned char tminus()
    {
    printf("Minus\n");
    }
    unsigned char tmal()
    {
    printf("Mal\n");    
    }
    
    unsigned char tgeteilt()
    {
        printf("Geteilt\n");    
    }
    
    unsigned char tbs()
    {
        printf("Backspace\n");
    }
    
    unsigned char tq()
    {
        beenden=1;
    }
    
    unsigned char status()
    {
        printf("SHIFTL: %d, SHIFTR: %d, STRGL: %d, STRGR: %d\n",shiftl,shiftr,strgl,strgr);
    }
    
    unsigned char tf1()
    {
        if(shiftl>=1 || shiftr>=1){
            printf("SHIFT + F1\n");
        }else{
            printf("F1\n");
        }
    }
    
    void tastatur(void *name)
    {
        struct input_event event;
        while ((read(0, &event, sizeof(event)) > 0) && (beenden==2) ) {
            if (event.type != EV_KEY) continue;
    //        if (event.value != EV_KEY) continue; //Nur Tastendrücke erkennen, kein Loslassen. 0=losgelassen, 1=gedrückt, 2=Wiederholung(lang gedrückt)
        printf("Typ: %d; Wert: %d; Code: %d\n",event.type,event.value,event.code);
    
            switch (event.code) {
                case 42: shiftl=event.value; break;
                case 54: shiftr=event.value; break;
                case 29: strgl=event.value; break;
                case 97: strgr=event.value; break;
                case 16: tq(); break; //q
                case 82: tnull(); break; //0
                case 79: teins(); break; //1
                case 80: tzwei(); break; //2
                case 81: tdrei(); break; //3
                case 75: tvier(); break; //4
                case 76: tfuenf(); break; //5
                case 77: tsechs(); break; //6
                case 71: tsieben(); break; //7
                case 72: tacht(); break; //8
                case 73: tneun(); break; //9
                case 83: tdel(); break; //DEL
                case 96: tenter(); break; //ENTER
                case 78: tplus(); break; //+
                case 74: tminus(); break; //-
                case 55: tmal(); break; //*
                case 98: tgeteilt(); break; ///
                case 14: tbs(); break; //Backspace
                case 69: tnum(); break; //NumLock
                case 59: tf1(); break; //F1
                case 31: status(); break; //s
            }
        }
        beenden=0;
        pthread_exit((void *) 0);
    }
    
    int main(int argc, char** argv)
    {
        pthread_t t1;
        if(pthread_create(&t1, NULL, (void *)&tastatur, (void *)"Tastatur") != 0)
        {
          fprintf(stderr, "Fehler bei Tastatur......\n");
          exit(0);
        }  
        
        while (beenden > 0)
            {     sleep(1);
                zeit++;
                if (zeit==30)
                {
                    zeit=0;
                    printf("Wieder 30 Sekunden um.\n");
                }
        } 
        usleep(50);
        printf("***********Ende************\n");
        return 0;
    }
    Dieses Programm zeigt die Codes an, welche an einer AM RASPI ANGESCHLOSSENEN Tastatur gedrückten / losgelassenen Taste entspricht. Ein Beispiel mit F1 ohne und mit SHIFT habe ich eingefügt.

    Das Programm wird mit q beendet. Als Startparameter muss das Device der Tastatur angegeben werden. Bei nur einer Tastatur reicht die zweite Zeile im Programmkopf zum Starten. Den Pfad (auch den zum zum kompilieren) natürlich anpassen.
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  3. #3
    HaWe
    Gast
    hallo,
    super, das sieht ja sehr beeindruckend aus!
    ich verwende Geany zum Kompilieren und habe da auch die compile- und Build- Parameter fest eingestellt.
    Mit make etc. stehe ich auf dem kriegsfuß...

    Ich verwende g++, nicht gcc, dürfte aber sicher kein Problem sein.

    -pthread
    hab ich schon drin

    -L/usr/local/lib
    muss sicher noch dazu

    was sonst noch? den rest verstehe ich nämlich nicht.



    bekomme sehr viele Fehlermeldungen

    printf not declared => #include <stdio.h> eingefügt.
    system not declared => ???
    exit not declared => ???

    int main(int argc, char** argv) geändert in
    int main()

    die Zeile mit if( pthread_create....) hat einen dicken Fehler
    invalid conversion from void* to void*(*)(void*)
    if kann man sicher doch ganz weglassen!!
    Ich initialisiere immer nur per
    pthread_create(&threadID, NULL, threadName, NULL);


    Startparameter kann ich nicht eingeben!
    Geändert von HaWe (05.04.2016 um 19:36 Uhr)

  4. #4
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    54
    Beiträge
    765
    Hallo,

    die Includes könnten mehr sein als notwendig sind. Das frisst aber kein Brot und in meinem Programm, wo ich das meiste rauskopiert habe, brauche ich diese. Geany sagt mir leider gar nichts. Ich kompiliere mit gcc. Der Aufruf dafür steht ja in der ersten Zeile.

    Dann kommen die Variablen für die 'Sondertasten'. Wobei ich für Capslock kein Beispiel reinprogrammiert habe.

    Je nach Tastencode (Scancode?) wird die dazugehörige Sub aufgerufen. Da braucht man natürlich nur die Codes der Tasten abfragen, die tatsächlich genutzt werden. Wird freie Texteingabe unterstützt, muss man das nachbauen.

    Wird q gedrückt, wird zuerst der zweite Thread beendet und dann 50 Mikrosekunden später das Hauptprogramm. Schmiert das ab, dann bleibt der Thread am Leben. Ist aber nicht tragisch. GCC beendet den beim nächsten kompilieren automatisch

    Die 30 Sekunden Wartezeit sollen nur demonstrieren, dass das Hauptprogramm weiterläuft, auch wenn keine Taste gedrückt wird.

    Ansonsten wird hhalt bei jedem Tastendruck die zugehörige Sub aufgerufen. Das Hauptprogramm und der zweite Thread teilen sich die globalen Variablen.


    Edit:
    Bei mir kompiliert er fehlerfrei. Hast Du gcc? Ich starte mal den Raspi und schaue, welche Pakete so drauf sind.
    Geändert von peterfido (05.04.2016 um 19:58 Uhr)
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  5. #5
    HaWe
    Gast
    nein, g++
    und Startparameter kann ich nicht eingeben!
    das Device der Tastatur kenne ich nicht

    ich kann nicht ohne Geany compilieren. Kommandozeile kann ich nicht.

    die includes stören mich nicht, aber bei dir fehlte stdio.h !

    und wohl noch ein wenig mehr wegen system und exit

    hier ist der Link zu meinem kompletten Programm, wo alles mit rein muss, nur zur Info:
    http://www.mindstormsforum.de/viewto...p=69043#p69089

    Geany-Build-Parameter:

    g++ -Wall -pthread -I/opt/vc/include -I/opt/vc/include/interface/vmcs_host/linux -I/opt/vc/include/interface/vcos/pthreads -o "%e" "%f" -lshapes -L/opt/vc/lib -lOpenVG -lEGL -lwiringPi -lrt
    Geändert von HaWe (05.04.2016 um 19:46 Uhr)

  6. #6
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    18.05.2007
    Ort
    Berlin
    Alter
    54
    Beiträge
    765
    Hallo,

    stdio.h ist doch drin. Das erste Include gleich. (Siehe Post #15). Ob g++ auch C-Code kompilieren kann, weiß ich nicht. Ich progge nur in C (BASH / PHP mal außen vor) und alles per Kommandozeile. Wie gesagt, Geany habe ich nicht. Die installierten Pakete liste ich doch nicht auf. Es sind 846 Pakete.

    Ich hänge mal meine fertig compilierte Datei hier an. Evtl. hilft sie Dir die Scancodes auszulesen. Die Datei ist unter Windows gepackt und muss auf den Raspi. Die Rechte auf 755 setzen und starten.

    Wenn Du sie, wie im Quellcodekopf, mit nice startest, dann läuft sie mit geringerer Priorität. Das & am Ende bedeutet, dass das Programm im Hintergrund ausgeführt wird und die Konsole für andere Dinge genutzt werden kann.

    Mehr kann ich da leider nicht für Dich tun. Die nächste Zeit bin ich erstmal hauptsächlich offline und komme auch nicht zum basteln.

    Edit: Bei Dir steht zwar -pthread im Parameter, bei mir jedoch -lpthread. Also scheint es da Unterschiede zu geben. Probiere mal nur meinen Code zu compilieren, ohne ihn irgendwo einzubauen.

    Edit 2:
    int main(int argc, char** argv) ist für die angegebenen Parameter wichtig. Evtl. will Geany für die Fensteroberfläche kompilieren. Schau mal, ob man da auch ein Konsolenprogramm als Typ auswählen kann.
    Angehängte Dateien Angehängte Dateien
    Geändert von peterfido (05.04.2016 um 20:03 Uhr)
    Wenn das Herz involviert ist, steht die Logik außen vor! \/

  7. #7
    HaWe
    Gast
    war ein copy + paste Fehler mit den #includes.

    Leider verstehe ich deinen Code nicht, es muss in meinen Task reinpassen, der läuft mit mittlerer prio, und darum geht es ja letztendlich:


    Code:
    void* thread1Go(void *)   // medium priority:  keyboard + heartbeat monitoring
    {
       int   c;  // keyboard key
       
       while(_TASKS_ACTIVE_) {         
          c=0;
          if (kbhit())    {           // <<<<<<<<<<<<<<<<<<
              c = getchar();          
              
              if( c==27 ) {           // ESC to quit program
                   printf("\n\n ESC pressed - program terminated by user \n");
                   _TASKS_ACTIVE_=0;  // semaphore to stop all tasks
                   printf("\n wait for tasks to join main()... \n\n");
                   return NULL;
              }
              else 
              if( ) { } //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< dein Code
          }
         
         //... ***SNIP***
    
         delay(50);
       }         
       return NULL;
    }
    Das auslesen müsste darin laufen, und die Art der gedrückten Taste könnte genau wie meine Meldungen bei ESC (analog per printf) in der Konsole angezeigt werden.

    Konsolenprogramm soll nicht sein, ist meines auch nicht!
    http://www.mindstormsforum.de/viewto...p=69043#p69089


    Code:
    int main() {
        char  sbuf[128];
        int err;
     
        // **SNIP**
       
        pthread_t thread0, thread1, thread2, thread3, thread4, thread5;
        struct  sched_param  param;
    
        pthread_create(&thread0, NULL, thread0Go, NULL);     // lowest priority task: screen output
        param.sched_priority = 10;
        pthread_setschedparam(thread0, SCHED_RR, &param);
       
        pthread_create(&thread1, NULL, thread1Go, NULL);     // low priority: keyboard monitoring (stop program)
        param.sched_priority = 20;
        pthread_setschedparam(thread1, SCHED_RR, &param);
       
        pthread_create(&thread2, NULL, thread2Go, NULL);     // medium  priority: motor control
        param.sched_priority = 40;
        pthread_setschedparam(thread2, SCHED_RR, &param);
       
        pthread_create(&thread3, NULL, thread3Go, NULL);     // highest priority: encoder reading     
        param.sched_priority = 80;
        pthread_setschedparam(thread3, SCHED_FIFO, &param);
       
        pthread_create(&thread4, NULL, thread4Go, NULL);     // medium priority:  UART comm   <<< test !!
        param.sched_priority = 40;
        pthread_setschedparam(thread4, SCHED_FIFO, &param);
       
        pthread_create(&thread5, NULL, thread5Go, NULL);     // medium priority: navigation
        param.sched_priority = 40;
        pthread_setschedparam(thread1, SCHED_FIFO, &param);
       
       //... **SNIP**
    
    }
    Geändert von HaWe (05.04.2016 um 20:41 Uhr)

Ähnliche Themen

  1. Antworten: 10
    Letzter Beitrag: 01.11.2017, 12:53
  2. Neue Atmega "A" und "PA" Typen
    Von AVR168 im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 2
    Letzter Beitrag: 07.05.2012, 16:47
  3. Antworten: 2
    Letzter Beitrag: 15.06.2011, 21:18
  4. "Lichtverfolgung" in "TV-Remote" einbaue
    Von fabqu im Forum Robby RP6
    Antworten: 3
    Letzter Beitrag: 04.01.2011, 10:14
  5. "Soft-Reset?" und "Finger-Interrupt?"
    Von trapperjohn im Forum Asuro
    Antworten: 8
    Letzter Beitrag: 10.06.2008, 23:02

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

fchao-Sinus-Wechselrichter AliExpress