I built a FFT spectrum analzyer web app and want to test it. To test it, I used analog signal generated by another Arduino Uno. For the spectrum analyzer to sample the signal I used Arduino Due. Arduino Due has more processing speed and capacity than Arduino Uno but one can also use the Arduino Uno board.
Below is the picture of Arduino which generates the 1 kHz sine wave signal from pin 9 using PWM method of generating sine wave. The PWM sine wave signal goes into the RC low pass filter filter which has a cutoff frequency ≈ 1.59 kHz. The magnitude slightly decreases. The RC filter uses 1kohm resistor and 0.1uF capacitor.
Arduino Code for Sine Wave Generation
/*
* Arduino Uno - 1kHz Sine Wave Generation using PWM
* LPF: 1kΩ resistor + 0.1µF capacitor (cutoff frequency ≈ 1.59kHz)
* PWM Pin: Pin 9 (OC1A - Timer1)
*/
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
// Sine wave lookup table (64 samples for one cycle)
// Values range from 0-255 (8-bit PWM resolution)
const uint8_t sineTable[] PROGMEM = {
128, 140, 152, 164, 176, 187, 197, 207,
216, 224, 231, 237, 242, 246, 249, 251,
253, 254, 254, 253, 251, 249, 246, 242,
237, 231, 224, 216, 207, 197, 187, 176,
164, 152, 140, 128, 115, 103, 91, 79,
68, 58, 48, 39, 31, 24, 18, 13,
9, 6, 4, 2, 1, 1, 2, 4,
6, 9, 13, 18, 24, 31, 39, 48
};
volatile uint8_t index = 0;
void setup() {
// Set PWM pin as output
pinMode(9, OUTPUT);
// Configure Timer1 for Fast PWM mode with 8-bit resolution
// PWM frequency = 16MHz / (prescaler * 510) ≈ 31.37kHz with prescaler=1
// Clear Timer1 control registers
TCCR1A = 0;
TCCR1B = 0;
// Configure Timer1 for Fast PWM 8-bit mode (Mode 5: WGM13=0, WGM12=1, WGM11=0, WGM10=1)
TCCR1A |= (1 << WGM10); // 8-bit Fast PWM
TCCR1B |= (1 << WGM12); // Fast PWM mode
// Set OC1A (Pin 9) as PWM output (non-inverting mode)
TCCR1A |= (1 << COM1A1);
// Set prescaler to 1 (no prescaling) - 62.5ns per count
TCCR1B |= (1 << CS10);
// Enable Timer1 overflow interrupt
TIMSK1 |= (1 << TOIE1);
// Enable global interrupts
sei();
// Initial PWM value
OCR1A = 128; // Midpoint value (2.5V)
}
ISR(TIMER1_OVF_vect) {
// Update PWM duty cycle with next sine value from lookup table
OCR1A = pgm_read_byte(&sineTable[index]);
// Increment index and wrap around
index++;
if (index >= 64) {
index = 0;
}
}
void loop() {
// Nothing to do here - everything handled by interrupts
// You can add other code here if needed
}
So I checked the signal out on an oscilloscope. Below is screenshot of the sine wave generated by using PWM signal from Arduino and then passing it through a RC low pass filter.

