сонар

MB1200 XL-MaxSonar-EZ0

Ультразвуковой датчик расстояния, широко используемый при разработке робототехники на ардуино, в том числе для контроля высоты на моделях вертолетов.

Согласно документации позволяет измерять расстояние от 20см до 7м 65см с точностью в 1 см

с тем чтобы показания сонара, снимаемые с аналогового выхода были стабильны прежде всего следует обеспечить стабильное питание модуля, даже если используется интегральный стабилизатор питающий ардуино или ардупилот, следует дополнительно установить дроссель по плюсу питания и фильтрующий конденсатор 30-100мкф а сигнальный кабель пустить экранированной жилой
схема:
sonar connection

красный - питание через дроссель +5 вольт
синий - подключение конденсатора
черный - общий он же экран сигнальной жилы
желтый - сигнальная жила, подключить к аналоговому входу ардуино используемому в скетче для замеров (или ардупилота)

Производитель сонаров не рекомендует использовать конденсатор в цепи сигнала для подавления помех, в место того рекомендуется использовать медианный фильтр. Принцип работы фильтра в следующем - делается замер из нескольких показаний, причем это число должно быть нечетным, эти показания сортируются по возрастанию, то значение которое оказывается в середине после сортировки и является истинным.(Возможно более правильно было бы использовать статистические методы для определения что из результатов замеров следует считать истинным и включить в округленное значение а какие замеры считать шумами и соответственно отсечь)

скомпоновать можно следующим образом:
sonar_filter_connection_photo

на фото два дросселя выпаянных из остатков старой электроники (фотоаппараты, ноутбуки, старые материнские платы)
подобный впаян в разрыв питающего провода и затянут термоусадкой. При выборе дросселя следует брать с большим числом витков тонким проводом, но чтобы сопротивление не превышало 10 Ом
сигнальный провод подведен тонким экранированным проводом (диаметр 1мм) рк-50
со стороны излучателя установлен электролитический конденсатор

скетч для ардуино позволяющий просматривать значения снимаемые с сонара и продемонстрировать принцип работы медианного фильтра:

//Analog pin A0 for reading in the analog voltage from the MaxSonar device.
int anPin = A0;

//variables needed to store values
int arraysize = 17;  //quantity of values to find the median (sample size). Needs to be an odd number
int rangevalue[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };    //declare an array to store the samples. not necessary to zero the array values here, it just makes the code clearer
//*************************************************************************************
void setup()
{

  //This opens up a serial connection to shoot the results back to the PC console
  Serial.begin(9600);
  printArray(rangevalue, arraysize);
  delay(5000);      //wait a while to open serial monitor window

}
//********************************************************************************
void loop()
{

  pinMode(anPin, INPUT);

  //MaxSonar Analog reads are known to be very sensitive. See the Arduino forum for more information.
  //Maxbotix does not recommend averaging readings as the occasional value can be wildly inaccurate and skew the average
  //A median sort is the preferred method.

   for(int i = 0; i < arraysize; i++)
   {                                    //array pointers go from 0 to 4

    //Used to read in the analog voltage output that is being sent by the MaxSonar device.
    //The MaxSonar Scale factor is (Vcc/512) per inch. A 5V supply yields ~9.8mV/in
    //The Arduino will map input voltages between 0 and 5 volts into integer values between 0 and 1023.
    //This yields a resolution between readings of: 5 volts / 1024 units or, .0049 volts (4.9 mV) per unit.
    //Therefore, one unit from the arduino's ADC represents 0.5 inches

     rangevalue[i] = analogRead(anPin);
        Serial.print("i, value   ");
        Serial.print(i);
        Serial.print(" ,  ");
        Serial.print(rangevalue[i]);
        Serial.println();

     delay(10);  //wait between analog samples
    }

   Serial.print("unsorted ");
   printArray(rangevalue, arraysize);
   Serial.println();
   isort(rangevalue, arraysize);
   Serial.print("sorted ");
   printArray(rangevalue, arraysize);
   Serial.println();

 // now show the medaian range
    int midpoint = arraysize/2;    //midpoint of the array is the medain value in a sorted array
    //note that for an array of 5, the midpoint is element 2, as the first element is element 0
     Serial.print("median range value ");
     Serial.print(rangevalue[midpoint]);
     Serial.println();
     Serial.println();

  delay(3000);    //wait a while so you can read the values on the serial monitor

}   //end of loop

//*********************************************************************************
// sort function
void isort(int *a, int n)
           //  *a is an array pointer function
{
  for (int i = 1; i < n; ++i)
  {
    int j = a[i];
    int k;
    for (k = i - 1; (k >= 0) && (j < a[k]); k--)
    {
    a[k + 1] = a[k];
    }
    a[k + 1] = j;
  }
}
//***********************************************************************************
//function to print array values
void printArray(int *a, int n)
{

  for (int i = 0; i < n; i++)
  {
    Serial.print(a[i], DEC);
    Serial.print(' ');
  }

  Serial.println();
}
 
 
результаты в окне терминала:

i, value   0 ,  291
i, value   1 ,  292
i, value   2 ,  291
i, value   3 ,  293
i, value   4 ,  292
i, value   5 ,  292
i, value   6 ,  291
i, value   7 ,  292
i, value   8 ,  291
i, value   9 ,  292
i, value   10 ,  291
i, value   11 ,  291
i, value   12 ,  292
i, value   13 ,  293
i, value   14 ,  293
i, value   15 ,  146
i, value   16 ,  82
unsorted 291 292 291 293 292 292 291 292 291 292 291 291 292 293 293 146 82

sorted 82 146 291 291 291 291 291 291 292 292 292 292 292 292 293 293 293

median range value 292



помимо аналогового выхода у этой модели сонара присутствует широтно - импульсный и цифровой (serial uart) выходы, снятие показаний через которые может быть менее зашумленным.





Comments