【Arduino】Arduino UNO와 컬러 LCD(ILI9341)로 값을 「보자」

소개



여기에서는 자신용의 비망록도 겸해, Arduino UNO와 컬러 액정 디스플레이(LCD)를 이용해 센서로 얻은 값을 볼 때까지를 설명합니다. 여기에서는 온습도 센서를 이용하고 있습니다.

이번에 사용할 모듈



이번 이용하는 모듈은 모두 아키하바라에 있는 점포에서 구입했습니다.
  • Arduino UNO R3 (아키즈키 전자 통상)
  • 컬러 액정 ILI9341 TJCTM24028-SPI 240x320 (aitendo)
  • 온습도 센서 AOSONG AM2320 (아키즈키 전자 통상)
  • 양방향 범용 로직 레벨 변환 FXMA108 (아키즈키 전자 통상)

  • 이 외에도 10kΩ 저항 두 개가 필요합니다.

    컬러 LCD ILI9341 TJCTM24028-SPI



    이번 사용하는 칼라 LCD는 aitendo 직영점에서 손에 넣은 「ILI9341 TJCTM24028-SPI」입니다.


    (↑뒷면 특히 아무것도 생각하지 않고 구입했기 때문에 악전 고투했습니다 ...)

    뒤에는 SD 카드가 들어가는 공간도 있지만 여기에서는 사용하지 않습니다.
    240x320의 화질까지 표시할 수 있는 것 같습니다.
    조사하면 ILI9341 기반임을 알았습니다.
    또, 구입한 것은 화상 우측 중앙의 부분 「J1」의 개소에 소자가 없기 때문에 터치 패널로서의 사용은 불가능했습니다.

    ※컬러 액정 디스플레이에는 많은 전류가 흐른다고 합니다. 이번 회로 작성에서는 arduino에서 전원을 당기고 있습니다만, 과전류를 막기 위해서도 가능한 한 arduino와는 별도로 외부 전원을 사용하는 것을 추천합니다.

    회로 작성



    조속히 회로를 짜 갑니다.
    LCD - Arduino UNO 간에는 SPI 통신이라는 기법으로 데이터가 전송됩니다.
    하지만, 어려운 것은 생각하지 않고 우선 짜 갑니다.


    (↑fritzing에 의한 회로 모델 곤란해 보인다...)


    실제로 짜면 이런 느낌에 ↑

    (덧붙여서 회로의 사진에 실려 있던 아크릴판의 보드는 OtaFab이라고 하는 곳에서 레이저 가공으로 작성했습니다. OtaFab에 대해서→ FabLab )

    ※ 회로도에 쓰는 것을 잊었 습니다만, 온습도 센서의 SCL, SDA 핀에는 각각 10kΩ의 저항으로 풀업하십시오!
    Arduino UNO의 전압(5V)과 LCD의 동작 전압(3.3V)이 다르기 때문에 로직 레벨 변환 모듈(이번 경우 FXMA108)이 필요하다. 부디도 5V로 움직이지 않는 것!

    ArduinoIDE에서 스케치



    LCD에 데이터(값과 그래프)를 표시하기 위해 스케치를 작성합니다. 여기에서는 소스만 올립니다. 완코피 OK입니다.
    부품별 사양이나 자세한 것은 사양서나 라이브러리를 읽어 주십시오. (온습도 센서의 데이터 취득(I2C 통신)은 매우 어려울지도 모릅니다. 하지만, 일본어의 사이트도 있으므로 노력해 봐 주세요.)

    LCD 조작용으로 다음 라이브러리를 외부에서 사용했습니다.
    - Adafruit_ILI9341
    - Adafruit_GFX

    Temperature_Humidity.ino
    #include <SPI.h>
    #include <Wire.h>
    
    #include <Adafruit_ILI9341.h>
    #include <Adafruit_GFX.h>
    
    #define TFT_RST 8
    #define TFT_DC 9
    #define TFT_CS 10
    
    Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
    
    unsigned char AM2320_DATA[8];
    unsigned char AM2320_ADDR = 0x5c; // (0xb8 >> 1) and 0x7f
    
    void getData() {
      Wire.beginTransmission(AM2320_ADDR);
      Wire.write(0x00);
      Wire.endTransmission();
    
      delayMicroseconds(1000);
    
      Wire.beginTransmission(AM2320_ADDR);
      Wire.write(0x03);
      Wire.write(0x00);
      Wire.write(0x04);
      Wire.endTransmission();
    
      delayMicroseconds(2000);
    
      Wire.requestFrom(0x5c, 8);
    
      for (int c = 0; Wire.available(); c++) {
        AM2320_DATA[c] = Wire.read();
      }
    }
    
    double temperature() {
      if (AM2320_DATA[4] & 0x80) {
        return (((AM2320_DATA[4]) & 0x7f) * 256) + AM2320_DATA[5] / 10.0;
      } else {
        return ((AM2320_DATA[4] * 256) + AM2320_DATA[5]) / 10.0;
      }
    }
    
    int humidity() {
      return (AM2320_DATA[2] * 256 + AM2320_DATA[3]) / 10;
    }
    
    void setup() {
      tft.begin();
      tft.fillScreen(ILI9341_BLACK);
      tft.setRotation(3);
    
      tft.setCursor(0, 0);
      tft.setTextColor(ILI9341_WHITE);
      tft.setTextSize(2);
      tft.println("Temperature and Humidity");
      tft.setCursor(120, 40);
      tft.println("degree Celsius");
      tft.setCursor(120, 60);
      tft.println("%");
    
      Wire.begin();
      pinMode(0xA0, INPUT);
    }
    
    void loop() {
      getData(); 
    
      double temp_c = temperature();
      static double p_temp_c = 0;
      int humid = humidity();
      static int p_humid = 0;
      static int Time = 60;
      static int HGraph = 240;
      static int TGraph = 240;
    
      if (temp_c != p_temp_c || humid != p_humid) {
        // Clear
        tft.setCursor(0, 40);
        tft.setTextColor(ILI9341_BLACK);
        tft.println(p_temp_c); 
        tft.setCursor(0, 60);
        tft.println(p_humid);
    
        // Print
        tft.setCursor(0, 40);
        tft.setTextColor(ILI9341_WHITE);
        tft.setTextSize(2);
        tft.println(temp_c);
        tft.setCursor(0, 60);
        tft.println(humid); 
      }
    
    
      tft.fillRect(Time, 140, 2, 100, ILI9341_BLACK);
      delay(1);
      tft.drawLine(Time, HGraph, Time + 1, 239 - humid, ILI9341_RED);
      tft.drawLine(Time, TGraph, Time + 1, 200 - (int)temp_c, ILI9341_BLUE);
      if (Time >= 320) {
        Time = 60;
      } else {
        Time += 1;
        HGraph = 239 - humid;
        TGraph = 200 - (int)temp_c;
      }
    
      delay(67);
      p_temp_c = temp_c;
      p_humid = humid;
    }
    

    스케치 예제에 추가되는 'graphictest'를 참고하면 잘 될까 생각합니다.
    0x 똥이라든지 있어요…

    마지막으로



    자기 자신 arduino 물론 전자 공작 초보자입니다만, 비교적 간단하게 액정 디스플레이가 조작할 수 있었던 것이 아닐까 생각합니다. Adafruit님의 도서관에 감사합니다. 액정은 어려울 것 같다! 라고 버리지 말고, 꼭 도전해 봐 주세요. 시리얼 모니터와는 전혀 다른 세계가 열립니다.

    좋은 웹페이지 즐겨찾기