산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Manufacturing Technology >> 제조공정

TFT LCD 실드에 SD 카드의 BMP 사진 표시

구성품 및 소모품

Arduino UNO
× 1

이 프로젝트 정보

안녕하세요, 이 튜토리얼은 Arduino UNO가 있는 2.4인치 TFT LCD Shield에 대한 다른 2개의 튜토리얼에 대한 후속 조치이므로 첫 번째 튜토리얼은 터치 기능 문제와 축이 반전된 인터페이스 및 수정에 관한 것이었고 두 번째 튜토리얼은 간단한 기능 사용에 관한 것이었습니다. 다양한 모양을 그리는 방법과 일부 기능을 활성화하는 터치 버튼을 만드는 방법...

Arduino TFT 2.4″ LCD 실드의 인터페이스 및 터치 문제 수정

TFT LCD 2.4″ 터치 스크린 실드 튜토리얼

하지만 오늘은 SD 카드에서 이미지를 읽고 화면에 표시하는 방법에 대해 알아보겠습니다. 먼저 SD 카드를 컴퓨터에 연결하고 FAT32로 포맷한 다음 이미지를 전송해야 합니다. "BMP" 형식, 비트맵 24 !! 올바른 이미지를 얻으려면 해상도가 240*320이어야 합니다. 설명은 거의 없습니다.

이것은 240*320의 이미지를 표시할 수 있는 화면의 일반적인 방향이며 setRotation(0)인 기본 회전입니다.

이것은 당신이 setRotation(1); 이제 320*240의 이미지를 표시할 수 있습니다.

따라서 원하는 것을 선택할 수 있습니다. PC에서 화면 회전이나 이미지 회전을 변경한 다음 이미지 이름을 기억하거나 복사하면 됩니다. SD 카드를 실드에 꽂으세요.

그것들은 "Img1"과 같은 SD 카드에 있는 내 bmp 24비트 이미지의 이름입니다. 코드에서 "Img1.bmp"를 사용하여 호출합니다.

라이브러리:

이것은 나를 위해 일한 라이브러리입니다:여기에서 다운로드 이 라이브러리를 사용하지만 예제 코드로 시도할 때 흰색 화면이 표시되면 반드시 자신에게 맞는 라이브러리를 찾아야 합니다.

코드:

다음은 비디오 in.ino 형식에서 사용한 코드입니다. 사용 중인 파일의 이름을 변경하는 것을 잊지 마십시오. 도움이 필요한 경우 튜토리얼을 확인하는 것을 잊지 마십시오.

<울>
  • 코드 1
  • 코드 2
  • <섹션 클래스="섹션 컨테이너 섹션 축소 가능" id="코드">

    코드

    <울>
  • TFT_Shield_SD_1.ino
  • TFT_Shield_SD_2.ino
  • TFT_Shield_SD_1.ino아두이노
    /*이 코드는 2.4" TFT LCD 터치 스크린 실드와 함께 사용하기 위한 것으로, SD 카드에 저장된 bmp 이미지를 읽고 *화면에 표시합니다. *자세한 내용은 SurtrTech.com을 참조하세요. */#include  // 코어 그래픽 라이브러리#include  // 하드웨어별 라이브러리#include #include #define LCD_CS A3 // 칩 선택이 아날로그 3으로 이동#define LCD_CD A2 // 명령/데이터는 아날로그 2로 이동#define LCD_WR A1 // LCD 쓰기는 아날로그 1로 이동#define LCD_RD A0 // LCD 읽기는 아날로그 0으로 이동#define SD_CS 10 //실드의 SD 카드 핀Adafruit_TFTLCD tft(LCD_CS, LCD_CD , LCD_WR, LCD_RD, A4); 무효 설정(){ Serial.begin(9600); tft.reset(); uint16_t 식별자 =tft.readID(); pinMode(10, OUTPUT); digitalWrite(10, HIGH); tft .begin(식별자); if (!SD.begin(SD_CS)) { progmemPrintln(PSTR("실패!")); 반환; } }void 루프(){ bmpDraw("Logo.bmp", 0, 0); //bmpDraw 함수 호출("Name_of_your_image.bmp",x,y)(x,y)은 그림 그리기의 시작 위치입니다. ng 지연(2000); bmpDraw("Img2.bmp", 0, 0); 지연(2000); bmpDraw("Img3.bmp", 0, 0); delay(2000);}#define BUFFPIXEL 20 //그리기 속도, 20이 최고지만 uno의 RAM을 많이 차지하지만 60을 사용할 수 있습니다. //Drawing 기능, SD 카드에서 파일 읽기 및 수행 //변환 및 그리기, 또한 문제의 경우 직렬 모니터에 메시지를 표시합니다.//이 함수에 손대지 않습니다. :Dvoid bmpDraw(char *filename, int x, int y) { File bmpFile; int bmp폭, bmp높이; // W+H(픽셀) uint8_t bmpDepth; // 비트 깊이(현재 24여야 함) uint32_t bmpImageoffset; // 파일의 이미지 데이터 시작 uint32_t rowSize; // 항상 그런 것은 아님 =bmpWidth; 패딩이 있을 수 있음 uint8_t sdbuffer[3*BUFFPIXEL]; // 버퍼의 픽셀(픽셀당 R+G+B) uint16_t lcdbuffer[BUFFPIXEL]; // 픽셀 출력 버퍼(픽셀당 16비트) uint8_t buffidx =sizeof(sdbuffer); // sdbuffer의 현재 위치 부울 goodBmp =false; // 유효한 헤더 구문 분석에서 true로 설정 부울 flip =true; // BMP는 아래에서 위로 저장됩니다. int w, h, row, col; uint8_t r, g, b; uint32_t 위치 =0, 시작 시간 =밀리(); uint8_t lcdidx =0; 부울 첫 번째 =true; if((x>=tft.width()) || (y>=tft.height())) 반환; 직렬.println(); progmemPrint(PSTR("이미지 로드 중 '")); Serial.print(파일명); Serial.println('\''); // 요청된 파일을 SD 카드에 열기 if ((bmpFile =SD.open(filename)) ==NULL) { progmemPrintln(PSTR("파일을 찾을 수 없음")); 반품; } // BMP 헤더 구문 분석 if(read16(bmpFile) ==0x4D42) { // BMP 서명 progmemPrint(PSTR("파일 크기:")); Serial.println(read32(bmp파일)); (무효)read32(bmp파일); // 작성자 바이트 읽기 및 무시 bmpImageoffset =read32(bmpFile); // 이미지 데이터 시작 progmemPrint(PSTR("이미지 오프셋:")); Serial.println(bmpImageoffset, DEC); // DIB 헤더 읽기 progmemPrint(PSTR("헤더 크기:")); Serial.println(read32(bmp파일)); bmp폭 =read32(bmp파일); bmp높이 =read32(bmp파일); if(read16(bmpFile) ==1) { // # 평면 -- '1'이어야 함 bmpDepth =read16(bmpFile); // 픽셀당 비트 수 progmemPrint(PSTR("Bit Depth:")); Serial.println(bmpDepth); if((bmpDepth ==24) &&(read32(bmpFile) ==0)) { // 0 =압축되지 않은 goodBmp =true; // 지원되는 BMP 형식 -- 계속하십시오! progmemPrint(PSTR("이미지 크기:")); Serial.print(bmpWidth); Serial.print('x'); Serial.println(bmp높이); // BMP 행은 (필요한 경우) 4바이트 경계로 채워집니다. rowSize =(bmpWidth * 3 + 3) &~3; // bmpHeight가 음수이면 이미지는 하향식 순서입니다. // 이것은 표준이 아니지만 야생에서 관찰되었습니다. if(bmpHeight <0) { bmpHeight =-bmpHeight; 뒤집기 =거짓; } // 로드할 자르기 영역 w =bmpWidth; h =bmp 높이; if((x+w-1)>=tft.width()) w =tft.width() - x; if((y+h-1)>=tft.height()) h =tft.height() - y; // TFT 주소 창을 잘린 이미지 경계로 설정 tft.setAddrWindow(x, y, x+w-1, y+h-1); for (row=0; row=sizeof(sdbuffer)) { // 실제로 // LCD 버퍼를 디스플레이에 먼저 푸시 if(lcdidx> 0) { tft.pushColors(lcdbuffer, lcdidx, first); lcdidx =0; 첫 번째 =거짓; } bmpFile.read(sdbuffer, sizeof(sdbuffer)); 버피드x =0; // 인덱스를 시작으로 설정 } // 픽셀을 BMP에서 TFT 형식으로 변환 b =sdbuffer[buffidx++]; g =sdbuffer[버피드x++]; r =sdbuffer[버피드x++]; LCD 버퍼[lcdidx++] =tft.color565(r,g,b); } // 픽셀 끝 } // 스캔라인 끝 // 남은 데이터를 LCD에 씁니다. if(lcdidx> 0) { tft.pushColors(lcdbuffer, lcdidx, first); } progmemPrint(PSTR("로딩됨")); Serial.print(millis() - 시작 시간); Serial.println("밀리초"); } // goodBmp 종료 } } bmpFile.close(); if(!goodBmp) progmemPrintln(PSTR("BMP 형식이 인식되지 않습니다."));}// SD 카드 파일에서 16비트 및 32비트 유형을 읽습니다.// BMP 데이터는 little-endian에 저장되고 Arduino는 little -endian too.// 다른 곳으로 이식하는 경우 첨자 순서를 반대로 해야 할 수도 있습니다.uint16_t read16(File f) { uint16_t result; ((uint8_t *)&결과)[0] =f.read(); // LSB((uint8_t *)&결과)[1] =f.read(); // MSB 반환 결과;}uint32_t read32(파일 f) { uint32_t 결과; ((uint8_t *)&결과)[0] =f.read(); // LSB((uint8_t *)&결과)[1] =f.read(); ((uint8_t *)&결과)[2] =f.read(); ((uint8_t *)&결과)[3] =f.read(); // MSB return result;}// 플래시에서 직렬 포트로 문자열 복사// 소스 문자열은 반드시 PSTR() 선언 안에 있어야 합니다!void progmemPrint(const char *str) { char c; while(c =pgm_read_byte(str++)) Serial.print(c);}// 위와 동일, 후행 newlinevoid progmemPrintln(const char *str) { progmemPrint(str); 직렬.println();}
    TFT_Shield_SD_2.ino아두이노
    /*이 코드는 UNO 보드가 있는 2.4" TFT LCD 터치 스크린 쉴드를 위한 것입니다. * 화면에서 누르는 위치에 따라 변경되는 이미지의 작은 슬라이드 쇼를 생성합니다. * 이미지는 SD 카드에서 읽습니다. * 참조 자세한 내용은 SurtrTech.com 참조 */#include  // 코어 그래픽 라이브러리#include  // 하드웨어별 라이브러리#include #include  #include  //터치 스크린 기능 라이브러리#if defined(__SAM3X8E__) #undef __FlashStringHelper::F(string_literal) #define F(string_literal) string_literal#endif//아래 매개변수는 실드에 따라 다르므로 핀이 다음과 같은지 확인하십시오. correct#define YP A3 // 반드시 아날로그 핀이어야 하며 "An" 표기법을 사용하십시오! #define XM A2 // 아날로그 핀이어야 하고 "An" 표기법을 사용하십시오!#define YM 9 // 디지털 핀일 수 있습니다#define XP 8 // 디지털 핀일 수 있음//터치 기능이 작동하지 않으면 위의 값을 확인하는 것을 잊지 마세요. (A1 A2 7 6) resp// 보정할 수 있는 값 ant는 먼저 보정 코드를 실행하고 해당 포인트를 설정합니다.#define TS_MINX 176#define TS_MINY 159#define TS_MAXX 921#define TS_MAXY 884#define MINPRESSURE 10#define MAXPRESSURE 1000TouchScreen ts =, TouchScreen(XP, YM) #define LCD_CS A3 // 칩 선택은 아날로그 3으로 이동#define LCD_CD A2 // 명령/데이터는 아날로그 2로 이동#define LCD_WR A1 // LCD 쓰기는 아날로그 1로 이동#define LCD_RD A0 // LCD 읽기는 아날로그 0으로 이동# define SD_CS 10 // 칩 선택 라인을 무엇이든 사용하도록 설정합니다.Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, A4);char x[]="x1.bmp";/*여기서 이 코드에서 이름을 다음과 같이 선언했습니다. 배열 * 스크롤하고 싶은 경우 수정할 수 있습니다. * 이미지에 "1"과 같은 숫자가 있어야 다음 이미지로 이동하기 위해 늘리거나 줄일 수 있습니다. */void setup(){ Serial.begin( 9600); tft.reset(); uint16_t 식별자 =tft.readID(); 핀모드(10, 출력); 디지털 쓰기(10, 높음); tft.begin(식별자); if (!SD.begin(SD_CS)) { progmemPrintln(PSTR("실패!")); 반품; } tft.setRotation(1); //화면을 90도 회전하려면 bmpDraw(x, 0, 0); //우리는 선언한 대로 x -> "x1.bmp"인 첫 번째 이미지를 그립니다.}void loop(){if(x[1]<49) //여기에 추가한 이상한 값으로 이동하지 않습니다. 값의 재설정x[1]=49; //우리가 이미 첫 번째 그림에 있는 경우, lastif(x[1]>52)에 대해 동일하게 유지합니다. // char의 "1"은 "49"이고 "4"는 "52"입니다. 이 형식을 사용하여 조작할 수 있습니다.x[1]=52; TSPoint p =ts.getPoint(); //사용자가 화면을 터치했는지 확인 pinMode(XM, OUTPUT); 핀모드(YP, 출력); if (pz> MINPRESSURE &&pz  0 &&py <100 ){ Serial.println("왼쪽"); //왼쪽으로 눌렀다는 직렬 모니터를 표시하기 위해 이 작업을 수행했습니다. x[1]=x[1]-1; //여기서 읽고자 하는 파일의 이름을 변경합니다. x[]="x1.bmp"이고 x[1]은 이름에서 1이고 x[0]은 x입니다. bmpDraw(x, 0, 0); //그래서 내가 하는 일은 그것을 2로 만들기 위해 증가시키거나 0으로 만들기 위해 감소시키는 것입니다. (0이 존재하지 않기 때문에 이 경우에 대한 해결책을 보려면 첫 번째 "if"를 참조하십시오) delay(300); //그런 다음 내가 누른 면에 따라 다른 이름을 가진 이미지를 그립니다. } //터치 감지가 바운스되지 않도록 약간의 지연을 추가합니다. else if(py>200 &&py <320){ Serial.println("Right "); x[1]=x[1]+1; bmpDraw(x, 0, 0); 지연(300); } } }#define BUFFPIXEL 20 //인쇄 속도 20이 최고입니다. 60으로 갈 수 있지만 RAM을 너무 많이 사용//그리기 기능을 터치하지 않음 :Dvoid bmpDraw(char *filename, int x, int y) { 파일 bmpFile; int bmp폭, bmp높이; // W+H(픽셀) uint8_t bmpDepth; // 비트 깊이(현재 24여야 함) uint32_t bmpImageoffset; // 파일의 이미지 데이터 시작 uint32_t rowSize; // 항상 그런 것은 아님 =bmpWidth; 패딩이 있을 수 있음 uint8_t sdbuffer[3*BUFFPIXEL]; // 버퍼의 픽셀(픽셀당 R+G+B) uint16_t lcdbuffer[BUFFPIXEL]; // 픽셀 출력 버퍼(픽셀당 16비트) uint8_t buffidx =sizeof(sdbuffer); // sdbuffer의 현재 위치 부울 goodBmp =false; // 유효한 헤더 구문 분석에서 true로 설정 부울 flip =true; // BMP는 아래에서 위로 저장됩니다. int w, h, row, col; uint8_t r, g, b; uint32_t 위치 =0, 시작 시간 =밀리(); uint8_t lcdidx =0; 부울 첫 번째 =true; if((x>=tft.width()) || (y>=tft.height())) 반환; 직렬.println(); progmemPrint(PSTR("이미지 로드 중 '")); Serial.print(파일명); Serial.println('\''); // 요청된 파일을 SD 카드에 열기 if ((bmpFile =SD.open(filename)) ==NULL) { progmemPrintln(PSTR("파일을 찾을 수 없음")); 반품; } // BMP 헤더 구문 분석 if(read16(bmpFile) ==0x4D42) { // BMP 서명 progmemPrint(PSTR("파일 크기:")); Serial.println(read32(bmp파일)); (무효)read32(bmp파일); // 작성자 바이트 읽기 및 무시 bmpImageoffset =read32(bmpFile); // 이미지 데이터 시작 progmemPrint(PSTR("이미지 오프셋:")); Serial.println(bmpImageoffset, DEC); // DIB 헤더 읽기 progmemPrint(PSTR("헤더 크기:")); Serial.println(read32(bmp파일)); bmp폭 =read32(bmp파일); bmp높이 =read32(bmp파일); if(read16(bmpFile) ==1) { // # 평면 -- '1'이어야 함 bmpDepth =read16(bmpFile); // 픽셀당 비트 수 progmemPrint(PSTR("Bit Depth:")); Serial.println(bmpDepth); if((bmpDepth ==24) &&(read32(bmpFile) ==0)) { // 0 =압축되지 않은 goodBmp =true; // 지원되는 BMP 형식 -- 계속하십시오! progmemPrint(PSTR("이미지 크기:")); Serial.print(bmpWidth); Serial.print('x'); Serial.println(bmp높이); // BMP 행은 (필요한 경우) 4바이트 경계로 채워집니다. rowSize =(bmpWidth * 3 + 3) &~3; // bmpHeight가 음수이면 이미지는 하향식 순서입니다. // 이것은 표준이 아니지만 야생에서 관찰되었습니다. if(bmpHeight <0) { bmpHeight =-bmpHeight; 뒤집기 =거짓; } // 로드할 자르기 영역 w =bmpWidth; h =bmp 높이; if((x+w-1)>=tft.width()) w =tft.width() - x; if((y+h-1)>=tft.height()) h =tft.height() - y; // TFT 주소 창을 잘린 이미지 경계로 설정 tft.setAddrWindow(x, y, x+w-1, y+h-1); for (row=0; row=sizeof(sdbuffer)) { // 실제로 // LCD 버퍼를 디스플레이에 먼저 푸시 if(lcdidx> 0) { tft.pushColors(lcdbuffer, lcdidx, first); lcdidx =0; 첫 번째 =거짓; } bmpFile.read(sdbuffer, sizeof(sdbuffer)); 버피드x =0; // 인덱스를 시작으로 설정 } // 픽셀을 BMP에서 TFT 형식으로 변환 b =sdbuffer[buffidx++]; g =sdbuffer[버피드x++]; r =sdbuffer[버피드x++]; LCD 버퍼[lcdidx++] =tft.color565(r,g,b); } // 픽셀 끝 } // 스캔라인 끝 // 남은 데이터를 LCD에 씁니다. if(lcdidx> 0) { tft.pushColors(lcdbuffer, lcdidx, first); } progmemPrint(PSTR("로딩됨")); Serial.print(millis() - 시작 시간); Serial.println("밀리초"); } // goodBmp 종료 } } bmpFile.close(); if(!goodBmp) progmemPrintln(PSTR("BMP 형식이 인식되지 않습니다."));}// SD 카드 파일에서 16비트 및 32비트 유형을 읽습니다.// BMP 데이터는 little-endian에 저장되고 Arduino는 little -endian too.// 다른 곳으로 이식하는 경우 첨자 순서를 반대로 해야 할 수도 있습니다.uint16_t read16(File f) { uint16_t result; ((uint8_t *)&결과)[0] =f.read(); // LSB((uint8_t *)&결과)[1] =f.read(); // MSB 반환 결과;}uint32_t read32(파일 f) { uint32_t 결과; ((uint8_t *)&결과)[0] =f.read(); // LSB((uint8_t *)&결과)[1] =f.read(); ((uint8_t *)&결과)[2] =f.read(); ((uint8_t *)&결과)[3] =f.read(); // MSB return result;}// 플래시에서 직렬 포트로 문자열 복사// 소스 문자열은 반드시 PSTR() 선언 안에 있어야 합니다!void progmemPrint(const char *str) { char c; while(c =pgm_read_byte(str++)) Serial.print(c);}// 위와 동일, 후행 newlinevoid progmemPrintln(const char *str) { progmemPrint(str); 직렬.println();}

    회로도

    방패입니다 :D

    제조공정

    1. 인사말 카드
    2. 신용카드
    3. 액정 디스플레이(LCD)
    4. 데이터 모듈:스마트 제어 기능이 있는 23.1인치 울트라 스트레치 TFT 디스플레이
    5. Distec:Ortustech의 견고한 7인치 TFT 디스플레이
    6. Acceed:GPU-PC가 그래픽 카드에서 성능 향상
    7. 전시:원시 전시
    8. Kuman TFT 3.5 RetroPie 2018
    9. AI는 간단한 텍스트 기반 레시피에서 완성된 식사의 이미지를 생성합니다.
    10. Dedge The Defs!