I2C мультиплексор TCA9548A Arduino
Скачать пример /articles/electronics/tca9548a/doc/9548ampu6050.zip
Документация - даташит /articles/electronics/tca9548a/doc/tca9548a.pdf
На днях возникла потребность подключить несколько датчиков угла поворота AS5600 к микроконтроллеру. У данных датчиков два интерфейса: аналоговый и I2C. При аналоговом подключении проблем со съемом данных нет, кроме помех, а вот при подключении по I2C интерфейсу возник вопрос! AS5600 имеют одинаковый адрес и изменить его невозможно, как осуществить подключение 4-х подобных датчиков? Немного разобравшись в вопросе, нашли решение: микросхема TCA9548A.
TCA9548A это переключатель I2C интерфейсов. На выходных линиях могут располагаться устройства с одинаковыми адресами, а их переключение производится управляющими командами по адресу самой микросхемы TCA9548A. Адрес TCA9548A для I2C интерфейса выбирается подачей на адресные контакты A0-A2 опрелеленных уровней: 000, это шестнадцатеричный адрес 0x70; 111 - 0х77. Если мы используем распаянную на плате микросхему как показано на рисунке ниже, то адресные контакты уже подтянуты к земле через резисторы и их можно не подключать, адрес устройства при этом будет 0х70.
RST - инвертированный сброс, подтянут через резистор к питанию, и если не собираетесь сбрасывать настроки устройства, то допустимо его не подключать.
Теперь технически можно подключить до 8 I2C устройств с одинаковыми адресами. Для примера подключим два гироприбора MPU6050 к ESP32 .
А теперь опишем этапы программной обработки данного решения.
Следующая программа опрашивает два гироприбора MPU6050, которые подключены согласно схемы изображенной выше. Перед обращением к гироприбору следует вызвать функцию void tcaselect(uint8_t i) , которая задает адрес подключения I2C устройства к TCA9548A. TCA9548A производит перекоммутацию, а дальше можно производить обмен, с прибором согласно его описанию.
-
// Библиотека для работы с протоколом I2C (порты A5/SCL и A4/SDA)
-
#include
-
-
#define TCAADDR 0x70
-
// упрощеный I2C адрес нашего гироскопа/акселерометра MPU-6050.
-
const int MPU_addr = 0x68;
-
// переменные для хранения данных возвращаемых прибором.
-
int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
-
double CompensatorZ, CompensatorX, CompensatorY;
-
double CompensatorZarray[7], CompensatorXarray[7], CompensatorYarray[7];
-
unsigned long timer = 0;
-
-
void tcaselect(uint8_t i);
-
void giroscop_setup(uint8_t adr);
-
void Calc_CompensatorZ(uint8_t adr, unsigned long mill_sec);
-
void Data_mpu6050(uint8_t adr);
-
void setup() {
-
-
Serial.begin(115200);
-
Serial.println();
-
-
/* Enable I2C */
-
Wire.begin();//(22,23); //SDA //SCL
-
-
// BNO055 clock stretches for 500us or more!
-
#ifdef ESP8266
-
Wire.setClockStretchLimit(1000); // Allow for 1000us of clock stretching
-
#endif
-
-
giroscop_setup(2);
-
giroscop_setup(7);
-
Calc_CompensatorZ(2, 2000);
-
CompensatorZarray[2]=CompensatorZ; CompensatorXarray[2]=CompensatorX; CompensatorYarray[2]=CompensatorY;
-
Calc_CompensatorZ(7, 2000);
-
CompensatorZarray[7]=CompensatorZ; CompensatorXarray[7]=CompensatorX; CompensatorYarray[7]=CompensatorY;
-
}
-
-
void loop()
-
{
-
Data_mpu6050(2);
-
Serial.println(" MPU6050 on 2 adress");
-
Serial.print("Accel X = "); Serial.print(AcX);
-
Serial.print(" Accel Y = "); Serial.print(AcY);
-
Serial.print(" Accel Z = "); Serial.println(AcZ);
-
Serial.print("angular speed X = "); Serial.print(GyX);
-
Serial.print(" angular speed Y = "); Serial.print(GyY);
-
Serial.print(" angular speed Z = "); Serial.println(GyZ);
-
Serial.println();
-
Data_mpu6050(7);
-
-
Serial.println(" MPU6050 on 7 adress");
-
Serial.print("Accel X = "); Serial.print(AcX);
-
Serial.print(" Accel Y = "); Serial.print(AcY);
-
Serial.print(" Accel Z = "); Serial.println(AcZ);
-
Serial.print("angular speed X = "); Serial.print(GyX);
-
Serial.print(" angular speed Y = "); Serial.print(GyY);
-
Serial.print(" angular speed Z = "); Serial.println(GyZ);
-
Serial.println();
-
delay(1000);
-
}
-
-
//Функция мультиплексирует/переключает адреса для обмена
-
void tcaselect(uint8_t i) {
-
if (i > 7) return;
-
-
Wire.beginTransmission(TCAADDR);
-
Wire.write(1 << i);
-
Wire.endTransmission();
-
}
-
/////////////////////////////////////////////////////////////////////////
-
//// Считывание данных с mpu6050
-
/////////////////////////////////////////////////////////////////////////
-
void Data_mpu6050(uint8_t adr)
-
{
-
tcaselect(adr); //Выбор переключаемого адреса
-
Wire.beginTransmission(MPU_addr);
-
Wire.write(0x3B); //Готовим для чтения регистры с адреса 0x3B.
-
Wire.endTransmission(false);
-
// Запрос 14 регистров.
-
Wire.requestFrom(MPU_addr, 14, true);
-
// 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
-
AcX = Wire.read() << 8 | Wire.read();
-
// 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
-
AcY = Wire.read() << 8 | Wire.read();
-
// 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
-
AcZ = Wire.read() << 8 | Wire.read();
-
// 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
-
Tmp = Wire.read() << 8 | Wire.read();
-
// 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
-
GyX = Wire.read() << 8 | Wire.read();
-
// 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
-
GyY = Wire.read() << 8 | Wire.read();
-
// 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
-
GyZ = Wire.read() << 8 | Wire.read();
-
}
-
/////////////////////////////////////////////////////////////////////////
-
/// Запуск гироскопа
-
/////////////////////////////////////////////////////////////////////////
-
void giroscop_setup(uint8_t adr)
-
{
-
tcaselect(adr); //Выбор переключаемого адреса
-
-
Wire.beginTransmission(MPU_addr);
-
Wire.write(0x6B); // Производим запись в регистр энергосбережения MPU-6050
-
Wire.write(0); // устанавливем его в ноль
-
Wire.endTransmission(true);
-
CompensatorZ = 0;
-
CompensatorX = 0;
-
CompensatorY = 0;
-
}
-
-
/////////////////////////////////////////////////////////////////////////
-
// Компенсация нуля гироскопа
-
void Calc_CompensatorZ(uint8_t adr, unsigned long mill_sec)
-
{
-
//tcaselect(adr); //Выбор переключаемого адреса
-
float i = 0;
-
CompensatorZ = 0;
-
CompensatorX = 0;
-
CompensatorY = 0;
-
timer = millis();
-
unsigned long endtime = millis() + mill_sec;
-
while (endtime > timer) {
-
timer = millis();
-
Data_mpu6050(adr);
-
CompensatorZ += (float)(GyZ);
-
CompensatorX += (float)(GyX);
-
CompensatorY += (float)(GyY);
-
delay(2);
-
i++;
-
}
-
CompensatorZ /= i;
-
CompensatorX /= i;
-
CompensatorY /= i;
-
-
}
ОСТАВИТЬ КОММЕНТАРИЙ
Форма авторизации
ВОЙТИ С ПОМОЩЬЮ:
ИЛИ Авторизация на сайте: