Ардуинщики всех стран - объединяйтесь! В этом форуме, конечно.
Ответить

Re: Научите мастерству на примере кода

Сб сен 10, 2022 21:20:36

"Здоровый" оффтоп: Ну у меня знакомые, в другой возрастной категории, > 68 лет, с Arduino начинали как в шутку, даже с легкой тревогой и неохотой. Сейчас иногда пишут свои программы или модифицируют чужие программы, для удовольствия, как хобби. И им нравится жизнь. С улыбкой. (частично пользуюсь переводчиком БГ->РУ)
---
A Arduino (по Wikipedia):
Проект Arduino начался в 2005 году как инструмент для студентов Interaction Design Institute Ivrea, Италия, с целью предоставить новичкам и профессионалам недорогой и простой способ создания устройств, которые взаимодействуют с окружающей средой с помощью датчиков и исполнительных механизмов. Типичными примерами таких устройств, предназначенных для начинающих любителей, являются простые роботы, термостаты и детекторы движения.

(ничего не написано для профессионалов :) )
Последний раз редактировалось veso74 Сб сен 10, 2022 21:31:03, всего редактировалось 4 раз(а).

Re: Научите мастерству на примере кода

Сб сен 10, 2022 21:24:12

Ха. Есть два граничных типа программистов - младшие школьники и старшие пенсионеры :))) Как ни странно, их подходы одинаковы. Только у школьников еще все впереди, а пенсионеры, извините, они уже мыслят без прицела на самосовершенствование. Потому что с возрастом, извините, не в обиду, но тяжелее мозгами ворочать, никуда не денешься от природы то.

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

Re: Научите мастерству на примере кода

Сб сен 10, 2022 21:33:59

Ariadna-on-Line, для чего хотите написать код более "красиво", правильно, компактно:
- для себя (например учиться)
- предоставите код где-нибудь
- другие причины?
Устройство работает?

Re: Научите мастерству на примере кода

Сб сен 10, 2022 21:40:46

Рискну порекомендовать статью Виктора Тимофеева http://pic24.ru/doku.php/osa/articles/e ... out_errors , как вводную для понимания, в каком направлении идти.

Re: Научите мастерству на примере кода

Вс сен 11, 2022 11:03:11

Можно я напишу своё imho? Пару лет назад, пытался (но так и не освоил) программирование андроидных устройств и набрёл на продукт, который назывался "processing". Когда я его запустил - о, это ж "Ардуина"! Немного почитал... и оказалось, что нет. Это ардуина - процессинг. Т.е. сначала был процессинг. И этот процессинг позиционировался как средство, чтобы специалисты в других областях создавали аппликацию, не заморачиваясь нюансами программирования андроидов. И позже, появилась ардуина, которая построена аналогично "процессингу" и сохраняя ту же идеалогию. Поэтому, я бы не рекомендовал увлекаться ардуиной, если цель научиться программировать микроконтроллеры. Если хотите создать нечто не вникая глубоко в микроконтроллеры - то это ваш продукт.

Re: Научите мастерству на примере кода

Вс сен 11, 2022 18:33:10

Ariadna-on-Line, для чего хотите написать код более "красиво", правильно, компактно:
- для себя (например учиться)
- предоставите код где-нибудь
- другие причины?
Устройство работает?
Я пользуясь командами, которые можно пересчитать по пальцам одной руки. Это видно по выложенному коду. Но в языках есть более "емкие" (комплексные) команды. Они вероятно дадут более компактный скомпилированный код. То бишь цель посмотреть как можно написать именно более КРАСИВО.

Re: Научите мастерству на примере кода

Вс сен 11, 2022 18:45:42

Для пополнения "словарного запаса" пример не нужен, нужно прочитать две книжки по языку программирования, общую и описание языка к тому компилятору, который используется. Ну или только последнюю.

Re: Научите мастерству на примере кода

Вс сен 11, 2022 19:00:44

... Они вероятно дадут более компактный скомпилированный код

Если устройство работает (и есть место в память), то только со временем подстроится. Иначе в компиляторе работает оптимизатор на последнего уровня / управляемой /, даже бессмысленный код игнорируется соответствующим образом. Пробуйте - повторяйте код, делите на ноль ... Получаете warnings и происходит компиляция. (A иногда это приводит к логическому срыву устройства). С годами сравниваю отклик Arduino и комилатора для PIC. В Arduino мне определенно даже не нужно обращать внимание на детали. Люди предсказали, какими будут пользователи и сделали система для их. А другой комилятор (профи) даже не мог считать x = ((a * b) / d) - 34567 * h; нужно построчно максимум 4-5 операнда :), нет uint64_t (для малых mcu), но есть оптимизировно умножение с точки зрения скорости и используемой памяти и др.

Re: Научите мастерству на примере кода

Вс сен 11, 2022 19:10:24

Люди предсказали, какими будут пользователи
бестолковыми :)
Вот уж не знаю, хорошо это или плохо. С одной стороны, конечно же хорошо, давая возможность более широкому кругу и разного уровня способностей заниматься делом. с другой стороны, как говорили (вроде бы Эдди_эм), это позволяет лезть бестолковым туда, куда не надо.
Но вот деление на ноль я бы делал везде с варнингом :) потому что:
Правда ли, что при делении на ноль происходит взрыв?
(с) изиэлектроникс.ру

Re: Научите мастерству на примере кода

Вс сен 11, 2022 19:30:42

деление на ноль:
Код:
  uint8_t a = 33;
  Serial.println(a / 0);

Пусть будут системы/компиляторы/среды программирования. Даже бесплатно. Чтобы люди делились кодом. Это лучше, чем было 15-20 лет назад - мало комп., платно, никто код никому не дает /как будто все продают код/.
Вложения
div_0.jpg
(160.52 KiB) Скачиваний: 51

Re: Научите мастерству на примере кода

Вс сен 11, 2022 19:58:48

[\Я пользуясь командами, которые можно пересчитать по пальцам одной руки. Это видно по выложенному коду. Но в языках есть более "емкие" (комплексные) команды. Они вероятно дадут более компактный скомпилированный код. То бишь цель посмотреть как можно написать именно более КРАСИВО.

В ЯЗЫКЕ Си или С++ нет КОМАНД. Есть функции, классы, методы и т.п. А то, что вы называете командами - это по сути, и есть алгоритм построения работы с дисплеем. Я уже как бы описал в двух словах замечания по этому алгоритму.
Главная мысль в этом - убрать инициализацию I2C из каждой отправки команды, и если возможно, сгруппировать отдельные посылки команд и параметров в один общий сеанс обмена, в соответствии с написанным в даташите дисплея.

Re: Научите мастерству на примере кода

Вс сен 11, 2022 20:17:59

Serial.begin(9600);
один раз напишите, в setup()
---
можно
if (digitalRead(BT_PIN) == HIGH)
в
if (digitalRead(BT_PIN))
(никакой разницы, просто читабельнее)
---
и
if (digitalRead(BT_PIN) == LOW)
в
if (!digitalRead(BT_PIN))
аналогично, отрицательно
---
Лично я после Паскаля принял фигурные скобки {} только для нескольких операций, для одной - без, но это дело личного выбора.
---
Условно половина Ваших переменных может быть локальной, а не глобальной. Лучше сделать анализ, локальные после выполнения освобождает память для них.
---
В Arduino IDE есть Инструменты -> АвтоФорматирование. На 10-20 строчке нажмите его. Результат форматирования виден издалека.
---
Задержки с delay() - их место не в основном цикле. Кнопка не "залипает" у вас? Лучше действие -> флаг, и в основном цикле проверяете флаг, выполняете действие2, снимаете флаг. И без того события не особо быстрые, задержки (и то - маленькое) - возможно только во внутреннем событии /или драйвере устройства/. По възможност - без delay(). Есть как минимум 10 способов сделать что-то кроме delay(1000);
Последний раз редактировалось veso74 Вс сен 11, 2022 20:44:13, всего редактировалось 5 раз(а).

Re: Научите мастерству на примере кода

Вс сен 11, 2022 20:25:14

зато какое многообразие написание одного и того же может быть!
например, всем известный оператор switch может выглядеть так:
Код:
var a = b switch
            {
                b1=> 1,
                b2 => 10,
                b3 => 100,
                _ => 0,
            };

Это, правда, С#, но всё равно красиво, классическое написание case break; он, разумеется, также поддерживает.
И всё это познаётся только чтением документации. В одном примере всего не показать, увы.

Re: Научите мастерству на примере кода

Вт сен 13, 2022 14:37:14

Вот мой код. Компилируется. Работает в Протеусе. Покажите методы (трюки) написания кода, компилирующегося более компактно, при сохранении функциональности. Хочу усвоить немного виртуозности в программировании. Буду благодарен за работоспособный код. С уважением.
ПС. Платформа - ATtinyCore / Плата ATtiny45/85 (Optiboot).

Пересмотрите мой процесс освоения "враждебного продукта" ардуино IDE в
viewtopic.php?f=62&t=156720
чего-то большего можно добиться только под "чистым СИ" или ассемблером.
У адуринок несколько иная задача.
Посему использование "малых" кристаллов дает эфект только для простейших задач или построения "вспомогательных" контроллеров в более крупном проекте.
:beer:
Пы.Сы.
у адуринки свой симулятор имеется (с имитацией "стандартной обвязки")
https://www.sites.google.com/site/unoardusim/
:wink:
Касательно использования термопары и того дисплея, что в проекте установлен - штука явно для простого термостата слишком избыточная. Там вполне DS18b20 да простенького дисплея достаточно.
Это ж не печка с температурой свыше +150...
Дисплейчик на той же MAX7219/tm1637 или "для куражу" на WH1602 - подобном двустрочнике...
Настройка - минимумом кнопок (или к примеру через штатный терминал той же ардуиноIDE).
Зачем избыточные усложнения на этапе освоения простейших устройств?
:dont_know:

Re: Научите мастерству на примере кода

Вт сен 13, 2022 18:05:36

Нет, почему же именно на ассемблере? Вовсе нет, особенно когда имеете дело с графической подсистемой, ассемблер становится неудобным. А С++ компилятор имеет неплохое "сжатие", образно выражаясь. Но тут в конкретном примере автора дело вовсе не в языке программирования, а дело именно в алгоритме работы с дисплеем. Убрав лишние повторяющиеся действия, можно добиться более быстрой, более "виртуозной" (как выразился автор) работы.

Как я уже ранее писал:
- инициализация I2C модуля в целом (настройка пинов, скорости, свойств модуля) должна выполняться только ОДИН раз, после запуска микроконтроллера.
- все байты команд дисплея можно отправлять за один раз, открыв сеанс связи отправкой I2C-адреса на шине и байта режима D/C дисплея (0x00). Далее идут байты настройки дисплея (команды и параметры), и завершает STOP-бит интерфейса. Причем, из обязательных команд дисплея требуется только настройка нужного режима развертки (мапинга) и некоторых свойств, таких как инверсия пикселей и яркости (контраста), если это требуется. Остальные настройки заданы по умолчанию производителем, и коррекция нужна только при отклонении напряжения питания или условий.
- команды запуска DC/DC (0x8D, 0x14) и включения панели (0xAF) желательно иметь в отдельной функции и отправлять их после настройки дисплея и очистки GRAM дисплея или загрузки в нее первого кадра, чтобы избежать кратковременного появления мусора на дисплее. Иногда требуется выключение дисплея во время работы, поэтому отдельная функция выключения пригодится.
- вывод подготовленной картинки на дисплей представляет собой так же единый пакет байтов, начиная от адреса I2C-адреса на шине, байта режима (0x40) и далее 1024 байта графических данных для полного кадра. Скорость I2C желательно установить на 400 кбит/с, чтобы полная перерисовка кадра была более быстрой (около 25 мс). Желательно чтобы отправка I2C была на прерываниях, а в идеале - DMA, если он есть в МК.
- если предполагается расширенный функционал типа изменения яркости во время работы или прокрутки области кадра, написать функционал для реализации этих возможностей, опираясь на предыдущие принципы.
- картинка для дисплея готовится заранее в графическом буфере размером 1 кБ и не связана с функциями коммуникации с дисплеем. Её основа - попиксельная прорисовка точек в координатах с помощью ф-ции SetDot(x, y, color) (в других вариантах название DrawPixel). Эта ф-ция выполняет преобразование X-Y координат дисплея в требуемый дисплеем постраничный формат байтов. Через эту ф-цию работают все алгоритмы векторного рисования линий и окружностей, а так же формирование символов растрового шрифта. Подготовленный таким образом графический буфер отправляется в дисплей за один раз ф-цией FullFrameUpdate(buf).
Как бы вот...

Re: Научите мастерству на примере кода

Вт сен 13, 2022 20:18:28

Три разных протокола работают по очереди на одной шине. Причем они не возвращают линии к какому-то единственному исходному состоянию. Поэтому приходится каждый цикл линии "настраивать вручную". Здесь не речь о "повышении квалификации". Здесь просьба к "кому не жалко" предложить более красивый вариант кода для конкретной самоделки. Для быстрого изготовления. И добавления функций таймера или часов, если получится укомпактнить код. Сугубо практическая цель. Всем спасибо.

Re: Научите мастерству на примере кода

Вт сен 13, 2022 21:03:49

Ну тогда вы просто неправильно работаете с шиной I2C. В конце обмена, завершаемого stop-битом, шина всегда возвращается к одному и тому же состоянию - высокие уровни на SDA и SCL, получаемые резисторами подтяжки. Это исходное состояние.
Я не пишу для ардуины. А написанный код для STM32 будет вам непонятен. Остальное я уже неоднократно объяснял на словах. Впрочем, извечная проблема всех ардуинщиков - "ниработает как хачю" и "дайте готовое".

Re: Научите мастерству на примере кода

Вт сен 13, 2022 21:42:23

MLX90640 практически всё разжевал и осталось лишь воплотить. Это соответствует "Научите мастерству".

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

Re: Научите мастерству на примере кода

Вт сен 13, 2022 22:38:03

Изменив "внешний вид" программного кода, можем также написать немного идеи о изменения алгоритма (и отображения данных):

1. Проверяете несколько раза датчик температуры: "// Производим вспомогательное чтение чтобы убрать некорректные данные" (комментарий из Вашей программы) -> то предлагаю использовать как минимум метод 2: Running Averagе из Three Methods to Filter Noisy Arduino Measurements. Вместо одного значения будет n, объем используемой памяти сильно не увеличится. Но "скачков" показания при чтении (почти) не будет. Напр. достаточно 4 событий, медленно по времени (3-5 сек) (изменение температуры является медленным явлением).

2. Меняйте задачи на отчет времени с помощью таймера. И встроенные millis(), micros() сделают работу. Так контроллер будет готов и к другим действиям, не делая "бессмысленных" delay(). Когда происходит событие, напр. поднять флаг. В loop() проверяете флаг, делаете второй и т. д. действия и снимаете флаг.

3. Посмотрите еще раз на переменные. У Вас есть неизменяемые. Измените их либо на константы, либо на #define. Память будет освобождена (оптимизатор, я уверен, исправил это, но видно в коде).

4. Проверите тип переменных. Вы используете типы, которые бессмысленно "длинны" в битах по отношению к данным, которые они будут представлять. Память будет освобождена.

5. Вижу как минимум два "стиля" кодирования. Откуда-то взяли строки? Можете унифицировать код.

Пример: можно byte Rep (до 255).
Код:
int Rep = 0;
if (Rep >= 10) {                     // Если нажата дольше 10 секунд -
    Rep = 10;

Это неправильно :) :
Код:
int State = LOW;

или
Код:
boolean State = LOW;

или byte/int:
Код:
byte State = 0;

Re: Научите мастерству на примере кода

Ср сен 14, 2022 20:32:11

Самое оптимальное улучшение - работа на основе собственноручно написаных библиотек согласно конкретной документации на элементную базу конкретной схемы.
"Чужие" решения всегда будут избыточны и часто не слишком удобны ( не такая разводка или иные "неудобства" ).
Естественно придется смириться с соответствующими потерями времени на изучение документации и написание своих программ.
Выбор всегда за пользователем ( в большинстве случаев компромис между "полной самоделкой" и использованием "сторонних разработок").
8)
Ответить