I'm trying to switch between a sine wave and a square wave every second using the analogWave.h library.
I can successfully start and stop either a sine wave or a square wave every second.
However, if I try to switch the waveform every second, it only works a couple of times before getting stuck on a sine wave.
I have tried adding stop() before switching, with delays before and after, but still no luck.
Example Code:
#include "analogWave.h"
analogWave waveform(DAC);
const unsigned long interval = 1000; // 1-second interval
unsigned long previousMillis = 0;
bool state = LOW;
void setup() {
pinMode(DAC, OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Update time
state = !state; // Toggle state
if (state) {
waveform.sine(1000); // Start sine wave
} else {
waveform.square(1000); // Start square wave
}
}
}
Observed Behaviour
On an oscilloscope, the output switches correctly a few times (sine → square → sine).
After 3 cycles, it gets stuck on a sine wave and no longer switches.
If I only use one waveform type, it works indefinitely without issues.
Has anyone successfully switched between square and sine waves periodically using analogWave.h?
Is there something in the library that prevents waveform changes after multiple transitions?
Quite possibly, but it was the only thing I could see that was remotely wrong, and I believe in fixing the obvious problems first. Thinking "it can't possibly be that so I won't change it" can lead to hours of frustration.
When I tested the code on an Uno R4 WiFi (which I found before I found my Minima), it did an even lower number of changes.
It did one second of sine wave then stuck on square wave.
I already tested the logic of the code with something simpler like toggling a pin. I think HIGH/true and LOW/false are just 1 and 0 aren't they? anyway that was from chat gpt so it must be right .
Anyway I think I found the solution and it is to create two instances of the analogWave, one for the squarewave and one for the sinewave and then just stop and start each one when you need it to take over.
#include <Arduino.h>
#include "analogWave.h"
analogWave audibleSignal(DAC);
analogWave tactileSignal(DAC);
const unsigned long interval = 1000; // 500ms interval
unsigned long previousMillis = 0;
bool state = false;
void setup() {
pinMode(DAC, OUTPUT);
tactileSignal.sine(1000);
audibleSignal.square(1000);
audibleSignal.stop();
}
void loop() {
unsigned long currentMillis = millis();
// Check if 500ms has passed
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis; // Update time
// Toggle the LED state
state = !state;
if (state) {
tactileSignal.stop();
audibleSignal.start();
} else {
tactileSignal.start();
audibleSignal.stop();
}
}
}
Those with far better knowledge of such things than me will tell you (and me) that you can't make that assumption. They will tell you something about breaking the deal you make with the compiler. I hope someone with better knowledge than me will correct me or clarify if required.
Certainly regardless of the compiler 0 == false cannot be assumed, logic works perfectly well if you have 1 == false provided you are consistent in your use. Nothing George Boole said demands that 0 must be false or 1 must be true, although I admit that's the usual arrangement.