Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Manufacturing Technology >> Manufacturing process

Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display

Components and supplies

Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display
Arduino UNO
×1
Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display
Adafruit NeoPixel Ring: WS2812 5050 RGB LED
×1
Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display
DHT22 Temperature Sensor
×1
Adafruit 1.44" Color TFT LCD Display with MicroSD Card breakout - ST7735R
×1
Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display
Breadboard (generic)
×1
Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display
4xAA battery holder
×1
Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display
Jumper wires (generic)
×1

Necessary tools and machines

Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display
Soldering iron (generic)
Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display
Hot glue gun (generic)

About this project

The Story Behind This Project

Learn how we built a walnut dovetailed case and used easy-to-find Arduino components to build a stylish and useful humidity and temperature monitor for the wood shop. This DIY project showcases a bit of woodworking with walnut dovetails and beginner electronics using an Arduino Uno and some excellent parts from Adafruit.

We live in Central Texas where we get massive swings in Humidity and Temperature in the Spring, which can be disastrous for certain woodworking projects. This cool project helps alert us when the humidity is changing or starts to get high so we can take precautions like moving our wood projects into the house, or not doing any milling during the high humidity weather. It also looks awesome and has our sweet logo!

We are new to Arduino and Electronics so we learned as we went when making this. We're very excited to make more projects now that we know how easy it is to make great things.

Watch the Detailed Build Video!

Code

  • Arduino Work Shop Sensor Code
Arduino Work Shop Sensor CodeArduino
#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;
  }
}

Custom parts and enclosures

Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display

Schematics

Fritzing didn't have most of the actual components so I did my best to represent the flow of things.Premium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT DisplayPremium Walnut‑Case Humidity & Temperature Sensor Kit – Arduino + NeoPixel + TFT Display

Manufacturing process

  1. Build a Remote Temperature Sensor with Raspberry Pi and Python – Step‑by‑Step Guide
  2. Seamless Temperature & Humidity Monitoring on Raspberry Pi with EzTemp
  3. Build a Multi‑Sensor Temperature & Light Monitoring System with Raspberry Pi & DS18B20
  4. Build an Automated Aeroponics System with Raspberry Pi and Humidity Sensor
  5. Verify and Calibrate Your Humidity Sensor for Precise Measurements
  6. Arduino Temperature & Humidity Logger Using DHT11 and Ethernet Shield
  7. Build a WiFi Weather Station with ESP8266 and DHT22 Temperature Sensor
  8. MKR1000 with DHT22: Real‑Time Temperature & Humidity Monitoring to Azure
  9. Arduino Weather Clock – Real-Time Date, Time, Temperature & Humidity Display
  10. DHT11 Temperature & Humidity Sensor for Arduino Projects