Jump to content

Recommended Posts

Geschrieben

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
}

 

Geschrieben

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(&current, 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.

Geschrieben

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$

 

 

Geschrieben

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.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...