简体中文
English
简体中文
日本語

Arduino 上手教程

2. 设备开发 & 案例程序

5. 拓展模块

6. 应用案例

Module13.2 Servo2 Arduino 使用教程

1. 准备工作

2. 注意事项

引脚兼容性
由于每款主机的引脚配置不同,使用前请参考产品文档中的引脚兼容表,并根据实际引脚连接情况修改案例程序。

3. 案例程序

  • 本教程中使用的主控设备为 CoreS3,搭配 Module13.2 Servo2 实现舵机控制。Module13.2 Servo2 使用 I2C 通讯,请根据实际的电路连接修改程序中的引脚定义,设备连接后对应的 I2C IO 为 G12 (SDA)G11 (SCL)
cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
#include <M5Unified.h>
#include <Wire.h>
#include "Adafruit_PWMServoDriver.h"

#define SERVO_FREQ 50  // Servo PWM frequency.

Adafruit_PWMServoDriver* pwm = nullptr;

void setup()
{
    auto cfg = M5.config();
    cfg.output_power = false;// Essential for Core2/CoreS3
    M5.begin(cfg);
    M5.Lcd.setFont(&fonts::FreeMonoBold12pt7b);

    // Get M5Bus I2C pins.
    const int8_t wireSda = M5.getPin(m5::pin_name_t::in_i2c_sda);
    const int8_t wireScl = M5.getPin(m5::pin_name_t::in_i2c_scl);

    // Find the configured SERVO2 address.
    uint8_t servo2Address = 0;
    Serial.println("Scanning SERVO2 addresses 0x40-0x47...");
    for (uint8_t address = 0x40; address <= 0x47; ++address) {
        if (M5.In_I2C.scanID(address)) {
            servo2Address = address;
            Serial.printf("Found PCA9685 at 0x%02X\n", address);
            break;
        }
    }

    if (servo2Address == 0) {
        Serial.println("PCA9685 not found on M5Bus");
        M5.Display.drawString("PCA9685 not found", 10, 80);
        while (true) {
            delay(1000);
        }
    }

    Wire.setPins(wireSda, wireScl);
    pwm = new Adafruit_PWMServoDriver(servo2Address, Wire);

    if (!pwm->begin()) {
        Serial.printf("Wire could not initialize PCA9685 at 0x%02X\n", servo2Address);
        M5.Display.drawString("Wire init failed", 10, 80);
        while (true) {
            delay(1000);
        }
    }

    // Set the PWM frequency for analog servos.
    pwm->setPWMFreq(SERVO_FREQ);

    M5.Lcd.setTextColor(TFT_GREEN, TFT_BLACK);
    M5.Lcd.drawCenterString("Module13.2 Servo2 Test", 160, 10);
}

// Set one PCA9685 channel using a pulse width in milliseconds.
void setServoPulse(uint8_t n, double pulse)
{
    double pulselength;

    // Calculate the PWM period in microseconds.
    pulselength = 1000000;
    pulselength /= SERVO_FREQ;

    // Print the period for debugging.
    Serial.print(pulselength);
    Serial.println(" us per period");

    // Convert the period to one 12-bit PWM step.
    pulselength /= 4096;
    Serial.print(pulselength);
    Serial.println(" us per bit");

    // Convert the pulse width from milliseconds to PWM steps.
    pulse *= 1000;
    pulse /= pulselength;
    Serial.println(pulse);

    // Output the requested high pulse.
    pwm->setPWM(n, 0, pulse);
}

void loop()
{
    // Drive all channels with a 0.5 ms pulse.
    for (int i = 0; i < 16; i++) {
        setServoPulse(i, 0.5);
    }
    M5.Lcd.fillRect(0, 70, 320, 20, TFT_BLACK);
    M5.Lcd.drawCenterString("Pulse width: 0.5 ms", 160, 80);
    delay(1000);

    // Drive all channels with a 2.5 ms pulse.
    for (int i = 0; i < 16; i++) {
        setServoPulse(i, 2.5);
    }
    M5.Lcd.fillRect(0, 70, 320, 20, TFT_BLACK);
    M5.Lcd.drawCenterString("Pulse width: 2.5 ms", 160, 80);
    delay(1000);
}

4. 编译上传

  • 1. 进入下载模式:CoreS3 长按复位按键 (大约 2 秒) 直到内部绿色 LED 灯亮起,便可松开,此时设备已进入下载模式,等待烧录。
说明
不同设备进行程序烧录前需要进入下载模式,不同的主控设备该步骤可能有所不同。详情可参考Arduino IDE上手教程页面底部的设备程序下载教程列表,查看具体的操作方式。
  • 选中设备端口,点击 Arduino IDE 左上角编译上传按钮,等待程序完成编译并上传至设备。

5. 舵机驱动

  • 上电后,会自动初始化 Module13.2 Servo2 模块,然后循环设置 0.5ms / 2.5ms 脉宽的脉冲驱动舵机。
说明
例程代码实际驱动 16 个通道,下方图片中仅一个通道连接舵机进行演示。
Page Tools
PDF
On This Page