首先介绍一下背景。我正在尝试让 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);
}