Модернизация дисплея WS2812B от самопала
- Войдите на сайт для отправки комментариев
Ср, 23/09/2020 - 23:48
На самопале автор делал дисплей для часов 3х5, я же сделал 4х7. samopal.pro/ws2812-4
Вот оригинальный код:
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define PIXEL_COUNT 57
Adafruit_NeoPixel strip = Adafruit_NeoPixel(57, PIN, NEO_GRB + NEO_KHZ800);
/**
* Знакогенератор для цифр
*/
uint16_t DIGIT[] = {
0x1FBF, /* 0 */
0x1F00, /* 1 */
0x1DF7, /* 2 */
0x1FF5, /* 3 */
0x1F5C, /* 4 */
0x17FD, /* 5 */
0x17FF, /* 6 */
0x1F30, /* 7 */
0x1FFF, /* 8 */
0x1FFD /* 9 */
};
/**
* Смещение для каждой цифры
*/
uint8_t POSITION[] = { 0,14,30,44 };
unsigned int R_MASK[] = { 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000 };
// Буфер экрана
uint32_t SB[PIXEL_COUNT];
/*
* Очистка буфера обмена
*/
void Clear(){
for( int i=0; i<PIXEL_COUNT; i++ )SB[i] = 0;
}
/**
* Запись одного сивола в буфер
*@param c - сивол ( '0' - '9' )
*@param digit - разряд digit ( 0-4 )
*@param color - цвет и яркость
*/
void PutChar(char c,uint8_t digit,uint32_t color){
if( digit < 0 || digit > 3 )return;
uint16_t mask = 0;
switch(c){
case '0': mask = DIGIT[0]; break;
case '1': mask = DIGIT[1]; break;
case '2': mask = DIGIT[2]; break;
case '3': mask = DIGIT[3]; break;
case '4': mask = DIGIT[4]; break;
case '5': mask = DIGIT[5]; break;
case '6': mask = DIGIT[6]; break;
case '7': mask = DIGIT[7]; break;
case '8': mask = DIGIT[8]; break;
case '9': mask = DIGIT[9]; break;
default : mask = 0;
}
for( int i=0; i<13; i++ )
if( mask & R_MASK[i] )SB[POSITION[digit]+i] = color;
else SB[POSITION[digit]+i] = 0;
}
/**
* Отображение буфера на дисплее
*/
void Refresh(){
for( int i=0; i<PIXEL_COUNT; i++ )strip.setPixelColor(i,SB[i]);
strip.show(); // Initialize all pixels to 'off'
}
/**
* Формирование цвета радуги
* Input a value 0 to 255 to get a color value.
* The colours are a transition r - g - b - back to r.
*/
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
}
int t=9999;
uint32_t l0 = 0, l1 = 0, l2 = 0,l3=0;
uint32_t color = 0;
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
color = strip.Color(255, 0, 0);
Clear();
PutChar('0',0,color);
PutChar('0',1,color);
PutChar('0',2,color);
PutChar('0',3,color);
SB[43] = color;
Refresh();
}
void loop() {
uint32_t l = millis();
if( ( l-l1 ) >10000 || l<l1 ){
if( color == strip.Color(255, 0, 0) )color = strip.Color(0, 255, 0);
else if( color == strip.Color(0, 255, 0) )color = strip.Color(0, 0, 255);
else color = strip.Color(255, 0, 0);
SB[43] = color;
l1 = l;
}
if( ( l-l0 ) >100 || l<l0 ){
char c;
int t1;
c = '0'+t%10;
PutChar(c,3,color);
t1 = t/10;
c = '0'+t1%10;
PutChar(c,2,color);
t1 = t1/10;
c = '0'+t1%10;
PutChar(c,1,color);
t1 = t1/10;
c = '0'+t1;
PutChar(c,0,color);
t--;
if( t< 0 )t=9999;
Refresh();
l0=l;
}
}
Исходя из своих скромных знаний, изменил количество светодиодов, массив с цифрами (у меня они больше), начало цифр (подключены с конца и больше размером).
#include <Adafruit_NeoPixel.h>
#define PIN 6
#define PIXEL_COUNT 91
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIN, NEO_GRB + NEO_KHZ800);
/**
* Знакогенератор для цифр
*/
uint16_t DIGIT[] = {
0xff6ff, /* 0 */
0x7F, /* 1 */
0xf3ff9, /* 2 */
0x83fff, /* 3 */
0x1e97f, /* 4 */
0x9ffcf, /* 5 */
0xfffcf, /* 6 */
0x30ff, /* 7 */
0xfffff, /* 8 */
0x9ffff /* 9 */
};
/**
* Смещение для каждой цифры
*/
uint8_t POSITION[] = { 68, 47, 24, 3 };
// 3, 24, 47, 68
long R_MASK[20] = {
0x1,
0x2,
0x4,
0x8,
0x10,
0x20,
0x40,
0x80,
0x100,
0x200,
0x400,
0x800,
0x1000,
0x2000,
0x4000,
0x8000,
0x10000,
0x20000,
0x40000,
0x80000
};
// Буфер экрана
uint32_t SB[PIXEL_COUNT];
/*
* Очистка буфера обмена
*/
void Clear(){
for( int i=0; i<PIXEL_COUNT; i++ )SB[i] = 0;
}
/**
* Запись одного сивола в буфер
*@param c - сивол ( '0' - '9' )
*@param digit - разряд digit ( 0-4 )
*@param color - цвет и яркость
*/
void PutChar(char c,uint8_t digit,uint32_t color){
if( digit < 0 || digit > 3 )return;
uint16_t mask = 0;
switch(c){
case '0': mask = DIGIT[0]; break;
case '1': mask = DIGIT[1]; break;
case '2': mask = DIGIT[2]; break;
case '3': mask = DIGIT[3]; break;
case '4': mask = DIGIT[4]; break;
case '5': mask = DIGIT[5]; break;
case '6': mask = DIGIT[6]; break;
case '7': mask = DIGIT[7]; break;
case '8': mask = DIGIT[8]; break;
case '9': mask = DIGIT[9]; break;
default : mask = 0;
}
for( int i=0; i<20; i++ )
if( mask & R_MASK[i] )SB[POSITION[digit]+i] = color;
else SB[POSITION[digit]+i] = 0;
}
/**
* Отображение буфера на дисплее
*/
void Refresh(){
for( int i=0; i<PIXEL_COUNT; i++ )strip.setPixelColor(i,SB[i]);
strip.show(); // Initialize all pixels to 'off'
}
/**
* Формирование цвета радуги
* Input a value 0 to 255 to get a color value.
* The colours are a transition r - g - b - back to r.
*/
/*
uint32_t Wheel(byte WheelPos) {
if(WheelPos < 85) {
return strip.Color(WheelPos * 3, 7 - WheelPos * 3, 0);
} else if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(7 - WheelPos * 3, 0, WheelPos * 3);
} else {
WheelPos -= 170;
return strip.Color(0, WheelPos * 3, 7 - WheelPos * 3);
}
}
*/
int t=9999;
uint32_t l0 = 0, l1 = 0, l2 = 0,l3=0;
uint32_t color = 0;
void setup() {
strip.begin();
strip.show(); // Initialize all pixels to 'off'
color = strip.Color(7, 0, 0);
Clear();
PutChar('0',3,color);
PutChar('0',2,color);
PutChar('0',1,color);
PutChar('0',0,color);
SB[23] = color;
Refresh();
}
void loop() {
uint32_t l = millis();
if( ( l-l1 ) >10000 || l<l1 ){
if( color == strip.Color(7, 0, 0) )color = strip.Color(0, 7, 0);
else if( color == strip.Color(0, 7, 0) )color = strip.Color(0, 0, 7);
else color = strip.Color(7, 0, 0);
SB[23] = color;
l1 = l;
}
if( ( l-l0 ) >100 || l<l0 ){
char c;
int t1;
c = '0'+t%10;
PutChar(c,3,color);
t1 = t/10;
c = '0'+t1%10;
PutChar(c,2,color);
t1 = t1/10;
c = '0'+t1%10;
PutChar(c,1,color);
t1 = t1/10;
c = '0'+t1;
PutChar(c,0,color);
t--;
if( t< 0 )t=9999;
Refresh();
l0=l;
}
}
Цифры стали рисоваться, но только с 1 по 13 светодиод. Решил поменять R_MASK и теперь правильно отображается 16 светодиодов, а 4 посследних притворяются мертвыми (у каждой цифры). Есть мнение что виновата маска R_MASK, но как её правильно поменять не догоняю :(
Подскажите пожалуйста, натолкните на мысль - что я делаю не так, с чем поработать и познакомиться?
Объедените светодиоды на прямых участках физически, приведя к матрице 3х5.
К сожалению такой вариант невозможен. все диоды последовательно одной линией стоят
uint16_t DIGIT[] = { 0xff6ff, /* 0 */ 0x7F, /* 1 */ 0xf3ff9, /* 2 */ 0x83fff, /* 3 */ 0x1e97f, /* 4 */ 0x9ffcf, /* 5 */ 0xfffcf, /* 6 */ 0x30ff, /* 7 */ 0xfffff, /* 8 */ 0x9ffff /* 9 */ };Что то мне тут глаза режет в 10 строке ... компилятор не сообщает о противоречиях ?
Нет, все хорошо компилируется.
А вопрос решил - надо было размер буфера экрана сделать 32 битным вместо 16. Чувствовал что где-то рядом, а понять не мог...
#include <Adafruit_NeoPixel.h> #define PIN 2 #define PIXEL_COUNT 91 Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIN, NEO_GRB + NEO_KHZ800); /** * Знакогенератор для цифр */ uint32_t DIGIT[] = { 0xff6ff, /* 0 */ 0x7F, /* 1 */ 0xf3ff9, /* 2 */ 0x83fff, /* 3 */ 0x1e97f, /* 4 */ 0x9ffcf, /* 5 */ 0xfffcf, /* 6 */ 0x30ff, /* 7 */ 0xfffff, /* 8 */ 0x9ffff /* 9 */ }; /** * Смещение для каждой цифры */ uint32_t POSITION[] = { 68, 47, 24, 3 }; // 3, 24, 47, 68 long R_MASK[20] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, /* 0040010000000000000000 */ 0x20000, /* 00100000000000000000 */ 0x40000, /* 01000000000000000000 */ 0x80000 /* 10000000000000000000 */ }; // Буфер экрана uint32_t SB[PIXEL_COUNT]; /* * Очистка буфера обмена */ void Clear(){ for( int i=0; i<PIXEL_COUNT; i++ )SB[i] = 0; } /** * Запись одного сивола в буфер *@param c - сивол ( '0' - '9' ) *@param digit - разряд digit ( 0-4 ) *@param color - цвет и яркость */ void PutChar(char c,uint8_t digit,uint32_t color){ if( digit < 0 || digit > 3 )return; uint32_t mask = 0; switch(c){ case '0': mask = DIGIT[0]; break; case '1': mask = DIGIT[1]; break; case '2': mask = DIGIT[2]; break; case '3': mask = DIGIT[3]; break; case '4': mask = DIGIT[4]; break; case '5': mask = DIGIT[5]; break; case '6': mask = DIGIT[6]; break; case '7': mask = DIGIT[7]; break; case '8': mask = DIGIT[8]; break; case '9': mask = DIGIT[9]; break; default : mask = 0; } for( int i=0; i<20; i++ ) if( mask & R_MASK[i] )SB[POSITION[digit]+i] = color; else SB[POSITION[digit]+i] = 0; } /** * Отображение буфера на дисплее */ void Refresh(){ for( int i=0; i<PIXEL_COUNT; i++ )strip.setPixelColor(i,SB[i]); strip.show(); // Initialize all pixels to 'off' } /** * Формирование цвета радуги * Input a value 0 to 255 to get a color value. * The colours are a transition r - g - b - back to r. */ /* uint32_t Wheel(byte WheelPos) { if(WheelPos < 85) { return strip.Color(WheelPos * 3, 7 - WheelPos * 3, 0); } else if(WheelPos < 170) { WheelPos -= 85; return strip.Color(7 - WheelPos * 3, 0, WheelPos * 3); } else { WheelPos -= 170; return strip.Color(0, WheelPos * 3, 7 - WheelPos * 3); } } */ int t=9999; uint32_t l0 = 0, l1 = 0, l2 = 0,l3=0; uint32_t color = 0; void setup() { strip.begin(); strip.show(); // Initialize all pixels to 'off' color = strip.Color(7, 0, 0); Clear(); PutChar('0',3,color); PutChar('0',2,color); PutChar('0',1,color); PutChar('0',0,color); SB[23] = color; Refresh(); } void loop() { uint32_t l = millis(); if( ( l-l1 ) >10000 || l<l1 ){ if( color == strip.Color(7, 0, 0) )color = strip.Color(0, 7, 0); else if( color == strip.Color(0, 7, 0) )color = strip.Color(0, 0, 7); else color = strip.Color(7, 0, 0); SB[23] = color; l1 = l; } if( ( l-l0 ) >100 || l<l0 ){ char c; int t1; c = '0'+t%10; PutChar(c,3,color); t1 = t/10; c = '0'+t1%10; PutChar(c,2,color); t1 = t1/10; c = '0'+t1%10; PutChar(c,1,color); t1 = t1/10; c = '0'+t1; PutChar(c,0,color); t--; if( t< 0 )t=9999; Refresh(); l0=l; } }Вопрос закрыт, всем спасибо.
ТС, вообще то об этом тебе и сообщил Komandir.
Объявлен массив 16битных переменных, а в нем прописаны 24битные значения