Android 4.4 and the SD card

Quite likely you have heard that Android 4.4 aka KitKat comes with a nasty change on the sd card. Apps cannot wrize to the sd card anymore respectively they can only write into their dedicated home directory. In the hierarchy of this directory you find a .nomedia file, so storing media files there hides them from standard apps.

This renders explorer and sync apps mostly useless if you want to manage data in tbe sd card.

Let me briefly rant about this change…

Google calls this change a security measure. I call it complete nonsense.

Any app can snoop into any data
No protection at all.

Any app can still freely randomly access the build in memory.
No protection at all.

The change is

hard wired

without rooting you cannot bypass it or grant a trusted application access.

Either somebody made a massively wrong decision (unlikely) or it was introduced with the intention to push people into the cloud and stream their content.

The benefits from a business perspective is obvious:

– Sell online storage
– Sell bandwidth
– Access and profile user data and sell it

It is definitely not a security measure but more of an enforced limitation without restrictions from a business perspective.

Sorry this one is too obvious.

Quantified Self Fitbit vs Withings

While I am always a little hesitant about collecting and sharing personal information I couldn’t resist to try these wearables ehich counting steps, elevation etc.

Due to a cross corporate event I carry a plain pedometer with me. So I used this opportunity to test a Fitbit One and a a Withings Pulse by carry one of these in addition for a few weeks and compare the results.

Unpacking
Both devicee come with a wristband, USB charging cable and a clip holder.

The Pulse has a micro USB connector on the device, which I consider as a good design choice, as standard micro USB cables can be used to charge the device and hooking it up with a PC.

The Fitbit One has a special connector and hence needs a special USB adapter which you have take care for – not my preference. It comes additionally with a bluetooh/USB adapter to connect it wireless to an PC.

Devices
Both devices ate quite small, have a display and a single button. Nothing special here.

The Pulse is somewhat wider but it didn’t bother me. In return it has bigger display which is touch sensitive and a LED/Sensor combination on the back to measure  heart rate and the blood oxygen level from the finger. Withings crammed quite a lot in this device which increases the coolness factor.

The Fitbit has just a simple display and a button next to it. That’s it. Oh I forgot – – the Fitbit has an vibrator inside, which can be used as a silent alarm clock.

Installation and Setup
Installation and connecting both devices with my HTC One was simple and worked without any problem.

Creating the accounts on their portals was also simple. I just recommend to revisit the privacy settings to ensure that your activities are adequately shared (Google Fitbit privacy)

After a few minutes I was walking around starring on these tiny displays and the phone to see what they do – First achievement I was voluntarily walking around!

Android Apps
The Android Apps look quite different.

Fitbits App is clean and simple like the device itself. The data captured is automatically synchronized and displayed in a good way. To me the straight and clean interface was a little bit boring even there is nothing I actually could complain.

The Withings app looks more technical and fancy –  again increased coolness. However the app has some inconsistencies –  not all data is properly presented (e.g. graphs without scaling), some data is not visible at all (heart rate disappeared with the last update), manual data entry is somewhat cumbersome.

Daily use
Well what shall I say, you carry them around, they do their job and that’s it.

Withings Pulse
The interface on the device is simple and easy, however I didn’t use it a lot.  The only occasion where I need it, is the heart rate measurement.

The clip holder for the Withings Pulse is not that good and doesn’t look to be  really solid. Once when I sat down the device just dropped out (this happened more than once). Luckily I noticed the Pulse laying on the floor so haven’t lost it yet.

The heart rate meter is useless for me because the Pulse must be removed from the clip holder to take a measurement. The measured values sometimes are quite strange and need a second measurement – don’t fully trust it.

Synchronization occurs automatically every 6 hours or can be manually triggered with the button on the device. The procedure is a little bit strange but worked for me (other users reported issues with this). Hence the Withings icon in the Android notification bar should be removed.

The battery powered the device for a week, then I charged it. It might run even longer – I didn’t tested it.

Fitbit One
Again the Fitbit just did its work. Nothing special to mention. Synchronization works without user intervention and the battery was also up for a week at least.

Measurements
Both devices counted steps – no surprise – but the Withings counted 20 –  30% less steps than the Fitbit. This is quite a significant difference. The third pedometer sympathized with the Fitbit One and showed the same difference to the Withings Pulse. I am not sure if my Withings Pulse is defective or if this is just a result of different approach to measure steps.

I found a similar difference in the elevation measurement however as the Fitbit calculates floors and the Pulse meters it cannot be directly compared.

I mentioned already that the Withings Pulse measures heart rate not always accurate. But frankly this can be easily spotted with multiple measurements.

Conclusion
Both devices do their job in a quite similar way. The Withings Pulse comes with more features while the Fitbit shines with simplicity.

The problem I had with the Withings App and the step counts still persist (othet user report similar issues). I issued two support requests but haven’t heard back since.

Personally I would love to go with the Withings Pulse however the problems I have with the device and the app as well as the cumbersome app itself stop me from doing that.

So I stick with the Fitbit as its overall simplicity seems to me as the better match for the daily use.

Update
Meanwhile Withings responded and the app as well as the Withings Pulse received an update. Generally the accuracy improved but still lacks behind the comparison. What I recognized is that the calculated distance does not vary as much as the number of steps –  strange.
The issue with the Withings Pulse Holder is really annoying, so far I still recognized when it dropped but that should be definitely fixed.

What’s wrong with Android?

I like Android and all the Android powered devices. However currently the market got somewhat insane. Every month a new device hits the market. In some cases I got the impression that during the rollout of the latest device the next device is already in production (i.e. Samsung Galaxy S3 vs Samsung Galaxy S4). The same time I experience myself that devices drop out of maintenance after a year or two and the last updates render a device finally unusable. So what’s wrong here?

Continue reading

TLedStrip (Arduino Library)

TLedStrip is a library I haven’t seen anywhere else yet and I htink this one is extermely useful. TLedStrip creates a buffer containing rgb values of a predefined size and offers a series of manipulations on that buffer. Actually it is like a one dimensional graphics driver.

Building an instance of TLedStrip is once again simple:

TLedStrip ledstrip = TLedStrip(number_of_leds);

(I know it should return an error in case the memory is not available – I left that one out)

Now you can apply the following operations on the buffer:


// mirror from posA to posB the next 'length'  leds
void mirror(int posA, int posB, int length);

// copy  from posA to posB the next 'length'  leds
void copy(int posA, int posB, int length);

// shift 'length' rgb values starting at pos one left
void shiftLeft(int pos, int length);

// shift 'length' rgb values starting at pos one right
void shiftRight(int pos, int length);

// shift 'length' rgb values starting at pos one right and the last one will put at 'pos'
void rotateRight(int pos, int length);

// shift 'length' rgb values starting at pos one right and pos will be moved to the last position
void rotateLeft(int pos, int length);

// fill 'length' values starting at pos with the value where pArray is pointing to
void fill(int pos, int length, byte *pArray);

// set all rgb buffer cells to zero
void blank();

// set all rgb buffer cells to 255
void white();

 // copy the value value of pElement to pos
void set(int pos, byte *pElement);

// set the r,g,b value to pos
void setRGB(int pos, int r, int g, int b);

// convert the h,s,v value to r,g,b and copy it to pos
void setHSV(int pos, int hue, int sat, int val);

// determine the number of configured leds
int getCount() { return _num; };

// return a pointer to the buffer at position pos
 byte* get(int pos);

// filter the 'length' values starting at pos based on the
// filter coeff with the target value which pRGB points to
void filter(int pos, int length, int coeff, byte *pRGB);

With this operations quite a lot of effects can be easily created (as shown in TLedShowStrip). The only thing that need to be done to make things visible, is to push the buffer to the led strip. The FastSPI library handles this buffer structure and can push it to the leds with a single call.

TLedStrip.h

</pre>
#ifndef _LEDSTRIP_H_
#define _LEDSTRIP_H_
#include <Arduino.h>

struct PIXEL { byte r; byte g; byte b;};

class TLedStrip {

private:
 int _num;
 struct PIXEL *_ledstrip;

public:
 TLedStrip(int num);
 void init();
 void mirror(int posA, int posB, int length);
 void copy(int posA, int posB, int length);
 void shiftLeft(int pos, int length);
 void shiftRight(int pos, int length);
 void rotateRight(int pos, int length);
 void rotateLeft(int pos, int length);
 void fill(int pos, int length, byte *pArray);
 void blank();
 void white();

 void set(int pos, byte *pElement);
 void setRGB(int pos, int r, int g, int b);
 void setHSV(int pos, int hue, int sat, int val);

int getCount() { return _num; };

 byte* get(int pos);

 void filter(int pos, int length, int coeff, byte *pRGB);
 void filter(byte *pTarget, byte *pRef, int coeff);
 byte filter(byte current, byte target, int coeff);

};

#endif
<pre>

TLedStrip.cpp

</pre>
#include "TLedstrip.h"

// ---------------------------------------------------------------------------
TLedStrip::TLedStrip(int num):_num(num) {
 _ledstrip = (PIXEL *)(malloc(num*sizeof(PIXEL)));
}

// ---------------------------------------------------------------------------
void TLedStrip::init() {
 blank();
}

// ---------------------------------------------------------------------------
void TLedStrip::set(int pos, byte *pElement) {

pos = constrain(pos, 0, _num-1);

_ledstrip[pos] = *((PIXEL *)(pElement));
}

// ---------------------------------------------------------------------------
void TLedStrip::setRGB(int pos, int r, int g, int b) {

pos = constrain(pos, 0, _num-1);

_ledstrip[pos].r = (byte)(constrain(r,0,255));
 _ledstrip[pos].g = (byte)(constrain(g,0,255));
 _ledstrip[pos].b = (byte)(constrain(b,0,255));
}

// ---------------------------------------------------------------------------
void TLedStrip::setHSV(int pos, int hue, int sat, int val)
 {
 // hue: 0 - 359, saturation: 0 - 255, val (lightness): 0 - 255

 if (hue > 359) hue = hue % 359;
 val = constrain(val,0,255);
 sat = constrain(sat,0,255);

 if (sat == 0)
 {
 // Acromatic color (gray)
 setRGB(pos, val, val, val);
 }
 else
 {
 int r =0, g=0, b=0;
 int base = ((255 - sat) * val) >> 8;

 if (hue < 60) {
 r = val;
 g = (((val - base)*hue)/60) + base;
 b = base;
 }
 else if (hue < 120) {
 r = (((val - base)*(60-(hue%60)))/60) + base;
 g = val;
 b = base;
 }
 else if (hue < 180) {
 r = base;
 g = val;
 b = (((val - base)*(hue%60))/60) + base;
 }
 else if (hue < 240) {
 r = base;
 g = (((val - base)*(60 - (hue%60)))/60) + base;
 b = val;
 }
 else if (hue < 300) {
 r = (((val - base)*(hue%60))/60) + base;
 g = base;
 b = val;
 }
 else if (hue < 360) {
 r = val;
 g = base;
 b = (((val - base)*(60 - (hue%60)))/60) + base;
 }

 setRGB(pos, r, g, b);
 }
 }

// ---------------------------------------------------------------------------
byte * TLedStrip::get(int pos) {
 pos = constrain(pos, 0, _num-1);
 return (byte *)(&(_ledstrip[pos]));
}

// ---------------------------------------------------------------------------
void TLedStrip::blank() {
 setRGB(0, 0, 0, 0);
 fill(1, _num-1, (byte *)(_ledstrip));
}

// ---------------------------------------------------------------------------
void TLedStrip::white() {
 setRGB(0,255,255,255);
 fill(1, _num-1, (byte *)(_ledstrip));
}

// ---------------------------------------------------------------------------
void TLedStrip::fill(int pos, int length, byte *pLed) {

// Protect buffer boundaries
 pos = constrain(pos, 0, _num-1);
 length = constrain(length, 0, _num-pos);
 while(length-- > 0) _ledstrip[pos++] = *((PIXEL*)(pLed));
}

// ---------------------------------------------------------------------------
void TLedStrip::rotateLeft(int pos, int length) {

 // Protect buffer boundaries
 pos = constrain(pos, 0, _num-1);
 length = constrain(length, 0, _num-pos);

_ledstrip[pos+length-1] = _ledstrip[pos];
 shiftLeft(pos, length-1);
}

// ---------------------------------------------------------------------------
void TLedStrip::rotateRight(int pos, int length) {

 // Protect buffer boundaries
 pos = constrain(pos, 0, _num-1);
 length = constrain(length, 0, _num-pos);

_ledstrip[pos] = _ledstrip[pos+length-1];
 shiftRight(pos+1, length-1);
}

// ---------------------------------------------------------------------------
void TLedStrip::shiftLeft(int pos, int length) {

// Protect buffer boundaries
 length = constrain(length, 0, _num-pos)-1;
 pos = constrain(pos, 0, _num-1);

while((length--) > 0) {
 _ledstrip[pos] = _ledstrip[pos+1];
 pos++;
 }
}

// ---------------------------------------------------------------------------
void TLedStrip::shiftRight(int pos, int length) {

 // Protect buffer boundaries
 length = constrain(length, 0, _num-pos)-1;
 pos = constrain(pos, 0, _num-1)+length;

 while((length--) > 0) {
 _ledstrip[pos] = _ledstrip[pos-1];
 pos--;
 }
}

// ---------------------------------------------------------------------------
void TLedStrip::copy(int posA, int posB, int length) {

// Protect buffer boundaries
 posA = constrain(posA, 0, _num-1);
 length = constrain(length, 0, _num-posA);

if (length <= 0) return;
 posA = constrain(posA,0,_num);
 posB = constrain(posB,0,_num);
 if (posA+length > _num) length = _num-posA;
 if (posB+length > _num) length = _num-posB;

if(posA > posB) {
 for(int i = posA, j = posB; i < posA+length; i++, j++) {
 _ledstrip[j] = _ledstrip[i];
 }
 }
 if(posB > posA) {
 for(int i = posA+length-1, j = posB+length-1; i >= posA; i--, j--) {
 _ledstrip[j] = _ledstrip[i];
 }
 }
}

// ---------------------------------------------------------------------------
void TLedStrip::mirror(int posA, int posB, int length) {

if(posA > posB) {
 for(int a = posA, b = posB+length-1; a < posA+length-1; a++, b--) {
 _ledstrip[b] = _ledstrip[a];
 }
 }
 if(posB > posA) {
 for(int a = posA+length-1, b = posB; a >= posA; a--, b++) {
 _ledstrip[b] = _ledstrip[a];
 }
 }
}

// ---------------------------------------------------------------------------
byte TLedStrip::filter(byte current, byte target, int coeff) {

 int diff = target - current;
 int delta = diff / coeff;
 int result = current + delta;

if (delta == 0) result = target;

 return constrain(result, 0, 255);
}

// ---------------------------------------------------------------------------
void TLedStrip::filter(byte *pTarget, byte *pRef, int coeff) {

 ((PIXEL *)(pTarget))->r = filter(((PIXEL *)(pTarget))->r, ((PIXEL *)(pRef))->r, coeff);
 ((PIXEL *)(pTarget))->g = filter(((PIXEL *)(pTarget))->g, ((PIXEL *)(pRef))->g, coeff);
 ((PIXEL *)(pTarget))->b = filter(((PIXEL *)(pTarget))->b, ((PIXEL *)(pRef))->b, coeff);
}

// ---------------------------------------------------------------------------
void TLedStrip::filter(int pos, int length, int coeff, byte *pRGB) {

 for(int i=pos; i < pos+length; i++) filter( get(i), pRGB, coeff);
}
<pre>

The source code without an example can be grabbed from here. If you need help with using this library drop me a note. You can also look into the implementation of LedStripShow, which makes use of this library.

TSwitch (Arduino Library)

The second library component I would like to present is TSwitch. TSwitch handles hardware switches attached to the Arduino. It does the debouncing, reads the state and detects long and short press (aka doubleclick) :

The easiest way to instantiate the class is (for more details please refer to the  code):

TSwitch switch = TSwitch(arduino_pin);

Then you poll the object continously

switch.poll();

switch.poll() returns the state  which can be more comfortably obtained through the following class members:

switch.hasChanged(); // Signals if there was a change since last read - destructive read
switch.wasLong(); // Signals if > 3 seconds passed since last change
switch.wasShort(); // Signals if < 250ms passed since transition
switch.get(); // state of the switch 0=0ff 1=on

TSwitch.h

</pre>
#ifndef _TSWITCH_H_
#define _TSWITCH_H_

#define PULLUP HIGH
#define PULLDOWN LOW

#define _SWITCH_OFF_ 0
#define _SWITCH_ON_ 1
#define _SWITCH_SHORT_ 2
#define _SWITCH_LONG_ 4
#define _SWITCH_CHANGE_ 8
#define _SWITCH_STABLE_ 16

#define _SWITCH_MS_LONG_ 3000
#define _SWITCH_MS_SHORT_ 250

class TSwitch {

private:
 uint8_t _pin; // CPU Pin of button
 uint8_t _mode; // PULLUP or PULLDOWN mode
 uint8_t _state; // State
 unsigned int _debounceTime; // Config for number of ms debouncing delay
 int _lastPinRead; // pin status last time the pin was read
 unsigned long _toggledAt; // last time the pin changed
 unsigned long _elapsedA; // last time the switch was stable
 unsigned long _elapsedB; // prior last time the switch was stable

public:
 // Constructor with Initialize timer
 TSwitch(uint8_t pin, uint8_t mode = PULLUP, unsigned int debounceTime=20);

// Run single debounce cycle - returns full state
 uint8_t poll();

 // Signals if there was a change since last read - destructive read
 uint8_t hasChanged();

 // Signals if the last transition was long
 uint8_t wasLong();

// Signals if the last transition was fast
 uint8_t wasShort();

 // Returns the current state with all flags
 uint8_t getState();

 // Returns the switch state
 uint8_t get();
};

#endif
<pre>

TSwitch.cpp

</pre>
#include <Arduino.h>
#include <limits.h>
#include <TSwitch.h>
// ---------------------------------------------------------------------------
TSwitch::TSwitch(uint8_t pin, uint8_t mode, unsigned int debounceTime) {

 _pin = pin;
 _mode = mode;
 _debounceTime = debounceTime;

_state = (_lastPinRead != _mode) ? _SWITCH_ON_:_SWITCH_OFF_;
 _lastPinRead = digitalRead(_pin);
 _toggledAt = millis();

 if (_mode == PULLUP) {
 digitalWrite(_pin, HIGH);
 }
 else {
 digitalWrite(_pin, LOW);
 }
}

// ---------------------------------------------------------------------------
boolean TSwitch::hasChanged() {

boolean changeFlag = _state & _SWITCH_CHANGE_;

 // Delete change flag as it has been read
 _state &= ~_SWITCH_CHANGE_;

 return changeFlag;
}
// ---------------------------------------------------------------------------
uint8_t TSwitch::getState() {
 return _state;
};

// ---------------------------------------------------------------------------
uint8_t TSwitch::get() {
 return _state & _SWITCH_ON_;
};

// ---------------------------------------------------------------------------
uint8_t TSwitch::wasLong() {
 return (_state & _SWITCH_LONG_)?1:0;
};

// ---------------------------------------------------------------------------
uint8_t TSwitch::wasShort() {
 return (_state & _SWITCH_SHORT_)?1:0;
};
// ---------------------------------------------------------------------------
uint8_t TSwitch::poll() {

 unsigned long now = millis();

 // read pin
 int pinRead = digitalRead(_pin);

 // If a change occurred start debouncing
 if ( pinRead != _lastPinRead ) {
 // Delete change and stable flag
 _state &= ~(_SWITCH_CHANGE_ | _SWITCH_STABLE_);

 // Maintain current state to handle debouncing
 _lastPinRead = pinRead;
 _toggledAt = now;
 }
 else if ( (_state & _SWITCH_STABLE_) == 0 ) {
 // If debounce time passed without a change the switch is stable
 if ( (now - _toggledAt) >= _debounceTime ) {

// Identify state
 _state = (_lastPinRead != _mode) ? _SWITCH_ON_:_SWITCH_OFF_;
 _state |= _SWITCH_CHANGE_ | _SWITCH_STABLE_ ;

// Identify double and long presses
 if (now - _elapsedA > _SWITCH_MS_LONG_ ) _state |= _SWITCH_LONG_;
 if (now - _elapsedB < _SWITCH_MS_SHORT_) _state |= _SWITCH_SHORT_;

 // Shift elapsed time
 _elapsedB = _elapsedA;
 _elapsedA = now;

 // Save current time to later determine the stable duration
 _toggledAt = now;
 }
 }

 return _state;
}
<pre>

TSwitch as library including an example can be found here for download

TTimer (Arduino Library)

TTimer is not one and only – there quite a few examples around – however I made one myself because I needed one that is simple to use. First about the capabilites… TTimer can be set to a certain amount of milli seconds, periodically polled and when this time passed it calls a function of type: void function(). If nothing else is specified it starts over, but you can restrict the  class to repeat this a certain amount of time.

To instantiate TTime the following is required at minimum:

TTimer timer = TTimer(time, callback)

where call back is a function of the type void (*callback)());

The class can provides functions to read the remaining time and the state of the timer. The class returns one of the following states:

  • STOP (the timer has been disabled)
  • RUN  (the timer is activ and counting)
  • HALT  (the timer ended)
  • CLEAR  (the timer is deleted respectivly does not exist)

TTimer to be polled through timer.run(). However when your application requires synchronized timing you can also poll and pass the actual  with timer.run(time).

TTimer.h

#ifndef _TTIMER_H_
#define _TTIMER_H_

class TTimer {
 public:
 enum Mode_t {STOP, RUN, HALT, CLEAR};

 private:
 unsigned char _signal;
 unsigned long _lastTime;
 unsigned long _trig;
 unsigned long _time;
 int _cycl;
 Mode_t _mode;
 void (*_callback)();

public:

 TTimer();

 // Constructor with setup - limited cycles/repetitions
 TTimer(unsigned long time, int rept, void (*callback)());

 // Constructor with setup - unlimited cycles/repetitions
 TTimer(unsigned long time, void (*callback)());

 // Init timer with limited cycles/repetitions
 void init(unsigned long time, int rept, void (*callback)());

 // Init timer with unlimited cycles/repetitions
 void init(unsigned long time, void (*callback)());

 // Set time
 void setTime(unsigned long time);

 // Set cycles/repetitions
 unsigned long getTime() { return _time; };

 // Set cycles/repetitions
 void setCycles(int cycles);

 // Clear the timer
 void clear();

 // Reset a running timer
 void reset();

 // Enable timer
 void enable();

 // Disable but not clear timer
 void disable();

 // Process timer
 int run();

 // Process timer at a given time - returns signal !=0 means timer expired
 int run(unsigned long now);

 // Returns current timer mode
 Mode_t getMode();
};

TTimer.cpp

#include <Arduino.h>
#include <limits.h>
#include <TTimer.h>

// ---------------------------------------------------------------------------
TTimer::TTimer() {
 clear();
}

// ---------------------------------------------------------------------------
TTimer::TTimer(unsigned long time, void (*callback)()) {
 init(time, callback);
}

// ---------------------------------------------------------------------------
TTimer::TTimer(unsigned long time, int cycl, void (*callback)()) {
 init(time, cycl, callback);
}

// ---------------------------------------------------------------------------
void TTimer::init(unsigned long time, int cycl, void (*callback)()) {
 clear();
 _callback = callback;
 _time = time;
 _cycl = cycl;
 _trig = millis();
 _mode = RUN;
}

// ---------------------------------------------------------------------------
void TTimer::init(unsigned long time, void (*callback)()) {
 init(time, -1, callback);
}

// ---------------------------------------------------------------------------
void TTimer::reset() {
 if (_mode == RUN) _trig = millis();
}

// ---------------------------------------------------------------------------
void TTimer::clear(){
 _callback = NULL;
 _mode = CLEAR;
}

// ---------------------------------------------------------------------------
void TTimer::enable() {
 if (_mode != CLEAR) {
 _trig = millis();
 _mode = RUN;
 }
}

// ---------------------------------------------------------------------------
void TTimer::disable() {
 if (_mode != CLEAR) _mode = STOP;
}

// ---------------------------------------------------------------------------
void TTimer::setTime(unsigned long time) {
 _time = time;
}

// ---------------------------------------------------------------------------
void TTimer::setCycles(int cycles) {
 _cycl = cycles;
}

// ---------------------------------------------------------------------------
TTimer::Mode_t TTimer::getMode() {
 return _mode;
}

// ---------------------------------------------------------------------------
int TTimer::run() {
 return run(millis());
}

// ---------------------------------------------------------------------------
int TTimer::run(unsigned long now) {

 _signal = 0;

// If current timer is inactive proceed to the next
 if (_mode != RUN) return _signal;

// Determine the elapsed time since trigger
 long elapsed = now - _trig;

 // if timer is not expired proceed stop further processing
 if (( (unsigned long)(elapsed)) < _time) return _signal;

 // the timer expired, set a flag
 _signal = 1;

 // trigger call back function if defined
 if (_callback != NULL) _callback();

 // Restart timer if required
 if ( _cycl < 0 ) {
 _trig = now;
 }
 // Repeat timer
 else if ( _cycl > 0 ) {
 _cycl--;
 _trig = now;
 }
 // Halt timer
 else if ( _cycl == 0 ) {
 _mode = HALT;
 }

 return _signal;
}

TTimer as library including an example can be found here for download

TCounter (Arduino Library)

When programming you will find some common functionalities you need over and over again. Well, this is all about reuseablility, software packaging,  Object Orientation etc. As this story has been discussed by many for years I stop now and dive into the actual subject of this post.

I have prepared a few Arduino C++/processing classes, packaged them as libraries and released them on github. In this and the following posts I will explore one after the other.

The first one is TCounter

A simple counter that can count up-down (e.g. 1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3…) or in cycles (1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1, 2, …). The counter has to be initialized with start value, counter step, lower boundary, higher boundary and counter type like follows:

TCounter counter = TCounter(start, step, lower, higher, TCounter:UPDOWN);

Then use the counter as follows:

counter.decrement(); // reduces the counter by step while maintaining the boundaries
counter.increment(); // adds the counter by step while maintaining the boundaries
counter.getSignal(); // returns >0 if the boundary was reached with the last step
counter.getValue() ; // returns the actual counter value

Here the source code which also available here

TCounter.h:


#ifndef _TCOUNTER_H_
#define _TCOUNTER_H_

class TCounter {

 public:
 // Counter types
 enum Mode_t {FIXED, UPDOWN, CYCLER};

 private:
 char _signal;
 int _value;
 int _step;
 int _min;
 int _max;
 Mode_t _mode;

 // Internal helper functions
 void doUpdate();
 void doUpDown();
 void doCycler();

 public:

 // Constructor with setup
 TCounter(int value, int step, int min, int max, Mode_t mode);

 // Setup the counter
 void init(int value, int step, int min, int max, Mode_t mode);

 // Get actual counter value
 int getValue();

 // Read signal - counter reached one limit
 char getSignal();

 // Override current counter value
 void setValue(int value);

 // Adjust counter steps
 void setStep(int value);

 // Adjust counter min
 void setMin(int value);

 // Adjust counter max
 void setMax(int value);

 // Increment counter
 char increment();

 // Decrement counter
 char decrement();
};

#endif

TCounter.cpp


#include "TCounter.h"

// ---------------------------------------------------------------------------
TCounter::TCounter(int value, int step, int minVal, int maxVal, Mode_t mode) {
 init(value, step, minVal, maxVal, mode);
}

// ---------------------------------------------------------------------------
void TCounter::init(int value, int step, int minVal, int maxVal, Mode_t mode) {
 _value = value;
 _step = step;
 _min = minVal;
 _max = maxVal;
 _mode = mode;
 _signal = 0;
};

// ---------------------------------------------------------------------------
int TCounter::getValue() {
 return _value;
};

// ---------------------------------------------------------------------------
char TCounter::getSignal() {
 return _signal;
};
// ---------------------------------------------------------------------------
void TCounter::setValue(int value) {
 _value = value;
};

// ---------------------------------------------------------------------------
void TCounter::setStep(int value) {
 _step = value;
}

// ---------------------------------------------------------------------------
void TCounter::setMin(int value) {
 _min = value;
}

// ---------------------------------------------------------------------------
void TCounter::setMax(int value) {
 _max = value;
}

// ---------------------------------------------------------------------------
char TCounter::increment() {
 doUpdate();
 return _signal;
}

// ---------------------------------------------------------------------------
char TCounter::decrement() {
 _step = -_step;
 doUpdate();
 _step = -_step;
 return _signal;
};

// ---------------------------------------------------------------------------
void TCounter::doUpdate() {

_signal = 0;

switch(_mode) {
 case TCounter::UPDOWN:
 doUpDown();
 break;

case TCounter::CYCLER:
 doCycler();
 break;

 default:
 break;
 }
};

// ---------------------------------------------------------------------------
void TCounter::doUpDown() {

 _value += _step;

 if ( _value > _max ) {
 _value = _max;
 _step = -_step;
 _signal = 1;
 }
 else if ( _value < _min ) {
 _value = _min;
 _step = -_step;
 _signal = 1;
 }
};

// ---------------------------------------------------------------------------
void TCounter::doCycler() {

 _value += _step;

if ( _value > _max ) {
 _value = _min;
 _signal = 1;
 }
 else if ( _value < _min ) {
 _value = _max;
 _signal = 1;
 }
};

Thats it.  The library is quite simple but I found it also quite handy for various purposes. If you grap the source from here you can put it into your library folder and use the bundled example to play around with it.