Friday, March 14, 2014

Microsmooth : Signal Smoothing Library for Arduino

During the past few months we have started work on our quadcopter platform, unimaginatively called MICAV. The quadcopter is a micro aerial vehicle with a span of less than 45 cm. The MICAV is currently being controlled remotely using the Avionic RCBX7 transmitter receiver. The device is fairly complex allowing for 7 channel control, and contains a lot of inbuilt functionality. The signals are sent to the Arduino Uno from the receiver. These are then processed, and the motor control signals are set.

As we were testing the controls, we noticed a rather odd pattern. The RPM was changing quite audibly on the motors with a high frequency. Our initial guess was that the wiring must be loose somewhere and we went over the entire circuit. Next, we tested out the motors using a control signal being generated via values sent over serial. The motors performed correctly. Nothing wrong with the motors. Phew!

This left only when avenue to explore. The RX-TX itself. We then hooked up it up with the Arduino and observed the input values being received. The results explained the problem. It was noise all along!



Noise was interfering with the control signals far too much. This necessitated the need for some signal processing to be done before sending it further. To resolve, we started exploring libraries in Arduino-verse that deal with signal processing. We found no relevant ones. The ones we did find that could work for us, were too expensive to use in terms of time and space. We then moved to studying the algorithms ourselves and implemented them. Over the course of two weeks, we programmed and tested about 5-6 algorithms with many variations of parameters.

The algorithms that we implemented are:
  • Simple Moving Average
  • Cumulative Moving Average
  • Exponential Moving Average
  • Savitzky Golay Filter
  • Ramer Douglas Peucker Filter
  • Kolmogorov Zurbenko Filter
Some performed surprisingly well, given the time and size constraints that were imposed.

The green signal is the result of the SMA filter applied to the input. This was one of the mediocre performing cases.

Now, given that there were no existing libraries that were suited to this task when we started to look, we felt it was best to release our code in the form of library, to help out others who may travel down this path. So, then Microsmooth came into existence!

Microsmooth hosted on Github, maintained by me and Pranav, is intended to be lightweight and fast for use in time critical Arduino-based applications. Given that none of the code is Arduino specific, it can even be used on other microcontrollers and platforms, but we make no promises. Time optimizations will eventually make us utilise microcontroller specific features, which may make the library tied down to a specific platform.

To use the library, paste the files in the source directory, and add the following include:
    #include "microsmooth.h"    

The library is still in development and we aiming to improve the overall library in many areas.
  • Reduced memory utilization
  • Improved algorithm performance
  • Addition of new filters and greater control over existing parameters
  • Switches to result in smaller footprint of the code

The library will become more stable and flexible in the months to come.

6 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Thank you for releasing your work to the community! I see in your documentation on github the instructions:

    • input your analog signal value using analogRead() or pulseIn into an int variable.
    • Pass the variable into the filter initialized in the first step: int processed_value = sma_filter(channel_value, history);
    • Repeat for input channel for a time domain signal.

    To clarify, does this mean channel_value is what you called "analog input signal"? And history is what you called "filter", i.e. the arbitrary name for each input signal's past readings?

    A few other questions:

    Are there plans to make this work with float input? (Smoothing, for example, proximity sensor readings in cm would be useful, although you could of course convert or even smooth the echo times first).

    Can you specify the strength/weight of a given filter?

    What filter gave ended up giving you the best results for your quadcopter control signal example above?

    Thank you!

    ReplyDelete
    Replies
    1. Thanks for the feedback! I realise the documentation does not provide technical details; I will try to improve that. I am in the middle of my exams at the moment, so a little short on time. I will add more details in about 2 weeks.

      > To clarify, does this mean channel_value is what you called "analog input signal"?

      Yes.

      > And history is what you called "filter", i.e. the arbitrary name for each input signal's past readings?

      History refers to the array declared in the initialization step. Filter refers to the algorithm being used.

      > Are there plans to make this work with float input? (Smoothing, for example, proximity sensor readings in cm would be useful, although you could of course convert or even smooth the echo times first).

      The reason I stayed away from floats is due to the time increase, and my top priority while designing this was to minimize the time being taken. At present, most filters work in 100-150 milliseconds with decent smoothing. I will take a look at this in a couple of weeks.

      > Can you specify the strength/weight of a given filter?

      We did a very thorough analysis of the filters some time back, including with variations in the parameters. I will upload the results soon. At present, the parameters are defined in the header file, which you can edit and test to get better performance.


      > What filter gave ended up giving you the best results for your quadcopter control signal example above?

      EMA with alpha 0.10

      Delete
  3. sorry Mr. Ranjan, i'm in training for development arduino..
    i want to ask, did you think microsmooth library can beadopt for temperature and Humidity sensors? like DHT11 or DHT22
    thank you..

    ReplyDelete
  4. Just want to say thanks, keep it going!

    ReplyDelete
  5. great solution, but maybe it was the transmitter and not the receiver though.. just a thought.

    ReplyDelete