xscc

  • 2024-09-01
  • 发表了主题帖: 【2024 DigiKey 创意大赛】基于树莓派的室内CO2浓度检测仪-开箱帖

    得捷电子上下单很方便,发货挺快,美国到国内5天就到了。 发的顺丰快递 内部有塑料袋和减震泡沫 树莓派5 4G版本   SGP30空气质量传感器,用来检测CO2浓度。 开箱结束。    

  • 2024-06-29
  • 加入了学习《PI PowiGaN 系列视频》,观看 氮化镓进化史 - PI 高层座谈 - PowerUP Expo 2023

  • 2024-03-22
  • 加入了学习《【得捷电子Follow me第4期】演示视频》,观看 【得捷电子Follow me第4期】演示视频

  • 2024-03-18
  • 加入了学习《泰克MSO6B探索营》,观看 MSO6B技术介绍

  • 加入了学习《泰克MSO6B探索营》,观看 MSO6B-360度介绍

  • 2024-03-11
  • 发表了主题帖: 【得捷电子Follow me第4期】补充项目材料

    终极任务二  使用主控板内存储和以太网接口,实现轻量ftp文件服务器,可以上传、下载、删除文件        参考大佬们的方案,采用microPython 进行开发,开发板重新刷入microPython固件。然后采用相同局域网网段的PC电脑对开发板进行FTP访问。 import socket import network import uos import gc from time import localtime from machine import Pin,SPI import time def w5x00_init(): #spi init spi=SPI(0,2_000_000, mosi=Pin(19),miso=Pin(16),sck=Pin(18)) nic = network.WIZNET5K(spi,Pin(17),Pin(20)) #spi,cs,reset pin nic.active(True)#network active nic.ifconfig(('192.168.1.100','255.255.255.0','192.168.1.1','8.8.8.8'))#Set static network address information while not nic.isconnected(): time.sleep(1) print(nic.regs())#Print register information #Print network address information print("IP Address:",nic.ifconfig()[0]) print("Subnet Mask:",nic.ifconfig()[1]) print("Gateway:",nic.ifconfig()[2]) print("DNS:",nic.ifconfig()[3]) return nic month_name = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] def send_list_data(path, dataclient, full): try: # whether path is a directory name for fname in uos.listdir(path): dataclient.sendall(make_description(path, fname, full)) except: # path may be a file name or pattern pattern = path.split("/")[-1] path = path[:-(len(pattern) + 1)] if path == "": path = "/" for fname in uos.listdir(path): if fncmp(fname, pattern) == True: dataclient.sendall(make_description(path, fname, full)) def make_description(path, fname, full): if full: stat = uos.stat(get_absolute_path(path,fname)) file_permissions = "drwxr-xr-x" if (stat[0] & 0o170000 == 0o040000) else "-rw-r--r--" file_size = stat[6] tm = localtime(stat[7]) if tm[0] != localtime()[0]: description = "{} 1 owner group {:>10} {} {:2} {:>5} {}\r\n".format( file_permissions, file_size, month_name[tm[1]], tm[2], tm[0], fname) else: description = "{} 1 owner group {:>10} {} {:2} {:02}:{:02} {}\r\n".format( file_permissions, file_size, month_name[tm[1]], tm[2], tm[3], tm[4], fname) else: description = fname + "\r\n" return description def send_file_data(path, dataclient): with open(path, "r") as file: chunk = file.read(512) while len(chunk) > 0: dataclient.sendall(chunk) chunk = file.read(512) def save_file_data(path, dataclient, mode): with open(path, mode) as file: chunk = dataclient.read(512) while len(chunk) > 0: file.write(chunk) chunk = dataclient.read(512) def get_absolute_path(cwd, payload): # Just a few special cases "..", "." and "" # If payload start's with /, set cwd to / # and consider the remainder a relative path if payload.startswith('/'): cwd = "/" for token in payload.split("/"): if token == '..': if cwd != '/': cwd = '/'.join(cwd.split('/')[:-1]) if cwd == '': cwd = '/' elif token != '.' and token != '': if cwd == '/': cwd += token else: cwd = cwd + '/' + token return cwd # compare fname against pattern. Pattern may contain # wildcards ? and *. def fncmp(fname, pattern): pi = 0 si = 0 while pi < len(pattern) and si < len(fname): if (fname[si] == pattern[pi]) or (pattern[pi] == '?'): si += 1 pi += 1 else: if pattern[pi] == '*': # recurse if (pi + 1) == len(pattern): return True while si < len(fname): if fncmp(fname[si:], pattern[pi+1:]) == True: return True else: si += 1 return False else: return False if pi == len(pattern.rstrip("*")) and si == len(fname): return True else: return False def ftpserver(): DATA_PORT = 13333 ftpsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) datasocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ftpsocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) datasocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) ftpsocket.bind(socket.getaddrinfo("0.0.0.0", 21)[0][4]) datasocket.bind(socket.getaddrinfo("0.0.0.0", DATA_PORT)[0][4]) ftpsocket.listen(1) datasocket.listen(1) datasocket.settimeout(10) msg_250_OK = '250 OK\r\n' msg_550_fail = '550 Failed\r\n' try: dataclient = None fromname = None while True: cl, remote_addr = ftpsocket.accept() cl.settimeout(300) cwd = '/' try: # print("FTP connection from:", remote_addr) cl.sendall("220 Hello, this is the ESP8266.\r\n") while True: gc.collect() data = cl.readline().decode("utf-8").rstrip("\r\n") if len(data) <= 0: print("Client disappeared") break command = data.split(" ")[0].upper() payload = data[len(command):].lstrip() path = get_absolute_path(cwd, payload) print("Command={}, Payload={}, Path={}".format(command, payload, path)) if command == "USER": cl.sendall("230 Logged in.\r\n") elif command == "SYST": cl.sendall("215 UNIX Type: L8\r\n") elif command == "NOOP": cl.sendall("200 OK\r\n") elif command == "FEAT": cl.sendall("211 no-features\r\n") elif command == "PWD": cl.sendall('257 "{}"\r\n'.format(cwd)) elif command == "CWD": try: files = uos.listdir(path) cwd = path cl.sendall(msg_250_OK) except: cl.sendall(msg_550_fail) elif command == "CDUP": cwd = get_absolute_path(cwd, "..") cl.sendall(msg_250_OK) elif command == "TYPE": # probably should switch between binary and not cl.sendall('200 Transfer mode set\r\n') elif command == "SIZE": try: size = uos.stat(path)[6] cl.sendall('213 {}\r\n'.format(size)) except: cl.sendall(msg_550_fail) elif command == "QUIT": cl.sendall('221 Bye.\r\n') break elif command == "PASV": addr = nic.ifconfig()[0] cl.sendall('227 Entering Passive Mode ({},{},{}).\r\n'.format( addr.replace('.',','), DATA_PORT>>8, DATA_PORT%256)) dataclient, data_addr = datasocket.accept() # print("FTP Data connection from:", data_addr) elif command == "LIST" or command == "NLST": if not payload.startswith("-"): place = path else: place = cwd try: send_list_data(place, dataclient, command == "LIST" or payload == "-l") cl.sendall("150 Here comes the directory listing.\r\n") cl.sendall("226 Listed.\r\n") except: cl.sendall(msg_550_fail) if dataclient is not None: dataclient.close() dataclient = None elif command == "RETR": try: send_file_data(path, dataclient) cl.sendall("150 Opening data connection.\r\n") cl.sendall("226 Transfer complete.\r\n") except: cl.sendall(msg_550_fail) if dataclient is not None: dataclient.close() dataclient = None elif command == "STOR": try: cl.sendall("150 Ok to send data.\r\n") save_file_data(path, dataclient, "w") cl.sendall("226 Transfer complete.\r\n") except: cl.sendall(msg_550_fail) if dataclient is not None: dataclient.close() dataclient = None elif command == "APPE": try: cl.sendall("150 Ok to send data.\r\n") save_file_data(path, dataclient, "a") cl.sendall("226 Transfer complete.\r\n") except: cl.sendall(msg_550_fail) if dataclient is not None: dataclient.close() dataclient = None elif command == "DELE": try: uos.remove(path) cl.sendall(msg_250_OK) except: cl.sendall(msg_550_fail) elif command == "RMD": try: uos.rmdir(path) cl.sendall(msg_250_OK) except: cl.sendall(msg_550_fail) elif command == "MKD": try: uos.mkdir(path) cl.sendall(msg_250_OK) except: cl.sendall(msg_550_fail) elif command == "RNFR": fromname = path cl.sendall("350 Rename from\r\n") elif command == "RNTO": if fromname is not None: try: uos.rename(fromname, path) cl.sendall(msg_250_OK) except: cl.sendall(msg_550_fail) else: cl.sendall(msg_550_fail) fromname = None else: cl.sendall("502 Unsupported command.\r\n") # print("Unsupported command {} with payload {}".format(command, payload)) except Exception as err: print(err) finally: cl.close() cl = None finally: datasocket.close() ftpsocket.close() if dataclient is not None: dataclient.close() nic = w5x00_init() ftpserver() 运行如图 建立了地址为192.168.1.100的ftp 在PC机上使用Xftp软件,建立连接 建立连接后传输一个文件到FTP上  将DGBCDX64.exe传输到ftp上     演示视频: https://training.eeworld.com.cn/video/39557   代码下载: 源码   总结        以前没接触过网络编程这次学到了很多网络底层的协议,提高了不少!       感谢EEWorld和DigiKey!

  • 加入了学习《【DigiKey创意大赛】人脸识别储物柜 》,观看 【DigiKey创意大赛】人脸识别储物柜

  • 上传了资料: 【得捷电子Follow me第4期】代码汇总

  • 2024-03-06
  • 发表了主题帖: 【得捷Follow me第4期】作品提交

    本帖最后由 xscc 于 2024-3-6 06:17 编辑 【得捷Follow me第4期】项目提交 硬件选用官方推荐的组合,w5500模块加Adafruit LCD显示屏。焊接好排线后,因电路比较简单,用面包板搭接电路。并刷入固件和所用到的库文件,按住boot键,同时将w5500插入U口,拖拽下好的固件至u盘即可,使用adafruit-circuitpython-wiznet_w5500_evb_pico-en_US-8.2.9.uf2。 W5500引脚图 一、入门任务: 使用circuit python进行开发工作,库文件比较全,开发简单。 基础任务1,驱动led闪烁,驱动lcd进行文字和线条测试。按照spi = GP14, MOSI=15,scs =GP13连接lcd和w5500。 写入如下程序 import sys import time import board import digitalio import busio import adafruit_sharpmemorydisplay # 打印输入到stdout print("start:xxx") # 初始化LED引脚 led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT # Initialize SPI bus and control pins spi = busio.SPI(board.GP14, MOSI=board.GP15) scs = digitalio.DigitalInOut(board.GP13) # inverted chip select # pass in the display size, width and height, as well # display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 96, 96) display = adafruit_sharpmemorydisplay.SharpMemoryDisplay(spi, scs, 144, 168) print("Pixel test") # Clear the display. Always call show after changing pixels to make the display # update visible! display.fill(1) display.show() # Set a pixel in the origin 0,0 position. display.pixel(0, 0, 0) # Set a pixel in the middle position. display.pixel(display.width // 2, display.width // 2, 0) # Set a pixel in the opposite corner position. display.pixel(display.width - 1, display.height - 1, 0) display.show() time.sleep(2) print("Lines test") # we'll draw from corner to corner, lets define all the pair coordinates here corners = ( (0, 0), (0, display.height - 1), (display.width - 1, 0), (display.width - 1, display.height - 1), ) display.fill(1) for corner_from in corners: for corner_to in corners: display.line(corner_from[0], corner_from[1], corner_to[0], corner_to[1], 0) display.show() time.sleep(2) print("Rectangle test") display.fill(1) w_delta = display.width / 10 h_delta = display.height / 10 for i in range(11): display.rect(0, 0, int(w_delta * i), int(h_delta * i), 0) display.show() time.sleep(2) print("Text test") display.fill(1) display.text(" hello world!", 0, 0, 0) display.text(" This is the", 0, 8, 0) display.text(" CircuitPython", 0, 16, 0) display.text("adafruit library", 0, 24, 0) display.text(" for the SHARP", 0, 32, 0) display.text(" Memory Display :) ", 0, 40, 0) display.show() # 循环使能LED点亮 while True: # 点亮LED led.value = True time.sleep(1) led.value = False time.sleep(1)   结果如图所示 文字显示 线条显示   [localvideo]cffc6364a2ef43c49165e917ade9fe33[/localvideo] 演示视频     基础任务2:完成主控板W5500初始化(静态IP配置),并能使用局域网电脑ping通,同时W5500可以ping通互联网站点;通过抓包软件(Wireshark、Sniffer等)抓取本地PC的ping报文,展示并分析。 查看本机的IP参数如下 配置w5500网络参数 IP_ADDRESS = (192, 168, 1, 123) SUBNET_MASK = (255, 255, 255, 0) GATEWAY_ADDRESS = (192, 168, 1, 1) DNS_SERVER = (8, 8, 8, 8) 代码如下 import board import busio import digitalio import time from adafruit_wiznet5k.adafruit_wiznet5k import WIZNET5K ##SPI0 SPI0_SCK = board.GP18 SPI0_TX = board.GP19 SPI0_RX = board.GP16 SPI0_CSn = board.GP17 ##reset W5x00_RSTn = board.GP20 print("Wiznet5k Ping Test (no DHCP)") # Setup your network configuration below # random MAC, later should change this value on your vendor ID MY_MAC = (0x00, 0x01, 0x02, 0x03, 0x04, 0x05) IP_ADDRESS = (192, 168, 1, 123) SUBNET_MASK = (255, 255, 255, 0) GATEWAY_ADDRESS = (192, 168, 1, 1) DNS_SERVER = (8, 8, 8, 8) led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT ethernetRst = digitalio.DigitalInOut(W5x00_RSTn) ethernetRst.direction = digitalio.Direction.OUTPUT # For Adafruit Ethernet FeatherWing cs = digitalio.DigitalInOut(SPI0_CSn) # For Particle Ethernet FeatherWing # cs = digitalio.DigitalInOut(board.D5) spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX) # Reset W5500 first ethernetRst.value = False time.sleep(1) ethernetRst.value = True # Initialize ethernet interface with DHCP # eth = WIZNET5K(spi_bus, cs) # Initialize ethernet interface without DHCP eth = WIZNET5K(spi_bus, cs, is_dhcp=False, mac=MY_MAC) # Set network configuration eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER) print("Chip Version:", eth.chip) print("MAC Address:", [hex(i) for i in eth.mac_address]) print("My IP address is:", eth.pretty_ip(eth.ip_address)) while True: led.value = not led.value time.sleep(1) print("Done!")   在本机上ping开发板如图所示 正常ping通。 使用wireshark进行抓包操作,用规则ip.addr == 192.168.1.123过滤出和W5500的交互数据。 进阶任务1 从NTP服务器(注意数据交互格式的解析)同步时间,获取时间送显示屏(串口)显示. 代码如下 import board import busio import digitalio import time import array import struct import adafruit_requests as requests from adafruit_wiznet5k.adafruit_wiznet5k import * import adafruit_wiznet5k.adafruit_wiznet5k_socket as socket from adafruit_wiznet5k.adafruit_wiznet5k_ntp import NTP import adafruit_wiznet5k.adafruit_wiznet5k_dns as dns import adafruit_ntp days = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday") ##SPI0 SPI0_SCK = board.GP18 SPI0_TX = board.GP19 SPI0_RX = board.GP16 SPI0_CSn = board.GP17 ##reset W5x00_RSTn = board.GP20 print("Wiznet5k NTP Client (DHCP)") # Setup your network configuration below # random MAC, later should change this value on your vendor ID MY_MAC = (0x00, 0x01, 0x02, 0xFF, 0xFF, 0xFF) IP_ADDRESS = (192, 168, 1, 123) SUBNET_MASK = (255, 255, 255, 0) GATEWAY_ADDRESS = (192, 168, 1, 1) DNS_SERVER = (8, 8, 8, 8) port = 5000 ntp_server_port= 123 led = digitalio.DigitalInOut(board.GP25) led.direction = digitalio.Direction.OUTPUT ethernetRst = digitalio.DigitalInOut(W5x00_RSTn) ethernetRst.direction = digitalio.Direction.OUTPUT # For Adafruit Ethernet FeatherWing cs = digitalio.DigitalInOut(SPI0_CSn) # cs = digitalio.DigitalInOut(board.D5) spi_bus = busio.SPI(SPI0_SCK, MOSI=SPI0_TX, MISO=SPI0_RX) # Reset W5500 first ethernetRst.value = False time.sleep(1) ethernetRst.value = True # Initialize ethernet interface without DHCP #eth = WIZNET5K(spi_bus, cs, is_dhcp=False, mac=MY_MAC, debug=False) # Initialize ethernet interface with DHCP eth = WIZNET5K(spi_bus, cs, is_dhcp=True, mac=MY_MAC, debug=False) print("Chip Version:", eth.chip) print("MAC Address:", [hex(i) for i in eth.mac_address]) print("My IP address is:", eth.pretty_ip(eth.ip_address)) # Initialize a socket for our server socket.set_interface(eth) # Set network configuration eth.ifconfig = (IP_ADDRESS, SUBNET_MASK, GATEWAY_ADDRESS, DNS_SERVER) ntp = adafruit_ntp.NTP(socket) print(ntp.datetime)   串口输出结果如下

  • 2024-02-06
  • 加入了学习《直播回放: FollowMe 4 W5500-EVB-Pico 使用入门》,观看 W5500-EVB-Pico 使用入门

  • 2024-01-17
  • 发表了主题帖: 【DigiKey“智造万物,快乐不停”创意大赛】+人脸识别储物柜 作品提交

    作品名称:人脸识别储物柜 作者:xscc   一、作品简介 人脸识别储物柜,通过人脸识别完成储物操作,解决传统储物柜钥匙或小票丢失带来的不便。项目主控采用树莓派4B,外扩摄像头和执行机构完成设计。 成品照片:   项目用到的板卡和模块有,1、树莓派4B,2、罗技USB摄像头,3、继电器模块,4、电控锁,5、电源。   树莓派4B   USB摄像头   继电器模块   电控锁   主要功能通过摄像头采集人员面部信息,在树莓派上运行OPENCV图像库,进行图形采集和特征提取工作,如果和存储的特征库吻合,则通过树莓派上GPIO17驱动继电器打开柜门锁完成存储工作。   二、系统框图 项目选用树莓派4B作为主控,安装官方64位系统,编程语言选用Python开发,Python编程符合自然语言习惯,上手快,官方系统已经安装Python。然后安装OpenCV库,OpenCV是开源计算机视觉库,拥有强大的内置函数和开源社群。OpenCV配合便携开源廉价的树莓派,可以直接读取来自摄像头的视频,进行人脸识别、边缘检测、图像识别等各种计算机视觉开发任务。树莓派系统和OpenCV安装网上教程很多,按教程一步步完成就行,此处不再重复。 硬件设计采用树莓派4B作为主控、HDMI显示屏、USB摄像头、一位继电器模块、电控门锁和电源,TF卡等附件组成。电路图如下图所示:   树莓派4B运行操纵系统和OPENCV图像识别库,USB摄像头负责采集人脸信息,继电器和电控锁完成开锁工作。   当人脸特征符合存储的数据后,树莓派GPIO17输出高电平,驱动继电器接通三秒,打开电控锁,弹出柜门。   软件流程见下图:     三、各部分功能说明    由于是演示只设计了一个柜门,硬件电路较为简单,就是通过树莓派GPIO17脚驱动继电器打开电控锁,扩展一个继电器是因为电控锁动作所需电流较大5V1A,树莓派GPIO引脚提供不了所需电流。      开发工具使用的是 Python2 作为开发语言,OpenCV 作为图像处理库,使用树莓派自带的 Thonny编辑器。 软件部分采用Python语言开发,代码参考了OpenCV例程。Python编辑器采用Thonny。它简单易用,可以在树莓派上轻松使用。它的用户界面直观,具有代码自动缩进、语法高亮等功能。   在工程目录下创建dataset文件夹储存人脸样本,和trainer文件夹储存训练数据。并将OpenCV提供的haarcascade 分类器(haarcascade_frontalface_default.xml)拷贝到工程目录下。目录结构和文件见下图。   dataset:放人脸图片的文件,里面有诸如ABCD文件夹,每个文件夹里是诸如ABCD的数据图片。 faces:数据文件,存放id和name. face_dataset_01.py: 人脸数据采集 face_training_02.py:训练已有数据并生成模型 face_recognition_03.py:人脸识别比对和开锁工作   首先是人脸数据的采集,在Thonny编辑器中运行程序1。人脸录入过程是用USB摄像头对准屏幕采集预先下载好的人脸图像,能够将视频图像显示到界面中,并对人脸进行检测,将图像中所有的人脸检测出来,并用矩形框框出。   采集30张灰度图做图像特征识别。程序会收集30个样本数据,存储样本数据在dataset中,可在用户界面直接打查看。 运行程序2进行训练人脸特征数据,会读取捕获的人脸图像进行识别训练,并将训练数据保存在程序目录下的文件中。 运行程序3进行人脸识别比对和开锁工作,用摄像头对准事先下载的图片,依次进行识别。   如人像比对不正确,显示unknow。   如人像比对正确,显示OPEN DOOR,并驱动电控锁打开柜门。   四、作品源码 1.face_dataset_01.py: 人脸数据采集 import cv2 import os cam = cv2.VideoCapture(0) cam.set(3, 640) # set video width cam.set(4, 480) # set video height face_detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # For each person, enter one numeric face id face_id = input('\n enter user id end press <return> ==> ') print("\n [INFO] Initializing face capture. Look the camera and wait ...") # Initialize individual sampling face count count = 0 while(True): ret, img = cam.read() img = cv2.flip(img, -1) # flip video image vertically gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) faces = face_detector.detectMultiScale(gray, 1.3, 5) for (x,y,w,h) in faces: cv2.rectangle(img, (x,y), (x+w,y+h), (255,0,0), 2) count += 1 # Save the captured image into the datasets folder cv2.imwrite("dataset/User." + str(face_id) + '.' + str(count) + ".jpg", gray[y:y+h,x:x+w]) cv2.imshow('image', img) k = cv2.waitKey(100) & 0xff # Press 'ESC' for exiting video if k == 27: break elif count >= 30: # Take 30 face sample and stop video break # Do a bit of cleanup print("\n [INFO] Exiting Program and cleanup stuff") cam.release() cv2.destroyAllWindows()   2.face_training_02_02.py:训练已有数据并生成模型 import numpy as np from PIL import Image import os import cv2 # Path for face image database path = 'dataset' recognizer = cv2.face.LBPHFaceRecognizer_create() detector = cv2.CascadeClassifier("haarcascade_frontalface_default.xml"); # function to get the images and label data def getImagesAndLabels(path): imagePaths = [os.path.join(path,f) for f in os.listdir(path)] faceSamples=[] ids = [] for imagePath in imagePaths: PIL_img = Image.open(imagePath).convert('L') # convert it to grayscale img_numpy = np.array(PIL_img,'uint8') id = int(os.path.split(imagePath)[-1].split(".")[1]) faces = detector.detectMultiScale(img_numpy) for (x,y,w,h) in faces: faceSamples.append(img_numpy[y:y+h,x:x+w]) ids.append(id) return faceSamples,ids print ("\n [INFO] Training faces. It will take a few seconds. Wait ...") faces,ids = getImagesAndLabels(path) recognizer.train(faces, np.array(ids)) # Save the model into trainer/trainer.yml recognizer.write('trainer/trainer.yml') # recognizer.save() worked on Mac, but not on Pi # Print the numer of faces trained and end program print("\n [INFO] {0} faces trained. Exiting Program".format(len(np.unique(ids))))  3、face_recognition_03.py:人脸识别比对和开锁工作 import cv2 import numpy as np import os from gpiozero import LED from time import sleep # 定义引脚编号 pin = 17 # 创建LED对象 led = LED(pin) recognizer = cv2.face.LBPHFaceRecognizer_create() recognizer.read('trainer/trainer.yml') cascadePath = "haarcascade_frontalface_default.xml" faceCascade = cv2.CascadeClassifier(cascadePath); font = cv2.FONT_HERSHEY_SIMPLEX #iniciate id counter id = 0 # names related to ids: example ==> 1: id=1, etc names = ['None', '1', '2', '3', '4', '5'] # Initialize and start realtime video capture cam = cv2.VideoCapture(0) cam.set(3, 640) # set video widht cam.set(4, 480) # set video height # Define min window size to be recognized as a face minW = 0.1*cam.get(3) minH = 0.1*cam.get(4) #开门 def open_door(): print("开锁...") #开锁三秒 led.on() sleep(3) led.off() # 清理资源 led.close() while True: ret, img =cam.read() img = cv2.flip(img, -1) # Flip vertically gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale( gray, scaleFactor = 1.2, minNeighbors = 5, minSize = (int(minW), int(minH)), ) for(x,y,w,h) in faces: cv2.rectangle(img, (x,y), (x+w,y+h), (0,255,0), 2) id, confidence = recognizer.predict(gray[y:y+h,x:x+w]) # Check if confidence is less them 100 ==> "0" is perfect match if (confidence < 60): id = names[id] confidence = " {0}%".format(round(100 - confidence)) #cv2.putText(img, str(id), (x+5,y-5), font, 1, (255,255,255), 2) cv2.putText(img, str("OPEN DOOR"), (x+5,y-5), font, 1, (255,255,255), 2) #cv2.putText(img, str(confidence), (x+5,y+h-5), font, 1, (255,255,0), 1) cv2.imshow('camera',img) open_door() else: id = "unknown" confidence = " {0}%".format(round(100 - confidence)) cv2.putText(img, str(id), (x+5,y-5), font, 1, (255,255,255), 2) cv2.putText(img, str(confidence), (x+5,y+h-5), font, 1, (255,255,0), 1) cv2.imshow('camera',img) k = cv2.waitKey(10) & 0xff # Press 'ESC' for exiting video if k == 27: break # Do a bit of cleanup print("\n [INFO] Exiting Program and cleanup stuff") cam.release() cv2.destroyAllWindows()   五、作品功能演示视频 [localvideo]9c33fb7cb1e544847471943914fb4152[/localvideo]   六、项目总结    在Raspberry Pi上使用OpenCV和Python进行图像处理非常简便快捷,可以实现实时面部检测,检测速度也很快,达到了实用级别。虽然当前使用Haar 级联的设置非常有效,但今后随着深度学习等进步可以提高准确性。    目前项目只是实现了基本功能,后面还需要进一步改进,使用QT完成界面开发,屏幕换用触控屏幕,增加活体检测功能提高安全性。 分享帖子链接 1、【DigiKey“智造万物,快乐不停”创意大赛】+人脸识别储物柜 GPIO设置和柜门机构 https://bbs.eeworld.com.cn/thread-1269691-1-1.html 2、【DigiKey“智造万物,快乐不停”创意大赛】+人脸识别储物柜 摄像头选择与配置  https://bbs.eeworld.com.cn/thread-1269587-1-1.html 3、【DigiKey创意大赛】+收货开箱 https://bbs.eeworld.com.cn/thread-1261214-1-1.html 4、代码下载地址https://download.eeworld.com.cn/detail/xscc/630812 5、word文档下载地址https://download.eeworld.com.cn/detail/xscc/630813  

  • 上传了资料: 【DigiKey“智造万物,快乐不停”创意大赛】+人脸识别储物柜 开发文档

  • 上传了资料: 【DigiKey“智造万物,快乐不停”创意大赛】+人脸识别储物柜 代码

  • 回复了主题帖: 【DigiKey“智造万物,快乐不停”创意大赛】+人脸识别储物柜 GPIO设置和柜门机构

    Jacktang 发表于 2024-1-13 20:58 电控锁的电源是5V供电吧 锁体和锁舌装在小机箱上比效果更好 就是

  • 2024-01-12
  • 发表了主题帖: 【DigiKey“智造万物,快乐不停”创意大赛】+人脸识别储物柜 作品提交

    先占楼,资料正在整理。 补充内容 (2024-1-17 11:28): 内容见新帖 https://bbs.eeworld.com.cn/thread-1270057-1-1.html

  • 发表了主题帖: 【DigiKey“智造万物,快乐不停”创意大赛】+人脸识别储物柜 GPIO设置和柜门机构

    储物柜柜门开启通过树莓派GPIO进行,树莓派 4B,有 40 个 GPIO 引脚,树莓派官方操作系统 Raspbian 下,可以使用系统默认安装的 python 中 RPi.GPIO 库,进行操作。 GPIO定义   由于使用的是64位系统,需使用gpiozero进行控制,GPIO Zero库是树莓派官方目前推荐的用于操作树莓派上GPIO口的Python库,该库最早是在RPi.GPIO库之上开发而来的。 官方的镜像已经包含了GPIO Zero库,不用单独安装。 测试一下GPIO控制,首先搭建测试,点亮一个LED灯。 连接图 可以使用下面代码来控制LED亮灭交替闪烁: # 引入LED类 from gpiozero import LED from time import sleep red = LED(17) #物理引脚11 while True: red.on() sleep(2) red.off() sleep(2) LED灯点亮,闪烁。 储物柜柜门开锁方式选用储物柜专用电控锁。 这个电控锁设计的很巧妙,是利用一根特殊金属丝,通电后热涨冷缩的原理来控制锁的开闭,控制简单可靠。根据实际电源情况,选用的是5v型号。   通电测试运行可靠。 采用一个塑料盒模拟储物柜 用将锁体和锁舌用热熔胶分别固定在盒身和盒盖上。 开好孔洞将控制线引出。 电路部分,由于电控锁电压为5V,且控制电流较大,树莓派的GPIO为3.3V,不能直接驱动,所以GPIO先控制一个3.3V的继电器,再通过继电器控制电控锁。GPIO使用物理第11引脚,接线如下图所示: 图中中间位置的调试器,只用来给电控锁提供5V电源。 编写如下程序进行测试 from gpiozero import LED from time import sleep # 定义引脚编号 pin = 17 # 创建LED对象 led = LED(pin) print("开锁...") #开锁三秒 led.on() sleep(3) led.off() # 清理资源 led.close()   运行后,如图 运行程序,输出开锁信息,电控锁动作,储物柜柜门弹开。 [localvideo]38518db66f1cd5f6b5e76373181a2fe7[/localvideo]            

  • 发表了主题帖: 【DigiKey“智造万物,快乐不停”创意大赛】+人脸识别储物柜 摄像头选择与配置

    本设计采用树莓派作为主控实现相关功能,首先安装树莓派系统,教程很多此处不再重复,然后是摄像头的选择。 树莓派上经常使用的摄像头有raspberry pi camera module和通用USB摄像头两种。 raspberry pi camera module USB摄像头   两者都能满足人脸识别要求,经过试用决定采用USB摄像头,原因是USB摄像头线长便于操作,而raspberry pi camera module线短,要带着树莓派操作,太不方便了。 首先是配置摄像头,安装fswebcam软件包 sudo apt install fswebcam 运行结果如下图 安装成功后,就可以拍照测试了 fswebcam image.jpg 拍照结果见下图 可以看到图像采集成功,但分辨率比较低,可以使用参数-r设置分辨率 fswebcam -r 1280x720 --no-banner image.jpg 拍摄了一幅分辨率为 1280 x 720的图像,至此摄像头配置完毕。  

  • 2023-12-18
  • 加入了学习《【得捷Follow me第3期】项目贴》,观看 【得捷电子Follow me第3期】项目报告

  • 2023-12-17
  • 上传了资料: 【得捷电子Follow me第3期】项目源码

  • 发表了主题帖: 【得捷电子Follow me第3期】项目报告

    项目视频: https://training.eeworld.com.cn/video/38855   必做任务1:使用MicroPython系统【对该任务的介绍、功能对应的主要代码片段及说明、功能展示及说明、心得体会建议】 并给开发板刷写MicroPython系统,完成入门程序的运行 这里采用Thonny环境搭建micropython 下载安装Thonny,4.1.4版本安装不上,最后安装3.3.13版本 我通过在线安装方式,开发板刷写MicroPython系统,完成入门程序的运行,不用下载软件,点击就能完成。 https://dev.16302.com/tools/#/ 点击  初始化设备(固件)工具  安提示进行。 安装完成后,编写一个 hello world 程序,结果如图 必做任务2:驱动扩展板上的OLED屏幕【对该任务的介绍、功能对应的主要代码片段及说明、功能展示及说明、心得体会建议】 首先通过THONNY集成开发环境加载SSD1306的库文件 显示一个方框,内部写一段文字”Follow me 3”。 import time from machine import Pin, SoftI2C import ssd1306 import math i2c = SoftI2C(scl=Pin(7), sda=Pin(6))# Adjust the Pin numbers based on your connections oled_width = 128 oled_height = 64 oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c) oled.fill(0)# Clear the screen oled.text("----------------", 0, 0) oled.text("Follow me 3", 10, 20) oled.text("----------------", 0, 40) oled.rect(0,10, 128,54, 1) oled.show()# Show the text 结果如图 必做任务3:控制蜂鸣器播放音乐【对该任务的介绍、功能对应的主要代码片段及说明、功能展示及说明、心得体会建议】   IO5脚直接驱动蜂鸣器就行 from machine import Pin, PWM import time buzzer = PWM(Pin(5, Pin.OUT)) buzzer.freq(5000) while True: buzzer.duty_u16(32767) time.sleep(1) buzzer.duty_u16(0) time.sleep(1) 结果见视频 必做任务4:连接WiFi网络【对该任务的介绍、功能对应的主要代码片段及说明、功能展示及说明、心得体会建议】 ESP 32的最大优势就是联网功能强大,有库支持使用也很简单。 先安装WiFi支持库network 通过WiFi连接授时网站,显示时间和日期。 from machine import Pin, SoftI2C import ssd1306 from time import sleep import time import network import urequests import ujson # ESP32 Pin assignment # i2c = SoftI2C(scl=Pin(22), sda=Pin(21)) # ESP8266 Pin assignment i2c = SoftI2C(scl=Pin(7), sda=Pin(6)) # Adjust the Pin numbers based on your connections oled_width = 128 oled_height = 64 oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c) station = network.WLAN(network.STA_IF) station.active(True) # Network settings wifi_ssid = "100" wifi_password = "87654321" url = "http://worldtimeapi.org/api/timezone/America/New_York" print("Scanning for WiFi networks, please wait...") authmodes = ['Open', 'WEP', 'WPA-PSK' 'WPA2-PSK4', 'WPA/WPA2-PSK'] for (ssid, bssid, channel, RSSI, authmode, hidden) in station.scan(): print("* {:s}".format(ssid)) print(" - Channel: {}".format(channel)) print(" - RSSI: {}".format(RSSI)) print(" - BSSID: {:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}".format(*bssid)) print() # Continually try to connect to WiFi access point while not station.isconnected(): # Try to connect to WiFi access point print("Connecting...") station.connect(wifi_ssid, wifi_password) time.sleep(10) # Display connection details print("Connected!") print("My IP Address:", station.ifconfig()[0]) while True: # Perform HTTP GET request on a non-SSL web response = urequests.get(url) # Check if the request was successful if response.status_code == 200: # Parse the JSON response data = ujson.loads(response.text) # Extract the "datetime" field for New York ny_datetime = data["datetime"] # Split the date and time components date_part, time_part = ny_datetime.split("T") # Get only the first two decimal places of the time time_part = time_part[:8] # Get the timezone timezone = data["timezone"] # Clear the OLED display oled.fill(0) # Display the New York date and time on separate lines oled.text("XIAN Date:", 0, 0) oled.text(date_part, 0, 10) oled.text("XIAN Time:", 0, 20) oled.text(time_part, 0, 30) oled.text("Timezone:", 0, 40) oled.text(timezone, 0, 50) # Update the display oled.show() else: oled.text("Failed to get the time for XIAN!") # Update the display oled.show() 设置好自己wifi的用户名和密码,安装好外接天线,联网过程稍微慢一些,结果如下图 必做任务5:使用外部传感器【对该任务的介绍、功能对应的主要代码片段及说明、功能展示及说明、心得体会建议】 使用温湿度传感器和光照传感器采集数据,显示在OLED上。 首先安装ahtx0库文件,用来支持AHT20 温湿度传感器,是IIC接口,光照传感器是模拟量接口,两个传感器接到对应的扩展口上,不要接错了。 from machine import Pin, SoftI2C, ADC import ssd1306 import utime import time from ahtx0 import AHT20 i2c = SoftI2C(scl=Pin(7), sda=Pin(6)) oled_width = 128 oled_height = 64 oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c) # 清空屏幕,并显示任务要求 oled.fill(0) oled.text("Light:", 0, 48) oled.text("Temp:", 0, 16) oled.text("Humi:", 0, 32) oled.show() # aht20 aht = AHT20(i2c) # 光照部分 adc = ADC(Pin(2)) adc.atten(ADC.ATTN_11DB) adc.width(ADC.WIDTH_12BIT) #4095 while True: temp = aht.temperature humi = aht.relative_humidity light_adc = adc.read() # 计算光照强度单位Lux light_lux = light_adc * 350 * 1.0 / 4095 # 算出电阻值单位K light_res = (4095 - light_adc) * 10.0 / light_adc print("Temp(°):\n"); print('{:.2f}'.format(temp)) print("Humi(%):\n"); print('{:.2f}'.format(humi)) print("Light(lux)\n"); print('{:.2f}'.format(light_lux)) print("Light(K)\n"); print('{:.2f}'.format(light_res)) # 清除变化部分的内容 oled.fill_rect(64,16,64,48,0) oled.text('{:.2f}'.format(temp), 64, 16) oled.text('{:.2f}'.format(humi), 64, 32) oled.text('{:.2f}'.format(light_lux), 64, 48) oled.show() # 延时1秒 time.sleep(1) 运行结果见下图 心得体会 Seeed Studio XIAO开发板虽然体积小但功能强大,得益于 ESP32C3芯片主频高,存储也不小、联网功能还强,结合不错的低功耗特性,在可穿戴设备开发方面优势不少。   源码已上传 https://download.eeworld.com.cn/detail/xscc/630303

最近访客

< 1/5 >

统计信息

已有557人来访过

  • 芯积分:372
  • 好友:--
  • 主题:35
  • 回复:314

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言