Forum: PC-Programmierung Programm aus C heraus starten


von Johann K. (john1999)


Lesenswert?

Guten Tag,

ich arbeite grade an einem Projekt, bei dem ich mit dem Raspberry Pi 
Daten über die Wiegand-Schnittstelle auslese. Dafür nutze ich diesen 
C-Code:
http://irishjesus.wordpress.com/2013/12/02/goodbye-dryspell-hello-raspberry-pi-wiegand-rfid/. 
Das funktioniert auch so weit wie es soll. Ich bekomme z.B. so eine 
Zeile im Terminal:
1
Read 26 bits (4 bytes): 612***** : 0*****010010******010000******10
Die Sternchen repräsentieren Zahlen, sind hier aber wegen des 
Verwendungszwecks zensiert.

Nun möchte ich, dass geprüft wird, ob diese Zeichenkette in einer Datei 
(der "Datenbank") steht. Da ich leider ÜBERHAUPT keine Ahnung von C 
habe, möchte ich diese Prüfung in ein Python-Script auslagern. Ich muss 
jetzt diese Zeichenfolge an das Python-Script übergeben.
Die Zeichenfolge wird im letzten Abschnitt ausgegeben:
1
void main(void) {
2
    int i;
3
4
    wiegandInit(D0_PIN, D1_PIN);
5
6
    while(1) {
7
        int bitLen = wiegandGetPendingBitCount();
8
        if (bitLen == 0) {
9
            usleep(5000);
10
        } else {
11
            char data[100];
12
            bitLen = wiegandReadData((void *)data, 100);
13
            int bytes = bitLen / 8 + 1;
14
            printf("Read %d bits (%d bytes): ", bitLen, bytes);
15
            for (i = 0; i < bytes; i++)
16
                printf("%02X", (int)data[i]);
17
            printf(" : ");
18
            for (i = 0; i < bytes; i++)
19
                printCharAsBinary(data[i]);
20
            printf("\n");
21
        }
22
    }
23
}

Ich wäre sehr dankbar, wenn jemand eine Idee hätte, wie ich diese 
Zeichenfolge (oder auch nur den letzten Abschnitt) an mein Python-Script 
übergebe. Vergesst bitte nicht, dass ich keine Ahnung von C habe, also 
erkärt es bitte Idiotensicher.

Vielen Dank für jede Hilfe,
Johann

: Verschoben durch Moderator
von andersrum (Gast)


Lesenswert?

Einfacher wäre es wahrscheinlich, wenn du den umgekehrten Weg gehst,
d.h. du verpackst deinen C-Code als "built-in module" in Python.
Auf den kannst du dann relativ einfach durch einen "regulären"
Funktionsaufruf von Python aus zugreifen und musst dich nicht
mit Interprozesskommunikation etc. rumärgern.

Beispiel dazu findet sich hier:
https://docs.python.org/2/extending/extending.html

von Poster (Gast)


Lesenswert?

Mich würde ja interessieren wie man in Wig26 4 Byte bekommen will.
Das erste und das 26. Bit sind ja Prüfbits. Da bleiben ja grade mal 3 
Byte Daten. Recht wenig für eine anständige ZK.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Johann K. schrieb:
> Nun möchte ich, dass geprüft wird, ob diese Zeichenkette in einer Datei
> (der "Datenbank") steht. Da ich leider ÜBERHAUPT keine Ahnung von C
> habe, möchte ich diese Prüfung in ein Python-Script auslagern.

Ein anderes Programm aufzurufen, für jede einzelne Überprüfung, das ist 
... nicht performant.

Liefe das andere Programm dauerhaft, könntest Du über eine geeignete 
Schnittstelle zwischen beiden Teilen kommunizieren (Pipe, Socket, shared 
memory o.ä.).


Ist die "Datei", die "Datenbank" in ihrer Struktur und Art bereits 
festgelegt oder ist das ein Konstrukt, das noch nicht finalisiert ist?

Wenn letzteres der Fall ist, bietet sich eine kleine Datenbank-Engine 
an, die es in Form von SQLite als direkt integrierbaren C-Code gibt. Und 
statt in Deinem Python-Skript Dateioperationen zu machen, kannst Du mit 
den recht leicht verständlichen API-Aufrufen von SQLite direkte 
Datenbankzugriffe durchführen.

Als "embedded"-Datenbank wird SQLite ziemlich häufig eingesetzt, auch 
auf Geräten mit einer dem Pi vergleichbaren Rechenleistung -- nämlich 
u.a. in Mobiltelephonen, egal ob mit iOS oder Android.

von Julian W. (julian-w) Benutzerseite


Lesenswert?

falsches Forum?

> Hier könnt ihr eure Projekte, Schaltungen oder Codeschnipsel vorstellen
> und diskutieren. Bitte hier keine Fragen posten!

von Johann K. (john1999)


Lesenswert?

Erstmal danke für alle eure Antworten. Es ist über schon, hier so schell 
so kompetente Hilfe zu erhalten. :)


andersrum schrieb:
> Einfacher wäre es wahrscheinlich, wenn du den umgekehrten Weg gehst,
> d.h. du verpackst deinen C-Code als "built-in module" in Python.

Das hat mich auf eine etwas andere Idee gebracht. Sollte das nicht 
funktionieren, schaue ich mir deine Idee noch mal genauer an.


Poster schrieb:
> Das erste und das 26. Bit sind ja Prüfbits.

Richtig.

Poster schrieb:
> Da bleiben ja grade mal 3
> Byte Daten. Recht wenig für eine anständige ZK.

Ja... du hast nicht ganz Unrecht. Es mag nicht perfekt sein, aber für 
meine Zwecke ausreichend. Ich werde auch mal rum experimentieren, ob ich 
den Reader mit Wiegand 34 zum laufen kriege.


Rufus Τ. Firefly schrieb:
> Liefe das andere Programm dauerhaft, könntest Du über eine geeignete
> Schnittstelle zwischen beiden Teilen kommunizieren (Pipe, Socket, shared
> memory o.ä.).

Könntest du mir bitte ein Codebeispiel geben? Das würde mich freuen.

Rufus Τ. Firefly schrieb:
> Ist die "Datei", die "Datenbank" in ihrer Struktur und Art bereits
> festgelegt oder ist das ein Konstrukt, das noch nicht finalisiert ist?

Die Datenbank ist momentan eine simple Textdatei, in der in jeder Zeile 
eine ID steht. Es werden am Ende um die 10 IDs werden, also halte ich 
das für die einfachste Art. Ist der Zugriff auf SQL den schneller?


Julian W. schrieb:
> falsches Forum?

Ja das hat du wohl recht. Dafür entschuldige ich mich. Bitte in das 
richtige Forum verschieben. Danke.


Erstmal ein großes Dankeschön an alle, ich hoffe auch weiter auf 
Mithilfe. Grade kann ich leider nichts testen, das mach ich heute aber 
noch. ;)

Gruß,
Johann

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann K. schrieb:
> Bitte in das richtige Forum verschieben.

Done.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Johann K. schrieb:
> Die Datenbank ist momentan eine simple Textdatei, in der in jeder Zeile
> eine ID steht. Es werden am Ende um die 10 IDs werden, also halte ich
> das für die einfachste Art. Ist der Zugriff auf SQL den schneller?

Den_N_. Mit zwei N.

Bei 10 Einträgen ist SQL natürlich nicht schneller. Bei ein paar hundert 
oder ein paar tausend bestehen Chancen dafür, bzw. hängt das davon ab, 
wie Du die Dateizugriffe und die Organisation der IDs handhabst.

von Johann K. (john1999)


Lesenswert?

Hi,

ich habe es geschafft! Nach Stundenlangem rumprobieren und googln bin 
ich durch Zufall auf die richtige Lösung gekommen. Ich habe jetzt das 
hier in der wiegand.c im Header hinzugefügt:
1
char combytes[100];
2
char command[100];

...das hier ist jetzt die main-Klasse (heißt es in C auch "Klasse"?):
1
void main(void) {
2
    int i;
3
4
    wiegandInit(D0_PIN, D1_PIN);
5
6
    while(1) {
7
        int bitLen = wiegandGetPendingBitCount();
8
        if (bitLen == 0) {
9
            usleep(5000);
10
        } else {
11
            char data[100];
12
            bitLen = wiegandReadData((void *)data, 100);
13
            int bytes = bitLen / 8 + 1;
14
            printf("Read %d bits (%d bytes): ", bitLen, bytes);
15
            sprintf(combytes, "");
16
            for (i = 0; i < bytes; i++)
17
                sprintf(combytes, "%s%02X", combytes, (int)data[i]);
18
            printf("%s", combytes);
19
            sprintf(command, "/home/pi/wiegand/check.py %s &", combytes);
20
            system(command);
21
            printf(" : ");
22
            for (i = 0; i < bytes; i++)
23
                printCharAsBinary(data[i]);
24
            printf("\n");
25
        }
26
    }
27
}

...und so sieht mein Python-Script aus:
1
#!/usr/bin/python
2
import RPi.GPIO as GPIO
3
import sys
4
import time
5
6
l = len(sys.argv)-1
7
GPIO.setmode(GPIO.BOARD)
8
GPIO.setwarnings(False)
9
GPIO.setup(13, GPIO.OUT)
10
11
db = open("/home/pi/wiegand/database", "r")
12
for line in db:
13
 if sys.argv[1] == line.rstrip():
14
  GPIO.output(13, GPIO.HIGH)
15
  time.sleep(3)
16
  GPIO.output(13, GPIO.LOW)
17
db.close()

Dass nur mal so für die Nachwelt, falls das jemand nachmachen möchte. ;)
Die GPIOs werde ich aber von einem anderen Script aus steuern lassen, 
das wird ein "größeres" Power-Management. Zum testen ist das aber gut.
Die Datei "database" enthält in jeder Zeile eine ID im Format 8*4***CC*3 
(Sternchen sind Zahlen oder große Buchstaben).

Ich bin zufrieden mit dieser Lösung und danke noch mal allen, die mich 
unterstützt haben!

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Johann K. schrieb:

> Dass nur mal so für die Nachwelt, falls das jemand nachmachen möchte. ;)

Bitte nicht.
Lernt lieber C. So schwer ist das nicht. So eine Lösung, ein Programm zu 
zerpflücken ist hier keine gute Idee. Das kostet Performance Ende nie 
und letzen Endes steht ihr dann mit einer Langsamlösung da, die nur aus 
dem einen Grund langsam ist, weil ihr etwas machen wollt, was ihr nie 
gelernt habt.

Eine C Lösung zu
1
db = open("/home/pi/wiegand/database", "r")
2
for line in db:
3
 if sys.argv[1] == line.rstrip():
4
  GPIO.output(13, GPIO.HIGH)
5
  time.sleep(3)
6
  GPIO.output(13, GPIO.LOW)
7
db.close()

sieht im Grunda auch nicht viel anders aus. Die Syntax ist ein wenig 
anders und die Funktionsaufrufe heißen ein wenig anders. Aber alles halb 
so wild.

von jetztschnallichs (Gast)


Lesenswert?

Langsam wird mir klar, warum Quad-Core-CPUs im Mobiltelefon benötigt 
werden. ;-)

von Johann K. (john1999)


Lesenswert?

Langsam? Davon merke ich nichts. Wie soll sich das den bitte äußern?

Und richtig, ich kann kein C. Und ich werde es nicht nur für dieses 
Projekt lernen. Auch, weil ich dafür momentan einfach keine Zeit habe.

Doch jedem seine Meinung, ich weil da ja auch keinem reinreden. Und wer 
einmal C kann, dem wird das sicherlich auch später noch mal etwas 
nutzen.

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.