Вопрос по параллельным задачам в ардуино

Kruppa
Offline
Зарегистрирован: 18.12.2015

Добрый день! Подскажите, пожалуйста, если знаете.

Как я понимаю, параллельные задачи Ардуино, а равно и атмега8, 16 и т.п. решать не могут.

Можно делать лишь псевдопараллельные потоки.

Так вот, можно ли этой псевдопараллельностью сделать так, чтоб скорость работы одной функции, регулировалось бы другой. Где во второй функции, скорость считывания/работы была бы постоянна?

 

Заранее спасибо

Kruppa
Offline
Зарегистрирован: 18.12.2015

Например, попробовал написать простой код, с помощью библиотеки "Thread".

В нём, мы управляем скоростью мигания светодиода с помощью кнопки. При этом, считываем информацию с кнопки раз в 1/2 секунды.

 

#include <Thread.h>  // подключение библиотеки ArduinoThread
const int PinForLed = 3;  // переменная с номером пина светодиода
const int PinForSpeed = 13;  // переменная с номером пина кнопки

Thread ledThread = Thread(); // создаём поток управления светодиодом
Thread speedThread = Thread(); // создаём поток управления частотой светодиода 
int x;

void setup() {
  x=1000;
    pinMode(PinForLed, OUTPUT); // объявляем пин 3 как выход.
    pinMode(PinForSpeed, INPUT);   // объявляем пин 13 как выход.

    ledThread.onRun(ledBlink);  // назначаем потоку задачу
    ledThread.setInterval(x); // задаём интервал срабатывания, мсек
    
    speedThread.onRun(setSp);     // назначаем потоку задачу
    speedThread.setInterval(500); // задаём интервал срабатывания, мсек
}

void loop() {
    // Проверим, пришло ли время переключиться светодиоду:
    if (ledThread.shouldRun());
        ledThread.run(); // запускаем поток
    
    // Проверим, пришло ли время сменить тональность сирены:
    if (speedThread.shouldRun())
        speedThread.run(); // запускаем поток
}

// Поток светодиода:
void ledBlink() { 
    static bool ledStatus = false;    // состояние светодиода Вкл/Выкл
    ledStatus = !ledStatus;           // инвертируем состояние
    digitalWrite(PinForLed, ledStatus);  // включаем/выключаем светодиод
}
// Поток установки скорости мигания светодиода:
void setSp() 
{ 
     if(digitalRead(PinForSpeed)==HIGH)
     {
      x=x+1000;
     
     }
      if (x>5000)
      {
        x=1000;
      }
     ledThread.setInterval(x);
     
}

 

Kruppa
Offline
Зарегистрирован: 18.12.2015

В общем, либо в коде ошибся, либо где-то эта псевдопараллельность не работает...

Joiner
Offline
Зарегистрирован: 04.09.2014

Прерывания нужны....прерывания..

Kruppa
Offline
Зарегистрирован: 18.12.2015

Прерывания в форме delay, как я помню, вроде как нельзя делать с этой библиотекой...

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

Ой блин. Говорят если много машин будет ехать по одной дороге, то будут сплошные аварии. И да есть и аварии , и все равно едет много машин по одним и тем же дорогам. Так и с паралленые задачи в Ардуине. Наверно вы криво пишете парралельные задачи в Ардуине, то и выходят у вас аварии.

/*to_kostik_v2.ino
  #1 светодиод 1 с ШИМ -> 3 (Led1_PWM_pin) 0-255 яркость
  #2 светодиод 2 с ШИМ -> 5 (Led2_PWM_pin) 0-255 яркость
  #3 светодиод 3 с ШИМ -> 6 (Led3_PWM_pin) 0-255 яркость
  #4 светодиод 4 с ШИМ -> 9 (Led4_PWM_pin) 0-255 яркость
  #5 кнопка SELECT     -> 2 (BTN1_PIN)
  #6 кнопка +          -> 7 (BTN2_PIN)
  #7 кнопка -          -> 8 (BTN3_PIN)
  Принцип кода: кнопкой SELECT выбор какой регулируем, мигает соответсвующий светодиод
              кнопкой +  нажатие яркость выбраного повышается на 25 в 0.3 s
              кнопкой -  нажатие яркость выбраного понижается на 25 в 0.3 s
*/
byte number = 0; // светодиоды от 0,1,2,3
const byte number_max = 4;
// #1,#2,#3,#4 светодиод
#include "Cl_Led_PWM.h"
#define Led1_PWM_PIN 3
#define Led2_PWM_PIN 5
#define Led3_PWM_PIN 6
#define Led4_PWM_PIN 9
Cl_Led_PWM  Device[4] = {Led1_PWM_PIN, Led2_PWM_PIN, Led3_PWM_PIN, Led4_PWM_PIN};
void func_1() {
  Device[number].plus();
//  Serial.println(Device[number].Led_PWM);
}
void func_2() {
  Device[number].minus();
//  Serial.println(Device[number].Led_PWM);
}
// #5 кнопка SELECT
#include "Cl_press_btn.h"
#define BTN_PIN 2
Cl_press_btn Btn1(BTN_PIN); // создать кнопку на пине 2
void func_3(void) {
  number++;
  if (number >= number_max) {
    number = 0;
  }
  Device[number].blink();
//  Serial.print("number= ");
//  Serial.println(number);
}
// #6 кнопка +
#include "Cl_press_btn_v2.h"
#define BTN2_PIN 7
Cl_press_btn2 Btn2(BTN2_PIN); // создать кнопку2 на пине 7
// #7 кнопка -
#define BTN3_PIN 8
Cl_press_btn2 Btn3(BTN3_PIN); // создать кнопку3 на пине 8
void setup() {
//  Serial.begin(9600);
  // #1 светодиод 1
  Device[0].setup();
  // #2 светодиод 2
  Device[1].setup();
  // #3 светодиод 3
  Device[2].setup();
  // #4 светодиод 4
  Device[3].setup();
  // #5 кнопка SELECT
  Btn1.setup();
  // #6 кнопка +
  Btn2.setup();
  // #7 кнопка -
  Btn3.setup();
}
void loop() {
  // #1 светодиод 1
  Device[0].loop();
  // #2 светодиод 2
  Device[1].loop();
  // #3 светодиод 3
  Device[2].loop();
  // #4 светодиод 4
  Device[3].loop();
  // #5 кнопка SELECT
  Btn1.loop(& func_3);
  // #6 кнопка +
  Btn2.loop(& func_1);
  // #7 кнопка -
  Btn3.loop(& func_2);
}

Ну и полный скетч здесь https://yadi.sk/d/Ezocs_n8395UxB

Logik
Offline
Зарегистрирован: 05.08.2014

Kruppa пишет:

Добрый день! Подскажите, пожалуйста, если знаете.

Как я понимаю, параллельные задачи Ардуино, а равно и атмега8, 16 и т.п. решать не могут.

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

Пишите код правильно. Выбросите из головы что Вам вбивали бездари на ПК. Они просто ищут как легче, потому как делать верно им не по силам. Пишите в один поток.   

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Kruppa пишет:

Прерывания в форме delay, как я помню, вроде как нельзя делать с этой библиотекой...

Нельзя. Ни прерывания в форме delay, ни рекурсию в форме volatile.

Kruppa
Offline
Зарегистрирован: 18.12.2015

       ЕвгенийП, и как тогда с этой библиотекой реализовать подобную задачу?)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Не знаю. Я эту библиотеку никогда не видел и в общем-то и видеть особо не хочу.