Ты чего ожидал-то? Готового кода?
хотя бы объяснения более понятного.
Спроси у ChatGPT и отстань уже от людей
ок, понял
Форум не является обучающей площадкой. Или тебе тут курс лекций написать по программированию?
Злые вы все!
Но спасение идет со Св. Земли!!! Покайтесь, грешники! (можно не публично )
ТС! Изучай значение словосочетания: “неблокирующий код”.
Смысл его в том, что при выполнении кода блокирущий вызов delay()
не используется. Вместо этого код переписывается исходя из модели “бесконечного цикла” в котором мы проверяем те или иные события.
ПРИМЕР;
Варим бейца рака (в смятку) (блокирующий):
включитьПлиту(конфорка);
налитьВоду (ковшик);
поставитьНагревать(ковшик, конфорка);
ПОКА (НЕ кипит (ковшик) НИЧЕГО_НЕ+ДЕЛАТЬ;
положить(ковшик, яйцо);
нАчало = текущееВремя();
ПОКА (текущееВремя() - нАчало < ВРЕМЯ ВАРКИ_ВСМЯТКУ) НИЧЕГО_НЕ_ДЕЛАТЬ;
достать(ковшик.яйцо);
всякие моменты про окатить холодной водой и варить в соленой воде - всё это чтобы чистилось легко - опустим.
Где блокировки: в двух местах - ожидание кипения и сама варка. Первая неизвестное время, вторая известное.
Код называется БЛОКИРУЮЩИМ, если при его выполнении есть такие явления.
Перепишем как НЕБЛОКИРУЩИЙ:
//описание состояний
флаг водаЗакипела = ложь;
флаг яйцоCвfрилось = ложь;
включитьПлиту(конфорка);
налитьВоду (ковшик);
поставитьНагревать(ковшик, конфорка);
//бесконечный цикл
ПОКА (2*2 == 4)
{
ЕСЛИ (кипит (ковшик)
{
водаЗакипела = истина;
положить(ковшик, яйцо);
нАчало = текущееВремя();
}
ЕСЛИ (водаЗакипела)
{
ЕСЛИ (текущееВремя() - нАчало > ВРЕМЯ ВАРКИ_ВСМЯТКУ И (НЕ яйцоСварилось))
{
достать(ковшик.яйцо);
яйцоСварилось = Истина:
}
}
}
Смотри, как это работает:
Перед бесконечным циклом мы сделали все подготовления.
В бесконечном цикле мы проверяем на закипание и продолжаем ТОЛЬКО после закипания. Если не кипит, то мы просто продолжаем цикл сначала. Нам НИЧЕГО не мешает в начале цикла сделать еще любые НЕ БЛОКИРУЮЩИЕ действия из других задач.
Далее короткое действие положить яйцо в воду и снова неблокирующее ожидание.
Пока ждем 2-3 минуты, чтобы яйцо сварилось мы снова-и-снова-и-снова будем начинать бесконечный цикл с начала и можем там выполнять ЛЮБЫЕ задачи. Потом окажемся в цикле, проверим флаг “водаЗакипела” попадем второй блок и станем проверять флаг “яйцоСварилось” и время варки. Когда сварится поднимем флаг, который позволит нам переходить к следующему блоку.
Эти называется “Машина состояний” и обычно программируют не отдельными флагами, а заводят переменную в которой хранится текущее состояние и проверяют ее при входе в бесконечный цикл. В зависимости от состояния делают нужные действия.
Понятно, что в бесконечном цикле можно вызвать хоть две, хоть три таких машины?
Каждая из них выполняется 1-2 миллисекунды или даже меньше. Это самое важное. Внутри машины не может быть блокирующих вызовов.
лисапеда нету, то и злые…
у меня лисапед есть если что
если допустим кто-то тупой то это блокирующий код полюбому.
И наоборот.
А позавчера Вы были погружены во что?
Имело ли это что то общее с программированием хоть на чем?
на кону вопрос, а нужен ли неблокирующий код, зачем? чтобы висеть не в delay(), а в loop() где она - разумная достаточность
Я так и не нашел, написал ли он хоть чтонить сам?
у меня было так что всё срочное делалось в прерываниях (в основном в таймерном), опрос клавиш то-сё неспешное по входам, а несрочное в фоновой программе: типа там УАРТ и тп, причем с дилеями! ибо они никого не парили тут.
я c++ не проходил, а проходил python
Мимо? ))
что мимо?
Шел бы ты, Кирилка, книжки читать. А то так в темноте всю жизнь и проживешь…
На однозалачных системах такое реализуется “тиками”: у тебя есть главный цикл, в котором вызываются функции, по чуть-чуть
while(!Exit) {
if (!button1_pressed) {
led_stripe_tick();
audio_tick();
}
...
}
Функции led_stripe_tick() и audio_tick() отвечают за светодиоды и звук, но они отработав, быстро возвращают управление.
Например, так сделана “многозадачность” в Quake1 (в однозадачной DOS)
FreeRTOS поможет). Мигание светодиодом с помощью FreeRTOS и Arduino: схема и программа
Спойлер
#define BUZZER_PIN 12 // Пин для пищалки
#define BUTTON_LED_PIN 2 // Пин кнопки для управления светодиодом
#define BUTTON_BUZZER_PIN 3 // Пин кнопки для управления пищалкой
// Таймеры для задач
unsigned long ledTimer = 0;
unsigned long buzzerTimer = 0;
// Интервалы для светодиода и пищалки
const unsigned long LED_INTERVAL = 500; // Интервал мигания светодиода (мс)
const unsigned long BUZZER_INTERVAL = 300; // Интервал для звука пищалки (мс)
// Состояния
bool ledEnabled = false; // Состояние управления светодиодом
bool buzzerEnabled = false; // Состояние управления пищалкой
bool ledState = false; // Состояние светодиода
bool buzzerState = false; // Состояние пищалки
void setup() {
pinMode(LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(BUTTON_LED_PIN, INPUT_PULLUP); // Кнопка с подтяжкой
pinMode(BUTTON_BUZZER_PIN, INPUT_PULLUP); // Кнопка с подтяжкой
digitalWrite(LED_PIN, LOW);
digitalWrite(BUZZER_PIN, LOW);
Serial.begin(115200);
}
void loop() {
handleButton(BUTTON_LED_PIN, ledEnabled); // Обработка кнопки для светодиода
handleButton(BUTTON_BUZZER_PIN, buzzerEnabled); // Обработка кнопки для пищалки
if (ledEnabled) handleLed(); // Управление светодиодом
if (buzzerEnabled) handleBuzzer(); // Управление пищалкой
}
// Обработка кнопки для управления потоком
void handleButton(int buttonPin, bool &taskEnabled) {
static unsigned long lastDebounceTime = 0; // Таймер для антидребезга
const unsigned long DEBOUNCE_DELAY = 50; // Задержка для антидребезга
static bool lastButtonState = HIGH; // Предыдущее состояние кнопки
bool currentState = digitalRead(buttonPin);
if (currentState != lastButtonState) {
lastDebounceTime = millis(); // Обновляем время изменения состояния
}
if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) {
// Если состояние кнопки изменилось после антидребезга
if (currentState == LOW && lastButtonState == HIGH) {
taskEnabled = !taskEnabled; // Переключаем состояние задачи
Serial.print("Поток ");
Serial.print(buttonPin == BUTTON_LED_PIN ? "LED" : "BUZZER");
Serial.println(taskEnabled ? " включен" : " выключен");
if (!taskEnabled) { // Если поток выключен, выключаем устройство
if (buttonPin == BUTTON_LED_PIN) digitalWrite(LED_PIN, LOW);
if (buttonPin == BUTTON_BUZZER_PIN) digitalWrite(BUZZER_PIN, LOW);
}
}
}
lastButtonState = currentState;
}
// Управление светодиодом
void handleLed() {
if (millis() - ledTimer >= LED_INTERVAL) {
ledTimer = millis();
ledState = !ledState;
digitalWrite(LED_PIN, ledState);
}
}
// Управление пищалкой
void handleBuzzer() {
if (millis() - buzzerTimer >= BUZZER_INTERVAL) {
buzzerTimer = millis();
buzzerState = !buzzerState;
digitalWrite(BUZZER_PIN, buzzerState);
}
}
Спойлер
Интересно, как скоро мой ЧатГПТ начнет тупеть от подобных заданий?))) И поговорить тогда не с кем будет на философские темы