I am currently attempting to build a program that acts like a theremin of sorts - to quickly summarize, I take input from a voltage divider using a photo-resistor and use it to determine the frequency I output to a buzzer via analogWrite. Unfortunately, however, I have come into a snag when attempting to add a mute button to enable/disable sound.
Something about my logic that handles button presses results in light detected by the photo-resistor to be read as button presses. I eventually found that I wasn't using pinMode before my analogWrite call for my buzzer, which fixed that issue yet unfortunately raised another - now, instead of light causing interference with my button handling, button handling (as well as the process of connecting to the cloud, and possibly even writing to terminal) is causing interference with my buzzer, not using the amount of light being detected anymore.
To be clear, I've gone over my actual breadboard hookup and have found no issues with how I've connected things. Disabling the button code causes the project to work correctly, but I wish to have this button work as intended. Provided below are the files being compiled for my firmware:
Main file:
// Include Particle Device OS APIs
#include "Particle.h"
// Include other .h files.
#include "ersatz_theremin.h"
// Let Device OS manage the connection to the Particle Cloud
SYSTEM_MODE(AUTOMATIC);
// Run the application and system concurrently in separate threads
SYSTEM_THREAD(ENABLED);
// Show system, cloud connectivity, and application logs over USB
// View logs with CLI using 'particle serial monitor --follow'
SerialLogHandler logHandler(LOG_LEVEL_INFO);
// Names of pins.
const int V_OUT = A0;
const int TMP36 = A1;
const int BUTTON = D0;
const int BUZZER = D1;
const int RED_LED = D2;
const int GREEN_LED = D3;
const int BLUE_LED = D4;
// Initialize class instances.
ErsatzTheremin ersatzTheremin = ErsatzTheremin();
// setup() runs once, when the device is first turned on
void setup()
{
// Set up pins.
pinMode(V_OUT, INPUT_PULLDOWN);
pinMode(TMP36, INPUT_PULLDOWN);
pinMode(BUTTON, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(BLUE_LED, OUTPUT);
}
// loop() runs over and over again, as quickly as it can execute.
void loop()
{
ersatzTheremin.main();
}
ersatzTheremin files:
#ifndef ersatz_theremin_h
#define ersatz_theremin_h
#include "Particle.h"
class ErsatzTheremin
{
private:
// Pins needed for this part of the assignment.
const int V_OUT = A0;
const int BUTTON = D0;
const int BUZZER = D1;
// Volume level, and reference constants.
int volume = 128;
const int MUTED_VOL = 0;
const int UNMUTED_VOL = 128;
// Button variables.
const int BOUNCE_INTERVAL = 500;
int lastTimeButtonPressed = 0;
public:
void main();
};
#endif
// Include Particle Device OS APIs
#include "Particle.h"
#include "ersatz_theremin.h"
void ErsatzTheremin::main()
{
// Detect whether button is pressed.
if (digitalRead(BUTTON) == LOW) {
Serial.printlnf("BUTTON PRESSED NOW at %d", millis());
// Detect whether it has been at least the bounce interval since the button was last pressed.
if (millis() - lastTimeButtonPressed > BOUNCE_INTERVAL) {
// Mute/unmute via altering volume level.
if (volume == MUTED_VOL) {
volume = UNMUTED_VOL;
} else {
volume = MUTED_VOL;
}
}
lastTimeButtonPressed = millis();
}
// Get reading from photoresistor.
int photoVoltageReading = analogRead(V_OUT);
// Send reading from photoresistor to buzzer.
pinMode(BUZZER, OUTPUT); // ENABLING THIS CAUSES SOME KIND OF INTERFERENCE IN THE BUZZER, DISABLING CAUSES PHOTOSENSOR TO INTERFERE W/ BUTTON AS DESCRIBED
analogWrite(BUZZER, volume, photoVoltageReading);
pinMode(BUTTON, INPUT_PULLUP); // Enabling/disabling this doesn't (seem to) make a difference.
}