Русский текст на 16*8 матрице

anriko
Offline
Зарегистрирован: 18.04.2011

Привет, Ребята!

Уже неделю голову ломаю, но так и не разобрался в чём дело.

Собрал из двух матриц и 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,    // ________
  },
};

 

Adessit
Adessit аватар
Offline
Зарегистрирован: 12.04.2011

Без хорошей травы здесь не разобраться) А вообще проще методом исключения. Исключи все блоки программы которые не нужны для вывода русского языка и скроллинга (Это я про английский). Для начала лучше отобразить хотябы 2 буквы вместе русские. 

Modular
Offline
Зарегистрирован: 05.03.2011

  Я конечно тоже влет не разобрался что тут к чему. Но возникли две мысли.
Во-первых я не понимаю, как английские буквы вообще работают. В функции void displayAndScroll(char crtChar) во всех case рассматирваются варианты русских букв, цифр, знаков препинания, но нигде нет case для английских букв, и нет default, если я чего не пропустил. как они вообще попадают на вывод?
Во-вторых ты говоришь, что сдвиг на 4 столбца, при этом везде оперируешь четырьмя знаками. Например,

case ' ':
 char1 = char2;
 char2 = char3;
 char3 = char4;
 char4 = 0;

................
................

setScreenMem(RED, sprites[char1], sprites[char2], sprites[char3], sprites[char4]);

Может причина здесь.

anriko
Offline
Зарегистрирован: 18.04.2011

Adessit пишет:

Без хорошей травы здесь не разобраться) А вообще проще методом исключения. Исключи все блоки программы которые не нужны для вывода русского языка и скроллинга (Это я про английский). Для начала лучше отобразить хотябы 2 буквы вместе русские. 

Исключал всё возможное, пробовал выводить по одной букве и по две... когда выводишь например : 91:А ... то 91: идёт нормально, а русский символ начинает глючить.

anriko
Offline
Зарегистрирован: 18.04.2011

Modular пишет:

  Я конечно тоже влет не разобрался что тут к чему. Но возникли две мысли.
Во-первых я не понимаю, как английские буквы вообще работают. В функции void displayAndScroll(char crtChar) во всех case рассматирваются варианты русских букв, цифр, знаков препинания, но нигде нет case для английских букв, и нет default, если я чего не пропустил. как они вообще попадают на вывод?
Во-вторых ты говоришь, что сдвиг на 4 столбца, при этом везде оперируешь четырьмя знаками. Например,

case ' ':
 char1 = char2;
 char2 = char3;
 char3 = char4;
 char4 = 0;

................
................

setScreenMem(RED, sprites[char1], sprites[char2], sprites[char3], sprites[char4]);

Может причина здесь.

Этот код переработан на русский алфавит, в оригинале сasы имеют английские буквы и работает отлично... я трогал только их...

 

MarioM
Offline
Зарегистрирован: 18.04.2011

 Проверь 215 строку, точно ли там у тебя РУССКАЯ 'А'

anriko
Offline
Зарегистрирован: 18.04.2011

MarioM пишет:

 Проверь 215 строку, точно ли там у тебя РУССКАЯ 'А'

Русская 'A' - 100% ...

Проблема походу в самой кодировке Кириллицы... а вообще Arduino какую языковую кодировку использует? Юникод?

MarioM
Offline
Зарегистрирован: 18.04.2011

В кодовой таблице MS-DOS русская буква А имеет код 128, а в 1251- MS Windows  - код 192, попробуй в 215 строке вместо 'A' эти значения

Zaliv
Offline
Зарегистрирован: 05.03.2011

 А где оригинал с английскими буквами, чтоб сравнить.

anriko
Offline
Зарегистрирован: 18.04.2011

Zaliv пишет:

 А где оригинал с английскими буквами, чтоб сравнить.

/** 
 * Dual RG LED matrix (16 x 8)
 *
 * This is a demo for scrolling text on the "Dual RG matrix shield" which can be
 * found here: http://timewitharduino.blogspot.com/2010/02/dual-bi-color-led-matrix-shi...
 */

#include <WProgram.h>
#include <string.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


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};



byte sprites[][8] = {
  {
    0x00,    // ________   blank
    0x00,    // ________
    0x00,    // ________
    0x00,    // ________
    0x00,    // ________
    0x00,    // ________
    0x00,    // ________
    0x00     // ________
  },
  {
    0x00,    // ________   A
    0x18,    // ___XX___
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x3C,    // __XXXX__
    0x24,    // __X__X__
    0x24,    // __X__X_
    0x00     // ________
  },
  {
    0x00,    // ________   B
    0x38,    // __XXX___
    0x24,    // __X__X__
    0x38,    // __XXX___
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x38,    // __XXX__
    0x00     // ________
  },
  {
    0x00,    // ________   C
    0x18,    // ___XX___
    0x24,    // __X__X__
    0x20,    // __X_____
    0x20,    // __X_____
    0x24,    // __X__X__
    0x18,    // ___XX__
    0x00     // ________
  },
  {
    0x00,    // ________   D
    0x38,    // __XXX___
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x38,    // __XXX__
    0x00     // ________
  },
  {
    0x00,    // ________   E
    0x3C,    // __XXXX__
    0x20,    // __X_____
    0x38,    // __XXX___
    0x20,    // __X_____
    0x20,    // __X_____
    0x3C,    // __XXXX__
    0x00     // ________
  },
  {
    0x00,    // ________   F
    0x3C,    // __XXXX__
    0x20,    // __X_____
    0x38,    // __XXX___
    0x20,    // __X_____
    0x20,    // __X_____
    0x20,    // __X_____
    0x00     // ________
  },
  {
    0x00,    // ________  G
    0x1C,    // ___XXX__
    0x20,    // __X_____
    0x20,    // __X_____
    0x2C,    // __X_XX__
    0x24,    // __X__X__
    0x1C,    // __XXXX__
    0x00     // ________
  },
  {
    0x00,    // ________  H
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x3C,    // __XXXX__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x00     // ________
  },
  {
    0x00,    // ________  I
    0x1C,    // ___XXX__
    0x08,    // ____X___
    0x08,    // ____X___
    0x08,    // ____X___
    0x08,    // ____X___
    0x1C,    // ___XXX__
    0x00     // ________
  },
  {
    0x00,    // ________  J
    0x3C,    // __XXXX__
    0x04,    // _____X__
    0x04,    // _____X__
    0x04,    // _____X__
    0x24,    // __X__X__
    0x18,    // ___XX___
    0x00     // ________
  },
  {
    0x00,    // ________  K
    0x24,    // __X__X__
    0x28,    // __X_X___
    0x30,    // __XX____
    0x28,    // __X_X___
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x00,    // ________
  },
  {
    0x00,    // ________  L
    0x20,    // __X_____
    0x20,    // __X_____
    0x20,    // __X_____
    0x20,    // __X_____
    0x20,    // __X_____
    0x3C,    // __XXXX__
    0x00,    // ________
  },
  {
    0x00,    // ________  M
    0x22,    // __X___X_
    0x36,    // __XX_XX_
    0x2A,    // __X_X_X_
    0x22,    // __X___X_
    0x22,    // __X___X_
    0x22,    // __X___X_
    0x00,    // ________
  },
  {
    0x00,    // ________  N
    0x24,    // __X__X__
    0x34,    // __XX_X__
    0x2C,    // __X_XX__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x00,    // ________
  },
  {
    0x00,    // ________  O
    0x18,    // ___XX___
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x18,    // ___XX___
    0x00,    // ________
  },
  {
    0x00,    // ________  P
    0x38,    // __XXX___
    0x24,    // __X__X__
    0x38,    // __XXX___
    0x20,    // __X_____
    0x20,    // __X_____
    0x20,    // __X_____
    0x00,    // ________
  },
  {
    0x00,    // ________  Q
    0x18,    // ___XX___
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x2C,    // __X_XX__
    0x1A,    // ___XX_X_
    0x00,    // ________
  },
  {
    0x00,    // ________  R
    0x38,    // __XXX___
    0x24,    // __X__X__
    0x38,    // __XXX___
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x00,    // ________
  },
  {
    0x00,    // ________  S
    0x1C,    // ___XXX__
    0x20,    // __X_____
    0x18,    // ___XX___
    0x04,    // _____X__
    0x24,    // __X__X__
    0x18,    // ___XX___
    0x00,    // ________
  },
  {
    0x00,    // ________  T
    0x3E,    // __XXXXX_
    0x08,    // ____X___
    0x08,    // ____X___
    0x08,    // ____X___
    0x08,    // ____X___
    0x08,    // ____X___
    0x00,    // ________
  },
  {
    0x00,    // ________  U
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x18,    // ___XX___
    0x00,    // ________
  },
  {
    0x00,    // ________  V
    0x22,    // __X___X_
    0x22,    // __X___X_
    0x22,    // __X___X_
    0x14,    // ___X_X__
    0x14,    // ___X_X__
    0x08,    // ____X___
    0x00,    // ________
  },
  {
    0x00,    // ________  W
    0x22,    // __X___X_
    0x22,    // __X___X_
    0x22,    // __X___X_
    0x2A,    // __X_X_X_
    0x2A,    // __X_X_X_
    0x14,    // ___X_X__
    0x00,    // ________
  },
  {
    0x00,    // ________ X
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x18,    // ___XX___
    0x18,    // ___XX___
    0x24,    // __X__X__
    0x24,    // __X__X__
    0x00,    // ________
  },
  {
    0x00,    // ________  Y
    0x22,    // __X___X_
    0x22,    // __X___X_
    0x14,    // ___X_X__
    0x08,    // ____X___
    0x08,    // ____X___
    0x08,    // ____X___
    0x00,    // ________
  },
  {
    0x00,    // ________  Z
    0x3E,    // __XXXXX_
    0x24,    // __X__X__
    0x08,    // ____X___
    0x10,    // ___X____
    0x22,    // __X___X_
    0x3E,    // __XXXXX_
    0x00,    // ________
  },
  {  // index 27
    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,    // ________  !
    0x10,    // ___X____
    0x10,    // ___X____
    0x10,    // ___X____
    0x10,    // ___X____
    0x00,    // ________
    0x10,    // ___X____
    0x10,    // ________
  },
  {  // index 40
    0x00,    // ________  :
    0x00,    // ________
    0x18,    // ___XX___
    0x18,    // ___XX___
    0x00,    // ________
    0x18,    // ___XX___
    0x18,    // ___XX___
    0x00,    // ________
  },
};


char msgBuffer[] = " 1. A ROBOT MAY NOT INJURE A HUMAN BEING OR, THROUGH INACTION, ALLOW A HUMAN BEING TO COME TO HARM.       ";
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);


  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()
{
  activeRow++;
    if ( activeRow>= 8) {
      activeRow = 0;
    }

  // 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);
}



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 'A':  case 'B':  case 'C':  case 'D':  case 'E':  case 'F':
  case 'G':  case 'H':  case 'I':  case 'J':  case 'K':  case 'L':
  case 'M':  case 'N':  case 'O':  case 'P':  case 'Q':  case 'R':
  case 'S':  case 'T':  case 'U':  case 'V':  case 'W':  case 'X':
  case 'Y':  case 'Z':
    char1 = char2;
    char2 = char3;
    char3 = char4;
    char4 = crtChar - 'A' + 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' + 27;
    break;

  case '.':
    // definition of the bitmaps for digits start at index 37;
    char1 = char2;
    char2 = char3;
    char3 = char4;
    char4 = 37;  // dot has index 37 in the character definition array;
    break;

  case ',':
    char1 = char2;
    char2 = char3;
    char3 = char4;
    char4 = 38;  // comma has index 38 in the character definition array;
    break;

  case '!':
    char1 = char2;
    char2 = char3;
    char3 = char4;
    char4 = 39;  // exclamation has index 39 in the character definition array;
    break;

  case ':':
    char1 = char2;
    char2 = char3;
    char3 = char4;
    char4 = 40;  // 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;
  }
}

 

MarioM
Offline
Зарегистрирован: 18.04.2011

 строка 297 в первом примере с русскими буквами и строка 701 в последнем с английскими, найди 2 отличия

anriko
Offline
Зарегистрирован: 18.04.2011

MarioM пишет:

 строка 297 в первом примере с русскими буквами и строка 701 в последнем с английскими, найди 2 отличия

Неа .. нет результата...

Кстати говоря если не пользовать алфавит, а только цифры и оставшиеся !,.: ...  всё ОК

И еще выяснилось, что не после новой буквы , а перед ней происходит сдвиг...