Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
3 views2 pages

Work Code

The document describes an Arduino program that sets up PWM on pins D9 and D10 at 90kHz with a 50% duty cycle, where D10 has inverted PWM. It reads an ADC value from pin A0, applies a 3rd order moving average filter, and displays the filtered value on the Serial Monitor at 9600 baud. The PWM is started or stopped based on the filtered ADC value exceeding 500.

Uploaded by

p24ee0202
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views2 pages

Work Code

The document describes an Arduino program that sets up PWM on pins D9 and D10 at 90kHz with a 50% duty cycle, where D10 has inverted PWM. It reads an ADC value from pin A0, applies a 3rd order moving average filter, and displays the filtered value on the Serial Monitor at 9600 baud. The PWM is started or stopped based on the filtered ADC value exceeding 500.

Uploaded by

p24ee0202
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 2

// PWM on D9 and D10 with 90kHz, 50% duty (D10 inverted PWM)

// Read ADC from A0 and apply a 3rd order moving average filter
// Display filtered ADC on Serial Monitor at 9600 baud

volatile uint16_t adcRaw = 0;


volatile uint16_t filteredADC = 0;
uint16_t adcSamples[3] = {0, 0, 0};

void setup()
{
// Configure PWM pins
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);

// ADC input pin


pinMode(A0, INPUT);

// Start Serial communication at 9600 baud


Serial.begin(9600);

cli(); // Disable interrupts during timer setup

// Timer1 PWM setup for 90kHz with 50% duty cycle on D9 and inverted on D10
TCCR1A = 0;
TCCR1B = 0;

// Fast PWM, TOP = ICR1 (mode 14)


TCCR1A |= (1 << WGM11);
TCCR1B |= (1 << WGM13) | (1 << WGM12);

// Non-inverting OC1A (D9), inverting OC1B (D10)


TCCR1A |= (1 << COM1A1);
TCCR1A |= (1 << COM1B1) | (1 << COM1B0);

// TOP for 90kHz PWM (16MHz / (1 * (1 + TOP)) ≈ 90kHz)


ICR1 = 176;

// 50% duty cycle


OCR1A = ICR1 / 2;
OCR1B = ICR1 / 2;

// Start timer with prescaler = 1


TCCR1B |= (1 << CS10);

// ADC setup
ADMUX = (1 << REFS0); // AVcc reference, ADC0 (A0)
ADCSRA = (1 << ADEN) // ADC enable
| (1 << ADATE) // Auto trigger enable
| (1 << ADIE) // ADC interrupt enable
| (1 << ADPS2) | (1 << ADPS1) | (1<< ADPS0); // Prescaler 128

ADCSRB = 0; // Free running mode


ADCSRA |= (1 << ADSC); // Start ADC conversions

sei(); // Enable global interrupts


}

ISR(ADC_vect)
{
// Read raw ADC value
adcRaw = ADC;

// Shift samples for 3rd order moving average filter


adcSamples[2] = adcSamples[1];
adcSamples[1] = adcSamples[0];
adcSamples[0] = adcRaw;

// Simple 3rd order moving average


filteredADC = (adcSamples[0] + adcSamples[1] + adcSamples[2]) / 3;
}

void loop()
{
static unsigned long lastPrintTime = 0;
unsigned long currentTime = millis();

// Print filtered ADC every 100ms (adjust as needed)


if (currentTime - lastPrintTime >= 100)
{
lastPrintTime = currentTime;
Serial.print("Filtered ADC Value: ");
Serial.println(filteredADC);

if (filteredADC > 500 )


{
startPWM();
}
else
{
stopPWM();
}
}
}

void startPWM()
{
TCCR1B |= (1 << CS10); // Start Timer1
}

void stopPWM()
{
TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10)); // Stop Timer1
digitalWrite(9, LOW);
digitalWrite(10, LOW);
}

You might also like