二氧化碳传感器CCS811简单的测试驱动_基于Arduino

  • 目的
  • 简单介绍
  • 由于MOX Sensor材料特性在使用过程中要注意的问题
  • IC的初始化过程
  • IC的读数据过程
  • 可配置参数
  • 完整程序代码
  • 数据输出图
  • 备注

目的

作为传感器的学习笔记,主要依据ic的datasheet手册,同时有借鉴一下pang9998作者的资料后完成。

简单介绍

CCS811是一个AMS艾迈斯公司的空气质量检测传感器,能测量CO2二氧化碳(400ppm to 8192ppm)和TVOC总挥发性有机物(0ppb to 1187ppb),接口是标准的I2C协议接口,电压支持1.8v-3.6v,电流在1.8v下睡眠情况下19uA。

由于MOX Sensor材料特性在使用过程中要注意的问题

  1. 需要由高速采样模式切换到低速采样模式的时候,不能直接切,需要先切到Mode0(idle),等10分钟以上才能切换,假如正在跑着Mode1(1Hz),先切换到Mode0 (空闲低功耗状态),等10分钟后,再切Mode2( 0.1Hz );
  2. 由低速采样模式切换到高速模式,无需等待,例如Mode2(0.1Hz)切换到Mode1(1Hz),无需等待时间;
  3. 新的sensor需要使用老化48小时,类似某些新的HIFI耳机“煲机”一样,“煲机”后能发挥更好的性能,“煲机”方式就是正常采样数据48小时;
  4. 如果是手动采集Baseline,为了贴合实际的Baseline的数据,需要适时更新手动采集的值,sensor使用的前500小时(20天左右),每1到2天就要比对跟新Baseline数据,500小时(20天左右)后每5到7天比对跟新Baseline数据,以保证Baseline数据贴近真实数据。 下图是手册上从开机到运行1小时多的Baseline数据情况,表明Baseline数据的稳定是需要一定时间的:

IC的初始化过程

有效
无效
BOOT恢复状态
APP应用状态
上电
软复位
检测FW固件状态
启动芯片
终止程序
检测芯片运行状态
设置工作模式
循环读数据

IC的读数据过程

有新数据
无数据
检测DATA_READY寄存器
读取CO2和TVOC的数据并组合输出

可配置参数

我设置的是ADDR接地,PC13控制wake脚,设置Mode3模式,1/60Hz采样,不使用硬件中断:

#define CCS811_I2C_ADDR 0x5B    //set pin addr pull down
//#define CCS811_I2C_ADDR 0x5A //set pin addr pull up
#define PIN_N_WAKE PC13
...
uint8_t work_mode = 3;  // default mode 3
uint8_t int_mode = 0;  // default off
uint8_t int_thresh_mode = 0;  // default off

完整程序代码

#include <Wire.h>#define CCS811_I2C_ADDR 0x5B    //set pin addr pull down
//#define CCS811_I2C_ADDR 0x5A //set pin addr pull up
#define PIN_N_WAKE PC13#define DEV_ON LOW
#define DEV_OFF HIGH/* Application Register */
#define CCS811_STATUS_REG 0x00
#define CCS811_MEAS_MODE_REG 0x01
#define CCS811_ALG_RESULT_DATA_REG 0x02
#define CCS811_APP_START_REG 0xF4
#define CCS811_SW_RESET_REG 0xFF/* Bootloader Register */
#define CCS811_HW_ID_REG 0x20
#define CCS811_HW_VER_REG 0x21
#define CCS811_FW_APP_VER_REG 0x23#define CCS811_HW_ID_VALUE 0x81
#define CCS811_APP_VAILED 0x10
#define DRIVE_MODE0 0x0 //idle
#define DRIVE_MODE1 0x1 //every second
#define DRIVE_MODE2 0x2 //every 10 secs
#define DRIVE_MODE3 0x3 //every 60 secs
#define DRIVE_MODE4 0x4 //every 250ms
#define DATA_READY_OK 1 //A new data sample is ready in ALG_RESULT_DATA, this bit is cleared when ALG_RESULT_DATA is read on the I2C interface
#define FW_MODE_APP 1<<7 //Firmware is in application mode. CCS811 is ready to take ADC measurements
#define INT_DATARDY_OK 1<<3
#define INT_THRESH_NO 1<<2uint8_t i2c_addr = CCS811_I2C_ADDR;uint8_t work_mode = 3;  // default mode 3
uint8_t int_mode = 0;  // default off
uint8_t int_thresh_mode = 0;  // default offvoid setup()
{uint8_t rbuf;uint8_t wbufs[4];uint8_t wbuf;//配置nwake脚对应的GPIO控制脚init_wake();// join I2C bus (I2Cdev library doesn't do this automatically)Wire.begin();Serial.begin(115200);delay(2000);//设置nwake脚准备操作I2Cset_wake(DEV_ON);delayMicroseconds(50);//reset chipwbufs[0] = 0x11;wbufs[1] = 0xE5;wbufs[2] = 0x72;wbufs[3] = 0x8A;i2c_multiple_write(CCS811_SW_RESET_REG, 4, wbufs);delay(50);//Get HW IDi2c_r_single(CCS811_HW_ID_REG, &rbuf);if (CCS811_HW_ID_VALUE != rbuf) {Serial.print("!!! Bad id:0x"); Serial.println(rbuf, HEX);}//检测固件FW的状态i2c_r_single(CCS811_STATUS_REG, &rbuf);rbuf &= CCS811_APP_VAILED;if (rbuf != CCS811_APP_VAILED) {Serial.print("No application firmware loaded.");Serial.println(" Pls. use \"ENS Dashboard for Windows\" fix firmware!!!");while (1); //用死循环间接终止程序//设置nwake脚结束操作I2Cset_wake(DEV_OFF);}//Start chipi2c_multiple_write(CCS811_APP_START_REG, 0, wbufs);delay(1);//检测固件FW的状态i2c_r_single(CCS811_STATUS_REG, &rbuf);rbuf &= FW_MODE_APP;if (rbuf != FW_MODE_APP) {Serial.print("Firmware mode bad .[0x"); Serial.print(rbuf, HEX);Serial.println("] Pls. use \"ENS Dashboard for Windows\" fix firmware!!!");while (1); //用死循环间接终止程序//设置nwake脚结束操作I2Cset_wake(DEV_OFF);}/*  ----------------Set Mode-------------------------------------- */wbuf = select_mode(work_mode);//set interruput statusif (int_mode == 1) {wbuf |= INT_DATARDY_OK << 3;}//set interrupt thresholds statusif (int_thresh_mode == 1) {wbuf |= INT_DATARDY_OK << 2;}i2c_w_single(CCS811_MEAS_MODE_REG, &wbuf);/*  ---------------- end -------------------------------------- *///设置nwake脚结束操作I2Cset_wake(DEV_OFF);
}void loop()
{uint8_t stau, err;uint8_t data[8] = {0};uint16_t eco2, tvoc;//设置nwake脚准备操作I2Cset_wake(DEV_ON);delayMicroseconds(50);//检测DATA_READY寄存器,判断是否有新的数据i2c_r_single(CCS811_STATUS_REG, &stau);stau &= INT_DATARDY_OK;if (stau == INT_DATARDY_OK) {i2c_multiple_read(CCS811_ALG_RESULT_DATA_REG, 8, data);eco2 = (uint16_t)((data[0] << 8) | data[1]);tvoc = (uint16_t)((data[2] << 8) | data[3]);err = data[5];Serial.print("CO2(ppm)= "); Serial.print(eco2);Serial.print(" TVOC(ppb)= "); Serial.println(tvoc);}//设置nwake脚结束操作I2Cset_wake(DEV_OFF);delay(60000);// sleep 60s
}//设置芯片运行模式
uint8_t select_mode(uint8_t mode)
{uint8_t wbuf = 0;switch (mode) {case 0://wbuf &= (~0x70);break;case 1:wbuf = DRIVE_MODE1 << 4;break;case 2:wbuf = DRIVE_MODE2 << 4;break;case 3:wbuf = DRIVE_MODE3 << 4;break;case 4:wbuf = DRIVE_MODE4 << 4;break;default:;}return wbuf;
}// ------------------ nWake GPIO set-----------------------------
void init_wake()
{pinMode(PIN_N_WAKE, OUTPUT);
}void set_wake(uint8_t mode)
{digitalWrite(PIN_N_WAKE, mode);
}
//-----------------------------------------------------------------//---------------------- i2c ---------------------------------------------------
int8_t i2c_w_single(uint8_t reg, uint8_t * sen_data)
{return i2c_multiple_write(reg, 1, sen_data);
}uint8_t i2c_multiple_write(uint8_t reg, uint8_t len, uint8_t * sen_data)
{Wire.beginTransmission(i2c_addr);Wire.write(reg);if (len > 0) {Wire.write(sen_data, len);}Wire.endTransmission();
}uint8_t i2c_r_single(uint8_t reg, uint8_t * gen_data)
{return i2c_multiple_read(reg, 1, gen_data);
}uint8_t i2c_multiple_read(uint8_t reg, uint8_t len, uint8_t * gen_data)
{int i;Wire.beginTransmission(i2c_addr);Wire.write(reg);Wire.endTransmission();delayMicroseconds(20);Wire.requestFrom(i2c_addr, len);for (i = 0; i < len; i++) {gen_data[i] = Wire.read();}
}
//---------------------------------------------------------------------------------

数据输出图

在室内测得,只在说明程序跑起来了。

备注

  1. 其实对于Arduino平台,核心是封装成库,但一来水平不够,二来重心不在这块,故没有封装,主要作用是为了理解datasheet;
  2. CCS811还有更新FW部分的内容,已更新到CCS811二氧化碳传感器基于Arduino的升级固件(刷机)教程文章中,点击就可以查看;
  3. Basline部分暂时不太熟悉,后续有经验后再补;

二氧化碳传感器CCS811简单的测试驱动_基于Arduino相关推荐

  1. Arduino开发(二)_基于Arduino UNO开发板的RGB灯光控制方法

    Arduino开发(二)_基于Arduino UNO开发板的RGB灯光控制方法 首先,我们来看一下Arduino UNO开发板的具体引脚排列,如下图所示, 再了解一下三色RGB LED模块,如下图所示 ...

  2. arduino灯光装置_基于Arduino的智能家居灯控系统设计

    &能应用 ------ T X 阵 W S 2 8 1 2 全 彩 灯 带 R X 工 G N D r 0 引言 智能家居的概念虽然已经有了几十年,但进入我国并取 得一定发展还是最近几年的事, ...

  3. arduino编乐谱_基于Arduino的电子音乐发声器设计

    作者 赵云娥1 吴振强2 1.青海建筑职业技术学院(青海 西宁 810012) 2.陕西师范大学计算机科学学院(陕西 西安 710119)本文引用地址:http://www.eepw.com.cn/a ...

  4. arduino编码器计数_基于Arduino开发环境的光电编码器检测仪设计方案 - 全文

    0 引言 Arduino是一款基于单片机系统的电子产品开发平台,它的软硬件系统都具有高度的模块化,而且软件系统是完全开源的.其硬件系统也是高度模块化的,在核心控制板的外围有开关量输入/输出模块.各种模 ...

  5. arduino智能浇花系统_基于Arduino单片机的智能浇花器

    Internal Combustion Engine & Parts • 119 • 基于Arduino单片机的智能淺花器 卞 云 松 ;张 国 祥 ;任 佳 豪 :陆晨雨 (江海职业技术学院 ...

  6. arduino智能浇花系统_基于Arduino的远程自动浇花系统设计

    基于 Arduino 的远程自动浇花系统设计 陈培东 ; 姚玉环 ; 李祖鹏 ; 周艺轩 [期刊名称] <电子世界> [年 ( 卷 ), 期] 2017(000)006 [摘要] 设计了一 ...

  7. arduino nano 蓝牙_基于Arduino的摩尔斯电码练习及无线收发报训练器

    摘要:本文介绍一款基于Arduino NANO开发的,带2.4G无线收发报功能的摩尔斯电码训练器的系统设计思路.发射端通过NANO板的外部中断引脚采集电键输入的脉冲PPM序列同时驱动喇叭播放电键音,然 ...

  8. 虚拟机安装dpdk 惊醒测试吗_基于KVM的SRIOV直通配置及性能测试

    SRIOV介绍.VF直通配置,以及包转发率性能测试 小慢哥的原创文章,欢迎转载 目录 ▪ 1. SRIOV介绍 ▪ 2. 环境说明 ▪ 3. 开启SRIOV ▪ 4. 生成VF ▪ 5. VF直通 ▪ ...

  9. 51单片机基本刷屏测试实验_基于单片机的发动机振动速度、位移和加速度测量方法...

    Single-chip microcomputer-based measuring of engine vibration speed.displacement and acceleration Ab ...

最新文章

  1. 使用 LSTM 进行多变量时间序列预测的保姆级教程
  2. CCNP视频教程下载全集
  3. DSOframer注册使用说明
  4. mysql 5.6 5.7 并存_centos同时运行mysql5.6和mysql5.7
  5. 程序员如何快速成长为IT精英
  6. PID:我应该何时计算积分项?
  7. 洛谷 数论入门相关题目--2022.01.22
  8. DJango 多条件查询结果分页
  9. mysql was1067_MySQL启动提示1067错误的解决
  10. ERP计划参数如何在线更新
  11. django mysql socket_django mysql 读写分离
  12. Android拍照返回图片
  13. C#下对象与JSON串互相转换
  14. 罗技鼠标显示无法连接服务器,罗技无线鼠标接收器无法配对的详细解决办法
  15. mock.js文档详解5及下载(Random中的Name,Web,Address种类函数)
  16. 大厂秋招~华为荣耀字节腾讯美团滴滴
  17. jdk8新特性之出现This inspection finds all usages of methods that have @since tag in their documentation.
  18. Velocity模板引擎
  19. 使用DGL实现基于闲鱼图进行边分类算法
  20. 基于帝国竞争算法的函数寻优算法

热门文章

  1. 死锁和活锁的发生及避免
  2. 分享爬取智联的一段源码
  3. 【仪器仪表专题】案例:万用表VC86E连接不上电脑?拆机看是器件虚焊惹的祸
  4. 长安大学转计算机专业,关于做好2019级本科生校内转专业工作的通知
  5. 数据库备份方案及容灾备份(Mysql,SqlServer,Oracle)
  6. 「民工哥技术之路」截止2019年12月31日所有文章集合
  7. 8086CPU引脚功能
  8. fatfs f_readdir 在使用长文件名时的问题
  9. postgresql易学堂_程序员最重要的就是学会“不写代码”
  10. CSS-伪类获取除第一个之外的其他子元素