วันอังคารที่ 17 กันยายน พ.ศ. 2562

สร้างกล้องเซลฟี่ ด้วย TTGO T-Camera Plus ESP32



TTGO T-Camera Plus ESP32  คือบอร์ด ESP32 ที่มีกล้อง OV2640 ความละเอียด 2 ล้านพิเซล ในตัว พร้อมจอภาพ IPS Panel ST7789 ขนาด 1.3 นิ้ว ซึ่งแอปพลิเคชั่นกล้องต้องการหน่วยความจำเพิ่มเติมดังนั้นจึงมีเพิ่ม Micro SD Card เข้าที่ช่องเสียบการ์ด


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


1. TTGO T-Camera Plus ESP32-DOWDQ6 Display Camera Module

2. Micro USB Cable Wire 1m

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




โดยการทำโปรเจคมีขั้นตอนดังนี้


1.ติดตั้ง Arduino core for ESP32

ลิงค์การติดตั้ง Arduino core for ESP32

https://robotsiam.blogspot.com/2017/09/arduino-core-for-esp32.html


2.ติดตั้ง ไลบรารี่ arduino-selfie-camera


2.1 ดาวน์โหลด ไลบรารี่ arduino-selfie-camera

https://github.com/moononournation/arduino-selfie-camera


2.2 คลิกที่ Clone or download -> Download ZIP





2.3 เปิด โปรแกรม Arduino IDE ไปที่ Skecth -> Include Library -> Add .ZIP Library...






2.4 ไปที่ ไลบรารี arduino-selfie-camera-master.zip ที่เรา ดาวน์โหลด มา -> Open




2.5 ตรวจสอบที่ Skecth -> Include Library  จะพบ ไลบรารี arduino-selfie-camera-master เพิ่มเข้ามาใน Arduino IDE ของเรา






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


ติดตั้งโปรแกรม SD Card Formatter 5.0 ใช้สำหรับ Format Disk สามารถดาวน์โหลดได้จากลิงก์



https://www.sdcard.org/downloads/formatter_4/eula_windows/


จากนั้นให้คลิกปุ่ม Accept โปรแกรม SD Formatter โปรแกรมจึงจะดาวน์โหลดสู่ คอมพิวเตอร์ของเรา




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




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



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




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






แล้วทำการ Format , Micro SD Card โดยใช้โปรแกรม  SD Card Formatter


ถ้าเสียบ Card Adapter ที่บรรจุ Micro SD Card ได้ถูกต้อง ที่ Select card จะมี ไดรฟ์ ให้เลือก ในตัวอย่างจะเป็น ไดรฟ์  F:/



เลือก Quick format และที่ Volume label ในตัวอย่างตั้งชื่อเป็น Robot



คลิก Format




คลิก Yes





คลิก OK  ถึงขั้นตอนนี้การ Format SD Card ของเรานั้นเสร็จสมบูรณ์แล้ว ให้ปิดโปรแกรมลงไป




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



 .




5.อัพโหลดโปรแกรม


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




5.2 เปิดโปรแกรม Arduino (IDE) และ ก็อปปี้ โค้ดด้านล่างนี้ ไปวางไว้ในส่วนเขียนโปรแกรม




#include <esp_camera.h>
#include <SD.h>
#include <FS.h>
#include <rom/tjpgd.h>
#include "cam.h"
#include "ST7789.h"
#include "tjpgdec.h"

#define SDCARA_CS 0
#define SNAP_QUALITY 6 // 1-63, 1 is the best

ST7789 tft = ST7789(); // Invoke library, pins defined in User_Setup.h

char tmpStr[256];
char nextFilename[31];
uint16_t fileIdx = 0;
int i = 0;
static uint16_t *preview;
sensor_t *s;
camera_fb_t *fb = NULL;
JPGIODEV dev;
char *work = NULL; // Pointer to the working buffer (must be 4-byte aligned)

void setup()
{
  Serial.begin(115200);
  // Serial.setDebugOutput(true);

  tft.init();
  tft.invertDisplay(true);
  tft.setSwapBytes(true);
  tft.setRotation(0);

  tft.fillScreen(TFT_BLACK);
  tft.setTextDatum(TL_DATUM);
  tft.setTextSize(2);
  tft.setTextColor(TFT_WHITE, TFT_RED);
  tft.drawString(" ESP", 0, 0);
  tft.setTextColor(TFT_WHITE, TFT_ORANGE);
  tft.drawString("32 ", 48, 0);
  tft.setTextColor(TFT_WHITE, TFT_GREEN);
  tft.drawString(" Camera ", 82, 0);
  tft.setTextColor(TFT_WHITE, TFT_BLUE);
  tft.drawString(" Plus  ", 172, 0);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextSize(1);

  if (!SD.begin(SDCARA_CS))
  {
    tft.drawString("SD Init Fail!", 0, 208);
    Serial.println("SD Init Fail!");
  }
  else
  {
    snprintf(tmpStr, sizeof(tmpStr), "SD Card Type: %d Size: %lu MB", SD.cardType(), SD.cardSize() / 1024 / 1024);
    tft.drawString(tmpStr, 0, 208);
    Serial.println(tmpStr);

    init_folder();

    xTaskCreate(
        findNextFileIdxTask,       /* Task function. */
        "FindNextFileIdxTask", /* String with name of task. */
        10000,                 /* Stack size in bytes. */
        work,                  /* Parameter passed as input of the task */
        1,                     /* Priority of the task. */
        NULL);                 /* Task handle. */
  }

  esp_err_t err = cam_init();
  if (err != ESP_OK)
  {
    snprintf(tmpStr, sizeof(tmpStr), "Camera init failed with error 0x%x", err);
    tft.drawString(tmpStr, 0, 208);
    Serial.println(tmpStr);
  }

  //drop down frame size for higher initial frame rate
  s = esp_camera_sensor_get();
  s->set_brightness(s, 2);
  s->set_contrast(s, 2);
  s->set_saturation(s, 2);
  s->set_sharpness(s, 2);
  s->set_aec2(s, true);
  s->set_denoise(s, true);
  s->set_lenc(s, true);
  s->set_hmirror(s, true);
  //s->set_vflip(s, true);
  s->set_quality(s, 63);

  preview = new uint16_t[200 * 150];
  work = (char *)malloc(WORK_BUF_SIZE);
  dev.linbuf_idx = 0;
  dev.x = 0;
  dev.y = 0;
  dev.linbuf[0] = (color_t *)heap_caps_malloc(JPG_IMAGE_LINE_BUF_SIZE * 3, MALLOC_CAP_DMA);
  dev.linbuf[1] = (color_t *)heap_caps_malloc(JPG_IMAGE_LINE_BUF_SIZE * 3, MALLOC_CAP_DMA);
}

esp_err_t cam_init()
{
  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;
  // init with high specs to pre-allocate larger buffers
  config.frame_size = FRAMESIZE_UXGA;
  config.jpeg_quality = SNAP_QUALITY;
  config.fb_count = 2;

  // camera init
  return esp_camera_init(&config);
}

void init_folder()
{
  File file = SD.open("/DCIM");
  if (!file)
  {
    Serial.println("Create /DCIM");
    SD.mkdir("/DCIM");
  }
  else
  {
    Serial.println("Found /DCIM");
    file.close();
  }
  file = SD.open("/DCIM/100ESPDC");
  if (!file)
  {
    Serial.println("Create /DCIM/100ESPDC");
    SD.mkdir("/DCIM/100ESPDC");
  }
  else
  {
    Serial.println("Found /DCIM/100ESPDC");
    file.close();
  }
}

void findNextFileIdxTask(void *parameter)
{
  findNextFileIdx();
  vTaskDelete(NULL);
}

void findNextFileIdx()
{ // TODO: revise ugly code
  fileIdx++;
  File file;
  snprintf(nextFilename, sizeof(nextFilename), "/DCIM/100ESPDC/DSC%05D.JPG", fileIdx);
  file = SD.open(nextFilename);
  if (!file)
  {
    Serial.printf("Next file: %s\n", nextFilename);
    return;
  }
  else
  {
    for (int k = 1000; k <= 30000; k += 1000)
    {
      snprintf(nextFilename, sizeof(nextFilename), "/DCIM/100ESPDC/DSC%05D.JPG", fileIdx + k);
      file = SD.open(nextFilename);
      if (file)
      {
        Serial.printf("Found %s\n", nextFilename);
        file.close();
      }
      else
      {
        Serial.printf("Not found %s\n", nextFilename);
        k -= 1000;
        for (int h = 100; h <= 1000; h += 100)
        {
          snprintf(nextFilename, sizeof(nextFilename), "/DCIM/100ESPDC/DSC%05D.JPG", fileIdx + k + h);
          file = SD.open(nextFilename);
          if (file)
          {
            Serial.printf("Found %s\n", nextFilename);
            file.close();
          }
          else
          {
            Serial.printf("Not found %s\n", nextFilename);
            h -= 100;
            for (int t = 10; t <= 100; t += 10)
            {
              snprintf(nextFilename, sizeof(nextFilename), "/DCIM/100ESPDC/DSC%05D.JPG", fileIdx + k + h + t);
              file = SD.open(nextFilename);
              if (file)
              {
                Serial.printf("Found %s\n", nextFilename);
                file.close();
              }
              else
              {
                Serial.printf("Not found %s\n", nextFilename);
                t -= 10;
                for (int d = 1; d <= 10; d++)
                {
                  snprintf(nextFilename, sizeof(nextFilename), "/DCIM/100ESPDC/DSC%05D.JPG", fileIdx + k + h + t + d);
                  file = SD.open(nextFilename);
                  if (file)
                  {
                    Serial.printf("Found %s\n", nextFilename);
                    file.close();
                  }
                  else
                  {
                    Serial.printf("Next file: %s\n", nextFilename);
                    fileIdx += k + h + t + d;
                    return;
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

void snap()
{
  s->set_hmirror(s, false);
  //s->set_vflip(s, false);
  s->set_quality(s, SNAP_QUALITY);

  tft.fillRect(20, 45, 200, 150, TFT_DARKGREY);

  fb = esp_camera_fb_get();
  esp_camera_fb_return(fb);
  fb = NULL;

  tft.fillRect(20, 45, 200, 150, TFT_LIGHTGREY);

  fb = esp_camera_fb_get();
  if (!fb)
  {
    tft.drawString("Camera capture JPG failed", 0, 208);
    Serial.println("Camera capture JPG failed");
  }
  else
  {
    File file = SD.open(nextFilename, FILE_WRITE);
    if (file.write(fb->buf, fb->len))
    {
      tft.fillRect(20, 45, 200, 150, TFT_LIGHTGREY);
      snprintf(tmpStr, sizeof(tmpStr), "File written: %luKB\n%s", fb->len / 1024, nextFilename);
      tft.drawString(tmpStr, 0, 224);
      Serial.println(tmpStr);
    }
    else
    {
      tft.drawString("Write failed!", 0, 224);
      Serial.println("Write failed!");
    }
    esp_camera_fb_return(fb);
    fb = NULL;
    file.close();
  }

  s->set_hmirror(s, true);
  //s->set_vflip(s, true);
  s->set_quality(s, 63);
  fb = esp_camera_fb_get();
  esp_camera_fb_return(fb);
  fb = NULL;
}

void enterSleep()
{
  tft.end();
  esp_deep_sleep_start();
}

void loop()
{
  if (i == 1) // count down
  {
    tft.setTextSize(2);
    tft.drawString("3", 116, 24);
    Serial.println("3");
  }
  else if (i == 5)
  {
    tft.setTextSize(2);
    tft.drawString("2", 116, 24);
    Serial.println("2");
  }
  else if (i == 9)
  {
    tft.setTextSize(2);
    tft.drawString("1", 116, 24);
    Serial.println("1");
  }
  else if (i == 13) // start snap 
  {
    tft.setTextSize(2);
    tft.drawString("Cheeze!", 92, 24);
    Serial.println("Cheeze!");

    snap();
  }
  else if (i == 15)
  {
    tft.setTextSize(2);
    tft.drawString("Cheeze!!", 92, 24);
    Serial.println("Cheeze!!");

    findNextFileIdx();
    snap();
  }
  else if (i == 17)
  {
    tft.setTextSize(2);
    tft.drawString("Cheeze!!!", 92, 24);
    Serial.println("Cheeze!!!");

    findNextFileIdx();
    snap();

    tft.setTextSize(2);
    tft.drawString("Reset to snap again!", 0, 24);
    Serial.println("Reset to snap again!");

    decodeJpegFile(nextFilename, 3);
    tft.pushRect(20, 45, 200, 150, preview);
    delay(5000);
    Serial.println("Enter deep sleep...");
    enterSleep();
  }
  else
  {
    fb = esp_camera_fb_get();
    if (!fb)
    {
      Serial.printf("Camera capture failed!");
      tft.drawString("Camera capture failed!", 0, 224);
    }
    else
    {
      decodeJpegBuff(fb->buf, fb->len, 3);
      tft.pushRect(20, 45, 200, 150, preview);
      esp_camera_fb_return(fb);
      fb = NULL;
    }
  }

  i++;
}

// User defined call-back function to input JPEG data from file
//---------------------
static UINT tjd_file_input (
 JDEC* jd,  // Decompression object
 BYTE* buff,  // Pointer to the read buffer (NULL:skip)
 UINT nd   // Number of bytes to read/skip from input stream
)
{
 int rb = 0;
 // Device identifier for the session (5th argument of jd_prepare function)
 JPGIODEV *dev = (JPGIODEV*)jd->device;

 if (buff) { // Read nd bytes from the input strem
  rb = dev->f.read(buff, nd);
  return rb; // Returns actual number of bytes read
 }
 else { // Remove nd bytes from the input stream
  if (dev->f.seek(dev->f.position() + nd)) return nd;
  else return 0;
 }
}

// User defined call-back function to input JPEG data from memory buffer
//-------------------------
static UINT tjd_buf_input(
    JDEC *jd,   // Decompression object
    BYTE *buff, // Pointer to the read buffer (NULL:skip)
    UINT nd     // Number of bytes to read/skip from input stream
)
{
  // Device identifier for the session (5th argument of jd_prepare function)
  JPGIODEV *dev = (JPGIODEV *)jd->device;
  if (!dev->membuff)
    return 0;
  if (dev->bufptr >= (dev->bufsize + 2))
    return 0; // end of stream

  if ((dev->bufptr + nd) > (dev->bufsize + 2))
    nd = (dev->bufsize + 2) - dev->bufptr;

  if (buff)
  { // Read nd bytes from the input strem
    memcpy(buff, dev->membuff + dev->bufptr, nd);
    dev->bufptr += nd;
    return nd; // Returns number of bytes read
  }
  else
  { // Remove nd bytes from the input stream
    dev->bufptr += nd;
    return nd;
  }
}

// User defined call-back function to output RGB bitmap to display device
//----------------------
static UINT tjd_output(
    JDEC *jd,     // Decompression object of current session
    void *bitmap, // Bitmap data to be output
    JRECT *rect   // Rectangular region to output
)
{
  BYTE *src = (BYTE *)bitmap;
  // Serial.printf("%d, %d, %d, %d\n", rect->top, rect->left, rect->bottom, rect->right);
  for (int y = rect->top; y <= rect->bottom; y++)
  {
    for (int x = rect->left; x <= rect->right; x++)
    {
      preview[y * 200 + x] = tft.color565(*(src++), *(src++), *(src++));
    }
  }
  return 1; // Continue to decompression
}

void decodeJpegBuff(uint8_t arrayname[], uint32_t array_size, uint8_t scale)
{
  JDEC jd; // Decompression object (70 bytes)
  JRESULT rc;

  //dev.fhndl = NULL;
  // image from buffer
  dev.membuff = arrayname;
  dev.bufsize = array_size;
  dev.bufptr = 0;

  if (scale > 3)
    scale = 3;

  if (work)
  {
    rc = jd_prepare(&jd, tjd_buf_input, (void *)work, WORK_BUF_SIZE, &dev);
    if (rc == JDR_OK)
    {
      // Start to decode the JPEG file
      rc = jd_decomp(&jd, tjd_output, scale);
    }
  }
}

void decodeJpegFile(char filename[], uint8_t scale)
{
  JDEC jd; // Decompression object (70 bytes)
  JRESULT rc;

  dev.f = SD.open(filename);
  // image from buffer
  //dev.membuff = null;
  dev.bufsize = JPG_IMAGE_LINE_BUF_SIZE;
  dev.bufptr = 0;

  if (scale > 3)
    scale = 3;

  if (work)
  {
    rc = jd_prepare(&jd, tjd_file_input, (void *)work, WORK_BUF_SIZE, &dev);
    if (rc == JDR_OK)
    {
      // Start to decode the JPEG file
      rc = jd_decomp(&jd, tjd_output, scale);
    }
  }
}



ดาวน์โหลดโค้ด :


https://drive.google.com/open?id=1qsyOCNZRPyIpr72bs7f1DzmVua4qYKX9


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




5.4 ไปที่ Tools -> PSRAM: เลือกเป็น Enabled






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

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





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


ตั้งชื่อไฟล์ -> Save โปรแกรม จะทำการ อัพโหลด







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




6. ทดสอบการทํางาน







1. กดปุ่มรีเซ็ตเพื่อเปิดกล้อง T-Camera Plus ESP32
2. กล้องนับถอยหลังจาก 3
3. ปรับมุมที่คุณชื่นชอบ
4. กล้องถ่ายรูปเริ่มถ่ายภาพ 3 ภาพติดต่อกัน
5. เล่นภาพที่ถ่ายครั้งสุดท้ายโดยอัตโนมัติ
6. เข้าสู่ Sleep Mode หลังจาก 5 วินาที
7. กดปุ่มรีเซ็ตเพื่อถ่ายอีกครั้ง




7. วีดีโอ ผลลัพล์การทำงาน








credit :  https://www.instructables.com/id/Arduino-Selfie-Camera/

วันอังคารที่ 6 สิงหาคม พ.ศ. 2562

โปรเจค ESP32 แสดงตำแหน่งจาก GPS Module ด้วย Google Maps


โปรเจค ESP32  แสดงตำแหน่งจาก GPS Module ด้วย Google Maps  โดย GPS ย่อมาจาก Global Positioning System  ใช้เพื่อค้นหาตำแหน่งต่างๆบนโลก อ่านค่าเป็น ละติจูด ลองจิจูด การใช้งานโดยการเชื่อมต่อโมดูล GPS กับ ESP32 และให้แสดง ละติจูด ลองจิจูด ที่อัปเดตในหน้า ของ Serial Monitor  และนำข้อมูลไปใช้งานที่  Google Maps เพื่อให้แสดงรายละเอียดของตำแหน่ง ของบอร์ด ESP32 



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


1. PICO KIT V4 ESP32 Development Board WiFi + Bluetooth

2. Micro USB Cable Wire 1m for NodeMCU

3. Breadboard 830 Point MB-102

4. GY-NEO6MV2 NEO-6M GPS Module

5. 2.54 mm Right Angle Single Row Pin Male Header

6. Jumper (M2M) 20cm Male to Male



โดยการทำโปรเจคมีขั้นตอนดังนี้


1.ติดตั้ง Arduino core for ESP32

ลิงค์การติดตั้ง Arduino core for ESP32

https://robotsiam.blogspot.com/2017/09/arduino-core-for-esp32.html




2.เชื่อมต่ออุปกรณ์


2.1 ใช้ตะกั่วบัดกรี ขา Right Angle เข้ากับ GPS Module






2.2 เชื่อมต่อ ตัวรับสัญญาณ GPS และเสาอากาศ






2.3 เชื่อมต่อ  ESP32  กับ GPS Module








ภาพรวมการต่อวงจร 









3.ติดตั้ง ไลบรารี่ Tiny GPS++ สำหรับ Arduino IDE 


 3.1 ดาวน์โหลด ไลบรารี่ Tiny GPS++ได้ที่


https://github.com/mikalhart/TinyGPSPlus/archive/v1.0.2.zip



3.2 เปิด โปรแกรม Arduino IDE ไปที่ Skecth -> Include Library -> Add .ZIP Library...







3.3 ไปที่ ไลบรารี TinyGPSPlus-1.0.2.zip ที่เรา ดาวน์โหลด มา -> Open





ตรวจสอบที่ Skecth -> Include Library  จะพบ ไลบรารี TinyGPS++ เพิ่มเข้ามาใน Arduino IDE ของเรา







4. อัพโหลดโปรแกรม


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




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

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

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






4.3 เปิดโปรแกรม Arduino (IDE) และ ก็อปปี้ โค้ดด้านล่างนี้ ไปวางไว้ในส่วนเขียนโปรแกรม




#include <TinyGPS++.h>
#include <HardwareSerial.h>

#define RXPin (22)
#define TXPin (21)

static const uint32_t GPSBaud = 9600;

// The TinyGPS++ object
TinyGPSPlus gps;

// The serial connection to the GPS device
HardwareSerial ss(2);

void setup()
{
  Serial.begin(115200);
  ss.begin(GPSBaud, SERIAL_8N1, RXPin, TXPin, false);
  Serial.println(TinyGPSPlus::libraryVersion());
}

void loop()
{
  
  while (ss.available() > 0)
    if (gps.encode(ss.read()))
      displayInfo();

  if (millis() > 5000 && gps.charsProcessed() < 10)
  {
    Serial.println(F("No GPS detected: check wiring."));
    while(true);
  }
}

void displayInfo()
{
  Serial.print(F("Location: ")); 
  if (gps.location.isValid())
  {
    Serial.print(gps.location.lat(), 6);
    Serial.print(F(","));
    Serial.print(gps.location.lng(), 6);
  }
  else
  {
    Serial.print(F("INVALID"));
  }

  Serial.println();
}



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




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

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





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


ตั้งชื่อไฟล์ -> Save โปรแกรม จะทำการ อัพโหลด






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




5. ทดสอบการทํางาน


5.1 เปิดหน้าต่าง Serial Monitor  โดยไปที่ Tools > Serial Monitor





5.2 มุมขวาล่าง ของ Serial Monitor เลือก 115200 baud  คือ ตั้งค่าความเร็วในการรับ-ส่งข้อมูล  คือ 115200






5.3 กดที่ปุ่ม EN 1 ครั้ง เพื่อเริ่มการทำงาน ของ ESP32




5.4 ในกรณี โมดูล GPS ยังไม่ทำงานจะแสดง Location: INVALID





5.5 รอจนกระทั่งทำงานปรกติ จะแสดงตำแหน่ง ละติจูด ลองจิจูด ในตัวอย่างนี้คือ 13.990263,100.540156

(สังเกต ไฟ LED สีแดง ใน GPS Module จะกระพริบ)




6. ดูตำแหน่งที่ Google Maps



6.1 ใช้ คอมพิวเตอร์ หรือ สมาร์ทโฟน เปิดเว็บบราวเซอร์ ที่ URL ป้อน  https://www.google.com/maps/



6.2 ป้อน ละติจูด ลองจิจูด  ที่ได้มาจากข้อ 5.5  ในตัวอย่างนี้คือ 13.990263,100.540156


จะแสดงตำแหน่งปัจจุบัน ของบอร์ด ESP32 










...

credit :  https://playground.cmmakerclub.com