Untitled

mail@pastecode.io avatar
unknown
c_cpp
a year ago
3.2 kB
19
Indexable
Never
// Pin assignments
const int outputPin = 9;        // Digital pin to generate the square wave output
const int leftButtonPin = 3;    // Digital pin for the left button
const int rightButtonPin = 2;   // Digital pin for the right button
const int redLED = 12;          // Red LED pin to indicate errors (use a different pin, e.g., pin 12)

// Initialize variables
volatile float frequency = 10000;  // Initial frequency: 10 kHz
volatile boolean frequencyChanged = false; // Flag to indicate frequency change
volatile boolean decreaseRequested = false; // Flag to indicate decrease button press
volatile boolean increaseRequested = false; // Flag to indicate increase button press

void setup() {
  pinMode(outputPin, OUTPUT);       // Set square wave output pin
  pinMode(leftButtonPin, INPUT_PULLUP);  // Set left button pin with internal pull-up resistor
  pinMode(rightButtonPin, INPUT_PULLUP); // Set right button pin with internal pull-up resistor
  pinMode(redLED, OUTPUT);          // Set red LED pin
  
  attachInterrupt(digitalPinToInterrupt(leftButtonPin), requestDecrease, FALLING);
  attachInterrupt(digitalPinToInterrupt(rightButtonPin), requestIncrease, FALLING);
  
  noInterrupts();
  timer1_init(100); // Period time in milliseconds
  interrupts();
  
  Serial.begin(9600);
  updateFrequency();
  frequencyChanged = false;
}

void loop() {
  if (decreaseRequested) {
    decreaseFrequency();
    decreaseRequested = false;
  }
  if (increaseRequested) {
    increaseFrequency();
    increaseRequested = false;
  }
  if (frequencyChanged) {
    updateFrequency();
    frequencyChanged = false;
  }
}

ISR(TIMER1_COMPA_vect) {
  static unsigned long previousMicros = 0;
  unsigned long currentMicros = micros();
  
  if (currentMicros - previousMicros >= frequency / 2) {
    digitalWrite(outputPin, !digitalRead(outputPin));
    previousMicros = currentMicros;
  }
}

void timer1_init(int msec) {
  TCCR1A = 0;          // Clear TCCR1A register
  TCCR1B = 0;          // Clear TCCR1B register
  TCNT1 = 0;           // Initialize counter value to 0
  OCR1A = (int)(15.624 * msec); // Set compare value for desired interval
  TCCR1B |= (1 << WGM12); // Set CTC mode
  TCCR1B |= (1 << CS12) | (1 << CS10); // Set prescaler to 1024
  TIMSK1 |= (1 << OCIE1A); // Enable Timer1 compare interrupt
}

void requestDecrease() {
  decreaseRequested = true;
}

void requestIncrease() {
  increaseRequested = true;
}

void decreaseFrequency() {
  noInterrupts();
  frequency -= frequency*0.1; // Decrease frequency by 10%
  frequencyChanged = true;
  interrupts();
}

void increaseFrequency() {
  noInterrupts();
  frequency += frequency*0.1; // Increase frequency by 10%
  frequencyChanged = true;
  interrupts();
}

void updateFrequency() {
  digitalWrite(redLED, LOW);
  
  if (frequency > 20000 || frequency < 1000) {
    digitalWrite(redLED, HIGH);
    Serial.println("Error: Frequency out of range!");
  } else {
    Serial.print("Frequency changed to ");
    Serial.print(frequency);
    Serial.println(" Hz");
  }
  
OCR1A = (int)(15.624 * 10000 / frequency);// Update compare value for new frequency
}