综合技术交流
直播中

jim

6年用户 514经验值
擅长:存储技术
私信 关注
[经验]

【CS创世 SD NAND】SD NAND芯片的测评与使用(基于卷积神经网络的数字识别)

目录

前言:

简介:

对照:

测试:

使用:

照片存储:

基于卷积神经网络的数字识别:

————————————————

前言:

感谢深圳雷龙公司寄送的样品,其中包括两张2代的4gbit和32gbit的SD NAND FLASH芯片以及一份测试板卡。

[]()

简介:

根据官方文档的描述,这款芯片采用LGA-8封装,具有标准SDIO接口,并同时兼容SPI和SD接口。因此,可以直接移植标准驱动代码,支持使用SD NAND FLASH的SOC也可以用于TF卡启动。

以下是该芯片的主要参数(以CSNP32GCR01-BOW手册为准):

接口:符合标准SD Specification Version 2.0规范,包括1-I/O和4-I/O两种模式。

默认模式:在默认模式下,时钟频率可变范围为0-25 MHz,接口速度高达12.5 MB/sec(使用4条并行数据线路)。

高速模式:在高速模式下,时钟频率可变范围为0-50 MHz,接口速度高达25 MB/sec(使用4条并行数据线路)。

对照:

下面是SD NAND芯片和传统TF卡的一些对比:

[]()

目前,一些树莓派和一些国产的微处理器经常通过SD卡进行系统的移植,但一些设计不合理的卡槽经常不能保护SD卡,反而会损坏折断。相比之下,SD NAND可以通过贴片直接嵌入嵌入式设备中,更适合嵌入式环境的开发。同时,裸露的SD卡槽和松动的SD卡时常会影响系统的稳定性,因此一个可以反复擦拭的稳定存储芯片显得十分重要。

通过将测试板和芯片进行简单的焊接,我们可以像使用SD卡一样对SD NAND FLASH进行测试。

测试:

首先,我们使用CrystalDiskMark 8.0.4c对这款储存器进行了测试:

本次测试的是512MB的容量的产品,容量是真实的。我们可以看出,在包括顺序读取、顺序写入、随机读取和随机写入的四个测试方式下,SD NAND取得了不错的测试结果,接近官方数据,可以成功进行高速存储。

[]()

使用:

此外,我们还利用k210与SD NAND进行了照片的存储和基于卷积神经网络的数字识别。

1.照片存储:

通过向SD NAND内烧录micropython代码,实现了k210对照片的拍摄和存储。存储速度非常快。

import sensor, lcd

from Maix import GPIO

from fpioa_manager import fm

from board import board_info

import os, sys

import time

import image

image size

set_windowing = (224, 224)

sensor config

sensor.reset(freq=22000000, dual_buff=False)

sensor.set_pixformat(sensor.RGB565)

sensor.set_framesize(sensor.QVGA) # 320x240

try:

sensor.set_jb_quality(95) # for IDE display quality

except Exception:

pass # no IDE support

if set_windowing:

sensor.set_windowing(set_windowing)

sensor.set_auto_gain(False)

sensor.set_auto_whitebal(False, rgb_gain_db=(0x52,0x40,0x4d))

sensor.set_saturation(0)

sensor.set_brightness(4)

sensor.set_contrast(0)

sensor.set_hmirror(True) # image horizonal mirror

sensor.set_vflip(True) # image vertical flip

sensor.set_auto_whitebal(False)

sensor.skip_frames()

lcd config

lcd.init(type=1, freq=15000000)

lcd.rotation(2)

boot key

boot_pin = 16 # board_info.BOOT_KEY

fm.register(boot_pin, fm.fpioa.GPIOHS0)

key = GPIO(GPIO.GPIOHS0, GPIO.PULL_UP)

######################################################

main

def capture_main(key):

def draw_string(img, x, y, text, color, scale, bg=None , full_w = False):

if bg:

if full_w:

full_w = img.width()

else:

full_w = len(text)8scale+4

img.draw_rectangle(x-2,y-2, full_w, 16*scale, fill=True, color=bg)

img = img.draw_string(x, y, text, color=color,scale=scale)

return img

def del_all_images():

os.chdir("/sd")

images_dir = "cap_images"

if images_dir in os.listdir():

os.chdir(images_dir)

types = os.listdir()

for t in types:

os.chdir(t)

files = os.listdir()

for f in files:

os.remove(f)

os.chdir("..")

os.rmdir(t)

os.chdir("..")

os.rmdir(images_dir)

del_all_images()

os.chdir("/sd")

dirs = os.listdir()

images_dir = "cap_images"

last_dir = 0

for d in dirs:

if d.startswith(images_dir):

if len(d) > 11:

n = int(d[11:])

if n > last_dir:

last_dir = n

images_dir = "{}_{}".format(images_dir, last_dir+1)

print("save to ", images_dir)

if images_dir in os.listdir():

img = image.Image()

img = draw_string(img, 2, 200, "please del cap_images dir", color=lcd.WHITE,scale=1, bg=lcd.RED)

lcd.display(img)

sys.exit(1)

os.mkdir(images_dir)

last_cap_time = 0

last_btn_status = 1

save_dir = 0

save_count = 0

os.mkdir("{}/{}".format(images_dir, save_dir))

while(True):

img0 = sensor.snapshot()

if set_windowing:

img = image.Image()

img = img.draw_image(img0, (img.width() - set_windowing[0])//2, img.height() - set_windowing[1])

else:

img = img0.copy()

img = img.resize(320, 240)

if key.value() == 0:

time.sleep_ms(30)

if key.value() == 0 and (last_btn_status == 1) and (time.ticks_ms() - last_cap_time > 500):

last_btn_status = 0

last_cap_time = time.ticks_ms()

else:

if time.ticks_ms() - last_cap_time > 5000:

img = draw_string(img, 2, 200, "release to change type", color=lcd.WHITE,scale=1, bg=lcd.RED)

else:

img = draw_string(img, 2, 200, "release to capture", color=lcd.WHITE,scale=1, bg=lcd.RED)

if time.ticks_ms() - last_cap_time > 2000:

img = draw_string(img, 2, 160, "keep push to change type", color=lcd.WHITE,scale=1, bg=lcd.RED)

else:

time.sleep_ms(30)

if key.value() == 1 and (last_btn_status == 0):

if time.ticks_ms() - last_cap_time > 5000:

img = draw_string(img, 2, 200, "change object type", color=lcd.WHITE,scale=1, bg=lcd.RED)

lcd.display(img)

time.sleep_ms(1000)

save_dir += 1

save_count = 0

dir_name = "{}/{}".format(images_dir, save_dir)

os.mkdir(dir_name)

else:

draw_string(img, 2, 200, "capture image {}".format(save_count), color=lcd.WHITE,scale=1, bg=lcd.RED)

lcd.display(img)

f_name = "{}/{}/{}.jpg".format(images_dir, save_dir, save_count)

img0.save(f_name, quality=95)

save_count += 1

last_btn_status = 1

img = draw_string(img, 2, 0, "will save to {}/{}/{}.jpg".format(images_dir, save_dir, save_count), color=lcd.WHITE,scale=1, bg=lcd.RED, full_w=True)

lcd.display(img)

del img

del img0

def main():

try:

capture_main(key)

except Exception as e:

print("error:", e)

import uio

s = uio.StringIO()

sys.print_exception(e, s)

s = s.getvalue()

img = image.Image()

img.draw_string(0, 0, s)

lcd.display(img)

main()

[]()

2.基于卷积神经网络的数字识别:

我们向SD NAND内烧录了功能代码、模型参数和模型结构。SD NAND可以很好地存储以上内容,并通过k210正确加载模型。在使用过程中,SD NAND表现出了出色的稳定性,没有出现崩溃或弹出的情况。

[]()

generated by maixhub, tested on maixpy3 v0.4.8

copy files to TF card and plug into board and power on

import sensor, image, lcd, time

import KPU as kpu

import gc, sys

input_size = (224, 224)

labels = ['1', '2', '3', '4', '5', '6', '7', '8']

anchors = [0.45, 1.55, 1.46, 2.54, 1.22, 1.55, 1.58, 2.59, 1.47, 2.78]

def lcd_show_except(e):

import uio

err_str = uio.StringIO()

sys.print_exception(e, err_str)

err_str = err_str.getvalue()

img = image.Image(size=input_size)

img.draw_string(0, 10, err_str, scale=1, color=(0xff,0x00,0x00))

lcd.display(img)

def main(anchors, labels = None, model_addr="/sd/m.kmodel", sensor_window=input_size, lcd_rotation=0, sensor_hmirror=False, sensor_vflip=False):

sensor.reset()

sensor.set_pixformat(sensor.RGB565)

sensor.set_framesize(sensor.QVGA)

sensor.set_windowing(sensor_window)

sensor.set_vflip(1)

sensor.run(1)

lcd.init(type=1)

lcd.rotation(lcd_rotation)

lcd.clear(lcd.WHITE)

if not labels:

with open('labels.txt','r') as f:

exec(f.read())

if not labels:

print("no labels.txt")

img = image.Image(size=(320, 240))

img.draw_string(90, 110, "no labels.txt", color=(255, 0, 0), scale=2)

lcd.display(img)

return 1

try:

img = image.Image("startup.jpg")

lcd.display(img)

except Exception:

img = image.Image(size=(320, 240))

img.draw_string(90, 110, "loading model...", color=(255, 255, 255), scale=2)

lcd.display(img)

try:

task = None

task = kpu.load(model_addr)

kpu.init_yolo2(task, 0.5, 0.3, 5, anchors) # threshold:[0,1], nms_value: [0, 1]

while(True):

img = sensor.snapshot()

t = time.ticks_ms()

objects = kpu.run_yolo2(task, img)

t = time.ticks_ms() - t

if objects:

for obj in objects:

pos = obj.rect()

img.draw_rectangle(pos)

img.draw_string(pos[0], pos[1], "%s : %.2f" %(labels[obj.classid()], obj.value()), scale=2, color=(255, 0, 0))

img.draw_string(0, 200, "t:%dms" %(t), scale=2, color=(255, 0, 0))

lcd.display(img)

except Exception as e:

raise e

finally:

if not task is None:

kpu.deinit(task)

if name == "main":

try:

main(anchors = anchors, labels=labels, model_addr=0x300000, lcd_rotation=0)

main(anchors = anchors, labels=labels, model_addr="/sd/model-54796.kmodel")

except Exception as e:

sys.print_exception(e)

lcd_show_except(e)

finally:

gc.collect()

通过以上两个实验,SD NAND代替传统的SD/TF卡进行数据存储表现出了极大的优势和稳定性。
SD NAND,贴片式TF卡,贴片式SD卡嵌入式sd卡,工业级sd卡

更多回帖

发帖
×
20
完善资料,
赚取积分