How can I plot a square pwm signal?

I am using an arduino uno to change the brightness of an led I have connected to PWM Pin 9. It works fine on its own without any additional code, but I was wondering if I could read pin 9’s square wave signal and plot it onto the serial plotter. Any ideas?

Why don't you simply try it?

when I try to analogRead pin 9 and give it a pwm signal at the same time, it outputs 0 and the LED doesn't light up. Any idea on how to fix this problem?

Which Arduino board?

A pin can perform only one function at a time.

PWM is digital so use digitalRead().

This could work...

Analogread may not be fast enough to follow pwm.
Maybe you should connect your pin to another pin for reading. You cannot have a pwm on a pin and read it without first stopping the pwm...
Also pwm is either high or low, so analogread makes no sense.

are you saying that I connect the digital PWM pin on my arduino uno to an analog input and read the PWM at the same time?

That is indeed my suggestion. Your new pin must be set as an input.
If you use a 220 ohm resistance wou may prevent damage if you set the pin to output and write an opposite state compared to your output pin.
Serial monitor and/or your eyes will be too slow to follow a normal pwm. You would need to buffer some readings and then write them to the monitor.

So, Ive hooked up an LED to pin 9 and connected that via 220 ohm resistor to pin A0. I adapted the "Fading" Example and can now plot the values. One problem though, the PWM waves are extremely thin and shoot up very high when alternating from 0v to 5v. Do you know of ways to fix this? Heres my code:

int ledPin = 9;    // LED connected to digital pin 9

void setup() {
  Serial.begin(9600); // Serial Setup
}

void loop() {
  // fade in from min to max in increments of 5 points:
  for (int fadeValue = 0 ; fadeValue <= 255; fadeValue += 1) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);
    Serial.println(map(analogRead(A0), 0, 1000, 0, 50)); // Part I added
    // wait for 30 milliseconds to see the dimming effect
    delay(30);
  }

  // fade out from max to min in increments of 5 points:
  for (int fadeValue = 255 ; fadeValue >= 0; fadeValue -= 1) {
    // sets the value (range from 0 to 255):
    analogWrite(ledPin, fadeValue);
    Serial.println(map(analogRead(A0), 0, 1000, 0, 50)); // Part I added
    // wait for 30 milliseconds to see the dimming effect
    delay(30);
  }
}

Here's what my serial monitor looks like.

That's a perfect square wave with a too high frequency for your sample rate.

The default PWM frequency is 480Hz (2ms), and you wait 30ms between two analogRead(). What meaningful curve do you expect?

I am trying to get something similar to this: image

Then sample it many times per millisecond. You need a high baud rate to be able to pass those values back though.

A 'scope or logic analyzer are the best tools to use for this.

OK, I found that 115200 baud is a good rate, but the wave is still extremely thin. At any other baud setting, it just spits out random question marks and characters. Is there any way to fix the wave being very spiky?

Please try to add a time scale to your expected curve. Perhaps then you understand why you expect something impossible.

Simplest way to get a fine rectangle: use BlinkWithoutDelay to produce a low frequency rectangle that can be scanned properly.

Why does the signal have to look pretty on the monitor, just curious?

I am going to use it as a demonstration of what PWM looks like and I would like it to look minimal and not too extreme.

1 Like

You should understand the problems you encounter before publishing your demonstration results. Else you only demonstrate your ignorance of the subject :frowning:

As said, you need to make a buffer with data of say 200 ms. Then you could send the data to the monitor. Maybe you can use a larger prescaler in pwm to make the wave slower. Dofferent pwm have different pwm freqs. So you coul chose slow one.