[Digi-Key Follow me Issue 2] + Submission Post: Tasks 1~4 and Internet-connected perpetual calendar and weather display
[Copy link]
I am very happy to participate in the 2nd event of Digi-Key Electronics' Follow me, because I have only used 51 MCU and STM32 before, and I used C language for programming at that time, and I have hardly ever touched Python. In addition, I have been mainly busy with graduate school matters in the past few months. I was confused when I first started with object-oriented CircuitPython a while ago. Fortunately, there were a few days of National Day holiday, so I quickly supplemented my Python knowledge roughly (fortunately, these tasks are not complicated), and then I looked at the project explanations and examples of the big guys in the forum, and then I slowly got started, so I am very grateful to the big guys for their detailed explanations in the forum!
Part 1: Demonstration Video
The content mainly includes hardware introduction and the completion demonstration of tasks 1 to 4 (for task 4, I chose sub-task 1: calendar and clock)
任务展示视频
Part 2: Project Summary Report
Below I will introduce each task separately:
Task 1: Control the screen to display Chinese
This task requires importing a 2Mb font file (of course, you can also just import a few fonts) and put it in the directory where code.py is located. A file of this size is unimaginable in the microcontrollers I have used before without storage expansion.
In this task, you only need to call two external libraries, adafruit_display_text and adafruit_bitmap_font. You can get the font by using the load_font method under bitmap_font of adafruit_bitmap_font. To display text, you need to create an instance of the Label class of adafruit_display_text. The first input parameter is the previous font, and the remaining parameters are keyword parameters. You can leave them blank and change the instance properties later. Finally, use board.DISPLAY.show() to display it.
The following is my code for looping through three lines of Chinese.
import board
import terminalio
import time
from adafruit_display_text import bitmap_label
from adafruit_bitmap_font import bitmap_font
font = bitmap_font.load_font("wenquanyi_9pt.pcf")
display = board.DISPLAY
color = {
"black" : 0x000000,
"white" : 0xFFFFFF,
"red" : 0xFF0000,
"green" : 0x00FF00,
"blue" : 0x0000FF,
"yellow" : 0xFFFF00,
}
txt = "你好"
txtCollection = ["Hello,World!","这里是zzu何同学的任务1展示","用户名:艾嘉西斯之铠"]
scaleCollection = [3,1,2]
text_area = bitmap_label.Label(font,color=color["white"])
text_area.scale = 3
text_area.x = 0
text_area.y = 60
display.show(text_area)
while True:
for i in range(3):
text_area.text = txtCollection[i]
text_area.scale = scaleCollection[i]
display.show(text_area)
time.sleep(1)
Task 2: Network Function Usage
The WIFI connection and hotspot opening of this development board also only require a simple call to the ready-made wifi library (I have to say it is really convenient). The following is only a picture of the board connecting to my mobile phone hotspot.
Here I have not considered the situation where the WiFi connection is not established for the first time. If the WiFi you set is not turned on after power-on, then it will not try to connect again. This should not be the case in actual application. Task 4 will improve it.
import board
import terminalio
import os
import wifi
from adafruit_display_text import bitmap_label
from adafruit_bitmap_font import bitmap_font
font = bitmap_font.load_font("wenquanyi_9pt.pcf")
display = board.DISPLAY
#=========================================================
#开启热点
#wifi.radio.start_ap('艾嘉西斯之铠', '1234567890')
#print("wifi start !!")
#=========================================================
#连接wifi(注意换成自己的wifi名称和密码)
wifi.radio.connect('你的wifi名称', 'your_password')
txt = "IP地址" + str(wifi.radio.ipv4_address)
text_area = bitmap_label.Label(font,text=txt)
text_area.scale = 2
text_area.x = 0
text_area.y = 60
display.show(text_area)
#=========================================================
while True:
pass
Task 3: Controlling the WS2812B
In fact, this task is still to adjust the library. What? You said you want to make some creative animation effects? Sorry, there are already libraries for common LED animation effects (let's be honest, Python is too convenient). Find the adafruit_led_animation library folder, the animation folder contains several animation effects. You can choose an LED light bar or directly use the neopixel that comes with this board. I choose and call the blink and colorcycle animation effects here. To save trouble, the colorcycle directly comes with the 'rainbow' cycle mode, and you don't even have to choose the color yourself. You can set the animation speed (it's called speed, but it's actually the cycle of an animation in seconds), brightness, etc.
In order to control the LED, a button is also needed. I use the built-in boot button here. RST is the reset button and cannot be used as a normal button. The level controlled by the button is read through the io port, so the digitalio library is called, and DigitalInOut(board.BOOT0) is used to obtain the instance of the io port corresponding to the boot button, and the direction attribute is used to control the input (Direction.INPUT) or output, and the pull attribute is used to set the input mode to pull up (Pull.UP) or pull down (Pull.DOWN). The level value of the IO port input can be obtained using buttom.value.
任务3演示
The following is my code, three display modes: emerald color fast flash, lace white slow flash and rainbow color cycle, each time a key is pressed, the color changes once.
import board
import time
import neopixel
from digitalio import DigitalInOut,Direction,Pull
from adafruit_led_animation.animation.blink import Blink
from adafruit_led_animation.animation.colorcycle import ColorCycle
#从adafruit_led_animation.color库导入五种颜色定义
from adafruit_led_animation.color import JADE, BLACK, ORANGE, GOLD, OLD_LACE
#初始化像素灯
pixel_pin = board.NEOPIXEL
pixel_num = 1
pixels = neopixel.NeoPixel(pixel_pin, pixel_num, brightness=0.1, auto_write=False, pixel_order=neopixel.GRB)
#初始化按键BOOT0
buttom = DigitalInOut(board.BOOT0)
buttom.direction = Direction.INPUT
buttom.pull = Pull.UP
#LED模式状态指示物
pixel_modeflag = 0
blink = Blink(pixels, speed=0.5, color=BLACK)
colorcycle = ColorCycle(pixels, speed=0.5)
#主循环
while True:
if not buttom.value:
pixel_modeflag = pixel_modeflag + 1
if (pixel_modeflag % 3 == 1):
blink = Blink(pixels, speed=0.2, color=JADE)
print("LED is Blink in JADE")
elif (pixel_modeflag % 3 == 2):
blink = Blink(pixels, speed=1, color=OLD_LACE)
print("LED is Blink in OLD_LACE")
elif (pixel_modeflag % 3 == 0):
colorcycle = ColorCycle(pixels, speed=0.1)
print("LED is ColorCycle in RAINBOW")
else:
pass
time.sleep(0.2)
if (pixel_modeflag % 3 == 0):
colorcycle.animate()
else:
blink.animate()
Task 4: Subtask 1: Calendar & Clock
In addition to transferring the database, there is more transferring the database. This task requires the content of Task 1 and Task 2, and it is my first time to use a single-chip microcomputer to obtain data from the Internet, so I print out the obtained json to see what the structure is like!
Get the current time
Get local weather and other information
It can be seen that the content obtained is a large dictionary, and the value in the key-value pair may also be an array, so you must look at the structure before calling it.
In addition, to use the website to obtain weather information, you need to query your local city code, which can be found here
The perpetual calendar effect I implemented is to connect to wifi in while. If wifi.radio.connected is 0, it means it is not connected (regardless of whether you have a connection error or there is no wifi). Try to connect again after two seconds, otherwise no subsequent activities will be performed. After the connection is successful, the time and weather will be updated every 60 seconds. The detailed code is as follows
import board
import os, wifi
import time
import ssl
import socketpool
import adafruit_requests
from adafruit_display_text import bitmap_label
from adafruit_bitmap_font import bitmap_font
#获取数据,返回str
def get_date():
try:
response = requests.get(JSON_TIME_URL)
print(response.json())
except ConnectionError as e:
print("Connection Error:",e)
print("Retrying in 60 seconds")
time_date = response.json()
city_code = "101180901"
url = JSON_WEATHER_URL.format(city_code)
try:
response = requests.get(url)
print(response.json())
except ConnectionError as e:
print("Connection Error:",e)
print("Retrying in 60 seconds")
city_date = response.json()
City_Name = city_date['cityInfo']['parent']+'省 '+city_date['cityInfo']['city']
City_Weather = city_date['data']
City_Forecast = City_Weather['forecast']
CurrentTime = time_date['sysTime2'] + ' ' + City_Forecast[0]['week']
TotalStr = City_Name
TotalStr += "\n时间:" + CurrentTime
TotalStr += "\n空气质量:" + City_Weather['quality']
TotalStr += "\n温度:" + City_Weather['wendu'] + '℃'
TotalStr += "\n湿度:" + City_Weather['shidu']
print(type(TotalStr))
return TotalStr
#屏幕显示,输入字符串
def screen_display(text):
text_area = bitmap_label.Label(font,color=color["white"])
text_area.scale = 1
text_area.x = 0
text_area.y = 5
text_area.text = text
display.show(text_area)
#显示屏显示初始化
font = bitmap_font.load_font("wenquanyi_9pt.pcf")
display = board.DISPLAY
color = {
"black" : 0x000000,
"white" : 0xFFFFFF,
"red" : 0xFF0000,
"green" : 0x00FF00,
"blue" : 0x0000FF,
"yellow" : 0xFFFF00,
}
#wifi连接
while not wifi.radio.connected:
try:
wifi.radio.connect('你的wifi名称','1234567890')
except ConnectionError as e:
print("Wifi connect error:{},wait for retry".format(e))
time.sleep(2)
print(f"IP Address:{wifi.radio.ipv4_address}" )
#请求获取JSON
JSON_TIME_URL = "http://quan.suning.com/getSysTime.do"
JSON_WEATHER_URL = "http://t.weather.sojson.com/api/weather/city/{}"
pool = socketpool.SocketPool(wifi.radio)
requests = adafruit_requests.Session(pool, ssl.create_default_context())
while True:
screen_display(get_date())
time.sleep(60)
The final effect is as follows
Part 3: Program source code
I have uploaded the source code of the four tasks, each in a folder. The download links are as follows:
download.eeworld.com.cn/detail/Agaxis Armor/629322?type__2276=n4%2BxcD9DRD0DuDAhi7D%2FjeeY5mhhDUxD5ii45x&alichlgref=http%3A%2F%2Fbbs.eeworld.com.cn%2Fmy%2Fhome.php%3Fcur%3Dmyhome%26act%3Ddownload
Experience
This Followme event allowed me to come into contact with CircuitPython for the first time. I have to say that it is really simple to write microcontrollers with Python, and CircuitPython has a fairly detailed instruction manual.
The above advantages give me the confidence to use this development board and CircuitPython language to complete our professional track-finding car course design. In fact, I did complete the tasks of tracking, obstacle avoidance, end point recognition, and distance time image display, and I only wrote 300 lines of code in the code.py file to achieve it. If I use STM32, I dare not think about how many lines. But this language also has a big shortcoming: it does not support interrupts... Whether it is a timer interrupt or an external interrupt, I have not found instructions or routines for use. It is said on the Internet that CircuitPython does not have this function... Alas, only using if else to make a track-finding car is indeed inconvenient when implementing certain functions.
All in all, this development board is really good, and I like it very much, but CircuitPython should still be used by beginners...
|