Модернизация дисплея WS2812B от самопала

xorkrus
Offline
Зарегистрирован: 22.09.2013

На самопале автор делал дисплей для часов 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, но как её правильно поменять не догоняю :(

Подскажите пожалуйста, натолкните на мысль - что я делаю не так, с чем поработать и познакомиться?

mykaida
mykaida аватар
Offline
Зарегистрирован: 12.07.2018

Объедените светодиоды на прямых участках физически, приведя к матрице 3х5.

xorkrus
Offline
Зарегистрирован: 22.09.2013

К сожалению такой вариант невозможен. все диоды последовательно одной линией стоят

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018
uint16_t DIGIT[] = {
  0xff6ff, /* 0 */
  0x7F, /* 1 */
  0xf3ff9, /* 2 */
  0x83fff, /* 3 */
  0x1e97f, /* 4 */ 
  0x9ffcf, /* 5 */ 
  0xfffcf, /* 6 */ 
  0x30ff, /* 7 */ 
  0xfffff, /* 8 */ 
  0x9ffff  /* 9 */ 
  
};

Что то мне тут глаза режет в 10 строке  ... компилятор не сообщает о противоречиях ?

xorkrus
Offline
Зарегистрирован: 22.09.2013

Нет, все хорошо компилируется.

А вопрос решил - надо было размер буфера экрана сделать 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;
  }
}

Вопрос закрыт, всем спасибо.

Kakmyc
Offline
Зарегистрирован: 15.01.2018

ТС, вообще то об этом тебе и сообщил Komandir.
Объявлен массив 16битных переменных, а в нем прописаны 24битные значения