И снова проект на Arduino: подсветка лестницы

Сей проект должен решить задачу подсветки лестницы в темноте при обнаружении движения одним из двух датчиков. Ну бонусом — кнопка принудительного включения и кнопка «новогодних эффектов». Подсветка осуществляется при адресной 5 вольтовой светодиодной ленты, с внешним питанием.

Разработку платы вёл традиционно в веб версии EasyEDA, Принципиальная схема получилась следующая:

А вот тут она-же, но уже в виде текстолитовой однослойной платы, которую вполне можно потравить и самому:

В «железе» пока еще готового варианта нет, детальки едут и Китая и прочих источников, но теоретическую модель в эмуляторе уже можно потрогать тут:

https://wokwi.com/projects/417413301092687873

Код следующий:

Реле времени своими руками 2

Ранее уже делал подобную схему, но вышло слишком дорого и сложно. Поэтому реле времени своими руками буду упрощать и удешевлять 😉 Во первых уберем индикатор, соответственно сдвиговый регистр будет не нужен. Из индикации добавим светодиод, который будет показывать включено или выключено реле. Так-же подумав, решил добавить кнопку ручного включения/выключения реле. Сердцем будет микросхема attiny85. Так-же в схему добавил и блок питания (HLK-PM01), чтоб вся конструкция была единой платой

Принципиальная схема (потыкать в эмуляторе можно тут):

Реле времени своими руками

Схема на текстолите:

Реле времени своими руками
Реле времени своими руками

Ну и скетч:

Вот так готовлю почву чем заниматься долгими зимними вечерами.. Итоговая стоимость предварительно, вышла примерно такая:

  • блок питания — 160р
  • attiny85 — 80р
  • текстолит — 150р
  • светодиод — 7р
  • реле — 150р

Итого — примерно 600р. Ну собственно это цена реле времени своими руками уже готового если покупать на валдберис. Но тут то своими руками 😉

Реле времени своими руками

Долго ли, коротко ли, но вот взяло и перестало работать реле времени на моём септике на даче. Его задачей было — раз в час, включать на 15 минут циркуляционный дренажный насос. А так как покупать новое реле «это не наш метод», было принято решение разработать реле времени своими руками. Максимально дешевое, максимально компактное. Итак, именно поэтому будем использовать микросхему attiny85:

реле времени своими руками

Купить её можно дешевле 100 руб. Так-же из хотелок, подумал , что не плохо бы видеть сколько осталось времени до включения реле и выключения реле. Следовательно будем использовать семи сегментый индикатор.

Включением-выключением насоса будет заниматься реле:

Чуть посчитав количество требуемых ног у микросхемы, взгруснул — для индикатора требуется 7 ног, плюс на реле одна. А у микросхемы всего 6 выходов. Значит придётся использовать сдвиговый регистр. Задача уже не получается совсем простой, но тем не менее остаётся вполне решаемой.

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

Итак, вырисовался в конце концов следующий алгоритм работы всего этого набора электронники: на индикаторе последовательно сменяются цифры от 9 до 0. Цифры сменяются с интервалом в 6 минут. При достижении 1, включается реле, которое выключается при достижении 0. И так по циклу. Т.е. реле (ну и насос) работает 12 минут из часа.

Общая схема подключения получилась такой:

реле времени своими руками

А скетч такой:

На эмуляторе работу скетча можно посмотреть здесь

Особенности работы Arduino nano с памятью

Свободная память

В качестве хобби, разрабатываю бортовой компьютер для своего автомобиля УАЗ патриот. Ну как компьютер..громко звучит. Функций не много, но те которых не хватает в повседневном использовании.. Но сейчас не об этом, о БП выпущу потом отдельную статью.

А сейчас поговорим о самой прошивке. Использую в разработке дисплей на базе чипсета SSD1306. Сначала заметил, что в то время как разрастается код программы, на экране случайным образом начинают появляться различные артефакты, в виде «белого шума». Дальше — больше, заполняю массив в одном месте программы, и через какое то время он начинает затираться случайными данными. Одно время даже уже даже почти отчаялся, И уж никак не приходило в голову, что всё это следствие простой не хватки оперативной памяти Arduino.

Хотя по идее, это первое что должно было придти в голову. Но! во всем виноват Яндекс ;). Он подсовывал ссылки в которых рассказывалось о подобных проблемах, но ни в одной из них не было рекомендации подумать в сторону памяти. Всякий бред типа «подпаяйте резистор, нет контакта, плохая плата, не правильно передаёте массив, не так работаете со строками» и .д. и т.п. Однако, решил на всякий случай измерить остаток оперативной памяти в процессе выполнения программы. Код для измерения следующий:

Запустил… и оказалось что проблемы с экраном начинаются, когда свободно памяти становится меньше 168 байт. Проблемы с очисткой и замусоривание переменных — когда остается меньше 140 байт. А сейчас самое время вспомнить, что в arduino nano всего 2кб оперативной памяти и 32кб flash (ну на самом деле на разных чипах по разному, но конкретно на используемой мной — Atmega 327p именно столько). И этого мало! Любое объявление переменной тратит память. Выход? Arduino способен хранить данные и во Flash. Но храниться они будут несколько своеобразно: фактически в оперативной памяти будет храниться ссылка на ячейку памяти Flash где хранятся данные. Показать переменной что она будет храниться во Flash памяти призван модификатор PROGMEM. Например, для того чтобы объявить что данные для отображения графики будут храниться во Flash памяти можно так:

И в принципе всё. Данные, будут помещены во Flash память. PROGMEM может работать со всеми целочисленными типами (8, 16, 32, 64 бита), float и char.
Важное замечание — PROGMEM применяется только к глобальным переменным, которые расположены ВНЕ функций.

Чтение переменных

Если с записью всё просто, то с чтением всё гораздо интереснее: оно осуществляется при помощи специальных функций:

  • pgm_read_byte(data) – для 1-го байта (char, byte, int8_t, uint8_t)
  • pgm_read_word(data) – для 2-х байт (int, word, unsigned int, int16_t, int16_t)
  • pgm_read_dword(data) – для 4-х байт (long, unsigned long, int32_t, int32_t)
  • pgm_read_float(data) – для чисел с плавающей точкой

,где data это адрес (или указатель) блока данных

Вот как например можно прочитать массив из флэш памяти:

Кроме того, есть встроенная функция — помогалка F(), которая при использовании компилируется в строку — константу во флеш памяти, и подставляется в нужном месте сама. Например код вида:

Serial.println(F(«Я занимаю одинаковое количество оперативной памяти вне зависимости от своей длины»));

Будет соответственно занимать 2 байта при любой длине строки.

Собственно перелопатив весь код, с учётом выше озвученного, удалось избавиться от артефактов на дисплее и не адекватного поведения переменных

Решено: Нужна помощь зала. Не объяснимая ошибка

Прошу очень помощи зала. Ситуация следующая: пишу прошивку «Бортовой компьютер» автомобиля
на основе Arduino Nano (хобби у меня такое, не работа).
Минимальный пример, для воспроизведения ошибки (удалил по максимуму всё, лишь бы ошибка воспроизводилась):

https://wokwi.com/projects/390348182761575425

Проблема в следующем, не обьяснимым образом, теряются данные в переменных при вызове функции translate.

Например при использовании вот так (строки 141-146):

На экран выводится «Bridge». Однако стоит убрать строчку

Как волшебным образом, на экран начинает выводится и Transmission: и Bridge:.

Дело не только в этой строчке. Закомментировав рандомно часть кода выше-ниже, вообще не относящегося к выводу на экран, можно добиться эффекта, что выводятся на экран все три строчки.

Подумал что памяти не хватает. Но вроде норм. Я уже начинаю сходить с ума, несколько дней бьюсь над проблемой. Проблема воспроизводится и на «реальном железе», не только в эмуляторе.

Update: си не умеет возвращать строки. Только массивы символов. Поэтому верный код что-то вроде:

1 2 3 4