PPMlib (read PPM signal) V3

Hello, I'm developping a librarie to make the Arduino easily read a PPM signal, first of all, here is a PPM signal :

Here is a "functionnal" shema of my lib :

Here is the example code :

#include "PPMread.h"          // On inclue la librairie

// Données du Rx
unsigned int cha[6];           // Les valeurs des canaux

PPMread ppm(&cha[0]);          // On lance l'instance, en fournissant le pointeur

void setup()
{
  Serial.begin(115200);        // On prepare la sortie série
  Serial.println("");
  Serial.println("PPM read, librarie test");

  ppm.begin();                // On démarre la lecture PPM en arrière-plan, avec un "lissage" de 3 par défaut
}

void loop()
{
switch (ppm.read()) {  // La fonction read retourne 0 si rien n'a changé depuis son dernier appel
  case 1:        // Si read retourne 1, les valeurs ont été mises à jour
    for (int i=0; i < 6; i++){ 
      Serial.print(cha[i]);
      Serial.print(";");
    }
    Serial.println("");    
    break;
  case 2:        // Si read retourne 2, c'est qu'il existe un problème de signal
    Serial.println("FAILSAFE");
  }
}

The complete ZIP file of the library is attached to this post.

PPMreadV003.zip (2.95 KB)

And here are the questions :
I'm trying to update the version of the lib to let the users choose the number of channels of the signal/receiver, and I'm having lot of troubles with this little thing.

The first thing is that I cannot create an "variable size" array in the lib ( a kind of Channel[nbOfChannel])

The second thing is that I'm really not sure on how to describe correctly my interrupts in my librararie, even when they are sharing variables with my LIB.

The first thing is that I cannot create an "variable size" array in the lib ( a kind of Channel[nbOfChannel])

That is correct. What you need to do is define an upper limit, like 8 channels. The user could then define any number up to that limit. The array elements above that limit would still be there, but empty/ignored.

The second thing is that I'm really not sure on how to describe correctly my interrupts in my librararie, even when they are sharing variables with my LIB.

Interrupts don't trigger instance methods. So, you will have a real challenge using interrupts in your class. It can be done, but the method must be static (shared by all instances). It is up to that static method to deal with instances, and that is where the challenge lies. The usual solution is to make the class a singleton.

Ok, no "variable size" array, so no optimized memory usage.
And what about let the user define the number of channel by a pre-compilator define in the sketch ?

#define NBOFCH 10

But how can I get it back to my lib ?

About interrupts and singleton, I need to see syntexed example, because theory is not really easy to me... and it seems there is a bunch of way to declare interrupts (ISR, _vect... what the difference ? why I should use avr/interrupt.h ?)

Save yourself the trouble and use this -

Duane B

UniseV:
But how can I get it back to my lib ?

In a conventional development environment you could define a macro to specify the size via a command-line argument to the compiler. That's not supported by the Arduino IDE. There are a few possible workarounds - all feasible, none elegant:

Provide an interface to specify the size at runtime and allocate the data store dynamically.
Provide an object-oriented interface where the caller instantiates objects defined by your library and each instance contains the necessary storage. The effect is similar, but it's a neater solution.
Put your code definitions in a .h file and give your users instructions to create their own .cpp file that defines sizing macros and #includes your implementation file. Ugly as hell, but gives you user-defined sizing without any dynamic allocation.
The last option is to tell your users to edit the definition in your code. That's easiest, but also least flexible (the change would apply to all sketches using that library).

@Duane B :
Thank you Duane, I've carefully read a lot of things from your website during the last year, you really give me a big help beginning personal RC projects.

To read PPM-sum I'm using an hardware feature of the ATmega328P (input capture unit), this timestamp "hardwarely" an event but only on the PIN8 of the Arduino, I really think this is the most optimized way to read PPM.
Also, PinChangeInt.h is a very powerfull tool, but I need a less weight product, that will ONLY do things I need.
Just to explain, this library is the origine of my signature below :wink:

@PeterH :
I really like your exhaustive list, and my favourite proposition is :

Provide an object-oriented interface where the caller instantiates objects defined by your library and each instance contains the necessary storage. The effect is similar, but it's a neater solution.

Could you please tell me more about this syntax ?

UniseV:
Could you please tell me more about this syntax ?

I suggest you look up object-oriented C++. It's a big subject, but very widely documented.

PaulS:

The first thing is that I cannot create an "variable size" array in the lib ( a kind of Channel[nbOfChannel])

That is correct. What you need to do is define an upper limit, like 8 channels. The user could then define any number up to that limit. The array elements above that limit would still be there, but empty/ignored.

Hey, I found this in the release note V1.0.4 of the Arduino IDE :

ARDUINO 1.0.4 - 2013.03.11
[core]
* Fixed malloc bug (Paul Stoffregen)

Is it safe to use malloc() now ? Is it a clean solution to create a "varialbe size" array ?

Is it safe to use malloc() now ?

Safe, yes. Reasonable? Maybe. Maybe not. Are you planning to deal, somehow, with a failure by malloc() to allocate space? If not, then, not it isn't reasonable. If so, how?

Is it a clean solution to create a "varialbe size" array ?

A what? Doesn't your spellchecker work?

Dynamic memory allocation on a processor with so little memory is rarely a good idea.

PaulS:
A what? Doesn't your spellchecker work?

Dynamic memory allocation on a processor with so little memory is rarely a good idea.

Spellchecker works fine, but it still does not write messages instead of me :sweat_smile:, sorry for my poor spelling, but I'm just a french e-tourist. :wink:

Could you please explain me why it is not safe to use malloc() on "little memory" hardware ?
I was considering this solution specifically to gain some valuable memory bytes, considering that my lib will be called early in the sketch (lot of free memory), so let it take a minimal place to give a maximal free memory for the user sketch.
What's wrong in my "thinking way" ?