Русский текст на 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 отличия
Неа .. нет результата...
Кстати говоря если не пользовать алфавит, а только цифры и оставшиеся !,.: ... всё ОК
И еще выяснилось, что не после новой буквы , а перед ней происходит сдвиг...