Обрабатывая данные от четырёх электретных микрофонов и управляя четырьмя шаговыми двигателями — два контроллера Arduino (Arduino Uno и Arduino Nano) — смогли жонглировать шариком для пинг-понга.
Интересен способ получения информации о местоположении шарика — для этого используется акустическая обратная связь:
контроллер рассчитывает разницу во времени между парой микрофонов (каждая пара расположенных на противоположных торцах пластины — выдаёт значение по соответствующей оси). Шум от удара шарика по пластине достаточно громкий и его легко отличить от других звуков, поэтому для обработки звука используется простая триггерная схема.
Сектч MicDiffs.ino
#include <DirectIO.h>
int mic12DiffCounter = 0;
int mic34DiffCounter = 0;
Output<2> ff_reset;
Input<8> mic1;
Input<9> mic2;
Input<10> mic3;
Input<11> mic4;
void setup()
{
Serial.begin(115200);
}
void loop()
{
// DEBUG
/*
while (1)
{
int ranVertical = random(-250, 250);
int ranHorizontal = random(-250, 250);
if (random(1, 10) >= 4)
{
ranVertical = 0;
}
if (random(1, 10) >= 4)
{
ranHorizontal = 0;
}
Serial.print(constrain(ranVertical, -200, 200));
Serial.print(":");
Serial.print(constrain(ranHorizontal, -200, 200));
Serial.println("&");
delay(500);
}
*/
// DEBUG
boolean micFlag1 = false;
boolean micFlag2 = false;
boolean micFlag3 = false;
boolean micFlag4 = false;
while (1)
{
while (!micFlag1 || !micFlag2 || !micFlag3 || !micFlag4)
{
// update micFlag values.
// only update the ones which aren't high yet for faster computation speed.
if (!micFlag1)
micFlag1 = mic1;
if (!micFlag2)
micFlag2 = mic2;
if (!micFlag3)
micFlag3 = mic3;
if (!micFlag4)
micFlag4 = mic4;
// track diff between mic 1 and 2
if (micFlag1 && !micFlag2)
{
mic12DiffCounter--;
}
if (micFlag2 && !micFlag1)
{
mic12DiffCounter++;
}
// track diff between mic 2 and 3
if (micFlag3 && !micFlag4)
{
mic34DiffCounter--;
}
if (micFlag4 && !micFlag3)
{
mic34DiffCounter++;
}
}
Serial.print(constrain(mic12DiffCounter, -200, 200));
Serial.print(":");
Serial.print(constrain(mic34DiffCounter, -200, 200));
Serial.print("&");
Serial.println(millis());
ff_reset = false;
delay(100);
// wait until all mics are low again.
while (micFlag1 || micFlag2 || micFlag3 || micFlag4)
{
micFlag1 = mic1;
micFlag2 = mic2;
micFlag3 = mic3;
micFlag4 = mic4;
}
ff_reset = true;
//Serial.println("reset done.");
mic12DiffCounter = 0;
mic34DiffCounter = 0;
micFlag1 = micFlag2 = micFlag3 = micFlag4 = false;
}
}
Данные о местоположении шарика передаются второму контроллеру Arduino, который использует их чтобы наклонить пластину таким образом, чтобы шарик не упал (для этого используется ПИД-регулятор).
Ссылки
Acoustic Location Determination of a Bouncing Ball
Stepper Juggler
https://github.com/T-Kuhn/Stepper-Juggler
По теме
Платформа балансирующая шариком
ЧПУ для сада Дзэн на Arduino
Arduino
Arduino, термины, начало работы
КМБ для начинающих ардуинщиков
Состав стартера (точка входа для начинающих ардуинщиков)
