Klausj
Published © GPL3+

PWM inside out

Get a deeper understanding what is happening by using analogWrite

IntermediateFull instructions provided1 hour280
PWM inside out

Things used in this project

Hardware components

ATmega328
Microchip ATmega328
any device with ATmega328 will do
×1

Story

Read more

Schematics

no_wires_z6TdlhDPHJ.png

Code

understandig_PWM.ino

C/C++
This sketch was meant to give you a better understanding what exactly is going to happen when you are using the analogWrite command.
/*
  Understanding PWM:
  Requirement: 
  any Arduino that contains an ATmega328, even a barebone would do.
  External hardware:

  n nnn     ooo    n nnn     eee
  nn   n   o   o   nn   n   e   e
  n    n   o   o   n    n   eeeee
  n    n   o   o   n    n   e
  n    n    ooo    n    n    eee

  PWM out: Pin-9 (controlled by TIMER-1)
  Option: Connect anode of an LED to pin-9,
  cathode of LED to GND (don't forget the resistor).
  Start the Serial plotter and set the baud rate to 115200.
  Since 1.6.7 the IDE supports drawing of multiples graphs at once.
  The area below the blue and the red graph will always be the same.
  The Serial Plotter replaces a dual beam oscilloscope.
  You can also watch the 20 minutes video of Paul McWhorter
  (https://www.youtube.com/watch?v=YfV-vYT3yfQ)
  who is using a GW Instek GOS-620FG analogue oscilloscope
  to demonstrate how PWM works, or any other of the 7 million links
  Google shows for PWM tutorial.
  Side note: as soon as the pwm value exceeds 255 it goes back to 0.
  No special treatment is required.
*/

void setup() {
  /*
    all this stuff is just to make sure the legend
    next to the blue and red bar will show up properly.
    In case it shows some garbage just restart the plotter.
  */
  delay(700);
  Serial.flush();
  Serial.begin(115200);
  delay(700);
  Serial.flush();
  Serial.println("PWM_signal mean_value");
}

byte pwm;

void loop() {
  // Serial plotter always shows 500 samples:
  const int N = 500;
  byte a[N];
  analogWrite(9, pwm);
  // to synchronize the plotter TIMER1 has to
  // start from zero to give a stable picture
  TCNT1 = 0;
  // read 500 samples fast:
  for (int i = 0; i < N; i++) {
    // trick to read pin-9:
    // sorry but this won't work: a[i] = digitalRead(9);
    a[i] = PINB & 2; // result always 0 or 2
    // with 21 you see exactly four pulses in the plot
    delayMicroseconds(21);
  }
  // calculate the mean value:
  float mean = 5.0 * pwm / 255;
  String s = " " + String(mean);
  // plot the samples (2 * 2.5 = 5 volts) and mean:
  for (int i = 0; i < N; i++) {
    Serial.print(a[i] * 2.5);
    Serial.println(s);
  }
  delay(400);
  pwm++;
}

audioOutPwmEn.zip

Arduino
Addendum. Listen to PWM signals
No preview (download only).

Credits

Klausj
89 projects • 8 followers

Comments