HS-F27-L 4-Way Motor 8-Way Servo Expansion Board

HS-F27-L 4-Way Motor 8-Way Servo Expansion Board

1. Introduction

Implement motor control: Connect to an external microcontroller via the I2C interface, use the PCA9685 chip to output PWM signals, and control the speed and other parameters of the four-channel MOC PF motor.8PIN Interface: Provides 8 pin interfaces, which can be used to connect sensors, other controllers, or expand more functions, facilitating further expansion and integration of the system.
Power management: It usually integrates power interfaces to provide the appropriate power for the connected motors and the chips themselves.Part of the expansion board also has reverse connection protection circuit, preventing damage to the circuit due to reversed positive and negative poles of the power supply.

2. Schematic

PCA9685-I2C-quad MOC-PF motor-8PIN-expansion board-HS-F27-LClick to view

Module Parameters

Pin Name

description

G

GND (Negative Power Input)

V

VCC (Positive Power Input)

SDA

Data pin

SCL

clock pin

  • Supply voltage: 3.3V-5V

  • Connection method: PH2.0 4P terminal wire

  • Installation method: Lego assembly

4, Circuit Board Size

5 of Arduino IDE example program

Attention: If prompted with an error message about the library file during program upload, please import the library file first!
Arduino IDE Library Download and Import Tutorial:
Click to view

Example program (UNO development board):

#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);
  }

}

6, ESP32 Python Example (for Mixly IDE/Misashi)

Choose the development board Python ESP32 [ESP32 Generic(4MB)] and upload in code mode

Attention: If prompted with an error message about the library file during program upload, please import the library file first!
Download and import tutorial for Mixly IDE ESP32 library:
Click to view

Example program (ESP32-Python):

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)

7, Mixly example program (graphical language)

Example program (UNO development board):Click to download
Attention: If prompted with an error message about the library file during program upload, please import the library file first!
Download and import tutorial of Mixly IDE Arduino library:Click to view

Example Program (ESP32 Development Board):Click to download
Attention: If prompted with an error message about the library file during program upload, please import the library file first!
Download and import tutorial for Mixly IDE ESP32 library:
Click to view

8. Setting up the Test Environment

Arduino UNO Test Environment Setup

Prepare Components:

  • UNO-R3 Development Board *1

  • UNO-R3 Expansion Board *1

  • USB TYPE-C DATA CABLE *1

  • HS-F27 4-channel motor 8-channel servo expansion board*1

  • PH2.0 4P Double Head Terminal Line *1

  • 6-9V battery box*1

  • LEGO motor*4

  • Servo*4

Circuit wiring diagram:

ESP32 Test Environment Setup

Prepare Components:Pending update...

Circuit wiring diagram:Pending update...

9, Video tutorial

Arduino UNO video tutorial:Click to view

ESP32 Python Video Tutorial:Click to view

10, Test results

Arduino UNO test results:

Insert the code, connect the corresponding module, after powering on, the motor and servo will rotate simultaneously.