Второй I2C на RTClib не запускается

Я использую SDA1, SCL1 для своего DS3232 с включенным RTClib. Он работает на Mega2560 на SDA, SCL. Я успешно запустил I2c_test после того, как вставил #определите провод Wire1 Однако с ds3231.ino это определение не работает. Глядя на RTClib.cpp похоже, я могу передать параметр в Wire.begin(). Я пробовал sda1, scl1 и Wire1. Они не сработали. Спасибо за помощь.

, 👍2

Обсуждение

Учитывая, что вы говорите об Ардуино 5 В и 3,3 В с тем, что звучит как один прорыв RTC, было бы неплохо точно знать, как вы это подключаете. Если ds3231.ino является одним из примеров, вы можете показать, какие изменения вы внесли в пример, тогда любой, у кого есть Due и один из этих модулей, может воссоздать вашу ситуацию для тестирования., @timemage

Что произойдет, если вы используете немодифицированный пример ds3231.ino со строкой 333 rtclib.h, измененной на ссылку &Wire1 вместо &Wire? (Ссылка https://github.com/adafruit/RTClib/blob/master/src/RTClib.h). Можете ли вы опубликовать свой скетч и вывод последовательного монитора?, @RowanP

Работает ли неизмененный пример скетча ds3231.ino, если ваш RTC подключен к порту Due Wire (а не к Wire1)?, @RowanP

ds3231.ino из RTClib. Он работает на порту I2C 1 (контакты 20, 21), но не на порту 2 (SDA1, SCL1), он же Wire1. I2C_Test.ino находит ответ на 0x50 и 0x68, что означает, что на ds3231 работает, по крайней мере, учет времени. Добавление #define Wire1 в ds3231 не дает никакого эффекта. Изучение RTCLib.cpp показывает это определение для #ifdef __AVR__ #включить<avr/pgmspace.h> #элиф определен(ESP8266) #включить<pgmspace.h> #elif defined(ARDUINO_ARCH_SAMD) // ничего особенного не требуется #elif defined(ARDUINO_SAM_DUE) #определите ПРОГРАММУ #определите pgm_read_byte(addr) (*(постоянный символ без знака *)(addr)) #определите провод Wire1 #эндиф, @Marlin Turbett

@Marlin Turbett, это хорошо, так что ds3231.ino без изменений работает нормально на выводах 20 и 21 (провод). Можете ли вы попробовать изменить строку 333 rtclib.h на ссылку &Wire1 и повторить попытку на порту Wire1? Я не уверен, что простое определение #в вашем сценарии окажет положительное влияние на поведение библиотеки., @RowanP


1 ответ


1

Неизмененный пример кода RTClib DS3231, работающий на Arduino, по умолчанию связан с проводным соединением I2C на выводах 20 SDA и 21 SCL. Due connection via Wire I2C pins Чтобы тот же скетч мог подключаться к устройству, подключенному к соединению Wire1 I2C на выводах 70 SDA1 и 71 SCL1, я изменил строку 333 RTClib.h на ссылку &Wire1, а не &Wire. Photo of code snippet in RTCLib.h Due connection via Wire1 I2C pins Показан успешный тестовый вывод из соединения Wire1. Serial Monitor Output

Обновление: OP @Марлин Турбетт отметил, что добавление #define Wire1 в RTClib.h также работает. Я согласен. Модификация строки 333 RTClib.h, которую я первоначально предложил, я думаю, является минимальным изменением для получения желаемого поведения. Но использование подстановки для достижения того же изменения также работает. Глобальные изменения во всей библиотеке могут оказаться большим ударом, чем хотелось бы.

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

Метод использования директив #define для перезаписи, на какой проводной порт ссылается RTClib, используется библиотекой выборочно в зависимости от архитектуры arduino (см. RTClib.cpp строки 46-73, ниже).

#include "RTClib.h"
#if defined(__AVR__) && !defined(TWCR) && defined(USICR)
#include <TinyWireM.h>
#define Wire TinyWireM
#else
#include <Wire.h>
#endif

#ifdef __AVR__
#include <avr/pgmspace.h>
#elif defined(ESP8266)
#include <pgmspace.h>
#elif defined(ARDUINO_ARCH_SAMD)
// nothing special needed
#elif defined(ARDUINO_SAM_DUE)
#define PROGMEM
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define Wire Wire1
#endif

#if (ARDUINO >= 100)
#define _I2C_WRITE write ///< Modern I2C write
#define _I2C_READ read   ///< Modern I2C read
#else
#include <WProgram.h>
#define _I2C_WRITE send   ///< Legacy I2C write
#define _I2C_READ receive ///< legacy I2C read
#endif

Я не знаю, почему код библиотеки в строках с 60 по 64 (для ARDUINO_SAM_DUE) оказался неэффективным, и я надеюсь провести еще несколько тестов. Может быть, другие здесь могут пролить немного света?

Обновление 2: Обратите внимание на ссылку @Edgar Bonet в комментариях к новому примеру скетча customWire_DS3231onSAMD21.ino в RTClib 1.14.1, который специально предназначен для нескольких портов i2c. Хорошенькая.

,

Спасибо. Это работает. Строки с 54 по 64 в RTClib.cpp похоже, он заменяет Wire1 на Wire на должном. Однако это не работает для меня., @Marlin Turbett

Отлично! Если вы можете; пожалуйста, поставьте галочку в ответе, чтобы показать, что он отвечает на ваш вопрос., @RowanP

Пока исправление работает, я поместил #define Wire1 в RTClib.h. Это тоже работает. Мое мнение на данный момент заключается в том, что моя настройка Arduino для Due не может оштрафовать определения$, которые уже есть в библиотеке., @Marlin Turbett

Я посмотрю еще раз и посмотрю, смогу ли я повторить ваш результат., @RowanP

На форуме Arduino есть интересная дискуссия о единицах компиляции, которая предполагает, что скетч и библиотека являются разными единицами компиляции и не могут совместно использовать #defines. Они обсуждают альтернативы. https://forum.arduino.cc/t/compiler-not-detecting-external-header-file-with-defines/526633/8, @RowanP

Re “ _ Я не знаю, почему код библиотеки в строках с 60 по 64 (для ARDUINO\_SAM\_DUE) не был эффективен_”: Это " #define` является рудиментарным из предыдущих [библиотека позволяла выбирать пользовательский интерфейс I2C](https://github.com/adafruit/RTClib/pull/231). Это больше не служит никакой цели., @Edgar Bonet

Я только что отправил [запрос на вывод](https://github.com/adafruit/RTClib/pull/242) , чтобы удалить этот запутанный, мертвый код препроцессора., @Edgar Bonet