Arduino и POV массив

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Здравствуйте !

Нужна помощь программеров чтоб натолкнуть на правильный путь.

Имеем собранное , исправно работающее устройство http://sebastian.setz.name/arduino/my-projekts/light-print/ .

Имеем массив типа

 int columns[] = {

 7230,25353,16702,34944,35007,34949,16698,25344,15935,25377,16670,34944,40127,34976,16703,25344,7231,128,1983,140,63,1920,286,1953,30};

в котром каждый элемент массива является одним столбцом изображения. С этим разобрался.

Вопрос первый - как реализовать свою библиотеку символов.

Вопрос второй, главный - как создать массив и  вывести изображение из bmp (черно белую) файла  вот в таком виде http://www.toxel.com/wp-content/uploads/2009/07/monkeylectric04.jpg .

Уж очень сынишка просит на велосипед картинку папе электронщику тяжело даются уроки программирования .

Спасибо !

 

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Продолжу беседу с умным человеком ))

Как правильно вывести на 16 светодиодов картинку, размером  16х16 пикселей , преобразованную битмап конвертером из этой темы http://arduino.ru/forum/programmirovanie/biblioteka-dlya-lcd-nokia-1100?page=7#comment-212906 в массив ?

Пример картинки

 

 

Код картинки "шахматная доска"

//------------------------------------------------------------------------------
// File generated by LCD Assistant
// http://en.radzio.dxp.pl/bitmap_converter/
//------------------------------------------------------------------------------

const unsigned char 16x16pics [] = {
0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC,
0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC
};

 

 

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Продолжим косилиум ))

Почему горят не все светодиоды? Ведь 177777 это 1111 1111 1111 1111 ?

Светодиоды подключены к пинам 2,3,4,5,6,7,8,9,10,11,12,13,A0,A1,A2,A3

Проверил в скетче blink - все работают. 

/*******************************************
 *
 * Name.......:  lightPrint
 * Description:  A small and fast scetch to draw words and grafics in to the night. Just with 16 LEDs. For more Information, required hardware, wireing and examples please check the project page.
 * Author.....:  Sebastian Setz
 * Version....:  0.1.0
 * Date.......:  2010-11-25
 * Project....:  http://sebastian.setz.name/arduino/my-projekts/light-print
 * Contact....:  http://Sebastian.Setz.name
 * License....:  This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
 *               To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to
 *               Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
 *
 ********************************************/
 
const int columnTime =  1; //15 Время [мс] работы каждого отдельного столбца 
const int spacer = 10; // 10Это значение, умноженное на columnTime , чтобы получить распорку между содержанием всего массива
 
long columns[] = {
// 7230,25353,16702,34944,35007,34949,16698,25344,15935,25377,16670,34944,40127,34976,16703,25344,7231,128,1983,140,63,1920,286,1953,30}; // Массив столбцов. Добавить символы, слова, символы, ...
//int columns[] = {
177777, 177777, 177777, 177777,177777, 177777, 177777, 177777, 177777, 177777, 177777, 177777,177777, 177777   }; // Array of colums. Add characters, words, symbols, ...




int columnCount = sizeof(columns) / sizeof(columns[0]); //Подсчет столбцов
 
void setup(){
  // Define digital pin 0 to 16 as OUTPUT, switch it on, wait, switch it off
  for (int i=2;i<17;i++){
    pinMode(i,OUTPUT);
    digitalWrite(i,HIGH);
    delay(columnTime);
    digitalWrite(i,LOW);
  }
}
 
void loop(){
  //Чтение из каждой части массива одного столбца
  for (int column=0;column<columnCount;column++){
    // Читайте каждый бит и установить строку
    for (int row=0;row<17;row++){
      digitalWrite(row,bitRead(columns[column],row));
    }
    delay(columnTime); //Подождите , так что ваши глаза или объектив может реализовать столбец
  }
  // Установить в каждой строке LOW
  for (int row=0;row<17;row++){
    digitalWrite(row,LOW);
  }
  delay(spacer*columnTime); //После отделка весь массив подождать некоторое время
}

__Alexander
Offline
Зарегистрирован: 24.10.2012

mobistrike пишет:

 

Почему горят не все светодиоды? Ведь 177777 это 1111 1111 1111 1111 ?

это кто вам такое сказал?

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

Пользуйтесь моей добротой =) стандартный калькулятор в винде, в режиме "программист"

 

а нужное вам число 0xFFFF = 65535 = 0177777 = 1111 1111 1111 1111

 

в вашей записи нехватат нолика перед числом чтоб его в виде восьмиричного записать

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Да , тупанул . Заменил 177777 на 65535.

Не горят светодиоды на ногах A2,A3. Подскажите почему ?

Напомню -светодиоды подключены к пинам 2,3,4,5,6,7,8,9,10,11,12,13,A0,A1,A2,A3

 

 

 

Junior1980
Offline
Зарегистрирован: 27.03.2015

Делать POV -эффекты с помощью Digitalwrite не получится, скорость выполнения очень низкая. Нужно пользоваться прямым управлением светодиодами через порты Дуни. Например

PORTB = B10101000; // устанавливает HIGH на цифровых выводах 7,5,3

Logik
Offline
Зарегистрирован: 05.08.2014

mobistrike пишет:

Не горят светодиоды на ногах A2,A3. Подскажите почему ?

 

Это элементарно. Потому что вы на них ничего не выводите. Зато выводите на ноги 0 и 1. Делайте циклы начиная с 2, как в сетапе. Телько и в сетапе ошибка, проверяйте количество проходов цикла.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Junior1980 пишет:

Делать POV -эффекты с помощью Digitalwrite не получится, скорость выполнения очень низкая. Нужно пользоваться прямым управлением светодиодами через порты Дуни. Например

PORTB = B10101000; // устанавливает HIGH на цифровых выводах 7,5,3

Все у нас получится ))

Logik пишет:

mobistrike пишет:

Не горят светодиоды на ногах A2,A3. Подскажите почему ?

 

Это элементарно. Потому что вы на них ничего не выводите. Зато выводите на ноги 0 и 1. Делайте циклы начиная с 2, как в сетапе. Телько и в сетапе ошибка, проверяйте количество проходов цикла.

Да увидел , спасибо большое !

Поправил. Теперь работает

Вот код

/*******************************************
 *
 * Name.......:  lightPrint
 * Description:  A small and fast scetch to draw words and grafics in to the night. Just with 16 LEDs. For more Information, required hardware, wireing and examples please check the project page.
 * Author.....:  Sebastian Setz
 * Version....:  0.1.0
 * Date.......:  2010-11-25
 * Project....:  http://sebastian.setz.name/arduino/my-projekts/light-print
 * Contact....:  http://Sebastian.Setz.name
 * License....:  This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
 *               To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/ or send a letter to
 *               Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.
 *
 ********************************************/
 
const int columnTime =  2; //15 Время [мс] работы каждого отдельного столбца 
const int spacer = 10; // 10Это значение, умноженное на columnTime , чтобы получить распорку между содержанием всего массива
 
long columns[] = {
// 7230,25353,16702,34944,35007,34949,16698,25344,15935,25377,16670,34944,40127,34976,16703,25344,7231,128,1983,140,63,1920,286,1953,30}; // Массив столбцов. Добавить символы, слова, символы, ...
//int columns[] = {
//0xFFFF, 0xFFFF, 0x8001, 0x8001   }; // Array of colums. Add characters, words, symbols, ...
7230,25353,16702,34944,35007,34949,16698,25344,15935,25377,16670,34944,40127,34976,16703,25344,7231,128,1983,140,63,1920,286,1953,30}; // Массив столбцов. Добавить символы, слова, символы, ...




int columnCount = sizeof(columns) / sizeof(columns[0]); //Подсчет столбцов
 
void setup(){

 // Serial.begin(9600);
  
 
  
  
  // Define digital pin 0 to 16 as OUTPUT, switch it on, wait, switch it off
  for (int i=2;i<18;i++){
    pinMode(i,OUTPUT);
    digitalWrite(i,HIGH);
    delay(columnTime);
    digitalWrite(i,LOW);
  //Serial.print(i);
   // Serial.print(row);
   // Serial.print("   ");
   // Serial.print(bitRead(columns[column],row));
  
  }
}
 
void loop(){
 
 
 
  //Чтение из каждой части массива одного столбца
  for (int column=0;column<columnCount;column++){
    // Читайте каждый бит и установить строку
    for (int row=0;row<=15;row++){
      digitalWrite(row+2,bitRead(columns[column],row));
    
   // Serial.println(column);
   // Serial.print(row);
   // Serial.print("   ");
   // Serial.println(bitRead(columns[column],row));
   //Serial.print("   ");
   // Serial.println(row,bitRead(columns[column],row));
   //delay(500);
    
   
    }
    delay(columnTime); //Подождите , так что ваши глаза или объектив может реализовать столбец
    
  }
  // Установить в каждой строке LOW
  for (int row=2;row<18;row++){
    digitalWrite(row,LOW);
  //Serial.println(row);
  //Serial.println("   ";
  }
  delay(spacer*columnTime); //После отделка весь массив подождать некоторое время


}

Теперь к самому началу.  Как "загнать" восьмибитную  шахматную доску ,выложеную  несколькими постами выше ? Или как сделать 16 битную картинку ?

Уважаемые программисты !Не ругайтесь сильно . Я только учусь ))

Зато могу помочь по электронике (работа у меня с паяльником и тестером)

Logik
Offline
Зарегистрирован: 05.08.2014

Для начала надо синхронизировать работу проги с вращением. Чтоб момент начала отсчета был. Затем вывод 0x5555, пауза, вывод  0xaaaa, пауза и т.д. И шахматная доска, но круглая, готова.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Logik пишет:

Для начала надо синхронизировать работу проги с вращением. Чтоб момент начала отсчета был. Затем вывод 0x5555, пауза, вывод  0xaaaa, пауза и т.д. И шахматная доска, но круглая, готова.

По поводу синхронизации и начала отсчета в курсе но решил оставить это в последнюю очередь - когда все остальное будет отточено. Сейчас пересобираю этот код с нуля так как многое непонятно (поторюсь - я начинающий). В процессе и обучаюсь. Тяжело дается , медленно  но интересно и сын подстегивает )).

Logik, Покажите плиз в коде .

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Посмотрите пожалуйста , я правильно мыслю по структуре BMP ?

К посту ниже ...

Пока для синхронизации регулирую обороты вентилятора - есть ЛБП(Лабораторный Блок Питания) 

 

Logik
Offline
Зарегистрирован: 05.08.2014

Ну ход мысли правильный. Но  без синхронизации даже имея верное формирование сигнала просто ниче не увидете. Все будет мерцать и крутится.

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

Нет вы мыслите не правильно и не в том направлении.

Во первых у вас картинка и матрица не 8\16 битные а всгего 1 битные =)

Битность картинки - кол-во бит кодирующих цвет 1 пиксела =)

смотрите картинку =)

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Вот что получилось ....


 
const int columnTime =  2; //15 Время [мс] работы каждого отдельного столбца 
const int spacer = 10; // 10Это значение, умноженное на columnTime ,  пауза между содержанием всего массива
 
long columns[] = {

//*******массив 16x16 шахматная доска
//0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC,
//0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC
// ****************************


//***************  массив 16x16 стрелка 
0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00,
0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00
//***********************************


//***************  массив 16x16 сердце
//0x00, 0x00, 0xFC, 0x02, 0x01, 0x01, 0x06, 0x18, 0x06, 0x01, 0x01, 0x02, 0xFC, 0x00, 0x00, 0x00,
//0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x80, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00
//***********************************


};

int columnCount = (sizeof(columns) / sizeof(columns[0])); //Подсчет количества столбцов 
int p1=0;
int p2=p1+8;

void setup(){

  for (int i=2;i<18;i++){ // массив пинов для светодиодов
    pinMode(i,OUTPUT);
    digitalWrite(i,HIGH);
    delay(columnTime);
    digitalWrite(i,LOW);
 
  }
}
 
void loop(){

for (int p0=0;p0<columnCount/2;p0++){ //преебираем все элементы массива  
   
 
//*******читаем все биты первого числа  (первые 8 бит)  

  for (int p1=0;p1<=7;p1++){ 

digitalWrite(p1+2,bitRead(columns[p0],p1));//..включаем первые 8 светодиодов 
}
//********************************
//*******читаем все биты второго числа (вторые 8 бит)  
  for (int p2=0;p2<=7;p2++){ 

digitalWrite(p2+10,bitRead(columns[p0+16],p2));//..включаем вторые 8 светодиодов 
}
//********************************

delay(columnTime); // пауза между столбцами  

//********гасим все светодиоды
  for (int i=2;i<18;i++){
    digitalWrite(i,LOW);
 
  }
//***************************

}

delay(spacer*columnTime);// пауза между всем  массивом
}

Теперь думаю с чего бы "содрать" датчик холла.

Теперь пинайте ))

ToRcH2565
Offline
Зарегистрирован: 16.05.2015

Получилось красиво =) датчик холла можно выдрать из любой расскладущки(я про старые мобилы) или из ноута, или вообще взять из карбюраторного движка( у меня стоит например на ваз 2109)....

 

но один момент который освящен в моем предыдущем посте, вы таки не учли, вы выводите попиксельно, и в случае с шахмотной доской это очень заметно.... чтобы клетки были ровные(квадраты и одинаковые) надо чуть больше математики =)

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016
mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

ToRcH2565 пишет:

Получилось красиво =) датчик холла можно выдрать из любой расскладущки(я про старые мобилы) или из ноута, или вообще взять из карбюраторного движка( у меня стоит например на ваз 2109)....

 

но один момент который освящен в моем предыдущем посте, вы таки не учли, вы выводите попиксельно, и в случае с шахмотной доской это очень заметно.... чтобы клетки были ровные(квадраты и одинаковые) надо чуть больше математики =)

Спасибо! Теперь я это вижу. 

Пока нет  датчика холла дальше писать смысла нет.

 

quote=qwone]

http://arduino.ru/Tutorial/Upravlenie_portami_cherez_registry

[/quote]

Рано мне еще . Я этот код еле осилил.

 

nik182
Offline
Зарегистрирован: 04.05.2015

Датчик Хола живёт в любом компьютерном вентиляторе.  Даже в том который у вас крутится. Я из из старых, заклинивших, достаю. 

Logik
Offline
Зарегистрирован: 05.08.2014

Прикольно. Успех не должен останавливать. Переходите к 3Д. Матрицу вращать например. Или вот еще интересная тема - линейка светодиодов+датчик ускорения. При резком взмахе, обнаруженому по датчику, отрисовываем картинку разово. Должен быть занятный эффект. После взмаха в воздухе остается изображение на мгновение.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Прикрутил датчик холла от кулера . Заодно почитал про прерывания. Можно обойтись без attachInterrupt ?

Дело в том что посадить прерывание на 2 или 3 ногу в моем проэкте теперь проблематично так как на них повешены светодиоды , а чтоб сдвинуть все на один выше нужно перепаивать все , что не очень хочется.

Например так .

int pin = 19;                
                   
unsigned long duration;
  
void setup()
{
Serial.begin (9600); 
  pinMode(pin, INPUT);
}
 
void loop()
{
  duration = pulseIn(pin, HIGH);
Serial.println(duration);

}

Датчик работает - миллисекунды , при поднесении магнита считает.

Только никак не соображу как это воткнуть в мою программу.

Logik
Offline
Зарегистрирован: 05.08.2014

Можна и без прерывания. Ждем срабатывания датчика, как сработало - выводим картинку. Затем снова ждем срабатывания  и т.д. Если вывод картинки успевает за 1 оборот - все ок. Иначе проблемы.  И эти проблемы с прерыванием проще решать. Но если заведомо за 1 оборот успеваем то проще без прерывания.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Logik пишет:

Можна и без прерывания. Ждем срабатывания датчика, как сработало - выводим картинку. Затем снова ждем срабатывания  и т.д. Если вывод картинки успевает за 1 оборот - все ок. Иначе проблемы.  И эти проблемы с прерыванием проще решать. Но если заведомо за 1 оборот успеваем то проще без прерывания.

У меня две новости. Начну с хорошей ))

Датчик холла от кулера меня шокировал (вернее его эффект). Все четко отрабатывает .Теперь не стыдно и видео показать , плюс добавил мигалку во время простоя.

Плохое. Где то в коде я накосячил что вчера 2 часа "ковыряний " и анализа загнали меня в тупик.

Суть такова - если массив 16х16 то все работает прекрасно . Но если массив в ширину больше 16 пикселей начинается то что на видео. На втором видео код с двумя стрелками подряд т.е. 16 пикс. в высоту и 32 в ширину.

Смотрите и выручайте ))

1. Здесь все нормально

https://www.youtube.com/watch?v=nSl68jKeD8s&feature=youtu.be

2. Проблемы

https://youtu.be/VbSZxkht80Q

3. Код




 
const int columnTime =  2; //15 Время [мс] работы каждого отдельного столбца 
const int spacer = 10; // 10Это значение, умноженное на columnTime ,  пауза между содержанием всего массива
unsigned long duration; 
long columns[] = {

// *******массив 16x16 шахматная доска
//0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC,
//0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC
// ****************************


// ***************  массив 16x16 стрелка 
0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00,
0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00,
//***********************************

// ***************  массив 16x16 стрелка 
0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00,
0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00
// ***********************************

// ***************  массив 16x32 черный прямоугольник 
//0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
//0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
//0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
//
// ***********************************



// ***************  массив 16x16 сердце
//0x00, 0x00, 0xFC, 0x02, 0x01, 0x01, 0x06, 0x18, 0x06, 0x01, 0x01, 0x02, 0xFC, 0x00, 0x00, 0x00,
//0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x80, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00
// ***********************************

// ***************  массив 16x16 черный квадрат 
//0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
//0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
// ***********************************

//0xFF, 0x01, 0x01, 0x01, 0x81, 0x41, 0x21, 0x19, 0x05, 0x19, 0x21, 0x41, 0x81, 0x01, 0x01, 0xFF,
//0xFF, 0x80, 0x80, 0x80, 0x81, 0x82, 0x84, 0x98, 0xA0, 0x98, 0x84, 0x82, 0x81, 0x80, 0x80, 0xFF

};

int columnCount = (sizeof(columns) / sizeof(columns[0])); //Подсчет количества столбцов 
int p1=0;
int p2=p1+8;
int pin = 19;                   //пин для подключения датчика холла
void setup(){

  for (int i=2;i<18;i++){ // массив пинов для светодиодов
    pinMode(i,OUTPUT);
    digitalWrite(i,HIGH);
    delay(columnTime);
    digitalWrite(i,LOW);
Serial.begin(9600);
  }
}
 
void loop(){
duration = pulseIn(pin, HIGH);

// ********гасим все светодиоды
  for (int i=2;i<18;i++){
    digitalWrite(i,LOW);
   }
// ***************************


///*
// ***************пока стоим - красиво мигаем ))
while (duration==0){
duration = pulseIn(pin, HIGH);
for (int kk=2;kk<18;kk++){
    digitalWrite(kk,HIGH);
   delay(20);
   digitalWrite(kk,LOW);
   }
for (int kk=16;kk>2;kk--){
    digitalWrite(kk,HIGH);
   delay(20);
   digitalWrite(kk,LOW);
   }
}
// *******************************************

if (duration>0){  //  ***если сработал датчик холла  то....
for (int p0=0;p0<columnCount/2;p0++){ //преебираем все элементы массива  

// *******читаем все биты первого числа  (первые 8 бит)  

  for (int p1=0;p1<=7;p1++){ 
digitalWrite(p1+2,bitRead(columns[p0],p1));//..включаем первые 8 светодиодов 

}
// ********************************


// *******читаем все биты второго числа (вторые 8 бит)  
  for (int p2=0;p2<=7;p2++){ 

digitalWrite(p2+10,bitRead(columns[p0+16],p2));//..включаем вторые 8 светодиодов 

}
// ********************************

delay(columnTime); // пауза между столбцами  
 
 }
}
//delay(spacer*columnTime);// пауза между всем  массивом
}

 

GarryC
Offline
Зарегистрирован: 08.08.2016

Исправьте строку 90 на следующую

  for (int p0=0; p0<ColumnCount-16; p0++, p0=((p0%16)==0)?p0+16:p0) {

должно помочь.

Logik
Offline
Зарегистрирован: 05.08.2014

Проблема тут запущенная. Надо начинать с того, почему columns[] имеет тип long, верно ли считает columnCount и чего в строке 104 явно прописано 16.

GarryC
Offline
Зарегистрирован: 08.08.2016

Ну, в принципе, если нам не жалко памяти, то можно и long, на работы не влияет, все равно используются 8 младших разрядов.

Количество элементов массива columnCount считает верно, и даже правильно.

А 16 - количество строк в подмассиве, так что можно и так.

А насчет запущенности - Вы правы, я предложил минимально возможную правку.

Logik
Offline
Зарегистрирован: 05.08.2014

GarryC пишет:

Количество элементов массива columnCount считает верно, и даже правильно.

сколько?

 

GarryC пишет:

А 16 - количество строк в подмассиве, так что можно и так.

Нельзя. код будет выводить пары значений с индексами 0,16;1,17;...15,31; 16,3217,32.....  Это даже по картинке видно.

Автор просто должен сам разобратся в своем коде. Как раз тот момент, когда заработало - наилучший. Код сохраняется на всяк случай;) и делается рефакторинг, исправляется все искаженное при отладке, оптимизируется, актуализируются имена переменных (очевидно что columnCount сейчас совсем не  columnCount ), коментарии  и пр. При этом выявляются и исправляются второстепенные ошибки.  Вы конечно можете сделать это за автора ;)

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

GarryC пишет:

Исправьте строку 90 на следующую

  for (int p0=0; p0<ColumnCount-16; p0++, p0=((p0%16)==0)?p0+16:p0) {

должно помочь.

Помогло ! За что СПАСИБО ! Но есть еще НО.

И про запущенность ... Тут не соглашусь . Это не запущенность , а незнание. Ненвижу TC ))  

С НО разбираюсь, завтра отпишусь о результатах.

Logik
Offline
Зарегистрирован: 05.08.2014

mobistrike пишет:

 Это не запущенность , а незнание. 

Ниразу нет. Это естественный ход процесса разработки. Когда по ходу приходится вносить правки, менять представление о назначении переменных, функций и т.д. И менять цели разработки тоже. Так всегда. Ну можно дополнит что всегда при отсутствии четкого планирования, но то скорей илюзия о наличии идеального планирования. Но проще это воспринимать как необходимость уборки в доме. Иногда надо, и даже старайся не сорить, хоть усрись, а всеравно прийдется убирать. Так и код, надо иногда "причесывать". 

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Logik пишет:

mobistrike пишет:

 Это не запущенность , а незнание. 

 Так и код, надо иногда "причесывать". 

Это если уметь пользоваться расческой )) У меня же пока получается только лохматить ))

Об обещанном "НО". Выявился глюк - конвертированные bmp размером больше 16x6 выводятся коряво. Удалось выяснить что это не глюк прошивки а конвертер конвертит "не в моем формате ". вот так.

Получается мои представления о структуре BMP , изложеные в посте 11 в корне неверны ?

Logik
Offline
Зарегистрирован: 05.08.2014

Не то чтоб совсем. Просто термин BMP он как бы имеет 2 смысла: общий - представление картинки в несжатом виде при котором каждому пикселю отводится некоторое количество бит и конкретный - стандарт файла в котором реализован первый смысл. Совместимость и переносимость обеспечивает стандарт. Но Вы и автор того конвертора имеют в виду общий смысл. Потому у вас обоих BMP, но они не совместимы. Ваш способ хранения картинки  мне показалось несколько не логичным и неудобным. Думаю нужно подстроится под конвертор.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

mobistrike пишет:

Получается мои представления о структуре BMP , изложеные в посте 11 в корне неверны ?

Угу.

Точнее так: я совекршенно не понял, как именно Вы себе представляете сруктуру BMP, но все-таки понял достаточно, чтобы сказать, что Вы ее себе представляете неверно.

1. Структура BMP начинается с заголовка.

2. Изображение хранится по строкам, а не по столбцам.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Причесал ."Впихиваются " любые (сделанные конвертером в начале топика )монохромные BMP высотой 16 и шириной , ограниченой диаметром.

Пинайте ))


 
const int columnTime =  2; //15 Время [мс] работы каждого отдельного столбца 
const int spacer = 10; // 10Это значение, умноженное на columnTime ,  пауза между содержанием всего массива
unsigned long duration; 
long columns[] = {

// *******массив 16x43 BMW ))
0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x60, 0x30, 0x18, 0xEC, 0x2C, 0x6C, 0xCC, 0x0C, 0x2C, 0xEC,
0xEC, 0x8C, 0xEC, 0xEC, 0x0C, 0xEC, 0x8C, 0x0C, 0xCC, 0xCC, 0x0C, 0x0C, 0xEC, 0x7C, 0xE0, 0xC0,
0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x3E, 0x33,
0x33, 0x30, 0x70, 0xD8, 0x8F, 0x8D, 0xFD, 0x7F, 0x26, 0x20, 0x27, 0x20, 0x21, 0x20, 0x27, 0x20,
0x20, 0x23, 0x26, 0x27, 0x21, 0x27, 0x67, 0xE1, 0xD8, 0x98, 0xF0, 0x60, 0x20, 0x21, 0x3F, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
// ****************************

// *******массив 16x16 шахматная доска
//0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC,
//0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC
// ****************************


// ***************  массив 16x16 стрелка 
//0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00,
//0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00,
//***********************************


// ***************  массив 16x16 сердце
//0x00, 0x00, 0xFC, 0x02, 0x01, 0x01, 0x06, 0x18, 0x06, 0x01, 0x01, 0x02, 0xFC, 0x00, 0x00, 0x00,
//0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x80, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00
// ***********************************


};
int columnCount = (sizeof(columns) / 4); //Подсчет количества 8 битных столбцов 
 
int p1=0;
int p2=p1+8;
int pin = 19;       //пин для подключения датчика холла
void setup(){

  for (int i=2;i<18;i++){ // массив пинов для светодиодов
    pinMode(i,OUTPUT);
    digitalWrite(i,HIGH);
    delay(columnTime);
    digitalWrite(i,LOW);

  }
}
 
void loop(){
duration = pulseIn(pin, HIGH);

// ***************пока стоим - красиво мигаем ))
while (duration==0){
duration = pulseIn(pin, HIGH);
for (int kk=2;kk<18;kk++){
    digitalWrite(kk,HIGH);
   delay(20);
   digitalWrite(kk,LOW);
   }
for (int kk=16;kk>2;kk--){
    digitalWrite(kk,HIGH);
   delay(20);
   digitalWrite(kk,LOW);
   }
}
// *******************************************




if (duration>0){  //  ***если сработал датчик холла  то....
  
  for (int p0=0; p0<columnCount/2; p0++ ){
  
// *******читаем все биты первого числа  (первые 8 бит)  

  for (int p1=0;p1<8;p1++){ 
digitalWrite(p1+2,bitRead(columns[p0],p1));//..включаем первые 8 светодиодов 
}
// ********************************

// *******читаем все биты второго числа (вторые 8 бит)  
  for (int p2=0;p2<8;p2++){ 
digitalWrite(p2+10,bitRead(columns[columnCount/2+p0],p2));//..включаем вторые 8 светодиодов
}
// ********************************
delay(columnTime); // пауза между столбцами  
 }
// ********гасим все светодиоды
  for (int i=2;i<18;i++){
    digitalWrite(i,LOW);
   }
// ***************************
}
delay(spacer*columnTime);// пауза между всем  массивом
}

 

Logik
Offline
Зарегистрирован: 05.08.2014

А columns по прежнему long. Зачем? И int columnCount ... //Подсчет количества 8 битных столбцов. Ну какие еще 8 битные столбцы, если у Вас четко аппаратно 16 бит в столбце. Дак так и считайте, ведь далее везде columnCount используется деленым на 2. Ну и посчитайте его так сразу. Зачем эти штаны через голову одевать?

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Logik пишет:

А columns по прежнему long. Зачем? И int columnCount ... //Подсчет количества 8 битных столбцов. Ну какие еще 8 битные столбцы, если у Вас четко аппаратно 16 бит в столбце. Дак так и считайте, ведь далее везде columnCount используется деленым на 2. Ну и посчитайте его так сразу. Зачем эти штаны через голову одевать?

Не ругайтесь. Я разрешал  только пинать))  

Это моя вторая  самостоятельная работа. Первая (измеритель емкости LI ION акб) обошлась без помощи.  А тут намного сложнее. По поводу ваших замечаний - я не совсем понимаю зачем это нужно. Если не трудно объясните "на пальцах" и в коде. По 8 битным столбцам - я имел в виду половину из 16 светодиодов. 

Сорри за оффтоп,похвастаюсь ))

 

 

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

И снова здравствуйте !

Выкладываю "причесаную" версию (я так думаю).

Код значительно переработан.

Размер изображения не зависит от оборотов(почти).

Освободил 2 пин для прерывания но пока не использовал для этого. Как считаете стоит его использовать ? Будет лучше ? 

И еще .... Подскажите редактор для преобразования картинки в полярную систему координат. Или есть другие мысли по этому поводу ?

 

int duration; //..толщина столбца 

//****************Пременные пинов светодиодов
int l1 = 18; 
int l2 = 3; 
int l3 = 4; 
int l4 = 5; 
int l5 = 6; 
int l6 = 7; 
int l7 = 8; 
int l8 = 9; 
int l9 = 10; 
int l10 = 11;
int l11 = 12; 
int l12 = 13; 
int l13 = 14; 
int l14 = 15; 
int l15 = 16; 
int l16 = 17; 
//**************************

int lp[] = {l1, l2, l3, l4, l5, l6, l7, l8,l9, l10, l11, l12, l13, l14, l15, l16}; // массив пинов светодиодов 


byte columns[] = {
// *******массив 16x43 BMW ))
//0x00, 0x80, 0xE0, 0x98, 0x06, 0x01, 0x06, 0x98, 0xE0, 0x80, 0x00, 0x00, 0xFF, 0x81, 0x81, 0x81,
//0x81, 0x42, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xFF, 0x00, 0x00, 0xC0,
//0x3C, 0x03, 0x3C, 0xC0, 0x00, 0x00, 0xFF, 0x1C, 0x60, 0x80, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
//0xFF, 0x80, 0x80, 0x80, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x01, 0x06, 0x18, 0x60,
//0x80, 0x00, 0x00, 0x00, 0xFF, 0x80, 0x80, 0x80, 0x80, 0xFF, 0xC0, 0x3C, 0x03, 0x00, 0x00, 0x00,
//0x03, 0x3C, 0xC0, 0xFF, 0x00, 0x00, 0x03, 0x1C, 0x60, 0xFF
// ****************************

// *******массив 16x16 шахматная доска
//0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC,
//0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC
// ****************************

// *************** 16x41 большая стрелка
//0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0xF8, 0xFC, 0xFC, 0xFE, 0xFE,
//0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC,
//0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x01, 0x01, 0x03, 0x03, 0x07, 0x07, 0x07,
//0x0F, 0x0F, 0x0F, 0x1F, 0x1F, 0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0x0F, 0x0F,
//0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
//0x0F, 0x0F, 
//**********************************

// ***************  массив 16x16 стрелка 
//0x00, 0xC0, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00,
//0x00, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x0E, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00,
//***********************************


// ***************  массив 16x16 сердце
//0x00, 0x00, 0xFC, 0x02, 0x01, 0x01, 0x06, 0x18, 0x06, 0x01, 0x01, 0x02, 0xFC, 0x00, 0x00, 0x00,
//0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x40, 0x80, 0x40, 0x20, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00
// ***********************************

// *************** массив 16x86 arduino.ru 
0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x00, 0x80, 0x7F, 0x00, 0x00, 0xCE, 0x31, 0x11, 0x11,
0x11, 0x11, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x82, 0x01, 0x01, 0x01, 0x01, 0x82,
0x7C, 0x00, 0x00, 0xFF, 0x80, 0x60, 0x10, 0x0C, 0x02, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x7F,
0x80, 0x00, 0x00, 0x00, 0x80, 0x7F, 0x00, 0x00, 0x7C, 0x82, 0x01, 0x01, 0x01, 0x01, 0xFF, 0x00,
0x00, 0xCE, 0x31, 0x11, 0x11, 0x11, 0x11, 0xFF, 0x00, 0x80, 0x60, 0x38, 0x26, 0x21, 0x26, 0x38,
0x60, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
// ***********************************
};
int columnCount = (sizeof(columns)); //Подсчет количества байтов в массиве 
 int pin = 2;       //пин для подключения датчика холла

void setup(){
 
for (int i = 0; i < 16; i++) {
        pinMode(lp[i], OUTPUT);
       digitalWrite(lp[i], LOW);
} 
}

void loop(){
duration = pulseIn(pin, HIGH);

// ***************пока стоим - красиво мигаем ))
while (duration==0){
duration = pulseIn(pin, HIGH);
for (int kk=2;kk<18;kk++){
    digitalWrite(kk,HIGH);
   delay(20);
   digitalWrite(kk,LOW);
   }
for (int kk=16;kk>2;kk--){
    digitalWrite(kk,HIGH);
   delay(20);
   digitalWrite(kk,LOW);
   }
}
// ****************************************** *




if (duration>0){  //  ***если сработал датчик холла  то....
  for (int p0=0; p0<columnCount/2; p0++ ){
// *******читаем все биты первого числа  (первые 8 бит)  
  for (int p1=0;p1<8;p1++){ 
digitalWrite(lp[p1],bitRead(columns[p0],p1));//..включаем первые 8 светодиодов 
}
// ********************************

// *******читаем все биты второго числа (вторые  8 бит)  
  for (int p2=0;p2<8;p2++){ 
digitalWrite(lp[p2+8],bitRead(columns[columnCount/2+p0],p2));//..включаем вторые 8 светодиодов
}
// ********************************
delayMicroseconds(duration/3); 


 }
// ********гасим все светодиоды
  for (int i=0;i<16;i++){
    digitalWrite(lp[i],LOW);
   }
// ***************************
}
}

Видео работы https://youtu.be/0llRyQKpjqc

Пинайте !

kasper007
Offline
Зарегистрирован: 23.05.2016

Получилось достаточно интересно. В 2002 году делал таким образом часы на PIC контроллере. Теперь увидев эту тему и посмотрев Ютуб кусаю локти, что ограничился тогда часами. :)
Заказал уже на Али упаковку миниатюрных трехцветных светодиодов, попробую многоцветный рисунок влспроизвести.

Растянуть рисунок на 64 светодиода можно к примеру с помощью max7219. Но это будет в одном цвете. Пока что-то никак не соображу как три цвета организовать.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

А вы спросите у гугла про WS2812 - будете приятно удивлены ))

Logik
Offline
Зарегистрирован: 05.08.2014

mobistrike пишет:

Размер изображения не зависит от оборотов(почти).

Очень красиво получилось. И на видео, и реализация в коде красиво - просто и коротко.

 

mobistrike пишет:

Освободил 2 пин для прерывания но пока не использовал для этого. Как считаете стоит его использовать ? Будет лучше ? 

А есть проблемы? "Работает - не трогай".

mobistrike пишет:
 Подскажите редактор для преобразования картинки в полярную систему координат. Или есть другие мысли по этому поводу ?

Есть мысль что такого не найдете.

По развитию проекта:

1. Убрать columns из  ОЗУ. Совсем не сложно, ищите по слову PROGMEM, на форуме часто встречается. Цель - возможность хранить в флеше и выводить десяток полноформатных картинок, анимация.

2. Работа с портами напрямую. Цель - ускорение вывода, снижение нагрузки на процессор. На данный момент может и не актуально, но экономия не повредит, да и изучить вопрос полезно.

3. Ну и традиционно - формат хранения. Если найдется редактор для преобразования картинки - подстроится под него. Если нет и п.2 не делаете - переработать тот формат, что есть. Цель - сокращение и упрощение кода, заменив два цикла на один.

4. Подумать о ИК управлении. Это при реализации п.1 даст возможность переключать картинки и передавать изображениие во время работы. Получится целый дисплей )))

 

GarryC
Offline
Зарегистрирован: 08.08.2016

Честно говоря, удивлен, что картинка не зависит от скорости вращения - должна зависеть или я чего то сильно недопонимаю.

У Вас датчик Холла отмечает одно место на колесе ? Или срабатывает несколько раз за оборот?

Вроде по коду одно, но почему тогда картинка на сжимается при малых скоростях, я не понимаю.

Logik
Offline
Зарегистрирован: 05.08.2014

GarryC пишет:

Честно говоря, удивлен, что картинка не зависит от скорости вращения - должна зависеть или я чего то сильно недопонимаю.

ага. Вот этого - delayMicroseconds(duration/3); ))) Я ж говорю, красиво проблема решена. Длительность вывода пикселя привязана к длительности импульса с датчика.

GarryC
Offline
Зарегистрирован: 08.08.2016

PS. Теперь понял, я просто старый код смотрел с фиксированными длительностями свечения, а Вы в новом привязали ее к длительности предыдущего импульса, красиво получилось, своего рода ФАПЧ, единственное, что надо бы исправить - у Вас может быть один рабочий оборот и один пустой для измерения - скважность ухудшится, надо бы объединить. Ну и мерять не длительность импульса, а паузы между ними и делить на количество выводимых строк, но идея хороша.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Спасибо всем за отзывы !

Приятно читать . Сам не ожидал. Думаю оставить все как есть . Пусть это будет это версией 1.0 . Планы на версию 2.0 - вывести картинку в горизольталой плоскости, добавить анимацию. Скорее это будет уже другой проект. Ведь программа поменяется кардинально.

Еще бы "подтянуть" знания в программированиии. Тяжело начинать делать в 45 то что никогда не делал. Прорвемся )) 

Logik
Offline
Зарегистрирован: 05.08.2014

GarryC пишет:

 у Вас может быть один рабочий оборот и один пустой для измерения - скважность ухудшится, надо бы объединить. 

Да. Риск есть. Важно заканчивать вывод до начала импульса с датчика. Ну и не получится выводить на все 360 градусов, 3-4 пикселя пропустится. Но помоему это мелочи. Если надо это решить - надо определять моменты фронтов ( понятно и длительность так получится, как время между ними) паралельно с выводом, тут возможно или прерывания или в лупе ловить фронты во время паузы между пикселями.   

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

Господа Программисты ! 

Тут http://mysku.ru/blog/ebay/30604.html есть описание редактора а тут https://yadi.sk/d/VreNSLjivqP5F сам редактор. Это вроде питоновский скрипт. Установил питон но запустить скрипт не удалось. Подскажите плиз по шагам как его запусть или перекомпилируйте пожалуйста в EXEшник .

kasper007
Offline
Зарегистрирован: 23.05.2016

Mobistrike, спасибо за подсказку, наконец-таки мне пришла лента WS8212b. На скорую руку соорудил макет.

Синхронизация по датчику холла. Светодиоды загораются на 40 мс, потом гаснут и так до следующего оборота.

Правильно ли я понимаю, что разрывы в свечении из-за импульсного питания светодиодов. Можно ли это исправить увеличив яркость светодиодов (strip.setBrightness(255), я использую библиотеку adafruit_neopixel)?

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

kasper007 , вы бы для начала скетч выложили. Второе -  с WS2812b я не работал , но уверен найдутся знающие люди и подскажут, третье - не совсем понимаю что вы имеете ввиду под "импульсным питанием светодиодов".

 

kasper007
Offline
Зарегистрирован: 23.05.2016

Скетча нет под рукой, дома на компьюетере. Но в нем нет ничего неординарного. Настроено прерывание на int.0. По прерыванию загорается все линейка. Дальше счетчик на 40 мс, после чего гасим светодиоды.

"Надеюсь с знакомы с алгоритмом работы POV дисплея ?"  Да, конечно же, прекрасно осведомлен. Вчера задача стояла завести агрегат физически, а что он будет потом отображать, это уже творческий процесс и "капелька ума" для реализации идеи в коде.

"что вы имеете ввиду под "импульсным питанием светодиодов".".  Для регулировки яркости светодиодов повсеместно используется импульсное питание. Изменяя скважность импульсов мы изменяем яркость свечения. Когда светодиод неподвижен мы не замечаем это моргание, а когда мы раскручиваем светодиод, то уже можно заметить периоды когда питание на светодиод подается, а когда нет. Вроде так.

mobistrike
mobistrike аватар
Offline
Зарегистрирован: 19.08.2016

kasper007 пишет:

Скетча нет под рукой, дома на компьюетере. Но в нем нет ничего неординарного. Настроено прерывание на int.0. По прерыванию загорается все линейка. Дальше счетчик на 40 мс, после чего гасим светодиоды.

"Надеюсь с знакомы с алгоритмом работы POV дисплея ?"  Да, конечно же, прекрасно осведомлен. Вчера задача стояла завести агрегат физически, а что он будет потом отображать, это уже творческий процесс и "капелька ума" для реализации идеи в коде.

"что вы имеете ввиду под "импульсным питанием светодиодов".".  Для регулировки яркости светодиодов повсеместно используется импульсное питание. И изменяя скважность импульсов и изменяем яркость. Когда светодиод неподвижен мы не замечаем это моргание, а когда мы раскручиваем светодиод, то уже можно заметить периоды когда питание на светодиод подается, а когда нет. Вроде так.

Теперь понятно . Тогда стоит проверить на максимальной яркости . 

kasper007
Offline
Зарегистрирован: 23.05.2016

Действительно, при максимальной яркости разрывов никаких нет.

Скелет кода получился примерно такой:

#include <Adafruit_NeoPixel.h>
#define PIN 5 // лента на 5ом порту
#define count_led 9 // количество светодиодов 
#define eff_int 50 // длина эффекта в точках
Adafruit_NeoPixel strip = Adafruit_NeoPixel(count_led, PIN, NEO_GRB + NEO_KHZ800);
 
 volatile byte hall_detect; // флаг срабатывания датчика холла
 byte i; // переменная для номера текущей точки  эффекта (не должна быть больше eff_int)
 unsigned long time_old; // время срабатывание датчика холла 
 unsigned long time_int; // длительность оборота 
 float time_eff; // длительность одной точки эффекта = длительность оборота/длина эффекта в точках
 boolean  ind_on; 
 
 void setup()
 {
   Serial.begin(115200);
   strip.begin();
   strip.show();  
   attachInterrupt(0, magnet_detect, RISING);
   hall_detect = 1;
   i = 1;
   ind_on = true;
   time_old = millis();
 }

 void loop()
 {
 if (hall_detect == 0) {
    if ((millis()-time_old) > 2000) {  //если оборот более чем за 2 сек, выключаем индикацию
    light_off();
    strip.show();
    }
    
    if ((millis()-time_old) > (time_eff*i)) { 
    i++;
    ind_on = true;
    strip.show();  //длительность записи в ленту 30*count_led мкс
    } else {
      if (ind_on) {  
      eff_1();       
      ind_on = false;
      }
    }   
 }
  
 if (hall_detect == 1)  { 
    time_int = millis()-time_old;
    time_old = millis();
    hall_detect = 0;
    i = 1;  
    time_eff = (float)time_int/eff_int; 
    } 
 } 

void magnet_detect()
 {
   hall_detect = 1;
 }

void light_off ()
 {
   for (byte ii=0; ii<count_led; ii++) { strip.setPixelColor(ii, 0,0,0);}
 }

void eff_1 ()
 {
   for (byte ii=0; ii<count_led; ii++) {
   if ((i > 1) & (i < 16))  { strip.setPixelColor(ii, 100, 0, 0);}
   if ((i > 17) & (i < 32)) { strip.setPixelColor(ii, 0, 100, 0);}
   if ((i > 33) & (i < 49)) { strip.setPixelColor(ii, 0, 0, 100);} 
   }
 }

В функцию eff_1 уже нужно вставлять то, что мы хотим индицировать на крутящейся полосе и что должно развернутся в рисунок.

Пока ради эксперимента и наглядности сделал три сегмента разных цветов.

https://www.youtube.com/watch?v=flEm-wQpx90

 

VALEK1809
Offline
Зарегистрирован: 08.01.2015

Доброе ввремя. mobistrike, в этом видео https://youtu.be/0llRyQKpjqc красные цифры я так понимаю скорость вращения? В чем она выражена и при какой минимальной скорости просмотривается строчка полностью?