You need to enable JavaScript to run this app. 基于Arduino和H桥生成PWM正弦波驱动电磁电机的频率控制咨询
优惠活动
大模型
产品
解决方案
定价
更多

基于Arduino和H桥生成PWM正弦波驱动电磁电机的频率控制咨询

问题根源

你修改f后输出没有变化,核心是两个问题:

  • 计算正弦波样点时f被约掉了:你用的公式2 * pi * f * n * dt里,dt = 1/(f*numSamples),代入计算后f直接消去,不管你把f设成多少,生成的sineSignal数组都是完全一样的20个半波绝对值采样点,波形本身不会有任何变化。
  • 采样点延时是固定值:你写死了delay(sampleFreq),也就是每个采样点停留2000ms,20个点走完整一个周期需要40秒,对应输出频率固定为0.025Hz,和你定义的f完全没有关联。

实现可变频率的修改方案

首先明确核心逻辑:输出正弦波的频率 = 1/(单周期采样点数 × 每个采样点的停留时间),你设置的numSamples=20就是单周期采样点数,只需要调整每个采样点的停留时间,就能直接控制输出频率。

修改后的参考代码如下:

const int DIR1_PIN = 4;
const int DIR2_PIN = 5;
const int PWM_PIN = 6;
const int LED_PIN = 9;

const int numSamples = 20;
const float pi = 3.1415;
float f = 1; // 按需修改这个值即可调整输出频率,单位Hz
int sineSignal[numSamples];
int dir1Array[numSamples];
int dir2Array[numSamples];

void setup()
{
  pinMode(LED_PIN, OUTPUT);
  pinMode(DIR1_PIN, OUTPUT);
  pinMode(DIR2_PIN, OUTPUT);
  pinMode(PWM_PIN, OUTPUT);

  // 正弦波表和输出频率无关,只生成一次即可
  for (int n = 0; n < numSamples; n++)
  {
    // 这里直接用2πn/numSamples计算,不需要带f,结果和你之前的计算完全一致
    sineSignal[n] = abs((int)(255 * sin(2 * pi * n / numSamples)));
    dir1Array[n] = n < numSamples / 2 ? HIGH : LOW;
    dir2Array[n] = n < numSamples / 2 ? LOW : HIGH;
  }
}

void loop()
{
  // 根据目标频率计算每个采样点的停留时长,单位ms
  int sampleDelay = 1000 / (numSamples * f);
  for (int n = 0; n < numSamples; n++)
  {
    analogWrite(LED_PIN, sineSignal[n]);
    analogWrite(PWM_PIN, sineSignal[n]);
    digitalWrite(DIR1_PIN, dir1Array[n]);
    digitalWrite(DIR2_PIN, dir2Array[n]);
    delay(sampleDelay);
  }

  // 如果需要动态调整频率,比如外接电位器,直接在这里修改f的值即可,不需要重新生成波表
  // 示例:f = map(analogRead(A0), 0, 1023, 1, 10); 即可实现1~10Hz的频率连续调节
}

补充说明

  • 如果需要输出的频率较高(比如超过10Hz),delay()的精度会不足,而且延时期间CPU无法处理其他任务,建议换成millis()实现非阻塞延时,或者用定时器中断触发射频输出,频率精度会高很多。
  • 目前的方向切换是半周时直接跳变,如果电磁阀工作时有明显顿挫感,可以在H桥输出端加一级RC低通滤波,输出的正弦波形会更平滑。

内容的提问来源于stack exchange,提问作者Hadar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.21 21:54:01