Помогите начинающему

Тема в разделе "Arduino & Shields", создана пользователем PRIUS, 17 сен 2020.

  1. PRIUS

    PRIUS Нерд

    Доброго времени суток!
    Модератору корзину добра.
    Пока скетч только на командах какие знаю, из уроков программирования, которые были нууу ооочень давно, другие команды пока не знаю, но по-тихому начинаю познавать. С библиотеками тоже начинаю разбираться, но продвигается очень тяжело.

    Все цифры с пульта работают почти нормально.

    Почему код приходит иногда другой, это указано в условии "OR" в некоторых цифрах.

    Постоянное горение светодиодов работает нормально, как только делаешь любую моргушку, как записано на восьмой кнопке, цикл повторяется один раз и все гаснет. Что с этим можно сделать? Интернет перерыл, не могу понять. Если что-то можно сделать то плиз закоментите. Скетч прилагаю.

    Спасибо.

    Код (C++):
    #include <IRremote.h>
    int red=9;
    int green=13;
    int blue=10;
    int RECV_PIN = A1;
    IRrecv irrecv(RECV_PIN);
    decode_results results;
    void setup()
    { pinMode (red,OUTPUT);
      pinMode (blue,OUTPUT);
      pinMode (green,OUTPUT);
      Serial.begin(9600);
      Serial.println("Enabling IRin");
      irrecv.enableIRIn();
      Serial.println("Enabled IRin");}
    void loop() {
      if (irrecv.decode(&results)) {
        Serial.println(results.value, HEX);
        irrecv.resume();  
        if(results.value==0xFF30CF or results.value==0x9716BE3F)// на еденичке
        {
         digitalWrite(red,HIGH);
          digitalWrite(green,LOW);
            digitalWrite(blue,LOW);
      }
       else if(results.value==0xFF18E7)// на двоичке
       {
         digitalWrite(red,LOW);
          digitalWrite(green,HIGH);
            digitalWrite(blue,LOW);
    }
    else if(results.value==0xFF7A85)// на троичке
    {
        digitalWrite(red,LOW);
          digitalWrite(green,LOW);
             digitalWrite(blue,HIGH);
    }
    else if(results.value==0xFF10EF)// на четверочке
    {
        digitalWrite(red,HIGH);
          digitalWrite(green,HIGH);
             digitalWrite(blue,HIGH);
      }
    else if(results.value==0xFF6897 or results.value==0xC101E57B  )// на нуле
    {
        digitalWrite(red,LOW);
          digitalWrite(green,LOW);
             digitalWrite(blue,LOW);
      }
    else if(results.value==0xFF38C7)// на на пятерочке
    {
        digitalWrite(red,HIGH);
          digitalWrite(green,HIGH);
             digitalWrite(blue,LOW);
      }
    else if(results.value==0xFF5AA5 or results.value==0x449E79F)// на шетерочке
    {
        digitalWrite(red,HIGH);
          digitalWrite(green,LOW);
             digitalWrite(blue,HIGH);
      }
    else if(results.value==0xFF42BD)// на семерочке
    {
        digitalWrite(red,LOW);
          digitalWrite(green,HIGH);
             digitalWrite(blue,HIGH);

    }
    else if(results.value==0xFF4AB5)// на восьмёрочке

    {
      digitalWrite(red,LOW);
          digitalWrite(green,LOW);
             digitalWrite(blue,LOW);        
      digitalWrite(red, HIGH);
      delay(1000);
      digitalWrite(red, LOW);
      delay(1000);
    }
    }

      }
     
  2. parovoZZ

    parovoZZ Гуру

    кучу else if можно заменить на switch case
     
    Igor68 нравится это.
  3. PRIUS

    PRIUS Нерд

    Пока не разобрался как это работает, но на верном пути.
     
  4. asam

    asam Гик

    А как это должно работать? Нажал/отпустил и оно моргает пока другую кнопку не нажмешь? Или должно моргать пока кнопку жмешь?
     
  5. PRIUS

    PRIUS Нерд

    Нажал/отпустил и оно моргает пока другую кнопку не нажмешь и включается другой режим.
     
  6. asam

    asam Гик

    Ну можно вот так, например:

    Код (C++):
    #include <IRremote.h>
    #include <TimerOne.h>
    int red = 9;
    int green = 13;
    int blue = 10;
    int RECV_PIN = A1;
    volatile bool blinking = false;
    IRrecv irrecv(RECV_PIN);
    decode_results results;

    void blinkfn()
    {
      static bool state = false;
      if (! blinking)
        return;
      state =  ! state;
      digitalWrite(red, state);
    }

    void setup()
    { pinMode (red, OUTPUT);
      pinMode (blue, OUTPUT);
      pinMode (green, OUTPUT);
      Serial.begin(9600);
      Serial.println("Enabling IRin");
      irrecv.enableIRIn();
      Serial.println("Enabled IRin");
      Timer1.initialize(1000000);            //Настраиваем таймер на прерывания раз в секунду
      Timer1.attachInterrupt(blinkfn);
    }
    void loop() {
      if (irrecv.decode(&results)) {
        Serial.println(results.value, HEX);
        irrecv.resume();
        blinking = false;
        if (results.value == 0xFF4AB5) // на восьмёрочке
        {
          digitalWrite(red, LOW);
          digitalWrite(green, LOW);
          digitalWrite(blue, LOW);
          blinking = true;
        }
        if (results.value == 0xFF30CF or results.value == 0x9716BE3F) // на еденичке
        {
          digitalWrite(red, HIGH);
          digitalWrite(green, LOW);
          digitalWrite(blue, LOW);
        }
        else if (results.value == 0xFF18E7) // на двоичке
        {
          digitalWrite(red, LOW);
          digitalWrite(green, HIGH);
          digitalWrite(blue, LOW);
        }
        else if (results.value == 0xFF7A85) // на троичке
        {
          digitalWrite(red, LOW);
          digitalWrite(green, LOW);
          digitalWrite(blue, HIGH);
        }
        else if (results.value == 0xFF10EF) // на четверочке
        {
          digitalWrite(red, HIGH);
          digitalWrite(green, HIGH);
          digitalWrite(blue, HIGH);
        }
        else if (results.value == 0xFF6897 or results.value == 0xC101E57B  ) // на нуле
        {
          digitalWrite(red, LOW);
          digitalWrite(green, LOW);
          digitalWrite(blue, LOW);
        }
        else if (results.value == 0xFF38C7) // на на пятерочке
        {
          digitalWrite(red, HIGH);
          digitalWrite(green, HIGH);
          digitalWrite(blue, LOW);
        }
        else if (results.value == 0xFF5AA5 or results.value == 0x449E79F) // на шетерочке
        {
          digitalWrite(red, HIGH);
          digitalWrite(green, LOW);
          digitalWrite(blue, HIGH);
        }
        else if (results.value == 0xFF42BD) // на семерочке
        {
          digitalWrite(red, LOW);
          digitalWrite(green, HIGH);
          digitalWrite(blue, HIGH);

        }

      }

    }
     
  7. PRIUS

    PRIUS Нерд

    мало что понял, но буду разбираться. если заработает спасибо.
     
  8. PRIUS

    PRIUS Нерд

    ничего не получилось. моргания так и нет
     
  9. parovoZZ

    parovoZZ Гуру

  10. Limoney

    Limoney Гик

    Это нормально, работает, как написали без моргания. Не используйте delay
     
  11. b707

    b707 Гуру

    а сколько он раз должен повторятся, если у вас и цикла никакого нет? Как написано - один раз моргнуть - ровно так и работает
     
  12. b707

    b707 Гуру

    его и не будет, в представленном коде нет моргания вовсе.

    Подобная задача решается не так.

    1. Для начала найдите пример "блинк без delay()" и разберитесь, как он работает. Напишите на его основе код мигания светодиодом, проверьте его работу.

    2. Потом добавьте к миганию код отработки кнопки (обычной. не радио). смысл в том, что кнопка должна опрашиватся одновременно с миганием, поэтому в коде НЕДОПУСТИМО использовать операторы delay(). Кнопка должна прекращать мигание, если светодиод мигает - или запускать снова, если мигание остановлено. Для этого вам придется изучить такое понятие, как "флаги".

    3. Теперь замените обычную кнопку на считаывание кода с радиопульта
     
    Daniil, arkadyf и issaom нравится это.
  13. PRIUS

    PRIUS Нерд

    Спасибо за наставление.
    очень долго искал в интернете информации.
    в итоге плюнул на светодиоды и заинтересовался адресной лентой.
    гуглил все что можно и нельзя.
    и вот что получилось
    Код (C++):
    // управление кнопкой адресной светодиодной лентой с управляемой частотой через потенциометр
    #define PIN 8        // кнопка подключена сюда (PIN --- КНОПКА --- GND) у нас пин 8
    #define MODE_AM 5    // количество режимов (от 0 до указанного)
    #define PIN_POD A1   // куда подключили потенциометр
    #include "GyverButton.h"//библиотека для более удобной работы с кнопкой, скачать мождно здесь https://github.com/AlexGyver/GyverLibs
    GButton butt1(PIN);  // создаём нашу "кнопку"
    byte mode = 0;       // переменная режима кнопки
    #include <Adafruit_NeoPixel.h>// библиотека для адресной ленты
    Adafruit_NeoPixel pixels_1 = Adafruit_NeoPixel(12, A2, NEO_GRB + NEO_KHZ800);// лента подключена на пин А2 и на 12 светодиодов
    int counter = 0;      // замена i
    long timer = 0;   // переменная таймера
    int T_PERIOD; // переменная для длительности свечения
    void setup() {
      Serial.begin(9600);//передача данных на монитор порта
      pixels_1.begin();// активируем адресную ленту
      butt1.setTickMode(AUTO);// устанавливаем опрос кнопки на автоматический
      pinMode(PIN_POD, INPUT);//устанавливам пин с потенциометром на вход
    }

    void loop() {
      T_PERIOD = analogRead(PIN_POD);//записываем информацию с потенциометра
      butt1.tick();      // обязательная функция отработки. Должна постоянно опрашиваться кнопку
      if (butt1.isPress()) {    // правильная отработка нажатия с защитой от дребезга
        if (++mode >= MODE_AM) mode = 0;// увеличиваем переменную номера режима. Если вышла за количество режимов - обнуляем
      }
      // всё переключение в итоге сводится к оператору switch
      switch (mode) {

        case 0: task_0();
          { // Выключение ленты
            if (millis() - timer >= T_PERIOD)  // таймер на millis()
              timer = millis(); // сброс
            //Serial.println(counter);// номер пикселя
            //Serial.println(T_PERIOD);//задержка
            //Serial.println(timer);// время от начала работы
            pixels_1.setPixelColor(counter, pixels_1.Color( 0, 0, 0));
            pixels_1.show();
            pixels_1.clear();
            // действие с counter - наш i-ый светодиод например
            counter++;  // прибавляем счётчик
            if (counter > 12) counter = 0;// закольцовываем изменение
          }


          break;
        case 1: task_1();
          {{ // Включение свтодиода друг за другом
              if (millis() - timer >= T_PERIOD)  // таймер на millis()
              { timer = millis(); // сброс
                counter++;  // прибавляем счётчик

                pixels_1.setPixelColor(counter - 1, pixels_1.Color((random(0, 255)), (random(0, 255)), (random(0, 255))));
                pixels_1.show();
              }
              pixels_1.clear();
              // действие с counter - наш i-ый светодиод например

              if (counter > 11) counter = 0;// закольцовываем изменение
            }
          }
          break;


        case 2: task_2();
          { { // Включение светодиодов друг за другом и не выключается позади
              if (millis() - timer >= T_PERIOD)  // таймер на millis()
              { timer = millis(); // сброс
                counter++;  // прибавляем счётчик
                pixels_1.setPixelColor(counter - 1, pixels_1.Color((random(0, 255)), (random(0, 255)), (random(0, 255))));
                pixels_1.show();
              }
              // pixels_1.clear();
              // действие с counter - наш i-ый светодиод например

              if (counter > 11) counter = 0;// закольцовываем изменение
            }
          }
          break;


        case 3: task_3();
          {{ // Включение светодиодов рандомно и не выключается последний

              if (millis() - timer >= T_PERIOD)  // таймер на millis()
              { timer = millis(); // сброс
                counter = random(1, 11);  // изменяем светодиод рандомно
                //Serial.println(counter);// номер пикселя
                //Serial.println(T_PERIOD);//задержка
                //Serial.println(timer);// время от начала работы
                pixels_1.setPixelColor(counter - 1, pixels_1.Color((random(0, 255)), (random(0, 255)), (random(0, 255))));
                pixels_1.show();
              }
              //pixels_1.clear();
              // действие с counter - наш i-ый светодиод например

              if (counter > 11) counter = 0;// закольцовываем изменение
            }
          }


          break;


        case 4: task_4();
          {{ // Включение светодиодов рандомно
              if (millis() - timer >= T_PERIOD)  // таймер на millis()
              { timer = millis(); // сброс
                counter = random(1, 11);  // изменяем светодиод рандомно
                //Serial.println(counter);// номер пикселя
                //Serial.println(T_PERIOD);//задержка
                //Serial.println(timer);// время от начала работы
                pixels_1.setPixelColor(counter, pixels_1.Color((random(0, 255)), (random(0, 255)), (random(0, 255))));
                pixels_1.show();
              }
              pixels_1.clear();
              // действие с counter - наш i-ый светодиод например

              if (counter > 11) counter = 0;// закольцовываем изменение
            }
          }

          break;
      }
    }
    // наши задачи, внутри функций понятное дело может быть всё что угодно
    void task_0() {

      Serial.println("Task 0");
    }
    void task_1() {
      Serial.println("Task 1");
    }
    void task_2() {
      Serial.println("Task 2");
    }
    void task_3() {
      Serial.println("Task 3");
    }
    void task_4() {
      Serial.println("Task 4");
    }
     
  14. PRIUS

    PRIUS Нерд

    библиотека с кнопкой более или менее понятная
     
  15. b707

    b707 Гуру

    не понятно, что вы там искали. да еще и столько времени... я четко написал, что изучать - пример "блинк без delay()
    ну получилось - значит получилось. Не ясно. чем адресная лента проще светодиодов... скорее всего тем, что у гайвера есть готовый код для ее управления, который вы и слямзили, вместо того чтоб учиться самому...
    "
     
  16. PRIUS

    PRIUS Нерд

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

    PRIUS Нерд

    С адресной лентой работать было интересней.
     
  18. PRIUS

    PRIUS Нерд

    кстати если убрать в коде моргания пару фигурных скобок, то период не будет учитываться и моргание будет с постоянной частотой.
     
  19. parovoZZ

    parovoZZ Гуру

    я тоже поработал
    http://forum.amperka.ru/threads/450-ws2812-на-attiny1614-и-немного-кода.20663/
    В результате "огонёк" пробегает 450 светодиодов за 11 секунд. Сравните со своими черепашечьими так называемыми "скетчами" ("наброски" в переводе).
     
  20. b707

    b707 Гуру

    Должен на 3 порядка быстрее:
    800 КГц / 24бита = 30 тыс пикселей в секунду