使用Arduino,ATTiny85和简单的蜂鸣器创建振荡音

时间:2018-06-09 11:40:30

标签: arduino microcontroller attiny

首先是一些背景知识。我试图让LED发光,蜂鸣器产生的音调在频率上上下平滑地扫过,就像空袭警报器一样。我使用的是Arduino Uno,连接到以8hz时钟速度运行的ATTiny85芯片。 SPDN接触开关用于在4上提供输入,而0和1分别用于蜂鸣器和LED的正极。合适的电阻用于限制电流,即Arduino电路板的电压为5v。

现在,我的问题。我可以在任何我喜欢的频率上产生恒定的音调。我可以产生一种在两种音调之间来回传递的音调,如英国警笛声(Dee-Daa-Dee-Daa等),但我无法在两种音调之间产生平滑过渡。 LED按预期工作。

我实际观察到的是单音不变。有一次或两次我设法产生一种变化的音调,但是在给定的范围内随机而不是顺利。

我没有使用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 :(得分:2)

愚蠢的错误!我终于注意到了:我正在阅读micros(),我打算阅读millis() - 换句话说,它正在振荡,比我想要的快一千倍!在正弦波函数中将所有值乘以系数1000会产生可爱的振荡。