1

Тема: Глюк у меня в голове или в Freeduino?

Доброго дня суток.

Не так давно купил Freeduino. Осваиваю. Разные примеры с сайта Arduino.cc поделал. Радости нет предела.

Придумал себе обучающую задачку: POV

Идея проста, диоды в планке мигают в нужной последовательности. А если этой планкой провести в темноте, то из-за инертности наших глаз мы увидим надпись.

http://www.adafruit.com/images/medium/minipov2_MED.jpg

Схема подключения предельно проста:

http://photofile.ru/photo/boby-at-net/96130667/middle/110223493.jpg

А вот и сам скетч:

 int timer = 2; 
 int x = 0;
 int y = 0;
 
 int pin_on [] = {7,6,5,4,3,12,11,10,9,8} ; // порядок подключения диодов

// матрица символа сердце
 int heart [10][10] = {
                       {0,0,1,1,0,0,1,1,0,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {1,1,1,1,1,1,1,1,1,1},
                       {1,1,1,1,1,1,1,1,1,1},
                       {1,1,1,1,1,1,1,1,1,1},
                       {1,1,1,1,1,1,1,1,1,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,0,1,1,1,1,1,1,0,0},
                       {0,0,0,1,1,1,1,0,0,0},
                       {0,0,0,0,1,1,0,0,0,0},
                     };

// матрица символа I
 int char_I [10][10] = {
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,0,0,0,1,1,0,0,0,0},
                       {0,0,0,0,1,1,0,0,0,0},
                       {0,0,0,0,1,1,0,0,0,0},
                       {0,0,0,0,1,1,0,0,0,0},
                       {0,0,0,0,1,1,0,0,0,0},
                       {0,0,0,0,1,1,0,0,0,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,1,1,1,1,1,1,1,1,0},
                     };

// матрица символа Y
 int char_Y [10][10] = {
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,0,1,1,0,0,1,1,0,0},
                       {0,0,1,1,0,0,1,1,0,0},
                       {0,0,0,1,1,1,1,0,0,0},
                       {0,0,0,0,1,1,0,0,0,0},
                       {0,0,0,0,1,1,0,0,0,0},
                       {0,0,0,0,1,1,0,0,0,0},
                       {0,0,0,0,1,1,0,0,0,0},
                     };

// матрица символа O
 int char_O [10][10] = {
                       {0,0,0,1,1,1,1,0,0,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,0,0,1,1,1,1,0,0,0},
                     };

// матрица символа A
 int char_A [10][10] = {
                       {0,0,1,1,1,1,1,1,0,0},
                       {0,1,1,1,1,1,1,1,0,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                     };

// матрица символа B
 int char_B [10][10] = {
                       {0,1,1,1,1,1,1,0,0,0},
                       {0,1,1,1,1,1,1,1,0,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,1,1,1,1,1,1,0,0,0},
                     };

// матрица символа C
 int char_C [10][10] = {
                       {0,0,0,1,1,1,1,0,0,0},
                       {0,0,1,1,1,1,1,1,0,0},
                       {0,1,1,1,0,0,0,0,0,0},
                       {0,1,1,0,0,0,0,0,0,0},
                       {0,1,1,0,0,0,0,0,0,0},
                       {0,1,1,0,0,0,0,0,0,0},
                       {0,1,1,0,0,0,0,0,0,0},
                       {0,1,1,1,0,0,0,0,0,0},
                       {0,0,1,1,1,1,1,1,0,0},
                       {0,0,0,1,1,1,1,0,0,0},
                     };


// матрица символа U
 int char_U [10][10] = {
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,0,0,0,0,1,1,0},
                       {0,1,1,1,1,1,1,1,1,0},
                       {0,0,0,1,1,1,1,0,0,0},
                     };
                     
 
 void setup() {
   for (int thisPin = 0; thisPin < 10; thisPin++)  {
     pinMode(pin_on[thisPin], OUTPUT);      
   }
      Serial.begin(9600);
   
 }

 void loop() {
  delay(100);
   Serial.println(" ");      
   Serial.println("A");
     draw_symbol(char_A);   
   Serial.println(" ");      
   Serial.println("B");     
     draw_symbol(char_B);   
   Serial.println(" ");      
   Serial.println("C");
     draw_symbol(char_C);   
   Serial.println(" ");      
   Serial.println("O");     
     draw_symbol(char_O);   

// Если следующие три строки раскомментировать, то работать перестает.

//  Serial.println(" ");      
//  Serial.println("Y");     
//     draw_symbol(char_Y);   
   
}

void draw_symbol(int what_symbol[10][10])
{
 for (int x = 0; x < 10; x++)
   { 
     for (int y = 0; y < 10; y++)
     { 
       if (what_symbol[y][x]==1)
         {digitalWrite(pin_on[y], HIGH);
          Serial.print("1"); } 
    else {
          Serial.print("0");      
    digitalWrite(pin_on[y], LOW);}

     }
   Serial.println(" ");      
   delay(timer);
   }

   all_off();

   delay(timer*2);

}


void all_off() {
   for (int y = 0; y < 10; y++)
     {digitalWrite(pin_on[y], LOW);} 
  
}

Все хорошо в таком варианте, но если раскомментировать три строчки, т.е. отображать еще одну букву, то работать наглухо перестает, причем если мониторить serial monitor, то фридуино выдает непонятные символы, а так же на плате мигает диод L.

Помогите диагностировать проблему.

2

Re: Глюк у меня в голове или в Freeduino?

Думаю com порт просто не успевает передавать данные.

3

Re: Глюк у меня в голове или в Freeduino?

т.е. нужно увеличить задержку между отправлением символов.

4

Re: Глюк у меня в голове или в Freeduino?

realist пишет:

т.е. нужно увеличить задержку между отправлением символов.

А причем здесь задержка между отправкой символов на компорт? :)

Логика же проста: скетч всегда выполняется по кругу. 4 символа отрабатываются без каких либо проблем. Добавляю еще один тут же все валиться... Такое ощущение что косяк с памятью, только не могу понять какой...

5

Re: Глюк у меня в голове или в Freeduino?

Bobeg пишет:

А причем здесь задержка между отправкой символов на компорт? :)

Ну, символов там выплевывается много - у меня мысль сперва тоже в эту сторону пошла :)

4 символа отрабатываются без каких либо проблем. Добавляю еще один тут же все валиться... Такое ощущение что косяк с памятью, только не могу понять какой...

Верно мыслите.
Итак, Вы описали 8 массивов по 100 элементов типа int. int в Arduino - 2 байта, итого 8*100*2=1600 байт.
Несмотря на то, что сложится это при компиляции в память программ, чтобы работать с этими данными их нужно будет перекинуть в ОЗУ. ОЗУ у нас 1024 байта. Компилятор умный (оптимизирующий! :)), и перекидывает только то, что нужно. В данном случае, когда используется 4 символа, памяти хватает. Когда используете 5й, памяти начинает не хватать, и такое ощущение, что она начинает пересекаться с буфером последовательного порта.
Из-за этого и лезет непонятный мусор в порт.
Кстати, у меня на версии ПО 0016 проблемы начинаются уже с 4-го символа.
Если в данной конкретной программе заменить int на char для хранения символов, то мы в 2 раза умерим аппетит, и она заработает, но предел в 8-9 символов - это все-таки не то, что нам нужно.
Путь к нормальному решению проблемы - хранить один столбец символа не в 10 байтах, а в 2х (используя каждый бит),
либо перейти на 8-строковые знаки - тогда хватит 1 байта.
Программа конечно усложнится.
Посмотрите тут: http://www.arduino.cc/cgi-bin/yabb2/YaB … 1223449559
Там как раз реализована аналогичная идея, только есть еще одна хитрость - светодиоды (8 штук) подключены не к произвольным выводам, а на так называемый порт PORTD (это выводы с 0 по 7).
И одной записью числа в PORTD выставляется правильное состояние всех 8 светодиодов (подробнее тут: http://www.arduino.cc/en/Reference/PortManipulation).
...на выводах 0 и 1 разведен COM-порт, поэтому связь по последовательному порту будет невозможна.

Re: Глюк у меня в голове или в Freeduino?

Admin пишет:

Несмотря на то, что сложится это при компиляции в память программ, чтобы работать с этими данными их нужно будет перекинуть в ОЗУ. ОЗУ у нас 1024 байта.

...skipped...

Путь к нормальному решению проблемы - хранить один столбец символа не в 10 байтах, а в 2х (используя каждый бит),
либо перейти на 8-строковые знаки - тогда хватит 1 байта.

Интересно, а никаких warning'ов при этом не выдается? Может GCC надо какие-то ключи передавать? Он же по идее мог сообразить, что памяти не хватит, и нам ругнуться?

...когда-то давно я на PIC'ах мелкие задачки решал - там был такой метод - таблицы данных прямо в секции кода. И хитрым образом к этой таблице можно было обратиться.
А то даже если сделать знакогенератор 8x8 пикселей (по 8 байт на символ), 26 англ. мелких букв, 26 заглавных, 10 чисел, еще пару всяких знаков, то выйдет 8*(26+26+10+2) = 512 байт - как раз половина ОЗУ. Много. А под код у нас 16к - куча места. У AVR такой метод тоже должен быть наверняка. Надо пошукать по докам.

7

Re: Глюк у меня в голове или в Freeduino?

Admin пишет:

....
Посмотрите тут: http://www.arduino.cc/cgi-bin/yabb2/YaB … 1223449559
Там как раз реализована аналогичная идея, только есть еще одна хитрость - светодиоды (8 штук) подключены не к произвольным выводам, а на так называемый порт PORTD (это выводы с 0 по 7).
И одной записью числа в PORTD выставляется правильное состояние всех 8 светодиодов (подробнее тут: http://www.arduino.cc/en/Reference/PortManipulation).
...на выводах 0 и 1 разведен COM-порт, поэтому связь по последовательному порту будет невозможна.

Спасибо большое за ответ. Изучу вопрос, обязательно отпишусь.