Tuesday, March 2, 2021

RPi Pico/MicroPython: read internal temperature sensor and display on ILI9341 SPI Display graphically.

On Raspberry Pi Pico, machine.ADC(4) is connected to the internal temperature sensor built into RP2040.

A simple MicroPython example can be found in GitHub: raspberrypi/pico-micropython-examples

pico-micropython-examples/adc/temperature.py
import machine
import utime

sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)

while True:
    reading = sensor_temp.read_u16() * conversion_factor
    
    # The temperature sensor measures the Vbe voltage of a biased bipolar diode, connected to the fifth ADC channel
    # Typically, Vbe = 0.706V at 27 degrees C, with a slope of -1.721mV (0.001721) per degree. 
    temperature = 27 - (reading - 0.706)/0.001721
    print(temperature)
    utime.sleep(2)

It's my exercise modified to read internal temperature sensorand display on 320x240 ILI9341 SPI Display graphically.

mpyPico_ili9341_Temp_20210303a.py

"""
Exercise on Raspberry Pi Pico/MicroPython
with 320x240 ILI9341 SPI Display

Pico plot internal temperature graphically
"""
from ili934xnew import ILI9341, color565
from machine import Pin, SPI, Timer
from micropython import const
import os
import glcdfont
import tt24
import tt32
#import freesans20fixed
import utime

sensor_temp = machine.ADC(4) #internal temperature sensor
conversion_factor = 3.3/(65535)

SCR_WIDTH = const(320)
SCR_HEIGHT = const(240)
SCR_ROT = const(0)
#SCR_ROT = const(2)

dispW = 240
dispH = 320
marginX = const(20)
marginY = const(10)
TempFrame_W = dispW-(2*marginX)
TempFrame_H = 100
TempFrame_X0 = marginX
TempFrame_Y0 = marginY
TempFrame_Y1 = marginY+TempFrame_H

TempPanel_X0 = TempFrame_X0
TempPanel_Y0 = TempFrame_Y1 + 10
TempPanel_W = TempFrame_W
TempPanel_H = 32

tempSize = TempFrame_W      #200
tempValueLim = TempFrame_H  #100

led = Pin(25, Pin.OUT)

print("MicroPython:")
print(os.uname()[3])
print(os.uname()[4])
print()

TFT_CLK_PIN = const(6)
TFT_MOSI_PIN = const(7)
TFT_MISO_PIN = const(4)

TFT_CS_PIN = const(13)
TFT_RST_PIN = const(14)
TFT_DC_PIN = const(15)

spi = SPI(
    0,
    baudrate=40000000,
    miso=Pin(TFT_MISO_PIN),
    mosi=Pin(TFT_MOSI_PIN),
    sck=Pin(TFT_CLK_PIN))
print(spi)

display = ILI9341(
    spi,
    cs=Pin(TFT_CS_PIN),
    dc=Pin(TFT_DC_PIN),
    rst=Pin(TFT_RST_PIN),
    w=SCR_WIDTH,
    h=SCR_HEIGHT,
    r=SCR_ROT)

def drawHLine(x, y, w, color):
    for i in range(w):
        display.pixel(x+i,y,color)
        
def drawVLine(x, y, h, color):
    for i in range(h):
        display.pixel(x,y+i,color)
        
def drawVLineUp(x, y, h, color):
    for i in range(h):
        display.pixel(x,y-i,color)
      
frameBGcolor = color565(150, 150, 150)
TempPanel = color565(0, 0, 0)

def drawFrame(x, y, w, h):
    display.fill_rectangle(x, y, w, h, frameBGcolor)

    l1x = x-1
    l2x = x+w
    l1y = y-1
    l2y = y+h+1
    lcolor = color565(250, 250, 250)
    
    for i in range(w+2):
        display.pixel(l1x+i,l1y,lcolor)
        display.pixel(l1x+i,l2y,lcolor)
 
    for i in range(h+2):
        display.pixel(l1x,l1y+i,lcolor)
        display.pixel(l2x,l1y+i,lcolor)
      
display.erase()

display.set_font(tt24)
display.set_pos(0, 0)
display.set_color(color565(250, 250, 0), color565(0, 0, 0))
display.print("Pico plot internal temperature")
display.print("")
display.set_color(color565(250, 250, 250), color565(0, 0, 0))
display.print("MicroPython:")
display.print(os.uname()[3])
display.print("")
display.print(os.uname()[4])
utime.sleep(3)

timReached = False
tim = Timer()
def TimerTick(timer):
    global led
    led.toggle()
    global timReached
    timReached = True
    
tim.init(freq=2, mode=Timer.PERIODIC, callback=TimerTick)
    
display.set_font(tt32)
#display.set_font(freesans20fixed)

display.set_color(color565(250, 250, 0), color565(0, 0,0))
display.erase()

drawFrame(TempFrame_X0, TempFrame_Y0, TempFrame_W, TempFrame_H)

utime.sleep(1)

#sampleTemp=[0]*tempSize
sampleTempIndex=0
tempString = "0"
while True:
    if timReached:
        timReached = False
        
        reading = sensor_temp.read_u16()*conversion_factor
        tempValue = 27-(reading-0.706)/0.001721
        
        print(tempValue)
        
        #clear previous value print
        #display.set_color(color565(0, 0, 0), color565(0, 0, 0))
        #display.set_pos(TempPanel_X0, TempPanel_Y0)
        #display.print(tempString)
        
        tempString=str(tempValue)
        if tempValue >= tempValueLim:
            display.set_color(color565(250, 0, 0), color565(0, 0, 0))
        else:
            display.set_color(color565(0, 0, 250), color565(0, 0, 0))
        display.set_pos(TempPanel_X0, TempPanel_Y0)
        display.print(tempString)
        
        if sampleTempIndex == 0:
            #clear frame
            display.fill_rectangle(TempFrame_X0,
                                   TempFrame_Y0,
                                   TempFrame_W,
                                   TempFrame_H,
                                   frameBGcolor)
        
        if tempValue >= tempValueLim:
            drawVLineUp(TempFrame_X0+sampleTempIndex,
                        TempFrame_Y1,
                        tempValueLim,
                        color565(250, 0, 0))
        else:
            drawVLineUp(TempFrame_X0+sampleTempIndex,
                        TempFrame_Y1,
                        tempValue,
                        color565(0, 0, 250))
        
        sampleTempIndex = sampleTempIndex+1
        if(sampleTempIndex>=tempSize):
            sampleTempIndex = 0
        
print("- bye-")

For the setup on Raspberry Pi Pico/MicroPython + 320x240 ILI9341 SPI Display, read another post HERE.



To improve:

If you run the example, it can be noticed that the code display.print() will not clear the previous printed pixels if newer printing area is shorter than previous.


To improve it, I have two approach:

approach I:
Re-print previous value with color Black-in-Black.


approach II:
Using monospaced (fixed) fonts.


Next:



No comments: