HS-F27L 4路电机8路舵机扩展板

目 录 (点击目录列表可以跳转到相应位置)

  1. 介绍
  2. 原理图
  3. 模块参数
  4. 电路板尺寸
  5. 添加Arduino库文件
  6. 添加Micropython库文件
  7. ArduinoIDE 和Python语言示例程序
  8. 米思齐 Mixly 示例程序(图形化语言)
  9. Arduino测试环境搭建
  10. 视频教程
  11. 测试结论

1、介绍 点这里回到目录

实现电机控制:通过 I2C 接口与外部微控制器相连,利用 PCA9685 芯片输出 PWM 信号,实现对四路 MOC PF 电机的速度等参数的控制。8PIN 接口:提供 8 个引脚接口,可用于连接传感器、其他控制器或扩展更多功能,方便系统的进一步扩展和集成 。
电源管理:通常会集成电源接口,为连接的电机和芯片本身提供合适的电源。部分扩展板还具备反接保护电路,防止因电源正负极接反而损坏电路。


2、原理图 点这里回到目录


3、模块参数 点这里回到目录

引脚名称 描述
G GND(电源输入负极)
V VCC(电源输入正极)
SDA 数据引脚
SCL 时钟引脚

  • 供电电压: 3.3V-5V

  • 连接方式:PH2.0 4P端子线

  • 安装方式:乐高搭建


4、电路板尺寸 点这里回到目录

HS-F27L 4路电机8路舵机扩展板


5、添加Arduino库文件 点这里回到目录

Arduino环境库文件安装步骤参考链接

Arduino环境库文件:点击下载

米思齐UNO开发板库文件安装步骤(使用代码前先下载安装米思齐库文件):参考链接


6、添加MicroPython环境库文件 点这里回到目录

米思齐ESP32开发板库文件下载安装步骤(使用代码前先下载安装米思齐库文件):参考链接


7、Arduino IDE示例程序 点这里回到目录

示例程序(UNO开发板):点击下载

#include "Wire.h"
#include "Adafruit_PWMServoDriver.h"
Adafruit_PWMServoDriver PWM = Adafruit_PWMServoDriver(0x40);

void setup(){
  PWM.begin();
  PWM.setPWMFreq(85);
}

void loop(){
  PWM.setPWM(0,0,0);
  PWM.setPWM(1,0,2048);
  PWM.setPWM(2,0,0);
  PWM.setPWM(3,0,2048);
  PWM.setPWM(4,0,0);
  PWM.setPWM(5,0,2048);
  PWM.setPWM(6,0,0);
  PWM.setPWM(7,0,2048);
  for (int i = 0; i <= 180; i = i + (1)) {
    PWM.setPWM(8,0,(map(i, 0, 180, 140, 680)));
    PWM.setPWM(9,0,(map(i, 0, 180, 140, 680)));
    PWM.setPWM(10,0,(map(i, 0, 180, 140, 680)));
    PWM.setPWM(11,0,(map(i, 0, 180, 140, 680)));
    delay(50);
  }

}

示例程序(ESP32开发板):

from machine import I2C, Pin
import time
from mixpy import math_map


PCA9685_MODE1      = 0x00
PCA9685_MODE2      = 0x01
PCA9685_LED0_ON_L  = 0x06
PCA9685_LED0_ON_H  = 0x07
PCA9685_LED0_OFF_L = 0x08
PCA9685_LED0_OFF_H = 0x09
PCA9685_ALLLED_ON_L  = 0xFA
PCA9685_ALLLED_ON_H  = 0xFB
PCA9685_ALLLED_OFF_L = 0xFC
PCA9685_ALLLED_OFF_H = 0xFD
PCA9685_PRESCALE     = 0xFE

MODE1_ALLCAL  = 0x01
MODE1_SUB3    = 0x02
MODE1_SUB2    = 0x04
MODE1_SUB1    = 0x08
MODE1_SLEEP   = 0x10
MODE1_AI      = 0x20
MODE1_EXTCLK  = 0x40
MODE1_RESTART = 0x80

MODE2_OUTNE_0 = 0x01
MODE2_OUTNE_1 = 0x02
MODE2_OUTDRV  = 0x04
MODE2_OCH     = 0x08
MODE2_INVRT   = 0x10


PCA9685_I2C_ADDRESS       = 0x40
FREQUENCY_OSCILLATOR_HZ   = 25_000_000
PRESCALE_MIN = 3
PRESCALE_MAX = 255


class PCA9685:
    def __init__(self, i2c: I2C, addr: int = PCA9685_I2C_ADDRESS):
        self.i2c = i2c
        self.addr = addr
        self._oscillator_freq = FREQUENCY_OSCILLATOR_HZ

    def _write8(self, reg: int, val: int):
        self.i2c.writeto_mem(self.addr, reg, bytes([val & 0xFF]))

    def _read8(self, reg: int) -> int:
        return self.i2c.readfrom_mem(self.addr, reg, 1)[0]

    def _write4(self, base_reg: int, on: int, off: int):
        buf = bytearray(4)
        buf[0] = on & 0xFF
        buf[1] = (on >> 8) & 0x0F
        buf[2] = off & 0xFF
        buf[3] = (off >> 8) & 0x0F
        self.i2c.writeto_mem(self.addr, base_reg, buf)

    def begin(self):
        self.reset()
        mode1 = self._read8(PCA9685_MODE1)
        self._write8(PCA9685_MODE1, mode1 | MODE1_AI)
        self.set_output_mode(True)

    def reset(self):
        self._write8(PCA9685_MODE1, MODE1_RESTART)  # 写 RESTART
        time.sleep_ms(10)

    def sleep(self):
        m1 = self._read8(PCA9685_MODE1)
        self._write8(PCA9685_MODE1, m1 | MODE1_SLEEP)
        time.sleep_ms(5)

    def wakeup(self):
        m1 = self._read8(PCA9685_MODE1)
        self._write8(PCA9685_MODE1, m1 & (~MODE1_SLEEP))
        time.sleep_ms(5)

    def set_output_mode(self, totempole: bool = True):
        m2 = self._read8(PCA9685_MODE2)
        if totempole:
            m2 |= MODE2_OUTDRV
        else:
            m2 &= ~MODE2_OUTDRV
        self._write8(PCA9685_MODE2, m2)

    def set_oscillator_frequency(self, freq_hz: int):
        self._oscillator_freq = int(freq_hz)

    def get_oscillator_frequency(self) -> int:
        return self._oscillator_freq

    def set_pwm_freq(self, freq_hz: float):
        if freq_hz < 1.0:
            freq_hz = 1.0
        if freq_hz > 3500.0:
            freq_hz = 3500.0

        prescaleval = ((self._oscillator_freq / (freq_hz * 4096.0)) + 0.5) - 1.0
        if prescaleval < PRESCALE_MIN:
            prescaleval = PRESCALE_MIN
        if prescaleval > PRESCALE_MAX:
            prescaleval = PRESCALE_MAX
        prescale = int(prescaleval)

        oldmode = self._read8(PCA9685_MODE1)
        newmode = (oldmode & ~MODE1_RESTART) | MODE1_SLEEP
        self._write8(PCA9685_MODE1, newmode)
        self._write8(PCA9685_PRESCALE, prescale)
        self._write8(PCA9685_MODE1, oldmode)
        time.sleep_ms(5)
        self._write8(PCA9685_MODE1, oldmode | MODE1_RESTART | MODE1_AI)

    def read_prescale(self) -> int:
        return self._read8(PCA9685_PRESCALE)

    def set_pwm(self, ch: int, on: int, off: int):
        base = PCA9685_LED0_ON_L + 4 * ch
        self._write4(base, on & 0x1FFF, off & 0x1FFF)

    def set_pin(self, ch: int, val: int, invert: bool = False):
        if val < 0:
            val = 0
        if val > 4095:
            val = 4095

        if invert:
            if val == 0:
                self.set_pwm(ch, 4096, 0)   # fully ON
            elif val == 4095:
                self.set_pwm(ch, 0, 4096)  # fully OFF
            else:
                self.set_pwm(ch, 0, 4095 - val)
        else:
            if val == 4095:
                self.set_pwm(ch, 4096, 0)  # fully ON
            elif val == 0:
                self.set_pwm(ch, 0, 4096)  # fully OFF
            else:
                self.set_pwm(ch, 0, val)

    def write_microseconds(self, ch: int, us: int):
        prescale = self.read_prescale() + 1
        us_per_bit = (1_000_000.0 * prescale) / float(self._oscillator_freq)
        ticks = int(us / us_per_bit + 0.5)
        if ticks < 0:
            ticks = 0
        if ticks > 4095:
            ticks = 4095
        self.set_pwm(ch, 0, ticks)


i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=400000)

PWM = PCA9685(i2c, addr=0x40)

PWM.begin()

PWM.set_pwm_freq(50)
while True:
    PWM.set_pwm(0,1,4095)
    PWM.set_pwm(1,1,2000)
    PWM.set_pwm(2,1,4095)
    PWM.set_pwm(3,1,2000)
    PWM.set_pwm(4,1,4095)
    PWM.set_pwm(5,1,2000)
    PWM.set_pwm(6,1,4095)
    PWM.set_pwm(7,1,2000)
    PWM.set_pwm(8,  0, int(math_map(90, 0, 180, 140, 680)))
    time.sleep(5)
    PWM.set_pwm(0,1,2000)
    PWM.set_pwm(1,1,2000)
    PWM.set_pwm(2,1,2000)
    PWM.set_pwm(3,1,2000)
    PWM.set_pwm(4,1,2000)
    PWM.set_pwm(5,1,2000)
    PWM.set_pwm(6,1,2000)
    PWM.set_pwm(7,1,2000)
    PWM.set_pwm(8,  0, int(math_map(0, 0, 180, 140, 680)))
    time.sleep(5)

8、米思齐 Mixly 示例程序(图形化语言) 点这里回到目录

示例程序(UNO开发板)点击下载

HS-F27L 4路电机8路舵机扩展板

示例程序(ESP32开发板):点击下载

HS-F27L 4路电机8路舵机扩展板


9、测试环境搭建 点这里回到目录

Arduino UNO 测试环境搭建

准备配件:

  • UNO-R3 开发板 *1
  • UNO-R3 EXP 扩展板 *1
  • USB type-c 数据线 *1
  • HS-F27 4路电机8路舵机扩展板*1
  • PH2.0 4P双头端子线 *1
  • 6-9V电池盒*1
  • 乐高电机*4
  • 舵机*4

电路接线图:

HS-F27L 4路电机8路舵机扩展板

ESP32 Python 测试环境搭建


10、视频教程 点这里回到目录

Arduino UNO视频教程:点击查看

ESP32 Python视频教程:


11、测试结论 点这里回到目录

Arduino UNO测试结论:

下入代码,接上对应模块,上电之后,电机和舵机会同时转动。

HS-F27L 4路电机8路舵机扩展板


点这里回到目录