Соединение АЦП при создании миди-контроллера (множество потенциометров)

Я делаю миди-контроллер с помощью Arduino Uno. Он содержит около 50 аналоговых входов с потенциометрами. У меня достаточно АЦП MCP3008, но я понятия не имею, как подключить 2 или более АЦП к Arduino, чтобы я мог прочитать 50. Как сложить АЦП?

, 👍0

Обсуждение

Также вопрос: http://forum.arduino.cc/index.php?topic=569402. Если вы собираетесь это сделать, пожалуйста, будьте достаточно внимательны и добавьте ссылки на другие места, где вы размещаете перекрестные сообщения. Это позволит нам избежать траты времени из-за дублирования усилий, а также поможет другим, у кого возникнут такие же вопросы и кто найдет ваше сообщение, найти всю необходимую информацию., @per1234

зачем вам использовать потенциометры? ..... цифровые кодеры имели бы гораздо больше смысла, @jsotola


2 ответа


1

Эти АЦП используют протокол SPI. К счастью, в Arduino есть такой модуль.

С каждым АЦП вы получаете 8 каналов (таким образом, входов). Поскольку вам нужно более одного устройства SPI (в вашем случае АЦП).

С помощью SPI вы можете подключить несколько устройств SPI к порту SPI Arduino. Чтобы выбрать, какой из них активен, вы используете сигнал выбора чипа/ведомого устройства. Это отдельный GPIO, который вы можете определить самостоятельно. Узнайте больше о SPI, чтобы узнать подробности.

Для 50 входов необходимо 50/8, округляя вверх, получается 7 АЦП. Это означает также 7 контактов CS. Таким образом, всего вам понадобится 3 (для SPI) + 7 = 10 контактов. Надеюсь, у вас осталось столько же.

Что касается «стекирования», просто поместите АЦП на макетную плату и подключите их в соответствии с протоколом SPI.

См. также Справочный SPI Arduino

,

Обратите внимание, что при таком большом количестве устройств на шине SPI вам может потребоваться снизить скорость связи или включить драйвер линии, чтобы преодолеть повышенную емкость шины., @Majenko

Пониженная скорость будет встроена из-за максимальной тактовой частоты 3,6 МГц для MCP3008 — таким образом, тактовая частота SPI составит 2 МГц для Arduino с частотой 16 МГц., @CrossRoads


0

При использовании SPI SCK, MISO, MOSI подключаются параллельно ко всем устройствам. Устройство с активным низким выводом Chip Select — это то, которое получает команду, а затем отправляет данные, остальные игнорируют происходящее. Вы также можете загрузить данные в сдвиговый регистр для создания выбора микросхемы, поэтому для всех устройств необходимы только 4 контакта: SCK (13), MISO (12), MOSI (11) и использовать D10, контакт SS. поскольку штифт защелки (SRCK) в 74HC595 для чипа 7 переключается на MCP3008.

Код для цикла может быть довольно простым.

for (pin = 0; pin <7; pin = pin +1){
  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address] = SPI.transfer(addressByte [address]); // send out address, read in D9, D8
  lowerBits[pin + address] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+1] = SPI.transfer(addressByte [address+1]); // send out address, read in D9, D8
  lowerBits[pin + address+1] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+2] = SPI.transfer(addressByte [address+2]); // send out address, read in D9, D8
  lowerBits[pin + address+2] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+3] = SPI.transfer(addressByte [address+3]); // send out address, read in D9, D8
  lowerBits[pin + address+3] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+4] = SPI.transfer(addressByte [address+4]); // send out address, read in D9, D8
  lowerBits[pin + address+4] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+5] = SPI.transfer(addressByte [address+5]); // send out address, read in D9, D8
  lowerBits[pin + address+5] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+6] = SPI.transfer(addressByte [address+6]); // send out address, read in D9, D8
  lowerBits[pin + address+6] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

  digitalWrite (csPin[pin], LOW); // select a device
  SPI.transfer(startByte); // send out start byte
  upperBits[pin + address+7] = SPI.transfer(addressByte [address+7]); // send out address, read in D9, D8
  lowerBits[pin + address+7] = SPI.transfer(0);  // send out don't care read in D7-D0
  digitalWrite (csPin [pin), HIGH); // deselect a device

}

Конечным результатом являются два 56-байтовых массива, UpperBits[] и LowerBits[], объединяющие по байту каждого для чтения на канал.

У меня там много дублированного кода, который, вероятно, можно было бы свести к циклу внутри цикла, чтобы устранить избыточность.

Адрес также может быть получен из массива, так как данные должны быть 0b10000000, 0b10010000, 0b10100000, 0b10110000, 0b11000000, 0b11010000, 0b11100000, 0b11110000

или начните с адреса = 0x80 и добавьте 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70

Этот код должен интегрироваться для управления сдвиговым регистром, о котором я забыл, поэтому вместо

digitalWrite (csPin[pin], LOW);
and
digitalWrite (csPin[pin], HIGH);

у вас было бы

digitalWrite (shiftRegisterLatch, LOW); // первый низкий уровень CS MCP3008
SPI.transfer(0b11111110);
digitalWrite (shiftRegisterLatch, HIGH); //первый низкий уровень CS MCP3008
// читаем из ADC0 на первом MCP3008, используя SPI.transfers выше
digitalWrite (shiftRegisterLatch, LOW); // первый высокий уровень CS MCP3008
SPI.transfer(0b11111111);
digitalWrite (shiftRegisterLatch, HIGH); //первый высокий уровень CS MCP3008

Повторите действия для каналов от ADC1 до ADC7

Затем перейдите к следующему устройству:

digitalWrite (shiftRegisterLatch, LOW); // 2-й низкий уровень CS MCP3008
SPI.transfer(0b11111101);
digitalWrite (shiftRegisterLatch, HIGH); //2-й MCP3008 CS низкий
// читаем из ADC0 на втором MCP3008, используя SPI.transfers выше
digitalWrite (shiftRegisterLatch, LOW); // 2-й высокий уровень CS MCP3008
SPI.transfer(0b11111111);
digitalWrite (shiftRegisterLatch, HIGH); //2-й MCP3008 CS высокий

Таким образом, данные также могут быть в массиве: 0b11111110, 0b11111101, 0b11111011, 0b11110111, 0b11101111, 0b11011111, 0b10111111, с 0b11111111 для отключения CS

Я бы также использовал прямое манипулирование портом вместо digitalWrite(), чтобы ускорить фиксацию данных в сдвиговом регистре.

,