Bastler Geschrieben June 13, 2015 at 15:17 Geschrieben June 13, 2015 at 15:17 Hallo, ich versuche die Zeit zwischen zwei Impulsen zu messen. Dazu habe ich folgenden Aufbau: DC-Brick -> RED-Brick -> Ethernet-Extension -> Master-Brick |-> IO16-Bricklet Wenn ich dann von Hand im Abstand von ca. 10 Senkunden ein Impuls auf ein PIN gebe erhalte ich folgende Ausgabe: tf@red-brick:~/programs/Test/bin$ ./zeit Press key to exit Konfiguriere UID: 329fJv Konfiguriere UID: 329fJv Konfiguriere UID: 68Wbrf Konfiguriere UID: spq ca. 10s Z1: 0.000499 Z1: 0.000172 ca. 10s Z1: 0.000621 Z1: 0.000168 ca. 10s Z1: 0.000638 Z1: 0.000166 ca. 10s Z1: 0.000571 Z1: 0.000168 ca. 10s Z1: 0.000496 Z1: 0.000165 ca. 10s Z1: 0.000738 Z1: 0.000175 ca. 1min Z1: 0.002010 Z1: 0.000178 tf@red-brick:~/programs/Test/bin$ Die Zeiten passen nu gar nicht. Habe ich da noch irgendwo ein Programmfehler (ich finde keinen) oder Denkfehler ? Ich vermute fast das die CLOCKS_PER_SEC nicht richtig ist ? Hier das Programm: #include <stdio.h> #include <time.h> #include "ip_connection.h" #include "bricklet_io16.h" #define HOST "localhost" #define PORT 4223 IPConnection ipcon; #define MASTER_1_UID "68Wbrf" #define IO16_1_UID "spq" IO16 io16_1; float z1; clock_t z1t; void printp(char port, int pin, uint8_t value_mask ) { int value = 0; if ( ( value_mask & ( 1 << pin ) ) != 0 ) { value = 1; } printf("Port: %c.%d = %d\n", port, pin, value ); } // Callback function for interrupts void cb_interrupt(char port, uint8_t interrupt_mask, uint8_t value_mask, void *user_data) { // avoid unused parameter warning (void)user_data; //printf("Interrupt on port: %c\n", port); //printf("Interrupt by: %d\n", interrupt_mask); //printf("Value: %d\n", value_mask); z1 = ( ( (float)( clock() - z1t ) ) / CLOCKS_PER_SEC ); z1t = clock(); printf("Z1: %f\n",z1 ); } void cb_enumerate( const char *uid, const char *connected_uid, char position, uint8_t hardware_version[3], uint8_t firmware_version[3], uint16_t device_identifier, uint8_t enumeration_type, void *user_data) { // avoid unused parameter warnings (void)user_data; (void)connected_uid; (void)position; (void)hardware_version; (void)firmware_version; (void)device_identifier; printf("Konfiguriere UID: %s\n", uid); if ( strcmp(uid, IO16_1_UID) == 0 ) { // Create device object //IO16 io; io16_create(&io16_1, IO16_1_UID, &ipcon); // Set all pins on port a to input with pullup io16_set_port_configuration( &io16_1, 'a', 255, 'i', true ); // Set all pins on port b to input with pullup io16_set_port_configuration( &io16_1, 'b', 255, 'i', true ); // Set Enprellzeit io16_set_debounce_period( &io16_1, 100 ); // Enable interrupt on all pins of port a io16_set_port_interrupt( &io16_1, 'a', 255 ); // Enable interrupt on all pins of port b io16_set_port_interrupt( &io16_1, 'b', 255 ); // Register callback for interrupts io16_register_callback( &io16_1, IO16_CALLBACK_INTERRUPT, (void *)cb_interrupt, NULL ); z1t = clock(); } } int main() { // Create IP connection ipcon_create(&ipcon); if ( ipcon_connect(&ipcon, HOST, PORT) < 0 ) { fprintf( stderr, "Could not connect to brickd\n"); exit(1); } // Register enumeration callback to "cb_enumerate" ipcon_register_callback(&ipcon, IPCON_CALLBACK_ENUMERATE, (void *)cb_enumerate, NULL); ipcon_enumerate(&ipcon); printf( "Press key to exit\n" ); getchar(); ipcon_destroy( &ipcon ); // Calls ipcon_disconnect internally } Zitieren
remotecontrol Geschrieben June 13, 2015 at 15:49 Geschrieben June 13, 2015 at 15:49 clock() liefert die Processor-Zeit (CPU-Zeit), und das ist wohl nicht das was Du willst - oder? Dazu kommt noch, dass clock() stark systemabhängig ist - ich habe damit zumindest eher schlechte Erfahrungen gemacht (verhält sich anders zwischen Linux/Windows). Das Ganze soll C bleiben - oder? Dann geht die reine Zeitmessung auch mit #include <sys/time.h> struct timeval current; gettimeofday(¤t, NULL); Noch ein kleiner Tipp: anstelle von void cb_interrupt(char port, uint8_t interrupt_mask, uint8_t value_mask, void *user_data) { // avoid unused parameter warning (void)user_data; sollte auch void cb_interrupt(char port, uint8_t interrupt_mask, uint8_t value_mask, void *) { gehen und somit das gleiche Ergebnis bei Warnings liefren. Zitieren
Bastler Geschrieben June 13, 2015 at 15:57 Autor Geschrieben June 13, 2015 at 15:57 Doch, clock() ist genau das was ich möchte. Ich möchte nicht's mit Datum oder Uhrzeit machen. Zitieren
Bastler Geschrieben June 13, 2015 at 16:10 Autor Geschrieben June 13, 2015 at 16:10 Oder noch einfacher (nach http://www.cplusplus.com/reference/ctime/clock/): /* clock example: frequency of primes */ #include <stdio.h> /* printf */ #include <time.h> /* clock_t, clock, CLOCKS_PER_SEC */ int main () { clock_t t; int f; t = clock(); printf ("Calculating...\n"); sleep(10); // 10 Sekunden t = clock() - t; printf ("It took me %d clicks (%f seconds).\n",t,((float)t)/CLOCKS_PER_SEC); return 0; } Die Ausgabe: tf@red-brick:~/programs/Test/bin$ ./zeit1 Calculating... It took me 271 clicks (0.000271 seconds). tf@red-brick:~/programs/Test/bin$ Zitieren
remotecontrol Geschrieben June 13, 2015 at 17:01 Geschrieben June 13, 2015 at 17:01 Aber dann passt doch alles - was war dann das Problem? Zitieren
Bastler Geschrieben June 13, 2015 at 17:07 Autor Geschrieben June 13, 2015 at 17:07 Das Problem ist das 10s nicht gleich 0.000271s sind. Zitieren
remotecontrol Geschrieben June 13, 2015 at 17:48 Geschrieben June 13, 2015 at 17:48 CPU-Zeit ist ungleich verstrichener Zeit: sleep(10) wartet 10 Sekunden. In der Zwischenzeit verbraucht Dein Programm nur minimal CPU-Zeit, eben die 0.000271s CPU-Sekunden. Das Programm rechnet ja nicht aktiv vor sich hin, sondern wartet auf Events, d.h. es tut nichts => CPU-Zeit sehr gering => völlig normal. Willst Du CPU-Zeit oder verstichene Zeit (Delta zwischen 2 Zeitpunkten) messen? Delta zwischen zwei Zeitpunkten kannst Du mit gettimeofday Mikrosekunden genau machen. CPU-Zeit geht mit getrusage oder clock. Zitieren
Bastler Geschrieben June 13, 2015 at 18:02 Autor Geschrieben June 13, 2015 at 18:02 ohh, ja, dann ist da wohl mein Denkfehler (bin halt nur Bastler kein Programmierer). Dann werd ich das Programm mal umschreiben. Danke für die Hilfe. 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.