Ардуина зависает при работе с адресной лентой

rline
Offline
Зарегистрирован: 02.03.2022

Товарищи, нужна помощь. Сразу скажу, я совсем новичок и это мой первый проект, поэтому если можно объясните на пальцах. В общем задумка следующая: при срабатывании датчика движения включается адресная светодиодная лента на 60 светодиодов. Сначала по три светодиода бегут влево и вправо от середины к концам, затем от концов к середине поочерёдно загорается каждый светодиод с интервалом 30 мс.

Изначально всё было на delay, затем я попытался от него избавиться с помощью millis. Кое где ещё есть delay но не обращайте внимания. Вот код.

// датчик движения
int pirPin = 3; // назначение пина для мини ИК датчика
int value ;// переменная для хранения положения датчика
// лента
#define LED_PIN 2     // пин подключения ленты
#define LED_NUM 60    // количество светодиодов
  int countR=30;
  int countL=29;
  int mode=2; // режим движения 0 - от середины к краю, 1 - от края к середине, 2 - выключение
  int i;
  long previousMillis;  // храним время последнего переключения светодиода
  long interval = 30; //скорость движения светодиода
  long worktime = 20000; //время работы ленты до выключения
  
#include "FastLED.h"
CRGB leds[LED_NUM];
void setup() {
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, LED_NUM);
  FastLED.setBrightness(50);
  Serial.begin (9600);

  Serial.print("countR=");
Serial.println(countR);
Serial.print("mode=");
Serial.println(mode);

pinMode (pirPin, INPUT) ; // пин датчика работает как вход
}

void loop () {
 previousMillis = millis();
value = digitalRead (pirPin) ;// чтение значения с датчика
if (value == HIGH) // когда с ИК сенсора появляется высокий уровень, светодиод загорается
  {mode=0;
    Serial.println("movement");}
  else
  {
   mode=2;
  Serial.println("no movement");
  }
  //delay(1000);


if (mode==2) // выключение
  {
  for (int i = 0; i < LED_NUM; i++)
  leds[i] = CHSV(0, 0, 0);
  FastLED.show();
  //mode=1;
  }  


if (mode==0) // от середины до конца
{do {
    if (millis() - previousMillis == interval  )
  {leds[countR] = CHSV(48, 100, 50);
  leds[countL] = CHSV(48, 100, 50);
  
  leds[countR - 3] = CHSV(0, 0, 0);
  leds[countL + 3] = CHSV(0, 0, 0);
   Serial.println(millis() - previousMillis);
  FastLED.show();
  //delay (30);
  countR++;
  countL--;
  previousMillis = millis();
  }
   // Serial.print("countR=");
//Serial.println(countR);
}
  while (countR < LED_NUM);
mode=1;
}
Serial.print("mode=");
Serial.println(mode);


if (mode==1) // от конца к середине
  {
  do {
  leds[countR] = CHSV(48, 100, 50);
  leds[countL] = CHSV(48, 100, 50);
  //leds[countR + 1] = CHSV(0, 0, 0);
  FastLED.show();
  delay (30);
  countR--;
  countL++;
  //Serial.print("countR=");
  //Serial.println(countR);
  }
  while (countR > LED_NUM/2-1);
  delay(20000); // сколько времени будет включенной
  }
//if (countR==30)  
{mode=2;};




Serial.print("countR=");
Serial.println(countR);
Serial.print("mode=");
Serial.println(mode);
//mode=2;


}

В общем работает через раз. Иногда может нормально отработать несколько раз подряд. Иногда может зависнуть как только светодиоды побежали от середины к концам. Иногда может зависнуть когда все светодиоды включены и остаётся так гореть. Лечится ресетом. Думал, что проблема в питании. Ардуина изначально подключена от компа через usb свитч с дополнительным питанием. Подключил отдельный БП на 40А, но ничего не изменилось. Подскажите пожалуйста в какую сторону копать.

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

31 строка не на своем месте как минимум

AndreyD
AndreyD аватар
Offline
Зарегистрирован: 07.10.2018

rline пишет:

Я немного переделал под мою ESP и ленту (кол-во светодиодов, пин ленты, строка 15 кода). Убрал чтение ИК датчика. 

Изменил блок "от середины до конца". 

// датчик движения
int pirPin = 3; // назначение пина для мини ИК датчика
int value = HIGH;// переменная для хранения положения датчика
// лента
#define LED_PIN D8     // пин подключения ленты
#define LED_NUM 50    // количество светодиодов
  int countR=25;
  int countL=24;
  int mode=2; // режим движения 0 - от середины к краю, 1 - от края к середине, 2 - выключение
  int i;
  unsigned long previousMillis;  // храним время последнего переключения светодиода
  unsigned long interval = 500; //скорость движения светодиода
  unsigned long worktime = 20000; //время работы ленты до выключения

#define FASTLED_ESP8266_RAW_PIN_ORDER //под ESP
#include "FastLED.h"
CRGB leds[LED_NUM];
void setup() {
  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, LED_NUM);
  FastLED.setBrightness(50);
  Serial.begin (9600);

  Serial.print("countR=");
Serial.println(countR);
Serial.print("mode=");
Serial.println(mode);

pinMode (pirPin, INPUT) ; // пин датчика работает как вход
}

void loop () {
//value = digitalRead (pirPin) ;// чтение значения с датчика
if (value == HIGH) // когда с ИК сенсора появляется высокий уровень, светодиод загорается
  {mode=0;
    Serial.println("movement");}
  else
  {
   mode=2;
  Serial.println("no movement");
  }
  //delay(1000);


if (mode==2) // выключение
  {
  for (int i = 0; i < LED_NUM; i++)
  leds[i] = CHSV(0, 0, 0);
  FastLED.show();
  //mode=1;
  }  


if (mode==0) // от середины до конца
  if (millis() - previousMillis >= interval){
    previousMillis = millis();
  
    leds[countR] = CHSV(48, 100, 50);
    leds[countL] = CHSV(48, 100, 50);
  
    leds[countR - 3] = CHSV(0, 0, 0);
    leds[countL + 3] = CHSV(0, 0, 0);
    Serial.println(millis() - previousMillis);
    FastLED.show();
    //delay (30);
    if (countR < LED_NUM){
      countR++;
      countL--;
    } else
      mode=1;
   // Serial.print("countR=");
   //Serial.println(countR);
  }

//Serial.print("mode=");
//Serial.println(mode);

if (mode==1) // от конца к середине
  {
                                         
  do {
  leds[countR] = CHSV(48, 100, 50);
  leds[countL] = CHSV(48, 100, 50);
  //leds[countR + 1] = CHSV(0, 0, 0);
  FastLED.show();
  delay (30);
  countR--;
  countL++;
  //Serial.print("countR=");
  //Serial.println(countR);
  }
  while (countR > LED_NUM/2-1);
  delay(20000); // сколько времени будет включенной
  }
//if (countR==30)  
{mode=2;};




Serial.print("countR=");
Serial.println(countR);
Serial.print("mode=");
Serial.println(mode);
//mode=2;


}

 

rline
Offline
Зарегистрирован: 02.03.2022

Komandir пишет:

31 строка не на своем месте как минимум

 

Подскажите куда её перенести.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018