Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Playground Wiki / Re: ISP page improvement? on: July 14, 2010, 11:20:43 am
Ah, OK. I missed that one completely!
2  Forum 2005-2010 (read only) / Playground Wiki / ISP page improvement? on: July 08, 2010, 10:45:35 am
I was reading about using the Arduino as an ISP/ICSP. What wondered me, is the complexity of the wiring... And looking at the schematic of a board, I guess using a 1:1 1pin header cable between both boards ICSP connectors would do the trick just as good. Many people have 6 (or 10) pin header connectors/cables laying around anyway, so why don't show that option?

Regards,

René
3  Forum 2005-2010 (read only) / Syntax & Programs / Re: A FIR Finite Impuls Response filter routine on: August 01, 2010, 07:35:18 am
Hello Henrik,

I hope this works for you. There is many info on the Arduino website about putting routines in a library. Basically you take the routines that are in this post and put them in the appropriate files for the library. Take a closer look at http://www.arduino.cc/en/Hacking/LibraryTutorial to see what I mean.

Height control from different sources... hmm, that sounds like a job better done with a Kalman filter, or a PID regulator! Take a look at http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1225283209 and http://starlino.com/imu_kalman_arduino.html

This is why: a filter helps with getting the data evened out, or removing stuff you don't need (noise, high frequencies, low frequencies, hum, etc) but it doesn't add relevance to the data. The Kalman technique does actually that. It takes into consideration what a sensor is good at (a barometer is OK for measuring long-time values that relate to height), and what it's not (a barometer will get noisy from external wind sources, movement of the copter, etc) Look for similarities with Gyro's and accelero's!

PID is the easiest source for stable control of height, although figuring out how to parametrize your PID regulator could be tricky. But in the end, a simple P action, and a little D would help you a lot getting things stable. Drift over time, or going to 'exact x meters' isn't relevant to you (or is it?) so the I action can be left out without a problem. Construction of your E (error) signal is the problem here. I would start off with simply take the set value (from the Remote), substract (0.5 × IR height estimation, and 0.5 × barometer height estimation) You can simply scale both to see what it does. You COULD use a filter (FIR low-pass) to remove HF noise from the barometer, and probably from the IR too. I wouldn't filter too much, though. Probably the best filter there, would be a simple RC filter on the analog outputs!
4  Forum 2005-2010 (read only) / Syntax & Programs / Re: A FIR Finite Impuls Response filter routine on: July 14, 2010, 01:34:34 pm
Ah, that looks a lot more professional. I sort of get the idea here, but I will print it out some time this weekend to see what exactly you did. Do you mind me asking for some explanation at a later time?

I see you use an integer for the indexes. Is this generally a good idea? I am wondering if this doesn't take too many processor cycles and a lot of register swapping on an AVR (I don't know C, but do know something about assembler language)

I guess a byte would be enough, since even for a demanding filter with impressive spec's, 255 steps would be enough. If you need more, you are either looking into the wrong filter design (look for an IIR filter) or doing something that ought not to be done on an Arduino (like detecting stars in a multi-megapixel picture of the sky...)
5  Forum 2005-2010 (read only) / Syntax & Programs / Re: A FIR Finite Impuls Response filter routine on: July 14, 2010, 12:01:53 pm
And this code initiates the indexer [k] at 0:

Code:
/*

Simple FIR filter implementation

This routine is just written as an excersize in Arduino programming.
The routine implements a Finite Impuls Response filter.

Finite Impuls Response filters can be used to create all kinds of filters.
Filters can be used to partially remove noise, remove 'DC' offsets, or 'shape' analogue values. See http://en.wikipedia.org/wiki/Finite_impulse_response to read more aboute FIR filters. Several online sources are available to generate the coefficients. Google for the various sources.

About the routine: it is not really optimized for anything. It accepts exactly one float, spits out one float, and should be called for every sample. For the filter to work as expected, the samples should be 'equidistant' in time, so taken at identical intervals.

Making this an 'integer' function (to make it more usable with the onboard analog inputs) can be done. This would also limit execution time and memory usage.

Talking performance: using floats a 5 tap cycle takes about 180µs, so that is pretty fast and allows about 3~4kHz sample rate, taking some overhead in the main loop into consideration. Using ints or even better bytes should fraction the looptime by at least 4 to 8 times!

Rene Knuvers, 14JUL2010, arduino@reneknuvers.nl

*/

#define FILTERTAPS 5            // The number of taps in your filter, or better the number of coefficients

// declare array for values
float values[FILTERTAPS] = {0, 0, 0, 0, 0}; // to have a nice start up, fill the array with 0's
// NOTE: this could be 1 shorter, as we already have the input in a variable. This would save stack size/memory

// declare input and output variables
float input = 1; // without a real input, looking at the step respons (input at unity, 1) would be nice to see
float output = 0; // output as a 0, but that doesn't really matter

// our counter, real life applications won't need this
byte n = 0;

void setup() {
      Serial.begin(115200);      // open the serial port, I like them fast ;-)
}

float fir(float in){
      static byte k = 0;                  // k stores a pointer to create a circular memory through the array. This variable remains its value the next time we call the fir routine (hence 'static')
      byte i = 0;                        // i is a counter to step through the filter coefficients and stored values
      float out = 0;                        // out is the return variable. It is set to 0 every time we call the filter!

      values[k] = in;                        // store the input of the routine (contents of the 'in' variable) in the array at the current pointer position

      
      // declare variables for coefficients
        // these should be calculated by hand, or using a tool
      // in case a phase linear filter is required, the coefficients are symmetric
      // for time optimization it seems best to enter symmetric values like below
      float coef[FILTERTAPS] = { 0.021, 0.096, 0.146, 0.096, 0.021};

      //declare gain coefficient to scale the output back to normal
      float gain = 0.38; // set to 1 and input unity to see what this needs to be

      
      for (i=0; i<FILTERTAPS; i++) {            // we step through the array
            out += coef[i] * values[(i + k) % FILTERTAPS];      // ... and add and multiply each value to accumulate the output
                                    //  (i + k) % FILTERTAPS creates a cyclic way of getting through the array
        }
      out /= gain;                        // We need to scale the output (unless the coefficients provide unity gain in the passband)

      k = (k+1) % FILTERTAPS;                  // k is increased and wraps around the FILTERTAPS, so next time we will overwrite the oldest saved sample in the array
      
        return out;                        // we send the output value back to whoever called the routine

}


void loop() {

      // This is the loop that takes care of calling the FIR filter for some samples

      for (n = 0; n < FILTERTAPS + 2; n++) {             // If you like to see the step response, take at least as many cycles as the length of your FIR filter (FILTERTAPS + 1 or 2)
            Serial.print("n= ");            // print the sample number
            Serial.println(n, DEC);
            Serial.println("Now calling fir...");
            output = fir(input);            // here we call the fir routine with the input. The value 'fir' spits out is stored in the output variable.
            Serial.print("fir presented the following value= ");
            Serial.println(output);            // just for debugging or to understand what it does, print the output value
      }
      while (true) {};                  // endless loop
}
6  Forum 2005-2010 (read only) / Syntax & Programs / Re: A FIR Finite Impuls Response filter routine on: July 14, 2010, 11:54:23 am
Ah, of course, when it has a value that is greater than the array length... right?
7  Forum 2005-2010 (read only) / Syntax & Programs / Re: A FIR Finite Impuls Response filter routine on: July 14, 2010, 11:52:52 am
The corrected code:

Code:
/*

Simple FIR filter implementation

This routine is just written as an excersize in Arduino programming.
The routine implements a Finite Impuls Response filter.

Finite Impuls Response filters can be used to create all kinds of filters.
Filters can be used to partially remove noise, remove 'DC' offsets, or 'shape' analogue values. See http://en.wikipedia.org/wiki/Finite_impulse_response to read more aboute FIR filters. Several online sources are available to generate the coefficients. Google for the various sources.

About the routine: it is not really optimized for anything. It accepts exactly one float, spits out one float, and should be called for every sample. For the filter to work as expected, the samples should be 'equidistant' in time, so taken at identical intervals.

Making this an 'integer' function (to make it more usable with the onboard analog inputs) can be done. This would also limit execution time and memory usage.

Talking performance: using floats a 5 tap cycle takes about 180µs, so that is pretty fast and allows about 3~4kHz sample rate, taking some overhead in the main loop into consideration. Using ints or even better bytes should fraction the looptime by at least 4 to 8 times!

Rene Knuvers, 14JUL2010, arduino@reneknuvers.nl

*/

#define FILTERTAPS 5            // The number of taps in your filter, or better the number of coefficients

// declare array for values
float values[FILTERTAPS] = {0, 0, 0, 0, 0}; // to have a nice start up, fill the array with 0's
// NOTE: this could be 1 shorter, as we already have the input in a variable. This would save stack size/memory

// declare input and output variables
float input = 1; // without a real input, looking at the step respons (input at unity, 1) would be nice to see
float output = 0; // output as a 0, but that doesn't really matter

// our counter, real life applications won't need this
byte n = 0;

void setup() {
      Serial.begin(115200);      // open the serial port, I like them fast ;-)
}

float fir(float in){
      static byte k;                  // k stores a pointer to create a circular memory through the array. This variable remains its value the next time we call the fir routine (hence 'static')
      byte i = 0;                        // i is a counter to step through the filter coefficients and stored values
      float out = 0;                        // out is the return variable. It is set to 0 every time we call the filter!

      values[k] = in;                        // store the input of the routine (contents of the 'in' variable) in the array at the current pointer position

      
      // declare variables for coefficients
        // these should be calculated by hand, or using a tool
      // in case a phase linear filter is required, the coefficients are symmetric
      // for time optimization it seems best to enter symmetric values like below
      float coef[FILTERTAPS] = { 0.021, 0.096, 0.146, 0.096, 0.021};

      //declare gain coefficient to scale the output back to normal
      float gain = 0.38; // set to 1 and input unity to see what this needs to be

      
      for (i=0; i<FILTERTAPS; i++) {            // we step through the array
            out += coef[i] * values[(i + k) % FILTERTAPS];      // ... and add and multiply each value to accumulate the output
                                    //  (i + k) % FILTERTAPS creates a cyclic way of getting through the array
        }
      out /= gain;                        // We need to scale the output (unless the coefficients provide unity gain in the passband)

      k = (k+1) % FILTERTAPS;                  // k is increased and wraps around the FILTERTAPS, so next time we will overwrite the oldest saved sample in the array
      
        return out;                        // we send the output value back to whoever called the routine

}


void loop() {

      // This is the loop that takes care of calling the FIR filter for some samples

      for (n = 0; n < FILTERTAPS + 2; n++) {             // If you like to see the step response, take at least as many cycles as the length of your FIR filter (FILTERTAPS + 1 or 2)
            Serial.print("n= ");            // print the sample number
            Serial.println(n, DEC);
            Serial.println("Now calling fir...");
            output = fir(input);            // here we call the fir routine with the input. The value 'fir' spits out is stored in the output variable.
            Serial.print("fir presented the following value= ");
            Serial.println(output);            // just for debugging or to understand what it does, print the output value
      }
      while (true) {};                  // endless loop
}
8  Forum 2005-2010 (read only) / Syntax & Programs / Re: A FIR Finite Impuls Response filter routine on: July 14, 2010, 11:50:26 am
Thanks for the reply. I guess I get what you are saying. Pointers, classes, constructors and deconstructors is a bit out of my league right now, but I will try to get that to work at some point.

Your remark about 'in' and 'input': you are pointing at the use of 'input' within the fir-routine? That's a typo, a leftover of the time when I changed the name to in for the routine. Thanks for finding that!
9  Forum 2005-2010 (read only) / Syntax & Programs / A FIR Finite Impuls Response filter routine on: July 14, 2010, 11:02:49 am
Hello there, fellow Arduino Programmers.

I spent my day (well, part of it at least) programming a FIR (or Finite Impuls Response) filter on the Arduino.

It can be used as a building block for any program that requires some form of filtering. Because of its simple nature, you may use this for various purposes:
- filtering audio (duh...)
- smoothing of analog inputs
- smoothing of PWM outputs (ramp up, and down of motors, gradually turning lights/LED's on and off)
- taking a 'running average' on streaming data
- removing 'DC' or static components of a signal (requires a 'high pass'  or 'band pass' filter

I've written this to sharpen my limited C-programming skills, so there is probably lots of room for improvement. I hope people will criticize my code, so I can learn to write proper code, and optimize it. Once optimized, I hope this code could make it into the 'playground'. I guess if it handled INT's it would be more useful there.

I've commented the code extensively, so people could understand what it going on, and change it to their own needs.

Code:
/*

Simple FIR filter implementation

This routine is just written as an excersize in Arduino programming.
The routine implements a Finite Impuls Response filter.

Finite Impuls Response filters can be used to create all kinds of filters.
Filters can be used to partially remove noise, remove 'DC' offsets, or 'shape' analogue values. See http://en.wikipedia.org/wiki/Finite_impulse_response to read more aboute FIR filters. Several online sources are available to generate the coefficients. Google for the various sources.

About the routine: it is not really optimized for anything. It accepts exactly one float, spits out one float, and should be called for every sample. For the filter to work as expected, the samples should be 'equidistant' in time, so taken at identical intervals.

Making this an 'integer' function (to make it more usable with the onboard analog inputs) can be done. This would also limit execution time and memory usage.

Talking performance: using floats a 5 tap cycle takes about 180µs, so that is pretty fast and allows about 3~4kHz sample rate, taking some overhead in the main loop into consideration. Using ints or even better bytes should fraction the looptime by at least 4 to 8 times!

Rene Knuvers, 14JUL2010, arduino@reneknuvers.nl

*/

#define FILTERTAPS 5            // The number of taps in your filter, or better the number of coefficients

// declare array for values
float values[FILTERTAPS] = {0, 0, 0, 0, 0}; // to have a nice start up, fill the array with 0's
// NOTE: this could be 1 shorter, as we already have the input in a variable. This would save stack size/memory

// declare input and output variables
float input = 1; // without a real input, looking at the step respons (input at unity, 1) would be nice to see
float output = 0; // output as a 0, but that doesn't really matter

// our counter, real life applications won't need this
byte n = 0;

void setup() {
      Serial.begin(115200);      // open the serial port, I like them fast ;-)
}

float fir(float in){
      static byte k;                  // k stores a pointer to create a circular memory through the array. This variable remains its value the next time we call the fir routine (hence 'static')
      byte i = 0;                        // i is a counter to step through the filter coefficients and stored values
      float out = 0;                        // out is the return variable. It is set to 0 every time we call the filter!

      values[k] = input;                  // store the input in the array at the current pointer position

      
      // declare variables for coefficients
        // these should be calculated by hand, or using a tool
      // in case a phase linear filter is required, the coefficients are symmetric
      // for time optimization it seems best to enter symmetric values like below
      float coef[FILTERTAPS] = { 0.021, 0.096, 0.146, 0.096, 0.021};

      //declare gain coefficient to scale the output back to normal
      float gain = 0.38; // set to 1 and input unity to see what this needs to be

      
      for (i=0; i<FILTERTAPS; i++) {            // we step through the array
            out += coef[i] * values[(i + k) % FILTERTAPS];      // ... and add and multiply each value to accumulate the output
                                    //  (i + k) % FILTERTAPS creates a cyclic way of getting through the array
        }
      out /= gain;                        // We need to scale the output (unless the coefficients provide unity gain in the passband)

      k = (k+1) % FILTERTAPS;                  // k is increased and wraps around the FILTERTAPS, so next time we will overwrite the oldest saved sample in the array
      
        return out;                        // we send the output value back to whoever called the routine

}


void loop() {

      // This is the loop that takes care of calling the FIR filter for some samples

      for (n = 0; n < FILTERTAPS + 2; n++) {             // If you like to see the step response, take at least as many cycles as the length of your FIR filter (FILTERTAPS + 1 or 2)
            Serial.print("n= ");            // print the sample number
            Serial.println(n, DEC);
            Serial.println("Now calling fir...");
            output = fir(input);            // here we call the fir routine with the input. The value 'fir' spits out is stored in the output variable.
            Serial.print("fir presented the following value= ");
            Serial.println(output);            // just for debugging or to understand what it does, print the output value
      }
      while (true) {};                  // endless loop
}

Please, feel free to comment and post alternatives!

Rene Knuvers
Goirle, The Netherlands
arduino@reneknuvers.nl
10  Forum 2005-2010 (read only) / Syntax & Programs / Re: Problem with DMX Example on: July 09, 2010, 10:57:08 am
In fact, there is one: http://blog.wingedvictorydesign.com/2009/07/10/rev13-of-the-arduino-dmx-reception-software-released/ This is a 'slave' application, where Arduino reads the DMX and can do things with the data some DMX master sent!

Note the hardware: RS485 (DMX's low-level hardware spec) is able to both transmit and receive on a single pair of lines. Not full duplex (at the same time), that would be called RS422. This means your 'transmitter' shield should work without much hassle as a receiver too!
11  Forum 2005-2010 (read only) / Interfacing / Powering Arduino from a USB-battery on: July 06, 2010, 08:24:45 am
I know some people use a  battery to power their Arduino. Some even use LithiumIon (LiIon) or LithiumPolymer (LiPo) contraptions to make Arduino work without a power supply.

I recently bought a Philips SCE4430, a 'rechargable USB power supply'. It basically is a battery with USB plugs to charge it, and a USB plug to draw the energy from. And, since Arduino's generally have a USB plug, it is easy to power an Arduino with it!

I guess this is a good solution for people who don't want to mess with batteries and chargers themselves and want to stick with an 'off the shelf' solution. Philips is by the way not the only OEM that produces these kind of products. Many can be found from various sources, either with solarcells or not. The Philips device is small, has a rather large capacity and is a quality product, but the final choice is up to you!

Happy programming!

---

René
12  Forum 2005-2010 (read only) / Exhibition / Re: Toolduino software for controlling your Arduino on: July 14, 2010, 11:33:25 am
This looks nice. I'm testing it under Ubuntu Linux (10.4) and am sorry to tell you it doesn't work. It starts with no problem, but it doesn't present me with an option to select a serial board.

This may have to do with adding myself to the 'dialout' group, although this is no problem with the Arduino IDE software...

Is there any way to set the port manually?
13  Forum 2005-2010 (read only) / Exhibition / Re: Orientation without kalman filter. on: July 14, 2010, 06:17:39 am
Some info I found on a Kalman filter implementation on the web is here: http://starlino.com/imu_kalman_arduino.html (and the theoretical background is explained in a background article)

Now this is an 'inclinometer', so it will give you two angles ('pitch' and 'roll') that tell you how 'horizontal' your quadcopter is. The software will eliminate the values for speed in any direction, and it won't tell you the 'yaw'.

Estimating the speed is relatively simple and should consider only the accelerometer's values, but I don't think you need to know the speed in the first place.

'yaw' (rotation around the vertical axis) can only be calculated if you add a third gyro, but then it should be a piece of cake. I guess keeping your quadcopter level is your first goal.

Thinking of it: the accelerometer could be used to estimate the rate of rotation in the horizontal plane too, as long as the angular speed is high enough. Centriputal/centrifuginal forces will exitade the outputs x and y if you place the IMU away from the center of rotation. This is risky calculation, as it will only work if the copter is hovering at the same position and the only movement is the rotation in the xy plane... But it would be worth trying to place your IMU out of the center of the copter.
Pages: [1]