CircuitPython ESP-NOW: Remote control on-board RGB LED via wireless, between ESP32-S3.
With previous CircuitPython exercises of CircuitPython/ESP-NOW and Touch buttons on ILI9341 SPI LCD with FT6336 Cap. Touch, this exercise implement remote control on-board RGB LED wirelessly, between ESP32-S3-DevKitC-1 (sender) and Waveshare ESP32-S3-Zero (receiver).
cpyS3_ili9341_FT6336_grouped_color_TouchButtons_espnow_sender.py
"""
ESP32-S3/CircuitPython 9.0.5 exercise,
act as ESP-NOW sender,
send msg to receiver to control onboard RGB,
with ILI9341 SPI LCD + FT6336 cap. touch.
---------------------------
Display Module:
3.2 inch IPS SPI Module ILI9341 with cap. touch FT6336U
Test on:
dev. board: Espressif ESP32-S3-DevKitC-1
CircuitPython: 9.0.5
Libraries needed:
- adafruit_ili9341.mpy
- adafruit_focaltouch.mpy
- adafruit_display_text folder
- adafruit_button folder
- adafruit_cursorcontrol folder
- adafruit_display_shapes folder
(It's needed by adafruit_button, so you have to load in /lib folder.)
"""
import os, sys
import board
import busio
import terminalio
import displayio
import fourwire
from adafruit_display_text import label
import adafruit_ili9341
import bitmaptools
from digitalio import DigitalInOut, Direction
import adafruit_focaltouch
import adafruit_cursorcontrol.cursorcontrol
from adafruit_button import Button
import time
import wifi
import espnow
ILI9341_INVOFF = 0x20 #Display Inversion OFF
ILI9341_INVON = 0x21 #Display Inversion ON
# Release any resources currently in use for the displays
displayio.release_displays()
#===init display ======================
#Connection to ILI9341/SD
DISP_CS = board.IO17
DISP_RES = board.IO16
DISP_DC = board.IO15
SPI_MOSI = board.IO7
SPI_SCL = board.IO6
DISP_BL = board.IO5
SPI_MISO = board.IO4
SD_CS = board.IO43
#Connection to FT6336U
TOUCH_SCL = board.IO42
TOUCH_SDA = board.IO1
TOUCH_INT = board.IO44
TOUCH_RST = board.IO2
touch_irq = DigitalInOut(TOUCH_INT)
touch_irq.direction = Direction.INPUT
touch_res = DigitalInOut(TOUCH_RST)
touch_res.direction = Direction.OUTPUT
touch_res.value = True
time.sleep(0.1)
touch_res.value = False
time.sleep(0.1)
touch_res.value = True
time.sleep(0.5)
spi = busio.SPI(clock=SPI_SCL,
MOSI=SPI_MOSI,
MISO=SPI_MISO)
#On CircuitPython 9 FourWire moved from displayio to fourwire
display_bus = fourwire.FourWire(spi, command=DISP_DC, chip_select=DISP_CS, reset=DISP_RES)
touch_i2c = busio.I2C(TOUCH_SCL, TOUCH_SDA)
#ft = adafruit_focaltouch.Adafruit_FocalTouch(touch_i2c, debug=False)
#In my test with irq_pin=touch_irq,
#reading ft.touched (in Main Loop) will not return if not touched;
#such that the Main Loop blocked, and the text not scrolled.
ft = adafruit_focaltouch.Adafruit_FocalTouch(touch_i2c, debug=False, irq_pin=touch_irq)
#--- Setup display ---
# for 3.2" 320x240 SPI ILI9341 TFT
disp_width = 320
disp_height = 240
display = adafruit_ili9341.ILI9341(display_bus,
width=disp_width,
height=disp_height,
backlight_pin=DISP_BL,
)
display_bus.send(int(ILI9341_INVON), "") #invert color
sysinfo = sys.implementation[0] + " " + os.uname()[3] + "\nrun on " + os.uname()[4]
drv_info = adafruit_ili9341.__name__ + " " + adafruit_ili9341.__version__ +"\n" \
+ adafruit_focaltouch.__name__ + " " + adafruit_focaltouch.__version__
print("=============================================")
print("coXXect.blogspot.com")
print("---------------------------------------------")
print(sys.implementation[0], os.uname()[3],
"\nrun on", os.uname()[4])
print("=============================================")
print(drv_info)
time.sleep(1)
# Make the display context
bgGroup = displayio.Group()
display.root_group = bgGroup
bg_bitmap = displayio.Bitmap(display.width, display.height, 1)
bg_palette = displayio.Palette(1)
bg_palette[0] = 0x000000 # Black
bg_sprite = displayio.TileGrid(bg_bitmap, pixel_shader=bg_palette, x=0, y=0)
bgGroup.append(bg_sprite)
# Draw label
text_group = displayio.Group(scale=2, x=10, y=120)
text = "coXXect.blogspot.com"
text_area = label.Label(terminalio.FONT, text=text, color=0xFFFFFF)
text_group.append(text_area) # Subgroup for text scaling
bgGroup.append(text_group)
info_group = displayio.Group(scale=1, x=10, y=180)
info_label = label.Label(terminalio.FONT,
text=sysinfo + "\n" + drv_info,
color=0xFFFFFF)
info_group.append(info_label) # Subgroup for text scaling
bgGroup.append(info_group)
time.sleep(1)
bgGroup.remove(text_group)
bgGroup.remove(info_group)
# Create color buttons panel ---
PANEL_WIDTH = 300
PANEL_HEIGHT = 200
PANEL_OFFSET_X = int((display.width - PANEL_WIDTH)/2)
PANEL_OFFSET_Y = 10
panel_bitmap = displayio.Bitmap(PANEL_WIDTH, PANEL_HEIGHT, 1)
panel_palette = displayio.Palette(1)
panel_palette[0] = 0x808080
panel_sprite = displayio.TileGrid(panel_bitmap, pixel_shader=panel_palette, x=PANEL_OFFSET_X, y=PANEL_OFFSET_Y)
bgGroup.append(panel_sprite)
# max len = num_of_roW * num_of_col
color_set= [ 0x000000, 0xFF0000, 0x00FF00, 0x0000FF,
0x808080, 0x800000, 0x008000, 0x000080,
0xA0A0A0, 0x008080, 0x800080, 0x808000,
0xFFFFFF, 0x00FFFF, 0xFF00FF, 0xFFFF00,
]
num_of_row = 4
num_of_col = 4
row_width = int(PANEL_WIDTH/num_of_row)
col_height = int(PANEL_HEIGHT/num_of_col)
btn_gap_x = 5
btn_gap_y = 3
btn_width = row_width - (2 * btn_gap_x)
btn_height = col_height - (2 * btn_gap_y)
col_btn = []
r = 0
c = 0
for i in range(len(color_set)):
btn = Button(x= r * row_width + btn_gap_x + PANEL_OFFSET_X,
y= c * col_height + btn_gap_y + PANEL_OFFSET_Y,
width=btn_width,
height=btn_height,
fill_color=color_set[i],
outline_color=0x000000,
)
col_btn.append(btn)
bgGroup.append(col_btn[i])
r = r + 1
if r == num_of_row:
r = 0
c = c + 1
#--- End of Create color buttons panel ---
# Prepare cursor, just to display the touch position for info only.
# initialize the mouse cursor object
# place over all others
mouse_cursor = adafruit_cursorcontrol.cursorcontrol.Cursor(
display, display_group=bgGroup)
mouse_cursor.x = int(display.width/2)
mouse_cursor.y = int(display.height/2)
running_symbols = ['-', '\\', '|', '/']
running_symbol_idx = 0
# display my MAC address
my_mac = " "
for m in wifi.radio.mac_address:
my_mac = my_mac + f"0x{m:02x}"[2:].upper() + "."
my_mac = my_mac[:-1] # remove last '.'
print("my mac address:", my_mac)
# Prepare ESP-NOW
e = espnow.ESPNow()
peer = espnow.Peer(mac=b'<receiver MAC>') # MAC of receiver
e.peers.append(peer)
# Main Loop
while True:
# if the screen is being touched print the touches
if ft.touched:
touches = ft.touches
#sometimes ft.touches is [], empty!
#so I check len to prevent IndexError: index out of range
if len(touches)>0:
#print(touches)
x = touches[0]['x']
y = touches[0]['y']
#with rotation=0, have to adjust touch x/y to project on screen.
mouse_cursor.x = y
mouse_cursor.y = display.height-x
touch = [mouse_cursor.x, mouse_cursor.y]
button_pressed = False
for i, b in enumerate(col_btn):
if b.contains(touch):
color_sellected = b.fill_color
bg_palette[0] = color_sellected
print("["+str(i)+"]:", f'{b.fill_color:0>6X}')
button_pressed = True
color_to_send = str(color_sellected)
print(type(color_to_send), color_to_send)
e.send(color_to_send)
e.send(b'end')
if not button_pressed:
print("pressed outside buttons")
else:
print('no touch')
# print a running symbol on REPL Shell without new-line,
# to check if it's in:
# running : no irq_pin parameter passed in creating Adafruit_FocalTouch
# blocked : with irq_pin=touch_irq in creating Adafruit_FocalTouch
running_sym = running_symbols[running_symbol_idx]
print(running_sym, end="\r")
running_symbol_idx = running_symbol_idx + 1
if running_symbol_idx == len(running_symbols):
running_symbol_idx = 0
time.sleep(0.05)
print("~ bye ~")
cpy_S3Zero-Zero_RGB__espnow_receiver.py
"""
ESP32-S3-Zero/Circuitpython 9.0.5 exercise,
act as ESP-NOW receiver,
to control on-board RGB (NeoPixel) base on received msg.
"""
import os, sys
import time
import neopixel
import board
import wifi
import espnow
def cycleNeopixel(wait):
for r in range(255):
pixel[0] = (r, 0, 0)
time.sleep(wait)
for r in range(255, 0, -1):
pixel[0] = (r, 0, 0)
time.sleep(wait)
for g in range(255):
pixel[0] = (0, g, 0)
time.sleep(wait)
for g in range(255, 0, -1):
pixel[0] = (0, g, 0)
time.sleep(wait)
for b in range(255):
pixel[0] = (0, 0, b)
time.sleep(wait)
for b in range(255, 0, -1):
pixel[0] = (0, 0, b)
time.sleep(wait)
print("=================================================")
info = sys.implementation[0] + ' ' + os.uname()[3] + '\n' + \
'run on ' + os.uname()[4]
print(info)
print("- Control onboard RGB (NeoPixel) -")
print("=================================================")
print("board.NEOPIXEL:", board.NEOPIXEL)
print()
# Create the NeoPixel object
pixel = neopixel.NeoPixel(board.NEOPIXEL,
1,
pixel_order=neopixel.RGB)
pixel[0] = (0, 0, 0)
time.sleep(0.5)
#to check if NeoPixel work correct
cycleNeopixel(0.005)
pixel[0] = (0, 0, 0)
mac = ""
for m in wifi.radio.mac_address:
mac = mac + "\\x" + f'{m:0>2x}'
print(mac)
e = espnow.ESPNow()
while True:
packets = []
while True:
if e:
packet = e.read()
packets.append(packet)
if packet.msg == b'end':
break
print("packets:", f"length={len(packets)}")
for packet in packets:
if packet.msg != b'end':
print("received msg:", type(packet.msg), packet.msg)
msg_to_int = int(packet.msg)
print("msg_to_int:", type(msg_to_int), msg_to_int, hex(msg_to_int))
r = int((msg_to_int & 0xFF0000) / 0x010000)
g = int((msg_to_int & 0x00FF00) / 0x000100)
b = int(msg_to_int & 0x0000FF)
print(type(r), r, type(g), g, type(b), b,)
pixel[0] = (r, g, b)
print("- bye -\n")
Comments
Post a Comment