https://create.arduino.cc/projecthub/Wi ... 87ada5?f=1
I'm stuck on the that requires you to load bitmap fonts onto a micro sd card, I have reasearch, and tried several things but I can't get the display to show any characters.
I'm looking to be pointed in the right direction, my questions are what type of file or files need to be on the sd card (.h? .bmp?.....)
Where can I find these file ?
Any help would be greatly appreciated.
Code: Select all
[#include <Adafruit_NeoPixel.h>
#include <Adafruit_ST7735.h>
#include <Adafruit_GFX.h>
#include <FastLED.h>
#include <SPI.h>
#include <SD.h>
#include <cactus_io_DHT22.h> // There's a bunch of DHTXX libraries you can find online. They all have varying levels of features.
// Define Pins
#define TFT_CS 10
#define TFT_RST 9
#define TFT_DC 8
#define DHT_PIN 2
#define PIXEL_PIN 6
#define PIXEL_NUM 24
#define SD_PIN 4
#define BMP_BUF 20
// Global Variables
int currentColor = 9999; //(Numbers correspond to chart. See below.)
CRGB leds[PIXEL_NUM];
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);
DHT22 dht(DHT_PIN);
int loopDelay = 2000; //ms
// SETUP
void setup() {
Serial.begin(9600);
Serial.println("Starting up.");
// Begin DHT
dht.begin();
// Initialize LCD Screen
tft.initR(INITR_144GREENTAB);
// Initialize SD Card
Serial.print("Initializing SD card.");
if (!SD.begin(SD_PIN)) {
Serial.println("Failed!");
return;
}
// Set Screen Background to Black
tft.fillScreen(ST7735_BLACK);
// Initialize LEDs
FastLED.addLeds<NEOPIXEL, PIXEL_PIN>(leds, PIXEL_NUM);
// Let everything catch up before starting loop
delay(500);
}
// LOOP
void loop() {
// Get Sensor Data
dht.readTemperature();
dht.readHumidity();
int f = dht.temperature_F; // Degrees in Fahrenheit
int h = dht.humidity; // Percentage
// Draw Degrees Icon
tft.fillCircle(102, 42, 6, ST7735_WHITE);
tft.fillCircle(102, 42, 4, ST7735_BLACK);
// Draw Temperature on LCD Screen
drawTemperature(f);
// Humidity
setHumidityColors(h);
//Print Data to Serial Monitor
Serial.print("Temperature: ");
Serial.println(f);
Serial.print("Humidity: ");
Serial.print(h);
Serial.println("%");
// Delay
delay(1000);
}
// Draw Bitmap - This is for the LCD Screen
void bmpDraw(char *filename, uint8_t x, uint8_t y) {
File bmpFile;
int bmpWidth, bmpHeight; // W+H in pixels
uint8_t bmpDepth; // Bit depth (currently must be 24)
uint32_t bmpImageoffset; // Start of image data in file
uint32_t rowSize; // Not always = bmpWidth; may have padding
uint8_t sdbuffer[3*BMP_BUF]; // pixel buffer (R+G+B per pixel)
uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer
boolean goodBmp = false; // Set to true on valid header parse
boolean flip = true; // BMP is stored bottom-to-top
int w, h, row, col;
uint8_t r, g, b;
uint32_t pos = 0, startTime = millis();
if((x >= tft.width()) || (y >= tft.height())) return;
// Serial.println();
// Serial.print("Loading Bitmap Image: '");
// Serial.print(filename);
// Serial.println('\'');
// Open requested file on SD card
if ((bmpFile = SD.open(filename)) == NULL) {
Serial.print("Bitmap file not found!");
return;
}
// Parse BMP header
if(read16(bmpFile) == 0x4D42) {
read32(bmpFile);
(void)read32(bmpFile);
bmpImageoffset = read32(bmpFile);
//Serial.println());
read32(bmpFile);
bmpWidth = read32(bmpFile);
bmpHeight = read32(bmpFile);
if(read16(bmpFile) == 1) {
bmpDepth = read16(bmpFile);
//Serial.print("Bit Depth: ");
if((bmpDepth == 24) && (read32(bmpFile) == 0)) {
goodBmp = true;
// BMP rows are padded (if needed) to 4-byte boundary
rowSize = (bmpWidth * 3 + 3) & ~3;
// If bmpHeight is negative, image is in top-down order.
// This is not canon but has been observed in the wild.
if(bmpHeight < 0) {
bmpHeight = -bmpHeight;
flip = false;
}
// Crop area to be loaded
w = bmpWidth;
h = bmpHeight;
if((x+w-1) >= tft.width()) w = tft.width() - x;
if((y+h-1) >= tft.height()) h = tft.height() - y;
// Set TFT address window to clipped image bounds
tft.setAddrWindow(x, y, x+w-1, y+h-1);
for (row=0; row<h; row++) { // For each scanline...
if(flip) {
pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize;
} else {
pos = bmpImageoffset + row * rowSize;
}
if(bmpFile.position() != pos) {
bmpFile.seek(pos);
buffidx = sizeof(sdbuffer);
}
for (col=0; col<w; col++) {
if (buffidx >= sizeof(sdbuffer)) {
bmpFile.read(sdbuffer, sizeof(sdbuffer));
buffidx = 0;
}
// Convert pixel from BMP to TFT format, push to display
b = sdbuffer[buffidx++];
g = sdbuffer[buffidx++];
r = sdbuffer[buffidx++];
tft.pushColor(tft.Color565(r,g,b));
}
}
}
}
}
bmpFile.close();
if(!goodBmp) Serial.println("BMP format not recognized.");
}
// This is for the Bitmap/LCD Screen
uint16_t read16(File f) {
uint16_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read(); // MSB
return result;
}
// This is for the Bitmap/LCD Screen
uint32_t read32(File f) {
uint32_t result;
((uint8_t *)&result)[0] = f.read(); // LSB
((uint8_t *)&result)[1] = f.read();
((uint8_t *)&result)[2] = f.read();
((uint8_t *)&result)[3] = f.read(); // MSB
return result;
}
// Draw Temperature on LCD Screen
void drawTemperature(int temp) {
// Get Number of Digits in the Temperature
int digits = numDigits(temp);
// Define Cursor Positions to Draw Bitmaps
int x1_2 = 62;
int x2_2 = 32;
int x1_3 = 1;
int x2_3 = 1;
int x3_3 = 1;
int y = 38;
char digit1[12];
char digit2[12];
char digit3[12];
char digitStr1[24];
char digitStr2[24];
char digitStr3[24];
// Get First Digit
itoa(temp % 10, digit1,10);
//Serial.println(temp % 10);
strcpy(digitStr1, "");
strcat(digitStr1, digit1);
strcat(digitStr1, ".bmp");
// Get Second Digit
if(digits == 2){
itoa((temp / 10) % 10, digit2,10);
strcpy(digitStr2, "");
strcat(digitStr2, digit2);
strcat(digitStr2, ".bmp");
}
// Get Third Digit
if(digits == 3){
itoa((temp / 100) % 10, digit3,10);
strcpy(digitStr3, "");
strcat(digitStr3, digit3);
strcat(digitStr3, ".bmp");
}
if(digits > 2){
bmpDraw(digitStr1,x1_3,y);
bmpDraw(digitStr2,x2_3,y);
bmpDraw(digitStr3,x3_3,y);
} else {
bmpDraw(digitStr1,x1_2,y);
bmpDraw(digitStr2,x2_2,y);
}
}
// Get number of digits in temperature to determine placement on screen
int numDigits(int number){
int valLen = 0;
if(number > 99)
valLen = 3;
else
valLen = 2;
return valLen;
}
// Set LED Colors
void setColors(int r, int g, int b){
for(int i = 0; i < PIXEL_NUM; i++){
leds[i].setRGB( r, g, b);
leds[i].fadeLightBy(125);
FastLED.show();
delay(100);
}
}
// Determine which colors to use based on Humidity level
void setHumidityColors(int humidity){
// Humidity Color Chart - This is just something we came up with.
// Red - 0-17%
// Orange - 18-34%
// Yellow - 35-51%
// Green - 52-68%
// Blue - 69-85%
// Purple - 86-100%
// Define Colors
int cRed[3] = {255,0,0};
int cOrange[3] = {255,90,0};
int cYellow[3] = {255,255,0};
int cGreen[3] = {0,255,0};
int cBlue[3] = {0,175,255};
int cPurple[3] = {255,0,255};
int range = map(humidity, 0, 100, 0, 6);
switch (range) {
case 0: // Red
if(currentColor == 0){
break;
}
else {
setColors(cRed[0], cRed[1], cRed[2]);
currentColor = 0;
}
break;
case 1: // Orange
if(currentColor == 1){
break;
}
else {
setColors(cOrange[0], cOrange[1], cOrange[2]);
currentColor = 1;
}
break;
case 2: // Yellow
if(currentColor == 2){
break;
}
else {
setColors(cYellow[0], cYellow[1], cYellow[2]);
currentColor = 2;
}
break;
case 3: // Green
if(currentColor == 3){
break;
}
else {
setColors(cGreen[0], cGreen[1], cGreen[2]);
currentColor = 3;
}
break;
case 4: // Blue
if(currentColor == 4){
break;
}
else {
setColors(cBlue[0], cBlue[1], cBlue[2]);
currentColor = 4;
}
break;
case 5: // Purple
if(currentColor == 5){
break;
}
else {
setColors(cPurple[0], cPurple[1], cPurple[2]);
currentColor = 5;
}
break;
}
}