Мигающий диод при наличии задержки в основном теле программы

Electroniume
Offline
Зарегистрирован: 05.06.2018

Добрый день!

Взял такой листинг, он мне как раз подходит (это будет автополив по таймеру):

// Первый регулятор управляет временем, которое будет литься вода (от 4 до 15 секунд)
#define MAX_FLOWTIME 15 // seconds
#define MIN_FLOWTIME 4 // seconds

// Второй регулятор управляет частотой полива от раза в день до раза в неделю
#define MAX_PERIOD 7 // days
#define MIN_PERIOD 1 // days

#define MAX 675
#define MIN 0

int volumePin = A0; // Пин, к которому подцеплен регулятор, отвечающий за объём поливаемой воды
int periodPin = A1; // Пин, к которому подцепелн регулятор, отвечающий за период между поливами
int pumpPin = 5; // Пин, к которому подсоединено управление насосом
int ledOnline = 13; // Сигнальный LED

int volume;
int period;

// Процедура, включающая насос на время, заданное в volume
void water() {
  digitalWrite(pumpPin, HIGH); // включаем насос
  delay(volume);
  digitalWrite(pumpPin, LOW); // выключаем насос
  delay(period);  
}


void setup() {
  pinMode(pumpPin, OUTPUT);
  digitalWrite(pumpPin, LOW); 
  ledOnline, OUTPUT);
}

void loop() {
  // Считываем значения регуляторов (переменных резисторов) и приводим их к заданным пределам
  volume = map(analogRead(volumePin), MIN, MAX, MIN_FLOWTIME, MAX_FLOWTIME) * 1000; 
  period = map(analogRead(periodPin), MIN, MAX, MIN_PERIOD, MAX_PERIOD) * 1000 * 60 * 60 * 24; 
 
  water();
}

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

 

Вопрос: как мне это сделать, если основной цикл loop исполняется раз в period, а period равен одному дню (или больше, в зависимости от настройки)?

negavoid
Offline
Зарегистрирован: 09.07.2016

В этом коде period никогда не может быть дольше, чем 37% дня. И volume тоже. На Uno и nano, по крайней мере.

b707
Offline
Зарегистрирован: 26.05.2017

Electroniume пишет:

Вопрос: как мне это сделать, если основной цикл loop исполняется раз в period, а period равен одному дню (или больше, в зависимости от настройки)?

Конечно, можно и заставить диод мигать и в рамках вашей задачи(и совсем несложно), однако это будет неправильно в педагогическом смысле :)

По уму правильнее будет переписать скетч, убрав огромные задержки, чтобы ЛУП исполнялся не дольше нескольких десятков мс.

b707
Offline
Зарегистрирован: 26.05.2017

negavoid пишет:

В этом коде period никогда не может быть дольше, чем 37% дня. И volume тоже.

точно :)

Автор, максимальная длительность задержки в вашем коде - 9 часов 6 минут :)

Это все не отменяет моего предыдущего сообщения - код реально бредовый и должен быть выкинут в помойку.

Electroniume
Offline
Зарегистрирован: 05.06.2018

negavoid пишет:

В этом коде period никогда не может быть дольше, чем 37% дня. И volume тоже. На Uno и nano, по крайней мере.

Почему, расскажи поподробнее?

b707 пишет:

Конечно, можно и заставить диод мигать и в рамках вашей задачи(и совсем несложно), однако это будет неправильно в педагогическом смысле :)

По уму правильнее будет переписать скетч, убрав огромные задержки, чтобы ЛУП исполнялся не дольше нескольких десятков мс.

Так, я тоже чувствую что ждать несколько дней через delay как-то неправильно.

А как переписать, какой алгоритм будет правильный?

b707
Offline
Зарегистрирован: 26.05.2017

Electroniume пишет:

А как переписать, какой алгоритм будет правильный?

смотри пример "blink without delay"

Pyotr
Offline
Зарегистрирован: 12.03.2014

Electroniume пишет:

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

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

volatile unsigned int  blinkLED = 10, period = 1000;

void setup(){
  pinMode(13, OUTPUT);
  OCR0A = 128;//записываем в регистр совпадения число  например 128 
  //Биты OCIE0B (2) и OCIE0A (1) разрешают прерывания при совпадении с A и B,
  TIMSK0 |= (1<<OCIE0A);
}
void loop(){
 delay(10000);
}
// Прерывание вызывается раз в 1024 mkc
ISR(TIMER0_COMPA_vect) {
  static word count = 0;
  if(count == period) count = 0;
  if(count == 0)  
    PORTB |= (1<<5);
  else if(count == blinkLED)
    PORTB &= ~(1<<5);  
  count++;
}

 

negavoid
Offline
Зарегистрирован: 09.07.2016
PORTB &= ~(1<<5);

человеку, который ещё не понимает типы данных, тогда уж сразу asm и вперёд, долой все if-ы, только je jnz, только хардкор :)

Pyotr
Offline
Зарегистрирован: 12.03.2014

negavoid пишет:

PORTB &= ~(1<<5);

человеку, который ещё не понимает типы данных, тогда уж сразу asm и вперёд, долой все if-ы, только je jnz, только хардкор :)

Ничего страшного)) научится... Пусть сам заменит на digitalWrite(), если надо.

Я свой первый скетч также писал)) 

На всяк случай для ТС - вкл\выключать полив можно также как и лед, без millis().

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

Electroniume пишет:

Взял такой листинг, он мне как раз подходит (это будет автополив по таймеру):

...

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

Вопрос: как мне это сделать, если основной цикл loop исполняется раз в period, а period равен одному дню (или больше, в зависимости от настройки)?

Используйте простую кооперативную операционную систему, например, такую. Одна задача поливает, другая мигает светодиодом.  Вдобавок к этому можете еще задач запендюрить сколько надо, пусть еще что-нибудь полезное делают.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Если прикручивать мигающий светодиод, то только к программе построенной по такой структуре

Electroniume
Offline
Зарегистрирован: 05.06.2018

b707 пишет:

смотри пример "blink without delay"

Попробовал всё переписать:

const int ledPin =  13;      // номер выхода, подключенного к светодиоду
int ledState = LOW;             // этой переменной устанавливаем состояние светодиода
unsigned long previousMillis = 0;        // храним время последнего переключения светодиода
int interval = 100;           // интервал между включение/выключением светодиода

unsigned long currentMillis;

const int pumpPin = 5;
int pumpState = LOW;
unsigned long previousMillis_period = 0; // храним время последнего переключения насоса

const int volumePin = A0; // Пин, к которому подцеплен регулятор, отвечающий за объём поливаемой воды
const int periodPin = A1; // Пин, к которому подцепелн регулятор, отвечающий за период между поливами
int period; // интервал между переключеием насоса. нужно считывать с потенциометра!
int volume; // время работы насоса. нужно считывать с потенциометра!

// калибровка потенциометров - минимальное и максимальное аналоговое значение
const int min = 0;
const int max = 675;
// и минимум и максимум значений интервала и времени работы насоса
const int period_min = 1; // дни
const int period_max = 7;
const int volume_min = 4; // секунды
const int volume_max = 15;

void setup() {
  pinMode(ledPin, OUTPUT);     
  pinMode(pumpPin, OUTPUT);
  pinMode(volumePin, INPUT);
  pinMode(periodPin, INPUT);
}
 
void loop()
{
  // включение-выключение насоса
  currentMillis = millis();

  volume = map(analogRead(volumePin), min, max, volume_min, volume_max) * 1000;
  period = map(analogRead(periodPin), min, max, period_min, period_max) * 1000 * 60 * 60 * 24;
  
  if(currentMillis - previousMillis_period > period) {
    previousMillis_period = currentMillis;
    if (pumpState == LOW) {
      pumpState = HIGH;
      delay(volume); // --- сделать задержку без delay - но тут задержка порядка секунд - будет работать и так
    }
    else
      pumpState = LOW;
    digitalWrite(pumpPin, pumpState);
  }
  
  // моргание диодом
  currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis; 
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    digitalWrite(ledPin, ledState);
  }
}

Верное направление, или совсем не то?

kalapanga
Онлайн
Зарегистрирован: 23.10.2016

Это насос "будет работать и так". А светодиод не будет. Задержку в 45 строке надо тоже ликвидировать.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Самый простой путь дописать первый листинг - это использование yield, которая вызывается внутри delay уже из коробки. Таким образом, объявив функцию yield - внутри неё можно будет мигать светодиодом вне зависимости от того, что кто-то где-то висит в delay:

typedef enum
{
	bmNop,
	bmHigh,
	
} BlinkMachine;

BlinkMachine blinkState;
#define ON_INTERVAL 500 // интервал горения светодиода, в мс
#define OFF_INTERVAL 5000 // интервал покоя светодиода
bool wantBlinkFlag = true;
uint32_t blinkTimer = OFF_INTERVAL;

void yield()
{
	if(wantBlinkFlag)
	{
		switch(blinkState)
		{
			case bmNop:
			{
				if(millis() - blinkTimer > OFF_INTERVAL)
				{
					blinkTimer = millis();
					digitalWrite(LED_BUILTIN, HIGH);
					blinkState = bmHigh;
				}
			}
			break;
			
			case bmHigh:
			{
				if(millis() - blinkTimer > ON_INTERVAL)
				{
					blinkTimer = millis();
					digitalWrite(LED_BUILTIN, LOW);
					blinkState = bmNop;
				}
			}
			break;
		}
	}
}

void loop()
{
	yield();
	delay(60000);
}

Как вариант, навскидку - без использования аппаратных таймеров и пр. Для мигания светодиодом - более чем достаточно. Функция позднего связывания yield может также использоваться как механизм периодической передачи управления выполнением кода из одной части прошивки в другую, что бывает очень полезно. Собственно, механизм такой передачи уже есть внутри delay - он вызывает функцию yield, внутри которой мы, на простеньком примере выше - делаем нужные нам дела.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

/**/
//---------------------------------------------------------
const int ledPin =  13;      // номер выхода, подключенного к светодиоду
bool ledState;             // этой переменной устанавливаем состояние светодиода
const unsigned long interval = 100;           // интервал между включение/выключением светодиода
unsigned long past;
void ledON() {
  ledState = HIGH;
  past = millis();
  digitalWrite(ledPin,  HIGH);
}
void ledOFF() {
  ledState = LOW;
  past = millis();
  digitalWrite(ledPin, LOW);
}
void ledInit() {
  pinMode(ledPin, OUTPUT);
  ledOFF();
}
void ledRun() {
  if (ledState == LOW && millis() - past >= interval )ledON();
  if (ledState == HIGH && millis() - past >= interval )ledOFF();
}
//----------насос--------------------------------------
const int pumpPin = 5;
const int volumePin = A0; // Пин, к которому подцеплен регулятор, отвечающий за объём поливаемой воды
const int periodPin = A1; // Пин, к которому подцепелн регулятор, отвечающий за период между поливами

// калибровка потенциометров - минимальное и максимальное аналоговое значение
const int min = 0;
const int max = 675;
// и минимум и максимум значений интервала и времени работы насоса
const int period_min = 1; // дни
const int period_max = 7;
const int volume_min = 4; // секунды
const int volume_max = 15;

bool pumpState = LOW;
unsigned long past2;

void PumpON() {
  pumpState = HIGH;
  past2 = millis();
  digitalWrite(pumpPin, HIGH);

}
void PumpOFF() {
  pumpState = LOW;
  past2 = millis();
  digitalWrite(pumpPin, LOW);

}
void PumpInit() {
  pinMode(pumpPin, OUTPUT);
  pinMode(volumePin, INPUT);
  pinMode(periodPin, INPUT);
  PumpOFF();
}
void PumpRun() {
  unsigned long volume = map(analogRead(volumePin), min, max, volume_min, volume_max) * 1000;
  unsigned long period = (unsigned long)map(analogRead(periodPin), min, max, period_min, period_max) * 1000 * 60 * 60 * 24;
  if (pumpState == LOW && millis() - past2 >= period)PumpON();
  if (pumpState == HIGH && millis() - past2 >= volume)PumpOFF();
}
//--------------main----------------------------------
void setup() {
  ledInit();
  PumpInit();
}
void loop() {
  ledRun();
  PumpRun();
}
/*Скетч использует 1616 байт (5%) памяти устройства. Всего доступно 30720 байт.
  Глобальные переменные используют 19 байт (0%) динамической памяти, оставляя 2029 байт для локальных переменных. Максимум: 2048 байт.
*/

 

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

Скетч из первого поста, переделанный для работы с кооперативной ОС

#include "coos.h"

// Первый регулятор управляет временем, которое будет литься вода (от 4 до 15 секунд)
  #define MAX_FLOWTIME 15 // seconds
  #define MIN_FLOWTIME 4 // seconds
  // Второй регулятор управляет частотой полива от раза в день до раза в неделю
  #define MAX_PERIOD 7 // days
  #define MIN_PERIOD 1 // days
  #define MAX 675
  #define MIN 0
  int volumePin = A0; // Пин, к которому подцеплен регулятор, отвечающий за объём поливаемой воды
  int periodPin = A1; // Пин, к которому подцепелн регулятор, отвечающий за период между поливами
  int pumpPin = 5; // Пин, к которому подсоединено управление насосом
  int ledOnline = 13; // Сигнальный LED
  int led_on;   // управление светодиодом
  int volume;
  int period;

  // Задача, включающая насос на время, заданное в volume
  void water() {
    COOS_DELAY(0);
    while(1)
    {
      // Считываем значения регуляторов (переменных резисторов) и приводим их к заданным пределам
      volume = map(analogRead(volumePin), MIN, MAX, MIN_FLOWTIME, MAX_FLOWTIME) * 1000;
      period = map(analogRead(periodPin), MIN, MAX, MIN_PERIOD, MAX_PERIOD) * 1000 * 60 * 60 * 24;
      digitalWrite(pumpPin, HIGH); // включаем насос
      led_on = 1;                  // можно мигать
      COOS_DELAY(volume);
      digitalWrite(pumpPin, LOW); // выключаем насос
      led_on = 0;                  // хватит мигать
      COOS_DELAY(period); 
    }
  }
  // Задача, мигающая светодиодом раз в секунду
  void led_flash() {
    while(1)
    {
      if (led_on) // если можно мигать
      {
        digitalWrite(ledOnline, HIGH);  // включаем светодиод
        COOS_DELAY(500);                // на полсекунды
      }
      digitalWrite(ledOnline, LOW);      // выключаем светодиод      
      COOS_DELAY(500); 
    }
  }    
  void setup() {
    pinMode(pumpPin, OUTPUT);
    digitalWrite(pumpPin, LOW);
    pinMode(ledOnline, OUTPUT);
    digitalWrite(ledOnline, LOW);      
    coos.register_task(water);
    coos.register_task(led_flash);
  }
  void loop() {
    coos.run_scheduler();
  }

 

Electroniume
Offline
Зарегистрирован: 05.06.2018

kalapanga пишет:

Это насос "будет работать и так". А светодиод не будет. Задержку в 45 строке надо тоже ликвидировать.

Получилось как-то так.

const int ledPin =  13;      // номер выхода, подключенного к светодиоду
int ledState = LOW;             // этой переменной устанавливаем состояние светодиода
unsigned long previousMillis = 0;        // храним время последнего переключения светодиода
int interval = 100;           // интервал между включение/выключением светодиода
int interval_led;

unsigned long currentMillis;

const int pumpPin = 5;
int pumpState = LOW;
unsigned long previousMillis_period = 0; // храним время последнего переключения насоса
unsigned long previousMillis_volume = 0; 

const int volumePin = A0; // Пин, к которому подцеплен регулятор, отвечающий за объём поливаемой воды
const int periodPin = A1; // Пин, к которому подцепелн регулятор, отвечающий за период между поливами
const int ledRegPin = A2;
int period; // интервал между переключеием насоса. нужно считывать с потенциометра!
int volume; // время работы насоса. нужно считывать с потенциометра!

// калибровка потенциометров - минимальное и максимальное аналоговое значение
const int min = 0;
const int max = 675;
// и минимум и максимум значений интервала и времени работы насоса
const int period_min = 1; // дни
const int period_max = 7;
const int volume_min = 4; // секунды
const int volume_max = 15;

const int led_min = 10; // миллисекунды
const int led_max = 1000;

void setup() {
  pinMode(ledPin, OUTPUT);     
  pinMode(pumpPin, OUTPUT);
  pinMode(volumePin, INPUT);
  pinMode(periodPin, INPUT);
  pinMode(ledRegPin, INPUT);
}
 
void loop()
{
  // включение-выключение насоса
  currentMillis = millis();

  volume = map(analogRead(volumePin), min, max, volume_min, volume_max) * 1000;
  period = map(analogRead(periodPin), min, max, period_min, period_max) * 1000 * 60 * 60 * 24;
  
  if(currentMillis - previousMillis_period > period) {
    previousMillis_period = currentMillis;
    digitalWrite(pumpPin, HIGH); // в начале очедного цикла включаем насос
    currentMillis = millis();
    if(currentMillis - previousMillis_volume > volume) {
      previousMillis_volume = currentMillis;
      digitalWrite(pumpPin, LOW); // насос поработал - выключаем
    }    
  }
 
interval_led =  map(analogRead(ledRegPin), min, max, led_min, led_max);
  
  // моргание диодом. для контроля у диода тоже есть регулятор в виде резистора
  currentMillis = millis();
  if(currentMillis - previousMillis > interval_led) {
    previousMillis = currentMillis; 
    if (ledState == LOW)
      ledState = HIGH;
    else
      ledState = LOW;
    digitalWrite(ledPin, ledState);
  }
}

DIYMan пишет:

Самый простой путь дописать первый листинг - это использование yield,

triac пишет:

Скетч из первого поста, переделанный для работы с кооперативной ОС

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

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

Electroniume пишет:

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

Это особая уличная магия, примерно как стрелять из пушки корабельной по воробьям =)

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

Electroniume пишет:

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

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

Заботу о том, чтобы они выполнялись как бы одновременно берет на себя ОС. Вам же для этого в теле задачи просто надо вставлять задержки COOS_DELAY(x). Когда этот оператор выполняется, управление предается ядру ОС. По прошествии заданного времени ОС возвращает управление задаче.

b707
Offline
Зарегистрирован: 26.05.2017

triac пишет:

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

я думаю, что подобные костыги - а это ведь костыль, очевидно - не следует применять новичкам, пока сами ходить не научатся.

Для столь простого проекта, как у ТС - никакие ОС не нужны в принципе.

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

triac пишет:

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

Вот после таких вот заявлений и появляются люди которые пишут с паузами и не понимают как оно работает и почему не мигает диод.

Ну напишите что ПАУЗЫ выполняются одновременно, а не задачи...

Задачи таки выполняются последовательно...

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

b707 пишет:
Для столь простого проекта, как у ТС - никакие ОС не нужны в принципе.
А вы думаете что для новичков(-шаровичков) тут пишут. Обычно просто обмениваемся приемами,идеями. А новички это всего лишь повод.

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

b707 пишет:

я думаю, что подобные костыги - а это ведь костыль, очевидно - не следует применять новичкам, пока сами ходить не научатся.

Для столь простого проекта, как у ТС - никакие ОС не нужны в принципе.

Я не считаю это костылем. Вот ProtoThreads - это, действительно, костыль. Или "смекалка темной головы" qwone. А COOS - это вполне полноценная кооперативная ОС, только простая и портативная (читай: портируемая и компактная) до предела.

Задача ТС как раз правильно решается при помощи ОС. А все прочие решения - самые натуральные костыли.

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

ToRcH2565 пишет:

Ну напишите что ПАУЗЫ выполняются одновременно, а не задачи...

Задачи таки выполняются последовательно...

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

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

triac пишет:
Если нажимаете на "последовательно", то можете указать в какой последовательности? Нет? Ну тогда и не  надо пудрить мозги новичкам. Человеку кажется, что они выполняются одновременно, этого достаточно.

Кажется у нас появилась многоядерность в МК с одним ядром...

А когда кажется - крестятся или смотрят точными приборами, выбор от религии зависит =)

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

ToRcH2565 пишет:

Кажется у нас появилась многоядерность в МК с одним ядром...

К сожалению, многоядерные процессоры внесли сумятицу в неокрепшие умы. Забудьте их покамест. На обычном одноядерном процессоре уже десятки лет как можно реализовать и многозадачность, и многопоточность.

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

triac пишет:

К сожалению, многоядерные процессоры внесли сумятицу в неокрепшие умы. Забудьте их покамест. На обычном одноядерном процессоре уже десятки лет как можно реализовать и многозадачность, и многопоточность.

К сожалению многопоточные(одноядерные)* процессоры, и многозадачные ОС внесли сумятицу в неокрепшие умы. На одноядерных процессорах потоки, и задачи выполняются не одновременно, а последовательно.

Не путайте понятия многопоточность\многозадачность и одновременное выполнение инструкций.

 

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

negavoid
Offline
Зарегистрирован: 09.07.2016

ToRcH2565 пишет:

На одноядерных процессорах потоки, и задачи выполняются не одновременно, а последовательно.

Не путайте понятия многопоточность\многозадачность и одновременное выполнение инструкций.

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

Смотря на каком уровне смотреть. Если на высоком уровне кода потока, то да, всё последовательно. Если начинаем смотреть на уровне ассемблера, который попадает в кэш, и чуть ниже, то всё становится интереснее, и именно исполнение нескольких операций одновременно(параллельно) привели к meltdown и spectre. Как это было - с точки зрения программы - да, результаты выходят из "чёрного ящика" процессора последовательно, но с точки зрения конвейера внутри - он мог исполнить некоторые инструкции, включая лишние, даже вперёд того, а такты-то остаются те же. И гипертрединг тоже, при некоторых определённых условиях и правда способен одновременно исполнять больше одной инструкции, если у проца остаётся свободное место в конвейере и регистрах.

https://ru.wikipedia.org/wiki/%D0%A1%D1%83%D0%BF%D0%B5%D1%80%D1%81%D0%BA%D0%B0%D0%BB%D1%8F%D1%80%D0%BD%D0%BE%D1%81%D1%82%D1%8C

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

ToRcH2565 пишет:

 На одноядерных процессорах потоки, и задачи выполняются не одновременно, а последовательно.

На самых простых одноядерных процессорах потоки и задачи, несомненно, выполняются одновременно.  Задача (или поток) не обязана дожидаться окончания выполнения другой задачи (или потока). Если вы попробуете приведенный мною скетч, то убедитесь, что там обе задачи работают одновременно. Но при этом процессор, конечно же, не исполняет несколько команд одновременно.

Неокрепшими следует признать умы, нетвердые в знаниях и терминологии, и, как следствие, употребляющие слова произвольно и неуместно.  В частности, к обсуждению многозадачности приплетающие многоядерность и/или одновременное выполнение инструкций, как якобы обязательное условие, необходимое для многозадачности; смешивающие в одну кучу одновременное выполнение задач и одновременное выполнение машинных команд. Путаница в неокрепших умах возникает, помимо прочего, из-за трудностей перевода с английского.

multitasking is the concurrent execution of multiple tasks (also known as processes) over a certain period of time.

Concurrent computing is a form of computing in which several computations are executed during overlapping time periods—concurrently—instead of sequentially (one completing before the next starts)

The concept of concurrent computing is frequently confused with the related but distinct concept of parallel computing,[2][3] although both can be described as "multiple processes executing during the same period of time". In parallel computing, execution occurs at the same physical instant: for example, on separate processors of a multi-processor machine, with the goal of speeding up computations—parallel computing is impossible on a (one-core) single processor, as only one computation can occur at any instant (during any single clock cycle).[a] By contrast, concurrent computing consists of process lifetimes overlapping, but execution need not happen at the same instant. The goal here is to model processes in the outside world that happen concurrently, such as multiple clients accessing a server at the same time.

Проблемы перевода:

parallel {прилаг.} RU параллельный, аналогичный, подобный

concurrent {прилаг.} RU параллельный, действующий совместно или одновременно, совпадающий

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

ТСу не надо мозг перегревать, ТСу нада чтоб у его светлодиот мигал отдельно от лупа.  И сё. 

Я, видя уровень, даже за свои таймеры ему не втираю, а они на 2 порядка проще этой вашей многозадачности.. 

triac
triac аватар
Offline
Зарегистрирован: 03.05.2018

Был скетч 41 в строку, стал в 58 строк. Добавилось 17 строк текста. Одна строка вызова либы, две строки регистрации задач и плюс сама задача мигания светодиодом. Ужас как сложно...

А "на два порядка проще" - наверное у вас в одну строку текста умещается, и тоже машинно-независимая реализация? Или надо парить ТС мозги железом?

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Дак я и не парю.