Pull to refresh

Comments 27

UFO just landed and posted this here
Ваша претензия несправедлива: в Arduino UNO есть светодиод TX, который будет подмигивать при передаче по Serial.
Целью статьи я ставил показать возможность использовать микроконтроллер не только для управления электронными компонентами.

Ну, цели вы не достигли. Применение ардуино тут вообще ничего не даёт. С тем же успехом вы могли просто положить его рядом на столе.

Эх, был бы шарп и мк в мои 17 лет, какую бы фигню только несотворил.

МК Intel 8051 появился аккурат в год вашего рождения. Что касается Шарпа — то на нем единственном свет клином не сошелся.
Не было. И с баяном тоже.
Думал, будут использованы прерывания ардуино (https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/), а не while(true) {delay(x)}
UFO just landed and posted this here
Рядом не лежало.

Событие обрабатывается «когда руки дойдут» (если у вас не RTOS, конечно, но там тоже не так все просто)

Прерывание обрабатывается как только оно возникает. Писать обработчик прерываний тоже некоторый опыт нужен — из нынешнего поколения фреймворков у кого он есть? Кто знает как работать с прерыванием RTC? Ась?

В общем и целом, кабы я был экзаменатором, а вы студентом — послал бы вас учить WinAPI с написанием учебнойпрограммы на голом API без никаких библиотек и фреймворков. Просто для понимания как оно работает внутри.
UFO just landed and posted this here
Давно не работал с AVR, но насколько помню у них при входе в обработчик прерывания происходит маскирования остальных прерываний. Если в начале void lol() не выполнить SEI, то из за запрета прерываний от таймера delay() будет висеть бесконечно.
Вот это — private static bool sost = true; — надо исправить: добавить volatile. Вот так: private static volatile bool sost = true;
Иначе у оптимизатора, если он вдруг захочет соптимизировать ваш код, появится искушение вынести sost как инвариант вот из этого цикла:
while (sost) Thread.Sleep(1);//Приостановить поток
И тогда ваша программа по Esc не закончится.
Стоит отметить, что в WindowsForms присутствует элемент Timer который включается и выполняет код через определенный промежуток времени.


Поколение фреймворков…

Таймер — это элемент WinAPI. Он всего лишь посылает сообщение WM_TIMER в очередь сообщений приложения через заданные промежутки времени. А выполнение кода обеспечивается диспетчером сообщений приложения в том случае, когда на это сообщение назначен соответствующий обработчик.

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

Так работает Windows и это надо понимать. Если у вас есть длинные циклы, то лучше бы внутри них периодически вызывать диспетчер сообщений (что-то типа метода ProcessMessages() или аналогичного)

Равно как и в коде потока периодически вызывать функцию, отдающую таймслайсы системе (Sleep, WaitObject и т.п.)

А настоящие аппаратные прерывания в Windows пользователю недоступны (разве что на уровне драйверов, но это отдельная тема).

Так что тут уже правильно сказали — ваша программа будет генерировать события, не более. А уж когда это событие будет обработано…
Код с обеих сторон настолько отвратительный, что я просто пройду мимо, дабы не портить себе настроение его чтением…
От комментариев по содержанию откажусь, но интересная мысль. Мне вот вспомнилась задача по синхронизации и обновлении данных на двух железках, одна из которых комп на win. Там был RealTime процесс который требовал обновления данных чаще чем 10ms. Так вот внешняя железка весьма бы помогла для выдачи тактов.
Суть той проблематики в несколько другой плоскости была. Задержки менее 30-15 мс реализуемые на WinApi на самом деле таковыми не являются, ОС накладывает ограничения на квант времени и если надо что-то делать быстрее чем этот квант, то это те еще танцы с бубном.
Никаких там танцев с бубном нет. Достаточно использовать Multimedia Timer. Он работает с точностью 1ms (обычный таймер — порядка 16ms). Все это неплохо документировано.

Проверено личным опытом.
Вы о чём? Тут негарантированная задержка генерации, потом миллисекунда на передачу каждого байта с рейтом 9600, потом буфер операционной системы, событие операционной системы, потом переключение процессов, и только потом обработка. На каждом шаге в операционной системе вносятся ещё и случайные ошибки.
Я про возможность использовать внешний микроконтроллер, для выдачи дискретных сигналов (тактов) на разнородные устройства. И по этим тактам синхронизировать две управляющие системы между собой.
У меня задача была скорее в отсутствии бюджета и необходимости распределять вычислительные ресурсы между тем что есть. По факту управляющему устройству необходимо было в достаточно быстром процессе считать вес падающего столба исходя из типа продукта и скорости его подачи с поправкой на накопленную ошибку и т.д и т.п. там много нюансов было. и запись сторонней метки времени по счетному дискретному входу весьма помогло бы.
Это хорошо сработает под какой-нибудь RTOS, но не под Windows. Там приход байта в порт сгенерирует событие, не более того. А дальше уже все будет зависеть от того, когда вы проверите наличие события и обратит на него внимание.

Я бы сделал Multimedia Timer, который вызывает callback функцию через заданный промежуток времени и из этой функции уже рассылал бы другим устройствам синхрометку.

А вообще, из моего опыта, пытаться поднять реалтайм на Win задача неблагодарная. Не та это система
Вообще говоря есть ещё такая штука: en.wikipedia.org/wiki/RTX_(operating_system)
Но это явно не предмет этой дискуссии.
Sign up to leave a comment.

Articles