air105#

This chapter describes how to use the i2c library for LuatOS

Introduction#

i2c Library provides communication between LuatOS and peripherals using the i2c protocol

I2C The bus is a simple, bidirectional two-wire synchronous serial bus developed by Philips. It requires only two wires to transfer information between devices connected to the bus.

Hardware preparation#

  • Air105 Development Board

  • AHT10

Air105 There is 1 channel i2c controller

AHT10 Is a temperature and humidity sensor, using I2C communication protocol, 7 i2c device address is0x38

Wiring Schematic

         PE7/GPIO71/I2C_SDA  ------     SDA
Air105   PE6/GPIO70/I2C_SCL  ------     SCL   AHT10
         +3.3V               ------     VIN
         GND                 ------     GND

Software part#

Interface documentation can be referred to:i2c library

Initialize hardware i2c#

The code is as follows

-- Air105 Hardware i2c ID
i2cId = 0
-- Initialization i2c
local setupRes = i2c.setup(i2cId, i2c.FAST)
log.info(PROJECT .. ".setup", setupRes)
if setupRes ~= i2c.FAST then
    log.error(PROJECT .. ".setup", "ERROR")
    return
end

The log is as follows

I/user.i2c.setup 1

setup The return value of the function is consistent with the i2c speed at the time of initialization, which means the initialization is successful.

Send command to AHT10 to trigger measurement and reading#

According to section 5.3 in the AHT10 data manual, the trigger measurement command of AHT10 is 0xac. when reading temperature and humidity data, the slave machine returns a total of 6 bytes, the first byte is the slave machine status, and the last 5 bytes are temperature and humidity information. the data transmission diagram of the master machine and the slave machine is as follows

Note that AHT10 needs time during acquisition. After the host sends out the measurement instruction 0xAC, the converted data will be read with a delay of more than 75 milliseconds.

The read data needs to be converted by the following formula

The code is as follows

-- AHT10 7 bit address
i2cSlaveAddr = 0x38
-- Send measurement command
i2c.send(i2cId, i2cSlaveAddr, string.char(0xac, 0x33, 0x00))
-- Wait for the measurement to complete
sys.wait(500)
-- Read temperature and humidity data
receivedData = i2c.recv(i2cId, i2cSlaveAddr, 6)
-- The separation temperature data includes the 6th bit, the 5th bit and the lower four bits of the 4th bit in the read data.
local tempBit = string.byte(receivedData, 6) + 0x100 * string.byte(receivedData, 5) + 0x10000 *
                    (string.byte(receivedData, 4) & 0x0F)
-- The separated humidity data contains the second bit, the third bit and the high four bits of the fourth bit in the read data.
local humidityBit = (string.byte(receivedData, 4) & 0xF0) + 0x100 * string.byte(receivedData, 3) + 0x10000 *
                        string.byte(receivedData, 2)
humidityBit = humidityBit >> 4
-- Converting Temperature and Humidity Results
local calcTemp = (tempBit / (2 ^ 20)) * 200 - 50
local calcHum = humidityBit / (2 ^ 20)
log.info(PROJECT .. ".Current Temperature", string.format("%.2f℃", calcTemp))
log.info(PROJECT .. ".Current humidity", string.format("%.2f%%", calcHum * 100))

The log is as follows

I/user.i2c.Current Temperature 27.78℃
I/user.i2c.Current humidity 63.51%

The complete code is as follows

PROJECT = "i2c"
VERSION = "1.0.0"
sys = require("sys")

-- AHT10 7 bit address
i2cSlaveAddr = 0x38
-- Air105 Hardware i2c ID
i2cId = 0

function getAHT10Data()
    -- Send measurement command
    i2c.send(i2cId, i2cSlaveAddr, string.char(0xac, 0x33, 0x00))
    -- Wait for the measurement to complete
    sys.wait(500)
    -- Read temperature and humidity data
    receivedData = i2c.recv(i2cId, i2cSlaveAddr, 6)
    -- Separation temperature data
    local tempBit = string.byte(receivedData, 6) + 0x100 * string.byte(receivedData, 5) + 0x10000 *
                        (string.byte(receivedData, 4) & 0x0F)
    -- Separate humidity data
    local humidityBit = (string.byte(receivedData, 4) & 0xF0) + 0x100 * string.byte(receivedData, 3) + 0x10000 *
                            string.byte(receivedData, 2)
    humidityBit = humidityBit >> 4
    -- Converting Temperature and Humidity Results
    local calcTemp = (tempBit / (2 ^ 20)) * 200 - 50
    local calcHum = humidityBit / (2 ^ 20)
    log.info(PROJECT .. ".Current Temperature", string.format("%.2f℃", calcTemp))
    log.info(PROJECT .. ".Current humidity", string.format("%.2f%%", calcHum * 100))

end
sys.taskInit(function()
    -- Initialization i2c
    local setupRes = i2c.setup(i2cId, i2c.FAST)
    log.info(PROJECT .. ".setup", setupRes)
    if setupRes ~= i2c.FAST then
        log.error(PROJECT .. ".setup", "ERROR")
        i2c.close(i2cId)
        return
    end
    while true do
        getAHT10Data()
        sys.wait(5000)
    end
end)

sys.run()