Подключение по I2C почему зависает?
- Войдите на сайт для отправки комментариев
Втр, 26/10/2021 - 20:46
Подключил к Arduino NANO BMP280, RTS_DS3231 и Oled SD1306.
Проверил, всё по отдельности - работает. Скомпоновал код на все 3 модуля, Ардуино виснет на процедуре Setup при инициализации 3 модуля.
Пробовал различные комбинации кода для работы по парно, т.е. часы с экраном, экран с BMP, BMP с часами. Попарно тоже все работает, а все вместе зависает на инициализации любого 3-го модуля.
Толи питания не хватает, толи нужно ставить какие-то подтягивающие резисторы?
Это мои первые шаги в освоении ардуино, так что не судите строго.
Схема подключения:
Вот код:
//----------------------------BMP280 #include <Wire.h> #include <SPI.h> #include <Adafruit_BMP280.h> Adafruit_BMP280 bmp; // I2C //--------------------------------------RTC_DS3231 #include <iarduino_RTC.h> iarduino_RTC time(RTC_DS3231); //#define OledOn #ifdef OledOn // библиотеки для работы с OLED экраном Arduino IDE //#include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> Adafruit_SSD1306 display(128, 64, &Wire, 4); // указываем размер экрана в пикселях #endif void setup() { Serial.begin(9600); Serial.println("Begin"); //-------------------------------------------------------------------------------BMP280 Setup Serial.println(F("BMP280 test")); if (!bmp.begin(BMP280_ADDRESS_ALT, BMP280_CHIPID)) { //if (!bmp.begin(0x76)) { Serial.println("Could not find a valid BMP280 sensor, check wiring or " "try a different address!"); //while (1) delay(10); } bmp.setSampling(Adafruit_BMP280::MODE_NORMAL, Adafruit_BMP280::SAMPLING_X2, Adafruit_BMP280::SAMPLING_X16, Adafruit_BMP280::FILTER_X16, Adafruit_BMP280::STANDBY_MS_500); //-------------------------------------------------------------------------------RTC_DS3231_Setup delay(300); time.begin(); time.settime(0, 30, 18, 12, 6, 20, 5); // 0 сек, 30 мин, 18 часов, 12, июня, 2020, четверг time.period(1); Serial.println(F("TimeOK")); //-------------------------------------------------------------------------------------------RTC_DS3231_Setup_END //-------------------------------------------------------------------------------OLED SSD1306 Setup #ifdef OledOn display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // указываем адрес устройства на шине Serial.println(F("errorDis")); display.clearDisplay(); display.setTextSize(1, 2); // указываем размер шрифта display.setCursor(30, 10); display.println("ARDUINO"); display.display(); delay(3000); display.clearDisplay(); // очищаем экран display.setTextSize(1); // указываем размер шрифта #endif //-------------------------------------------------------------------------------OLED SSD1306 SetupEND } void loop() { if (millis() % 1000 == 0) { float t = bmp.readTemperature(); float p = bmp.readPressure(); String timeT = time.gettime("d-m-Y, H:i:s"); p = p * 0.00750062; // Преобразуем Паскали в мм.рт.ст. #ifdef OledOn display.clearDisplay(); display.setCursor(0, 20); display.println(timeT); //-------------------------------Температура display.setCursor(0, 30); if (t > 0) display.print("+"); display.print(t, 1); display.print("oC "); //--------------------------------Давление display.print(p, 0); display.println("mmGh"); display.display(); #endif Serial.println(timeT); if (t > 0) Serial.print("+"); Serial.print(t, 1); Serial.print("oC "); Serial.print(p, 0); Serial.println("mmGh"); } }
в каких то девайсах мне приходилось инициализацию дисплея вынести вперед
в каких то девайсах мне приходилось инициализацию дисплея вынести вперед
Неа, не помогает. Кстати, зависает именно на модуле экрана.
Памяти нехватат
Резисторы подтяжки проверь.
Я не ставил ни одного резистора. Все как на схеме. Я и обратился сюда, чтоб подсказали, куда их ставить?
Какие номиналом и самое главное понять почему?
Памяти нехватат
Да вроде хватает. Компилятор выдает:
Кстати, отсюда, попутно, еще один вопрос - это, что так мало памяти?! я еще планировал в этот проект подключить УЗ датчик, модуль SD карты и GSM модуль, а уже 90% памяти занято
Это называется проектированием. Рисуем схему с модулями. Пишем сколько кому надо тока, памяти и прочих ресурсов. Суммируем. Выбираем МК, который справится с задачей. С Вашей задачей нана не справится. Нужен контроллер мощнее. Или урезать хотелки. Например взять экран не так сильно жрущий память.
Это называется проектированием. Рисуем схему с модулями. Пишем сколько кому надо тока, памяти и прочих ресурсов. Суммируем. Выбираем МК, который справится с задачей.
Блин, ну понятно, что проектировать надо. Это первые шаги.
По току то можно прикинуть:
BMP280 - 2,7мкА, RTS_DS3231 -250мкА, Oled SSD1306 - 16мА. Арпдуино нано выдает 40мА, должно хватать. По ходу прикрутки остальных модулей, проблему можно решить с внешним питанием.
А вот как быть с расчетом памяти заранее, не понимаю? Просветите.
Да я понимаю, но принять не могу. Ну, не мегу же ставить! Или придется 2-3 нано использовать?
Может я ошибаюсь, но в сравнении с BMP280 и часиками, экран памяти хавает, не так уж и сильно. Без него 58% памяти, т.е. 32% а 58% другие два датчика! Я в шоке конечно пребываю, и все это можно сказать только примеры использование. А когда начнешь еще и свой код ваять, там вообще ничего не остается. Вроде всякие проекты в интернете видел, как они все это умещают в памяти?
Используют только то что необходимо программе, а не сыпят всё в подряд что есть в библиотеках. Компилятор конечно помогает что то лишнее выкинуть но много и остается. Это тоже к проектированию относится - составить необходимый минимум подпрограмм. Проще конечно взять библиотеку и не думая впихнуть. Оно заработает. Однако на форуме много тем типа считываем данные без библиотеки и т.п. Есть тема про 13 тиньку там памяти мало и нужно как то впихивать программы. Страниц в теме много, но если бегло почитать, то можно найти много советов как уменьшить размер программы.
P.S. Компилировал - Скетч использует 17254 байт (56%) памяти устройства. Всего доступно 30720 байт.
Используют только то что необходимо программе, а не сыпят всё в подряд что есть в библиотеках. Компилятор конечно помогает что то лишнее выкинуть но много и остается. Это тоже к проектированию относится - составить необходимый минимум подпрограмм. Проще конечно взять библиотеку и не думая впихнуть. Оно заработает. Однако на форуме много тем типа считываем данные без библиотеки и т.п. Есть тема про 13 тиньку там памяти мало и нужно как то впихивать программы. Страниц в теме много, но если бегло почитать, то можно найти много советов как уменьшить размер программы.
Благодарю за ссылку, да, есть, что там по изучать.
Все таки хотелось вернуться к главному вопросу, почему не работает 3 модуля вместе и как это исправить?
Чем спорить, можете принять или не можете, лучше поставьте резисторы как Вам сказали (два штуки по 4,7к от пинов A4 и A5 ардуины на питание)
и вставьте после строки №24
delay(500);
Отпишитесь, что получилось с обязательным выкладыванием актуальной схемы и актуального скетча.
float, Serial, шрифты для OLED - основные загрязнители. От первого не избавитесь в ближайшем будущем, от второго - легко, для экрана взять u2glib - такие рекомендации можно дать.
Я не ставил ни одного резистора. Все как на схеме.
На схеме они уже есть. Причем, по два экземпляра каждого, потому что они имеются в каждом из модулей (в этом и есть опасность сборки схему из готовых модулей, а не из деталей россыпью). Вам нужно проверить, что при параллельном включении итоговое сопротивление не окажется меньше 2 кОм.
А вот как быть с расчетом памяти заранее, не понимаю? Просветите.
Что значит "заранее"?
Переменная типа char занимает 1 байт, типа int - два байта, типа long или flot - 4 байта. Если массив на 100 элементов - в 100 раз больше. А дальше - просто сложение. Арифметику в школе изучали?
почему не работает 3 модуля вместе и как это исправить?
На это может быть 1001 причина.
Как исправить - зависит от причины.
Другими словами, прежде, чем пытаться лечить, следует поставить диагноз.
Диагностику следует начинать с поверки, что разные библиотеки на "дерутся" за одни и те же ресурсы. В качестве ресурсов следует рассматривать оперативную и постоянную память, пины контроллера, таймеры и прерывания. Ну и еще - время: в программе, которая работает с несколькими разными устройствами, как правило, не должно быть задержек типа delay().
Чем спорить, можете принять или не можете, лучше поставьте резисторы как Вам сказали (два штуки по 4,7к от пинов A4 и A5 ардуины на питание)
и вставьте после строки №24
delay(500);
Отпишитесь, что получилось с обязательным выкладыванием актуальной схемы и актуального скетча.
Отписываюсь. Кошмар какой то. Ардуино - это какой то бред недоделанный. Я думал все гораздо проще будет. Подключил модуль, подключил библиотеку и работай. А тут такое мракобесие. Как уже только не переделывал и схему и код, но толи лыжи не едут, толи китайцы враги русского народа.
Подключил в эту схему подтягивающие резисторы, как и советовал на 4,7кОм
, добавил делей на 24 строчке кода. Запустил, не работает.
Ну ладно, думаю. начнем все сначала, как будет работать все по отдельности с этими резюками. Начал с датчика температуры. Оп, не работает. Колдовал и так и сяк, убрал резюки. Не работает. Пересобрал всю схему. Подключил только BMP. Танцы с бубном, все заработал. Подтянул SDA и SDL резисторами. Работает, изменений нет. Добавляю модуль Oled. Работает.
Добавляю часы. Програмно отключаю дисплей. Все работает.
Отключаю БМП, подключаю дисплей и часы. Работает, но перестал работать *.print ни в сом порт, ни в экран, причем как то выборочно, как это возможно.
Хрен с этими датчиками, там да ну может конфликтовать библиотеки, какие ни будь помехи, но когда один код глючит, я всю голову сломал. Почему один Serial.print("get_time"); работает, а следом за ним Serial.print(timeT); не работает
Подключил в эту схему ... добавил делей на 24
Вы принципиально или беспринципно проигнорировали мои слова:
с обязательным выкладыванием актуальной схемы и актуального скетча.
Макетка, похоже, с разрывом шин питания.
Или это так и задумано?
Если да, то я бы не стал трехвольтовый BMP подключать к 5-вольтовому контроллеру.
Вы принципиально или беспринципно проигнорировали мои слова:
Да, нет братан, не специально. Просто уже голову сломал и мозг зациклил уже. Схему же надо отдельно рисовать.
Вот последняя схема подключения (а их уже всяких вариаций было):
Я уже всяко перепробовал. В 3 модуля, виснет на методе display.println() 41 строка. Ну как виснет, доходит до 41 строки и заново запускается setup(), Вычислил принтами на компорт.
В два модуля работает, в различных комбинациях, не меняя схемы и не отключая физически модули, а только програмно, через директивы, но только вылез косяк - отказ печатать в порт -
Serial
.print(timeT)
104 и 126 строка.Да работает он и так и так. В даташите китайцы указывают питание от 1,8 до 5в.
Подключал и к 3,3 и к 5в разницы не заметил. Последняя версия подключена на 3,3в.
https://www.bosch-sensortec.com/products/environmental-sensors/pressure-...
Supply voltage VDDIO. 1.2 ... 3.6 V. <<<<<<<
Supply voltage VDD 1.71 ... 3.6 V
Может на одном из девайсов адрес поменять
Ну если такой затык, то сообщаю. Часики отлично работают на софтовом I2C Влада. Вешаете часики на две любые свободные ноги, кроме D0 D1, запускаете софт I2C и обращаетесь к часам через него.
Еще хотелось бы видеть диагностику после компиляции. Ибо то, что размещено в сообщении №6, не вызывает доверия: для дисплея, насколько я понимаю, используется экранный буфер, а потому общий расход памяти никак не может составлять 924 байта.
На схеме они уже есть. Причем, по два экземпляра каждого, потому что они имеются в каждом из модулей (в этом и есть опасность сборки схему из готовых модулей, а не из деталей россыпью). Вам нужно проверить, что при параллельном включении итоговое сопротивление не окажется меньше 2 кОм.
Правильно ли я понимаю, что в модулях уже есть свои резисторы и отдельно подтягивать не надо?
Так как попарно модули работают в любой конфигурации, склоняюсь к вашему мнению про итоговое сопротивление. Скажи как его измерить? В смысле на каких контактах мерить?
Правильно ли я понимаю, что в модулях уже есть свои резисторы
А почему Вы меня об этом спрашиваете?
У кого модули перед глазами, у меня или у Вас?
... итоговое сопротивление. Скажи как его измерить? В смысле на каких контактах мерить?
Проще всего - прочитать маркировку.
Но если хочется именно измерить, то на соответствующих резисторах. Впрочем, можно и на контактах разъема, с которыми они соединены накоротко.
Еще хотелось бы видеть диагностику после компиляции. Ибо то, что размещено в сообщении №6, не вызывает доверия: для дисплея, насколько я понимаю, используется экранный буфер, а потому общий расход памяти никак не может составлять 924 байта.
У меня после компиляции выдается только это. Как включить диагностику?
Замерил сопротивление SDA - Vcc - 6,13кОм, SCL-Vcc - 6,10кОм. SDA-SCL - 4.79кОм.
Схема подключения как в первом посте, без подтягивающих резисторов.
Что это значит и куда дальше копать?
Software Wire
Ну если такой затык, то сообщаю. Часики отлично работают на софтовом I2C Влада. Вешаете часики на две любые свободные ноги, кроме D0 D1, запускаете софт I2C и обращаетесь к часам через него.
Посмотрел, тот код который в том сообщении, для меня труден в понимании. Я пока еще не такой продвинутый в этом деле. В любом случае, спасибо за ссылку, возможно в будущем разберусь.
https://www.arduino.cc/reference/en/libraries/softwire/
Еще хотелось бы видеть диагностику после компиляции. Ибо то, что размещено в сообщении №6, не вызывает доверия: для дисплея, насколько я понимаю, используется экранный буфер, а потому общий расход памяти никак не может составлять 924 байта.
Включил в настройках полный вывод компилятора, вот, что выдал, для меня это пока без понимания. Если, что сможешь прокоментировать, буду примного благодарен
Вот, что выдал компилятор:
Код, последний вариант:
Вот мне интересно, по ссылке сказано, что при подключении нескольких устройств по шине I2C одно должно быть master, а остальные slave. Как это реализуется на практике. Я это как то должен указать в коде, но как?
Вот мне интересно, по ссылке сказано, что при подключении нескольких устройств по шине I2C одно должно быть master, а остальные slave. Как это реализуется на практике. Я это как то должен указать в коде, но как?