ทดสอบ เซนเซอร์วัดความเข้มแสง ด้วย ESP 8266 + อ่านค่าจาก Blynk

สวัสดีครับ สำหรับบทความนี้ผมจะทำการทดสอบเซนเซอร์วัดความเข้มแสงด้วย ESP 8266 + อ่านค่าจาก Blynk
สำหรับตัวเซ็นเซอร์จะใช้รุ่นนี้ครับ MCU-3001 OPT3001 Ambient Light lux meter Sensor

สเปคตามนี้ครับ

  • มีวงจรกรองแสงที่แม่นยำ

  • ตั้งค่าอัตโนมัติเต็มรูปแบบ

  • วัดความเข้มแสงได้ช่วงกว้างตั้งแต่ 0.01 lux ถึง 83,000 lux

  • ใช้ไฟเลี้ยง 3.3V กระแสไฟใช้งานต่ำเพียง 1.8 μA

    อาจจะมีหลายท่านสงสัยว่าจะเอาเซ็นเซอร์ตัวนี้ไปทำอะไร ก็จะบอกว่าแล้วแต่ไอเดียลักษณะงานที่จะใช้ โดยโครงงานต่างๆที่ผมทำขึ้นมา ส่วนใหญ่จะเริ่มต้นใช้ภายในบ้าน แล้วค่อยขยายออกไปข้างนอก โดยเซ็นเซอร์ตัวนี้ผมมีจุดประสงค์ก็คือผมอยากจะเช็คสภาพแวดล้อมที่บ้าน โดย Monitor ผ่านสมาร์ทโฟนก็คือ App blynk นั่นเอง ก็คือผมอยากจะรู้ว่าที่บ้านแสงแดดเป็นยังไงบ้าง แสงแดดจ้า แดดร่มหรือครึ้ม หรือเข้าสู่ตอนกลางคืนแล้ว จะบอกว่าผมจะไม่ใช้เซ็นเซอร์ตัวนี้ตัวเดียว แต่จะมีเซ็นเซอร์อีก 2 ตัวเข้ามาเกี่ยวข้องก็คือ เซ็นเซอร์วัดอุณหภูมิและความชื้น และเซ็นเซอร์บอกระดับความแรงของฝนตก ซึ่งตรงนี้ก็กำลังศึกษาอยู่ว่าควรจะใช้เซ็นเซอร์ตัวไหนที่จะเหมาะกับที่บ้าน และมีไอเดียว่าเมื่อเราสามารถเช็คสภาพอากาศจากเซ็นเซอร์ทั้ง 3 ตัวได้ เราก็สามารถที่จะประเมินได้ว่า ขณะนี้สภาพอากาศที่บ้านเป็นอย่างไร เช่นฝนตกแต่แดดออก หรือฝนตกฟ้ามืด หรืออื่นๆ ซึ่ง Project ที่นำมาเสนอ ผมอยากจะเก็บข้อมูลเอาไว้ในเว็บไซต์นี้ ส่วนหนึ่งและอีกส่วนหนึ่ง ถ้าผู้ที่เข้ามาอ่านในกระทู้นี้แล้วเกิดมีไอเดียที่แตกยอดออกไปก็ถือว่าโครงการที่ผมทำ มีประโยชน์ต่อบุคคลที่สนใจครับ ส่วนใครมีไอเดียอะไร ก็ โพสท์ แนะนำมาได้เลยครับ

ลองชมคลิปดูครับ สั้นๆ

Code เบื้องต้น รอพัฒนาต่อ

#include <ESP8266WiFi.h>                  //โหลดไลบารี่ ..มาใช้งาน                        //https://github.com/esp8266/Arduino
#include <ESP8266WebServer.h>             //โหลดไลบารี่ ..มาใช้งาน
#include <WiFiManager.h>                  //โหลดไลบารี่ ..มาใช้งาน                        //https://github.com/tzapu/WiFiManager
#include <FS.h>                           //โหลดไลบารี่ ..มาใช้งาน                        //this needs to be first, or it all crashes and burns...
#include <DNSServer.h>                    //โหลดไลบารี่ ..มาใช้งาน
#include <ArduinoJson.h>                  //โหลดไลบารี่ ..มาใช้งาน                        //https://github.com/bblanchon/ArduinoJson
#include <BlynkSimpleEsp8266.h>           //โหลดไลบรารี่ของ BLYNK ..มาใช้งาน

#include <Wire.h>
#include <ClosedCube_OPT3001.h>
ClosedCube_OPT3001 opt3001;

#define OPT3001_ADDRESS 0x44


//------------------------------------------------------------------------------------------------

#define BLYNK_DEBUG
#define BLYNK_PRINT Serial        // Comment this out to disable prints and save space

//------------------------------------------------------------------------------------------------


//------------------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------------------------------------------------------------

int blynkIsDownCount = 0;                                     //Integer Variable ตัวแปรชื่อ blynkIsDownCount ใช้เก็บเลขจำนวนเต็ม โดยเริ่มต้นให้มีค่า = 0
char blynk_token[34] = "YkNarC2Yub7M2OcPbPnnn7UVBIeFMqgD";   
//Character Variable ตัวแปรที่ใช้เก็บอักขระ
bool shouldSaveConfig = false;

BlynkTimer timer;  //เรียกใช้การตั้งเวลาของ Blynk

//callback notifying us of the need to save config
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}
//-------------------------------------------------------------------------------------------------------------------------------------------


//***********สำหรับ Server local ที่แจกให้ เพิ่ม **** แค่ 2 บรรทัดนี้
char server[] = "oasiskit.com";
int port = 8080;
//***************************************************************



//*****************************************************************************************************
//*******************************       void setup        *********************************************
//*****************************************************************************************************

void setup() {

  //****************************************************************************************************

  pinMode(D0, OUTPUT);//กำหนดโหมดใช้งานให้กับขา D0 เป็นขา สัญญาณไฟ ในสภาวะต่างๆ
  pinMode(D3, INPUT_PULLUP);//กำหนดโหมดใช้งานให้กับขา D3 เป็นขา กดปุ่ม ค้าง เพื่อตั้งค่า AP config

  // ให้ LED ทั้งหมดดับก่อน
  digitalWrite(D0, LOW);//ให้หลอด LED สีฟ้าดับก่อน


  //***************************************************************************************************

  Serial.begin(115200);
  opt3001.begin(OPT3001_ADDRESS);
  //*************************    การ อ่าน  เขียนค่า WiFi + Password ]ลงใน Node MCU ESP8266   ************

  //read configuration from FS json
  Serial.println("mounting FS...");//แสดงข้อความใน Serial Monitor

  if (SPIFFS.begin()) {
    Serial.println("mounted file system");//แสดงข้อความใน Serial Monitor

    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");//แสดงข้อความใน Serial Monitor
      File configFile = SPIFFS.open("/config.json", "r");

      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success()) {
          Serial.println("\nparsed json");//แสดงข้อความใน Serial Monitor
          strcpy(blynk_token, json["blynk_token"]);

        } else {
          Serial.println("failed to load json config");//แสดงข้อความใน Serial Monitor
        }
      }
    }
  } else {
    Serial.println("failed to mount FS");//แสดงข้อความใน Serial Monitor
  }
  //end read

  //*************************   จบการ อ่าน  เขียนค่า WiFi + Password ]ลงใน Node MCU ESP8266   ***************


  //**************************        AP AUTO CONNECT   **************************************************

  WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 34);

  //WiFiManager
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;

  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);
  wifiManager.addParameter(&custom_blynk_token);

  for (int i = 5; i > 0; i--) {
    digitalWrite(D0, HIGH);
    delay(500);
    digitalWrite(D0, LOW);
    delay(500);
    Serial.print (String(i) + " ");//แสดงข้อความใน Serial Monitor

  }


  if (digitalRead(D3) == LOW) {
    digitalWrite(D0, LOW);
    Serial.println("Button Pressed");//แสดงข้อความใน Serial Monitor
    wifiManager.resetSettings();//ให้ล้างค่า SSID และ Password ที่เคยบันทึกไว้


    // wifiManager.autoConnect(); ใช้สร้างชื่อแอคเซสพอยต์อันโนมัติจาก ESP + ChipID

    if (!wifiManager.autoConnect("PUYIOT AP CONFIG")) {
      Serial.println("failed to connect and hit timeout");//แสดงข้อความใน Serial Monitor
      delay(3000);
      //reset and try again, or maybe put it to deep sleep
      ESP.reset();
      delay(5000);

    }
  }


  Serial.println("connected........:)");//แสดงข้อความใน Serial Monitor
  strcpy(blynk_token, custom_blynk_token.getValue());


  //save the custom parameters to FS
  if (shouldSaveConfig) {
    Serial.println("saving config");//แสดงข้อความใน Serial Monitor
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    json["blynk_token"] = blynk_token;
    File configFile = SPIFFS.open("/config.json", "w");

    if (!configFile) {
      Serial.println("failed to open config file for writing");//แสดงข้อความใน Serial Monitor
    }
    json.printTo(Serial);
    json.printTo(configFile);
    configFile.close();
    //end save
  }

  //**************************    จบ    AP AUTO CONNECT   **************************************************

  Serial.println("local ip"); //แสดงข้อความใน Serial Monitor
  delay(100);
  Serial.println(WiFi.localIP());//แสดงข้อความใน Serial Monitor
  // Blynk.config(blynk_token);////เริ่มการเชื่อมต่อ Blynk Server แบบปกติ
  Blynk.config(blynk_token, server, port);
  ////เริ่มการเชื่อมต่อ Blynk Server*********สำหรับ Server local ที่แจกให้ เพิ่ม, server, port  แค่นี้จบ



  timer.setInterval(30000L, reconnecting);  //Function reconnect
  //ตั้งเวลาส่งข้อมูลให้ Blynk Server ทุกๆ 30 วินาที
  //มาจากฟังชั่นเปิดใช้งาน BlynkTimer ซึ่งทำหน้าที่คล้าย ๆ interrupt timer หมายถึงเมื่อครบเวลาตามที่กำหนดไว้โปรแกรมหลักจะกระโดดไปทำงานในโปรแกรมตอบสนองที่กำหนดไว้
  // (1) ชื่อออฟเจคไว้อ้างอิง (ผู้ใช้งานตั้งชื่อเองในที่นี้ตั้งคำว่า "timer")
  // (2) กำหนดค่าช่วงเวลาที่ให้บอร์ดกระโดดไปทำงานในโปรแกรมตอบสนอง ในที่นี้กำหนดเป็น 30000L หมายถึงให้บอร์ดมาทำงานในโปรแกรมตอบสนองทุก ๆ 30 วินาที
  // (3) ชื่อโปรแกรมตอบสนอง (ฟังก์ชั่นย่อย)  ในที่นี้ตั้งชื่อว่า reconnecting  ซึ่งบอร์ดจะวนมาทำงานฟังก์ชั่นชื่อนี้ทุก ๆ เวลาที่กำหนด (ทุกๆ 30 วินาที)


  configureSensor();
  printResult("High-Limit", opt3001.readHighLimit());
  printResult("Low-Limit", opt3001.readLowLimit());


}


//*****************************************************************************************************
//*******************************     จบ  void setup        *********************************************
//*****************************************************************************************************



//*****************************************************************************************************
//*******************************     void loop       *************************************************

void loop() {

  OPT3001 result = opt3001.readResult();
  printResult("OPT3001", result);

  delay(3000);

  //--------------------------------------------------------------------------------------------------------

  if (Blynk.connected())
  {
    Blynk.run();// ถ้าเชื่อมต่ Blynk Server ได้-----ไฟ LED สีน้ำเงินบนบอร์ด จะติดค้าง

    digitalWrite(D0, HIGH); //หลอด LED สีน้ำเงินที่ บอร์ด MCU esp8266 ติดค้างแสดงว่า WiFi ใช้งานได้



    //-----// ถ้าเชื่อมต่ Blynk Server ไม่ได้-----ไฟ LED สีน้ำเงินบนบอร์ด จะกระพริบ---------------------------------
    //----//หลอด LED สีแดงติดกระพริบแสดงว่ากำลังค้นหา WiFi ----------------------------------------------------

  } else {

    digitalWrite(D0, LOW);
    delay(200);
    digitalWrite(D0, HIGH);
    delay(100);

  }
  //--------------------------------------------------------------------------------------------------------


  timer.run();//ให้เวลาของ Blynk ทำงาน

  delay(100);
}


//*******************************   จบ  void loop     *************************************************
//*****************************************************************************************************


//--------------------------------------------------------------------------------------------------------
void reconnecting()
{
  if (!Blynk.connected())
  {
    blynkIsDownCount++;
    BLYNK_LOG("blynk server is down! %d  times", blynkIsDownCount);
    Blynk.connect(5000);
  }
}
//--------------------------------------------------------------------------------------------------------


BLYNK_CONNECTED()
{


  Blynk.syncAll();//ให้ซิงค์ข้อมูลทั้งหมดล่าสุดจาก Blynk Server
  //Serial.println(".");//per debug  //แสดงข้อความใน Serial Monitor


}

void configureSensor() {
  OPT3001_Config newConfig;

  newConfig.RangeNumber = B1100;
  newConfig.ConvertionTime = B0;
  newConfig.Latch = B1;
  newConfig.ModeOfConversionOperation = B11;

  OPT3001_ErrorCode errorConfig = opt3001.writeConfig(newConfig);
  if (errorConfig != NO_ERROR)
    printError("OPT3001 configuration", errorConfig);
  else {
    OPT3001_Config sensorConfig = opt3001.readConfig();
    //    Serial.println("OPT3001 Current Config:");
    //    Serial.println("------------------------------");
    //
    //    Serial.print("Conversion ready (R):");
    //    Serial.println(sensorConfig.ConversionReady, HEX);
    //
    //    Serial.print("Conversion time (R/W):");
    //    Serial.println(sensorConfig.ConvertionTime, HEX);
    //
    //    Serial.print("Fault count field (R/W):");
    //    Serial.println(sensorConfig.FaultCount, HEX);
    //
    //    Serial.print("Flag high field (R-only):");
    //    Serial.println(sensorConfig.FlagHigh, HEX);
    //
    //    Serial.print("Flag low field (R-only):");
    //    Serial.println(sensorConfig.FlagLow, HEX);
    //
    //    Serial.print("Latch field (R/W):");
    //    Serial.println(sensorConfig.Latch, HEX);
    //
    //    Serial.print("Mask exponent field (R/W):");
    //    Serial.println(sensorConfig.MaskExponent, HEX);
    //
    //    Serial.print("Mode of conversion operation (R/W):");
    //    Serial.println(sensorConfig.ModeOfConversionOperation, HEX);
    //
    //    Serial.print("Polarity field (R/W):");
    //    Serial.println(sensorConfig.Polarity, HEX);
    //
    //    Serial.print("Overflow flag (R-only):");
    //    Serial.println(sensorConfig.OverflowFlag, HEX);
    //
    //    Serial.print("Range number (R/W):");
    //    Serial.println(sensorConfig.RangeNumber, HEX);
    //
    //    Serial.println("------------------------------");
  }

}

void printResult(String text, OPT3001 result) {
  if (result.error == NO_ERROR) {
    Serial.print(text);
    Serial.print(": ");
    Serial.print(result.lux);
    Serial.println(" lux");
    Blynk.virtualWrite(V0, result.lux);

    //https://apps.timwhitlock.info/emoji/tables/unicode
    //"\xE2\x9B\x85"Sun behind
    //"\xE2\x98\x80" :black sun with rays
    //"\xE2\x98\x81" cloud
    //"\xF0\x9F\x8C\x9C"  last quarter moon with face

  }
  else {
    printError(text, result.error);
  }
  if (result.lux < 50 ) {
    Blynk.virtualWrite(V40,  "\xF0\x9F\x8C\x9C");
  }
  
  if (result.lux > 50 and result.lux <= 2000) {
    Blynk.virtualWrite(V40,  "\xE2\x98\x81");
  }

  if (result.lux > 2000 and result.lux <= 20000 ) {
    Blynk.virtualWrite(V40,  "\xE2\x9B\x85");
  }

  if (result.lux > 20000 and result.lux <= 80000 ) {
    Blynk.virtualWrite(V40,  "\xE2\x98\x80");
  }
}

void printError(String text, OPT3001_ErrorCode error) {
  Serial.print(text);
  Serial.print(": [ERROR] Code #");
  Serial.println(error);
  Blynk.virtualWrite(V0, error);
}
1 Likes

สอบถามหน่อยครับ เอา esp8266 กับ opt3001 มาต่อกันเลยไม่ต้องผ่านอะไรก่อนใช่ไหมครับ

ต่อกันได้โดยตรงเลยครับ

ตอนนี้ผมเอาไปใช้แล้วนะครับ

1 Likes