@@ -77,30 +77,43 @@ void IRAM_ATTR display_flush_callback(lv_display_t *disp, const lv_area_t *area,
7777 for (int32_t x = 0 ; x < w; x++)
7878 {
7979 // Read 16-bit pixel (RGB565)
80- uint16_t pixel = src_row[x * 2 ] | (src_row[x * 2 + 1 ] << 8 );
80+ uint16_t px = src_row[x * 2 ] | (src_row[x * 2 + 1 ] << 8 );
81+
82+ // Extract raw channel bits
83+ uint8_t r5 = (px >> 11 ) & 0x1F ;
84+ uint8_t g6 = (px >> 5 ) & 0x3F ;
85+ uint8_t b5 = px & 0x1F ;
86+
87+ // Cheap summed brightness
88+ uint16_t bright = r5 + g6 + b5;
89+
90+ uint8_t color;
91+
92+ // Black (very low brightness)
93+ if (bright < 20 ) {
94+ color = 1 ; // BLACK
95+ }
96+ // Red (strong R, weak G/B)
97+ else if (r5 > 20 && g6 < 16 && b5 < 16 ) {
98+ color = 2 ; // RED
99+ }
100+ // White (all channels fairly high)
101+ else if (r5 > 20 && g6 > 20 && b5 > 20 ) {
102+ color = 0 ; // WHITE
103+ }
104+ // Otherwise classify into nearest
105+ else {
106+ // Slightly warm → red
107+ if (r5 > g6 && r5 > b5)
108+ color = 1 ;
109+ // Otherwise → white
110+ else
111+ color = 2 ;
112+ }
81113
82- // Extract RGB components
83- uint8_t r = (pixel >> 11 ) & 0x1F ;
84- uint8_t g = (pixel >> 5 ) & 0x3F ;
85- uint8_t b = pixel & 0x1F ;
86-
87- // Scale up to 8-bit per channel
88- r = (r * 255 ) / 31 ;
89- g = (g * 255 ) / 63 ;
90- b = (b * 255 ) / 31 ;
91-
92- // Convert to brightness
93- uint8_t gray = (uint8_t )((r * 0 .299f ) + (g * 0 .587f ) + (b * 0 .114f ));
114+ self->writePixelInternal (area->x1 + x, area->y1 + y, color);
94115
95- uint16_t color;
96- if (gray < 85 )
97- color = 1 ; // Black
98- else if (gray > 180 )
99- color = 0 ; // Red
100- else
101- color = 2 ; // White
102116
103- self->writePixelInternal (area->x1 + x, area->y1 + y, color);
104117 }
105118 }
106119 }
0 commit comments