Smoothing Arduino IR SHARP analog signal

tedor's icon

Hello
I wonder whether I could get a tip? I am using IR sharp sensors > when they get into MAX/MSP the signal is jumping around. I am going to try using the [mean], but I wonder whether anyone knows a more effective way to smooth this kind of signals?
Thank you and all the best
Krisztian

brendan mccloskey's icon

Have you checked that the data is flowing smoothly from your Arduino program? Sometimes the bits can jump around due to a HW problem (voltage bleed across inputs e.g.), or bad maths (which I'm always guilty of). I like to troubleshoot this problem at the source - and the place to start is ensuring you're getting steady and reliable data into and out of the Arduino first. People tend to 'shoot the messenger' when they see jumpy input to Max in this context, and it's rarely Max's fault. But of course you can try [line] or [slide~] or maybe [rampsmooth~].

brendan mccloskey's icon
Max Patch
Copy patch and select New From Clipboard in Max.

PS
try these

Chris Muir's icon

There was a discussion a while back on controller smoothing which compared a bunch of methods:
https://cycling74.com/forums/smoothing-out-numbers

tedor's icon

hello, thank you for both, the max5 patcher teaches me a lot and the earlier discussion too.

The IR sensors go straight into the analogue pin. I use a sarcduino0_15nw. Here the code is too advanced for me to understand, but if there is a simpler version, which by chance would turn out to be more reliable, I would go for it:

The arduino is:

//*************************************************************************//
//* Sarcuino
//* Version: Beta 0.14.5
//* Last modified by: Nicholas Ward
//* Date: Mar 2nd, 2009
//*************************************************************************//

/* This is just simple data acquisition code. It sends a packet via serial that look s like this

(byte representing digital inputs 2 to 7)
(byte representing digital inputs 8 to 13)

(byte representing high 4 bits of analog n)
(byte representing low 6 bits of analog n)
// the above two bytes repeat depending on how many analog inputs you have enabled

(255 send to indicate end of packet)

Use [comport] in PD or [serial] in max to open the serial connection

In MAX/MSP use [zl group 50] in combination with [select 255] to put the data stream into lists with one packet per list
then use [unpack i i i i i i i i i i i i i i i i i i i i i ] to get at each individual byte

In PD I use [zexy/repack] instead of [zl group]

*/

#include
#include

#define ANALOG_INPUTS_ENABLED 6 // Choose number of analog inputs to enable
#define SAMPLE_FREQ 4 // Use: 1 -> 1kHz; 2 -> 500Hz; 4 -> 250Hz, etc.
// N.B. The arduino can sample all pins at 500Hz
// This however causes serious burstiness

// FOR REALTIME CONTROL (lower latency and lower burstiness)
// To avoid data being buffered and sent in blocks of 4KB you should insure that
// ((ANALOG_INPUTS_ENABLED * 2) + 3) * ((1/SAMPLE_FREQ)*1000) < 3875
// This is a limitation of the ftdi usb driver
// Further details and possible solutions can be found here
// http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1170939903/15

//**************************************************************************//
//** Variables for data polling
//**
int analogPin, digitalPin; // Counters for poll loop
int analogData; // outgoing ADC value
byte x = 0; //byte to store digital status
byte y = 0; //same as above to store remaining digital pins status

//**************************************************************************//
//** Setup
//**
void setup() {
//setup serial baudrate for USB connection
Serial.begin(57600);

//enable digital pullups. All digital pins are set high
//and will only output change when connected to ground
for(digitalPin=2;digitalPin
{
pinMode(digitalPin, INPUT); //Setpin up for input
digitalWrite(digitalPin, HIGH); //enable internal pullups
}
}

//**************************************************************************//
//** Main Loop.
//** Millis is an interrupt friven timer that begins to increment every ms once the
//** arduino starts. If millis modded with sample freq is 0 then the correct sampling
//** period has passed and its time to sample again.
void loop() {

long periodCheck = millis()%SAMPLE_FREQ;

if (periodCheck == 0)
{
SampleAndSend();
}
}

//**************************************************************************//
//** SampleAndSend
//** This function is called by the main loop and does the actual work of
//** reading the input pins and sending the data via serial

void SampleAndSend()
{
x = PIND >> 2; // Shift analog pin port D by 2 to avoid TX and RX pins
Serial.print(x, BYTE);
y = PINB; // Read remaining digital pins
Serial.print(y, BYTE);

for(analogPin=0; analogPin

{
analogData = analogRead(analogPin); // Read current analog pin value
Serial.print(analogData >> 7, BYTE); // shift high bits into output byte
Serial.print(analogData % 128, BYTE); // mod by 128 for the small byte
}

Serial.print(255, BYTE); // end of packet signifier

// This bit of code was used for checking how long a full read takes
//Serial.println(millis());
}

The Max 5 patch is:

Max Patch
Copy patch and select New From Clipboard in Max.

thank you
best,
K

mzed's icon

I think there's another thread on this someplace. Those IR sensors create a lot of noise in the power supply, and get jittery when you use many of them. Search around. Stronger power supply and decoupling capacitors might improve the signal before it gets to the arduino.

mz

Chris Muir's icon

Another thing to keep in mind is that you probably want to ground any unused analog input pins.

tedor's icon

hello both.
I have to search around as the stronger power supply should not be a problem, however I have never used capacitors before. Grounding unused analog inputs? Never thought about this, there is only going to be one, but I will ground it if it only means to connect it with the ground :)

thank you all the best

Krisztian

brendan mccloskey's icon

do you know how to monitor the serial data from within the Arduino program? If you don't, look for Brian Evans' or Massimo Banzi's tutorials, they're very easy (in English).
If the data coming into Max is unreliable, you are always going to have problems, no matter how many Max objects you throw at it.

Andrew Benson's icon

Two things you will run into with an IR range sensor:
1. Non-linearity - the voltage/distance ratio is not linear, so you might need to use some sort of lookup table or waveshaping on the data to get the response into something fairly linear.

2. High Impedance - IR sensors have notoriously high impedence which is a well known issue with getting stable readings on your ADC. You should try running the signal through an op-amp buffer to convert it to a low-impedence voltage.

There is a great article about sensor conditioning here: Electrotap

Assuming you can get the electronic side worked out, a little bit of smoothing on the Max side won't hurt as well.

tedor's icon

hello

I am using a power supply with 1.2 amp which definitely gives me a more reliable signal, now I wonder what happens if I increase the amp to 2.5? hmm...

Unfortunately I will not have the time to use (write) an other Arduino code for sending IR sensors to Max, and here using the serial monitor in the Arduino software shows me jiberesh:)

The only way I can see to get rid of the peaks in the signal (noise?) is with decoupling capacitors, as I suspect the op-amp buffer would be more complex....

... and then if it still hurst in Max/MSP I will use the smoothing patches :)

I hope it will work out, I will keep posting my progress.
thank you and all the best
K

Chris Muir's icon

Adding a 2.5 amp power supply probably won't help, if the current draw is below the 1.2 amp level.

tedor's icon

hi, yes, I kinda got closer, there might be an issue with the long cables or the power supply (which now is only 4.5V) or perhaps I just have to try to get digital sensors next time, they seem to be more reliable,

if anyone is following, there is the Arduino forum I asking questions as well,
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1271778947/3#3

thanks,
all the best
K