Lab 1: Digital Signal Generation

Course: DE6417 Microcontrollers 2

Assessment Type: Laboratory (Practical)

Weighting: 6%

1. Objective

Design and implement a digital signal generator using an Arduino Uno R3. The system will generate three distinct waveforms—Square, Triangle, and Sine—using Pulse Width Modulation (PWM) techniques. The frequency of these signals must be adjustable via a rotary potentiometer.

Key Requirement: This is a strictly digital implementation. You will observe the changing duty cycles (PWM modulation) directly on an oscilloscope to understand how digital signals can represent analog waveforms.

2. Learning Outcomes

This lab assesses the following course learning outcomes:


3. Hardware Implementation

Required Components

Connection Table

Component Arduino Pin Notes
Potentiometer (Wiper) A0 Analog Input for Frequency
Push Button Digital 2 Input (Active High with Pull-down)
Output Signal Digital 9 PWM Output (Probe here)
Oscilloscope GND GND Common Ground

Circuit Setup

  1. Potentiometer: Connect the wiper to Analog Pin A0. Connect the outer legs to 5V and GND.
  2. Mode Switch: Connect a push button to Digital Pin 2 (configure as input). Use a pull-down resistor or internal pull-up.
  3. Signal Output: Use Digital Pin 9 (OC1A) or 3 (OC2B) for the PWM output. Connect this pin to the Oscilloscope probe.
  4. Ground: Ensure the Oscilloscope ground is connected to the Arduino GND.

4. Theory: Digital Signal Generation

4.1 Pulse Width Modulation (PWM)

Digital pins can only be strictly HIGH (5V) or LOW (0V). To generate "analog-like" signals, we use PWM. By switching the pin on and off very fast, the average voltage corresponds to the Duty Cycle (D).

Formula:
Vavg = Vcc × D

Where:

Example:
If the signal is ON for 50μs and OFF for 50μs (Ttotal = 100μs):
D = 50 / 100 = 0.5 (50%)
Vavg = 5V × 0.5 = 2.5V

4.2 Sinusoidal PWM (SPWM) & Look-Up Tables

To generate a sine wave, we cannot calculate sin(x) inside the Interrupt Service Routine (ISR) because standard math functions are too slow for high-speed signals.

Instead, we use a Look-Up Table (LUT). This is a pre-calculated array of integers representing one full sine wave cycle.

LUT Formula:
LUT[i] = 127 + 127 × sin( 2π × i / N )

Visual Concept:
Imagine walking through this array.


5. Software Development

Task A: Frequency Control (ADC)

Read the analog voltage from the potentiometer (0-5V) and map it to a frequency range.

Task B: Waveform Generation (PWM)

Implement a system to generate three waveforms. Use a Timer Interrupt to update the PWM duty cycle at a fixed "sampling rate." This ensures stable timing regardless of the main loop's workload.

Why use Interrupts?
If you generate signals inside the loop(), the timing will jitter whenever you read the ADC or check buttons. An interrupt ensures your waveform updates happen at perfect intervals (e.g., every 50μs or 100μs).

1. Setup Timer Interrupts (Example)

You will need to configure a timer (e.g., Timer1 or Timer2) to trigger an interrupt at a specific frequency.

void setupTimer1() {
  noInterrupts();           // Disable interrupts during setup
  TCCR1A = 0;               // Clear control registers
  TCCR1B = 0;
  TCNT1  = 0;               // Initialize counter value to 0
  
  // Set Compare Match Value for your desired sampling frequency
  // Formula: OCR1A = (16,000,000 / (Prescaler * Target_Freq)) - 1
  OCR1A = 399;              // Example for 40kHz sampling (with Prescaler 1)
  
  TCCR1B |= (1 << WGM12);   // CTC Mode
  TCCR1B |= (1 << CS10);    // No Prescaler
  TIMSK1 |= (1 << OCIE1A);  // Enable Timer Compare Interrupt
  interrupts();             // Enable interrupts
}

ISR(TIMER1_COMPA_vect) {
  // This function runs automatically ~40,000 times per second
  // Update your PWM duty cycle here!
}

2. Signal Generation Logic (Inside ISR)

Square Wave Logic:

// Logic: Toggle strictly between 0 and 255 based on a "counter"
static int counter = 0;
counter++;
if (counter >= period) {
    if (currentOutput == 0) currentOutput = 255;
    else currentOutput = 0;
    counter = 0; // Reset
}
analogWrite(PWM_PIN, currentOutput);

Triangle Wave Logic:

// Logic: Increment duty cycle until 255, then decrement to 0
static int duty = 0;
static int direction = 1; // 1 for up, -1 for down

duty += direction * stepSize; // 'stepSize' controls frequency
if (duty >= 255) {
    duty = 255; 
    direction = -1; // Switch to ramp down
} else if (duty <= 0) {
    duty = 0; 
    direction = 1;  // Switch to ramp up
}
analogWrite(PWM_PIN, duty);

Sine Wave (SPWM) Logic:

// Logic: Read from a Look-Up Table (LUT)
static int index = 0;
// 'step' can be a fixed point number or integer to vary speed
index = (index + speed) % LUT_SIZE; 
analogWrite(PWM_PIN, sineTable[index]);

Task C: Mode Switching

Implement a state machine to switch between waveforms when the button is pressed (Square -> Triangle -> Sine -> Square...).

Debounce: Ensure the button press is debounced correctly to prevent skipping modes.

6. Verification & Observation

  1. Connect the Oscilloscope to the PWM output pin.
  2. Square Mode: Verify that the signal toggles between 0V and 5V. Adjust the potentiometer and observe the period change.
  3. Triangle Mode: Adjust the time base on the scope. You should see a "train" of pulses where the width steadily increases and decreases.
  4. Sine Mode: Observe the SPWM pattern. The pulse density should appear sinusoidal.

Note: Since there is no filtering, you will NOT see a smooth analog sine wave. You are observing the raw digital SPWM signal.


7. Submission Requirements

Create a ZIP file containing the following:

  1. Arduino Sketch (.ino): Fully commented code.
    • Explain your Timer configuration registers.
    • Explain how the LUT was calculated.
  2. Video Demonstration: A Cloud Link (e.g., OneDrive, YouTube Unlisted, Google Drive) to a short video showing:
    • Switching between modes.
    • Varying the frequency with the potentiometer.
    • The resulting waveforms on the Oscilloscope.

Deadline: [Insert Date Here]


8. Grading Rubric

Criteria Marks Details
Hardware Setup 10 Correct wiring of pot, button, and scope connections.
Software: Frequency Control 20 Smooth frequency variation using ADC reading.
Software: Waveforms 40 Square (10): Correct frequency.
Triangle (15): Linear duty cycle ramp.
Sine (15): Accurate SPWM using LUT.
Mode Switching 10 Reliable button switching (debounced) between modes.
Code Quality & Understanding 10 Properly commented code, correct register usage, non-blocking logic.
Demonstration 10 Clear video showing all functionality.
Total 100