Gast LinTec Geschrieben April 21, 2014 at 17:24 Geschrieben April 21, 2014 at 17:24 Moin zusammen, ich habe folgendes Problem. Mein Motion Detektor soll bei einer Bewegung eine E-Mail versenden. Das Programm soll so lange laufen, bis getchar() einen Wert erhält. Das Problem aber ist, dass das Programm automatisch endet. Ich habe es schon mit fflush(stdin) versucht, aber es scheint nichts zu bringen. Vielleicht fällt einem von euch was auf, oder kann mir helfen. Hier der Code: // // main.c // Motion_Detector_V01 #include <stdio.h> #include <unistd.h> #include "brick_master.h" #include "bricklet_industrial_quad_relay.h" #include "ip_connection.h" #include "bricklet_motion_detector.h" #include "bricklet_piezo_speaker.h" #include <string.h> #include <errno.h> //Globale Var IPConnection ipcon; //Sendmail functionality for detected motion void sendmail(const char *to, const char *from, const char *subject, const char *message) { FILE *mailpipe = popen("/usr/sbin/sendmail -t", "w"); if (mailpipe != NULL) { fprintf(mailpipe, "%s", to); fprintf(mailpipe, "%s", from); fprintf(mailpipe, "%s", subject); fwrite(message, 1, strlen(message), mailpipe); pclose(mailpipe); } else { perror("Failed to invoke sendmail"); } fflush(stdin); } // Callback function for detected motion void cb_motion_detected(int argc, char** argv) { PiezoSpeaker ps; IndustrialQuadRelay iqr; industrial_quad_relay_create(&iqr, "g3n", &ipcon); piezo_speaker_create(&ps, "iLP", &ipcon); piezo_speaker_morse_code(&ps, "----", 1500); printf("Motion Detected\n"); sendmail("To: xxxxx@xx.de\n", "From: xxxxx@xx.com\n", "Subject: Test Mail\n\n","Test Nachricht"); for(int i = 4; i >= 0; i--) { industrial_quad_relay_set_monoflop(&iqr, 1, 1, 1500); sleep(2); } fflush(stdin); } int main(int argc, const char * argv[]) { MotionDetector md; ipcon_create(&ipcon); motion_detector_create(&md, "kg6", &ipcon); //Check connection if(ipcon_connect(&ipcon, "localhost", 4223) < 0) { fprintf(stderr, "Could not connect to brickd\n"); exit(1); } // Callback function MD motion_detector_register_callback(&md, MOTION_DETECTOR_CALLBACK_MOTION_DETECTED, (void *)cb_motion_detected, NULL); printf("Press any key to exit\n"); getchar(); //ipcon disconnect ipcon_destroy(&ipcon); } Zitieren
borg Geschrieben April 22, 2014 at 16:16 Geschrieben April 22, 2014 at 16:16 Ich kann da auf die Schnelle nichts finden was böse aussieht. Was genau passiert denn wenn sich das Programm beendet? Kannst du vor dem ipcon_destroy mal ein printf machen um zu sehen ob das getchar aus irgendwelchen Gründen ausgelöst wird? Wenn sich das Programm nicht normal beendet, gibt es einen Segfault oder irgendeine andere Fehlermeldung? Zitieren
remotecontrol Geschrieben April 22, 2014 at 16:53 Geschrieben April 22, 2014 at 16:53 Der "cb_motion_detected" hat auf jeden Fall die falsche Signatur (sollte nur einen user_data-Parameter haben). Außerdem registriert der Callback (falls er gerufen wird) Objekte, die nicht wieder de-registriert werden (relay + piezo-Speaker). Wie weit kommt das Programm denn? Kommt es bis zum printf("Motion Detected\n");? Zitieren
Gast LinTec Geschrieben April 22, 2014 at 18:30 Geschrieben April 22, 2014 at 18:30 @borg: Folgendes wird mir zurückgeliefert: Code: printf("Press any key to exit\n"); int c; c = getchar(); putchar©; Ergebnis = \377 ==> Das ist im Stream @remotecontrol Das Programm läuft 1 mal sauber durch. Nur wartet er nicht auf das getchar(); Was ich bis jetzt rausgefunden habe ist, dass es in der sendmail Funktion liegen muss. Wenn ich den sendmail Aufruf im Callback auskommentiere, dann funktioniert es. Ich war jetzt am überlegen, ob ich folgendes machen soll: while((c = getchar()) != EOF); Dann sollte er eigentlich auch die Tastenkombination warten, um das Programm zu beenden. NACHTRAG: Ich habe es jetzt mal mit "while((c = getchar()) != EOF);" probiert und das selbe Problem :-( Das Programm endet nach dem ersten Durchlauf. Zitieren
remotecontrol Geschrieben April 22, 2014 at 19:41 Geschrieben April 22, 2014 at 19:41 Wie ist der Wert \377 gemeint: ist das der Output des putchar? Das wäre nämlich eine -1 oder EOF (d.h. c==EOF). Sieht so aus, als würde der popen / close auch stdin schließen. Evtl. ist es hier besser, die Anwendung über einen signal handler zu beenden, der auf ctrl-c oder sigterm reagiert. Nachtrag: fflush auf stdin ist keine gute Idee: das ist eigentlich nur für zum Schreiben geöffnete Steams zulässig. Zitieren
Gast LinTec Geschrieben April 22, 2014 at 23:04 Geschrieben April 22, 2014 at 23:04 @remotecontrol Ich schau mir das mal an. Vielleicht gibt es da eine Möglichkeit. Ich habe das Problem jetzt etwas kompliziert gelöst. Ich habe eine do while Schleife in der main Funktion eingebaut, die eine Globale Variable (ex) prüft. Diese Variable wird am Ende von sendmail auf 1 gesetzt. In der while Bedingung wird geprüft, ob ex == 1 ist. Das ist immer der Fall und somit habe ich eine Endlosschleife. Um diese zu beenden, habe ich eine IF Schleife benutzt, die die Variable code abfragt. Wenn code == 1, dann nutze GOTO und spring aus der WHILE Schleife und beende das Programm. Hier der Source Code: #include <stdio.h> #include <unistd.h> #include "brick_master.h" #include "bricklet_industrial_quad_relay.h" #include "ip_connection.h" #include "bricklet_motion_detector.h" #include "bricklet_piezo_speaker.h" #include <string.h> #include <errno.h> //Globale Variablen IPConnection ipcon; int ex = 0; //Sendmail functionality for detected motion int sendmail(const char *to, const char *from, const char *subject, const char *message) { FILE *mailpipe = popen("/usr/sbin/sendmail -t", "w"); if (mailpipe != NULL) { fprintf(mailpipe, "%s", to); fprintf(mailpipe, "%s", from); fprintf(mailpipe, "%s", subject); fwrite(message, 1, strlen(message), mailpipe); pclose(mailpipe); } else { perror("Failed to invoke sendmail"); } printf("E-Mail wurde versendet!\n"); ex = 1; return ex; } // Callback function for detected motion void cb_motion_detected(void *user_data) { (void)user_data; PiezoSpeaker ps; IndustrialQuadRelay iqr; industrial_quad_relay_create(&iqr, "g3n", &ipcon); piezo_speaker_create(&ps, "iLP", &ipcon); piezo_speaker_morse_code(&ps, "----", 1500); printf("\nMotion Detected\n"); for(int i = 2; i >= 0; i--) { industrial_quad_relay_set_monoflop(&iqr, 1, 1, 1500); sleep(2); } sendmail("To: xxxx@xx.de\n", "From: xxxx@xx.com\n", "Subject: Test Mail\n\n","Test Nachricht"); } int main(int argc, const char * argv[]) { printf("Motion Detector is now running and active!\n"); do { int code = 0; MotionDetector md; ipcon_create(&ipcon); motion_detector_create(&md, "kg6", &ipcon); //Check connection if(ipcon_connect(&ipcon, "localhost", 4223) < 0) { fprintf(stderr, "Could not connect to brickd\n"); exit(1); } // Register detected callback to function cb_motion_detected motion_detector_register_callback(&md, MOTION_DETECTOR_CALLBACK_MOTION_DETECTED, (void *)cb_motion_detected, NULL); printf("Bitte Code eingeben: "); scanf("%i", &code); if(code == 1) { goto ende; } //ipcon disconnect ipcon_destroy(&ipcon); } while (ex == 1); ende: fclose(stdin); } Zitieren
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.