#define N 32 #define RATE 255 // Top value for ICR3: (3200 counts) * (1us / 16 counts) = 200 us period #define PWM_PIN 5 // Must be an OCR3A pin (e.g., Pin 5 on Arduino Mega) // Define the sine wave array as a constant in program memory (PROGMEM not necessary for uint8_t size) const uint8_t sin_wave[N] = {128, 153, 177, 199, 219, 234, 246, 254, 255, 254, 246, 234, 219, 199, 177, 153, 128, 103, 79, 57, 37, 22, 10, 2, 0, 2, 10, 22, 37, 57, 79, 103}; void setup() { Serial.begin(9600); // Initialize serial communication once pinMode(PWM_PIN, OUTPUT); // Set the PWM pin as an output // --- Configure Timer 3 for Fast PWM Mode (WGM33:0 = 14) --- cli(); // Disable global interrupts while configuring timer TCCR3A = 0; // Clear TCCR3A register TCCR3B = 0; // Clear TCCR3B register // Set Wave Generation Mode bits: WGM31 and WGM30 (for Mode 14: Fast PWM, TOP set by ICR3) TCCR3A |= (1 << WGM31); TCCR3B |= (1 << WGM32) | (1 << WGM33); // Set TOP value for the timer in the Input Capture Register (ICR3) to define the frequency ICR3 = RATE; // What is the PWM's frequency? // Configure Output Compare Pin A (OC3A) for non-inverting mode (Clear OC3A on Compare Match, set on BOTTOM) TCCR3A |= (1 << COM3A1); // Set Prescaler to 256 and start the timer TCCR3B |= (1 << CS32); sei(); // Enable global interrupts // Initial PWM duty cycle (e.g., midpoint of sine wave) OCR3A = sin_wave[0]; } void loop(){ uint8_t i; uint16_t index; char cmd; // uint8_t volumeAdjust = 1; // This variable was unused in original code Serial.println("Analog waveform generator running."); Serial.println("Enter 's' to step through sine table."); for(;;){ if (Serial.available()) { cmd = Serial.read(); switch (cmd) { case 's': Serial.println("Press 'x' to exit stepping mode."); Serial.println("Press any other key to step."); index = 0; // Use a while loop that runs until 'x' is read while (1) { // Check for new input within the stepping loop if (Serial.available()) { if (Serial.read() == 'x') { break; // Exit the while(1) loop } } // Update the PWM duty cycle with the next sine wave value OCR3A = sin_wave[index]; //What is the PWM's duty cycle? // Increment index and wrap around using the bitmask index = (index + 1) & 0b00011111; // Wait for user input to step again, or continue waiting for 'x' while (!Serial.available()); } // The PWM continues running at the last value after exiting the loop Serial.println("Exited stepping mode. Timer is still running."); while (Serial.available()) Serial.read(); // Clear serial buffer break; } } } }