Русский текст на 16*8 матрице
- Войдите на сайт для отправки комментариев
Пнд, 18/04/2011 - 00:58
Привет, Ребята!
Уже неделю голову ломаю, но так и не разобрался в чём дело.
Собрал из двух матриц и 3-х регистров табло для бегущей строки. Английский хорошо показывает, а русский после каждой новой буквы весь текст сдвигается назад на 4 столбца, т.е. весь текст показывается рывками. В чём может быть дело?? Вот код:
#include <WProgram.h> #include <string.h> #include "font.h" // used to enable/disable Serial.print, time-consuming operation; // to minimize the code size, all references to Serial should be commented out; //#define _DEBUG_ 1 // display colours; #define BLACK 0 #define RED 1 #define GREEN 2 #define ORANGE 3 byte soft_prescaler = 0; byte activeRow = 0; #define CLOCK_PIN 12 #define LATCH_PIN 8 #define SER_DATA_PIN 11 // pins assigned to LED matrix rows; //byte pinForRow[8] = {0, 2, 3, 4, 5, 6, 7, 9}; int matrixrow[8] = {1,2,4,8,16,32,64,128}; #define MAX_OPTION 1 // maximum number of options in the menu; #define DEFAULT_OPTION 0 #define OPTION_MESSAGE 0 #define OPTION_CLOCK 1 // general-purpose setting; particularly used to set the scrolling speed (wait); // values from 0 to 7; byte level = 1; // used to adjust the scrolling speed; // user can set it through the menu option 3; // may be also set through other means, e.g. potentiometer on analog pin (not implemented yet); byte wait = (8-level) * 15; // used to be initially set to 200; // video memory is two arrays of 16 bit integers, one per colour; volatile uint16_t screenMemR[8] = {0}; volatile uint16_t screenMemG[8] = {0}; char msgBuffer[] = "РУССКИЙ ТЕКСТ!"; byte msgBufferPos = 0; byte msgBufferSize = 0; // this is the screen memory; it stores 4 chars (ascii rather than sprites); byte char1 = 0; byte char2 = 0; byte char3 = 0; byte char4 = 0; byte char5 = 0; void setup() { // Calculation for timer 2 // 16 MHz / 8 = 2 MHz (prescaler 8) // 2 MHz / 256 = 7812 Hz // soft_prescaler = 15 ==> 520.8 updates per second // 520.8 / 8 rows ==> 65.1 Hz for the complete display TCCR2A = 0; // normal operation TCCR2B = (1<<CS21); // prescaler 8 TIMSK2 = (1<<TOIE2); // enable overflow interrupt // define outputs for serial shift registers pinMode(CLOCK_PIN, OUTPUT); pinMode(LATCH_PIN, OUTPUT); pinMode(SER_DATA_PIN, OUTPUT); // set outputs for the 8 matrix rows; // for (int i=0; i<8; i++) // pinMode(pinForRow[i], OUTPUT); // resetDisplay(); msgBufferSize = strlen(msgBuffer); #ifdef _DEBUG_ Serial.begin(9600); #endif } ISR(TIMER2_OVF_vect) { soft_prescaler++; if (soft_prescaler == 15) { // display the next row displayActiveRow(); soft_prescaler = 0; } }; void displayActiveRow() { // disable current row; // digitalWrite(matrixrow[activeRow], LOW); activeRow++; if ( activeRow>= 8) { activeRow = 0; } // set next row; // activeRow = (activeRow+1) % 8; // shift out values for this row; byte redHi = screenMemR[activeRow] >> 8; byte redLo = screenMemR[activeRow] & 0xFF; byte greenHi = screenMemG[activeRow] >> 8; byte greenLo = screenMemG[activeRow] & 0xFF; byte row = matrixrow[activeRow]; shiftOutRow(redHi, greenHi, redLo, greenLo, row); // switch to new row; //row = row << 8; } void shiftOutRow(byte redHi, byte greenHi, byte redLo, byte greenLo, byte row) { digitalWrite(LATCH_PIN, LOW); shiftOut(SER_DATA_PIN, CLOCK_PIN, MSBFIRST, -redLo-1); shiftOut(SER_DATA_PIN, CLOCK_PIN, MSBFIRST, 0xFF); shiftOut(SER_DATA_PIN, CLOCK_PIN, MSBFIRST, -redHi-1); shiftOut(SER_DATA_PIN, CLOCK_PIN, MSBFIRST, 0xFF); shiftOut(SER_DATA_PIN, CLOCK_PIN, LSBFIRST, row); // return the latch pin high to signal chip that it // no longer needs to listen for information digitalWrite(LATCH_PIN, HIGH); } void resetDisplay() { for (byte i = 0; i < 8; i++) screenMemR[i] = 0; for (byte i = 0; i < 8; i++) screenMemG[i] = 0; char1 = 0; char2 = 0; char3 = 0; char4 = 0; char5 = 0; // reset the buffer pointers; msgBufferPos = 0; } void loop() { #ifdef _DEBUG_ Serial.print("loop char="); Serial.println(msgBuffer[msgBufferPos]); #endif displayAndScroll(msgBuffer[msgBufferPos]); msgBufferPos++; if (msgBufferPos >= msgBufferSize) msgBufferPos = 0; } void displayAndScroll(char crtChar) { #ifdef _DEBUG_ Serial.print("crtChar="); Serial.println(crtChar); #endif switch (crtChar) { case ' ': char1 = char2; char2 = char3; char3 = char4; char4 = 0; break; case 'А': case 'Б': case 'В': case 'Г': case 'Д': case 'Е': case 'Ж': case 'З': case 'И': case 'Й': case 'К': case 'Л': case 'М': case 'Н': case 'О': case 'П': case 'Р': case 'С': case 'Т': case 'У': case 'Ф': case 'Х': case 'Ц': case 'Ч': case 'Ш': case 'Щ': case 'Ъ': case 'Ы': case 'Ь': case 'Э': case 'Ю': case 'Я': char1 = char2; char2 = char3; char3 = char4; char4 = crtChar - 'А' + 1; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': char1 = char2; char2 = char3; char3 = char4; char4 = crtChar - '0' + 33; break; case '.': // definition of the bitmaps for digits start at index 37; char1 = char2; char2 = char3; char3 = char4; char4 = 43; // dot has index 37 in the character definition array; break; case ',': char1 = char2; char2 = char3; char3 = char4; char4 = 44; // comma has index 38 in the character definition array; break; case '!': char1 = char2; char2 = char3; char3 = char4; char4 = 45; // exclamation has index 39 in the character definition array; break; case ':': char1 = char2; char2 = char3; char3 = char4; char4 = 46; // colon has index 40 in the character definition array; break; } setScreenMem(RED, sprites[char1], sprites[char2], sprites[char3], sprites[char4]); } void setScreenMem(byte color, byte sprite1[8], byte sprite2[8], byte sprite3[8], byte sprite4[8]) { unsigned long row[16] = {0}; // for each row; for (byte i = 0; i < 8; i++) { byte c1 = sprite1[i] >> 1; byte c2 = sprite2[i] >> 1; byte c3 = sprite3[i] >> 1; byte c4 = sprite4[i] >> 1; row[i] = ((((((unsigned long) c1 << 5) + c2) << 5) + c3) << 5) + c4; #ifdef _DEBUG_ Serial.print(c1, DEC); Serial.print(", "); Serial.print(c2, DEC); Serial.print(", "); Serial.print(c3, DEC); Serial.print(", "); Serial.print(c4, DEC); Serial.print(", "); Serial.println(row[i]); #endif } // scroll 5 times to the left (5 being the width of a char, as defined); for (byte x = 1; x <= 5; x++) { // for each row; for (byte i = 0; i < 8; i++) { switch (color) { case RED: screenMemR[i] = row[i] >> 5-x; break; case GREEN: screenMemG[i] = row[i] >> (5-x); break; case ORANGE: screenMemR[i] = row[i] >> (5-x); screenMemG[i] = row[i] >> (5-x); break; } } delay(wait); } } // statically displays the given character/sprite; // used to display the menu option (number); void setScreenMem(byte color, byte sprite[8]) { uint16_t row; for (byte i = 0; i < 8; i++) { row = sprite[i]; if ((color & RED) == RED) screenMemR[i] = row; if ((color & GREEN) == GREEN) screenMemG[i] = row; } }
font.h :
byte sprites[][8] = { { 0x00, // ________ blank 0x00, // ________ 0x00, // ________ 0x00, // ________ 0x00, // ________ 0x00, // ________ 0x00, // ________ 0x00 // ________ }, {B00000000, B00011000, B00100100, B00100100, B00111100, B00100100, B00100100, B00000000}, {B00000000, B00111100, B00100000, B00111000, B00100100, B00100100, B00111000, B00000000}, {B00000000, B00111000, B00100100, B00111000, B00100100, B00100100, B00111000, B00000000}, {B00000000, B00111100, B00100000, B00100000, B00100000, B00100000, B00100000, B00000000}, {B00000000, B00001100, B00010100, B00010100, B00010100, B00111110, B00100010, B00000000}, {B00000000, B00111100, B00100000, B00111000, B00100000, B00100000, B00111100, B00000000}, {B00000000, B00101010, B00101010, B00011100, B00011100, B00101010, B00101010, B00000000}, {B00000000, B00011000, B00100100, B00001000, B00000100, B00100100, B00011000, B00000000}, {B00000000, B00100100, B00100100, B00101100, B00110100, B00100100, B00100100, B00000000}, {B00000000, B00101100, B00100100, B00101100, B00110100, B00100100, B00100100, B00000000}, {B00000000, B00100100, B00101000, B00110000, B00101000, B00100100, B00100100, B00000000}, {B00000000, B00001100, B00010100, B00100100, B00100100, B00100100, B00100100, B00000000}, {B00000000, B00100010, B00110110, B00101010, B00101010, B00100010, B00100010, B00000000}, {B00000000, B00100100, B00100100, B00100100, B00111100, B00100100, B00100100, B00000000}, {B00000000, B00011000, B00100100, B00100100, B00100100, B00100100, B00011000, B00000000}, {B00000000, B00111100, B00100100, B00100100, B00100100, B00100100, B00100100, B00000000}, {B00000000, B00111000, B00100100, B00100100, B00111000, B00100000, B00100000, B00000000}, {B00000000, B00011000, B00100100, B00100000, B00100000, B00100100, B00011000, B00000000}, {B00000000, B00111110, B00001000, B00001000, B00001000, B00001000, B00001000, B00000000}, {B00000000, B00100100, B00100100, B00011100, B00000100, B00100100, B00011000, B00000000}, {B00000000, B00011100, B00101010, B00101010, B00011100, B00001000, B00001000, B00000000}, {B00000000, B00100010, B00010100, B00001000, B00001000, B00010100, B00100010, B00000000}, {B00000000, B00100100, B00100100, B00100100, B00100100, B00100100, B00111110, B00000000}, {B00000000, B00100100, B00100100, B00100100, B00011100, B00000100, B00000100, B00000000}, {B00000000, B00100010, B00101010, B00101010, B00101010, B00101010, B00111110, B00000000}, {B00000000, B00100010, B00101010, B00101010, B00101110, B00101110, B00111110, B00000000}, {B00000000, B00110000, B00010000, B00011000, B00010100, B00010100, B00011000, B00000000}, {B00000000, B00100010, B00100010, B00110010, B00101010, B00101010, B00110010, B00000000}, {B00000000, B00100000, B00100000, B00110000, B00101000, B00101000, B00110000, B00000000}, {B00000000, B00011000, B00100100, B00000100, B00001100, B00100100, B00011000, B00000000}, {B00000000, B00100100, B00101010, B00101010, B00111010, B00101010, B00100100, B00000000}, {B00000000, B00011100, B00100100, B00100100, B00011100, B00100100, B00100100, B00000000}, //{B00000000, // B00110010, // B00110100, // B00001000, // B00001000, // B00010110, // B00100110, // B00000000}, { // index 28 0x00, // ________ 0 0x18, // ___XX___ 0x24, // __X__X__ 0x24, // __X__X__ 0x24, // __X__X__ 0x24, // __X__X__ 0x18, // ___XX___ 0x00, // ________ }, { 0x00, // ________ 1 0x08, // ____X___ 0x18, // ___XX___ 0x28, // __X_X___ 0x08, // ____X___ 0x08, // ____X___ 0x1C, // ___XXX__ 0x00, // ________ }, { 0x00, // ________ 2 0x18, // ___XX___ 0x24, // __X__X__ 0x08, // ____X___ 0x10, // ___X____ 0x20, // __X_____ 0x3C, // __XXXX__ 0x00, // ________ }, { 0x00, // ________ 3 0x3C, // __XXXX__ 0x04, // _____X__ 0x18, // ___XX___ 0x04, // _____X__ 0x24, // __X__X__ 0x18, // ___XX___ 0x00, // ________ }, { 0x00, // ________ 4 0x04, // _____X__ 0x0C, // ____XX__ 0x14, // ___X_X__ 0x3C, // __XXXX__ 0x04, // _____X__ 0x04, // _____X__ 0x00, // ________ }, { 0x00, // ________ 5 0x3C, // __XXXX__ 0x20, // __X_____ 0x38, // __XXX___ 0x04, // _____X__ 0x24, // __X__X__ 0x18, // ___XX___ 0x00, // ________ }, { 0x00, // ________ 6 0x18, // ___XX___ 0x20, // __X_____ 0x38, // __XXX___ 0x24, // __X__X__ 0x24, // __X__X__ 0x18, // ___XX___ 0x00, // ________ }, { 0x00, // ________ 7 0x3C, // __XXXX__ 0x04, // _____X__ 0x08, // ____X__ 0x10, // ___X___ 0x10, // ___X____ 0x10, // ___X____ 0x00, // ________ }, { 0x00, // ________ 8 0x18, // ___XX___ 0x24, // __X__X__ 0x18, // ___XX___ 0x24, // __X__X__ 0x24, // __X__X__ 0x18, // ___XX___ 0x00, // ________ }, { 0x00, // ________ 9 0x18, // ___XX___ 0x24, // __X__X__ 0x1C, // ___XXX__ 0x04, // _____X__ 0x24, // __X__X__ 0x18, // ___XX___ 0x00, // ________ }, { 0x00, // ________ . 0x00, // ________ 0x00, // ________ 0x00, // ________ 0x00, // ________ 0x30, // __XX____ 0x30, // __XX____ 0x00, // ________ }, { 0x00, // ________ , 0x00, // ________ 0x00, // ________ 0x00, // ________ 0x00, // ________ 0x30, // __XX____ 0x10, // ___X____ 0x20, // __X_____ }, { 0x00, // ________ ! 0x18, // ___X____ 0x18, // ___X____ 0x18, // ___X____ 0x18, // ___X____ 0x00, // ________ 0x18, // ___X____ 0x00, // ________ }, { // index 40 0x00, // ________ : 0x00, // ________ 0x18, // ___XX___ 0x18, // ___XX___ 0x00, // ________ 0x18, // ___XX___ 0x18, // ___XX___ 0x00, // ________ }, };
Без хорошей травы здесь не разобраться) А вообще проще методом исключения. Исключи все блоки программы которые не нужны для вывода русского языка и скроллинга (Это я про английский). Для начала лучше отобразить хотябы 2 буквы вместе русские.
Я конечно тоже влет не разобрался что тут к чему. Но возникли две мысли.
Во-первых я не понимаю, как английские буквы вообще работают. В функции void displayAndScroll(char crtChar) во всех case рассматирваются варианты русских букв, цифр, знаков препинания, но нигде нет case для английских букв, и нет default, если я чего не пропустил. как они вообще попадают на вывод?
Во-вторых ты говоришь, что сдвиг на 4 столбца, при этом везде оперируешь четырьмя знаками. Например,
Может причина здесь.
Без хорошей травы здесь не разобраться) А вообще проще методом исключения. Исключи все блоки программы которые не нужны для вывода русского языка и скроллинга (Это я про английский). Для начала лучше отобразить хотябы 2 буквы вместе русские.
Исключал всё возможное, пробовал выводить по одной букве и по две... когда выводишь например : 91:А ... то 91: идёт нормально, а русский символ начинает глючить.
Я конечно тоже влет не разобрался что тут к чему. Но возникли две мысли.
Во-первых я не понимаю, как английские буквы вообще работают. В функции void displayAndScroll(char crtChar) во всех case рассматирваются варианты русских букв, цифр, знаков препинания, но нигде нет case для английских букв, и нет default, если я чего не пропустил. как они вообще попадают на вывод?
Во-вторых ты говоришь, что сдвиг на 4 столбца, при этом везде оперируешь четырьмя знаками. Например,
Может причина здесь.
Этот код переработан на русский алфавит, в оригинале сasы имеют английские буквы и работает отлично... я трогал только их...
Проверь 215 строку, точно ли там у тебя РУССКАЯ 'А'
Проверь 215 строку, точно ли там у тебя РУССКАЯ 'А'
Русская 'A' - 100% ...
Проблема походу в самой кодировке Кириллицы... а вообще Arduino какую языковую кодировку использует? Юникод?
В кодовой таблице MS-DOS русская буква А имеет код 128, а в 1251- MS Windows - код 192, попробуй в 215 строке вместо 'A' эти значения
А где оригинал с английскими буквами, чтоб сравнить.
А где оригинал с английскими буквами, чтоб сравнить.
строка 297 в первом примере с русскими буквами и строка 701 в последнем с английскими, найди 2 отличия
строка 297 в первом примере с русскими буквами и строка 701 в последнем с английскими, найди 2 отличия
Неа .. нет результата...
Кстати говоря если не пользовать алфавит, а только цифры и оставшиеся !,.: ... всё ОК
И еще выяснилось, что не после новой буквы , а перед ней происходит сдвиг...