Dec 30

Being a Gadgeteer Module junkie I was very excited when GHI Electronic released their Distance US3 Module as while I had built a working Ultrasonic range finder using raw components but I’ve always preferred using native Gadgeteer modules, however after working with this module there were a couple of things that didn’t quite work up to my expectations so I thought I would do some testing to further my understanding of the module and how it works.  I started this adventure as I do all my adventures with gratuitous testing in order to identify possible focus areas and then to run more detailed testing to explore possible issues.  I thought I was done a couple of times, but then something unexpected would happen and off I’d go to understand what I’d seen.

The module was stated to have 2cm to 400cm range and I never seemed to get that so I thought I’d written my own drivers for my custom range finder, why not write my own now as the concept of these devices is very simple, as they send out a sound ping and then listens for the reflected sound to return and if you know the time that it takes then you can calculate the distance to the object the sound reflected off of.  Now let me state you can build tons of devices with Gadgeteer without ever having to touch or look at a driver as modules you buy already have drivers, however it won’t be long till you become a tad curious as to what drivers look like and once you start learning about them you will be writing your own in no time, especially considering there is a module driver template in Visual Studio that makes it easy.

So this is the driver I wrote, and please understand I was also experimenting with various ideas and so this driver has some ‘features’ that might seem like over kill, but it was all part of the fun.

using System;
using System.Threading;
using Gadgeteer.SocketInterfaces;
using Microsoft.SPOT.Hardware;

namespace Gadgeteer.Modules.GHIElectronics
{
    /// <summary>
    ///     A DistanceUS3 module for Microsoft .NET Gadgeteer
    /// </summary>
    public class DukeNukemDistanceUS3 : Module
    {
        /// <summary>
        ///     Represents the state of the <see cref="Button" /> object.
        /// </summary>
        public enum Errors
        {
            /// <summary>
            ///     No Pulse Detected
            /// </summary>
            NoPulse = -1,

            /// <summary>
            ///     Object possibly out of range
            /// </summary>
            NoReading = -2,

            /// <summary>
            ///     Object possibly to close
            /// </summary>
            ToClose = -3
        }

        private const int MIN_DISTANCE = 2;
        private const int MAX_DISTANCE = 400;
        private const double TicksPerSecond = TimeSpan.TicksPerSecond;
        private double _temp = 20; //default temp 20C
        private double velocityEcho = 17130.18243; //default factor calculated for 20C
        private readonly DigitalInput echo;
        private readonly int MAX_COUNT;
        private readonly int PULSE_COUNT;
        private readonly int TicksPerLoop;
        private readonly DigitalOutput trigger;

        /// <summary>
        ///     Constructs a new instance.
        /// </summary>
        /// <param name="socketNumber">The socket that this module is plugged in to.</param>
        public DukeNukemDistanceUS3(int socketNumber)
        {
            var socket = Socket.GetSocket(socketNumber, true, this, null);
            socket.EnsureTypeIsSupported(new char[2]
            {
                'X',
                'Y'
            }, this);
            echo = DigitalInputFactory.Create(socket, Socket.Pin.Three, GlitchFilterMode.Off, ResistorMode.Disabled,
                this);
            trigger = DigitalOutputFactory.Create(socket, Socket.Pin.Four, false, this);

            //Get some performance indicators
            var counter = 0;
            var start = DateTime.Now.Ticks;
            while (start > 0)
            {
                if (++counter > 0)
                    break;
                start--; //just for fun
            }
            var end = DateTime.Now.Ticks;
            TicksPerLoop = (int) (end - start);

            //Calculate reasonable loop counter limits
            MAX_COUNT = (int) ((TicksPerSecond*0.03)/TicksPerLoop);
                //based on time it takes sound to travel almost 9 meters
            PULSE_COUNT = (int) (MAX_COUNT*0.1);
            if (PULSE_COUNT < 10)
                PULSE_COUNT = 10;
        }

        /// <summary>
        ///     Temperature correction in Celsius (default 20C).
        /// </summary>
        public double Temperature
        {
            get { return _temp; }

            set
            {
                //simple calculation, just do it
                _temp = value;
                velocityEcho = Math.Sqrt((_temp + 273.15)*400.4)*50.0;
            }
        }

        /// <summary>
        ///     Gets distance in centimeters.
        /// </summary>
        public double GetDistance()
        {
            long start, end;

            var counter1 = 0;
            var counter2 = 0;

            trigger.Write(false);
            Thread.Sleep(1);

            trigger.Write(true);
            Thread.Sleep(1);
            trigger.Write(false);

            while (!echo.Read())
            {
                if (counter1++ > PULSE_COUNT)
                    return -1.0;
            }

            start = Utility.GetMachineTime().Ticks;

            while (echo.Read())
            {
                if (counter2++ > MAX_COUNT)
                    return -2.0;
                //Thread.Sleep(0);
            }

            if (counter2 == 0)
                return -3.0;

            end = Utility.GetMachineTime().Ticks;

            var distance = velocityEcho*(end - start)/TicksPerSecond;

            return distance;
        }

        /// <summary>
        ///     Gets distance in inches.
        /// </summary>
        public double GetDistanceInches()
        {
            var d = GetDistance();

            if (d < 0)
                return d;

            return (0.39370079*d);
        }
    }
}

So lets look at a couple of sections in detail

            while (!echo.Read())
            {
                if (counter1++ > PULSE_COUNT)
                    return -1.0;
            }

This is the first loop where we have created the ping and we are listening for the ping going out, so this should almost be immediate given the ping source and the listener are by side so the limiting PULSE_COUNT can be very much smaller then the limiting COUNT waiting for the echo.  If we miss the initial ping out, waiting around isn’t going to help anything except burn up valuable cpu cycles and time, so if you didn’t catch the initial ping out quickly report an error and exit.

The second loop is very similar but here we are waiting for the echo to return.

            while (echo.Read())
            {
                if (counter2++ > MAX_COUNT)
                    return -2.0;
                //Thread.Sleep(0);
            }

I’m often torn on sleep statements as I love sneaking in cycles else where whenever possible, but in this case when we get to slower mainboards a sleep here is killer in terms of measurement accuracy, even if the Sleep is a Sleep(0) which basically surrenders the rest of this thread’s time slice.  Again note the use of a Counter to limit the loop and given this sound is traveling further (a maximum of 8m, ie 4m each way) we will want to set a reasonable limit as readings over 4 m should be considered suspect. Which is why we have this code in the initialization routine:

            //Get some performance indicators
            var counter = 0;
            var start = DateTime.Now.Ticks;
            while (start > 0)
            {
                if (++counter > 0)
                    break;
                start--; //just for fun
            }
            var end = DateTime.Now.Ticks;
            TicksPerLoop = (int) (end - start);

            //Calculate reasonable loop counter limits
            MAX_COUNT = (int) ((TicksPerSecond*0.03)/TicksPerLoop);
                //based on time it takes sound to travel almost 9 meters
            PULSE_COUNT = (int) (MAX_COUNT*0.1);
            if (PULSE_COUNT < 15)
                PULSE_COUNT = 15;

Given the current range of CPU speeds for Gadgeteer is from a subdued 72MHz. 32-bit ARM7 found in a Spider Mainboard to a rip your eyes out of their socket from the back of your skull 400 MHz 32-bit ARM 9 found in the Raptor, one must be careful not to make assumptions about performance, so some simple tests are in order to tweak the module performance to its best for every case.  So while we can query the hardware to get ticks per second, what we really want is roughly how many ticks per while loop iteration, so this simple test can give us a reasonable ballpark figure.

            var counter = 0;
            var start = DateTime.Now.Ticks;
            while (start > 0)
            {
                if (++counter > 0)
                    break;
                start--; //just for fun
            }
            var end = DateTime.Now.Ticks;
            TicksPerLoop = (int) (end - start);

Now that we have an idea of loop speed, now we need to calculate loop limits for roughly how long it takes sound to travel roughly 10 m which gives up a bit of a safety margin.

            MAX_COUNT = (int) ((TicksPerSecond*0.03)/TicksPerLoop);
                //based on time it takes sound to travel almost 10 meters
            PULSE_COUNT = (int) (MAX_COUNT*0.1);
            if (PULSE_COUNT < 10)
                PULSE_COUNT = 10;

Then we take a fraction of that for the detection of the outbound Ping.

As far as performance went I was able to get the full 2cm to 400cm range using the Raptor and Cerberus, but the due to the Spiders reduced performance the minimum distance measured was in the range of 15cm.

One of the other things I wanted to try was a temperature correction as temperature has the biggest effect on the speed of sound through air.  A commonly used equation is

V = 331.4 + 0.6 * T

but I started life off as an Engineer and prefer something a little more accurate

image

where we use the ratio of specifics heats (1.4 for air at STP) and R is the gas constant (286 m2 / S2 / K for air) and T is the absolute temperature (273.15 + C).   So we make Temperature a property with a default of 20C and calculate a factor for every temperature set

        public double Temperature
        {
            get { return _temp; }

            set
            {
                //simple calculation, just do it
                _temp = value;
                velocityEcho = Math.Sqrt((_temp + 273.15)*400.4)*50.0;
            }
        }

So now we simply multiple this factor by our time and we get our distance as we already have our half distance (ie the the sound traveled there and back) correction in this factor.

This worked out rather well, but certainly my neighbours must have thought my cheese has slipped off my cracker standing outside in the –20C weather and wondering what I was pointing at my house and sky (testing the no return echo case), but I suspect they are used to me testing all sorts of devices by now.

Now granted this is taking a simple module to an extreme, but sometimes isn’t that the fun of the adventure.

WP_20141226_15_47_32_Pro

During Raptor testing the distances were tape measure close but what I was more interested in was the deviations which I use to indicate the ‘wobble’ of the measurement and looking at my results

2 cm 5 cm 10 cm 20 cm 50 cm 75 cm 100 cm
2.046806 4.222287 9.30044 18.06049 44.81205 67.01156 89.46895
0.167092 0.1243 0.22035 0.2911 0.237223 0.17363 0.272982
             
150 cm 200 cm 250 cm 300 cm 350 cm 400 cm  
134.1193 178.8136 220.7308 266.2561 339.7466 549.5284  
0.454754 0.439135 0.570651 0.670198 0.922268 605.4946  

 

You can see that the measurements are fairly consistent until we get to the 400+ cm range then the consistency drops off as sometime I didn’t get valid readings so we were pushing it a bit at that range.

My measurements were consistently better then the native driver, but it should also be mentioned that differences did exist between individual modules when run with the same driver so while my driver seemed better I certainly wouldn’t feel right about claiming all the improvements I saw were due entirely to the new driver.

WP_20141230_04_18_49_Pro

When testing the Spider the slower speed meant that the shortest distance I could measure was around 15 cm on the low end but was able to measure into the 400 cm range.  When testing the Spider below its minimum range the error handling times between the native driver and my driver was very apparent as my driver quickly reported back the error because of the lower PULSE_COUNT limiter on the while loop iterations whereas the native driver took significantly longer.

The test results for the Cerberus were similar to the Raptor in that I was able to measure from 2cm up into the 400cm range.

WP_20141230_04_44_28_Pro

Certainly this was a fun learning experience in that I got to ‘think’ about something over a busy Christmas and do a little coding and testing and feel that I learned a little more about Gadgeteer drivers and some of the issues around ultra sonic ranging.

Remember good programmer write code that works, great programmers write code that works when things go funky as you should always consider more then just the ‘working’ scenarios.

Gadgeteer ROCKS!!!!

Nov 11

Being fortunate enough to be a Microsoft MVP (Developer Security) I was able to attend the MVP Summit 2014 meeting at Microsoft Redmond and spent most of my time with the Embedded MVPs and Microsoft IoT Product Group which I really enjoyed as IoT has been a personal passion of mine for many years.  On the last day of the conference are side sessions where the groups at Microsoft who don’t have MVPs can present to interested MVPs and this year the Microsoft Accessibly group scheduled a full day of sessions which really caught my attention as this has been an interest of mine for a long time as well.  When I was at the University of Calgary in the late 80’s I taught special sessions for Visually Challenged students (I’d be remised if I didn’t mention Norman Palardy as he was the other session instructor and friend)  as the thinking was that Computer Science is a very cerebral activity and hence could be a viable occupation for someone with visual challenges.  While some of the students did manage to graduate with a degree in Computer Science I have to applaud their persistence as while the course material is difficult, the challenges of working with the existing technology etc  as a sight challenge student was ridiculously difficult.  Life in general for people with challenges is ridiculously difficult, for example in the US 65% of people with vision loss are unemployed and even those who are employed are often paid less then their co-workers.  Now one can argue all sorts of realities etc, but technology is the tool we use to change our realities, for example two hundred years ago it took weeks to cross the Atlantic in a sailing ship, then we invented self powered ships that only took days to cross the Atlantic and now it only takes hours as we fly across the Atlantic.  One reality we face today is as our life expectance increases so do our chances of personally living with disabilities so people should be far more empathetic and motivated for improvements in areas of computer accessibility as work in this field doesn’t just benefit those with disabilities but everyone, for example the idea of pinch and zoom is from enabling low vision users in the early 80’s (thank you University of Toronto for multi-touch gestures) but now it benefits all users.  My students used a couple of inventions by Ray Kurzweil, first was a CCD flatbed scanner which we used to scan the text books and then a OCR (Optical Character Recognition) system used to take those scans and produce digital versions of the text books (there were no ebooks back then so yet another spin off that everyone uses today) and we used his reader so our students could listen to those book and screen scrapers which pulled the text off of their computer screens so they could work with the compilers etc.  All of these technologies are used by everyone today, but were initial created as a solution for challenged users.  May we continue to use technology make the world a better and more accessible place for everyone.

Some Links you might be interested in.  First is Microsoft’s Accessibility Site which is a great starting point as a user, developer or IT Pro.

Guy Barker presented on his experiences as developer building apps which used various interfaces which as a developer was very interesting http://blogs.msdn.com/b/accessibility/archive/2014/01/28/windows-developer-quietly-creates-apps-to-help-people-with-disabilities-communicate.aspx

And a recent project that was shown that as a developer and embedded device guy I found very inspiring

 

More complete write up of the Independence Day Project

Jun 05

I have funded a number of projects on KickStarter and elsewhere and have been really happy with the products which I’ve received and I even remember to blog about some of them.  Today my Waka Waka Power arrived and it is really as cool as I thought it was going to be.

WP_20130605_002

One of the features that attracted me to this was the solar panel which is next generation with 23% efficiency and it does look different then any other solar panel you have seen and can fully charge the 2750 mAh internal battery in 8 hours, even in Calgary.

WP_20130605_005

Now this is more then just a light, and what a light with spec like this on a single full charge:

  • Bright 20+ Hours
  • Reader 40+ Hours
  • Saver 200+ Hours

When they say bright we are talking about hurt your eyes its so bright, which again is an indication that they didn’t use your Daddy’s parts to make these as these are superbright A-brand LEDs with a combined output of 60 lumens so that is pretty good light, with exceptional duration.

WP_20130605_015

What I really got this for was to have a high efficiency solar panel in a compact (its a bit smaller then my cell phone) rugged form for charging my cell phone (loving my Nokia Lumina 920 Windows Phone) or to charge my CamelBak All Clear UV Water Purification water bottles as my 72 Hour Pack has a number of high tech components in it that all center on using or providing USB power, like my BioLite Stove or my Bootstrap Solar Charger Kit as in an emergency you can’t count on the grid and your cell phone is likely to be far more important then you would think (communication device for requesting help or letting others know your OK etc).  For example in the recent Sandy Hurricane 75% of the cell towers in the affected areas were working so if you had a way to charge your cell phone, you likely had communication capabilities.

WP_20130605_008

The USB out port can provide 1 A which should fully charge a phone in 2hours. This is a well engineered product as the thought and consideration taken show in a number of ways and I know I’ll get years of excellent service from this.

Why you want a Waka Waka

This was a KickStarter project with a social aspect as the project was so successful in attracting backers that they were able to included some goodies (expanded battery capacity, waterproof pouch, but the stretch goal that impressed me was that they assembled these in Haiti (providing employment to people who really need it), and were able to provide a large number (over 17,000) for humanitarian use for Syrian refugees and Haitian families living without electricity.  One of the big risks to safety in refugee camps is the use of candles or kerosene lamps etc in flammable tents.  I know some people that I mentioned this to were sceptical that someone would actually give these away, but they do and you can read about their efforts in Haiti here.  So not only did I get a cool piece of technology, but I also helped make the world a little brighter for someone else as well, what could make cool technology better?

Tags:
Jan 22

In my office I have some Kentia Palm Trees on either side of my desk as Palm Trees are likely one of my favourite trees, as where you have Palm Trees, you don’t likely have snow, so I guess I associate Palm Trees like many others with warmth and beaches.

Now I’ve had a Gadgeteer device monitoring them for awhile now, but I wanted to take this device to the next level and not just monitor the conditions, but to inform me about those conditions and do it in different ways.  So of course the first idea is to have the device email me when the soil gets dry and let me know that I need to water my Palms, but that turned out to be trivial, so I wanted something a little more challenging, so how about being able to log into a web server on the device and get the current conditions, well with Gadgeteer that is trivial as well.  OK so how about uploading the condition data to a web site so I can login in and graph the data over some period of time so I can see trends etc, well bugger that was easy too.  So how about I have the device give my Palm Trees a life in the twitter world, by letting my Palms send tweets pertaining to the soil moisture, temperature, light etc and even send out tweets contains Palm Tree trivia and then for bonus points have the device do all of these things at once.  Well no problem with Gadgeteer, so here it is:

IMG_1163

And a YouTube video describing it

My Palm Tree Monitors

Source code etc is available here:

http://www.tinyclr.com/codeshare/entry/639

Now granted I’m not a rookie coder, or someone who is afraid to try something new or lacks ideas or vision, and so Gadgeteer gives me a powerful medium in which to explore and express some of my ideas.  I see lots of Ardunio demo projects where someone is flashing some LED’s or something and I think, hey that is great, but I dream much bigger then that and so I need a tool that won’t limit my imagination or make it impossible to express my ideas, so Gadgeteer is my tool of choice for building devices.  Now that I have this device working, now its time to let my imagination run wild and design and build another uber cool Gadgeteer device.

The Kentia Palm is from Lord Howell Island and here is one company which grows Palms for export from Lord Howell Island.  I must admit I was surprised and impressed at the level of automation and that it takes at least 4 years to grow a Palm for shipment.  I’m sure they would appreciate the device I built to monitor my Palms.

Shows some of the automation used in growing Kentia Palms
Jan 09

Gadgeteer is really starting to hit its stride as when you can get a Color Sensor module, you got to know that there are getting to be a lot of different modules.  So one of my objectives this year is to try to post at least one Gadgeteer project a month on YouTube and Code Share as I think if you believe if something is good then you should let other people know about it.  In November I posted a Gadgeteer Gas Sensor which uploads its readings in real-time to ThingSpeak and uses ThingSpeak services to send out Twitter messages as gas concentration alerts and alarms and its been running for the last two months using different gas sensors.

My Gas Sensor Project

Today I posted my Color Sensor project onto YouTube

My Color Sensor Project

As I wanted to show off some cool Seven Segment LED’s which are expandable.  Want only two digits or twenty, no problem you just clip them together to whatever length you need.  Also they come in different colors, so what else could you want.  As I mentioned in the video it also gave me a chance to try out a color sensor, as I recently had one person telling me about how amazing their photocopier was because they could tell it to copy something onto blue paper and it could figure out which bin had the blue paper in it.  Twenty years ago that might have been rocket science, but now its a wonder that not every photocopier on the planet doesn’t include such a cheap and trivial to build and code feature.

I’ve likely spent far too much on Gadgeteer but for me my candy is creating stuff so if you walk into my office you will see a number of Gadgeteer projects in various stages of creation so that is what I get from Gadgeteer,  creative freedom.  Someday Gadgeteer could be the next greatest thing in IT as smart devices or the ‘Internet of Things’ becomes all the rage, but for me its about exercising my creative process now.

Now what should I create to post on YouTube next, so many choices…..

Tags: