Components and supplies
Arduino UNO
Jumper wires (generic)
Breadboard (generic)
NeoPixel Ring: WS2812 5050 RGB LED
DHT22 Temperature Sensor
4xAA battery holder
Adafruit 1.44" Color TFT LCD Display with MicroSD Card breakout - ST7735R
Tools and machines
Soldering iron (generic)
Hot glue gun (generic)
Project description
Code
Arduino Work Shop Sensor Code
arduino
1#include <Adafruit_NeoPixel.h> 2#include <Adafruit_ST7735.h> 3#include <Adafruit_GFX.h> 4#include <FastLED.h> 5#include <SPI.h> 6#include <SD.h> 7#include <cactus_io_DHT22.h> // There's a bunch of DHTXX libraries you can find online. They all have varying levels of features. 8 9// Define Pins 10#define TFT_CS 10 11#define TFT_RST 9 12#define TFT_DC 8 13#define DHT_PIN 2 14#define PIXEL_PIN 6 15#define PIXEL_NUM 24 16#define SD_PIN 4 17#define BMP_BUF 20 18 19// Global Variables 20int currentColor = 9999; //(Numbers correspond to chart. See below.) 21CRGB leds[PIXEL_NUM]; 22Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 23DHT22 dht(DHT_PIN); 24int loopDelay = 2000; //ms 25 26// SETUP 27void setup() { 28 29 Serial.begin(9600); 30 Serial.println("Starting up."); 31 32 // Begin DHT 33 dht.begin(); 34 35 // Initialize LCD Screen 36 tft.initR(INITR_144GREENTAB); 37 38 // Initialize SD Card 39 Serial.print("Initializing SD card."); 40 if (!SD.begin(SD_PIN)) { 41 Serial.println("Failed!"); 42 return; 43 } 44 45 // Set Screen Background to Black 46 tft.fillScreen(ST7735_BLACK); 47 48 // Initialize LEDs 49 FastLED.addLeds<NEOPIXEL, PIXEL_PIN>(leds, PIXEL_NUM); 50 51 // Let everything catch up before starting loop 52 delay(500); 53 54} 55 56 57// LOOP 58void loop() { 59 60 // Get Sensor Data 61 dht.readTemperature(); 62 dht.readHumidity(); 63 int f = dht.temperature_F; // Degrees in Fahrenheit 64 int h = dht.humidity; // Percentage 65 66 // Draw Degrees Icon 67 tft.fillCircle(102, 42, 6, ST7735_WHITE); 68 tft.fillCircle(102, 42, 4, ST7735_BLACK); 69 70 // Draw Temperature on LCD Screen 71 drawTemperature(f); 72 73 // Humidity 74 setHumidityColors(h); 75 76 //Print Data to Serial Monitor 77 Serial.print("Temperature: "); 78 Serial.println(f); 79 Serial.print("Humidity: "); 80 Serial.print(h); 81 Serial.println("%"); 82 83 // Delay 84 delay(1000); 85 86} 87 88 89// Draw Bitmap - This is for the LCD Screen 90void bmpDraw(char *filename, uint8_t x, uint8_t y) { 91 92 File bmpFile; 93 int bmpWidth, bmpHeight; // W+H in pixels 94 uint8_t bmpDepth; // Bit depth (currently must be 24) 95 uint32_t bmpImageoffset; // Start of image data in file 96 uint32_t rowSize; // Not always = bmpWidth; may have padding 97 uint8_t sdbuffer[3*BMP_BUF]; // pixel buffer (R+G+B per pixel) 98 uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer 99 boolean goodBmp = false; // Set to true on valid header parse 100 boolean flip = true; // BMP is stored bottom-to-top 101 int w, h, row, col; 102 uint8_t r, g, b; 103 uint32_t pos = 0, startTime = millis(); 104 105 if((x >= tft.width()) || (y >= tft.height())) return; 106 107// Serial.println(); 108// Serial.print("Loading Bitmap Image: '"); 109// Serial.print(filename); 110// Serial.println('\\''); 111 112 // Open requested file on SD card 113 if ((bmpFile = SD.open(filename)) == NULL) { 114 Serial.print("Bitmap file not found!"); 115 return; 116 } 117 118 // Parse BMP header 119 if(read16(bmpFile) == 0x4D42) { 120 read32(bmpFile); 121 (void)read32(bmpFile); 122 bmpImageoffset = read32(bmpFile); 123 //Serial.println()); 124 read32(bmpFile); 125 bmpWidth = read32(bmpFile); 126 bmpHeight = read32(bmpFile); 127 if(read16(bmpFile) == 1) { 128 bmpDepth = read16(bmpFile); 129 //Serial.print("Bit Depth: "); 130 if((bmpDepth == 24) && (read32(bmpFile) == 0)) { 131 132 goodBmp = true; 133 134 // BMP rows are padded (if needed) to 4-byte boundary 135 rowSize = (bmpWidth * 3 + 3) & ~3; 136 137 // If bmpHeight is negative, image is in top-down order. 138 // This is not canon but has been observed in the wild. 139 if(bmpHeight < 0) { 140 bmpHeight = -bmpHeight; 141 flip = false; 142 } 143 144 // Crop area to be loaded 145 w = bmpWidth; 146 h = bmpHeight; 147 if((x+w-1) >= tft.width()) w = tft.width() - x; 148 if((y+h-1) >= tft.height()) h = tft.height() - y; 149 150 // Set TFT address window to clipped image bounds 151 tft.setAddrWindow(x, y, x+w-1, y+h-1); 152 153 for (row=0; row<h; row++) { // For each scanline... 154 if(flip) { 155 pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize; 156 } else { 157 pos = bmpImageoffset + row * rowSize; 158 } 159 if(bmpFile.position() != pos) { 160 bmpFile.seek(pos); 161 buffidx = sizeof(sdbuffer); 162 } 163 164 for (col=0; col<w; col++) { 165 if (buffidx >= sizeof(sdbuffer)) { 166 bmpFile.read(sdbuffer, sizeof(sdbuffer)); 167 buffidx = 0; 168 } 169 170 // Convert pixel from BMP to TFT format, push to display 171 b = sdbuffer[buffidx++]; 172 g = sdbuffer[buffidx++]; 173 r = sdbuffer[buffidx++]; 174 tft.pushColor(tft.Color565(r,g,b)); 175 } 176 } 177 } 178 } 179 } 180 181 bmpFile.close(); 182 if(!goodBmp) Serial.println("BMP format not recognized."); 183 184} 185 186// This is for the Bitmap/LCD Screen 187uint16_t read16(File f) { 188 uint16_t result; 189 ((uint8_t *)&result)[0] = f.read(); // LSB 190 ((uint8_t *)&result)[1] = f.read(); // MSB 191 return result; 192} 193 194// This is for the Bitmap/LCD Screen 195uint32_t read32(File f) { 196 uint32_t result; 197 ((uint8_t *)&result)[0] = f.read(); // LSB 198 ((uint8_t *)&result)[1] = f.read(); 199 ((uint8_t *)&result)[2] = f.read(); 200 ((uint8_t *)&result)[3] = f.read(); // MSB 201 return result; 202} 203 204 205// Draw Temperature on LCD Screen 206void drawTemperature(int temp) { 207 208 // Get Number of Digits in the Temperature 209 int digits = numDigits(temp); 210 211 // Define Cursor Positions to Draw Bitmaps 212 int x1_2 = 62; 213 int x2_2 = 32; 214 int x1_3 = 1; 215 int x2_3 = 1; 216 int x3_3 = 1; 217 int y = 38; 218 219 char digit1[12]; 220 char digit2[12]; 221 char digit3[12]; 222 char digitStr1[24]; 223 char digitStr2[24]; 224 char digitStr3[24]; 225 226 // Get First Digit 227 itoa(temp % 10, digit1,10); 228 //Serial.println(temp % 10); 229 strcpy(digitStr1, ""); 230 strcat(digitStr1, digit1); 231 strcat(digitStr1, ".bmp"); 232 233 // Get Second Digit 234 if(digits == 2){ 235 itoa((temp / 10) % 10, digit2,10); 236 strcpy(digitStr2, ""); 237 strcat(digitStr2, digit2); 238 strcat(digitStr2, ".bmp"); 239 } 240 241 // Get Third Digit 242 if(digits == 3){ 243 itoa((temp / 100) % 10, digit3,10); 244 strcpy(digitStr3, ""); 245 strcat(digitStr3, digit3); 246 strcat(digitStr3, ".bmp"); 247 } 248 249 if(digits > 2){ 250 bmpDraw(digitStr1,x1_3,y); 251 bmpDraw(digitStr2,x2_3,y); 252 bmpDraw(digitStr3,x3_3,y); 253 } else { 254 bmpDraw(digitStr1,x1_2,y); 255 bmpDraw(digitStr2,x2_2,y); 256 } 257 258} 259 260 261// Get number of digits in temperature to determine placement on screen 262int numDigits(int number){ 263 264 int valLen = 0; 265 if(number > 99) 266 valLen = 3; 267 else 268 valLen = 2; 269 return valLen; 270 271} 272 273 274// Set LED Colors 275void setColors(int r, int g, int b){ 276 277 for(int i = 0; i < PIXEL_NUM; i++){ 278 279 leds[i].setRGB( r, g, b); 280 leds[i].fadeLightBy(125); 281 FastLED.show(); 282 delay(100); 283 284 } 285 286} 287 288 289// Determine which colors to use based on Humidity level 290void setHumidityColors(int humidity){ 291 292 // Humidity Color Chart - This is just something we came up with. 293 // Red - 0-17% 294 // Orange - 18-34% 295 // Yellow - 35-51% 296 // Green - 52-68% 297 // Blue - 69-85% 298 // Purple - 86-100% 299 300 // Define Colors 301 int cRed[3] = {255,0,0}; 302 int cOrange[3] = {255,90,0}; 303 int cYellow[3] = {255,255,0}; 304 int cGreen[3] = {0,255,0}; 305 int cBlue[3] = {0,175,255}; 306 int cPurple[3] = {255,0,255}; 307 308 int range = map(humidity, 0, 100, 0, 6); 309 switch (range) { 310 case 0: // Red 311 if(currentColor == 0){ 312 break; 313 } 314 else { 315 setColors(cRed[0], cRed[1], cRed[2]); 316 currentColor = 0; 317 } 318 break; 319 case 1: // Orange 320 if(currentColor == 1){ 321 break; 322 } 323 else { 324 setColors(cOrange[0], cOrange[1], cOrange[2]); 325 currentColor = 1; 326 } 327 break; 328 case 2: // Yellow 329 if(currentColor == 2){ 330 break; 331 } 332 else { 333 setColors(cYellow[0], cYellow[1], cYellow[2]); 334 currentColor = 2; 335 } 336 break; 337 case 3: // Green 338 if(currentColor == 3){ 339 break; 340 } 341 else { 342 setColors(cGreen[0], cGreen[1], cGreen[2]); 343 currentColor = 3; 344 } 345 break; 346 case 4: // Blue 347 if(currentColor == 4){ 348 break; 349 } 350 else { 351 setColors(cBlue[0], cBlue[1], cBlue[2]); 352 currentColor = 4; 353 } 354 break; 355 case 5: // Purple 356 if(currentColor == 5){ 357 break; 358 } 359 else { 360 setColors(cPurple[0], cPurple[1], cPurple[2]); 361 currentColor = 5; 362 } 363 break; 364 } 365}
Arduino Work Shop Sensor Code
arduino
1#include <Adafruit_NeoPixel.h> 2#include <Adafruit_ST7735.h> 3#include <Adafruit_GFX.h> 4#include <FastLED.h> 5#include <SPI.h> 6#include <SD.h> 7#include <cactus_io_DHT22.h> // There's a bunch of DHTXX libraries you can find online. They all have varying levels of features. 8 9// Define Pins 10#define TFT_CS 10 11#define TFT_RST 9 12#define TFT_DC 8 13#define DHT_PIN 2 14#define PIXEL_PIN 6 15#define PIXEL_NUM 24 16#define SD_PIN 4 17#define BMP_BUF 20 18 19// Global Variables 20int currentColor = 9999; //(Numbers correspond to chart. See below.) 21CRGB leds[PIXEL_NUM]; 22Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST); 23DHT22 dht(DHT_PIN); 24int loopDelay = 2000; //ms 25 26// SETUP 27void setup() { 28 29 Serial.begin(9600); 30 Serial.println("Starting up."); 31 32 // Begin DHT 33 dht.begin(); 34 35 // Initialize LCD Screen 36 tft.initR(INITR_144GREENTAB); 37 38 // Initialize SD Card 39 Serial.print("Initializing SD card."); 40 if (!SD.begin(SD_PIN)) { 41 Serial.println("Failed!"); 42 return; 43 } 44 45 // Set Screen Background to Black 46 tft.fillScreen(ST7735_BLACK); 47 48 // Initialize LEDs 49 FastLED.addLeds<NEOPIXEL, PIXEL_PIN>(leds, PIXEL_NUM); 50 51 // Let everything catch up before starting loop 52 delay(500); 53 54} 55 56 57// LOOP 58void loop() { 59 60 // Get Sensor Data 61 dht.readTemperature(); 62 dht.readHumidity(); 63 int f = dht.temperature_F; // Degrees in Fahrenheit 64 int h = dht.humidity; // Percentage 65 66 // Draw Degrees Icon 67 tft.fillCircle(102, 42, 6, ST7735_WHITE); 68 tft.fillCircle(102, 42, 4, ST7735_BLACK); 69 70 // Draw Temperature on LCD Screen 71 drawTemperature(f); 72 73 // Humidity 74 setHumidityColors(h); 75 76 //Print Data to Serial Monitor 77 Serial.print("Temperature: "); 78 Serial.println(f); 79 Serial.print("Humidity: "); 80 Serial.print(h); 81 Serial.println("%"); 82 83 // Delay 84 delay(1000); 85 86} 87 88 89// Draw Bitmap - This is for the LCD Screen 90void bmpDraw(char *filename, uint8_t x, uint8_t y) { 91 92 File bmpFile; 93 int bmpWidth, bmpHeight; // W+H in pixels 94 uint8_t bmpDepth; // Bit depth (currently must be 24) 95 uint32_t bmpImageoffset; // Start of image data in file 96 uint32_t rowSize; // Not always = bmpWidth; may have padding 97 uint8_t sdbuffer[3*BMP_BUF]; // pixel buffer (R+G+B per pixel) 98 uint8_t buffidx = sizeof(sdbuffer); // Current position in sdbuffer 99 boolean goodBmp = false; // Set to true on valid header parse 100 boolean flip = true; // BMP is stored bottom-to-top 101 int w, h, row, col; 102 uint8_t r, g, b; 103 uint32_t pos = 0, startTime = millis(); 104 105 if((x >= tft.width()) || (y >= tft.height())) return; 106 107// Serial.println(); 108// Serial.print("Loading Bitmap Image: '"); 109// Serial.print(filename); 110// Serial.println('\\''); 111 112 // Open requested file on SD card 113 if ((bmpFile = SD.open(filename)) == NULL) { 114 Serial.print("Bitmap file not found!"); 115 return; 116 } 117 118 // Parse BMP header 119 if(read16(bmpFile) == 0x4D42) { 120 read32(bmpFile); 121 (void)read32(bmpFile); 122 bmpImageoffset = read32(bmpFile); 123 //Serial.println()); 124 read32(bmpFile); 125 bmpWidth = read32(bmpFile); 126 bmpHeight = read32(bmpFile); 127 if(read16(bmpFile) == 1) { 128 bmpDepth = read16(bmpFile); 129 //Serial.print("Bit Depth: "); 130 if((bmpDepth == 24) && (read32(bmpFile) == 0)) { 131 132 goodBmp = true; 133 134 // BMP rows are padded (if needed) to 4-byte boundary 135 rowSize = (bmpWidth * 3 + 3) & ~3; 136 137 // If bmpHeight is negative, image is in top-down order. 138 // This is not canon but has been observed in the wild. 139 if(bmpHeight < 0) { 140 bmpHeight = -bmpHeight; 141 flip = false; 142 } 143 144 // Crop area to be loaded 145 w = bmpWidth; 146 h = bmpHeight; 147 if((x+w-1) >= tft.width()) w = tft.width() - x; 148 if((y+h-1) >= tft.height()) h = tft.height() - y; 149 150 // Set TFT address window to clipped image bounds 151 tft.setAddrWindow(x, y, x+w-1, y+h-1); 152 153 for (row=0; row<h; row++) { // For each scanline... 154 if(flip) { 155 pos = bmpImageoffset + (bmpHeight - 1 - row) * rowSize; 156 } else { 157 pos = bmpImageoffset + row * rowSize; 158 } 159 if(bmpFile.position() != pos) { 160 bmpFile.seek(pos); 161 buffidx = sizeof(sdbuffer); 162 } 163 164 for (col=0; col<w; col++) { 165 if (buffidx >= sizeof(sdbuffer)) { 166 bmpFile.read(sdbuffer, sizeof(sdbuffer)); 167 buffidx = 0; 168 } 169 170 // Convert pixel from BMP to TFT format, push to display 171 b = sdbuffer[buffidx++]; 172 g = sdbuffer[buffidx++]; 173 r = sdbuffer[buffidx++]; 174 tft.pushColor(tft.Color565(r,g,b)); 175 } 176 } 177 } 178 } 179 } 180 181 bmpFile.close(); 182 if(!goodBmp) Serial.println("BMP format not recognized."); 183 184} 185 186// This is for the Bitmap/LCD Screen 187uint16_t read16(File f) { 188 uint16_t result; 189 ((uint8_t *)&result)[0] = f.read(); // LSB 190 ((uint8_t *)&result)[1] = f.read(); // MSB 191 return result; 192} 193 194// This is for the Bitmap/LCD Screen 195uint32_t read32(File f) { 196 uint32_t result; 197 ((uint8_t *)&result)[0] = f.read(); // LSB 198 ((uint8_t *)&result)[1] = f.read(); 199 ((uint8_t *)&result)[2] = f.read(); 200 ((uint8_t *)&result)[3] = f.read(); // MSB 201 return result; 202} 203 204 205// Draw Temperature on LCD Screen 206void drawTemperature(int temp) { 207 208 // Get Number of Digits in the Temperature 209 int digits = numDigits(temp); 210 211 // Define Cursor Positions to Draw Bitmaps 212 int x1_2 = 62; 213 int x2_2 = 32; 214 int x1_3 = 1; 215 int x2_3 = 1; 216 int x3_3 = 1; 217 int y = 38; 218 219 char digit1[12]; 220 char digit2[12]; 221 char digit3[12]; 222 char digitStr1[24]; 223 char digitStr2[24]; 224 char digitStr3[24]; 225 226 // Get First Digit 227 itoa(temp % 10, digit1,10); 228 //Serial.println(temp % 10); 229 strcpy(digitStr1, ""); 230 strcat(digitStr1, digit1); 231 strcat(digitStr1, ".bmp"); 232 233 // Get Second Digit 234 if(digits == 2){ 235 itoa((temp / 10) % 10, digit2,10); 236 strcpy(digitStr2, ""); 237 strcat(digitStr2, digit2); 238 strcat(digitStr2, ".bmp"); 239 } 240 241 // Get Third Digit 242 if(digits == 3){ 243 itoa((temp / 100) % 10, digit3,10); 244 strcpy(digitStr3, ""); 245 strcat(digitStr3, digit3); 246 strcat(digitStr3, ".bmp"); 247 } 248 249 if(digits > 2){ 250 bmpDraw(digitStr1,x1_3,y); 251 bmpDraw(digitStr2,x2_3,y); 252 bmpDraw(digitStr3,x3_3,y); 253 } else { 254 bmpDraw(digitStr1,x1_2,y); 255 bmpDraw(digitStr2,x2_2,y); 256 } 257 258} 259 260 261// Get number of digits in temperature to determine placement on screen 262int numDigits(int number){ 263 264 int valLen = 0; 265 if(number > 99) 266 valLen = 3; 267 else 268 valLen = 2; 269 return valLen; 270 271} 272 273 274// Set LED Colors 275void setColors(int r, int g, int b){ 276 277 for(int i = 0; i < PIXEL_NUM; i++){ 278 279 leds[i].setRGB( r, g, b); 280 leds[i].fadeLightBy(125); 281 FastLED.show(); 282 delay(100); 283 284 } 285 286} 287 288 289// Determine which colors to use based on Humidity level 290void setHumidityColors(int humidity){ 291 292 // Humidity Color Chart - This is just something we came up with. 293 // Red - 0-17% 294 // Orange - 18-34% 295 // Yellow - 35-51% 296 // Green - 52-68% 297 // Blue - 69-85% 298 // Purple - 86-100% 299 300 // Define Colors 301 int cRed[3] = {255,0,0}; 302 int cOrange[3] = {255,90,0}; 303 int cYellow[3] = {255,255,0}; 304 int cGreen[3] = {0,255,0}; 305 int cBlue[3] = {0,175,255}; 306 int cPurple[3] = {255,0,255}; 307 308 int range = map(humidity, 0, 100, 0, 6); 309 switch (range) { 310 case 0: // Red 311 if(currentColor == 0){ 312 break; 313 } 314 else { 315 setColors(cRed[0], cRed[1], cRed[2]); 316 currentColor = 0; 317 } 318 break; 319 case 1: // Orange 320 if(currentColor == 1){ 321 break; 322 } 323 else { 324 setColors(cOrange[0], cOrange[1], cOrange[2]); 325 currentColor = 1; 326 } 327 break; 328 case 2: // Yellow 329 if(currentColor == 2){ 330 break; 331 } 332 else { 333 setColors(cYellow[0], cYellow[1], cYellow[2]); 334 currentColor = 2; 335 } 336 break; 337 case 3: // Green 338 if(currentColor == 3){ 339 break; 340 } 341 else { 342 setColors(cGreen[0], cGreen[1], cGreen[2]); 343 currentColor = 3; 344 } 345 break; 346 case 4: // Blue 347 if(currentColor == 4){ 348 break; 349 } 350 else { 351 setColors(cBlue[0], cBlue[1], cBlue[2]); 352 currentColor = 4; 353 } 354 break; 355 case 5: // Purple 356 if(currentColor == 5){ 357 break; 358 } 359 else { 360 setColors(cPurple[0], cPurple[1], cPurple[2]); 361 currentColor = 5; 362 } 363 break; 364 } 365}
Downloadable files
Picture of Actual Setup
Picture of Actual Setup
Schematic
Fritzing didn't have most of the actual components so I did my best to represent the flow of things.
Schematic
Picture of Actual Setup
Picture of Actual Setup
Documentation
Arduino Work Shop Sensor Plans
Arduino Work Shop Sensor Plans
Arduino Work Shop Sensor Plans
Arduino Work Shop Sensor Plans
Comments
Only logged in users can leave comments
WickedMakers
0 Followers
•0 Projects
Table of contents
Intro
94
0