Помогите сделать ходовые огни умные

Всем привет. Силы на исходе. Ну не доходит до меня. Мучаюсь уже неделю. Знаний С++ по 10ти бальной на 1.5)) Скачал готовый скетч, хочу переделать под передние ходовые огни. Не получается выполнить простую задачу.

  • В нормальном режиме, работает, будем называть его ожиданием. Это когда включено зажигание - выполняется одно действие. (Светиться на половину яркости и бегает яркий огонек(вообще с анимацией я могу сам разобраться))
  • Включаем D - светиться полностью белым.
  • Включаем R - бегает один белый огонек
  • Включаем поворот - бегает полоска желтого
  • Соответсвтенно второй.
    Основая моя проблема. Это то что не могу понять, как сделать, чтобы при включении поворотника, одно действие переставало выполняться, а другой выполнялось. Может такое реализовать проще функциями, а не if…else?
#include <Adafruit_ADXL345_U.h>

//несколько общих комментариев
// я отключил по одному крайнему светодиоду, т.к. они отсвечивали на декоративные панели стоек
//видно на примере этого цикла for (int i=1; i<39; i++ )
//если отключать не нужно, заменяем на for (int i=0; i<CountLed; i++ )

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

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

// Пин для подключения управляющего сигнала светодной ленты
const int PinLS = 26;

//Пины для подключения датчиков
//если более удобно будет подключать контакты в другом порядке - просто поменяйте значения переменных
const int buttonPinL = 12;
const int buttonPinR = 14;
const int buttonPinS = 27;
const int buttonPinD = 32;

//начальные статусы входов (подтянуты к плюсу)
int buttonStateS = HIGH;
int buttonStateD = HIGH;
int buttonStateL = HIGH;
int buttonStateR = HIGH;

// пауза pause_pov1 (в миллисекундах) нужна, чтобы синхронизировать циклы "пробегания" полоски и включения лампочки поворотника 
// такое может быть, если используется меньше половины светодиодов
// в моем случае паузы нет (pause_pov1 = 0)
int pause_pov1 = 30;

// этой паузой регулируем длительность состояния, когда все светодиоды выключены
//я определял опытным путем - включал поворотник, засекал по отдельности время ста мыргов лампочкой и ста беганий полоски, разницу делил на 100, на полученное время увеличивал или уменьшал значение переменной (в зависимости от того, отставали или убегали вперед лампочки)
int pause_pov2 = 90;

// переменная для значения ускорения
int ix;
int CountLed = 54;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(CountLed, PinLS, NEO_GRB + NEO_KHZ800);
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);

void setup() {
  pinMode(buttonPinS, INPUT_PULLUP);   
  pinMode(buttonPinD, INPUT_PULLUP);   
  pinMode(buttonPinL, INPUT_PULLUP);   
  pinMode(buttonPinR, INPUT_PULLUP);   
  
  strip.begin();
// гасим ленту
  for (int i=0; i<CountLed; i++ ) strip.setPixelColor(i, strip.Color(0,0,0));
  strip.show();

  accel.begin();
  
  accel.setRange(ADXL345_RANGE_8_G);
  accel.setDataRate(ADXL345_DATARATE_100_HZ);
}

void loop() {

// СТОПЫ: если включены  - высший приоритет   
 buttonStateS = digitalRead(buttonPinS);
 if (buttonStateS == LOW) 
 {
  sensors_event_t event; 
  accel.getEvent(&event);
  ix = event.acceleration.x;

// проверка резкого торможения  - мигающий режим
// значение 10 - это 1G, минус - торможение
  if (ix < -10) 
   {
    for (int is=0; is<15; is++ ) {
      for (int i=0; i<CountLed; i++ ) strip.setPixelColor(i, strip.Color(255,0,0));
      strip.show(); 
      delay(10 + is*10);
      for (int i=0; i<CountLed; i++ ) strip.setPixelColor(i, strip.Color(0,0,0));
      strip.show();
      delay(10 + is*3);
      buttonStateS = digitalRead(buttonPinS);
      if ( buttonStateS == HIGH ) return;
     }
   }

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

  if (buttonStateS == LOW) {
   for (int i=0; i<CountLed; i++ ) strip.setPixelColor(i, strip.Color(200,0,0));
    strip.show();
    while(buttonStateS == LOW){
      buttonStateS = digitalRead(buttonPinS);
      delay(50);
     } 
// плавно гасим
    for (int is=0; is<20; is++ ) {
    for (int i=0; i<CountLed; i++ ) strip.setPixelColor(i, strip.Color(190 - is*10,0,0));
    strip.show();
    delay(20);
    } // СТОПЫ конец
   } 
  }
  else  // если СТОПЫ выключены
  {

   // ЗАДНИЙ ХОД: если включен - средний приоритет
    buttonStateD = digitalRead(buttonPinD);
    if (buttonStateD == LOW) {
    for (int i=0;   i<CountLed;  i++ ) strip.setPixelColor(i, strip.Color(255,255,255));
    for (int i=0; i<CountLed; i++ ) strip.setPixelColor(i, strip.Color(255,255,255));
    strip.show();
    while(buttonStateD == LOW){
      buttonStateD = digitalRead(buttonPinD);
      delay(50);
     } 
//плавно гасим 
     for (int is=0; is<16; is++ ) {
     for (int i=0;   i<CountLed;  i++ ) strip.setPixelColor(i, strip.Color(60 - is*4,60 - is*4,60 - is*4));
     for (int i=0; i<CountLed; i++ ) strip.setPixelColor(i, strip.Color(60 - is*4,60 - is*4,60 - is*4));
     strip.show();
     delay(10);
     }
    }

    buttonStateL = digitalRead(buttonPinL);
    buttonStateR = digitalRead(buttonPinR);

//  если включена аварийка
    if (buttonStateL == LOW && buttonStateR == LOW) {
      for (int il=0; il<CountLed/2;  il++ ) {
       strip.setPixelColor(CountLed/2-il-1, strip.Color(103,31,0));
       strip.setPixelColor(il+CountLed/2, strip.Color(103,31,0));
       strip.show();
       delay(pause_pov1);
      }
      for (int il=0; il<CountLed/2; il++ ) {
       strip.setPixelColor(CountLed/2-il-1, strip.Color(0,0,0));
       strip.setPixelColor(il+CountLed/2, strip.Color(0,0,0));
       strip.show();
       delay(pause_pov1);
      }
    delay(pause_pov2);
    }

// если включен ЛЕВЫЙ ПОВОРОТНИК
    if (buttonStateL == LOW && buttonStateR == HIGH) {
      for (int il=0; il<CountLed/2; il++ ) {
        strip.setPixelColor(il+CountLed/2, strip.Color(103,31,0));
        strip.show();
        delay(pause_pov1);
       }
       for (int il=0; il<CountLed/2; il++ ) {
        strip.setPixelColor(il+CountLed/2, strip.Color(0,0,0));
        strip.show();
        delay(pause_pov1);
      }
      delay(pause_pov2);
     }
// если включен ПРАВЫЙ ПОВОРОТНИК
    if (buttonStateL == HIGH && buttonStateR == LOW) {
     for (int il=0; il<CountLed/2; il++ ) {
        strip.setPixelColor(CountLed/2-il-1, strip.Color(103,31,0));
        strip.show();
        delay(pause_pov1);
      }
     for (int il=0; il<CountLed/2; il++ ) {
       strip.setPixelColor(CountLed/2-il-1, strip.Color(0,0,0));
       strip.show();
       delay(pause_pov1);
     }
     delay(pause_pov2);
    } //правый поворотник конец
     
  } //конец условия else Стоп

// задержка для следующего опроса датчиков
  delay(10);
 }

? Дважды причём …

Логику программы надо менять.
Не должно быть глухих циклов без опроса состояния кнопок внутри !

А можете скинуть пример скетча с правильной логикой? Попытаюсь подстроить.

Этот код невозможно “подстроить”. Его надо переписывать полностью

Да почему невозможно? Я же примерно понимаю как работает программа, какие мне библиотеки нужны для адресной ленты, как переменные назначать, как пины определять для ввода вывода. Просто нужен пример кода.

for (i = 1; 55 > i; ++i) {
  if (buttonIsActive(btChangeMode)) { break; }
  stripe.setPixelColor(i-1, BLACK);
  stripe.setPixelColor(i, WHITE);
}

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

:man_shrugging: не не знаю…цикл какой то странный. Для чего он мне?

Сейчас нарисую.

Вы писали “Просто нужен пример кода”.

Вы же просили помочь изменить код - вот sadman1 и показал вам, что в КАЖДОМ цикле надо на каждой итерации проверять условие, которое было перед входом в этот цикл и если оно уже не верно - выходить !

Это касательно именно ПЕРЕДЕЛКИ вашего кода.


Примерно накидал. Отличается немного от того что писал в начале. Но не суть. Самое главное, это понять мне, как прерывать одно действие и выполнять другое.

А, внутри цикла проверять! Ну вроде доходит немного

Мне вот не ясен вопрос - при движении задним ходом и включенном поворотнике или аварийке - моргать ДХО не надо ???

Если отойти в сторону о вашего кода …

Самый простой способ - повесить все сигналы от периферии на один порт и читать состояние всех сигналов одной командой status = PIN… и потом в case уже решать чем и как моргать. Вызов strip.show вынести в отдельную функцию и в ней проверять, если status изменился с момента запуска процессора - идти на 0x0000 и перезапускать процессор !!!
Или если вы знаете что-нибудь про PCINT, то не трогать strip.show, а сделать сброс процессора именно в этом прерывании.

Код будет почти как ваш и не надо будет в каждом цикле на каждой итерации что то проверять.

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

Ну что, кто нибудь возьмётся за один килорубль?)) Проект надо добить, времени нет. Вотсап 89235632863
Эл почта myzhev.pavel@gmail.com

Есть старый анекдот. Немного неприличный, но компания у нас мужская.

Приходят в бордель два укурка. Подходят к мадам.
-Мадам! У нас всего 20 долларов, что мы можем иметь за свои деньги?
-За 20 долларов вы таки можете отсосать друг другу вон в тех кустах!
Укурки уходят и возвращаются через несколько минут.
-Мадам! Кому нужно отдать деньги?


Почему мне вспомнился этот анекдот? Не знаю… :wink:

Анекдот смешной. Но как мне кажется, но как мне кажется, он переоценивает сложность задачи, которую требуется выполнить опытному, допустим, знающему программисту по отношению к затратам. Задачу, алгоритм программы которой можно описать одним предложением: Есть 4 пина и адресная лента. Нужно мигать различной анимацией, в зависимости от состоянием пинов, с приоритетом на указатели поворотов. Я уже думал сделать вызовом функций, а состояние пинов опрашивать в лупе и там же условия. Но мало очень понимания в том как работает код…