// Generated by : UTFTConverter v0.1
// Generated from : smiley_tongue_24.jpg
// Time generated : 2017-04-24 16:31:50.352856 UTC
// Image Size : 24x24 pixels
// Memory usage : 1152 bytes
#if defined(__AVR__)
#include <avr/pgmspace.h>
#elif defined(__PIC32MX__)
#define PROGMEM
#elif defined(__arm__)
#define PROGMEM
#endif
const unsigned short
bitmap24[576] PROGMEM =
{
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0010 (16) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0020 (32) pixels
0x0000, 0x0000, 0x4207, 0xFFDD, 0xCE57, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0030 (48) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0xFFBB, 0xFF56, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xE564, 0xFF99, // 0x0040 (64) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0xAD33, 0xF6D1, 0xE501, // 0x0050 (80) pixels
0xE501, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xE501, 0xFF9A, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0060 (96) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0xFFBB, 0xE501,
0xE501, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xE501, 0xE501, // 0x0070 (112) pixels
0xE501, 0xE501, 0xFF57, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFFDC,
0xE501, 0xE501, 0xDD01, 0xE501, // 0x0080 (128) pixels
0xE501, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xDD01, 0xE501, 0xE501, 0xFF78,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0090 (144) pixels
0x0000, 0x0000, 0x0000, 0xE501, 0xDD01, 0xE501,
0xE501, 0xE501, 0xE501, 0xE501, 0xE502, 0xE501,
0xE501, 0xDD01, 0xDD01, 0xE501, // 0x00A0 (160) pixels
0xE501, 0xDD01, 0xE501, 0xE501, 0xE501, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0xFF99, 0xE501,
0xE502, 0xE501, 0x4A69, 0x4A6A, // 0x00B0 (176) pixels
0xE501, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xE502, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xDD01, 0x0000, 0x0000, 0x0000, // 0x00C0 (192) pixels
0x0000, 0x0000, 0xE501, 0xE501, 0xE501, 0x0000,
0x0000, 0x0000, 0x0000, 0x94B2, 0xE501, 0xE502,
0xE501, 0xE501, 0xE501, 0xE501, // 0x00D0 (208) pixels
0xDD01, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0x0000, 0x0000, 0x0000, 0xFFDC, 0xE501, 0xE501,
0xE501, 0x0000, 0x4A69, 0xE502, // 0x00E0 (224) pixels
0x4A69, 0x0000, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0x4A69, 0x0000, 0x0000, 0xE501, 0xE501,
0xE501, 0xFF58, 0x0000, 0x0000, // 0x00F0 (240) pixels
0x0000, 0xFF9A, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xE501, 0x94B3, 0xE501, 0xE501,
0xE501, 0xE502, 0x0000, 0x0000, // 0x0100 (256) pixels
0x4A69, 0x0000, 0x0000, 0xE501, 0xE501, 0xE5A7,
0x0000, 0x0000, 0x0000, 0xFF79, 0xE501, 0xE501,
0xE501, 0xE501, 0xE501, 0xDD01, // 0x0110 (272) pixels
0xE501, 0xE501, 0xE501, 0xE501, 0xE501, 0xE502,
0x94B2, 0xE501, 0xE501, 0xE501, 0x0000, 0xDD01,
0xDD01, 0xE501, 0x0000, 0x0000, // 0x0120 (288) pixels
0x0000, 0xFF79, 0xE501, 0xE501, 0xFE31, 0xFD91,
0xF5B0, 0xF5F1, 0xF5EC, 0xE501, 0xDD01, 0xE501,
0xE501, 0xE501, 0xE501, 0xE501, // 0x0130 (304) pixels
0xE501, 0xE501, 0xE501, 0xE502, 0xE501, 0xE501,
0x0000, 0x0000, 0x0000, 0xFF9A, 0xE501, 0xE501,
0xFE31, 0xF4D0, 0xF800, 0xF800, // 0x0140 (320) pixels
0xF800, 0xDC4D, 0xE4AE, 0xE50F, 0xED90, 0xFE52,
0xE501, 0xE501, 0xE502, 0xE501, 0xE501, 0xE501,
0xE501, 0xEDA7, 0x0000, 0x0000, // 0x0150 (336) pixels
0x0000, 0xFFDC, 0xE501, 0xE501, 0xED66, 0xE48E,
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xDBAC,
0xE40D, 0xF4F0, 0xF4F0, 0xF530, // 0x0160 (352) pixels
0xFD91, 0xE501, 0xE501, 0xE501, 0xE501, 0xFF57,
0x0000, 0x0000, 0x0000, 0x0000, 0xE501, 0xE501,
0xE501, 0xF800, 0xF800, 0xF800, // 0x0170 (368) pixels
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800,
0xF800, 0xF4F0, 0xFDB1, 0xDD01, 0xE501, 0xE501,
0xE501, 0xE501, 0x0000, 0x0000, // 0x0180 (384) pixels
0x0000, 0x0000, 0xFF78, 0xE501, 0xED70, 0xF800,
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF800,
0xF800, 0xF800, 0xF800, 0xF550, // 0x0190 (400) pixels
0xE501, 0xE501, 0xDD01, 0xE501, 0xE501, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xE501,
0xE50E, 0xF800, 0xF800, 0xF800, // 0x01A0 (416) pixels
0xF800, 0xF800, 0xF800, 0xF800, 0xF800, 0xF4F0,
0xF550, 0xE501, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0x0000, 0x0000, 0x0000, // 0x01B0 (432) pixels
0x0000, 0x0000, 0x0000, 0xFFBC, 0xED90, 0xDC0D,
0xE30A, 0xF800, 0xF800, 0xDC0C, 0xE46E, 0xF510,
0xF570, 0xFE11, 0xE501, 0xE502, // 0x01C0 (448) pixels
0xDD01, 0xE501, 0xE501, 0xFF77, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0xFF7A, 0xE4AE, 0xE3CB, 0xE36A, // 0x01D0 (464) pixels
0xDBCC, 0xDC8E, 0xE501, 0xE501, 0xE501, 0xE501,
0xE501, 0xE501, 0xE501, 0xE501, 0xFF57, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x01E0 (480) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF9C,
0xEDD2, 0xED2F, 0xEDB0, 0xDD01, 0xE501, 0xE501,
0xDD01, 0xE501, 0xE521, 0xE501, // 0x01F0 (496) pixels
0xE501, 0xFF99, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0xFFBB, // 0x0200 (512) pixels
0xFF55, 0xE501, 0xE501, 0xE501, 0xE501, 0xE502,
0xE501, 0xFF79, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0210 (528) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0xEF5B, 0xE501,
0xE501, 0x2103, 0x0000, 0x0000, // 0x0220 (544) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0230 (560) pixels
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, // 0x0240 (576) pixels
};
// Generated by : UTFTConverter v0.1
// Generated from : google.jpg
// Time generated : 2018-02-08 06:09:41.424425 UTC
// Image Size : 32x32 pixels
// Memory usage : 2048 bytes
#if defined(__AVR__)
#include <avr/pgmspace.h>
#elif defined(__PIC32MX__)
#define PROGMEM
#elif defined(__arm__)
#define PROGMEM
#endif
const unsigned short
bitmap32[1024] PROGMEM =
{
0xFFFE, 0xFFFE, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
0xFFDF, 0xFFDF, 0xFFFE, 0xFFFE, 0xFFFE, 0xFFFE,
0xFFFF, 0xFFFF, 0xFFDF, 0xFFDF, // 0x0010 (16) pixels
0xFFFF, 0xFFFF, 0xFFDE, 0xFFDE, 0xFFFF, 0xFFFF,
0xFFDF, 0xFFFF, 0xFFFE, 0xFFDE, 0xFFFE, 0xFFFE,
0xFFFF, 0xFFFF, 0xFFBF, 0xFFDF, // 0x0020 (32) pixels
0xFFFE, 0x0840, 0x0820, 0x0841, 0x0040, 0x0020,
0x1020, 0x0800, 0x0040, 0x0060, 0x0020, 0x0840,
0x0000, 0x0040, 0x1022, 0x0821, // 0x0030 (48) pixels
0x0861, 0x0020, 0x1020, 0x0800, 0x0820, 0x0820,
0x0001, 0x0821, 0x0800, 0x1020, 0x0820, 0x1040,
0x0041, 0x0021, 0x0821, 0xFFDF, // 0x0040 (64) pixels
0xFFFF, 0x0021, 0x0042, 0x1926, 0x343A, 0x1B98,
0x02F7, 0x0318, 0x031A, 0x033A, 0x43F8, 0x8E7F,
0xF7DF, 0xEF9F, 0xEF9D, 0xEFBD, // 0x0050 (80) pixels
0xEBF0, 0x9966, 0xE801, 0xE001, 0xD821, 0xD800,
0xE001, 0xE000, 0xD820, 0xD000, 0xD001, 0xC000,
0x3020, 0x2800, 0x0861, 0xF7FF, // 0x0060 (96) pixels
0xFFFF, 0x0021, 0x10E5, 0xB5D8, 0x2BF9, 0x0B36,
0x02F7, 0x0338, 0x031A, 0x031A, 0x2315, 0x54BB,
0xE75E, 0xF7FF, 0xF7FE, 0xFFFF, // 0x0070 (112) pixels
0xFE9B, 0xCAEC, 0xE801, 0xE801, 0xD821, 0xD800,
0xE801, 0xE001, 0xD800, 0xE040, 0xD042, 0xD022,
0x5964, 0x2800, 0x0020, 0xFFFF, // 0x0080 (128) pixels
0xFFFD, 0x0880, 0xB63C, 0x9D58, 0x0BBB, 0x0339,
0x0B1B, 0x02DB, 0x02F8, 0x0B39, 0x031B, 0x139C,
0x9E1B, 0xE7FF, 0xFFFF, 0xFFDE, // 0x0090 (144) pixels
0xFFDE, 0xC5B5, 0xF863, 0xE000, 0xE001, 0xE001,
0xD821, 0xD821, 0xE020, 0xD800, 0xF000, 0xF000,
0xC801, 0xC800, 0x0040, 0xFFFE, // 0x00A0 (160) pixels
0xFFFD, 0x10C0, 0xD71F, 0xA59A, 0x0B9A, 0x0339,
0x0B3C, 0x02FB, 0x0B39, 0x0B19, 0x02FA, 0x0B7C,
0x6C95, 0xD7DF, 0xFFFF, 0xFFDE, // 0x00B0 (176) pixels
0xFFDE, 0xEEDA, 0xF8C4, 0xE801, 0xE001, 0xE001,
0xE041, 0xD821, 0xE020, 0xE000, 0xF801, 0xF801,
0xD022, 0xC801, 0x0860, 0xFFFD, // 0x00C0 (192) pixels
0xFFFF, 0x62EB, 0xCF5E, 0x9597, 0x1BB9, 0x1337,
0x02D9, 0x031A, 0x0319, 0x0319, 0x031B, 0x033B,
0x4396, 0xB71F, 0xFFFE, 0xFFFE, // 0x00D0 (208) pixels
0xFFBF, 0xFF1C, 0xF924, 0xE041, 0xF000, 0xF000,
0xE820, 0xE000, 0xF000, 0xF800, 0xE000, 0xD800,
0xD801, 0xD801, 0x4947, 0xFF9F, // 0x00E0 (224) pixels
0xFFFF, 0x738D, 0xCF7F, 0xAE7B, 0x23B9, 0x0B37,
0x02FA, 0x0B1A, 0x0339, 0x0339, 0x033C, 0x031B,
0x3B76, 0x963F, 0xFFFE, 0xFFFE, // 0x00F0 (240) pixels
0xFF9E, 0xFF3D, 0xF945, 0xD820, 0xF801, 0xF800,
0xE800, 0xE820, 0xF800, 0xF800, 0xE821, 0xE020,
0xE001, 0xD800, 0x5167, 0xFF7F, // 0x0100 (256) pixels
0xFFFF, 0x6B8F, 0xE71D, 0xE6FD, 0x4439, 0x2335,
0x033A, 0x035A, 0x0317, 0x0B58, 0x0319, 0x0319,
0x2B76, 0x7E1F, 0xF7FF, 0xFFFF, // 0x0110 (272) pixels
0xFF7E, 0xFE7A, 0xE904, 0xD021, 0xB8C2, 0xB8C2,
0xA8C0, 0xB101, 0xC881, 0xC880, 0xF001, 0xF001,
0xE000, 0xD800, 0x5166, 0xFF9E, // 0x0120 (288) pixels
0xF7BF, 0x73B0, 0xEF3E, 0xF79F, 0x655E, 0x2356,
0x037B, 0x033A, 0x0B58, 0x0316, 0x0319, 0x033A,
0x2356, 0x7E1F, 0xFFFF, 0xF7FF, // 0x0130 (304) pixels
0xFF9E, 0xCCF4, 0xE0A3, 0xD862, 0xB8C2, 0xC0E2,
0xB942, 0xB101, 0xC8A1, 0xC8A1, 0xF001, 0xF001,
0xD800, 0xD800, 0x5166, 0xFFBF, // 0x0140 (320) pixels
0xFFFE, 0x6B6C, 0xFEFC, 0xFF7E, 0xAEFF, 0x3B94,
0x039D, 0x033B, 0x0358, 0x0379, 0x033C, 0x035C,
0x3B74, 0x963E, 0xFFFF, 0xFFFF, // 0x0150 (336) pixels
0xD7FC, 0x5C6D, 0x13C6, 0x1C07, 0x1407, 0x1407,
0x04C8, 0x0487, 0x1BE7, 0x1BE7, 0x3B45, 0x3324,
0xA101, 0xA0C0, 0x4984, 0xFFDD, // 0x0160 (352) pixels
0xFFFE, 0x73AD, 0xFF1C, 0xFF9E, 0xD7FF, 0x85DD,
0x03BE, 0x039D, 0x0358, 0x0358, 0x035C, 0x035C,
0x5437, 0xBF9F, 0xFFFF, 0xFFBE, // 0x0170 (368) pixels
0x7D72, 0x3B49, 0x1C07, 0x1C07, 0x1448, 0x1448,
0x04A8, 0x04A8, 0x1C28, 0x1C28, 0x4386, 0x3B86,
0xB142, 0xA101, 0x4984, 0xFFDD, // 0x0180 (384) pixels
0xFFFF, 0x6350, 0xDFBC, 0xEFFD, 0xFFDE, 0xF77D,
0x853A, 0x4B53, 0x2375, 0x2355, 0x3B34, 0x5C18,
0xC63A, 0xFFFF, 0xCFFC, 0x6E11, // 0x0190 (400) pixels
0x04A8, 0x0467, 0x04A7, 0x0487, 0x0466, 0x0C86,
0x0486, 0x04A6, 0x0467, 0x0488, 0x04A7, 0x04C7,
0x0447, 0x03E6, 0x41A8, 0xFFDF, // 0x01A0 (416) pixels
0xFFFF, 0x422B, 0xCF19, 0xEFFD, 0xFFFF, 0xFFFF,
0xE7FF, 0xB69F, 0x6D9E, 0x655D, 0x95DF, 0xC75F,
0xFFDF, 0xFFBF, 0x5D8F, 0x23A8, // 0x01B0 (432) pixels
0x0487, 0x04A8, 0x04A7, 0x04A7, 0x0466, 0x0C86,
0x04C7, 0x04A6, 0x0488, 0x0488, 0x04A7, 0x04A7,
0x0467, 0x0406, 0x49C8, 0xFFDF, // 0x01C0 (448) pixels
0xF7FF, 0x2968, 0x3C5B, 0x7E7F, 0xD7DF, 0xE7FF,
0xEFFF, 0xEFFF, 0xFFFF, 0xF7DF, 0xFFFF, 0xFFBF,
0xD7FC, 0x652F, 0x0487, 0x04A7, // 0x01D0 (464) pixels
0x1447, 0x1447, 0x04A8, 0x0488, 0x0467, 0x0467,
0x0C68, 0x0447, 0x0489, 0x0489, 0x0468, 0x0488,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x01E0 (480) pixels
0xFFFF, 0x2127, 0x1336, 0x1B97, 0x6433, 0x74D6,
0x9539, 0x9D9A, 0xE75E, 0xFFFF, 0xFFBF, 0xFFFF,
0xAF57, 0x3388, 0x0487, 0x04A8, // 0x01F0 (496) pixels
0x1427, 0x1427, 0x04A8, 0x0488, 0x04A8, 0x0467,
0x0C68, 0x0C68, 0x0469, 0x0469, 0x0468, 0x0488,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x0200 (512) pixels
0xEFFF, 0x1147, 0x02D9, 0x033A, 0x0B1A, 0x0B1A,
0x137A, 0x349E, 0xF79D, 0xFFFE, 0xFFDF, 0xFFDF,
0x9F9A, 0x23CB, 0x0467, 0x0488, // 0x0210 (528) pixels
0x0C48, 0x0C47, 0x0487, 0x04A7, 0x04A7, 0x04A7,
0x0488, 0x0488, 0x0488, 0x0488, 0x0488, 0x04A8,
0x0428, 0x03E7, 0x3227, 0xF7FF, // 0x0220 (544) pixels
0xEFFF, 0x1167, 0x02D9, 0x02F9, 0x0B1A, 0x02FA,
0x0B39, 0x2C3D, 0xF7DD, 0xFFFE, 0xFFBE, 0xFFDF,
0xC7FF, 0x7E55, 0x0467, 0x0467, // 0x0230 (560) pixels
0x0C68, 0x0C68, 0x04A7, 0x0466, 0x04C7, 0x0486,
0x0467, 0x04A8, 0x0488, 0x0488, 0x0488, 0x04A8,
0x0428, 0x03E7, 0x3227, 0xF7FF, // 0x0240 (576) pixels
0xEFFF, 0x1948, 0x02F7, 0x02F7, 0x0338, 0x0338,
0x0337, 0x243A, 0xCE9D, 0xF7FF, 0xFFFF, 0xFFFF,
0xFFFD, 0xFFFD, 0x9674, 0x43EA, // 0x0250 (592) pixels
0x0447, 0x0488, 0x04A7, 0x04E8, 0x0446, 0x0487,
0x0CA8, 0x0467, 0x0C67, 0x0C67, 0x0487, 0x0487,
0x0468, 0x0427, 0x3A26, 0xFFFE, // 0x0260 (608) pixels
0xF7FF, 0x1948, 0x02F7, 0x0338, 0x0B99, 0x13BA,
0x1BD9, 0x2C7C, 0xA558, 0xF7DF, 0xFFFF, 0xFFFF,
0xFFFD, 0xFFFD, 0xDFFD, 0xB758, // 0x0270 (624) pixels
0x1D8C, 0x0488, 0x0487, 0x0487, 0x0CA8, 0x0467,
0x0C88, 0x0467, 0x0C67, 0x0C67, 0x0487, 0x0487,
0x0468, 0x0427, 0x3A26, 0xFFFE, // 0x0280 (640) pixels
0xEFFF, 0x1186, 0x5336, 0x743A, 0x9558, 0xB63B,
0xCF1A, 0xD75B, 0xFF9A, 0xFFDB, 0xFFFD, 0xFFFD,
0xFFFF, 0xFFDF, 0xFFFF, 0xFFFF, // 0x0290 (656) pixels
0xD79B, 0x640D, 0x0C48, 0x0C69, 0x0447, 0x0447,
0x0C68, 0x0447, 0x0467, 0x0467, 0x0487, 0x0487,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x02A0 (672) pixels
0xE7FF, 0x3ACB, 0xAE1F, 0xDF7F, 0xEFFF, 0xEFFF,
0xEFFE, 0xE7BD, 0xFF58, 0xF738, 0xF73A, 0xFF9C,
0xF7DF, 0xFFFF, 0xFFFF, 0xFFFF, // 0x02B0 (688) pixels
0xEFFE, 0xDFBC, 0x1CEB, 0x0428, 0x0C68, 0x0447,
0x0447, 0x0C68, 0x0467, 0x0467, 0x0487, 0x0487,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x02C0 (704) pixels
0xFFFF, 0x738F, 0xF736, 0xFF98, 0xFF0D, 0xFE6B,
0xF646, 0xF625, 0xFDA3, 0xFE04, 0xEDC4, 0xFE66,
0xFF34, 0xFFB6, 0xFFDE, 0xFFFF, // 0x02D0 (720) pixels
0xFFBF, 0xFFDF, 0x9F78, 0x23A9, 0x0468, 0x04CA,
0x0448, 0x0489, 0x04A8, 0x04A8, 0x0487, 0x0487,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x02E0 (736) pixels
0xFFDF, 0x736F, 0xE6B4, 0xD653, 0xEDE8, 0xE5A7,
0xE5C4, 0xEDE4, 0xFD82, 0xF582, 0xEDC4, 0xEDE4,
0xE5AE, 0xFEB2, 0xFFFF, 0xFFFF, // 0x02F0 (752) pixels
0xFFDF, 0xFFBF, 0xC7FD, 0x552F, 0x0488, 0x0468,
0x0488, 0x0468, 0x04A8, 0x04A8, 0x0487, 0x0487,
0x0448, 0x0407, 0x3227, 0xF7FF, // 0x0300 (768) pixels
0xFFFD, 0x734A, 0xE584, 0xEDC5, 0xF5C1, 0xF5C1,
0xEDC0, 0xEDC0, 0xED82, 0xF5A2, 0xE5E1, 0xE5E1,
0xFDC1, 0xFDE2, 0xE6B2, 0xFFF7, // 0x0310 (784) pixels
0xFFFF, 0xF7FF, 0xEFFE, 0xA5D4, 0x0448, 0x0C89,
0x0468, 0x0468, 0x0487, 0x04A7, 0x0447, 0x0447,
0x0469, 0x03E7, 0x2A27, 0xEFFF, // 0x0320 (800) pixels
0xFFDD, 0x5AA8, 0xDD43, 0xDD64, 0xED80, 0xF5C1,
0xF5E0, 0xEDC0, 0xF5A2, 0xF5A3, 0xE5E1, 0xE5C1,
0xF5A1, 0xF5A1, 0xD60F, 0xF713, // 0x0330 (816) pixels
0xF7FF, 0xFFFF, 0xF7FE, 0xB656, 0x0427, 0x0448,
0x0488, 0x0468, 0x0487, 0x04C8, 0x0C88, 0x0426,
0x0468, 0x03E6, 0x21E6, 0xF7FF, // 0x0340 (832) pixels
0xF7FF, 0x00A2, 0xE501, 0xED62, 0xFD81, 0xFD81,
0xF562, 0xFDA3, 0xE5C0, 0xEDE0, 0xEDC1, 0xEDA0,
0xF5C0, 0xF5C0, 0xEDE3, 0xFE65, // 0x0350 (848) pixels
0xFFDE, 0xFFDE, 0xE7FC, 0xA634, 0x0487, 0x04A8,
0x0488, 0x0467, 0x04C7, 0x0487, 0x0466, 0x0487,
0x1408, 0x0BC7, 0x08A1, 0xFFFE, // 0x0360 (864) pixels
0xF7FF, 0x0060, 0xC420, 0xE542, 0xFD81, 0xFDA2,
0xFDA3, 0xF562, 0xEDE1, 0xEDE1, 0xF5E1, 0xEDC1,
0xF5C0, 0xF5C0, 0xEDC3, 0xFE24, // 0x0370 (880) pixels
0xFFBD, 0xFFDE, 0xEFFD, 0x8551, 0x0487, 0x04A7,
0x0488, 0x0488, 0x04A7, 0x04A7, 0x0487, 0x0487,
0x0BE7, 0x0345, 0x0040, 0xFFFE, // 0x0380 (896) pixels
0xFFDF, 0x0823, 0x3120, 0xACEC, 0xED83, 0xE542,
0xE582, 0xEDA3, 0xF564, 0xED64, 0xF561, 0xF561,
0xF561, 0xF561, 0xDDA7, 0xEE29, // 0x0390 (912) pixels
0xFF5C, 0xFFDF, 0xB7FB, 0x3C4B, 0x0448, 0x0489,
0x1429, 0x1429, 0x0C28, 0x0C69, 0x1408, 0x13E7,
0x3308, 0x0161, 0x0800, 0xFFFF, // 0x03A0 (928) pixels
0xFFDF, 0x0002, 0x1880, 0x3120, 0xC460, 0xDD22,
0xEDA3, 0xDD41, 0xED43, 0xE523, 0xED41, 0xED41,
0xED41, 0xED41, 0xDDA7, 0xEE29, // 0x03B0 (944) pixels
0xFF7D, 0xFF7D, 0x7E73, 0x23A9, 0x0428, 0x0448,
0x0BE8, 0x0BE8, 0x0428, 0x0408, 0x1407, 0x0345,
0x0100, 0x0080, 0x1020, 0xFFFF, // 0x03C0 (960) pixels
0xFFFE, 0x0020, 0x0802, 0x0802, 0x0040, 0x0080,
0x0020, 0x0840, 0x0840, 0x0820, 0x0801, 0x0801,
0x0020, 0x0020, 0x0040, 0x0060, // 0x03D0 (976) pixels
0x0000, 0x1062, 0x0040, 0x0060, 0x1820, 0x1000,
0x0020, 0x0040, 0x0040, 0x0060, 0x0060, 0x00A0,
0x0841, 0x0800, 0x0042, 0xF7FF, // 0x03E0 (992) pixels
0xFFFE, 0xFFFE, 0xFFDF, 0xFFBF, 0xF7FF, 0xF7FF,
0xFFFE, 0xFFFF, 0xFFFE, 0xFFFD, 0xFFFF, 0xFFFF,
0xFFFF, 0xFFFF, 0xFFFF, 0xF7FF, // 0x03F0 (1008) pixels
0xFFFF, 0xFFDF, 0xEFFF, 0xF7FF, 0xFFBE, 0xFFDF,
0xFFFF, 0xFFFF, 0xF7FF, 0xF7FE, 0xF7FF, 0xF7FE,
0xFFFF, 0xFFFF, 0xF7FF, 0xFFFF, // 0x0400 (1024) pixels
};
// Adafruit_NeoMatrix example for single NeoPixel Shield.
// By Marc MERLIN <[email protected]>
// Contains code (c) Adafruit, license BSD
#include <Adafruit_GFX.h>
#include <Adafruit_NeoMatrix.h>
#include <Adafruit_NeoPixel.h>
// Choose your prefered pixmap
//#include "heart24.h"
//#include "yellowsmiley24.h"
//#include "bluesmiley24.h"
//#include "smileytongue24.h"
#ifndef PSTR
#define PSTR // Make Arduino Due happy
#endif
#define PIN 2
// ESP8266 has an I2S neopixel library which can only use pin RX
// so it's recommended to use the same pin with Neopixel to avoid
// rewiring when changing libs
#ifdef ESP8266
#define PIN RX
#endif
//#define P32BY8X4
#define P16BY16X4
#if defined(P32BY8X4) || defined(P16BY16X4)
#define BM32
#endif
#ifdef BM32
//#include "google32.h"
// Anything with black does not look so good with the naked eye (better on pictures)
//#include "linux32.h"
#endif
// Max is 255, 32 is a conservative value to not overload
// a USB power supply (500mA) for 12x12 pixels.
#define BRIGHTNESS 255
// MATRIX DECLARATION:
// Parameter 1 = width of EACH NEOPIXEL MATRIX (not total display)
// Parameter 2 = height of each matrix
// Parameter 3 = number of matrices arranged horizontally
// Parameter 4 = number of matrices arranged vertically
// Parameter 5 = pin number (most are valid)
// Parameter 6 = matrix layout flags, add together as needed:
// NEO_MATRIX_TOP, NEO_MATRIX_BOTTOM, NEO_MATRIX_LEFT, NEO_MATRIX_RIGHT:
// Position of the FIRST LED in the FIRST MATRIX; pick two, e.g.
// NEO_MATRIX_TOP + NEO_MATRIX_LEFT for the top-left corner.
// NEO_MATRIX_ROWS, NEO_MATRIX_COLUMNS: LEDs WITHIN EACH MATRIX are
// arranged in horizontal rows or in vertical columns, respectively;
// pick one or the other.
// NEO_MATRIX_PROGRESSIVE, NEO_MATRIX_ZIGZAG: all rows/columns WITHIN
// EACH MATRIX proceed in the same order, or alternate lines reverse
// direction; pick one.
// NEO_TILE_TOP, NEO_TILE_BOTTOM, NEO_TILE_LEFT, NEO_TILE_RIGHT:
// Position of the FIRST MATRIX (tile) in the OVERALL DISPLAY; pick
// two, e.g. NEO_TILE_TOP + NEO_TILE_LEFT for the top-left corner.
// NEO_TILE_ROWS, NEO_TILE_COLUMNS: the matrices in the OVERALL DISPLAY
// are arranged in horizontal rows or in vertical columns, respectively;
// pick one or the other.
// NEO_TILE_PROGRESSIVE, NEO_TILE_ZIGZAG: the ROWS/COLUMS OF MATRICES
// (tiles) in the OVERALL DISPLAY proceed in the same order for every
// line, or alternate lines reverse direction; pick one. When using
// zig-zag order, the orientation of the matrices in alternate rows
// will be rotated 180 degrees (this is normal -- simplifies wiring).
// See example below for these values in action.
// Parameter 7 = pixel type flags, add together as needed:
// NEO_RGB Pixels are wired for RGB bitstream (v1 pixels)
// NEO_GRB Pixels are wired for GRB bitstream (v2 pixels)
// NEO_KHZ400 400 KHz bitstream (e.g. FLORA v1 pixels)
// NEO_KHZ800 800 KHz bitstream (e.g. High Density LED strip)
// Define full matrix width and height.
#define mw 32
#define mh 32
Adafruit_NeoMatrix *matrix = new Adafruit_NeoMatrix(32, 32, PIN,
NEO_MATRIX_RIGHT + NEO_MATRIX_RIGHT +
NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
NEO_GRB + NEO_KHZ800);
// This could also be defined as matrix->color(255,0,0) but those defines
// are meant to work for adafruit_gfx backends that are lacking color()
#define LED_BLACK 0
#define LED_RED_VERYLOW (3 << 11)
#define LED_RED_LOW (7 << 11)
#define LED_RED_MEDIUM (15 << 11)
#define LED_RED_HIGH (31 << 11)
#define LED_GREEN_VERYLOW (1 << 5)
#define LED_GREEN_LOW (15 << 5)
#define LED_GREEN_MEDIUM (31 << 5)
#define LED_GREEN_HIGH (63 << 5)
#define LED_BLUE_VERYLOW 3
#define LED_BLUE_LOW 7
#define LED_BLUE_MEDIUM 15
#define LED_BLUE_HIGH 31
#define LED_ORANGE_VERYLOW (LED_RED_VERYLOW + LED_GREEN_VERYLOW)
#define LED_ORANGE_LOW (LED_RED_LOW + LED_GREEN_LOW)
#define LED_ORANGE_MEDIUM (LED_RED_MEDIUM + LED_GREEN_MEDIUM)
#define LED_ORANGE_HIGH (LED_RED_HIGH + LED_GREEN_HIGH)
#define LED_PURPLE_VERYLOW (LED_RED_VERYLOW + LED_BLUE_VERYLOW)
#define LED_PURPLE_LOW (LED_RED_LOW + LED_BLUE_LOW)
#define LED_PURPLE_MEDIUM (LED_RED_MEDIUM + LED_BLUE_MEDIUM)
#define LED_PURPLE_HIGH (LED_RED_HIGH + LED_BLUE_HIGH)
#define LED_CYAN_VERYLOW (LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
#define LED_CYAN_LOW (LED_GREEN_LOW + LED_BLUE_LOW)
#define LED_CYAN_MEDIUM (LED_GREEN_MEDIUM + LED_BLUE_MEDIUM)
#define LED_CYAN_HIGH (LED_GREEN_HIGH + LED_BLUE_HIGH)
#define LED_WHITE_VERYLOW (LED_RED_VERYLOW + LED_GREEN_VERYLOW + LED_BLUE_VERYLOW)
#define LED_WHITE_LOW (LED_RED_LOW + LED_GREEN_LOW + LED_BLUE_LOW)
#define LED_WHITE_MEDIUM (LED_RED_MEDIUM + LED_GREEN_MEDIUM + LED_BLUE_MEDIUM)
#define LED_WHITE_HIGH (LED_RED_HIGH + LED_GREEN_HIGH + LED_BLUE_HIGH)
static const uint8_t PROGMEM
mono_bmp[][8] =
{
{ // 0: checkered 1
B10101010,
B01010101,
B10101010,
B01010101,
B10101010,
B01010101,
B10101010,
B01010101,
},
{ // 1: checkered 2
B01010101,
B10101010,
B01010101,
B10101010,
B01010101,
B10101010,
B01010101,
B10101010,
},
{ // 2: smiley
B00111100,
B01000010,
B10100101,
B10000001,
B10100101,
B10011001,
B01000010,
B00111100 },
{ // 3: neutral
B00111100,
B01000010,
B10100101,
B10000001,
B10111101,
B10000001,
B01000010,
B00111100 },
{ // 4; frowny
B00111100,
B01000010,
B10100101,
B10000001,
B10011001,
B10100101,
B01000010,
B00111100 },
};
static const uint16_t PROGMEM
// These bitmaps were written for a backend that only supported
// 4 bits per color with Blue/Green/Red ordering while neomatrix
// uses native 565 color mapping as RGB.
// I'm leaving the arrays as is because it's easier to read
// which color is what when separated on a 4bit boundary
// The demo code will modify the arrays at runtime to be compatible
// with the neomatrix color ordering and bit depth.
RGB_bmp[][64] = {
// 00: blue, blue/red, red, red/green, green, green/blue, blue, white
{ 0x100, 0x200, 0x300, 0x400, 0x600, 0x800, 0xA00, 0xF00,
0x101, 0x202, 0x303, 0x404, 0x606, 0x808, 0xA0A, 0xF0F,
0x001, 0x002, 0x003, 0x004, 0x006, 0x008, 0x00A, 0x00F,
0x011, 0x022, 0x033, 0x044, 0x066, 0x088, 0x0AA, 0x0FF,
0x010, 0x020, 0x030, 0x040, 0x060, 0x080, 0x0A0, 0x0F0,
0x110, 0x220, 0x330, 0x440, 0x660, 0x880, 0xAA0, 0xFF0,
0x100, 0x200, 0x300, 0x400, 0x600, 0x800, 0xA00, 0xF00,
0x111, 0x222, 0x333, 0x444, 0x666, 0x888, 0xAAA, 0xFFF, },
// 01: grey to white
{ 0x111, 0x222, 0x333, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
0x222, 0x222, 0x333, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
0x333, 0x333, 0x333, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
0x555, 0x555, 0x555, 0x555, 0x777, 0x999, 0xAAA, 0xFFF,
0x777, 0x777, 0x777, 0x777, 0x777, 0x999, 0xAAA, 0xFFF,
0x999, 0x999, 0x999, 0x999, 0x999, 0x999, 0xAAA, 0xFFF,
0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xAAA, 0xFFF,
0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, 0xFFF, },
// 02: low red to high red
{ 0x001, 0x002, 0x003, 0x005, 0x007, 0x009, 0x00A, 0x00F,
0x002, 0x002, 0x003, 0x005, 0x007, 0x009, 0x00A, 0x00F,
0x003, 0x003, 0x003, 0x005, 0x007, 0x009, 0x00A, 0x00F,
0x005, 0x005, 0x005, 0x005, 0x007, 0x009, 0x00A, 0x00F,
0x007, 0x007, 0x007, 0x007, 0x007, 0x009, 0x00A, 0x00F,
0x009, 0x009, 0x009, 0x009, 0x009, 0x009, 0x00A, 0x00F,
0x00A, 0x00A, 0x00A, 0x00A, 0x00A, 0x00A, 0x00A, 0x00F,
0x00F, 0x00F, 0x00F, 0x00F, 0x00F, 0x00F, 0x00F, 0x00F, },
// 03: low green to high green
{ 0x010, 0x020, 0x030, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
0x020, 0x020, 0x030, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
0x030, 0x030, 0x030, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
0x050, 0x050, 0x050, 0x050, 0x070, 0x090, 0x0A0, 0x0F0,
0x070, 0x070, 0x070, 0x070, 0x070, 0x090, 0x0A0, 0x0F0,
0x090, 0x090, 0x090, 0x090, 0x090, 0x090, 0x0A0, 0x0F0,
0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0A0, 0x0F0,
0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, 0x0F0, },
// 04: low blue to high blue
{ 0x100, 0x200, 0x300, 0x500, 0x700, 0x900, 0xA00, 0xF00,
0x200, 0x200, 0x300, 0x500, 0x700, 0x900, 0xA00, 0xF00,
0x300, 0x300, 0x300, 0x500, 0x700, 0x900, 0xA00, 0xF00,
0x500, 0x500, 0x500, 0x500, 0x700, 0x900, 0xA00, 0xF00,
0x700, 0x700, 0x700, 0x700, 0x700, 0x900, 0xA00, 0xF00,
0x900, 0x900, 0x900, 0x900, 0x900, 0x900, 0xA00, 0xF00,
0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xA00, 0xF00,
0xF00, 0xF00, 0xF00, 0xF00, 0xF00, 0xF00, 0xF00, 0xF00, },
// 05: 1 black, 2R, 2O, 2G, 1B with 4 blue lines rising right
{ 0x000, 0x200, 0x000, 0x400, 0x000, 0x800, 0x000, 0xF00,
0x000, 0x201, 0x002, 0x403, 0x004, 0x805, 0x006, 0xF07,
0x008, 0x209, 0x00A, 0x40B, 0x00C, 0x80D, 0x00E, 0xF0F,
0x000, 0x211, 0x022, 0x433, 0x044, 0x855, 0x066, 0xF77,
0x088, 0x299, 0x0AA, 0x4BB, 0x0CC, 0x8DD, 0x0EE, 0xFFF,
0x000, 0x210, 0x020, 0x430, 0x040, 0x850, 0x060, 0xF70,
0x080, 0x290, 0x0A0, 0x4B0, 0x0C0, 0x8D0, 0x0E0, 0xFF0,
0x000, 0x200, 0x000, 0x500, 0x000, 0x800, 0x000, 0xF00, },
// 06: 4 lines of increasing red and then green
{ 0x000, 0x000, 0x001, 0x001, 0x002, 0x002, 0x003, 0x003,
0x004, 0x004, 0x005, 0x005, 0x006, 0x006, 0x007, 0x007,
0x008, 0x008, 0x009, 0x009, 0x00A, 0x00A, 0x00B, 0x00B,
0x00C, 0x00C, 0x00D, 0x00D, 0x00E, 0x00E, 0x00F, 0x00F,
0x000, 0x000, 0x010, 0x010, 0x020, 0x020, 0x030, 0x030,
0x040, 0x040, 0x050, 0x050, 0x060, 0x060, 0x070, 0x070,
0x080, 0x080, 0x090, 0x090, 0x0A0, 0x0A0, 0x0B0, 0x0B0,
0x0C0, 0x0C0, 0x0D0, 0x0D0, 0x0E0, 0x0E0, 0x0F0, 0x0F0, },
// 07: 4 lines of increasing red and then blue
{ 0x000, 0x000, 0x001, 0x001, 0x002, 0x002, 0x003, 0x003,
0x004, 0x004, 0x005, 0x005, 0x006, 0x006, 0x007, 0x007,
0x008, 0x008, 0x009, 0x009, 0x00A, 0x00A, 0x00B, 0x00B,
0x00C, 0x00C, 0x00D, 0x00D, 0x00E, 0x00E, 0x00F, 0x00F,
0x000, 0x000, 0x100, 0x100, 0x200, 0x200, 0x300, 0x300,
0x400, 0x400, 0x500, 0x500, 0x600, 0x600, 0x700, 0x700,
0x800, 0x800, 0x900, 0x900, 0xA00, 0xA00, 0xB00, 0xB00,
0xC00, 0xC00, 0xD00, 0xD00, 0xE00, 0xE00, 0xF00, 0xF00, },
// 08: criss cross of green and red with diagonal blue.
{ 0xF00, 0x001, 0x003, 0x005, 0x007, 0x00A, 0x00F, 0x000,
0x020, 0xF21, 0x023, 0x025, 0x027, 0x02A, 0x02F, 0x020,
0x040, 0x041, 0xF43, 0x045, 0x047, 0x04A, 0x04F, 0x040,
0x060, 0x061, 0x063, 0xF65, 0x067, 0x06A, 0x06F, 0x060,
0x080, 0x081, 0x083, 0x085, 0xF87, 0x08A, 0x08F, 0x080,
0x0A0, 0x0A1, 0x0A3, 0x0A5, 0x0A7, 0xFAA, 0x0AF, 0x0A0,
0x0F0, 0x0F1, 0x0F3, 0x0F5, 0x0F7, 0x0FA, 0xFFF, 0x0F0,
0x000, 0x001, 0x003, 0x005, 0x007, 0x00A, 0x00F, 0xF00, },
// 09: 2 lines of green, 2 red, 2 orange, 2 green
{ 0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0,
0x0F0, 0x0F0, 0x0FF, 0x0FF, 0x00F, 0x00F, 0x0F0, 0x0F0, },
// 10: multicolor smiley face
{ 0x000, 0x000, 0x00F, 0x00F, 0x00F, 0x00F, 0x000, 0x000,
0x000, 0x00F, 0x000, 0x000, 0x000, 0x000, 0x00F, 0x000,
0x00F, 0x000, 0xF00, 0x000, 0x000, 0xF00, 0x000, 0x00F,
0x00F, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x00F,
0x00F, 0x000, 0x0F0, 0x000, 0x000, 0x0F0, 0x000, 0x00F,
0x00F, 0x000, 0x000, 0x0F4, 0x0F3, 0x000, 0x000, 0x00F,
0x000, 0x00F, 0x000, 0x000, 0x000, 0x000, 0x00F, 0x000,
0x000, 0x000, 0x00F, 0x00F, 0x00F, 0x00F, 0x000, 0x000, },
};
// Convert a BGR 4/4/4 bitmap to RGB 5/6/5 used by Adafruit_GFX
void fixdrawRGBBitmap(int16_t x, int16_t y, const uint16_t *bitmap, int16_t w, int16_t h) {
// work around "a15 cannot be used in asm here" compiler bug when using an array on ESP8266
// uint16_t RGB_bmp_fixed[w * h];
static uint16_t *RGB_bmp_fixed = (uint16_t *) malloc( w*h*2);
for (uint16_t pixel=0; pixel<w*h; pixel++) {
uint8_t r,g,b;
uint16_t color = pgm_read_word(bitmap + pixel);
//Serial.print(color, HEX);
b = (color & 0xF00) >> 8;
g = (color & 0x0F0) >> 4;
r = color & 0x00F;
//Serial.print(" ");
//Serial.print(b);
//Serial.print("/");
//Serial.print(g);
//Serial.print("/");
//Serial.print(r);
//Serial.print(" -> ");
// expand from 4/4/4 bits per color to 5/6/5
b = map(b, 0, 15, 0, 31);
g = map(g, 0, 15, 0, 63);
r = map(r, 0, 15, 0, 31);
//Serial.print(r);
//Serial.print("/");
//Serial.print(g);
//Serial.print("/");
//Serial.print(b);
RGB_bmp_fixed[pixel] = (r << 11) + (g << 5) + b;
//Serial.print(" -> ");
//Serial.println(RGB_bmp_fixed[pixel], HEX);
}
matrix->drawRGBBitmap(x, y, RGB_bmp_fixed, w, h);
}
// In a case of a tile of neomatrices, this test is helpful to make sure that the
// pixels are all in sequence (to check your wiring order and the tile options you
// gave to the constructor).
void count_pixels() {
matrix->clear();
for (uint16_t i=0; i<mh; i++) {
for (uint16_t j=0; j<mw; j++) {
matrix->drawPixel(j, i, i%3==0?LED_BLUE_HIGH:i%3==1?LED_RED_HIGH:LED_GREEN_HIGH);
// depending on the matrix size, it's too slow to display each pixel, so
// make the scan init faster. This will however be too fast on a small matrix.
if (!(j%7)) matrix->show();
yield();
}
}
}
// Fill the screen with multiple levels of white to gauge the quality
void display_four_white() {
matrix->clear();
matrix->fillRect(0,0, mw,mh, LED_WHITE_HIGH);
matrix->drawRect(1,1, mw-2,mh-2, LED_WHITE_MEDIUM);
matrix->drawRect(2,2, mw-4,mh-4, LED_WHITE_LOW);
matrix->drawRect(3,3, mw-6,mh-6, LED_WHITE_VERYLOW);
matrix->show();
}
void display_bitmap(uint8_t bmp_num, uint16_t color) {
static uint16_t bmx,bmy;
// Clear the space under the bitmap that will be drawn as
// drawing a single color pixmap does not write over pixels
// that are nul, and leaves the data that was underneath
matrix->fillRect(bmx,bmy, bmx+8,bmy+8, LED_BLACK);
matrix->drawBitmap(bmx, bmy, mono_bmp[bmp_num], 8, 8, color);
bmx += 8;
if (bmx >= mw) bmx = 0;
if (!bmx) bmy += 8;
if (bmy >= mh) bmy = 0;
matrix->show();
}
void display_rgbBitmap(uint8_t bmp_num) {
static uint16_t bmx,bmy;
fixdrawRGBBitmap(bmx, bmy, RGB_bmp[bmp_num], 8, 8);
bmx += 8;
if (bmx >= mw) bmx = 0;
if (!bmx) bmy += 8;
if (bmy >= mh) bmy = 0;
matrix->show();
}
void display_lines() {
matrix->clear();
// 4 levels of crossing red lines.
matrix->drawLine(0,mh/2-2, mw-1,2, LED_RED_VERYLOW);
matrix->drawLine(0,mh/2-1, mw-1,3, LED_RED_LOW);
matrix->drawLine(0,mh/2, mw-1,mh/2, LED_RED_MEDIUM);
matrix->drawLine(0,mh/2+1, mw-1,mh/2+1, LED_RED_HIGH);
// 4 levels of crossing green lines.
matrix->drawLine(mw/2-2, 0, mw/2-2, mh-1, LED_GREEN_VERYLOW);
matrix->drawLine(mw/2-1, 0, mw/2-1, mh-1, LED_GREEN_LOW);
matrix->drawLine(mw/2+0, 0, mw/2+0, mh-1, LED_GREEN_MEDIUM);
matrix->drawLine(mw/2+1, 0, mw/2+1, mh-1, LED_GREEN_HIGH);
// Diagonal blue line.
matrix->drawLine(0,0, mw-1,mh-1, LED_BLUE_HIGH);
matrix->drawLine(0,mh-1, mw-1,0, LED_ORANGE_MEDIUM);
matrix->show();
}
void display_boxes() {
matrix->clear();
matrix->drawRect(0,0, mw,mh, LED_BLUE_HIGH);
matrix->drawRect(1,1, mw-2,mh-2, LED_GREEN_MEDIUM);
matrix->fillRect(2,2, mw-4,mh-4, LED_RED_HIGH);
matrix->fillRect(3,3, mw-6,mh-6, LED_ORANGE_MEDIUM);
matrix->show();
}
void display_circles() {
matrix->clear();
matrix->drawCircle(mw/2,mh/2, 2, LED_RED_MEDIUM);
matrix->drawCircle(mw/2-1-min(mw,mh)/8, mh/2-1-min(mw,mh)/8, min(mw,mh)/4, LED_BLUE_HIGH);
matrix->drawCircle(mw/2+1+min(mw,mh)/8, mh/2+1+min(mw,mh)/8, min(mw,mh)/4-1, LED_ORANGE_MEDIUM);
matrix->drawCircle(1,mh-2, 1, LED_GREEN_LOW);
matrix->drawCircle(mw-2,1, 1, LED_GREEN_HIGH);
if (min(mw,mh)>12) matrix->drawCircle(mw/2-1, mh/2-1, min(mh/2-1,mw/2-1), LED_CYAN_HIGH);
matrix->show();
}
void display_resolution() {
matrix->setTextSize(1);
// not wide enough;
if (mw<16) return;
matrix->clear();
// Font is 5x7, if display is too small
// 8 can only display 1 char
// 16 can almost display 3 chars
// 24 can display 4 chars
// 32 can display 5 chars
matrix->setCursor(0, 0);
matrix->setTextColor(matrix->Color(255,0,0));
if (mw>10) matrix->print(mw/10);
matrix->setTextColor(matrix->Color(255,128,0));
matrix->print(mw % 10);
matrix->setTextColor(matrix->Color(0,255,0));
matrix->print('x');
// not wide enough to print 5 chars, go to next line
if (mw<25) {
if (mh==13) matrix->setCursor(6, 7);
else if (mh>=13) {
matrix->setCursor(mw-11, 8);
} else {
// we're not tall enough either, so we wait and display
// the 2nd value on top.
matrix->show();
delay(2000);
matrix->clear();
matrix->setCursor(mw-11, 0);
}
}
matrix->setTextColor(matrix->Color(0,255,128));
matrix->print(mh/10);
matrix->setTextColor(matrix->Color(0,128,255));
matrix->print(mh % 10);
// enough room for a 2nd line
if ((mw>25 && mh >14) || mh>16) {
matrix->setCursor(0, mh-7);
matrix->setTextColor(matrix->Color(0,255,255));
if (mw>16) matrix->print('*');
matrix->setTextColor(matrix->Color(255,0,0));
matrix->print('R');
matrix->setTextColor(matrix->Color(0,255,0));
matrix->print('G');
matrix->setTextColor(matrix->Color(0,0,255));
matrix->print("B");
matrix->setTextColor(matrix->Color(255,255,0));
// this one could be displayed off screen, but we don't care :)
matrix->print("*");
// We have a big array, great, let's assume 32x32 and add something in the middle
if (mh>24 && mw>25) {
for (uint16_t i=0; i<mw; i+=8) fixdrawRGBBitmap(i, mh/2-7+(i%16)/8*6, RGB_bmp[10], 8, 8);
}
}
matrix->show();
}
void display_scrollText() {
uint8_t size = max(int(mw/8), 1);
matrix->clear();
matrix->setTextWrap(false); // we don't wrap text so it scrolls nicely
matrix->setTextSize(1);
matrix->setRotation(0);
for (int8_t x=7; x>=-42; x--) {
matrix->clear();
matrix->setCursor(x,0);
matrix->setTextColor(LED_GREEN_HIGH);
matrix->print("Hello");
if (mh>11) {
matrix->setCursor(-20-x,mh-7);
matrix->setTextColor(LED_ORANGE_HIGH);
matrix->print("World");
}
matrix->show();
delay(50);
}
matrix->setRotation(3);
matrix->setTextSize(size);
matrix->setTextColor(LED_BLUE_HIGH);
for (int16_t x=8*size; x>=-6*8*size; x--) {
matrix->clear();
matrix->setCursor(x,mw/2-size*4);
matrix->print("Rotate");
matrix->show();
// note that on a big array the refresh rate from show() will be slow enough that
// the delay become irrelevant. This is already true on a 32x32 array.
delay(50/size);
}
matrix->setRotation(0);
matrix->setCursor(0,0);
matrix->show();
}
// Scroll within big bitmap so that all if it becomes visible or bounce a small one.
// If the bitmap is bigger in one dimension and smaller in the other one, it will
// be both panned and bounced in the appropriate dimensions.
void display_panOrBounceBitmap (uint8_t bitmapSize) {
// keep integer math, deal with values 16 times too big
// start by showing upper left of big bitmap or centering if the display is big
int16_t xf = max(0, (mw-bitmapSize)/2) << 4;
int16_t yf = max(0, (mh-bitmapSize)/2) << 4;
// scroll speed in 1/16th
int16_t xfc = 6;
int16_t yfc = 3;
// scroll down and right by moving upper left corner off screen
// more up and left (which means negative numbers)
int16_t xfdir = -1;
int16_t yfdir = -1;
for (uint16_t i=1; i<200; i++) {
bool updDir = false;
// Get actual x/y by dividing by 16.
int16_t x = xf >> 4;
int16_t y = yf >> 4;
matrix->clear();
// bounce 8x8 tri color smiley face around the screen
if (bitmapSize == 8) fixdrawRGBBitmap(x, y, RGB_bmp[10], 8, 8);
// pan 24x24 pixmap
if (bitmapSize == 24) matrix->drawRGBBitmap(x, y, (const uint16_t *) bitmap24, bitmapSize, bitmapSize);
#ifdef BM32
if (bitmapSize == 32) matrix->drawRGBBitmap(x, y, (const uint16_t *) bitmap32, bitmapSize, bitmapSize);
#endif
matrix->show();
// Only pan if the display size is smaller than the pixmap
// but not if the difference is too small or it'll look bad.
if (bitmapSize-mw>2) {
xf += xfc*xfdir;
if (xf >= 0) { xfdir = -1; updDir = true ; };
// we don't go negative past right corner, go back positive
if (xf <= ((mw-bitmapSize) << 4)) { xfdir = 1; updDir = true ; };
}
if (bitmapSize-mh>2) {
yf += yfc*yfdir;
// we shouldn't display past left corner, reverse direction.
if (yf >= 0) { yfdir = -1; updDir = true ; };
if (yf <= ((mh-bitmapSize) << 4)) { yfdir = 1; updDir = true ; };
}
// only bounce a pixmap if it's smaller than the display size
if (mw>bitmapSize) {
xf += xfc*xfdir;
// Deal with bouncing off the 'walls'
if (xf >= (mw-bitmapSize) << 4) { xfdir = -1; updDir = true ; };
if (xf <= 0) { xfdir = 1; updDir = true ; };
}
if (mh>bitmapSize) {
yf += yfc*yfdir;
if (yf >= (mh-bitmapSize) << 4) { yfdir = -1; updDir = true ; };
if (yf <= 0) { yfdir = 1; updDir = true ; };
}
if (updDir) {
// Add -1, 0 or 1 but bind result to 1 to 1.
// Let's take 3 is a minimum speed, otherwise it's too slow.
xfc = constrain(xfc + random(-1, 2), 3, 16);
yfc = constrain(xfc + random(-1, 2), 3, 16);
}
delay(10);
}
}
void loop() {
// clear the screen after X bitmaps have been displayed and we
// loop back to the top left corner
// 8x8 => 1, 16x8 => 2, 17x9 => 6
static uint8_t pixmap_count = ((mw+7)/8) * ((mh+7)/8);
// You can't use millis to time frame fresh rate because it uses cli() which breaks millis()
// So I use my stopwatch to count 200 displays and that's good enough
#if 0
// 200 displays in 13 seconds = 15 frames per second for 4096 pixels
for (uint8_t i=0; i<100; i++) {
matrix->fillScreen(LED_BLUE_LOW);
matrix->show();
matrix->fillScreen(LED_RED_LOW);
matrix->show();
}
#endif
count_pixels();
delay(1000);
display_four_white();
delay(3000);
Serial.print("Screen pixmap capacity: ");
Serial.println(pixmap_count);
// multicolor bitmap sent as many times as we can display an 8x8 pixmap
for (uint8_t i=0; i<=pixmap_count; i++)
{
display_rgbBitmap(0);
}
delay(1000);
display_resolution();
delay(3000);
// Cycle through red, green, blue, display 2 checkered patterns
// useful to debug some screen types and alignment.
uint16_t bmpcolor[] = { LED_GREEN_HIGH, LED_BLUE_HIGH, LED_RED_HIGH };
for (uint8_t i=0; i<3; i++)
{
display_bitmap(0, bmpcolor[i]);
delay(500);
display_bitmap(1, bmpcolor[i]);
delay(500);
}
// Display 3 smiley faces.
for (uint8_t i=2; i<=4; i++)
{
display_bitmap(i, bmpcolor[i-2]);
// If more than one pixmap displayed per screen, display more quickly.
delay(mw>8?500:1500);
}
// If we have multiple pixmaps displayed at once, wait a bit longer on the last.
delay(mw>8?1000:500);
display_lines();
delay(3000);
display_boxes();
delay(3000);
display_circles();
matrix->clear();
delay(3000);
for (uint8_t i=0; i<=(sizeof(RGB_bmp)/sizeof(RGB_bmp[0])-1); i++)
{
display_rgbBitmap(i);
delay(mw>8?500:1500);
}
// If we have multiple pixmaps displayed at once, wait a bit longer on the last.
delay(mw>8?1000:500);
display_scrollText();
#ifdef BM32
display_panOrBounceBitmap(32);
#endif
// pan a big pixmap
display_panOrBounceBitmap(24);
// bounce around a small one
display_panOrBounceBitmap(8);
}
void setup() {
Serial.begin(115200);
matrix->begin();
matrix->setTextWrap(false);
matrix->setBrightness(BRIGHTNESS);
// Test full bright of all LEDs. If brightness is too high
// for your current limit (i.e. USB), decrease it.
matrix->fillScreen(LED_WHITE_HIGH);
matrix->show();
delay(3000);
matrix->clear();
}
// vim:sts=4:sw=4