Интернет-лаборатория роботов ZiZiBOT.RU

Проектирование и разработки в области робототехники и автоматизации технологических процессов. Производство готовых роботов и конструкторов для творчества. Консультации и обучение по электронике и программированию.

г. Юрга,
ул.Ленинградская 38/83

+7 923-503-6074

 

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 - инвертированный сброс, подтянут через резистор к питанию, и если не собираетесь сбрасывать настроки устройства, то допустимо его не подключать.

tca9548a описание

Теперь технически можно подключить до 8 I2C устройств с одинаковыми адресами. Для примера подключим два гироприбора MPU6050 к ESP32 .

 

 

tca9548a пример подключения

А теперь опишем этапы программной обработки данного решения.

Следующая программа опрашивает два гироприбора MPU6050, которые подключены согласно схемы изображенной выше. Перед обращением к гироприбору следует вызвать функцию void tcaselect(uint8_t i) , которая задает адрес подключения I2C устройства к TCA9548A. TCA9548A производит перекоммутацию, а дальше можно производить обмен, с прибором согласно его описанию.

 


 
  1. // Библиотека для работы с протоколом I2C (порты A5/SCL и A4/SDA)
  2. #include
  3.  
  4. #define TCAADDR 0x70
  5. // упрощеный I2C адрес нашего гироскопа/акселерометра MPU-6050.
  6. const int MPU_addr = 0x68;
  7. // переменные для хранения данных возвращаемых прибором.
  8. int16_t AcX, AcY, AcZ, Tmp, GyX, GyY, GyZ;
  9. double CompensatorZ, CompensatorX, CompensatorY;
  10. double CompensatorZarray[7], CompensatorXarray[7], CompensatorYarray[7];
  11. unsigned long timer = 0;
  12.  
  13. void tcaselect(uint8_t i);
  14. void giroscop_setup(uint8_t adr);
  15. void Calc_CompensatorZ(uint8_t adr, unsigned long mill_sec);
  16. void Data_mpu6050(uint8_t adr);
  17. void setup() {
  18.  
  19.  Serial.begin(115200);
  20.  Serial.println();
  21.  
  22.  /* Enable I2C */
  23.  Wire.begin();//(22,23); //SDA //SCL
  24.  
  25.  // BNO055 clock stretches for 500us or more!
  26. #ifdef ESP8266
  27.  Wire.setClockStretchLimit(1000); // Allow for 1000us of clock stretching
  28. #endif
  29.  
  30.  giroscop_setup(2);
  31.  giroscop_setup(7);
  32.  Calc_CompensatorZ(2, 2000);
  33.  CompensatorZarray[2]=CompensatorZ; CompensatorXarray[2]=CompensatorX; CompensatorYarray[2]=CompensatorY;
  34.  Calc_CompensatorZ(7, 2000);
  35.  CompensatorZarray[7]=CompensatorZ; CompensatorXarray[7]=CompensatorX; CompensatorYarray[7]=CompensatorY;
  36. }
  37.  
  38. void loop()
  39. {
  40.  Data_mpu6050(2);
  41.  Serial.println("  MPU6050 on 2 adress");
  42.  Serial.print("Accel X = "); Serial.print(AcX);
  43.  Serial.print("  Accel Y = "); Serial.print(AcY);
  44.  Serial.print("  Accel Z = "); Serial.println(AcZ);
  45.  Serial.print("angular speed X = "); Serial.print(GyX);
  46.  Serial.print(" angular speed Y = "); Serial.print(GyY);
  47.  Serial.print(" angular speed Z = "); Serial.println(GyZ);
  48.  Serial.println();
  49.  Data_mpu6050(7);
  50.  
  51.  Serial.println("  MPU6050 on 7 adress");
  52.  Serial.print("Accel X = "); Serial.print(AcX);
  53.  Serial.print("  Accel Y = "); Serial.print(AcY);
  54.  Serial.print("  Accel Z = "); Serial.println(AcZ);
  55.  Serial.print("angular speed X = "); Serial.print(GyX);
  56.  Serial.print(" angular speed Y = "); Serial.print(GyY);
  57.  Serial.print(" angular speed Z = "); Serial.println(GyZ);
  58.  Serial.println();
  59.  delay(1000);
  60. }
  61.  
  62. //Функция мультиплексирует/переключает адреса для обмена
  63. void tcaselect(uint8_t i) {
  64.  if (i > 7) return;
  65.  
  66.  Wire.beginTransmission(TCAADDR);
  67.  Wire.write(1 << i);
  68.  Wire.endTransmission();
  69. }
  70. /////////////////////////////////////////////////////////////////////////
  71. //// Считывание данных с mpu6050
  72. /////////////////////////////////////////////////////////////////////////
  73. void Data_mpu6050(uint8_t adr)
  74. {
  75.  tcaselect(adr); //Выбор переключаемого адреса
  76.  Wire.beginTransmission(MPU_addr);
  77.  Wire.write(0x3B);  //Готовим для чтения регистры  с адреса 0x3B.
  78.  Wire.endTransmission(false);
  79.  // Запрос 14 регистров.
  80.  Wire.requestFrom(MPU_addr, 14, true);
  81.  // 0x3B (ACCEL_XOUT_H) & 0x3C (ACCEL_XOUT_L)
  82.  AcX = Wire.read() << 8 | Wire.read();
  83.  // 0x3D (ACCEL_YOUT_H) & 0x3E (ACCEL_YOUT_L)
  84.  AcY = Wire.read() << 8 | Wire.read();
  85.  // 0x3F (ACCEL_ZOUT_H) & 0x40 (ACCEL_ZOUT_L)
  86.  AcZ = Wire.read() << 8 | Wire.read();
  87.  // 0x41 (TEMP_OUT_H) & 0x42 (TEMP_OUT_L)
  88.  Tmp = Wire.read() << 8 | Wire.read();
  89.  // 0x43 (GYRO_XOUT_H) & 0x44 (GYRO_XOUT_L)
  90.  GyX = Wire.read() << 8 | Wire.read();
  91.  // 0x45 (GYRO_YOUT_H) & 0x46 (GYRO_YOUT_L)
  92.  GyY = Wire.read() << 8 | Wire.read();
  93.  // 0x47 (GYRO_ZOUT_H) & 0x48 (GYRO_ZOUT_L)
  94.  GyZ = Wire.read() << 8 | Wire.read();
  95. }
  96. /////////////////////////////////////////////////////////////////////////
  97. /// Запуск гироскопа
  98. /////////////////////////////////////////////////////////////////////////
  99. void giroscop_setup(uint8_t adr)
  100. {
  101.  tcaselect(adr); //Выбор переключаемого адреса
  102.  
  103.  Wire.beginTransmission(MPU_addr);
  104.  Wire.write(0x6B);  // Производим запись в регистр энергосбережения MPU-6050
  105.  Wire.write(0);     // устанавливем его в ноль
  106.  Wire.endTransmission(true);
  107.  CompensatorZ = 0;
  108.  CompensatorX = 0;
  109.  CompensatorY = 0;
  110. }
  111.  
  112. /////////////////////////////////////////////////////////////////////////
  113. // Компенсация нуля гироскопа
  114. void Calc_CompensatorZ(uint8_t adr, unsigned long mill_sec)
  115. {
  116.  //tcaselect(adr); //Выбор переключаемого адреса
  117.  float i = 0;
  118.  CompensatorZ = 0;
  119.  CompensatorX = 0;
  120.  CompensatorY = 0;
  121.  timer = millis();
  122.  unsigned long endtime = millis() + mill_sec;
  123.  while (endtime > timer) {
  124.    timer = millis();
  125.    Data_mpu6050(adr);
  126.    CompensatorZ += (float)(GyZ);
  127.    CompensatorX += (float)(GyX);
  128.    CompensatorY += (float)(GyY);
  129.    delay(2);
  130.    i++;
  131.  }
  132.  CompensatorZ /= i;
  133.  CompensatorX /= i;
  134.  CompensatorY /= i;
  135.  
  136. }

 

 

ОСТАВИТЬ КОММЕНТАРИЙ

Форма авторизации

ВОЙТИ С ПОМОЩЬЮ:
ИЛИ Авторизация на сайте:

или



X

Написать сообщение:

Укажите свой номер телефона или e-mail для обратной связи
- e-mail
ИЛИ
- номер телефона

Текст сообщения: