Hallo miteinander, ich mal wieder mit nem Problemchen.
Ich habe 2 M5 Hat_8servos geholt, das die Servos über I2C anspricht. Ich will die Dinger jedoch nicht mit dem M5 sondernmit nem STM32 nutzen. das problem ist, die Hat's haben leider eine fixe, nicht änderbare I2C-Adresse (0x36) dan mein STM32 Board (ein Stm32F411 blackpill) mehrere I2C-Schnittstellen besitzt will ich jeweils ein Hat an I2C 1 und das andere an I2C 2 hängen. In der Lib zum Hat sind jedoch die I2C Pins in der .h datei direkt eingetragen. Ich möchte jetzt jedoch gerne beim initialisieren der Lib also da wo ich angebe 'Hat_8Servos myServo' in klamern auch die SDA/SDL Pins mit übergeben, so dass ich die Lib mit meinem Conroller nutzen kann und auch die zu benutzende Schnittstelle durch die Angabe der Pins wählen kann. Wie muss ich die Hat_8Servos.h ändern, damit ich die Pins beim Init angeben kann?
hier die Hat_8Servos.h;
/*!
* @brief An 8-channel servo driver module that works From M5Stack
* @copyright Copyright (c) 2022 by M5Stack[https://m5stack.com]
*
* @Links [8Servos HAT v1.1](https://docs.m5stack.com/en/hat/hat_8servos_1.1)
* @version V0.0.2
* @date 2022-07-25
*/
#ifndef _HAT_8SERVOS_H_
#define _HAT_8SERVOS_H_
#include <Arduino.h>
#include <Wire.h>
#define SERVOS_DEVICE_ADDR 0x36
#define SERVOS_ANGLE_REG 0x00
#define SERVOS_PULSE_REG 0x10
#define SERVOS_MOS_CTL_REG 0x30
class Hat_8Servos {
private:
uint8_t _addr;
TwoWire *_wire;
uint8_t _sda;
uint8_t _scl;
bool writeBytes(uint8_t addr, uint8_t reg, uint8_t *buffer, uint8_t length);
bool readBytes(uint8_t addr, uint8_t reg, uint8_t *buffer, uint8_t length);
public:
bool begin(TwoWire *wire = &Wire, uint8_t sda = 0, uint8_t scl = 26,
uint8_t addr = SERVOS_DEVICE_ADDR);
bool setServoAngle(uint8_t index, uint8_t deg);
bool setAllServoAngle(uint8_t deg);
bool setServoPulse(uint8_t index, uint16_t pulse);
bool setAllServoPulse(uint16_t pulse);
bool enableServoPower(uint8_t state);
uint8_t getServoAngle(uint8_t index);
uint16_t getServoPulse(uint8_t index);
};
#endif
hier die Hat_8Servos.cpp
#include "Hat_8Servos.h"
/*! @brief Initialize the hardware.
@return True if the init was successful, otherwise false.. */
bool Hat_8Servos::begin(TwoWire *wire, uint8_t sda, uint8_t scl, uint8_t addr) {
_wire = wire;
_addr = addr;
_sda = sda;
_scl = scl;
_wire->begin(_sda, _scl);
delay(10);
_wire->beginTransmission(_addr);
uint8_t error = _wire->endTransmission();
if (error == 0) {
return true;
} else {
return false;
}
}
/*! @brief Write a certain length of data to the specified register address.
@return True if the write was successful, otherwise false.. */
bool Hat_8Servos::writeBytes(uint8_t addr, uint8_t reg, uint8_t *buffer,
uint8_t length) {
_wire->beginTransmission(addr);
_wire->write(reg);
_wire->write(buffer, length);
if (_wire->endTransmission() == 0) return true;
return false;
}
/*! @brief Read a certain length of data to the specified register address.
@return True if the read was successful, otherwise false.. */
bool Hat_8Servos::readBytes(uint8_t addr, uint8_t reg, uint8_t *buffer,
uint8_t length) {
uint8_t index = 0;
_wire->beginTransmission(addr);
_wire->write(reg);
_wire->endTransmission();
if (_wire->requestFrom(addr, length)) {
for (uint8_t i = 0; i < length; i++) {
buffer[index++] = _wire->read();
}
return true;
}
return false;
}
/*! @brief Set the angle of a certain servo.
@return True if the set was successful, otherwise false.. */
bool Hat_8Servos::setServoAngle(uint8_t index, uint8_t deg) {
uint8_t data = deg;
uint8_t reg = index;
return writeBytes(_addr, reg, &data, 1);
}
/*! @brief Set the angle of all servos.
@return True if the set was successful, otherwise false.. */
bool Hat_8Servos::setAllServoAngle(uint8_t deg) {
uint8_t data[8] = {0};
memset(data, deg, 8);
return writeBytes(_addr, SERVOS_ANGLE_REG, data, 8);
}
/*! @brief Set the pulse of a certain servo.
@return True if the set was successful, otherwise false.. */
bool Hat_8Servos::setServoPulse(uint8_t index, uint16_t pulse) {
uint8_t data[2] = {0};
data[1] = pulse & 0xff;
data[0] = (pulse >> 8) & 0xff;
uint8_t reg = SERVOS_PULSE_REG + (2 * index);
return writeBytes(_addr, reg, data, 2);
;
}
/*! @brief Set the pulse of all servos.
@return True if the set was successful, otherwise false.. */
bool Hat_8Servos::setAllServoPulse(uint16_t pulse) {
for (uint8_t i = 0; i < 8; i++) {
if (!setServoPulse(i, pulse)) {
return false;
}
}
return true;
}
/*! @brief Turn on power to all servos.
@return True if the set was successful, otherwise false.. */
bool Hat_8Servos::enableServoPower(uint8_t state) {
uint8_t data = state;
return writeBytes(_addr, SERVOS_MOS_CTL_REG, &data, 1);
}
/*! @brief Get the angle of a particular servo.
@return Angle of a certain servo.. */
uint8_t Hat_8Servos::getServoAngle(uint8_t index) {
uint8_t data = 0;
uint8_t reg = SERVOS_ANGLE_REG + index;
if (readBytes(_addr, reg, &data, 1)) {
return data;
} else {
return 0;
};
}
/*! @brief Get the angle of a particular pulse.
@return Pulse of a certain servo.. */
uint16_t Hat_8Servos::getServoPulse(uint8_t index) {
uint8_t data[2] = {0};
uint8_t reg = SERVOS_PULSE_REG + index;
if (readBytes(_addr, reg, data, 2)) {
return (data[1] << 8) | data[0];
} else {
return 0;
};
}
Danke schon im voraus für eure Hilfe.