Skip to content

Instantly share code, notes, and snippets.

@idriszmy
Last active July 27, 2021 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save idriszmy/4cad5f2780d7da4c2ff76ac8f6f83565 to your computer and use it in GitHub Desktop.
Save idriszmy/4cad5f2780d7da4c2ff76ac8f6f83565 to your computer and use it in GitHub Desktop.
Display Covid-19 Data Using Maker Pi Pico and CircuitPython
#
# Display Covid-19 Data Using Maker Pi Pico and CircuitPython
#
# Tutorial
# - https://tutorial.cytron.io/2021/07/27/display-covid-19-data-using-maker-pi-pico-and-circuitpython/
#
# Raspberry Pi Pico
# - [Maker Pi Pico] https://my.cytron.io/p-maker-pi-pico?tracking=idris
# - Node32 Lite https://my.cytron.io/p-node32-lite-wifi-and-bluetooth-development-kit?tracking=idris
# - Grove 16x2 LCD https://my.cytron.io/p-grove-16-x-2-lcd-white-on-blue?tracking=idris
#
# Additional Libraries
# - adafruit_bus_device
# - adafruit_esp32spi
# - adafruit_requests.mpy
# Download CircuitPython Libraries Bundle - https://circuitpython.org/libraries
#
# Update:
# 27 Jul 2021 - Tested with CircuitPython Pico 6.3.0
#
# SPDX-FileCopyrightText: Brent Rubell for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
import busio
from digitalio import DigitalInOut
from grove_lcd_i2c import Grove_LCD_I2C
import adafruit_requests as requests
from adafruit_esp32spi import adafruit_esp32spi
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
COVID_URL = "https://jhucoronavirus.azureedge.net/api/v1/regions/my.json"
# Get wifi details and more from a secrets.py file
try:
from secrets import secrets
except ImportError:
print("WiFi secrets are kept in secrets.py, please add them there!")
raise
LCD_SDA = board.GP4
LCD_SCL = board.GP5
LCD_ADDR = 0x3E
i2c = busio.I2C(scl=LCD_SCL, sda=LCD_SDA)
lcd = Grove_LCD_I2C(i2c, LCD_ADDR)
lcd.home()
lcd.print("Data Covid-19\ndi Malaysia")
print("Data Covid-19 di Malaysia")
# Raspberry Pi RP2040
esp32_cs = DigitalInOut(board.GP13)
esp32_ready = DigitalInOut(board.GP14)
esp32_reset = DigitalInOut(board.GP15)
spi = busio.SPI(board.GP10, board.GP11, board.GP12)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)
requests.set_socket(socket, esp)
if esp.status == adafruit_esp32spi.WL_IDLE_STATUS:
print("ESP32 found and in idle mode")
print("Firmware vers.", esp.firmware_version)
print("MAC addr:", [hex(i) for i in esp.MAC_address])
prev_total = 0
while True:
while not esp.is_connected:
print("Connecting to AP...")
try:
esp.connect_AP(secrets["ssid"], secrets["password"])
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)
print("My IP address is", esp.pretty_ip(esp.ip_address))
print()
except RuntimeError as e:
print("could not connect to AP, retrying: ", e)
continue
try:
#print("Fetching json from", COVID_URL)
response = requests.get(COVID_URL)
#print()
#print(response.json())
#print()
daily_case = int(response.json()["confirmed_cases"]["day"])
total = response.json()["confirmed_cases"]["all"]
response.close()
print("Kes baru: {}\tJumlah: {}".format(daily_case, total))
if total != prev_total:
prev_total = total
print("Display on LCD...")
lcd.clear()
lcd.print("Kes baru: {} \nJumlah: {} ".format(daily_case, total))
except:
print("{} retrying...".format(response))
lcd.clear()
lcd.print("{}\nRetrying...".format(response))
time.sleep(60)
from board import *
import digitalio
import busio
import time
from adafruit_bus_device.i2c_device import I2CDevice
# Command values
LCD_CLEAR_DISPLAY = 0x01
LCD_RETURN_HOME = 0x02
LCD_ENTRY_MODE_SET = 0x04
LCD_DISPLAY_CONTROL = 0x08
LCD_CURSOR_SHIFT = 0x10
LCD_FUNCTION_SET = 0x20
LCD_SET_CG_RAM_ADDR = 0x40
LCD_SET_DD_RAM_ADDR = 0x80
# Flags for display entry mode
LCD_ENTRY_RIGHT = 0x00
LCD_ENTRY_LEFT = 0x02
LCD_ENTRY_SHIFT_INCREMENT = 0x01
LCD_ENTRY_SHIFT_DECREMENT = 0x00
# Flags for display on/off control
LCD_DISPLAY_ON = 0x04
LCD_DISPLAY_OFF = 0x00
LCD_CURSOR_ON = 0x02
LCD_CURSOR_OFF = 0x00
LCD_BLINK_ON = 0x01
LCD_BLINK_OFF = 0x00
# Flags for display/cursor shift
LCD_DISPLAY_MOVE = 0x08
LCD_CURSOR_MOVE = 0x00
LCD_MOVE_RIGHT = 0x04
LCD_MOVE_LEFT = 0x00
# Flags for function set
LCD_8_BIT_MODE = 0x10
LCD_4_BIT_MODE = 0x00
LCD_2_LINE = 0x08
LCD_1_LINE = 0x00
LCD_5x10_DOTS = 0x04
LCD_5x8_DOTS = 0x00
class Grove_LCD_I2C():
def __init__(self, i2c_bus, lcd_address, cols=16, lines=2, dotsize=LCD_5x8_DOTS):
self.lcd = I2CDevice(i2c_bus, lcd_address)
self._displayfunction = 0
self._displaycontrol = 0
self._displaymode = 0
self._initialized = 0
self._numlines = lines
self._currline = 0
if lines > 1:
self._displayfunction |= LCD_2_LINE
if (not dotsize == 0) and lines == 1:
self._displayfunction |= LCD_5x10_DOTS
time.sleep(0.05)
self.command(LCD_FUNCTION_SET | self._displayfunction)
time.sleep(0.0045) #wait more than 4.1 ms
self.command(LCD_FUNCTION_SET | self._displayfunction)
time.sleep(0.00015)
self.command(LCD_FUNCTION_SET | self._displayfunction)
self.command(LCD_FUNCTION_SET | self._displayfunction)
self._displaycontrol = LCD_DISPLAY_ON | LCD_CURSOR_OFF | LCD_BLINK_OFF
self.display()
self.clear()
self._displaymode = LCD_ENTRY_LEFT | LCD_ENTRY_SHIFT_DECREMENT
self.command(LCD_ENTRY_MODE_SET | self._displaymode)
def clear(self):
self.command(LCD_CLEAR_DISPLAY)
time.sleep(0.002)
def home(self):
self.command(LCD_RETURN_HOME)
time.sleep(0.002)
def cursor_position(self, col, row):
position = col | 0x80 if row == 0 else col | 0xc0
data = bytearray(2)
data[0] = 0x80
data[1] = position
#print(data)
self.i2c_send_bytes(data)
def noDisplay(self):
self._displaycontrol &= (0xff - LCD_DISPLAY_ON)
self.command(LCD_DISPLAY_CONTROL | self._displaycontrol)
def display(self):
self._displaycontrol |= LCD_DISPLAY_ON
self.command(LCD_DISPLAY_CONTROL | self._displaycontrol)
def noCursor(self):
self._displaycontrol &= (0xff - LCD_CURSOR_ON)
self.command(LCD_DISPLAY_CONTROL | self._displaycontrol)
def cursor(self):
self._displaycontrol &= (0xff - LCD_CURSOR_ON)
self.command(LCD_DISPLAY_CONTROL | self._displaycontrol)
def noBlink(self):
self._displaycontrol |= LCD_CURSOR_ON
self.command(LCD_DISPLAY_CONTROL | self._displaycontrol)
def blink(self):
self._displaycontrol |= LCD_BLINK_ON
self.command(LCD_DISPLAY_CONTROL | self._displaycontrol)
def scrollDisplayLeft(self):
self.command(LCD_CURSOR_SHIFT | LCD_DISPLAY_MOVE | LCD_MOVE_LEFT)
def scrollDisplayRight(self):
self.command(LCD_CURSOR_SHIFT | LCD_DISPLAY_MOVE | LCD_MOVE_RIGHT)
def rightToLeft(self):
self._displaymode |= LCD_ENTRY_LEFT
self.command(LCD_ENTRY_MODE_SET | self._displaymode)
def autoscroll(self):
self._displaymode |= LCD_ENTRY_SHIFT_INCREMENT
self.command(LCD_ENTRY_MODE_SET | self._displaymode)
def noAutoscroll(self):
self._displaymode &= (0xff - LCD_ENTRY_SHIFT_INCREMENT)
self.command(LCD_ENTRY_MODE_SET | self._displaymode)
def createChar(self, location, charmap):
location &= 0x7
self.command(LCD_SET_CG_RAM_ADDR | (location << 3))
data = bytearray(9)
data[0] = 0x40
for i in range(8):
data[i+1] = charmap[i]
self.i2c_send_bytes(data)
def command(self, value):
data = bytearray(2)
data[0] = 0x80 #command register address
data[1] = value #command byte
self.i2c_send_bytes(data)
def write(self, value):
data = bytearray(2)
data[0] = 0x40
data[1] = value
self.i2c_send_bytes(data)
return 1
def i2c_send_bytes(self, data):
with self.lcd as wire:
wire.write(data)
def print(self, text):
string = str(text)
for char in string:
if char == '\n':
self.cursor_position(0, 1)
else:
self.write(ord(char))
# This file is where you keep secret settings, passwords, and tokens!
# If you put them in the code you risk committing that info or sharing it
secrets = {
'ssid' : 'Your WiFi SSID',
'password' : 'Your WiFi Password',
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment