Grove Temperature Sensor 1.2

This example shows how to use the Grove Temperature Sensor v1.2 on the Pynq-Z1 board. You will also see how to plot a graph using matplotlib. The Grove Temperature sensor produces an analog signal, and requires an ADC.

A Grove Temperature sensor and Pynq Grove Adapter, or Pynq Shield is required. The Grove Temperature Sensor, Pynq Grove Adapter, and Grove I2C ADC are used for this example.

You can read a single value of temperature or read multiple values at regular intervals for a desired duration.

At the end of this notebook, a Python only solution with single-sample read functionality is provided.

1. Load overlay


In [2]:
from pynq.pl import Overlay
Overlay("base.bit").download()

2. Read single temperature

This example shows on how to get a single temperature sample from the Grove TMP sensor.

The Grove ADC is assumed to be attached to the GR4 connector of the StickIt. The StickIt module is assumed to be plugged in the 1st PMOD labeled JB. The Grove TMP sensor is connected to the other connector of the Grove ADC.

Grove ADC provides a raw sample which is converted into resistance first and then converted into temperature.


In [3]:
import math
from pynq.iop import Grove_TMP
from pynq.iop import PMODB
from pynq.iop import PMOD_GROVE_G4

tmp = Grove_TMP(PMODB, PMOD_GROVE_G4)
temperature = tmp.read()
print(float("{0:.2f}".format(temperature)),'degree Celsius')


27.24 degree Celsius

3. Start logging once every 100ms for 10 seconds

Executing the next cell will start logging the temperature sensor values every 100ms, and will run for 10s. You can try touch/hold the temperature sensor to vary the measured temperature.

You can vary the logging interval and the duration by changing the values 100 and 10 in the cellbelow. The raw samples are stored in the internal memory, and converted into temperature values.


In [4]:
import time
%matplotlib inline
import matplotlib.pyplot as plt

tmp.set_log_interval_ms(100)
tmp.start_log()
# Change input during this time
time.sleep(10)
tmp_log = tmp.get_log()

plt.plot(range(len(tmp_log)), tmp_log, 'ro')
plt.title('Grove Temperature Plot')
min_tmp_log = min(tmp_log)
max_tmp_log = max(tmp_log)
plt.axis([0, len(tmp_log), min_tmp_log, max_tmp_log])
plt.show()


4. A Pure Python class to exercise the AXI IIC Controller inheriting from PMOD_IIC

This class is ported from http://www.seeedstudio.com/wiki/Grove_-_Temperature_Sensor.


In [10]:
from time import sleep
from math import log
from pynq.iop import PMOD_GROVE_G3
from pynq.iop import PMOD_GROVE_G4
from pynq.iop.pmod_iic import Pmod_IIC

class Python_Grove_TMP(Pmod_IIC):
    """This class controls the grove temperature sensor.
    
    This class inherits from the PMODIIC class.
    
    Attributes
    ----------
    iop : _IOP
        The _IOP object returned from the DevMode.
    scl_pin : int
        The SCL pin number.
    sda_pin : int
        The SDA pin number.
    iic_addr : int
        The IIC device address.
    
    """
    def __init__(self, pmod_id, gr_pins, model = 'v1.2'): 
        """Return a new instance of a grove OLED object. 
        
        Parameters
        ----------
        pmod_id : int
            The PMOD ID (1, 2) corresponding to (PMODA, PMODB).
        gr_pins: list
            The group pins on Grove Adapter. G3 or G4 is valid.
        model : string
            Temperature sensor model (can be found on the device).
            
        """
        if gr_pins in [PMOD_GROVE_G3, PMOD_GROVE_G4]:
            [scl_pin,sda_pin] = gr_pins
        else:
            raise ValueError("Valid group numbers are G3 and G4.")
            
        # Each revision has its own B value
        if model == 'v1.2':
            # v1.2 uses thermistor NCP18WF104F03RC
            self.bValue = 4250
        elif model == 'v1.1':
            # v1.1 uses thermistor NCP18WF104F03RC
            self.bValue = 4250
        else:
            # v1.0 uses thermistor TTC3A103*39H
            self.bValue = 3975
        
        super().__init__(pmod_id, scl_pin, sda_pin, 0x50)
        
        # Initialize the Grove ADC         
        self.send([0x2,0x20]);   
        
    def read(self):
        """Read temperature in Celsius from grove temperature sensor.
        
        Parameters
        ----------
        None
        
        Returns
        -------
        float
            Temperature reading in Celsius.
        
        """
        val = self._read_grove_adc()
        R = 4095.0/val - 1.0
        temp = 1.0/(log(R)/self.bValue + 1/298.15)-273.15
        return temp
        
    def _read_grove_adc(self):       
       self.send([0])
       bytes = self.receive(2)
       return 2*(((bytes[0] & 0x0f) << 8) | bytes[1])

In [11]:
from pynq import PL

# Flush IOP state
PL.reset_ip_dict()

py_tmp = Python_Grove_TMP(PMODB, PMOD_GROVE_G4)
temperature = py_tmp.read()
print(float("{0:.2f}".format(temperature)),'degree Celsius')


26.78 degree Celsius