Связь Arduino по Bluetooth замедляется из-за цикла for!

Я отправляю данные в Arduino через мобильное приложение. До сих пор весь код работал последовательно.

#include <SoftwareSerial.h>
#define FASTLED_INTERNAL
#include <FastLED.h>
#define NUM_LEDS_PER_STRIP 48
SoftwareSerial bluetooth(53,52);    // TX, RX
int bar_analog=0;                                    
int head_analog=0;
int bar_anim=0;
int anim=0;
int motor_speed=1;
int direct=0;
int level=0;
CRGB strip1[NUM_LEDS_PER_STRIP];
CRGB strip2[NUM_LEDS_PER_STRIP];
CRGB strip3[NUM_LEDS_PER_STRIP];
CRGB strip4[NUM_LEDS_PER_STRIP];
boolean debug = true;
int IN1a=49;
int IN2a=48;
int PWM1=3;
int IN1b=22;
int IN2b=23;
int PWM2=4;
int hiz=100;
int PWM_kare=2;
int INA_kare = 51;  
int INB_kare = 50; //LED '+'sı OUTPUT B'de olduğu için INB'yi HIGH yapıyoruz.
void m1_cw() {
digitalWrite(IN1a,HIGH);
digitalWrite(IN2a,LOW);
analogWrite(PWM1,hiz);
}
void m1_ccw() {
digitalWrite(IN1a,LOW);
digitalWrite(IN2a,HIGH);
analogWrite(PWM1,hiz);
}
void m2_cw() {
digitalWrite(IN1b,HIGH);
digitalWrite(IN2b,LOW);
analogWrite(PWM2,hiz);
}
void m2_ccw() {
digitalWrite(IN1b,LOW);
digitalWrite(IN2b,HIGH);
analogWrite(PWM2,hiz);
}
void m1_stop() {
digitalWrite(IN1a,LOW);
digitalWrite(IN2a,LOW);
analogWrite(PWM1,0);
}
void m2_stop() {
digitalWrite(IN1b,LOW);
digitalWrite(IN2b,LOW);
analogWrite(PWM2,0);
}
void mast_up() {
digitalWrite(24,HIGH);
digitalWrite(25,LOW);
}
void mast_down() {
digitalWrite(24,LOW);
digitalWrite(25,HIGH);
}
void mast_stop() {
digitalWrite(24,LOW);
digitalWrite(25,LOW);
}
void kare() {
analogWrite(PWM_kare,head_analog);
digitalWrite(INB_kare, HIGH);
digitalWrite(INA_kare, LOW);
}
void strip_dim() {
for(int i=0;i<256;i=i+10) {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(i); //Парлаклык
strip1[j] = CRGB( 100, 172, 45); //leds[0] относится к 1-му светодиоду на полосе. (Вот переменная светодиодов.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show(); 
}}
for(int i=255;i>=0;i=i-10) {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(i); //Яркость
strip1[j] = CRGB( 100, 172, 45); //leds[0] относится к 1-му светодиоду на полосе. (Вот переменная светодиодов.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show(); 
}}
}
void strip_stop() {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(0); //Яркость
strip1[j] = CRGB( 100, 172, 45); //leds[0] относится к 1-му светодиоду на полосе. (Вот переменная светодиодов.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show(); 
}
}
void setup() {
  Serial.begin(9600);                              
  bluetooth.begin(9600);                           
  Serial.println("Program is starting...");              
  Serial.println("by Berke Ogulcan Parlak"); 
pinMode(IN1a,OUTPUT);
pinMode(IN2a,OUTPUT);
pinMode(IN1b,OUTPUT);
pinMode(IN2b,OUTPUT);
pinMode(PWM1,OUTPUT);
pinMode(PWM2,OUTPUT);
pinMode(24,OUTPUT);
pinMode(25,OUTPUT);
pinMode(INA_kare, OUTPUT);
pinMode(INB_kare, OUTPUT);
pinMode(PWM_kare, OUTPUT);
digitalWrite(IN1a,LOW);
digitalWrite(IN2a,LOW);
digitalWrite(IN1b,LOW);
digitalWrite(IN2b,LOW);
digitalWrite(PWM1,LOW);
digitalWrite(PWM2,LOW);  
digitalWrite(24,LOW);
digitalWrite(25,LOW);
digitalWrite(INA_kare, LOW);
digitalWrite(INB_kare, LOW);
digitalWrite(PWM_kare, LOW); 
FastLED.addLeds<NEOPIXEL, 26>(strip1, NUM_LEDS_PER_STRIP); 
FastLED.addLeds<NEOPIXEL, 28>(strip2, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 30>(strip3, NUM_LEDS_PER_STRIP);
FastLED.addLeds<NEOPIXEL, 32>(strip4, NUM_LEDS_PER_STRIP);
FastLED.setBrightness(0); 
}

void loop() {
  while (bluetooth.available())                    
    {                                                
      bar_analog = bluetooth.parseInt();              
      head_analog = bluetooth.parseInt();
      bar_anim = bluetooth.parseInt();
      anim = bluetooth.parseInt();
      motor_speed = bluetooth.parseInt();
      direct = bluetooth.parseInt();
      level = bluetooth.parseInt();
      if (debug) {                                  
        Serial.print("Bar Brightness: ");                        
        Serial.println(bar_analog);
        Serial.print("Bar Animation Type: ");
        Serial.println(bar_anim);
        Serial.print("Headlight Brightness: ");
        Serial.println(head_analog);
        Serial.print("Strip Animation Type: ");
        Serial.println(anim);
        Serial.print("Motor Speed Level: ");
        Serial.println(motor_speed);
        Serial.print("Direction: ");
        Serial.println(direct);
        Serial.print("Mast Goes: ");
        Serial.println(level);
        Serial.println("--------------------------------");
      }
      if (bluetooth.read() == '\n') {               

  }} 
        kare();            
       if(direct==1) { //илери
  m1_ccw();
  m2_ccw(); 
  }
else if(direct==2) { //geri
  m1_cw();
  m2_cw(); 
  }
else if(direct==3) { //соль
  m1_ccw();
  m2_cw(); 
  }
else if(direct==4) { //sağ
  m1_cw();
  m2_ccw(); 
  }
else if(direct==0) { // прочно
  m1_stop();
  m2_stop(); 
  }
if(level==1) { //мачта юкары
  mast_up(); 
  }
else if(level==2) { //мачта aşağı
  mast_down(); 
  }
else if(level==0) { //долговечность мачты
  mast_stop(); 
  }
if(anim==2) {
  strip_dim();
  }
else if(anim==0) {
  strip_stop();
  }
  }

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

void strip_dim() {
for(int i=0;i<256;i=i+10) {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(i); //Парлаклык
strip1[j] = CRGB( 100, 172, 45); //leds[0] şeritteki 1.Ledi ifade eder. (Бурадаки ведет переменную дир.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show(); 
}}
for(int i=255;i>=0;i=i-10) {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(i); //Яркость
strip1[j] = CRGB( 100, 172, 45); //leds[0] относится к 1-му светодиоду на полосе. (Вот переменная светодиодов.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show(); 
}}
}
void strip_stop() {
for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
FastLED.setBrightness(0); //Яркость
strip1[j] = CRGB( 100, 172, 45); //leds[0] относится к 1-му светодиоду на полосе. (Вот переменная светодиодов.)
strip2[j] = CRGB( 100, 172, 45);
strip3[j] = CRGB( 100, 172, 45);
strip4[j] = CRGB( 100, 172, 45);
FastLED.show(); 
}
}

, 👍1

Обсуждение

Почему вы используете software serial на Меге?!?!, @Majenko


2 ответа


1

Вы создаете экземпляр класса много раз (25 * 48 * 8 + 255 * 48 * 4 = 58 560 раз), и это дорогостоящая операция.

Вместо этого создайте один экземпляр (перед циклами for) и используйте его для назначения везде, где вам это нужно.

Что-то вроде;

CRGB crgb( 100, 172, 45);

for(int i=0;i<256;i=i+10) {
    for(int j=0;j<NUM_LEDS_PER_STRIP;j++) {
        FastLED.setBrightness(i);
        strip1[j] = crgb;
        ...
,

Хорошая точка зрения. Однако, если setBrightness выполняет последовательную связь, > 58 000 итераций цикла по-прежнему будут занимать значительное количество времени., @Duncan C

@DuncanC Верно, но я не хотел менять функциональность., @Michel Keijzers

Спасибо за комментарий, но изменений нет., @bopele


3

Ваша главная проблема в том, что FastLED отключает прерывания при отправке данных. Это происходит потому, что синхронизация имеет решающее значение, а при включенных прерываниях синхронизация будет полностью нарушена.

Поэтому, когда FastLED постоянно работает в цикле, очень мало времени, когда разрешены прерывания для приема через SoftwareSerial.

В отличие от настоящего UART, который может получать и сохранять байты перед инициированием прерывания, SoftwareSerial инициирует прерывание в начале получения байта, и эта процедура прерывания используется для фактического приема. Таким образом, если прерывания не включены в тот момент, когда байт начинает поступать на вывод GPIO, он не может начать прием, поэтому он пропускает байт, и в итоге получается беспорядок.

Поскольку вы используете Arduino Mega, у вас нет абсолютно никаких причин использовать SoftwareSerial. У вас есть много реальных аппаратных UART, доступных для подключения вашего Bluetooth-устройства, к которому вы сможете получить байт, пока FastLED отправляет данные (пока он не отправляет данные слишком долго...).

,

Проголосовал за ваш комментарий, и ваш ответ вызвал у меня вопрос, связанный с вашим ответом. Я надеюсь, что вы можете взглянуть на него вкратце. https://arduinoprosto.ru/q/67381/does-dmxserial-stops-interrupts, @Michel Keijzers

Прежде всего, спасибо за ваш ответ, но я мало что знаю об UART. Какие изменения нужно внести в код, чтобы использовать UART вместо SoftwareSerial?, @bopele