Arduino Uno如何简单绘制引脚输出与读取的PWM信号波形?
嘿,我来帮你搞定这个示波器式绘制PWM波形的需求~ 先给你捋清楚现有代码的小问题,再给你两个简单易上手的实现方案:
先修正你代码里的几个小错误
你的代码里有两处容易踩坑的地方:
pulseIn(0, pwm)用法不对:pulseIn的第二个参数只能是HIGH或LOW,用来指定你要测量的是高电平还是低电平的持续时间,不是PWM的数值,应该改成pulseIn(0, HIGH)。analogRead(0)其实读的是模拟引脚A0,不是数字引脚0;如果你想读数字引脚0的电平状态,得用digitalRead(0);要是想把PWM转换成平滑的模拟电压读取,需要给引脚9加个RC低通滤波器(1k电阻+10u电容),再接到A0引脚。
方案一:用Arduino自带的Serial Plotter(最简便,零额外工具)
这是最快实现的方法,Arduino IDE自带的串口绘图器就能直接生成波形,步骤如下:
- 修正后的参考代码(两种读取方式可选):
int pwm = 254; unsigned long highPulseTime; // 存储PWM高电平持续时间 int analogVoltage; // 存储滤波后的模拟电压值 void setup() { pinMode(9, OUTPUT); Serial.begin(115200); // 数字引脚0是RX串口接收脚,建议换成引脚2避免串口冲突,这里先保留原引脚 pinMode(0, INPUT); } void loop() { analogWrite(9, pwm); // 方式1:读取PWM高电平持续时间(直接连接引脚9和0) highPulseTime = pulseIn(0, HIGH); // 方式2:读取滤波后的模拟电压(引脚9加RC滤波后接A0) // analogVoltage = analogRead(A0); // 发送数据到串口,逗号分隔可同时显示多条曲线 Serial.print(highPulseTime); // 如果用方式2,加上下面这行 // Serial.print(","); // Serial.println(analogVoltage); Serial.println(); delay(10); // 控制波形刷新速度,可根据需求调整 }
- 电路连接:
- 测脉冲时间:直接把引脚9和数字引脚0用杜邦线连起来;
- 测模拟电压:在引脚9和A0之间接RC低通滤波器(电阻一端接引脚9,另一端接A0和电容,电容另一端接地)。
- 打开绘图器:在Arduino IDE里点击工具 > Serial Plotter(快捷键Ctrl+Shift+L),就能看到实时滚动的波形了,多条数据会用不同颜色显示。
方案二:用Processing做自定义示波器(灵活性更高)
如果你想要更个性化的波形显示(比如调整界面、添加刻度),可以用Arduino官方配套的Processing工具,步骤如下:
- Arduino端代码(只需要发送单个数值即可):
int pwm = 254; void setup() { pinMode(9, OUTPUT); pinMode(2, INPUT); // 换成引脚2避免串口冲突 Serial.begin(115200); } void loop() { analogWrite(9, pwm); unsigned long pulseTime = pulseIn(2, HIGH); Serial.println(pulseTime); delay(10); }
- Processing端代码(用来绘制滚动波形):
import processing.serial.*; Serial arduinoPort; int[] waveformData = new int[600]; // 存储600个数据点,控制波形长度 int dataIndex = 0; void setup() { size(800, 400); // 替换成你的Arduino串口端口,比如Windows的"COM3"或Mac的"/dev/ttyACM0" arduinoPort = new Serial(this, "/dev/ttyACM0", 115200); arduinoPort.bufferUntil('\n'); } void draw() { background(255); stroke(0, 100, 200); strokeWeight(2); // 绘制连续波形 for (int i = 1; i < waveformData.length; i++) { line(i-1, height - waveformData[i-1], i, height - waveformData[i]); } } void serialEvent(Serial arduinoPort) { String input = arduinoPort.readStringUntil('\n'); if (input != null) { input = trim(input); int data = int(input); waveformData[dataIndex] = data; dataIndex = (dataIndex + 1) % waveformData.length; // 循环覆盖旧数据 } }
额外注意点
- 数字引脚0是Arduino的串口RX脚,如果你用它读取信号,同时开启串口通信可能会干扰数据,建议换成其他数字引脚(比如2、3)。
- Arduino Uno引脚9的PWM频率约为490Hz,
pulseIn可以准确测量它的高电平时间,比如pwm=254时,占空比接近100%,高电平时间大概2ms左右。
内容的提问来源于stack exchange,提问作者Artur Müller Romanov
相关产品推荐
相关产品推荐

