int sampler_last(sampler s, size_t eid, size_t from, size_t to, long long* pval) { size_t i; int status = 0; for(i = from; i < to; i++) { long long val; if(sampler_get(s, eid, i, &val)) { *pval = val; status = 1; } } return status; }
int sampler_first(sampler s, size_t eid, size_t from, size_t to, long long* pval) { size_t i; for(i = from; i < to; i++) { long long val; if(sampler_get(s, eid, i, &val)) { *pval = val; return 1; } } /* Found no valid items */ return 0; }
int sampler_max(sampler s, size_t eid, size_t from, size_t to, long long* pval) { size_t i, valid_nelem = 0; *pval = LLONG_MIN; for(i = from; i < to; i++) { long long val; int ok = sampler_get(s, eid, i, &val); if(ok) { if(*pval < val) *pval = val; } } return valid_nelem > 0; }
int sampler_avg(sampler s, size_t eid, size_t from, size_t to, long long* pval) { size_t i, valid_nelem = 0; long long sum = 0LL; for(i = from; i < to; i++) { long long val; int ok = sampler_get(s, eid, i, &val); if(ok) { valid_nelem++; sum += val; } } if(valid_nelem > 0) { *pval = sum / valid_nelem; return 1; } else return 0; }
int main(void) { size_t i; #if 1 { sampler s; size_t niter = 10; /* Test the new/free functions for performance and leaks */ for(i = 0; i < niter; i++) { if( (s = sampler_new(nentity, nsamples)) == NULL) abort(); sampler_free(s); } } #endif #define TEST_AGGREGATE #ifdef TEST_AGGREGATE /* Test the aggregate functions. Here's how: * 1) Create 3600 samples, one for each second in an hour. * 2) Aggregate that up to 1 sampler with 60 minutes * 3) Aggregate that up to 1 sampler with 1 hour. * The data will be dummy data to speed things up. */ { sampler secs, minutes, hour; time_t now; size_t eid; long long val; #if 0 now = time(NULL) - 3600; #else // We want more readable time values while testing. now = 0; #endif secs = sampler_new(nentity, 3600); minutes = sampler_new(nentity, 60); hour = sampler_new(nentity, 24); for(i = 0; i < 3600; i++) { /* Add values for this second */ sampler_start_update(secs, now++); for(eid = 0; eid < nentity; eid++) { val = i % 10; sampler_add(secs, eid, val); } sampler_commit(secs); } /* Verify that we have data for all 3600 seconds. */ #if 1 fprintf(stderr, "Secs: Sample count:%zu, nvalue %zu\n", secs->samplecount, secs->nvalue); for(i = 0; i < 3600; i++) { if(secs->entities[0].data[i] == LLONG_MIN) { fprintf(stderr, "WTF?\n"); abort(); } } /* Now we know that we have values for each and every second */ #endif fprintf(stderr, "Aggregating secs->minutes\n"); sampler_aggregate(minutes, secs, 60, 60, SAMPLER_AGG_AVG); #if 1 fprintf(stderr, "Dumping minutes for eid 0\n"); fprintf(stderr, "Minutes: Sample count:%zu, nvalue %zu\n", minutes->samplecount, minutes->nvalue); for(i = sampler_samplecount(minutes) - 3; i < sampler_samplecount(minutes); i++) { if(sampler_get(minutes, 0, i, &val)) fprintf(stderr, "Minute: %zu: Value: %lld\n", i, val); else fprintf(stderr, "Minute: %zu: No value found\n", i); } #endif fprintf(stderr, "Aggregating minutes->hour\n"); sampler_aggregate(hour, minutes, 1, 60, SAMPLER_AGG_AVG); fprintf(stderr, "Dumping hour for eid 0\n"); sleep(1); for(i = 0; i < sampler_samplecount(hour); i++) { if(sampler_get(hour, 0, i, &val)) fprintf(stderr, "Hour: %zu: Value: %lld\n", i, val); else fprintf(stderr, "Hour: %zu: No value found\n", i); } sampler sdup = sampler_dup(secs); sampler_copy(sdup, secs); sampler_free(sdup); sampler_free(hour); sampler_free(secs); sampler_free(minutes); } #endif { pthread_t writerthread, reader1, reader2; int id1 = 1, id2 = 2; sampled_data = sampler_new(nentity, nsamples); /* Start the writer thread */ pthread_create(&writerthread, NULL, writer, NULL); pthread_create(&reader1, NULL, reader, &id1); pthread_create(&reader2, NULL, reader, &id2); fprintf(stderr, "Main thread sleeping\n"); sleep(5); fprintf(stderr, "Main thread shutting down\n"); shutting_down = 1; pthread_join(writerthread, NULL); sampler_free(sampled_data); } return 0; }
int main() { init(); puts("Initialised."); //fputs("Initialised.\n", tftout); //tft::setBGLight(true); // Sampler //static uint8_t smpBuffer[128]; static uint8_t *smpBuffer; smpBuffer = payloadBuffer(); static uint8_t *sptr; sptr = smpBuffer; static bool smpReady = false; // PWM, double buffering static uint8_t pwmBuffer[2][SMP_SIZE]; // Current reading buffer static uint8_t pwmRead = 0; // Reading position (initially at the end) static uint8_t *pptr = pwmBuffer[0] + SMP_SIZE; static bool pwmReady = false; // UART static char buffer[200] = "\e[96mGroup 7, yz39g13 with jm15g13: \e[0m"; const uint8_t len = strlen(buffer); char *ptr = buffer + len; static bool uartReady = false; // Miscellaneous uint16_t txCount = 0, rxCount = 0; int c; DDRC |= _BV(7); DDRC &= ~_BV(0); PORTC |= _BV(0); poll: // If sampler is ready if ((PINC & _BV(0)) && sampler_available()) { if (smpReady) sampler_get(); // Reset sampler else { *sptr++ = sampler_get(); if (sptr == smpBuffer + SMP_SIZE) { smpReady = true; sptr = smpBuffer; } } } // If data from sampler is ready for transmit if (smpReady) smpReady = send(MACHINE_ADDRESS, SMP_SIZE) != RFM12_TX_ENQUEUED; // If PWM buffer is filled if (sampler_tick()) { // Same sample rate if (pwmReady) { // Another PWM buffer is filled PINC |= _BV(7); pwmReady = false; pwmRead = !pwmRead; pptr = pwmBuffer[pwmRead]; pwm2_set(*pptr++); } else if (pptr != pwmBuffer[pwmRead] + SMP_SIZE) { // Current PWM buffer not fully read pwm2_set(*pptr++); } } // If something is received through UART if ((c = uart0_read_unblocked()) != -1) { if (!uartReady) { putchar(c); *ptr++ = c; if (c == '\n' || c == '\r') { *ptr++ = '\n'; *ptr = 0; uartReady = true; ptr = buffer + len; } } } // If data from UART is ready for transmit if (uartReady) { uartReady = write(MACHINE_ADDRESS, strlen(buffer) + 1, (uint8_t *)buffer) != RFM12_TX_ENQUEUED; if (uartReady) { printf("Sent (0x%02x): %u\n", MACHINE_ADDRESS, txCount); //fprintf(tftout, "Sent: %u\n", txCount); txCount++; puts(buffer); //fputs(buffer, tftout); //fputc('\n', tftout); } } // If something is received through rfm12b uint8_t rxLen; if ((rxLen = available()) != 0) { uint8_t type = rfm12_rx_type(); uint8_t src; if (rxLen == SMP_SIZE) { // Sampler package read(&src, pwmBuffer[!pwmRead]); pwmReady = true; goto tick; } // General message static uint8_t buffer[RFM12_RX_BUFFER_SIZE]; read(&src, buffer); printf_P(PSTR("\e[91mReceived %u: "), rxCount); //fprintf_P(tftout, PSTR("Received %u: "), rxCount++); rxCount++; printf_P(PSTR("length %u, type 0x%02x, from 0x%02x\n\e[92m"), rxLen, type, src); //fprintf_P(tftout, PSTR("length %u, type 0x%02x\n"), len, type); *(buffer + rxLen) = '\0'; puts((char *)buffer); //fputs((char *)buffer, tftout); //fputc('\n', tftout); //rfm12_rx_clear(); }