Бегущая строка

Тема в разделе "Глядите, что я сделал", создана пользователем Рокки1945, 27 дек 2020.

  1. Рокки1945

    Рокки1945 Гуру

    Здравствуйте!
    Ч.1
    Среда программирования - ARDUINO
    Отладка - PROTEUS
    Комплектующие - WS2812B - ATMEGA 2560
    Русский шрифт брал здесь
    Что сделано:
    Вывод строки на русском языке
    Код (C++):
    //---------------------------------------------------------//
    //библиотеки
    //Часть первая "Просто вывод строки с русским шрифтом"
    #include <avr/eeprom.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_NeoMatrix.h>
    #include <Adafruit_NeoPixel.h>
    #ifndef PSTR
    #define PSTR
    #endif
    #define PIN 25 // выход на ленту 75 вывод меги (константа)
    //---------------------------------------------------------//
    //создаём объект класса Adafruit_NeoMatrix - это для отладки в Proteuse
    Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(56, 8, PIN,NEO_MATRIX_BOTTOM + NEO_MATRIX_LEFT + NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE, NEO_GRB + NEO_KHZ800);
    /*Глобальные переменные*/
    volatile int x = matrix.width();//ширина матрицы
    volatile byte Speed = 30; //переменная скорости в цикле
    volatile char incoming[127] = {"АМПЕРКА ПРИВЕТ! ПАРОВОЗЗ ПРИВЕТ! ВОЗДУШНЫЙ БАС ПРИВЕТ! СЕРГЕЙ ПРИВЕТ!"};//массив символов максимум 127 - русская буква за 2 символа
    byte rus = 3;//на русский символ потому что занимает 2 знакоместа
    volatile byte length_buffer;//длина буфера уарта
    byte probel = 10;//пробел зависит от количества слов + 2
    unsigned long timing;//для миллис
    byte bright = 255;//яркость уарт
    byte R = 255;
    byte G = 255;
    byte B = 255;
    //---------------------------------------------------------//
    void setup() {
    matrix.begin(); matrix.setTextWrap(0); matrix.cp437(true);
    matrix.setBrightness(bright);//яркость по умолчанию
    matrix.setTextColor(matrix.Color(R, G, B));//цвет по умолчанию
    }
    //---------------------------------------------------------//
    void loop() {
      //
    if (millis() - timing > Speed){timing = millis(); {matrix.fillScreen(0);matrix.setCursor(x,0);matrix.print(utf8rus(incoming));length_buffer = strlen(incoming) + probel;if (--x < -(length_buffer * rus)) {x = matrix.width();} matrix.show();}}

    }
    Код (C++):
    #define maxString 127//длина максимальная приёма символов
    char target[maxString + 1] = "";

    char *utf8rus(char *source)

    {
      int i,j,k;
      unsigned char n;
      char m[2] = { '0', '\0' };
      strcpy(target, ""); k = strlen(source); i = j = 0;


      while (i < k) {

        n = source[i]; i++;

        if (n >= 0xC0) {

          switch (n) {

            case 0xD0: {

              n = source[i]; i++;

              if (n == 0x81) { n = 0xA8; break; }

              if (n >= 0x90 && n <= 0xBF) n = n + 0x30;

              break;

            }

            case 0xD1: {

              n = source[i]; i++;

              if (n == 0x91) { n = 0xB8; break; }

              if (n >= 0x80 && n <= 0x8F) n = n + 0x70;

              break;

            }

          }

        }


        m[0] = n; strcat(target, m);

        j++; if (j >= maxString) break;

      }

      return target;

    }

     
    Tomasina, Airbus, SergeiL и ещё 1-му нравится это.
  2. SergeiL

    SergeiL Оракул Модератор

    Код (C++):
    if (millis() - timing > Speed){timing = millis(); {matrix.fillScreen(0);matrix.setCursor(x,0);matrix.print(utf8rus(incoming));length_buffer = strlen(incoming) + probel;if (--x < -(length_buffer * rus)) {x = matrix.width();} matrix.show();}}
    А почему if без форматирования?
     
    b707 и Рокки1945 нравится это.
  3. Рокки1945

    Рокки1945 Гуру

    Сергей приветствую - а что это изменит?
     
  4. b707

    b707 Гуру

    Вот эта строчка в читаемом виде:
    Код (C++):
    if (millis() - timing > Speed){
      timing = millis();
    {matrix.fillScreen(0);
    matrix.setCursor(x,0);
    matrix.print(utf8rus(incoming));
    length_buffer = strlen(incoming) + probel;
    if (--x < -(length_buffer * rus))
       {x = matrix.width();}
    matrix.show();}
    }
    Вы правда считаете, что записать 9 операторов и три блока в одну строку - это нормально?
    А почему тогда не весь скетч?

    Кстати, зачем фигурная строчка в начале третьей строки? Что она здесь делает?
     
    Un_ka, parovoZZ, Рокки1945 и ещё 1-му нравится это.
  5. SergeiL

    SergeiL Оракул Модератор

    Приветствую!
    Читаться будет нормально! ;)
    Если хочется упростить loop() можно все это из loop перенести в отдельную функцию.
    Что то типа этого:
    Код (C++):
    void loop()
    {
        Input_Process();
        Voltage_check();
        Temp_check();
        check_connectivity();
        mqtt_publish_changes();
        mqtt.loop();
    }
     
    Un_ka и Рокки1945 нравится это.
  6. SergeiL

    SergeiL Оракул Модератор

    А я привык к такому форматированию:
    Код (C++):
      if (millis() - timing > Speed)
      {
        timing = millis();
        {
          matrix.fillScreen(0);
          matrix.setCursor(x, 0);
          matrix.print(utf8rus(incoming));
          length_buffer = strlen(incoming) + probel;
          if (--x < -(length_buffer * rus))
          {
            x = matrix.width();
          }
          matrix.show();
        }
      }
     
    Присоединяюсь к вопросу о дополнительном блоке.
     
    Tomasina нравится это.
  7. Рокки1945

    Рокки1945 Гуру

    Скоро узнаете - ;)
    В 2 Части
     
  8. Рокки1945

    Рокки1945 Гуру

    Бегущая строка Ч.2
    Среда программирования - ARDUINO IDE; APP INVENTOR
    Отладка - PROTEUS; блютуз компьютера; телефон с программой
    Комплектующие - WS2812B - ATMEGA 2560
    Русский шрифт брал здесь
    Что сделано:
    Вывод строки на русском языке
    Стирание строки
    Изменение скорости
    Изменение цвета
    Изменение яркости
    Останов
    Смена строки происходит по следующему алгоритму:
    1. стирание текущей
    2. останов - стоп
    3. посылка новой до 60 символов русского (буфер уарта расшарин до 127 символов)
    4. останов - запуск
    Костыли - ожидание приёма 300 милисекунд...- жертвуя динамикой
    Видео под углом - сори
    Код (C++):
    //---------------------------------------------------------//
    //библиотеки
    //Часть первая "Просто вывод строки с русским шрифтом"
    #include <avr/eeprom.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_NeoMatrix.h>
    #include <Adafruit_NeoPixel.h>
    #ifndef PSTR
    #define PSTR
    #endif
    #define PIN 25 // выход на ленту 75 вывод меги (константа)
    //---------------------------------------------------------//
    //создаём объект класса Adafruit_NeoMatrix - это для отладки в Proteuse
    Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(56, 8, PIN,NEO_MATRIX_BOTTOM + NEO_MATRIX_LEFT + NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE, NEO_GRB + NEO_KHZ800);
    /*Глобальные переменные*/
    volatile int x = matrix.width();//ширина матрицы
    byte Speed; //переменная скорости в цикле
    volatile char incoming[127];//массив приходящих символов по уарту максимум 127 - русская буква за 2 символа
    volatile char new_incoming[127];
    int i;//для подсчёта символов массива приёма по уарту
    byte rus = 3;//на русский символ потому что занимает 2 знакоместа - это множитель для длины строки
    volatile byte length_buffer = 0;//длина буфера уарта
    volatile byte probel = 0;//пробел необходим при русском шрифте
    volatile byte new_probel = 0;//пробел необходим при русском шрифте
    volatile char menu;//для прохождения по меню
    unsigned long timing;//для миллис
    byte bright = 255;//яркость уарт
    bool freez = true;//для остановки
    byte R = 255;
    byte G = 255;
    byte B = 255;
    //---------------------------------------------------------//
    void setup() {
    Serial.begin(9600); matrix.begin(); matrix.setTextWrap(0); matrix.cp437(true);
    matrix.setBrightness(bright);//яркость по умолчанию
    matrix.setTextColor(matrix.Color(R, G, B));//цвет по умолчанию
    }
    //---------------------------------------------------------//
    void loop() {
    if (Serial.available() > 0) {delay(300);//задержка для высокой скорости и принимаемого массива строки

      for (i = 0; i < 127; i++) {incoming [i] = Serial.read();//принимаем в первый элемент массива первый приходящий байт

        if (incoming [0] == '`') { menu = Serial.read();//если пришла птичка "`", значит изменяем свойства строки

                                  switch (menu) {                  
                                    case '_': for (i = 0; i < 127; i++){incoming[i] = 0;} break;//символ '_' стирания строки, обнуление массива            
                                    case '#': Speed = Serial.read();break;//изменение скорости
                                    case '?': R = Serial.read();matrix.setTextColor(matrix.Color(R, G, B));break;//изменение интенсивности красного цвета
                                    case '@': G = Serial.read();matrix.setTextColor(matrix.Color(R, G, B));break;//изменение интенсивности зелёного цвета
                                    case ':': B = Serial.read();matrix.setTextColor(matrix.Color(R, G, B));break;//изменение интенсивности синего цвета
                                    case '!': bright = Serial.read();matrix.setBrightness(bright);break;//изменение яркости
                                    case '+': freez = !freez;break;//приостановка проката
                                  }break;}

        if (incoming [i] == ' '){new_probel ++;}//если пустоместо, то прибавляем к пробелу 1 для русского шрифта
     
      }

      if (incoming [0] == '`'){Serial.end(); delay(1); Serial.begin(9600); delay(1);}//не оказывать влияния на строку

      else//произвести со строкой действия

      {
        for (i = 0; i < 127; i++){new_incoming[i] = incoming[i];}
     
        probel = new_probel; new_probel = 0;  length_buffer = strlen(incoming) + probel;
     
        Serial.end(); delay(1); Serial.begin(9600); delay(1);}} //надо чтобы не заходил ещё раз в сериал - !перезагрузка сериал!
    if (millis() - timing > Speed){timing = millis();{if(freez == true){matrix.fillScreen(0);matrix.setCursor(x,0);matrix.print(utf8rus(new_incoming));if (--x < -(length_buffer * rus)) {x = matrix.width();} matrix.show();}}}

    }

     
  9. Рокки1945

    Рокки1945 Гуру

  10. Tomasina

    Tomasina Сушитель лампочек Модератор

    А 2560 не избыточно для такого проекта?
     
    parovoZZ нравится это.
  11. Рокки1945

    Рокки1945 Гуру

    Приветствую - если есть куда рости - а фантазия - штука непредсказуемая - то лучше сделать с запасом.
     
  12. parovoZZ

    parovoZZ Гуру

    я бы взял МК на ядре ARM c той же флешкой и за те же деньги, но корпус в разы меньше.
    Но если есть на плате блютуз, то лишний МК на плате - чисто хоббийный подход.
     
  13. Рокки1945

    Рокки1945 Гуру

    Приветствую - эта штука хороша будет на стадионах каких-нибудь - пока только это придумал.
    Главное рыба - остальное приделается.
     
  14. parovoZZ

    parovoZZ Гуру

    это не смешно. Рекламщики очень сильно обожглись на этих светодиодах. Больше ими не балуются.
     
  15. Рокки1945

    Рокки1945 Гуру

    Может как нацпроект пройдёт - ? Сделать вывод строки не бегущий - а транспорантом - и на 1 Мая!
     
  16. Рокки1945

    Рокки1945 Гуру

    Бегущая строка Ч.4
    Среда программирования - ARDUINO IDE; APP INVENTOR
    Отладка - PROTEUS; блютуз компьютера; телефон с программой
    Комплектующие - WS2812B - ATMEGA 2560
    Русский шрифт брал здесь
    Что сделано:
    Вывод строки на русском языке
    Стирание строки
    Изменение скорости
    Изменение цвета
    Изменение яркости
    Останов
    Вывод русских(60) и английских (120) символов
    Исправлен приём - ноль принудительный при приёме - автоматом

    Смена строки происходит по следующему алгоритму:
    1. стирание текущей
    2. останов - стоп
    3. посылка новой до 60 символов русского (буфер уарта расшарин до 127 символов)
    4. останов - запуск
    Костыли - ожидание приёма 300 милисекунд...- жертвуя динамикой
    Код (C++):
    //---------------------------------------------------------//
    //библиотеки
    //Часть первая "Просто вывод строки с русским шрифтом"
    #include <avr/eeprom.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_NeoMatrix.h>
    #include <Adafruit_NeoPixel.h>
    #ifndef PSTR
    #define PSTR
    #endif
    #define PIN 25 // выход на ленту 75 вывод меги (константа)
    //---------------------------------------------------------//
    //создаём объект класса Adafruit_NeoMatrix - это для отладки в Proteuse
    Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(56, 8, PIN,NEO_MATRIX_BOTTOM + NEO_MATRIX_LEFT + NEO_MATRIX_COLUMNS + NEO_MATRIX_PROGRESSIVE, NEO_GRB + NEO_KHZ800);
    /*Глобальные переменные*/
    volatile int x = matrix.width();//ширина матрицы
    byte Speed; //переменная скорости в цикле
    volatile char incoming[127];//массив приходящих символов по уарту максимум 127 - русская буква за 2 символа
    volatile char new_incoming[127];
    int i;//для подсчёта символов массива приёма по уарту
    byte rus = 3;//на русский символ потому что занимает 2 знакоместа - это множитель для длины строки
    volatile byte length_buffer = 0;//длина буфера уарта
    volatile byte probel = 0;//пробел необходим при русском шрифте
    volatile byte new_probel = 0;//пробел необходим при русском шрифте
    volatile char menu;//для прохождения по меню
    unsigned long timing;//для миллис
    byte bright = 255;//яркость уарт
    bool freez = true;//для остановки
    volatile byte R = 255;
    byte G = 255;
    byte B = 255;
    //---------------------------------------------------------//
    void setup() {
    Serial.begin(9600); matrix.begin(); matrix.setTextWrap(0); matrix.cp437(true);
    matrix.setBrightness(bright);//яркость по умолчанию
    matrix.setTextColor(matrix.Color(R, G, B));//цвет по умолчанию
    }
    //---------------------------------------------------------//
    void loop() {
    if (Serial.available() > 0) {delay(300);//задержка для высокой скорости и принимаемого массива строки

      for (i = 0; i < 127; i++) {incoming [i] = Serial.read();//принимаем в первый элемент массива первый приходящий байт

        if (incoming [0] == '`') {menu = Serial.read();//если пришла птичка "`", значит изменяем свойства строки

                                  switch (menu) {                  
                                    case '_': for (i = 0; i < 127; i++){incoming[i] = 0;} break;//символ '_' стирания строки, обнуление массива            
                                    case '#': Speed = Serial.read();break;//изменение скорости
                                    case '?': R = Serial.read();matrix.setTextColor(matrix.Color(R, G, B));break;//изменение интенсивности красного цвета
                                    case '@': G = Serial.read();matrix.setTextColor(matrix.Color(R, G, B));break;//изменение интенсивности зелёного цвета
                                    case ':': B = Serial.read();matrix.setTextColor(matrix.Color(R, G, B));break;//изменение интенсивности синего цвета
                                    case '!': bright = Serial.read();matrix.setBrightness(bright);break;//изменение яркости
                                    case '+': freez = !freez;break;//приостановка проката
                                    case 'P': rus = 3;break;//прокат русского
                                    case 'Q': rus = 6;break;//прокат английского
                                  }i++; incoming [i] = 0;break;}//принудительный ноль для выхода

        if (incoming [i] == ' ' && rus == 3){new_probel ++;}//если пустоместо, то прибавляем к пробелу 1 для русского шрифта
     
      }

      if (incoming [0] == '`'){Serial.end(); delay(1); Serial.begin(9600); delay(1);}//не оказывать влияния на строку

      else//произвести со строкой действия

      {
        for (i = 0; i < 127; i++){new_incoming[i] = incoming[i];}
     
        probel = new_probel; new_probel = 0;  length_buffer = strlen(incoming) + probel;
     
        Serial.end(); delay(1); Serial.begin(9600); delay(1);}} //надо чтобы не заходил ещё раз в сериал - !перезагрузка сериал!
    if (millis() - timing > Speed){timing = millis();{if(freez == true){matrix.fillScreen(0);matrix.setCursor(x,0);matrix.print(utf8rus(new_incoming));if (--x < -(length_buffer * rus)) {x = matrix.width();} matrix.show();}}}

    }
    Скриншот GUI
    Screenshot_2020-12-30-19-09-17-363_edu.mit.appinventor.aicompanion3.jpg
     
  17. b707

    b707 Гуру

    один единственный фонт?

    Поскольку код написан с использованием либы от Адафруит - имеет смысл смотреть в сторону прикручивания сюда Адафруитовских фонтов.
    К Адафруиту есть конвертер из TTF - то есть, теоретически , бери любой фонт из винды и прикручивай....
    Любого размера и начертания. с любым национальным алфавитом. а не только с русским.
     
    Рокки1945 нравится это.
  18. Рокки1945

    Рокки1945 Гуру

    Приветствую - спасибо за инфу - устройство будет не функциональным, а цельным...
    За помощь спасибо - всегда приветствуется.
     
  19. Рокки1945

    Рокки1945 Гуру

    Бегущая строка Ч.5 (Отладка)

    Отладка - прототип устройства

    !UPDATE!
    В программе 10 макросов-слотов - в которые можно сохранить пользовательские строки - каждой строке придать свой цвет.
    Слоты можно выводить один за одним на автомате - менять последовательность их вывода - перезаписывать.
    Выдача строк идёт без задержки - благодаря En и Rus.
    В процессе проезда можно менять яркость и скорость.
    Любой макрос можно запустить в любой момент и вывести на строку.
    Очерёдность слотов в маленьких квадратиках - текстовка в больших.
    1200 английских символов-букв и 600 русских букв.
    Screenshot_2020-12-31-14-45-06-031_appinventor.ai_diiimitriipetruhin.LED_RUN_2x.jpg

    Видео

    На этом проект закрываю.
     
    Последнее редактирование модератором: 31 дек 2020
  20. Un_ka

    Un_ka Гуру

    А что с ними не то?