I2C. Хочу странного

Modsley
Offline
Зарегистрирован: 14.01.2018

Приветствую.

Задача стоит следующая. 

Есть одна ардуинка, к ней подключен гироскоп GY521. Подключен он по I2C, как я понимаю, ардуина в этом случае Master. 

Есть вторая ардуинка, к ней тоже подключен гироскоп GY521.

Можно ли в свою очередь соединить эти две ардуинки по I2C, чтобы одна запрашивала данные от другой? 

Или тут только Serial? 

 

Спасибо

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Можно, в примерах в поставке есть пример.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Modsley пишет:

Есть одна ардуинка, к ней подключен гироскоп GY521. Подключен он по I2C, как я понимаю, ардуина в этом случае Master. 

Есть вторая ардуинка, к ней тоже подключен гироскоп GY521.

Можно ли в свою очередь соединить эти две ардуинки по I2C, чтобы одна запрашивала данные от другой? 

Спасибо

Если соединять две ардуины по отдельной от гироскопов I2C, то можно и без особых проблем. Если же хотите что бы оба гироскопа и обе ардуины висели на одной I2C шине, то тоже можно, но заметно сложнее.

Logik
Offline
Зарегистрирован: 05.08.2014

//Если же хотите что бы оба гироскопа и обе ардуины висели на одной I2C шине, то тоже можно, но заметно сложнее.

Ни сказал бы что сложней. Все 4 устройства на одну шину. AD0 одного датчика на 0 друого на 1. Они на разных адресах станут. Дальше курим раздел про мультимастер на шине или делаем проще - каждая ардуина фиксирует активность на шине (т.е. опрос датчиков другой ардуиной), и сама опрашивает по таймауту после активности. Ну а если обмен между ардуинами потребуется - тоже не проблема.

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Logik пишет:

Ни сказал бы что сложней. 

То есть вы считаете, что просто послать на I2C шину команду и считать со слейва данные это задача одного уровня сложности что и 

Цитата:
Дальше курим раздел про мультимастер на шине или делаем проще - каждая ардуина фиксирует активность на шине (т.е. опрос датчиков другой ардуиной), и сама опрашивает по таймауту после активности.

?

Лично на мой взгляд, даже для опытного специалиста это, хоть и решаемые, но задачи разной степени сложности, особенно в отладке. А для начинающего это принципиально другой, хоть и достижимый, уровень.

Logik
Offline
Зарегистрирован: 05.08.2014

Мне действительно не просто стать на место новичка. Зато несложно сделать декомпозицию задачи "фиксирует активность на шине (т.е. опрос датчиков другой ардуиной), и сама опрашивает по таймауту после активности."

1. "фиксирует активность на шине" В зависимости от того, аппаратно или програмно реализована I2C тут будет по разному, но полюбому механизм фиксации работает в паузах между собственным обменом. Для аппаратной реализации ловим прерывания от модуля I2C,  в обработчике вылавливаем STOP на шине (хотя можна и не заморачиватся вылавливать именно STOP, если таймаут заведомо большой и на любое прерывание i2c годно срабатывать) и сохраняем текущее время, т.е. millis(), в переменную. Для програмной реализации проще по завершению собственного обмена настроить пин на котором SCK на прерывание, а в нем как и для аппаратного - сохраняем текущее время. Универсальный подход - заводим свободный пин на SCK и в его прерываниии делаем то же самое. В любом случае позаботится чтоб механизм не реагировал на собственный обмен контролера по шине, например запретом соответствующего прерывания во время собственного обмена.

2. "по таймауту после активности." Совсем просто. Зная время последней чужой активности формируем таймаут по механизму аналогичному "блинкбезделея". Когда время таймаута истекло - делаем опрос датчиков. Вторая ардуина в это время, работая по такому же алгоритму ждет и молчит.

Как видим новичку всегото надо: уметь работать с прерываниями, как минимум прерываниями пинов и владеть "блинкбезделея". Не особо то и много. Конечно это не для человека 3 дня как начавшено. Но и обмен по i2c с GY521 тоже требует знаний выше чем 3 дня опыта. Даже вобщем поболе чем прерывания пина и "блинкбезделея".

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

asam, Да, это ни разу не сложней. Надо просто пользовать правильный режим драйвера I2C, там практически "все едино".. ;)

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Arhat109-2 пишет:

asam, Да, это ни разу не сложней. Надо просто пользовать правильный режим драйвера I2C, там практически "все едино".. ;)

В софтверной индустрии сложность кода принято измерять его длинной. Критерий не идеальный, но тем не менее.

Что бы считать байт из регистра слейва (например EEPROM) при одном мастере нам надо 

    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,1);
    data = Wire.read();

Приведите, пожалуйста, пример как можно реализовать то же чтение  байта, с учетом того, что у нас есть 2й мастер и надо делать арбитраж, используя TwoWire lib или любую другую доступную ардуиновскую библиотеку.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

asam пишет:

Arhat109-2 пишет:

asam, Да, это ни разу не сложней. Надо просто пользовать правильный режим драйвера I2C, там практически "все едино".. ;)

В софтверной индустрии сложность кода принято измерять его длинной. Критерий не идеальный, но тем не менее.

Что бы считать байт из регистра слейва (например EEPROM) при одном мастере нам надо 

    Wire.beginTransmission(deviceaddress);
    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(deviceaddress,1);
    data = Wire.read();

Приведите, пожалуйста, пример как можно реализовать то же чтение  байта, с учетом того, что у нас есть 2й мастер и надо делать арбитраж, используя TwoWire lib или любую другую доступную ардуиновскую библиотеку.

Посмотрите даташит, я уже плохо помню, но там вроде как занятость шины контролируется аппаратно и в случае мультимастер - наличия двух мастеров (2 дуньки) и обращения каждой к своему или общему слейву - ничего в коде менять не требуется. Для общения двух дунек промеж себя, мне в своем драйвере надо только изменить режим компиляции на "Master+Slave" и назначить адреса в сетапе. Остальное будет работать точно также.

Там "проблема" (новые типовые библиотеки не смотрю уже давно, а в старых так было) в том, что вокруг самого драйвера наворочено много лишнего и оно не позволяло работать в режимах "чтение после записи" без освобождения шины, что соответственно не позволяло читать мультимастером, скажем внешнюю общую EEPROM: надо сначала отправить команду записи адреса чтения, а потом команду чтения и получить данные без освобождения шины. Это более одной посылки и кто послал, кого послал, куда послал .. 2 мастера с пошаговым освобождением шины после каждой посылки способны запутаться от слова "легко".

Собственно это (кривизна типовых библиотек) и побудило меня в свое время сваять себе собственный драйвер. Пока не жалуюсь..

P.S.

Это вообще больная тема "в целом": наши "преподы" учат не писать код (алгоритмированию), а пользовать типовые библиотеки, которые писаны для некоего своего применения и далеко не всегда "удобны/полезны". Даже тут посмотрите:

основные проблемы это - "я взял код"(свистнул) тут, прикрутил это, подключил то .. и оно не работает, что делать?

типовые "советы": "возьмите эту библиотеку" или "попробуйте такой скетч" ..

Занавес. Собственно "местные идиотики" и возбуждаются по этому поводу ..

 

asam
asam аватар
Offline
Зарегистрирован: 12.12.2018

Ваша правда - в  тех драйверах что идут в стандартно поставке - twi.c что-то про арбитраж есть. Но что-то берут меня сомнения - насколько все это будет работать хоть при каком нибудь серьезном траффике. Надо будет подключить 4 EEPROM и 4 Ардуины на одну линию и посмтореть как вся эта хрень с блэкджеком  и шлюхами будет работать... 

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

Если не будете подключать типовые ардуиновские Wire.h и пр. хренотень, а делать через twi.h (кажется есть даже релиз в avr инклудах) то пользуйте режим "чтение после записи" и всё должно получиться. Аппаратная реализация мультимастера от нагрузки не зависит. Проблема (раньше была) как раз в том что Wire.h освобождает шину после каждой посылки каждого байтика и имеет по кучке лишнего для запуска, останова и т.д. на каждый байтик. Ручками все получается куда как кучерявей и, кроме этого, легко можно управлять скоростью обмена вплоть до 880Мгц включительно. Атмелы это тянут.

Пошукайте тут где-то был и сам драйвер и код его применения для LCD (там правда тема засрана..). Если что-то останется непонятно - лучше пишите на почту.