yps: an event-driven, object-oriented framework

Hey there!

I’m playing around with Arduino Uno since a while, but would claim myself a beginner. I like it because it makes working with microcontrollers quite easy. However, I’m more addicted to high-level-programming languages and found the original Arduino framework still too C-ish :wink:
So I tried to pursue the idea of developing a framework, which makes it possible to write sketches with the most self-speaking syntax I could think of (at least in the boundaries of what C++ supplies), so that the programmer don’t need to care about loops and implementation-details and stuff like that. I’m not quite sure, whether this approach is able to prove itself in practice or even is useful for anyone. Or whether the whole concept is „capable of development“ after all.

The framework is called „yps“ and the sources are published here: https://github.com/jotaen/yps

I would be looking forward for thoughts and feedback on that. I had a lot of fun developing yps (and also documenting it!) and would like to bring the project forward.

Aside from that: It’s quite hard to struggle through all the libraries and frameworks for Arduino out there. So, does anyone know, whether there are similar (more high-level) projects/approaches, perhaps also in other programming languages?

Best regards, Jan

Hi

i just skimmed trough your examples...and now what ? I wrote something very similar (along with a tiny fraction of the stl) :wink:

just a couple of remarks...

  1. don't make the pin an template argument. Otherwise it's very hard to store them in arrays/containers i.e.
DigitalOutput<??>  myOutputPins[3]; //will not be possible

Device  myOutputDevices[3]; //will work but is unsecure/errorprone since  there 
                                                          //is no RTTI avialable and dynamic_cast will fail/not work
  1. don't just use global callbacks but use the listener pattern instead. It's often realy hard to get back into the object scope once you lost it....

Hey
thanks for your feedback. I have spend a lot of thoughts, whether to use templates or not. The advantage of templates is, that they perform better (at least what I figured out). If you want to store the pins, you would have to store the objects (pointers) instead of the pin numbers. But I’m still unsure if it’s the best solution, the main drawback is that you aren’t able to change pin-numbers at runtime.
Can you explain your second point further?
regards!

u r welcome

  1. This would be for me THE reason not to use yor framework because it actualy prevents generic programming...

2.Il' try that with some sample/pseudo code

void globalFunc();

class MyClass {
   DigitalInput<7> _button;
   DigitalOutput<13> _led;

   MyClass () {
    button.onHigh(switchLedOn); //doesn't work since switchLedOn is a member function
     button.onHigh(globalFunc); //at least it compiles
   }
   void switchLedOn() { led.on(); }
};

void globalFunc() {  //ok...we got invoked...but how the hell do i get a refernce to MyClass or MyClass.led ?? }

in this case, you would need some global variables the get back into the object context which isn't usualy what you want.
on the other hand, if you use the listener/observer pattern, it's much simpler, cleaner, robust and easier to understand

class DigitalInputListener {
    virtual void pinStateChanged(int pin, int state);
 };

class PinStateListener : public DigitalInputListener {
   virtual void pinStateChanged(int pin, int state) {  if(state == HIGH)  pinStateHigh(pin);  if(state == LOW) pinStateLow(pin);  }
   virtual void pinStateHigh(int pin) {}
    virtual void pinStateLow(int pin) {}
}

class MyClass : public PinStateListener {
   DigitalInput<6> _button;
   DigitalOutput<13> _led;

   MyClass () {  _button.onHigh(this); }

   virtual void pinStateHigh(int pin, int state) {  _led.on(); }
};

the things mentioned above are actualy the reason, why i'm refactoring the PinChangeInterrupt libraries....

another remark about the templates...
yes, they perform better then virtual functions (no vtable lookup) and they do reduce ram size (again, because there is no vtable). But, they should be used "in the right place". i.e. to make things more generic, configurable etc... I use a LOT of templates...but in your example, it's IMO the wrong place to use it...you prohibit generic programming with it...

for example, in my library, i do have a template for the Pin...but its used to define if its an input or output pin.

template<typenme Reader, int mode> Pin;
typedef Pin<DigitalReader, INPUT> DigitalInputPin;
typedef Pin<DigitalWriter, OUTPUT> DigitalOutputPin;
typedef Pin<AnalogReader, INPUT> AnalogInputPin;

Hey there
I’m getting your point. However, the approach is still a bit different and doesn’t gear towards technical concepts at all. The idea is rather, that especially when developing „simple“ applications, there is no need for generic programming, class-hirachies and stuff like that, but that it’s sufficient to have a simplified and handy toolkit with as few as possible concepts behind it, even though it won’t cover all possible use-cases or challenges.