Ringbuffers en super arrays

Van de week 2 x 32kByte I2C FRAM's binnen gekregen. Eerste testen zijn veel belovend:

--------------------------------------------------------------
Aantal records gemaakt ............ :        10 
Dit gebruikte ..................... :        40 bytes
Dit duurde ........................ :   0.00600 seconden
Het vullen duurde ................. :   0.00300 seconden
Het lezen duurde .................. :   0.00300 seconden
--------------------------------------------------------------
Aantal records gemaakt ............ :       100 
Dit gebruikte ..................... :       400 bytes
Dit duurde ........................ :   0.00900 seconden
Het vullen duurde ................. :   0.02900 seconden
Het lezen duurde .................. :   0.03200 seconden
--------------------------------------------------------------
Aantal records gemaakt ............ :      1000 
Dit gebruikte ..................... :      4000 bytes
Dit duurde ........................ :   0.02700 seconden
Het vullen duurde ................. :   0.28500 seconden
Het lezen duurde .................. :   0.31600 seconden
--------------------------------------------------------------
Aantal records gemaakt ............ :      4000 
Dit gebruikte ..................... :     16000 bytes
Dit duurde ........................ :   0.08800 seconden
Het vullen duurde ................. :   1.13900 seconden
Het lezen duurde .................. :   1.26300 seconden
--------------------------------------------------------------
Aantal records gemaakt ............ :      8000 
Dit gebruikte ..................... :     32000 bytes
Dit duurde ........................ :   0.16900 seconden
Het vullen duurde ................. :   2.27600 seconden
Het lezen duurde .................. :   2.52700 seconden
--------------------------------------------------------------

Deze werkt op I2C waarbij ik de max snelheid op 400kHz heb gezet,

de class wordt al een stuk complexer... als attachement

hierbij wordt gebruik gemaakt van een bestandje Memory.h waarin de configuratie wordt bepaald. Wel zie ik eea nog wel over de kop gaan voordat het helemaal rond is :slight_smile:

/*
    Name:       memory.h
    Created:    15-12-2018 08:41:43
    Author:     nico verduin
    Brief:      Defines the memory to be used for our array class
*/
#ifndef MEMORY_H_
#define MEMORY_H_

// select one and comment the rest out
//#define BUILTIN_RAM       // will use internal RAM memory
//#define SPI_FRAM          // will use F-RAM memory through SPI interface
#define I2C_FRAM            // will use F_RAM memory through I2C interface

// specific I2C F-RAM parameters
#ifdef I2C_FRAM
#define MB85RC_SLAVE_ID       (0xF8)

#endif
// Specific SPI F-RAM connections
#ifdef SPI_FRAM
#define PIN_FRAM_ENABLE     10         // chip select on pin 10
#define PIN_FRAM_ADDRESS_A0 9          // A0
#define PIN_FRAM_ADDRESS_A1 8          // A1
#define PIN_FRAM_ADDRESS_A2 7          // A2

#endif

#endif /* MEMORY_H_ */

Wat overigens opvalt is dat er erg veel tijd verloren gaat in de wire functies Wire.beginTransmission() en Wire.endTransmission(). Een tabel vullen waarbij de begin en end eenmalig worden uitgevoerd duurt veel en veel korter.

test programma

/*
 Name:       Ringbuffer.ino
 Created:    14-12-2018 08:41:43
 Author:     nico verduin
 Brief:      Eenvoudige manier om met een array  een ringbuffer te maken
 */

void printResult(const char * tekst1, const char * aantal,
    const char * tekst2);
void printStreep();
void convertToDoubleString(char * resultaatString, uint32_t aantal, uint32_t deelGetal);


// includes
#include "Array.h"        // Super Array class

// program defines

#define MAX_ARRAY_SIZE 8000
#define COLUMNS_PER_ROW 10
#define ARRAY_TYPE uint32_t

// global variables
// create an array of type uint32
Array<ARRAY_TYPE> myArray;

/*
 * @name setup()
 * @brief Initializes the program
 */
void setup() {
  uint32_t timer;
  uint32_t tijd;
  char werkveld[10];

  // initialiseer Serial
  Serial.begin(115200);

  Serial.println("\nTesten met I2C FRAM chip van adafruit\n\n");
  printStreep();

  // dummy init
  myArray.init(1, 0x50);
  uint32_t aantalEntries  = 10;
  uint32_t increment      = 10;
  while(aantalEntries *sizeof(ARRAY_TYPE) < myArray.getCapacity()) {

    // maak de array
    timer = millis();
    myArray.init(aantalEntries, 0x50);
    tijd = millis() - timer;

    sprintf(werkveld, "%9lu", aantalEntries);
    printResult("Aantal records gemaakt ", werkveld, "");

    sprintf(werkveld, "%9lu", aantalEntries * sizeof(ARRAY_TYPE));
    printResult("Dit gebruikte ", werkveld, "bytes");

    convertToDoubleString(werkveld, tijd , 1000UL);
    printResult("Dit duurde ", werkveld, "seconden");

    // vul de array
    timer = millis();
    for (uint32_t j = 0; j < aantalEntries; j++) {
      myArray.addEntry((ARRAY_TYPE) j);
    }
    tijd = millis() - timer;
    convertToDoubleString(werkveld, tijd , 1000UL);
    printResult("Het vullen duurde ", werkveld, "seconden");

    // lees de array
    timer = millis();
    for (uint32_t j = 0; j < aantalEntries; j++) {
      myArray.getEntry(j);
    }
    tijd = millis() - timer;
    convertToDoubleString(werkveld, tijd , 1000UL);
    printResult("Het lezen duurde ", werkveld, "seconden");
    printStreep();

    // verhoog aantal entries
    aantalEntries = aantalEntries + increment;
    if (aantalEntries == 100) {
      increment = 100;
    }
    if (aantalEntries == 1000) {
      increment = 1000;
    }
  }
}

// Add the main program code into the continuous loop() function
void loop() {
}

void printResult(const char * tekst1, const char * aantal, const char * tekst2) {
  char regel[100];
  char tekstVeld[36];
  strncpy(tekstVeld, tekst1, 35);

  // tekst opvullen met punten
  for (uint8_t i = strlen(tekstVeld); i < 36; i++) {
    tekstVeld[i] = '.';
  }
  tekstVeld[35] = '\0';
  sprintf(regel, "%35s : %9s %s\n", tekstVeld, aantal, tekst2);
  Serial.print(regel);
}

void printStreep() {
  for (uint8_t i = 0; i < 62; i++) {
    Serial.print("-");
  }
  Serial.println();
}

void convertToDoubleString(char * resultaatString, uint32_t aantal, uint32_t deelGetal){
  double resultaat = (double)aantal / double(deelGetal);
  dtostrf(resultaat, 9, 5, resultaatString);
}

suggesties voor performance verbeteringen zijn altijd welkom.

Array.h (11.6 KB)