วันจันทร์ที่ 4 พฤษภาคม พ.ศ. 2563

การใช้งาน ESP-IDF ด้วย Eclipse IDE บน Windows



ESP-IDF เป็นชุดคอมไพล์เลอร์ ESP32 ที่พัฒนาโดยบริษัท Espressif ผู้ผลิตและออกแบบ ESP32 การพัฒนาโค้ด ESP32  สำหรับ Arduino นั้น จะทำควบคู่ไปกับการพัฒนา ESP-IDF โดยที่ ESP-IDF จะเป็นแกนหลัก โดยเมื่อมีการเพิ่มฟีเจอร์ใหม่ๆ ให้ ESP-IDF แล้ว จึงจะมีการเพิ่มใน Arduino IDE โดยใช้  ESP-IDF เป็นตัวคอมไพล์โค๊ด  แต่เพิ่มเติมการเขียนโปรแกรมแบบ Arduino เข้าไป ซึ่งหมายความว่า ต้องรอคน เขียน ไลบรารี่ ขึ้นมาก่อน  Arduino IDE ถึงจะทำงานได้


ขั้นตอนการทํางาน



1. ติดตั้ง Java 8 หรือ เวอร์ชั่นที่สูงกว่า


https://www.oracle.com/java/technologies/javase-jdk14-downloads.html







2. ติดตั้ง Python 3.5 หรือ เวอร์ชั่นที่สูงกว่า



ไปที่  https://www.python.org/downloads/windows/


ในตัวอย่างติดตั้งเวอร์ชั่น 3.7.4


คลิกที่ [ Download Windows x86 executable installer]









หลังจากนั้นจะได้ไฟล์ชื่อ python-3.X.X.exe ในคอมพิวเตอร์ของคุณ ให้ดับเบิ้ลคลิกที่ไฟล์เพื่อเปิด




 เลือก “Add Python 3.X to PATH“




 คลิกที่ “Install Now”




รอจนกระทั่งติดตั้งเสร็จ แล้วคลิก Close





3. ติดตั้ง Git บน Windows



https://git-scm.com/downloads






4. ติดตั้ง ESP-IDF 3.3.2


https://dl.espressif.com/dl/esp-idf/releases/esp-idf-v3.3.2.zip




คลายซิป แล้ว เลือกไปไว้ตามที่ต้องการ



5. ติดตั้ง Eclipse Installer 2020‑03 R หรือ เวอร์ชั่นที่สูงกว่า


https://www.eclipse.org/downloads/packages/installer

.





ติดตั้ง และ เลือกเป็น Eclipse IDE for C/C++ Developers









6. ปรับแต่ง ให้ Eclipse IDE ใช้งานกับ ESP-IDF


ไปที่ Help -> Install New Software



ที่ Work with: ป้อน https://dl.espressif.com/dl/idf-eclipse-plugin/updates/latest/ -> Add



Neme: ตั้งชื่อเป็น Espressif IDF Plugins for Eclipse -> Add




เลือกทั้งหมด -> Next


Next >



เลือก I accept the terms of the license agreement -> Finish






ไปที่ Help > Espressif IDF Tools Manager > Install Tools




ESP-IDF Directory : เลือกไปที่โฟลเดอร์ที่ติดตั้ง ESP-IDF (ติดตั้งในขั้นตอนที่ 4)

Git Executable Locations : เลือกไปที่ไฟล์ git.exe (ติดตั้งในขั้นตอนที่ 3)

Choose Python version : ซึ่งในตัวอย่างจะขึ้นให้โดยอัตโนมัติ (ติดตั้งในขั้นตอนที่ 2)

คลิก Install Tools >




รอจนกระทั่งติดตั้งเสร็จ




ไปที่ Window > Perspective > Reset Perspective





ตรวจสอบที่ File > New >  จะพบ Espressif IDF Project เพิ่มเข้ามา แสดงว่า  Eclipse IDE พร้อมใช้งานกับ ESP-IDF แล้ว







7. ตรวจสอบการเชื่อมต่อ ระหว่างคอมพิวเตอร์ กับ ESP32


เชื่อมต่อสาย USB ระหว่าง คอมพิวเตอร์ กับ ESP32




ตรวจสอบการติดตั้งไดร์เวอร์ ของ ชิปแปลง USB to UART เบอร์ CP2102 โดย คลิกขวา Computet -> Properties -> Device Manager

ที่ Ports (COM & LPT) จะพบ ไดร์เวอร์ ของชิป CP2102

ในตัวอย่างเป็น Silicon Labs CP210x USB to UART Bridge (COM20)





8. โปรแกรมแรกกับ ESP-IDF


ไปที่ File > New > Espressif IDF Projec




ตัวอย่างตั้งชื่อเป็น hello_world_esp32 > Next





เลือก Create a project using one of the templates > hello_world > Finish




ปิดหน้า Welcome ลงไป



คลิก dropdown ที่ Local > New Launch Target



เลือก ESP Target > Next



์Name : esp32

IDF Target : esp32

Serial Port : COM20 (แต่ละเครื่องไม่เหมือนกัน ให้เลือกข้อมูลจาก ขั้นตอนที่ 7 )

คลิก Finish



เลือกโปรเจค hello_world_esp32 แล้วคลิก รูปค้อน เพื่อ Build โปรแกรม




รอจนกระทั่ง  ขึ้น Build complete (0 errors, 0 warnings):




คลิก Launch เพื่ออัพโหลดโค้ดไปยัง ESP32




รอจนกระทั่ง  ขึ้น Done




คลิก Open a Terminal





เลือก Serial Terminal > OK



ที่ Terminal จะนับถอยหลัง จาก 10 - 0 แล้วจะแสดงข้อความ Hello world! แสดงว่าโปรแกรมแรกของคุณสำเร็จแล้ว



credit :  https://github.com/espressif/idf-eclipse-plugin/blob/master/README.md

วันอาทิตย์ที่ 24 พฤศจิกายน พ.ศ. 2562

โปรเจค ESP32-CAM กล้องดักถ่ายภาพอัตโนมัติ ด้วย PIR Motion



โปรเจค ESP32-CAM กล้องดักถ่ายภาพอัตโนมัติ ด้วย PIR Motion โดยโปรเจคนี้ สามารถประยุกต์เป็นกล้องดักถ่ายภาพเมื่อมีผู้บุกรุก หรือเป็นกล้องดักถ่ายภาพสัตว์ มีชื่อเรียกหลายชื่อได้แก่ Trail Cam, Scout Cam, Camera Trap โดยผู้ใช้งานโดยซ่อนไว้ใกล้บริเวณทางที่สัตว์เดินผ่าน หรือแหล่งน้ำและดินโป่งที่สัตว์ใช้ประจำเมื่อมีสัตว์เดินผ่านมาบริเวณที่ตัวเซ็นเซอร์จับการเคลื่อนไหวได้กล้องจะถ่ายภาพเองโดยอัตโนมัติ โดยจะเก็บไฟล์รูปภาพไว้ที่ SD Card


หลักการทำงานของโปรเจค

โดยเมื่อเริ่มทำงานเราจะให้ ESP32 อยู่โหมดการใช้งานแบบ Deep Sleep เพื่อเป็นการประหยัดพลังงาน แล้ว ปลุกให้ตื่นด้วยเซ็นเซอร์ PIR Motion เมื่อตรวจจับความเคลื่อนไหวได้ แล้วจึงสั่งให้กล้องจะถ่ายภาพ โดยเก็บไฟล์รูปภาพไว้ที่ SD Card จากนั้น ESP32 จะกลับเข้าสู่โหมดการใช้งานแบบ Deep Sleep เพื่อรอ การปลุกให้ตื่น ในครั้งต่อๆไป






### อุปกรณ์ที่ใช้ ###


1. ESP32-CAM ESP32 Development Board with Camera Module

2. CP2102 USB 2.0 to UART TTL 5PIN Connector Module

3. Jumper (M2M) 10cm Male to Male

4. Micro SD Card Class 10 16GB + Card Adapter

5. Keyestudio PIR Motion Sensor Module

6. 2N3904 NPN General Purpose Transistor

7. รีซิสเตอร์ 10K Ohm

8. รีซิสเตอร์ 1K Ohm

9. Jumper (F2M) 20cm Female to Male




การทำงานมีขั้นตอนดังนี้



1. ทดสอบการใช้งาน ESP32-CAM

จากบทความ การใช้งาน ESP32-CAM กล้อง OV2640 เป็น Video Stream ภาพเคลื่อนไหว


http://esp32robot.blogspot.com/2019/07/esp32-cam-ov2640-video-stream.html


2. ฟอร์แมต Micro SD Card



Micro SD Card , Class 10 ความจุ 16GB + Card Adapter




ให้เสียบ Micro SD Card เข้าไปใน Card Adapter



Card Adapter ที่มี Micro SD Card อยู่ด้านใน




แล้วจึงเสียบ Card Adapter ที่บรรจุ Micro SD Card ใส่ในช่องซ็อกเก็ตของคอมพิวเตอร์ PC (ดันจนกระทั่งมีเสียงคลิก)






ไปที่ My Computer แล้วคลิกขวาที่ไดร์ของ Micro SD Card เลือกรูปแบบตามที่แสดงในภาพด้านล่าง









3. ทดสอบบันทึกรูปภาพลง SD Card



เสียบ Micro SD Card เข้าไปใน Slot Card  







เปิดโปรแกรม Arduino (IDE) และ ก็อปปี้ โค้ดด้านล่างนี้ ไปวางไว้ในส่วนเขียนโปรแกรม
/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-cam-take-photo-save-microsd-card
  
  IMPORTANT!!! 
   - Select Board "ESP32 Wrover Module"
   - Select the Partion Scheme "Huge APP (3MB No OTA)
   - GPIO 0 must be connected to GND to upload a sketch
   - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "fb_gfx.h"
#include "fd_forward.h"
#include "fr_forward.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "dl_lib.h"
#include "driver/rtc_io.h"
#include <EEPROM.h>            // read and write from flash memory

// define the number of bytes you want to access
#define EEPROM_SIZE 1

// Pin definition for CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27

#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22

int pictureNumber = 0;

void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
 
  Serial.begin(115200);
  //Serial.setDebugOutput(true);
  //Serial.println();
  
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG; 
  
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
  
  // Init Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
  
  //Serial.println("Starting SD Card");
  if(!SD_MMC.begin()){
    Serial.println("SD Card Mount Failed");
    return;
  }
  
  uint8_t cardType = SD_MMC.cardType();
  if(cardType == CARD_NONE){
    Serial.println("No SD Card attached");
    return;
  }
    
  camera_fb_t * fb = NULL;
  
  // Take Picture with Camera
  fb = esp_camera_fb_get();  
  if(!fb) {
    Serial.println("Camera capture failed");
    return;
  }
  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureNumber = EEPROM.read(0) + 1;

  // Path where new picture will be saved in SD Card
  String path = "/picture" + String(pictureNumber) +".jpg";

  fs::FS &fs = SD_MMC; 
  Serial.printf("Picture file name: %s\n", path.c_str());
  
  File file = fs.open(path.c_str(), FILE_WRITE);
  if(!file){
    Serial.println("Failed to open file in writing mode");
  } 
  else {
    file.write(fb->buf, fb->len); // payload (image), payload length
    Serial.printf("Saved file to path: %s\n", path.c_str());
    EEPROM.write(0, pictureNumber);
    EEPROM.commit();
  }
  file.close();
  esp_camera_fb_return(fb); 
  
  // Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  rtc_gpio_hold_en(GPIO_NUM_4);
  
  delay(2000);
  Serial.println("Going to sleep now");
  delay(2000);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
}

void loop() {
  
}

*** เมื่อต้องการ อัพโหลดโค้ดทุกครั้งให้เชื่อมต่อสาย ระหว่าง IO0 <-> GND ***






 เชื่อมต่อ CP2102 USB เข้ากับคอมพิวเตอร์




ไปที่ Tools -> Board เลือก ESP32 Wrover Module





ไปที่ Tools -> Partition Scheme แล้วเลือก Huge APP(3MB No OTA)


ไปที่ Tools -> Port แล้วเลือกพอร์ตที่ปรากฏ (กรณีใช้เครื่องคอมพิวเตอร์ที่มี COM Port ให้เลือกตัวอื่นที่ไม่ใช่ COM1)

ในตัวอย่างเลือกเป็น "COM12"


กดปุ่ม   เพื่ออัพโหลด



หากสามารถอัพโหลดโปรแกรมลงบอร์ดได้สำเร็จ จะแสดงคำว่า Done uploading. ที่แถบด้านล่าง



### ถ้ามีปัญหาในการอัพโหลดไม่ได้ ให้กดปุ่ม RST ค้างไว้ในขณะอัพโหลด ###





ถอด Jumper ที่เชื่อมต่อระหว่าง IO0 <-> GND ออก





กดปุ่ม RST 1 ครั้ง  ต่อ 1 รูปภาพ



ESP32-CAM จะถ่ายภาพ โดยจะเก็บไฟล์รูปภาพไว้ที่ SD Card





เมื่อถอด SD Card ไปดูที่คอมพิวเตอร์ จะพบไฟล์รูปภาพ ที่ ESP32-CAM ถ่ายภาพเอาไว้





credit : https://randomnerdtutorials.com/esp32-cam-take-photo-save-microsd-card/



4. อัพโหลดโค้ดของโปรเจค



 เปิดโปรแกรม Arduino (IDE) อัพโหลดโค้ดด้านล่างนี้  ไปยัง ESP32-CAM

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-cam-pir-motion-detector-photo-capture/
 
  IMPORTANT!!!
   - Select Board "AI Thinker ESP32-CAM"
   - GPIO 0 must be connected to GND to upload a sketch
   - After connecting GPIO 0 to GND, press the ESP32-CAM on-board RESET button to put your board in flashing mode
 
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/
 
#include "esp_camera.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "fb_gfx.h"
#include "fd_forward.h"
#include "fr_forward.h"
#include "FS.h"                // SD Card ESP32
#include "SD_MMC.h"            // SD Card ESP32
#include "soc/soc.h"           // Disable brownour problems
#include "soc/rtc_cntl_reg.h"  // Disable brownour problems
#include "dl_lib.h"
#include "driver/rtc_io.h"
#include <EEPROM.h>            // read and write from flash memory
// define the number of bytes you want to access
#define EEPROM_SIZE 1
 
RTC_DATA_ATTR int bootCount = 0;

// Pin definition for CAMERA_MODEL_AI_THINKER
#define PWDN_GPIO_NUM     32
#define RESET_GPIO_NUM    -1
#define XCLK_GPIO_NUM      0
#define SIOD_GPIO_NUM     26
#define SIOC_GPIO_NUM     27
#define Y9_GPIO_NUM       35
#define Y8_GPIO_NUM       34
#define Y7_GPIO_NUM       39
#define Y6_GPIO_NUM       36
#define Y5_GPIO_NUM       21
#define Y4_GPIO_NUM       19
#define Y3_GPIO_NUM       18
#define Y2_GPIO_NUM        5
#define VSYNC_GPIO_NUM    25
#define HREF_GPIO_NUM     23
#define PCLK_GPIO_NUM     22
 
int pictureNumber = 0;

#define uS_TO_S_FACTOR 1000000
  
void setup() {
  WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); //disable brownout detector
  Serial.begin(115200);
 
  Serial.setDebugOutput(true);
 
  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;
  
  pinMode(4, INPUT);
  digitalWrite(4, LOW);
  rtc_gpio_hold_dis(GPIO_NUM_4);
 
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA; // FRAMESIZE_ + QVGA|CIF|VGA|SVGA|XGA|SXGA|UXGA
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }
 
  // Init Camera
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }
 
  Serial.println("Starting SD Card");
 
  delay(500);
  if(!SD_MMC.begin()){
    Serial.println("SD Card Mount Failed");
    //return;
  }
 
  uint8_t cardType = SD_MMC.cardType();
  if(cardType == CARD_NONE){
    Serial.println("No SD Card attached");
    return;
  }
   
  camera_fb_t * fb = NULL;
 
  // Take Picture with Camera
  fb = esp_camera_fb_get();  
  if(!fb) {
    Serial.println("Camera capture failed");
    return;
  }
  // initialize EEPROM with predefined size
  EEPROM.begin(EEPROM_SIZE);
  pictureNumber = EEPROM.read(0) + 1;
 
  // Path where new picture will be saved in SD Card
  String path = "/picture" + String(pictureNumber) +".jpg";
 
  fs::FS &fs = SD_MMC;
  Serial.printf("Picture file name: %s\n", path.c_str());
 
  File file = fs.open(path.c_str(), FILE_WRITE);
  if(!file){
    Serial.println("Failed to open file in writing mode");
  }
  else {
    file.write(fb->buf, fb->len); // payload (image), payload length
    Serial.printf("Saved file to path: %s\n", path.c_str());
    EEPROM.write(0, pictureNumber);
    EEPROM.commit();
  }
  file.close();
  esp_camera_fb_return(fb);
  
  delay(1000);
  
  // Turns off the ESP32-CAM white on-board LED (flash) connected to GPIO 4
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  rtc_gpio_hold_en(GPIO_NUM_4);

  esp_sleep_enable_ext0_wakeup(GPIO_NUM_13, 0);
 
  Serial.println("Going to sleep now");
  delay(1000);
  esp_deep_sleep_start();
  Serial.println("This will never be printed");
} 
 
void loop() {
 
}


5. เชื่อมต่ออุปกรณ์เพิ่มเติม


วงจรทำงานของโปรเจค









6. ทดสอบการทำงานของโปรเจค



    


credit : https://randomnerdtutorials.com/esp32-cam-pir-motion-detector-photo-capture/