Как лучше всего получить данные от датчиков, если Arduino является подчиненным?
Я работаю над проектом, в котором контроллер двигателя (arduino nano) является ведомым устройством i2c. Его работа состоит в том, чтобы получать данные RF24 и управлять двигателем, а также одновременно отправлять данные мастеру о двигателе... В настоящее время у меня есть 2 ультразвуковых датчика для измерения расстояния, и если они будут слишком близко, он остановит двигатель. Я хочу добавить еще 2-4, но это приводит к большой задержке из-за
pulseIn();
команда. Я хочу использовать Attiny в качестве устройства чтения датчиков и просто сбрасывать текущие данные по запросу.
Возможно ли, чтобы arduino nano был подчиненным устройством i2c (аппаратное обеспечение i2c) и в то же время ведущим i2c (программное обеспечение i2c/библиотека, пожалуйста, без использования таймеров... мне их не хватает) или есть способ сбросить данные менее чем за 2 мс по последовательному или другому протоколу? SPI уже используется для RF24, и мне нужно, чтобы RF24 работал постоянно.
@Nicky, 👍-1
Обсуждение1 ответ
При одновременном использовании ведущего и ведомого устройств: да и нет. Вы можете инициировать библиотеку Wire
как подчиненную и использовать Wire.beginTransmission()
, а ее дочерние элементы отправлять в качестве главной. Библиотека настроит оборудование в качестве ведущего только на время, необходимое для отправки. Но есть 2 проблемы:
- Когда у вас есть несколько мастеров на одной шине, они должны постоянно следить за шиной, чтобы начинать передачу только тогда, когда шина свободна. Библиотека
Wire
, похоже, этого не делает. - Если два мастера начнут передачу одновременно, данные будут хорошими, поскольку все передаваемые биты равны. Для других случаев в протоколе I2C есть правило: когда два ведущих устройства одновременно начинают передачу, первый, кто первым запишет
1
на шину (высокое значение), должен немедленно вернуться в подчиненный режим. . (Это связано с тем, что для записи1
в линию данных используются подтягивающие резисторы. Когда другой ведущий пытается записать0
на шину (низкое значение на SDA), он выигрывает. против подтягиваний, эффективно записывая в порт0
, а не1
)
Как упоминалось в этой проблеме с Github, существует обходной путь, хотя я до сих пор не проверял их сам. . В целом, мультимастер I2C на данном этапе может оказаться слишком сложным.
В качестве другого варианта вы можете использовать дополнительную линию, соединяющую ведущего и ведомых (используйте внутреннюю подтяжку на стороне ведущего). Любой ведомый может в любой момент записать в эту строку LOW
, заставляя ведущего запрашивать данные у всех ведомых (возможно, через внешнее прерывание или прерывание смены контакта).
Примечание: я не знаю, для каких целей вы использовали все свои таймеры, но, возможно, есть способ поделиться одним из них с другим оборудованием, чтобы вам не приходилось использовать блокирующий pulseIn ()
. Или, может быть, вы можете настроить значение тайм-аута функции на подходящее значение.
Один таймер используется для сервопривода, другой - для миллис, задержки и ШИМ для управления двигателями, третий, я думаю, используется какой-то библиотекой.... В любом случае в цикле мне нужно прочитать 5 ультразвуковых датчиков, и он должен завершиться целиком цикл менее чем за 10 мс, я боюсь, что если я добавлю слишком много ультразвуковых датчиков (максимум 6), он будет запаздывать (задержка из-за 6-кратного импульса, у меня тайм-аут установлен на 60 см)., @Nicky
- Как перевести Arduino Nano в спящий режим с низким энергопотреблением (<0,05 мА)
- MAX30100 не работает
- Ведомое устройство Arduino с двумя мастерами, использующими одну и ту же шину I2C?
- Библиотека I2C MIFARE RC522
- Не удалось выделить SSD1306 при добавлении константы
- Сброс адреса I2c — MLX90614
- SSD1306 распознается сканером I2C, но не может его отобразить
- Могу ли я соединить вместе несколько плат Arduino Nano ?
Какова длина передаваемых данных? В любом случае, используя UART, вы можете отправить на частоте 115200 около 230 бит (23 байта) за 2 миллисекунды (считайте 8 бит/байт + стартовый и стоповый биты). На 9600 можно отправить чуть меньше 2 байт. Этого достаточно? Поскольку attiny просто должен проверить это асинхронно, лучше использовать асинхронную передачу (UART), если у нее достаточная полоса пропускания), @frarugi87
Мне понадобится около 6 байт, структура из 6 байт (6 показаний ультразвукового датчика), есть ли Serial_Anything, например I2C_anything?, @Nicky
Что ты имеешь в виду? [Serial.write(buf, len)](https://www.arduino.cc/en/Serial/Write) и, ну, чтение должно выполняться побайтово, используя [Serial.read()](https ://www.arduino.cc/en/Serial/Read) функция, @frarugi87
О, спасибо, я не знал, что могу использовать (buf, len)., @Nicky