Внесение изменений в библиотеку датчика BMP180

imy5665
Offline
Зарегистрирован: 14.07.2016

Здравствуйте! Понемного осваиваю ардуино и сегодня столкнулся с проблемой, рпешение которой в сети не нашел. Есть два устройста, работающих через шину I2C и по, судя по описанию библиотек, должны подключасться к одним и тем же ногам ардуины (А4, А5). Хотелось бы узнать, как внести изменения в библиотеку одного устройста, чтобы можно было поключить к разным ножкам Ардуино. Спасибо

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

Зачем? I2C - общая шина, на ней могут висеть несколько устройств одновременно, выбираются по адресу на шине.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

А я вот с недавних пор задался вопросом: можно ли сделать так, чтобы Ардуино для части устройств был ведущим, а для части - ведомым (конкретнее: чтобы Ардуино-мастер управлял Ардуино-слейвами, к каждому из которых по I2C подключены исполнительные устройства)?

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

andriano пишет:

А я вот с недавних пор задался вопросом: можно ли сделать так, чтобы Ардуино для части устройств был ведущим, а для части - ведомым (конкретнее: чтобы Ардуино-мастер управлял Ардуино-слейвами, к каждому из которых по I2C подключены исполнительные устройства)?

Почему нет? Делаю подобное как раз сейчас, только не по I2C, а по 1-Wire и RS-485. Как раз есть и исполнительные модули, которые типа всякими реле рулят, и - модули с датчиками, к которым подключены всякоразные датчики, в том числе и по I2C. Т.е. ведомый модуль для подключенных к нему устройств - вполне себе ведущий.

Или я не понял вопроса?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Честно говоря, с 1-Wire не работал. Несколько смущает 8-байтный идентификатор. На каких там вообще скоростях можно работать? И на какие пины это можно подключать?

a5021
Offline
Зарегистрирован: 07.07.2013

andriano пишет:
А я вот с недавних пор задался вопросом: можно ли сделать так, чтобы Ардуино для части устройств был ведущим, а для части - ведомым (конкретнее: чтобы Ардуино-мастер управлял Ардуино-слейвами, к каждому из которых по I2C подключены исполнительные устройства)?

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

Второй вариант -- к аппаратному I2C интерфейсу добавить еще софтовый и по одному из них разговаривать с датчиками, а по второму с главным ардуиной.

Третий вариант -- мультиплексировать шину внешним чипом. Что-то вроде такого:

Еще наверное можно использовать кобинации из  этих способов.

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

andriano пишет:

Честно говоря, с 1-Wire не работал. Несколько смущает 8-байтный идентификатор. На каких там вообще скоростях можно работать? И на какие пины это можно подключать?

У мну самопальное общение, без выбора адресов. Скорости и тайминги - из даташита на 1-Wire, их вполне хватает для работы с датчиками и прочей хренью. Конечно, для realtime реагирования - в топку, не для того протокол изначально придумывался :)

Кстати, гоняю по шине туда/сюда по 30 байт в виде скратчпада, так что 8-байтный идентификатор смущать вас не должен :) Впрочем, оговорюсь, что у мну только частичная реализация 1-Wire, без выбора адресов на шине, писалось коллегой, я только чуть-чуть правил код 1-Wire автомата.

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

Может и легко. Режимы мастера и слейва у мег практически независимы, и находясь в режиме слейва адрес устройства задается программно, то бишь "выбери любой". Более того! все эти мастера, слейвы и периферия могут висеть .. на одной и той же шине I2C.

Делал обработчик I2C для своего arhat.h .. в качестве теста использовалась конфигурация Mega2560 - master, UNO328P - slave, LCD1602 - разделяемая периферия и гирокомпас. Всё на одной шине. Задача: Мега2560 читает данные со своего узв. датчика и отдает их слейву, который выводит расстояние в нижнюю строку экрана. Слейв читает данные с гироскопа и отдает их мастеру по запросу, который выводит результат в верхнюю строку экрана.

Код искать лень, да и не уверен что он сохранился .. была "перестройка компа".

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Мультимастер - это интересно, надо будет почитать.

Софтовый вариант, вероятноЮ не подойдет по скорости.

Мультиплексирование - вообще не понял, в чем "фишка". Как иакая схема позволит быть и мастером и слейвом одновременно?

С мастеру должно быть подключено порядка десятка слейвов (поэтому "индивидуальные" протоколы типа COM-порта не подходят), а слейв должен управляться со своими устройствами, НИКОГДА не отключаясь от мастера.

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

А какие требования к скорости? Почему считаете, что софтовый вариант не пойдёт? Можно ведь по разному написать - на таймерах, прерываниях, ещё как.

Celestron
Offline
Зарегистрирован: 13.04.2016

Да простит меня топик-стартер. Тоже есть вопрос по реализации I2C в ардуино. Не секрет, что большинство датчиков I2C имеют регистры данных. Когда для чтения данных ты сначала отправляешь адрес, потом регистр и только потом читаешь или пишешь в него. Так вот, неожиданно захотелось сделать полноценный обмен данными по i2C между двумя ардуинами. И...

Для начала передачи с мастера на слейв мы пишем

Wire.beginTransmission(18);

И далее методом Wir.write(nn) отдаем байты слейву. Все нормально, здесь можно и регистр указать и данные отправить и т.п.

Слейв принимает данные от мастера (в данном случае они воспринимаются как запрос конкретных данных из всего существующего набора) и что-то может даже отдать. Но дальше, чтобы получить данные от слейва на мастере я должен сказать Wire.requestFrom(адр, кол-во). А если я не знаю кол-ва, которое мне передаст слейв (у меня для этого стоп-байт сущестует)? И почему я не могу сразу использовать Wire.read() на мастере для чтения. Я догадываюсь, что это связано с "открытием соединения". Но вопрос, он его будет закрывать, только после получения указанного количества байтов?

Я сегодня вечером буду экспериментировать, но если кто-то сразу наведет меня на мысли, буду очень признателен.

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

Будете разбираться - не забудьте заглянуть в файлик twi.c .. это и есть "собственно реализация" :)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

DIYMan пишет:

А какие требования к скорости? Почему считаете, что софтовый вариант не пойдёт? Можно ведь по разному написать - на таймерах, прерываниях, ещё как.

Ну, все три таймера уже заняты. Требования к скорости пока трудноформализуемы. В общем время отклика на любое воздействие должно быть порядка 1 мс при том, что эту миллисекунду уже и так есть чем занять. Ну и прерывания, связанные с обменом, не должны мешать прерываниям от таймера.

По-хорошему мне нужно, чтобы прерывания от 2-го таймера шли с наивысшим приоритетом. Вплоть до того, что прерывали прерывания 0-го таймера. Пока не понял, можно ли так сделать.

a5021
Offline
Зарегистрирован: 07.07.2013

andriano пишет:
а слейв должен управляться со своими устройствами, НИКОГДА не отключаясь от мастера.

Аппаратный I2C для связи с мастером, а софтовый для общения с устройствами.

Скорость на интерфейсе задает мастер. Именно он генерит синхру на SCL. С какой частотой идут импульсы на SCL, с такой скоростью и идет обмен. Всякие датчики и прочие слейв-устройства вообще могут не знать с какой частотой они работают. Они тупо по каждому заднему фронту на SCL либо прижимают SDA к земле, либо отпускают. Это, если они передают что-то. Если принимают, то читают состояние SDA по каждому заднему фронту во внутренний сдвиговый регистр.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

a5021 пишет:

Аппаратный I2C для связи с мастером, а софтовый для общения с устройствами.

Ну, в общем-то логично. Но нужно посчитать, потянет ли софтовый скорость обмена хотя бы 400 kbps. Там ведь 4 перехода уровня на 1 бит, да служебные биты. Т.е. примерно по 0.5 мкс на один переход. 8 тактов процессора, пожалуй, не для С.

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

andriano пишет:

По-хорошему мне нужно, чтобы прерывания от 2-го таймера шли с наивысшим приоритетом. Вплоть до того, что прерывали прерывания 0-го таймера. Пока не понял, можно ли так сделать.

STM?

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Нет, обычная 328.

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

andriano пишет:

Нет, обычная 328.

Я имел в виду - может, стоит посмотреть в сторону STM? Там есть и приоритеты прерываний, и прочие описанные вами хотелки.

a5021
Offline
Зарегистрирован: 07.07.2013

andriano пишет:
Ну, в общем-то логично. Но нужно посчитать, потянет ли софтовый скорость обмена хотя бы 400 kbps.

Хотябы? 8-0 Не все полностью железные I2C устройства поддерживают эту скорость, а вы в софте собираетесь? Сильно завшенные ожидания. Софтовые скорости -- это цифры в районе 50кгц, с понижением в зависимости от загрузки другими задачами.

Цитата:
пожалуй, не для С.

Пожалуй не для меги.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

a5021 пишет:

Хотябы?

...

Пожалуй не для меги.

Пожалуй, софтверный вариант отпадает. А у аппаратного 400к без проблем.

a5021
Offline
Зарегистрирован: 07.07.2013

Пожалуй, мега отпадает. А у другий семейств и по нескольку железных I2C и со скоростями до 3.4мгц без проблем.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Нет, мега остается, отпадает что-то другое. Например, I2C в одном из применений.

Кстати, почитал о мультимастер - это тоже не то. Слейвам не нужно инициировать связь с мастером. А нужно управлять каждому своей периферией, причем идентификаторы периферии разных слейвов могут пересекаться, т.е. их надо делать в разных адресных простанствах. Вероятнее всего, отказаться придется именно от I2C при управлении датчиками.

a5021
Offline
Зарегистрирован: 07.07.2013

Что ж это за датчики такие, которые требуют не ниже 400к по I2C, адреса у них одинаковые, а в случае чего, можно и I2C послать нахрен? Как-то у меня картинка не складывается.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Минимизировать нужно не время взаимодействия с датчиками как таковое, а время полного прохода цикла loop(). Да и не датчики на самом деле, а исполнительные устройства. Их можно выбрать разные - с тем или иным протоколом обмена. В частности, есть I2C. Хотелось бы, чтобы единичный акт взаимодействия с датчиком не превышал 100 мкс.

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

andriano пишет:

 Хотелось бы, чтобы единичный акт взаимодействия с датчиком не превышал 100 мкс.

Присоединюсь к вопросу, прозвучавшему выше: что это за система такая, где с датчиками надо работать, как с пулемётной лентой? Мне правда интересно, сам люблю, когда ничего не тормозит, но как бы опрос датчиков - это обычно не самое нужное в плане быстродействия, если только это не VR-разработка какая-нибудь. А даже если и она - в этом случае точно сослался бы на необходимость юзать STM32, т.к. дядьки-родители Oculus Rift на нём неспроста запилили ;)

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Система - музыкальный синтезатор.

Это - не пулемет. Это раз в 50 быстрее пулемета.

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

andriano пишет:

Система - музыкальный синтезатор.

Это - не пулемет. Это раз в 50 быстрее пулемета.

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

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

a5021 пишет:
Хотябы? 8-0 Не все полностью железные I2C устройства поддерживают эту скорость, а вы в софте собираетесь? Сильно завшенные ожидания. Софтовые скорости -- это цифры в районе 50кгц, с понижением в зависимости от загрузки другими задачами.

А5021, вот как железячника и ЛУТильщика, я Вас очень даже уважаю, но вот программист из вас, извините - "хреновый".

Зачем советовать то, в чем вы сами явно не разобрались? Аппаратный I2C у мег вполне СПОСОБЕН работать и как мастер (и даже как мультимастер) и как слейв, вися при этом на одном-единственном прерывании. Обработчик прерывания, в самом объемном случае (одновременная работа во всех возможных режимах) не занимает более 400 байт и вполне вытягивает скорости до 880 кГц тактирования I2C включительно .. чем он вас "не устроил"?

Зачем советовать какие-то "софтовые" реализации, когда шина - стекируемая и может поддерживать туеву кучу устройств на всего 2-х проводах?!?

Я могу понять, что ваш любимый STM32 "так не может" и по-просту затрахаешься запинывать его в тот или иной режим, не говоря уже о совмещенной работе .. но меги-то "легко" решают такую проблему... :)

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

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

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

DIYMan пишет:

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

Время покажет.

Не хватит AVR, попытаюсь STM. Не хватит STM, в запасе еще Raspberry Pi.

Но пока в планах - макет на 328 (один голос) и по отработанной технологии - на 2560  (вероятно, с использованием нескольких 328, для чего, собственно, и ставится вопрос об I2C).

a5021
Offline
Зарегистрирован: 07.07.2013

Arhat109-2 пишет:
Зачем советовать то, в чем вы сами явно не разобрались? Аппаратный I2C у мег вполне СПОСОБЕН работать и как мастер (и даже как мультимастер) и как слейв

Я могу и совсем ни в чем не  разбираться вообще, но данный рецепт я уже отпускал в сообщении №5 этой ветки. Он был отвергнут. В следующий раз, вместо того, чтобы кидаться с пафосными обличениями, потратьте лучше это время на прочтение сообщений, которые были написаны до вашего появления. Это убережет вас от глупых ситуаций, навроде этой.

Цитата:
могу понять, что ваш любимый STM32 "так не может" и по-просту затрахаешься запинывать его в тот или иной режим, не говоря уже о совмещенной работе .. но меги-то "легко" решают такую проблему.

Набор слов, не имеющий никакого отношения к реальности.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Arhat109-2 пишет:

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

Думал написать как-нибудь попозже - когда проект будет ближе к завершению, на раз возник интерес: http://arduino.ru/forum/proekty/analog-analogovogo-sintezatora#comment-2...

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

Прочитал, оч. интересный проект. На самом деле, у дунек есть "спаренный" выход ШИМ от двух таймеров. Вот использовать его под "голос", мне кажется наиболее перспективным. Соответственно, вариант "миниМег" становится перспективным в случае 1 мини = 1 голос (набирай сколько хочу). Но, мелкие камни имеют как правило мало памяти и флеша в т.ч. а большие тут не нужны, по сути достаточно одного этого совмещенного вывода (№13 для АрдуиноМега2560, такие есть у очень многих мег, в т.ч. мелких).

Для управления отцентральной меги такими голосами вполне можно пользовать I2C в режим мастер - кучка слейвов (400-600кгц вам "за глаза"). Но, придется отказаться от реализаций типа wiring в пользу ассемблерных или сильно оптимизированных вариантов. Как понимаю, ваши заикания при передаче по UART как раз связаны с косяками длительного запрета прерываний в типовой реализации классов Strem и т.п.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Arhat109-2, спасибо за теплый отзыв, но, честно говоря, в нем больше непонятного, чем понятного. Я не скажу, что перечитал всю документацию вдоль и поперек, но понемногу в разных местах подчитывал. По большей части, правда, выбирая 328.

Arhat109-2 пишет:

Прочитал, оч. интересный проект. На самом деле, у дунек есть "спаренный" выход ШИМ от двух таймеров. Вот использовать его под "голос", мне кажется наиболее перспективным.

Честно говоря, не знаю, о чем речь. Можно в паре слов, в чем он состоит?

Цитата:
Соответственно, вариант "миниМег" становится перспективным в случае 1 мини = 1 голос (набирай сколько хочу). Но, мелкие камни имеют как правило мало памяти и флеша в т.ч. а большие тут не нужны, по сути достаточно одного этого совмещенного вывода (№13 для АрдуиноМега2560, такие есть у очень многих мег, в т.ч. мелких).

Совмещенный вывод - это который ШИМ от двух таймеров?

Цитата:

Для управления отцентральной меги такими голосами вполне можно пользовать I2C в режим мастер - кучка слейвов (400-600кгц вам "за глаза"). Но, придется отказаться от реализаций типа wiring в пользу ассемблерных или сильно оптимизированных вариантов. Как понимаю, ваши заикания при передаче по UART как раз связаны с косяками длительного запрета прерываний в типовой реализации классов Strem и т.п.

Ну, по поводу I2C я примерно к такому выводу и прихожу - отказаться от всяких управляемых устройств (типа цифровых потенциометров), управляемых по этому протоколу и оставить его только для обмена между Ардуинами.

По поводу прерываний, либо не понял, о чем речь, либо не согласен.

Совсем отказаться от прерываний IMHO нельзя - время как-то считать нужно. Потом, прерывания они мешают только в случае, когда софтверный элемент присутствует неполсредственно при генерации волновой формы. Если генерация происходит чисто аппаратно (таймером), прерывания особенно не мешают.

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

Да, речь шла об этом сдвоенном выводе OCR0A+OCR1C для мега2560. Такой, как понимаю, есть практически у всех "мег", в т.ч и в меньших корпусах. Он позволяет выдавать ШИМ "пачками", длительность которых определяется вторым выходом и, настраивая прерывание по завершению длительности этого второго выхода - тупо управлять пачками импульсов без затрат времени МК: "кончилась пачка" - переставили как ширину ШИМ импульсов, так и размер пачки - 2 записи в 2 регистра.

По поводу работы UART в wiring (заикания вашего синтезатора на приемах) - это и было про прерывания. Если хотите чтобы не заикалось и не глючило - откажитесь от всей этой кухни из "чудо-классов", начиная со stream, print, wire ... та карусель что там реализована не позволит вам избежать "заиканий".

А в целом, конечно отказываться вовсе от прерываний - вредно. :)

a5021
Offline
Зарегистрирован: 07.07.2013

Arhat109-2 пишет:
Да, речь шла об этом сдвоенном выводе OCR0A+OCR1C для мега2560. Такой, как понимаю, есть практически у всех "мег", в т.ч и в меньших корпусах.

Ваше "как понимаю" не соответствует действительности. Понимайет в другой раз более тщательно, плс.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Arhat109-2 пишет:

Да, речь шла об этом сдвоенном выводе OCR0A+OCR1C для мега2560. Такой, как понимаю, есть практически у всех "мег", в т.ч и в меньших корпусах. Он позволяет выдавать ШИМ "пачками", длительность которых определяется вторым выходом и, настраивая прерывание по завершению длительности этого второго выхода - тупо управлять пачками импульсов без затрат времени МК: "кончилась пачка" - переставили как ширину ШИМ импульсов, так и размер пачки - 2 записи в 2 регистра.

При этом наше прерывание по таймеру будет задерживаться другими прерываниями, например, от тамера 0, обновляющего значения миллисекунд. На слух это воспринимается как вполне отчетливая помеха. С подобным эффектом я уже сталкивался, пытаясь сделать второй генератор тона в 328 на таймере 2. Пришлось от этой идеи отказаться. Уверен, что в данном случае будет то же самое. Или есть способ вызвать прерывание вовремя, не смотря даже на то, что в этот момент уже выполняется другое прерывание?

Цитата:

По поводу работы UART в wiring (заикания вашего синтезатора на приемах) - это и было про прерывания. Если хотите чтобы не заикалось и не глючило - откажитесь от всей этой кухни из "чудо-классов", начиная со stream, print, wire ... та карусель что там реализована не позволит вам избежать "заиканий".

А в целом, конечно отказываться вовсе от прерываний - вредно. :)

С заиканием столкнулся, но причина и способ борьбы оказались совершенно другими, подробнее http://arduino.ru/forum/programmirovanie/generatsiya-muzykalnogo-zvuka-n...

 

a5021
Offline
Зарегистрирован: 07.07.2013

andriano пишет:
Или есть способ вызвать прерывание вовремя, не смотря даже на то, что в этот момент уже выполняется другое прерывание?

Способ простой -- разрешить прерывания в обработчике. Способ опасный и нерекомендуемый, т.к. чреват ошибками, отловить которые весьма затруднительно.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

a5021 пишет:

Способ простой -- разрешить прерывания в обработчике. Способ опасный и нерекомендуемый, т.к. чреват ошибками, отловить которые весьма затруднительно.

Ну то есть все библиотеки (включая системные) писать ручками с нуля (т.к. мне нужно, чтобы все прочие прерывания пускали вперед мое).

В общем-то способ мне не очень нравится, т.к. мне нужно, чтобы вперед пускали одно-единственное прерывание, а не все подряд друг дружку.

a5021
Offline
Зарегистрирован: 07.07.2013

В атмеге не предусмотрена произвольная приоритезация прерываний. Народные умельцы реализуют данный механизм в софте. Разумеется, сторонние библиотеки без правки вряд ли получится использовать.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Да Бог с ними - со сторонними библиотеками, Ардуино ведь напихивает в код много всего уже по умолчанию. И, честно говоря, я пока не готов от всего этого отказаться.

А сторонние библиотеки я, как правило, без переделки под себя и не использую.