Модернизация дисплея 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.
К сожалению такой вариант невозможен. все диоды последовательно одной линией стоят
Что то мне тут глаза режет в 10 строке ... компилятор не сообщает о противоречиях ?
Нет, все хорошо компилируется.
А вопрос решил - надо было размер буфера экрана сделать 32 битным вместо 16. Чувствовал что где-то рядом, а понять не мог...
Вопрос закрыт, всем спасибо.
ТС, вообще то об этом тебе и сообщил Komandir.
Объявлен массив 16битных переменных, а в нем прописаны 24битные значения