0

I'm attempting to use a Tessel 2 to read data from a CO2 sensor but not having much success.

From the sensor's data sheet:

To read the current CO2 concentration from the sensor we need to read memory locations 0x08 (hi byte) and 0x09 (low byte).

To do this we need to send a sequence of two I2C frames: first we send an I2C write frame containing the sensor address, command number and how many bytes to read, RAM address to read from, and a checksum. Then we send an I2C read frame to read the status, data and checksum.

In our case we want to read 2 bytes starting from address 0x08. This will give us data from address 0x08 and 0x09, which contains current CO2 reading. The sensor address is 0x68 (default factory setting, configurable in EEPROM).

So, the first frame should look like:

Start | 0xD0 | 0x22 | 0x00 | 0x08 | 0x2A | Stop

--a. 0xD0 is Sensor address and read/write bit. 0x68 shifted one bit to left and R/W bit is 0 (Write).

--b. 0x22 is command number 2(ReadRAM), and 2 bytes to read

--c. Checksum 0x2A is calculated as sum of byte 2, 3 and 4.

The next frame will read the actual data:

Start | 0xD1 | <4 bytes read from sensor> | Stop

--d. The 1:st byte from the sensor will contain operation status, where bit 0 tells us if the read command was successfully executed.

--e. The 2:nd and 3:rd byte will contain CO2 value hi byte and CO2 value low byte.

--f. The 4:th byte contains checksum

So, my code looks like this:

'use strict';

// Require
var async   = require('async');
var tessel  = require('tessel');
var port    = tessel.port.B;

// Vars
var i2c;
   
// Process
async.waterfall([
  function(callback) {
    i2c = new port.I2C(0xD0);
    callback(null,new Buffer([0xD0, 0x22, 0x00, 0x08, 0x2A]));
  },
  function(data, callback) {
    i2c.send(data, function (error) {
        console.log("Done sending the data");
        callback(null,null);
    })
  },
  function(data, callback) {
    i2c = new port.I2C(0xD1);
    callback(null,null);
  }
], function (err, result) {
    i2c.read(4, function (error, buffer) {
        console.log(`I2C Slave (0x${address.toString(16)} response: `, buffer);
    });    
});

The code executes all the way until the i2c.read code block and never receives a buffer back from the sensor.

I decided not to use the transfer method because the address changes.

What am I doing wrong?

4

1 回答 1

0

我通过查看 Arduino 草图来作弊,这给了我一些最终成功的想法。

  1. i2C 应使用正确的地址 (0x68) 进行实例化,而不是像数据表中提供的文档中那样移动
  2. i2c.send 的缓冲区不应包含地址,因为 i2c 已经在实例化的帧中添加了地址。所以缓冲区应该是这样的:

    回调(空,新缓冲区([0x22,0x00,0x08,0x2A]));

  3. 在发送 1000 毫秒的读数之间添加超时

于 2017-08-22T17:15:31.073 回答