A Speed Machine?

Please excuse the title. I worked on a short project that my son (age 6) suggested measuring how fast he could run. This was the reason behind my post on ultrasonic sensors in fact. The working principle of the device is effectively two barriers a known distance apart that a person runs through and the time taken is then used to calculate their speed. I decided to use two ultrasonic sensors in the end. Initially, I wanted light gates but this turned out to be more expensive and more complicated to set up (reflectors, alignment, more hardware etc). Eventually, we hacked some hardware together. Here’s a demo…

You can see that this rig is very rough but hopefully demonstrates the concept to you. I was really interested in getting to grips with C++ a little more as it’s starting to become important for me at work.

I decided to go for a simple architecture that was centred around a controller class that is responsible for doing the speed calculation when it receives calls from barriers and updating the display when results arrive…

    class Controller : public BarrierListener
    {
    public:
        Controller(
            Barrier* barrier1, Barrier* barrier2, Display* display);// :
        void start(void);
        bool isReady(void);
        void stop(void);
        void setUnits(Units);
        void setBarrierDistanceM(double);
        // need to obscure this somehow...
        void handleBarrierTriggered(Barrier* barrier);
    private:
        double calculateVelocity(double transitSec);
        static uint32_t maxTransitSec;
        static double barrierDistanceMetres;
        static double conversionFactors[];
        static Units units;
        Barrier* barrier1;
        Barrier* barrier2;
        Display* display;
    };

The controller is responsible for specifying its dependencies for example the barriers and display as abstract base classes in the same source file…

    class Barrier
    {
    public:
        virtual bool isEnabled(void) const = 0;
        virtual bool isTriggered(void) const = 0;
        virtual void enable(void) = 0;
        virtual void disable(void) = 0;
        virtual uint32_t triggeredAt(void) = 0;
        void registerListener(BarrierListener* toRegister) {listener = toRegister;}
    protected:
        BarrierListener* listener = NULL;
    };

    class Display
    {
    public:
        virtual void clear(void) = 0;
        virtual void showDecimal(double decimal, uint8_t precision) = 0;
        virtual void doAnimation(void) = 0;
    };

You can see that the barrier must register a listener which in this case will be the controller class. The rest of the api is relatively obvious. I fleshed out these classes as you can see on the project github page. There were some details to work out such as specifying the distance at which the barriers should trigger and debouncing their output (it was rather noisy especially the edges when an object was detected).

I’m not convinced about this measurement technique since the ultrasonic barriers can be triggered inconsistently depending on the target’s distance; their ultrasound output spreads out. However, I certainly enjoyed this project and it’s made me hungry for more C++ and given me an opportunity to explore writing a project rather than reading examples and doing exercises.

You can find a link to the project here.