Создание осциллирующего тона, используя Arduino, ATTiny85 и простой зуммер - PullRequest
0 голосов
/ 09 июня 2018

Сначала немного фона.Я пытаюсь заставить светодиод светиться, и зуммер воспроизводит звук, который плавно поднимается и опускается по частоте, как сирена воздушного налета.Я использую Arduino Uno, подключенный к чипу ATTiny85, работающему на тактовой частоте 8 Гц.Контактный переключатель SPDN используется для обеспечения входа 4, а 0 и 1 выходят на положительные ветви зуммера и светодиода соответственно.Подходящие резисторы используются для ограничения тока, который составляет 5 В от платы Arduino.

Теперь моя проблема.Я могу воспроизводить постоянный тон на любой частоте, которая мне нравится.Я могу воспроизводить тон между двумя тонами, например сирену британской полиции (Ди-Даа-Ди-Даа и т. Д.), Но я не могу сгенерировать плавный переход между двумя тонами.Светодиод работает, как и ожидалось.

То, что я на самом деле наблюдаю, это один тональный сигнал, который не меняется.Один или два раза мне удавалось воспроизводить тон, который изменяется, но случайно в заданном диапазоне, а не плавно.

Я не использую команду tone() Arduino и предпочел бы не делать этого, поскольку это не таклучше всего подходит для того, что я пытаюсь сделать.

Вот мой код:

const float pi2 = 6.28318530717;
const int buzzer = 0;
const int light = 1;
const int button = 4;

// Set up the pins as input and output
void setup() {
  pinMode(buzzer, OUTPUT);
  pinMode(light, OUTPUT);
  pinMode(button, INPUT);
}

bool buzzerState = LOW;
float nextFlip = 0;

// Generates a sine wave for the given uptime, with a period and offset (in milliseconds).
float sineWave(float uptime, float period, float offset, float minimum, float maximum) {
  float s = sin(((uptime + offset) * pi2) / period);
  // Normalise the result between minimum and maximum
  return (s + 1) / 2 * (maximum - minimum) + minimum;
}

// Returns the time between buzzer inversions based on a given system uptime.
float frequency(float uptime) {
  return sineWave(uptime, 5000, 0, 1, 10);
}

// Main loop
void loop() {

  // Check button state and turn the light on or off
  bool buttonDown = digitalRead(button);
  digitalWrite(light, buttonDown);

  // Check to see if it's time for the next buzzer inversion
  float m = micros();
  if (!buttonDown || m < nextFlip) return;

  // Get the inverse of the current buzzer state
  if (buzzerState == HIGH) {
    buzzerState = LOW;
  } else {
    buzzerState = HIGH;
  }

  // Write the new buzzer state
  digitalWrite(buzzer, buzzerState);

  // Decide when the next inversion will occur
  nextFlip = m + frequency(m);
}

1 Ответ

0 голосов
/ 09 июня 2018

Глупая ошибка!Наконец я заметил: я читаю micros(), где я хотел прочитать millis() - другими словами, он колебался, всего в тысячу раз быстрее, чем я хотел!Умножение всех значений в 1000 раз в синусоидальной функции произвело прекрасное колебание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...