VEML6070 UV Light Sensor Module#


Vishay VEML6070#

ไอซี VEML6070 (Datasheet) ผลิตโดยบริษัท Vishay Semiconductor เป็นเซนเซอร์วัดความเข้มแสงอัลตราไวโอเลต หรือ รังสียูวี (Ultraviolet: UV) และให้เอาต์พุตแบบดิจิทัล (Digital UV Light Sensor) ภายในไอซีได้รวมโฟโต้ไดโอด (Photodiode) ซึ่งทำหน้าที่เป็นตัวรับแสง วงจรขยายสัญญาณไฟฟ้า และวงจรแปลงให้เป็นข้อมูลดิจิทัล เป็นต้น

แสงยูวีจากดวงอาทิตย์ มีความยาวคลื่นประมาณ 100 nm ถึง 400 nm และมีการจำแนกเป็นประเภทย่อย ตามย่านความยาวคลื่นได้ดังนี้

  • UV-A: 320 nm ~ 400 nm
  • UV-B: 280 nm ~ 320 nm
  • UV-C: 100 nm ~ 280 nm

คุณสมบัติของ VEML6070

  • ช่วงแรงดันไฟเลี้ยง (VCC): 2.7V ~ 5.5V
  • ปริมาณกระแสไฟฟ้าที่ใช้ (Current Consumption): ประมาณ 100 μA ขณะทำการวัด และ 1μA เมื่ออยู่ในโหมด Shutdown
  • มีความไวแสงสูงสุดสำหรับความยาวคลื่น 355 nm หรือในช่วงความยาวคลื่น 335nm ~ 375nm (UV-A)
  • มีขาสำหรับใช้กับตัวต้านทานภายนอก (R_SET) เพื่อกำหนดระดับความไวแสงของเซนเซอร์
  • เชื่อมต่อด้วยบัส I2C (แอดเดรสแบบ 7 บิต เท่ากับ 0x38 และ 0x39) ใช้ความเร็วได้ถึง 400kHz
  • 0x38 ใช้สำหรับเขียนค่าลงในรีจิสเตอร์คำสั่ง และอ่านค่าไบต์ LSB
  • 0x39 ใช้สำหรับอ่านค่าไบต์ MSB
  • มีขา ACK สำหรับสัญญาณ Interrupt / Alert และเป็นเอาต์พุต สามารถโปรแกรมการทำงานให้แจ้งเตือน ในกรณีที่มีการวัดความเข้มแสงได้สูงเกินกว่าค่าที่กำหนดไว้
  • ให้ค่าเป็นข้อมูลดิจิทัลขนาด 16 บิต (0..65535)

 

รูป: ไอซี VEML6070 (ซ้าย) และแผนผังแสดงองค์ประกอบภายในของไอซี (Block Diagram)

รูป: ช่วงความยาวคลื่นแสง UV ที่เหมาะสมสำหรับการวัดความเข้มแสงด้วย VEML6070

รูป: ตัวอย่างการเชื่อมต่อกับไมโครคอนโทรลเลอร์ด้วยบัส I2C

รูป: การกำหนดค่าบิตในรีจิสเตอร์คำสั่ง (Command Register) ของ VEML6070

คำสั่ง (Command) ประกอบด้วยบิตที่สำคัญดังนี้

  • บิตที่ 0: SD (Shutdown Bit) ถ้า SD=0 (normal mode) คือ เปิดใช้งานปรกติ แต่ถ้า SD=1 (shutdown mode) จะอ่านค่าจากเซนเซอร์ได้ค่าเดิม (ไม่มีการอัปเดตค่าใหม่)
  • บิตที่ 3-2: IT[1:0] สำหรับกำหนดค่า Integration Time มี 2 บิต
  • บิตที่ 4: ACK_THD (Acknowledge threshold value setting)
  • บิตที่ 5: ACK (Acknowledge activity setting)

ค่าของเซนเซอร์ที่วัดได้ จะขึ้นอยู่ความเข้มแสง (Light Intensity) และระยะเวลาในการเปิดรับแสง (Integration Time: IT) สำหรับตัวรับแสงที่เป็นโฟโต้ไดโอด

กระแสที่เกิดขึ้นที่ตัวโฟโต้ไดโอดจะเป็นสัญญาณอินพุตให้วงจรขยายสัญญาณ OpAmp ที่มีการต่อวงจรในรูปแบบที่เรียกว่า Transimpedance Amplifier วงจรประเภทนี้ทำหน้าที่แปลงปริมาณกระแสที่เกิดขึ้นในช่วงเวลาดังกล่าว ให้เป็นแรงดันไฟฟ้า (สัญญาณแบบแอนะล็อก) จากนั้นจึงนำไปผ่านวงจร ADC (Analog-to-Digital Converter) เพื่อแปลงข้อมูลแบบดิจิทัลขนาด 16 บิต

ตาราง: ความสัมพันธ์ระหว่างค่า Integration Time (IT) และ R_SET

ถ้าเลือกใช้ตัวต้านทาน R_SET=270kΩ ก็จะคำนวณค่า Refresh Time (มิลลิวินาที) ซึ่งเป็นระยะเวลาในการรอให้เซนเซอร์ทำงานก่อนจะอ่านค่าในครั้งถัดไปได้ดังนี้ (ใช้ความสัมพันธ์แบบเชิงเส้น)

ในกรณีที่เลือกใช้ค่า R_SET = 270 kΩ จะมีค่า 1T=112.5ms

การแปลงค่าที่อ่านได้จาก VEML6070 ให้เป็นค่า UV Index (UVI) ซึ่งมีค่าอยู่ในช่วง 0 ถึง 12 (ยิ่งมีค่าสูง จะเป็นอันตรายต่อผิวหนังมาก) ขึ้นอยู่กับ R_SET ที่เลือกใช้ และการตั้งค่า Integration Time (IT) ตามค่าตัวอย่างในตารางต่อไปนี้

รูป: ความสัมพันธ์ระหว่าง UV Index กับค่าที่ได้จาก VEML6070 และ IT

 


โมดูลเซนเซอร์แสงยูวี VEML6070#

ในปัจจุบันมีโมดูลเซนเซอร์แสงยูวีที่ใช้ไอซี VEML6070 จากหลายบริษัท และสามารถนำมาต่อวงจรทดลองได้อย่างสะดวก ตัวอย่างโมดูลได้แก่

  • Adafruit VEML6070 UV Index Sensor Breakout
  • Seeed Studio Grove VEML6070
  • CJMCU-6070
  • GY-VEML6070

รูป: โมดูล Adafruit VEML6070 (มีตัวต้านทาน R_SET = 270k)

รูป: โมดูล Grove VEML6070 UV Sensor (มีตัวต้านทาน R_SET = 270k)

รูป: โมดูล CJMCU-6070 (มีตัวต้านทาน R_SET = 270k)

รูป: แผนผังวงจรไฟฟ้าของโมดูล CJMCU-6070

รูป: โมดูล GY-VEML6070 (มีตัวต้านทาน R_SET = 270k)

รูป: แผนผังวงจรไฟฟ้าของโมดูล GY-VEML6070

 


การเขียนโค้ด Arduino สำหรับ VEML6070#

หากต้องการเขียนด้วย Arduino ก็มีไลบรารีสำหรับ VEML6070 ให้เลือกใช้งานได้ เช่น

แต่ลองมาดูตัวอย่างการเขียนโค้ด Arduino โดยไม่จำเป็นต้องใช้ไลบรารี และสามารถนำไปทดลองได้กับบอร์ดไมโครคอนโทรลเลอร์ เช่น ESP32 (เลือกใช้ขา GPIO 16 / 17 สำหรับ I2C SDA / SCL) และ Arduino Uno/Nano (ใช้ขา Arduino A4 / A5 สำหรับ I2C SDA / SCL ตามลำดับ)

ในโค้ดตัวอย่างนี้ ได้เลือกใช้ค่า Integration (IT) เท่ากับ 1T และโมดูล VEML6070 ที่นำมาใช้งานมีค่า R_SET=270k

#include <Wire.h>

#ifdef ESP32
#define I2C_SDA_PIN  (16)
#define I2C_SCL_PIN  (17)
#endif

#define I2C_ADDR    (0x38)

#define CMD_REG_DEFAULT_VALUE  (0x02)
#define IT_1T_HALF  (0b00)
#define IT_1T       (0b01)
#define IT_2T       (0b10)
#define IT_4T       (0b11)

void setup() {
  Serial.begin( 115200 );
#ifdef ESP32
  Wire.begin( I2C_SDA_PIN, I2C_SCL_PIN );
#else
  Wire.begin( ); // use A4=SDA and A5=SCL pins for Arduino Uno/Nano
#endif
  Wire.setClock( 400000 ); // 400kHz

  for( int i=0; i < 3; i++ ) { 
    i2c_scan();
    delay(2000);
  } 
  // Initialize the VEML6070 sensor.
  init_sensor();
}

void i2c_scan() {
  int n_devices = 0;
  Serial.println( "Scanning I2C bus..." );
  Serial.print( "   " );
  for ( uint8_t col=0; col < 16; col++ ) {
    Serial.printf( "%3x", col );
  }
  Serial.println( "" );

  uint8_t addr=0;
  for( uint8_t row=0; row < 8; row++ ) {
    Serial.printf( "%02x:", row << 4 );
    for ( uint8_t col=0; col < 16; col++ ) {
      if ( row == 0 && addr<=1 ) {
        Serial.print("   ");
      } else {
        Wire.beginTransmission( addr );
        if ( Wire.endTransmission()>0 ) {
          Serial.printf( " --" );
        } else {
          Serial.printf( " %2x", addr );
          n_devices++;
        }
      }
      addr++;
    }
    Serial.println( "" );
  }
  Serial.println( "---------------------\n\n" );
  Serial.flush();
}

void init_sensor() {
  Wire.beginTransmission( I2C_ADDR );
  // Use integration time: 1T.
  Wire.write( (IT_1T<<2) | CMD_REG_DEFAULT_VALUE ); 
  Wire.endTransmission();
  delay( 500 );
}

uint16_t read_uv_sensor() {
   uint16_t value = 0x00;
   Wire.requestFrom( I2C_ADDR+1, 1 ); // read MSB
   delayMicroseconds(10);
   if( Wire.available() == 1 ) {
      value = Wire.read();
   }
   value <<= 8;
   Wire.requestFrom( I2C_ADDR, 1 ); // read LSB
   delayMicroseconds(10);
   if( Wire.available() ) {
      value |= Wire.read();
   }
   return value;
}

const char *UVI_LEVELS[] = {
   "Low", "Moderate", "High", "Very High", "Extreme"
};

void loop() {
  int uv_level ;
  uint32_t value = read_uv_sensor();
  // note: UVI conversion (R_SET = 270k, IT = 1T)
  if ( value <= 560 ) {
      uv_level = 0;
  } else if ( value <= 1120 ) {
      uv_level = 1;     
  } else if ( value <= 1494 ) {
       uv_level = 2;
  } else if ( value <= 2054 ) {
      uv_level = 3;
  } else {
      uv_level = 4;
  }
  String str = "UV: ";
  str += value;
  str += " ";
  str += UVI_LEVELS[ uv_level ];
  Serial.println( str.c_str() );
  delay(1000);
}

รูป: ตัวอย่างข้อความเอาต์พุตใน Arduino Serial Monitor ที่ได้จากการทำงานของโค้ดตัวอย่าง

รูป: การทดลองต่อวงจรโดยใช้บอร์ด ESP32 ร่วมกับโมดูล GY-VEML6070

รูป: การใช้แผง UV LEDs (มีความยาวคลื่นประมาณ 395-400nm ดังนั้นจึงมองเห็นด้วยตาเปล่าเป็นสีม่วง) และวัดระดับความเข้มแสงด้วยโมดูล GY-VEML6070

 


กล่าวสรุป#

บทความนี้ได้นำเสนอการใช้งานโมดูลที่มีไอซี VEML6070 ซึ่งเป็นเซนเซอร์แบบดิจิทัลสำหรับการวัดความเข้มแสงยูวี (Ultraviolet: UV) โดยนำมาทดลองใช้งานร่วมกับบอร์ดไมโครคอนโทรลเลอร์ ESP32 และ Arduino Nano และเขียนโปรแกรมด้วย Arduino IDE

 


This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Created: 2022-10-22 | Last Updated: 2022-10-23