[Arduino] 二氧化碳传感器 ELT IoT-300E 驱动代码

使用方法、原理都在JavaDoc (ArduinoDoc) 里面了,复制即用:

// IoT300E.h

/**
 * For ELT Sensor IoT-300E
 * @version 1.0
 * @since Apr.24th, 2020.
 * @author 星雪鸢尾
 */
#ifndef __IOT300E__
#define __IOT300E__
#include "Wire.h"
namespace IoT300E
{
  /**
   * 将IIC通信初始化到主机模式.
   */
  void InitIIC()
  {
    Wire.begin(); 
  }
  
  /**
   * Use IIC to get ppm of CO2.
   * <p>摘抄自Datasheet:<ul>
   *   <li>Internal pull up resister</li> 
   *   <li>Slave Address: 0x31, Slave Address Byte: Slave Address(0x31) 7 Bit + R/W 1 Bit</li>  
   *   <li>Transmission Sequence in Master</li><ol> 
   *     <li>I2C Start Condition</li> 
   *     <li>Write Command(Slave Address + R/W Bit(0) = 0x62) Transmission and Check Acknowledge</li> 
   *     <li>Write Command(ASCII ‘R’ : 0x52) Transmission and Check Acknowledge</li> 
   *     <li>I2C Stop Command</li> 
   *     <li>I2C Start Command</li> 
   *     <li>Read Command(Slave Address + R/W Bit(1) = 0x63) Transmission and Check Acknowledge</li>
   *     <li>Read 7 Byte Receiving Data from Module and Send Acknowledge (Delay at least 1ms for reading each byte)</li>
   *   </ol></ul>
   * 以上接收的7个Byte为: 1Byte Configuration({@code 0b00001000}), 2Byte CO2, 4Byte reserved({@code 0x00})
   * @return ppm of CO2; {@code -1} Configuration Byte 出错
   */
  int GetPPMFromIIC()
  {
    Wire.beginTransmission(0x31);
    Wire.write('R');
    Wire.endTransmission(0);
    unsigned char recv_iic[7] = {0};
    Wire.requestFrom(0x31, 7, 1);
    for (byte i = 0; i < 7; ++i) 
      if (Wire.available()) 
        recv_iic[i] = Wire.read(); 
      else 
        break;
    if (recv_iic[0] != 0b1000) 
      return -1;
    union {unsigned char in[2]; unsigned short out;} temp;
    temp.in[0] = recv_iic[2];
    temp.in[1] = recv_iic[1];
    return temp.out; 
  }
  
  /**
   * 将给定串口初始化到 {@code 38400} 波特率.
   * @param serialNo 串口号
   * @return {@code 0} 初始化完成; {@code -2} 串口号错误
   */
  int InitUART(byte serialNo)
  {
    switch (serialNo)
    {
      case 0: 
        Serial.begin(38400);
        return 0;
      case 1: 
        Serial1.begin(38400);
        return 0;
      case 2: 
        Serial2.begin(38400);
        return 0;
      default: 
        return -2;
    }    
  }
  
  /**
   * Use UART to get ppm of CO2.
   * WARNING: 请确认串口存在
   * <p>摘抄自Datasheet:<ul>
   *   </li>Data Transmit</li><ul>
   *     <li>Interval : 3 seconds</li>
   *     <li>Handshake protocol : None (Data is transmitted to outer device periodically)</li></ul> 
   * <li>Data Format</li><ul>
   *   <li>D5 D4 D3 D2 D1 BL ‘p’ ‘p’ ‘m’ CR LF</li><ul>
   *     <li>D1 ~ D5 = 5 byte CO2 density string</li> 
   *     <li>BL = Blank: 0x20</li> 
   *     <li>‘ppm’ = ‘ppm’ string</li> 
   *     <li>CR = Carriage return : 0x0D</li> 
   *     <li>LF = Line feed : 0x0A</li></ul></ul></ul>
   * @param serialNo 串口号
   * @return ppm of CO2; {@code -1} 读取出错,串口可能正在接收数据; {@code -2} 串口号错误
   */
  int GetPPMFromUART(byte serialNo)
  {
    if ((serialNo > 2)|(serialNo < 0)) return -2;
    unsigned long timeStart;
    timeStart = millis();
    char recv_uart[11] = {0};
    for (byte i = 0; i < 11; ++i) 
      switch (serialNo)
      {
        case 0: 
          recv_uart[i] = Serial.read(); 
          break;
        case 1: 
          recv_uart[i] = Serial1.read();
          break;
        case 2: 
          recv_uart[i] = Serial2.read();
          break;
        default: 
          break;
      }
    int ppm = 0;
    for (byte i = 0; i < 5; ++i) 
      if (recv_uart[i] != 0x20)
        ppm = ppm * 10 + (int)(recv_uart[i] - '0');
    if (atoi(recv_uart) != ppm) // 玄学校验,反正能用
      return -1;
    return ppm;
  }
}
#endif

很多东西第一次接触,还请各位指教.

原创文章 1 获赞 0 访问量 445

猜你喜欢

转载自blog.csdn.net/Snowy_Iris/article/details/105741887