#include #include #include #include #include #include #include // 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(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= 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; } }