// Include necessary libraries
#include <Arduino.h>
// Define the pins for various components
const int outputPin = 9; // Digital pin to output the square wave
const int leftButtonPin = 2; // Digital pin for the left button
const int rightButtonPin = 3; // Digital pin for the right button
const int redLightPin = 13; // Digital pin for the red light indicator
// Declare the frequency variable and frequency limits
volatile unsigned long frequency = 10000; // Initial frequency in Hz (10 kHz)
unsigned long minFrequency = 1000; // 1 kHz minimum frequency
unsigned long maxFrequency = 20000; // 20 kHz maximum frequency
// Setup function runs once when the Arduino starts
void setup() {
// Set pin modes for various components
pinMode(outputPin, OUTPUT); // Output pin for the square wave
pinMode(leftButtonPin, INPUT_PULLUP); // Input pin for the left button
pinMode(rightButtonPin, INPUT_PULLUP); // Input pin for the right button
pinMode(redLightPin, OUTPUT); // Output pin for the red light indicator
// Attach interrupt functions to the buttons
attachInterrupt(digitalPinToInterrupt(leftButtonPin), decreaseFrequency, FALLING);
attachInterrupt(digitalPinToInterrupt(rightButtonPin), increaseFrequency, FALLING);
// Disable interrupts temporarily and initialize timer
noInterrupts();
timer1_init(100); // Timer period in milliseconds
interrupts();
// Initialize serial communication for debugging
Serial.begin(9600);
}
// Loop function continuously runs after setup
void loop() {
// No code needed in the loop
}
// Timer interrupt service routine (ISR)
ISR(TIMER1_COMPA_vect) {
digitalWrite(outputPin, !digitalRead(outputPin)); // Toggle the output pin to generate square wave
}
// Initialize timer1 with given period in milliseconds
void timer1_init(int msec) {
TCCR1A = 0; // Clear Timer1 configuration A register
TCCR1B = 0; // Clear Timer1 configuration B register
TCNT1 = 0; // Initialize the timer count value
OCR1A = (int)(F_CPU / (2 * 1024.0 * 1000 / frequency)) - 1; // Set compare value for desired frequency
TCCR1B |= (1 << WGM12); // Set Timer1 to CTC mode
TCCR1B |= (1 << CS12) | (1 << CS10); // Set prescaler to 1024
TIMSK1 |= (1 << OCIE1A); // Enable Timer1 compare interrupt
}
// Function to decrease frequency by 10% when left button is pressed
void decreaseFrequency() {
frequency -= frequency * 0.1; // Decrease frequency by 10%
updateFrequency(); // Update the frequency and related components
}
// Function to increase frequency by 10% when right button is pressed
void increaseFrequency() {
frequency += frequency * 0.1; // Increase frequency by 10%
updateFrequency(); // Update the frequency and related components
}
// Function to update frequency and handle limit checks
void updateFrequency() {
if (frequency < minFrequency) {
frequency = minFrequency;
digitalWrite(redLightPin, HIGH); // Turn on the red light indicator if below minimum frequency
} else if (frequency > maxFrequency) {
frequency = maxFrequency;
digitalWrite(redLightPin, HIGH); // Turn on the red light indicator if above maximum frequency
} else {
digitalWrite(redLightPin, LOW); // Turn off the red light indicator within frequency range
}
// Update the timer with the new frequency
timer1_init(100);
// Print the updated frequency to the serial monitor
Serial.print("Frequency: ");
Serial.print(frequency);
Serial.println(" Hz");
}