Temperature Sensor Board with ZIO

In this article, we will see how we can use ZIO and Python to prototype an embedded system and how ZIO and Python simplifies an engineer’s work. We will use ZIO’s Python API to read temperature from Zilogic’s Temperature Sensor Board.

The Temperature Sensor Board is based on NXP’s SA56004 temperature sensor chip, which can be interfaced through I2C bus. SA56004 is an SMBus compatible, 11-bit remote/local digital temperature sensor with over temperature alarms. The remote channel of the board monitors a diode junction, such as a diode connected transistor, with the accuracy of +/- 1oC.

Reading the Temperature

The Python script running on the PC will read the temperature from Temperature Sensor Board through the ZIO Motherboard. The interface between ZIO and the Temperature Sensor Board is based on I2C communication, since the temperature sensor is an I2C slave device. The following diagram shows the hardware setup.

We have to connect the temperature sensor board to the I2C header in ZIO Mother board. Now connect the ZIO Motherboard to PC via USB cable. Then we have to write a Python script to read the temperature.

/static/images/zio-tempsensor.png

Algorithm

  • Initialize the temperature sensor by reading the manufacturer ID. If fails return -1 else return 0

  • Configure the temperature sensor register by setting values to configuration register in slave device.

  • Read the High byte register value from the temperature sensor.

  • Display the high byte register value in stdout.

Python Script to Read Temperature

Below is the Python script that uses the ZIO Python API, to read the temperature.

  • /static/code/temp_sense.py[Download the source file]

"""Reading Temperature using ZIO and Temperature Sensor Board

temp_sense.py - Script to read temperature and display on stdout
Refer SA56004x data sheet for register descriptions
"""
import zio
import sys
from time import sleep

#Slave address
TEMP_SENSOR = 0x90 >> 1
#Read Manufacturer ID
REG_RMID = 0xFE
#Configuration register
REG_CON = 0x09
#Alert Mode register
REG_AM = 0xBF
#Status Register
REG_SR = 0x02
#Local Temperature high byte register
REG_LTHB = 0x00
#Temote Temperature high byte register
REG_RTHB = 0x01
#Status of sensor
DIODE_OPEN = 2
#Variable to read LOCAL Temperature
TEMP_LOCAL = 0
#Variable to read Remote Temperature
TEMP_REMOTE = 1


def i2c_set_reg8(i2c, dev, reg, value):
    """Write an 8-bit value to a slave device register.

    Args:
        i2c: I2C slave device object
        dev: Slave device register address
        reg: Register address
        value: Value to be written to the slave register
    """
    i2c.write(dev, [reg, value])
    return


def i2c_get_reg8(i2c, dev, reg):
    """Read an 8-bit value from a slave device register.

    Args:
        i2c: I2C slave device object
        dev: I2C slave address
        reg: Register address

    Returns:
        int, a byte Read from the device
    """
    rx = i2c.write_read(dev, [reg], 1)
    return rx[0]


def temperature_init(i2c):
    """Initialize the Temperature Sensor.

    Read the manufacturer ID by which
    we can know the slave device is working.

    Args:
        i2c: I2C Slave device object

    Returns:
        int, Returns integer 0 on success and -1 on failure
    """
    global TEMP_SENSOR, REG_RMID
    i2c.config(100)
    ide = i2c_get_reg8(i2c, TEMP_SENSOR, REG_RMID)
    if ide != 0xA1:
        return -1

    return 0


def temperature_read(i2c, sensor):
    """Read the temperature from the Temperature Sensor

    Args:
        i2c: I2C slave device object
        sensor: Local sensor or remote sensor values

    Returns:
        If the sensor is LOCAL then return local temperature
        highbyte. Else it will return remote sensor high byte
        If there is no remote sensor connected it will return None.
    """
    global TEMP_LOCAL

    if sensor == TEMP_LOCAL:
        return i2c_get_reg8(i2c, TEMP_SENSOR, REG_LTHB)
    else:
        status = i2c_get_reg8(i2c, TEMP_SENSOR, REG_SR)
        if status & DIODE_OPEN:
            return None

        return i2c_get_reg8(i2c, TEMP_SENSOR, REG_LTHB)

    return None


def main():
    global TEMP_LOCAL
    global temp
    agent = zio.Agent("/dev/ttyACM0")
    i2c = zio.I2C(agent)
    ret = temperature_init(i2c)
    if ret != 0:
        print "Temperature SensorInitialize error"
        sys.exit(1)

    while True:
        tem = temperature_read(i2c, TEMP_LOCAL)
        if  tem is None:
            print "Read Error"
            sys.exit(1)

        sys.stdout.write("Temperature is %02d\r" % tem)
        sys.stdout.flush()
        sleep(1)

if __name__ == '__main__':
    try:
        main()
    except KeyboardInterrupt:
        print "KeboardInterrupt"
        sys.exit(1)
    except zio.I2CNoAckError, error:
        print error
        sys.exit(1)

Credits

  • Thanks to Visual Pharm for the Thermometer Icon.

  • Thanks to Mr. Vijaykumar for reviewing the coding part and guided to write a clean code.