Помогите доработать функцию

Rasberg
Offline
Зарегистрирован: 21.03.2022

Добрый день!
Помогите плез доработать функцию бегущей строки на светодиодной адресной матрице!

Суть в том, что в программировании очень слаб, проект для личного пользования. Есть функция вывода бегущей строки - runText. В Loop - прописано условие приема кода с ИК пульта (т.е. если пришел нужный HEX код - запускаем runText). Проблема в том, что при нажатии на кнопку пульта - функция выполняется 1 раз, т.е. текст смещается ровно на 1 пиксель. А надо чтоб надпись проигралась до конца, и только потом ловила следующий код с пульта. Пытался играть с While - но происходит полная ерунда... 

#include <FastLED.h>
#include "font.h"
#include <IRremote.h> // подключаем библиотеку для IR приемника

#define DATA_PIN 2

#define NUM_LEDS 256
#define MATRIX_WIDTH 32            
#define MATRIX_HEIGHT 8 
#define BRIGHTNESS 200

IRrecv irrecv(11); // указываем пин, к которому подключен IR приемник
decode_results results;

//константы и переменные для работы с текстом
const String fontNumStr="0123456789 !,.:;?";
const String fontLetStr="АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
uint16_t curPixel;
uint8_t curX;
uint8_t curY;
unsigned long timer;
CRGB leds[NUM_LEDS];

//переменные для работы с бегущей строкой
uint16_t lineStart=0;//с какого столбца строки начинаем вопроизведение текста
uint16_t lineFin=0;//каким столбцом строки заканчиваем вопроизведение текста
uint8_t startRunLineX=MATRIX_WIDTH-1;//столбец X начала отрисовки бегущей строки


void setup() { 
    irrecv.enableIRIn();  // запускаем прием инфракрасного сигнала
    FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
    FastLED.setBrightness(BRIGHTNESS);//0-255
    
    Serial.begin (9600);

     
    //вывод статического текста
    //showText("123", 2, 0, 0xFF0000);
    //showText("АБВГ", 0, 8, 0x0000FF);
    FastLED.show();
}
void loop() { 

  if ( irrecv.decode( &results )) { // если данные пришли
    Serial.println(results.value, HEX);
    switch ( results.value ) {
    case 0xFFA25D:
         runText("СПАСИБО!", 0, 0x32CD32, 50);
        break;
        case 0xE318261B:
         runText("СПАСИБО!", 0, 0x32CD32, 50);
        break;
    case 0xFF629D:
         runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
         case 0x462CAD38:
         runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
         case 0x511DBB:
         runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
         case 0xFF:
         results.value=0;
        break;
    }    
      irrecv.resume(); // принимаем следующую команду  
  }
}
void setPixel (byte x, byte y, uint32_t color) {
   uint16_t curLed;
   if (x%2==0){
      curLed=MATRIX_HEIGHT*x+y;
   }
   else {
      curLed=(MATRIX_HEIGHT*(x+1)-1)-y; 
   }
   
   leds[curLed]=color;
}

byte getPixel (uint8_t vertPixels, byte startY, uint32_t color) {
   byte pixel;
   for (int k = 7; k >=0; k--) {//
        pixel = ((vertPixels >> k) & 0x01);
        if (pixel==1){
            setPixel (curX, curY, color);
        }
        curY++;
    }
    curY=startY;
    curX++;
}
void showText(String text, byte startX, byte startY, uint32_t color){//вывод статического текста
    int i;
    byte n;
    bool isRusLetter=false;
    byte vertPixels;
   
    curX=startX;
    curY=startY;
   
    for (i=0;i<text.length();i++){
        if (int(text[i])>=0){//цифры и символы
            n=fontNumStr.indexOf(text[i]);
            for (byte j=0;j<4;j++){
               vertPixels=pgm_read_byte(&(font7num[n][j]));
               if ((j==0)||(vertPixels>0)){//только первая колонка и не пустые колонки
                   getPixel (vertPixels, startY, color);
               }
                if (curX>=MATRIX_WIDTH) {
                    break;  
                }
            }
            curX++;
            if (curX>=MATRIX_WIDTH) {
                break;  
            }
        }
        else {//русские буквы
            if (isRusLetter==true){
                isRusLetter=false;
                n=112+int(text[i]);
                for (byte j=0;j<7;j++){
                     vertPixels=pgm_read_byte(&(font7let[n][j]));

                     if ((j==0)||(vertPixels>0)||((n==27)&&(j<6))){//только первая колонка, не пустые колонки и исключения буквы Ы
                         getPixel (vertPixels, startY, color);
                     }
                      if (curX>=MATRIX_WIDTH) {
                          break;  
                      }

                }
                curX++;
                if (curX>=MATRIX_WIDTH) {
                    break;  
                }
            }
            else {
               isRusLetter=true;
            }
        }
    }
}

void runText(String text, byte startY, uint32_t color, int speedText){//вывод бегущей строки
    int i;
    byte n;
    bool isRusLetter=false;
    byte vertPixels;
    
    curY=startY;
    curX=startRunLineX;
    FastLED.clear();

    int l=0;
    for (i=0;i<text.length();i++){
        if (int(text[i])>0){
            n=fontNumStr.indexOf(text[i]);
            for (byte j=0;j<4;j++){
               vertPixels=pgm_read_byte(&(font7num[n][j]));
               if ((j==0)||(vertPixels>0)){//только первая колонка и не пустые колонки
                   if ((l>=lineStart)&&(l<=lineFin)){
                     getPixel (vertPixels, startY, color);
                   }

                   l++;
               }
               if (j==3){//в конце каждого символа добавляем пробел
                  if ((l>=lineStart)&&(l<=lineFin)){
                      curX++;
                   }
                   l++;
               }
             }
        }
        else {
            if (isRusLetter==true){
                isRusLetter=false;
                n=112+int(text[i]);
                for (byte j=0;j<7;j++){
                     vertPixels=pgm_read_byte(&(font7let[n][j]));

                     if ((j==0)||(vertPixels>0)||((n==27)&&(j<6))){//только первая колонка, не пустые колонки или буква Ы
                         if ((l>=lineStart)&&(l<=lineFin)){
                            getPixel (vertPixels, startY, color);
                         }
                         l++;
                     }
                      if (j==6){//в конце каждого символа добавляем пробел
                          if ((l>=lineStart)&&(l<=lineFin)){
                              curX++;
                           }
                           l++;
                       }
                }
            }
            else {
               isRusLetter=true;
            }
        }
    }
    lineFin++;
    if (lineFin>=MATRIX_WIDTH) {
        lineStart++;  
    }

    if (startRunLineX>0){//каждый кадр смещаем начало отрисовки бегущей строки на 1 пиксель влево от правого края матрицы
        startRunLineX--;
    }

   /* if (lineStart>l){//воспроизводим с начала
      l=0;
      lineStart=0;
      lineFin=0;
      startRunLineX=MATRIX_WIDTH-1;

    }*/
    FastLED.show();
    delay(speedText);
}

 


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

Одного цикла не хватает внутри runtext. Без номеров строк хз как ориентироваться.

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Вставляйте программу с номерами строк, чтобы было на что ссылаться

#include <FastLED.h>
#include "font.h"
#include <IRremote.h> // подключаем библиотеку для IR приемника

#define DATA_PIN 2

#define NUM_LEDS 256
#define MATRIX_WIDTH 32            
#define MATRIX_HEIGHT 8 
#define BRIGHTNESS 200

IRrecv irrecv(11); // указываем пин, к которому подключен IR приемник
decode_results results;

//константы и переменные для работы с текстом
const String fontNumStr="0123456789 !,.:;?";
const String fontLetStr="АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
uint16_t curPixel;
uint8_t curX;
uint8_t curY;
unsigned long timer;
CRGB leds[NUM_LEDS];

//переменные для работы с бегущей строкой
uint16_t lineStart=0;//с какого столбца строки начинаем вопроизведение текста
uint16_t lineFin=0;//каким столбцом строки заканчиваем вопроизведение текста
uint8_t startRunLineX=MATRIX_WIDTH-1;//столбец X начала отрисовки бегущей строки


void setup() { 
    irrecv.enableIRIn();  // запускаем прием инфракрасного сигнала
    FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
    FastLED.setBrightness(BRIGHTNESS);//0-255
    
    Serial.begin (9600);

     
    //вывод статического текста
    //showText("123", 2, 0, 0xFF0000);
    //showText("АБВГ", 0, 8, 0x0000FF);
    FastLED.show();
}
void loop() { 

  if ( irrecv.decode( &results )) { // если данные пришли
    Serial.println(results.value, HEX);
    switch ( results.value ) {
    case 0xFFA25D:
         runText("СПАСИБО!", 0, 0x32CD32, 50);
        break;
        case 0xE318261B:
         runText("СПАСИБО!", 0, 0x32CD32, 50);
        break;
    case 0xFF629D:
         runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
         case 0x462CAD38:
         runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
         case 0x511DBB:
         runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
         case 0xFF:
         results.value=0;
        break;
    }    
      irrecv.resume(); // принимаем следующую команду  
  }
}
void setPixel (byte x, byte y, uint32_t color) {
   uint16_t curLed;
   if (x%2==0){
      curLed=MATRIX_HEIGHT*x+y;
   }
   else {
      curLed=(MATRIX_HEIGHT*(x+1)-1)-y; 
   }
   
   leds[curLed]=color;
}

byte getPixel (uint8_t vertPixels, byte startY, uint32_t color) {
   byte pixel;
   for (int k = 7; k >=0; k--) {//
        pixel = ((vertPixels >> k) & 0x01);
        if (pixel==1){
            setPixel (curX, curY, color);
        }
        curY++;
    }
    curY=startY;
    curX++;
}
void showText(String text, byte startX, byte startY, uint32_t color){//вывод статического текста
    int i;
    byte n;
    bool isRusLetter=false;
    byte vertPixels;
   
    curX=startX;
    curY=startY;
   
    for (i=0;i<text.length();i++){
        if (int(text[i])>=0){//цифры и символы
            n=fontNumStr.indexOf(text[i]);
            for (byte j=0;j<4;j++){
               vertPixels=pgm_read_byte(&(font7num[n][j]));
               if ((j==0)||(vertPixels>0)){//только первая колонка и не пустые колонки
                   getPixel (vertPixels, startY, color);
               }
                if (curX>=MATRIX_WIDTH) {
                    break;  
                }
            }
            curX++;
            if (curX>=MATRIX_WIDTH) {
                break;  
            }
        }
        else {//русские буквы
            if (isRusLetter==true){
                isRusLetter=false;
                n=112+int(text[i]);
                for (byte j=0;j<7;j++){
                     vertPixels=pgm_read_byte(&(font7let[n][j]));

                     if ((j==0)||(vertPixels>0)||((n==27)&&(j<6))){//только первая колонка, не пустые колонки и исключения буквы Ы
                         getPixel (vertPixels, startY, color);
                     }
                      if (curX>=MATRIX_WIDTH) {
                          break;  
                      }

                }
                curX++;
                if (curX>=MATRIX_WIDTH) {
                    break;  
                }
            }
            else {
               isRusLetter=true;
            }
        }
    }
}

void runText(String text, byte startY, uint32_t color, int speedText){//вывод бегущей строки
    int i;
    byte n;
    bool isRusLetter=false;
    byte vertPixels;
    
    curY=startY;
    curX=startRunLineX;
    FastLED.clear();

    int l=0;
    for (i=0;i<text.length();i++){
        if (int(text[i])>0){
            n=fontNumStr.indexOf(text[i]);
            for (byte j=0;j<4;j++){
               vertPixels=pgm_read_byte(&(font7num[n][j]));
               if ((j==0)||(vertPixels>0)){//только первая колонка и не пустые колонки
                   if ((l>=lineStart)&&(l<=lineFin)){
                     getPixel (vertPixels, startY, color);
                   }

                   l++;
               }
               if (j==3){//в конце каждого символа добавляем пробел
                  if ((l>=lineStart)&&(l<=lineFin)){
                      curX++;
                   }
                   l++;
               }
             }
        }
        else {
            if (isRusLetter==true){
                isRusLetter=false;
                n=112+int(text[i]);
                for (byte j=0;j<7;j++){
                     vertPixels=pgm_read_byte(&(font7let[n][j]));

                     if ((j==0)||(vertPixels>0)||((n==27)&&(j<6))){//только первая колонка, не пустые колонки или буква Ы
                         if ((l>=lineStart)&&(l<=lineFin)){
                            getPixel (vertPixels, startY, color);
                         }
                         l++;
                     }
                      if (j==6){//в конце каждого символа добавляем пробел
                          if ((l>=lineStart)&&(l<=lineFin)){
                              curX++;
                           }
                           l++;
                       }
                }
            }
            else {
               isRusLetter=true;
            }
        }
    }
    lineFin++;
    if (lineFin>=MATRIX_WIDTH) {
        lineStart++;  
    }

    if (startRunLineX>0){//каждый кадр смещаем начало отрисовки бегущей строки на 1 пиксель влево от правого края матрицы
        startRunLineX--;
    }

   /* if (lineStart>l){//воспроизводим с начала
      l=0;
      lineStart=0;
      lineFin=0;
      startRunLineX=MATRIX_WIDTH-1;

    }*/
    FastLED.show();
    delay(speedText);
}

 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018
#include <FastLED.h>
#include "font.h"
#include <IRremote.h> // подключаем библиотеку для IR приемника

#define DATA_PIN 2

#define NUM_LEDS 256
#define MATRIX_WIDTH 32
#define MATRIX_HEIGHT 8
#define BRIGHTNESS 200

IRrecv irrecv(11); // указываем пин, к которому подключен IR приемник
decode_results results;

//константы и переменные для работы с текстом
const String fontNumStr = "0123456789 !,.:;?";
const String fontLetStr = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
uint16_t curPixel;
uint8_t curX;
uint8_t curY;
unsigned long timer;
CRGB leds[NUM_LEDS];

//переменные для работы с бегущей строкой
uint16_t lineStart = 0; //с какого столбца строки начинаем вопроизведение текста
uint16_t lineFin = 0; //каким столбцом строки заканчиваем вопроизведение текста
//uint8_t startRunLineX = MATRIX_WIDTH - 1; //столбец X начала отрисовки бегущей строки


void setup() {
  irrecv.enableIRIn();  // запускаем прием инфракрасного сигнала
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);//0-255

  Serial.begin (9600);


  //вывод статического текста
  //showText("123", 2, 0, 0xFF0000);
  //showText("АБВГ", 0, 8, 0x0000FF);
  FastLED.show();
}
void loop() {

  if ( irrecv.decode( &results )) { // если данные пришли
    Serial.println(results.value, HEX);
    switch ( results.value ) {
      case 0xFFA25D:
        runText("СПАСИБО!", 0, 0x32CD32, 50);
        break;
      case 0xE318261B:
        runText("СПАСИБО!", 0, 0x32CD32, 50);
        break;
      case 0xFF629D:
        runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
      case 0x462CAD38:
        runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
      case 0x511DBB:
        runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
      case 0xFF:
        results.value = 0;
        break;
    }
    irrecv.resume(); // принимаем следующую команду
  }
}
void setPixel (byte x, byte y, uint32_t color) {
  uint16_t curLed;
  if (x % 2 == 0) {
    curLed = MATRIX_HEIGHT * x + y;
  }
  else {
    curLed = (MATRIX_HEIGHT * (x + 1) - 1) - y;
  }

  leds[curLed] = color;
}

byte getPixel (uint8_t vertPixels, byte startY, uint32_t color) {
  byte pixel;
  for (int k = 7; k >= 0; k--) { //
    pixel = ((vertPixels >> k) & 0x01);
    if (pixel == 1) {
      setPixel (curX, curY, color);
    }
    curY++;
  }
  curY = startY;
  curX++;
}
void showText(String text, byte startX, byte startY, uint32_t color) { //вывод статического текста
  int i;
  byte n;
  bool isRusLetter = false;
  byte vertPixels;

  curX = startX;
  curY = startY;

  for (i = 0; i < text.length(); i++) {
    if (int(text[i]) >= 0) { //цифры и символы
      n = fontNumStr.indexOf(text[i]);
      for (byte j = 0; j < 4; j++) {
        vertPixels = pgm_read_byte(&(font7num[n][j]));
        if ((j == 0) || (vertPixels > 0)) { //только первая колонка и не пустые колонки
          getPixel (vertPixels, startY, color);
        }
        if (curX >= MATRIX_WIDTH) {
          break;
        }
      }
      curX++;
      if (curX >= MATRIX_WIDTH) {
        break;
      }
    }
    else {//русские буквы
      if (isRusLetter == true) {
        isRusLetter = false;
        n = 112 + int(text[i]);
        for (byte j = 0; j < 7; j++) {
          vertPixels = pgm_read_byte(&(font7let[n][j]));

          if ((j == 0) || (vertPixels > 0) || ((n == 27) && (j < 6))) { //только первая колонка, не пустые колонки и исключения буквы Ы
            getPixel (vertPixels, startY, color);
          }
          if (curX >= MATRIX_WIDTH) {
            break;
          }

        }
        curX++;
        if (curX >= MATRIX_WIDTH) {
          break;
        }
      }
      else {
        isRusLetter = true;
      }
    }
  }
}

void runText(String text, byte startY, uint32_t color, int speedText) { //вывод бегущей строки
  int i;
  byte n;
  bool isRusLetter = false;
  byte vertPixels;
  uint8_t startRunLineX = MATRIX_WIDTH - 1;

  curY = startY;
  do {
    curX = startRunLineX;
    FastLED.clear();

    int l = 0;
    for (i = 0; i < text.length(); i++) {
      if (int(text[i]) > 0) {
        n = fontNumStr.indexOf(text[i]);
        for (byte j = 0; j < 4; j++) {
          vertPixels = pgm_read_byte(&(font7num[n][j]));
          if ((j == 0) || (vertPixels > 0)) { //только первая колонка и не пустые колонки
            if ((l >= lineStart) && (l <= lineFin)) {
              getPixel (vertPixels, startY, color);
            }

            l++;
          }
          if (j == 3) { //в конце каждого символа добавляем пробел
            if ((l >= lineStart) && (l <= lineFin)) {
              curX++;
            }
            l++;
          }
        }
      }
      else {
        if (isRusLetter == true) {
          isRusLetter = false;
          n = 112 + int(text[i]);
          for (byte j = 0; j < 7; j++) {
            vertPixels = pgm_read_byte(&(font7let[n][j]));

            if ((j == 0) || (vertPixels > 0) || ((n == 27) && (j < 6))) { //только первая колонка, не пустые колонки или буква Ы
              if ((l >= lineStart) && (l <= lineFin)) {
                getPixel (vertPixels, startY, color);
              }
              l++;
            }
            if (j == 6) { //в конце каждого символа добавляем пробел
              if ((l >= lineStart) && (l <= lineFin)) {
                curX++;
              }
              l++;
            }
          }
        }
        else {
          isRusLetter = true;
        }
      }
    }
    lineFin++;
    if (lineFin >= MATRIX_WIDTH) {
      lineStart++;
    }

    // if (startRunLineX > 0) { //каждый кадр смещаем начало отрисовки бегущей строки на 1 пиксель влево от правого края матрицы
    //   startRunLineX--;
    // }

    /* if (lineStart>l){//воспроизводим с начала
       l=0;
       lineStart=0;
       lineFin=0;
       startRunLineX=MATRIX_WIDTH-1;

      }*/
    FastLED.show();
    delay(speedText);

  } while ((--startRunLineX) > 0)
}

(компилировать не пробовал)

А чем библиотека Adafruit_NeoMatrix не угодила ?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Теперь к тексту - у Вас задокументирована строка 217, которая возвращает значение  startRunLineX в изначальное состояние, когда цикл вывода прошел.

Далее - 209 строка, как я понимаю, должна зацикливать воспроизведение, пока startRunLineX>0, а у Вас там стоит if. Подумайте над do{}while()

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Komandir пишет:

(компилировать не пробовал)

Только после 

} while ((--startRunLineX) > 0);

Надо поставить 

startRunLineX=MATRIX_WIDTH-1;

Но ,по моему, это глупость делать эту переменную глобальной. Ее надо сделать статичной, а в подпрограмме ввести локальную переменную.

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

Да - я уже подправил.

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

Rasberg
Offline
Зарегистрирован: 21.03.2022

Хм... Все начало вести себя вроде лучше, но странно. 
При нажатии на нужную клавишу - надпись пробегает, но не до уходит до конца. А останавливается, когда первая буква достигла конца ленты. Т.е. не уходит дальше. 
И после нажатия кнопки  - ардуино очень долго не воспринимает сигналы с пульта, ловля какие-то дребезги и прочее.. Сижу пока думаю...

Rasberg
Offline
Зарегистрирован: 21.03.2022
#include <FastLED.h>
#include "font.h"
#include <IRremote.h> // подключаем библиотеку для IR приемника

#define DATA_PIN 2

#define NUM_LEDS 256
#define MATRIX_WIDTH 32
#define MATRIX_HEIGHT 8
#define BRIGHTNESS 200

IRrecv irrecv(11); // указываем пин, к которому подключен IR приемник
decode_results results;

//константы и переменные для работы с текстом
const String fontNumStr = "0123456789 !,.:;?";
const String fontLetStr = "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
uint16_t curPixel;
uint8_t curX;
uint8_t curY;
unsigned long timer;
CRGB leds[NUM_LEDS];

//переменные для работы с бегущей строкой
uint16_t lineStart = 0; //с какого столбца строки начинаем вопроизведение текста
uint16_t lineFin = 0; //каким столбцом строки заканчиваем вопроизведение текста
//uint8_t startRunLineX = MATRIX_WIDTH - 1; //столбец X начала отрисовки бегущей строки


void setup() {
  irrecv.enableIRIn();  // запускаем прием инфракрасного сигнала
  FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  FastLED.setBrightness(BRIGHTNESS);//0-255

  Serial.begin (9600);


  //вывод статического текста
  //showText("123", 2, 0, 0xFF0000);
  //showText("АБВГ", 0, 8, 0x0000FF);
  FastLED.show();
}
void loop() {

  if ( irrecv.decode( &results )) { // если данные пришли
    Serial.println(results.value, HEX);
    switch ( results.value ) {
      case 0xFFA25D:
        runText("СПАСИБО!", 0, 0x32CD32, 50);
        break;
      case 0xE318261B:
        runText("СПАСИБО!", 0, 0x32CD32, 50);
        break;
      case 0xFF629D:
        runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
      case 0x462CAD38:
        runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
      case 0x511DBB:
        runText("КОШМАР!!", 0, 0xFF8C00, 50);
        break;
      case 0xFF:
        results.value = 0;
        break;
    }
    irrecv.resume(); // принимаем следующую команду
  }
}
void setPixel (byte x, byte y, uint32_t color) {
  uint16_t curLed;
  if (x % 2 == 0) {
    curLed = MATRIX_HEIGHT * x + y;
  }
  else {
    curLed = (MATRIX_HEIGHT * (x + 1) - 1) - y;
  }

  leds[curLed] = color;
}

byte getPixel (uint8_t vertPixels, byte startY, uint32_t color) {
  byte pixel;
  for (int k = 7; k >= 0; k--) { //
    pixel = ((vertPixels >> k) & 0x01);
    if (pixel == 1) {
      setPixel (curX, curY, color);
    }
    curY++;
  }
  curY = startY;
  curX++;
}
void showText(String text, byte startX, byte startY, uint32_t color) { //вывод статического текста
  int i;
  byte n;
  bool isRusLetter = false;
  byte vertPixels;

  curX = startX;
  curY = startY;

  for (i = 0; i < text.length(); i++) {
    if (int(text[i]) >= 0) { //цифры и символы
      n = fontNumStr.indexOf(text[i]);
      for (byte j = 0; j < 4; j++) {
        vertPixels = pgm_read_byte(&(font7num[n][j]));
        if ((j == 0) || (vertPixels > 0)) { //только первая колонка и не пустые колонки
          getPixel (vertPixels, startY, color);
        }
        if (curX >= MATRIX_WIDTH) {
          break;
        }
      }
      curX++;
      if (curX >= MATRIX_WIDTH) {
        break;
      }
    }
    else {//русские буквы
      if (isRusLetter == true) {
        isRusLetter = false;
        n = 112 + int(text[i]);
        for (byte j = 0; j < 7; j++) {
          vertPixels = pgm_read_byte(&(font7let[n][j]));

          if ((j == 0) || (vertPixels > 0) || ((n == 27) && (j < 6))) { //только первая колонка, не пустые колонки и исключения буквы Ы
            getPixel (vertPixels, startY, color);
          }
          if (curX >= MATRIX_WIDTH) {
            break;
          }

        }
        curX++;
        if (curX >= MATRIX_WIDTH) {
          break;
        }
      }
      else {
        isRusLetter = true;
      }
    }
  }
}

void runText(String text, byte startY, uint32_t color, int speedText) { //вывод бегущей строки
  int i;
  byte n;
  bool isRusLetter = false;
  byte vertPixels;
  uint8_t startRunLineX = MATRIX_WIDTH - 1;

  curY = startY;
  do {
    curX = startRunLineX;
    FastLED.clear();

    int l = 0;
    for (i = 0; i < text.length(); i++) {
      if (int(text[i]) > 0) {
        n = fontNumStr.indexOf(text[i]);
        for (byte j = 0; j < 4; j++) {
          vertPixels = pgm_read_byte(&(font7num[n][j]));
          if ((j == 0) || (vertPixels > 0)) { //только первая колонка и не пустые колонки
            if ((l >= lineStart) && (l <= lineFin)) {
              getPixel (vertPixels, startY, color);
            }

            l++;
          }
          if (j == 3) { //в конце каждого символа добавляем пробел
            if ((l >= lineStart) && (l <= lineFin)) {
              curX++;
            }
            l++;
          }
        }
      }
      else {
        if (isRusLetter == true) {
          isRusLetter = false;
          n = 112 + int(text[i]);
          for (byte j = 0; j < 7; j++) {
            vertPixels = pgm_read_byte(&(font7let[n][j]));

            if ((j == 0) || (vertPixels > 0) || ((n == 27) && (j < 6))) { //только первая колонка, не пустые колонки или буква Ы
              if ((l >= lineStart) && (l <= lineFin)) {
                getPixel (vertPixels, startY, color);
              }
              l++;
            }
            if (j == 6) { //в конце каждого символа добавляем пробел
              if ((l >= lineStart) && (l <= lineFin)) {
                curX++;
              }
              l++;
            }
          }
        }
        else {
          isRusLetter = true;
        }
      }
    }
    lineFin++;
    if (lineFin >= MATRIX_WIDTH) {
      lineStart++;
    }

    // if (startRunLineX > 0) { //каждый кадр смещаем начало отрисовки бегущей строки на 1 пиксель влево от правого края матрицы
    //   startRunLineX--;
    // }

     /*if (lineStart>l){//воспроизводим с начала
       l=0;
       lineStart=0;
       lineFin=0;
       startRunLineX=MATRIX_WIDTH-1;

      }*/
    FastLED.show();
    delay(speedText);

  } while ((--startRunLineX) > 0);
  startRunLineX=MATRIX_WIDTH-1;
}

 

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

А бог его знает. Поставьте в 224 строку

Serial.println(startRunLineX);

и посмотрите чего там творится

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

Значит по осям могут быть и отрицательные числа !

https://wokwi.com/projects/329525261530825299

У вас строка объявления матрицы скорее всего будет выглядеть так:

Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(32, 8, 1, 1, PIN,
  NEO_TILE_TOP   + NEO_TILE_LEFT   + NEO_TILE_ROWS  + NEO_TILE_PROGRESSIVE+
  NEO_MATRIX_TOP + NEO_MATRIX_LEFT + NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
  NEO_GRB + NEO_KHZ800);
Rasberg
Offline
Зарегистрирован: 21.03.2022

Доходит до 6-8 строчки и выдает такую прелесть:
⸮⸮⸮Q)7⸮⸮⸮⸮⸮⸮Xv,*⸮.⸮J⸮⸮⸮/a⸮R⸮⸮b⸮c١⸮⸮⸮6⸮⸮⸮⸮E⸮⸮+⸮⸮⸮$⸮⸮ ⸮⸮⸮&b

Дальше на команды не реагирует