查看: 3716|回复: 1

Micropython TPYBoard v102 DIY照相机

[复制链接]
  • TA的每日心情
    慵懒
    2018-1-6 09:01
  • 签到天数: 7 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2018-3-19 17:11:47 | 显示全部楼层 |阅读模式
    分享到:

    摄像头(CAMERA或WEBCAM)又称为电脑相机、电脑眼、电子眼等,是一种视频输入设备,被广泛的运用于视频


    会议,安防系统  、图像采集系统、 环境监控 、工业现场过程控制 等方面。本实验用TPYBoard v102以


    及PTC06 串口摄像头模块DIY一个简易的照相机。


    1.所用器材:


       TPYBoard v102  1块


       PTC06 串口摄像头模块1个


       杜邦线若干


       TF卡1个


       下载数据线1条


    2.TPYBoard v102简介


    TPYBoard  v102主控芯片采用STM32F405,M4的内核,168MHZ的最高运行速度,1024KB的Flash,192KB的


    RAM,内置SD卡槽,最大支持8G内存的内存卡。板载四个LED灯和一个加速度传感器。TPYBoard v102板载


    30 个通用GPIO 接口、 2个 SPI 接口、2个 CAN  接口、2个I2C  接口、 5个 USART 接口、 2


    个ADC接


    口 (精度12bit ) 、2个DAC接口、   1个SWD接口。可与大部分常用传感器模块连接。


                                                                                                                                                     

    3. PTC06 串口摄像头模块简介:


    PTC06 串口摄像头模块是一款集图像采集、拍摄控制、数据压缩、串口传输于一体的工业级图像采集 处理模


    块。其内置的高性能数字信号处理芯片实现了对原始图像的高比例压缩。产品图像输 出采用标准 JPEG 格


    式,可方便地兼容各种图像处理软件;采用 3 线制 TTL 电平 UART 通 信接口,可以方便地实现与单


    片机或


    其他微处理器连接。


    默认波特率为 115200,其它可选波特率有 9600,19200,38400 和 57600。

    其中对于串口控制拍照,读取静态图片的应用中,只需要用到 GND,RX,TX,VCC 这 4 个信号线。 如果是


    要输出模拟视频的应用,才需要将 CVBS 信号。


    注意: TX 和 RX 是 3.3v 的 TTL 电平信号。

    4.接线方式:


      TPYBoard v102     

         摄像头模块
       VIN         5V
       GND        GND

       X1(UART 4 TX)

            RX
       X2(UART 4 RX)          TX


    5.实验步骤.


    基本原理:TPYboard v102 通过串口与串口摄像头模块(PTC06)进行连接,通过按键控制模块进行拍照,并


    保存到TF卡中。


    上电后,等待ToyBoard v102板载绿灯亮起,说明摄像头模块初始化完毕,按一下USR键,控制摄像头进行拍


    照,蓝灯会闪烁,说明正在传输图片数据,等待蓝灯熄灭后,说明传输完毕。


    按一下rst键让板子重新加载一下TF卡,打开TF卡就会看到一个新生成的jpeg文件。


    详情见视频。https://v.qq.com/x/page/s0608s2re8g.html





    6.源代码:

    """
    #TPYBoard v102 驱动串口摄像头PTC06 拍照并保存到TF卡
    #------------------------------------------------------
    #作者:山东萝卜电子科技有限公司
    #时间:2018年03月15日
    """

    import pyb
    from pyb import UART,Switch

    """
    拍照的基本流程
    --------------------
    1.清空图片缓存
    2.发送拍照命令
    3.获取图片的长度
    4.根据长度读取图片数据

    使用到的指令与返回的数据格式
    -------------------------------
    复位
    0x56 0x00 0x26 0x00
    返回
    0x76 0x00 0x26 0x00 +DSP 版本信息+Init end
    ------------------------
    清空图片缓存
    0x56 0x00 0x36 0x01 0x02
    返回
    0x76 0x00 0x36 0x00 0x00
    -------------------------
    拍照命令
    0x56 0x00 0x36 0x01 0x00
    返回
    0x76 0x00 0x36 0x00 0x00
    --------------------------
    读所拍图片的长度
    56 00 34 01 00
    返回
    0x76 0x00 0x34 0x00 0x04 0x00 0x00 XX YY
    (XX 为高位字节,YY 为低位字节)
    --------------------------
    读取图片数据
    0x56 0x00 0x32 0x0C 0x00 0x0A 0x00 0x00 AA BB 0x00 0x00 XX YY 0x00 0xFF
    AA BB:起始地址(先高位字节,后低位字节.必须是8的倍数)
    XX YY:本次读的数据长度(先高位字节,后低位字节)
    返回
    76 00 32 00 00 FF D8 ....... FF D9 76 00 32 00 00
    (完整的JPEG 图片文件是以 FF D8 开始 FF D9 结尾)
    """
    #-----Command---------#
    initcmd=b'\x56\x00\x26\x00' #复位指令
    clearcmd=b'\x56\x00\x36\x01\x02' #清除缓存
    photocmd=b'\x56\x00\x36\x01\x00' #拍照
    lengthcmd=b'\x56\x00\x34\x01\x00' #获取图片长度
    readcmd=b'\x56\x00\x32\x0C\x00\x0A\x00\x00' #获取图片数据
    responseCmd=b'\x76\x00\x32\x00\x00'#返回的图片数据固定头和尾
    #---------------------------------#
    isFlag=0#标识是否初始化
    isPhoto=0#标识是否发送拍照命令
    num=1
    f_name='/sd/photo%s.jpeg'#保存的文件名称
    nBytes=512#每次读取的字节数
    #---------------------------------#
    uart=UART(4,115200,timeout=100)#串口4 TX-X1 RX-X2

    #------将10进制转为16进制字节数组--------#
    def convert_Data(num):
        if num>255:
            num_h=hex(num)
            if len(num_h)<6:
                num_h_a=num_h[:3]
                num_h_b='0x'+num_h[3:]
            else:
                num_h_a=num_h[:4]
                num_h_b='0x'+num_h[4:]
            byte_num=bytes([int(num_h_a,16),int(num_h_b,16)])
        else:
            byte_num=b'\x00'+bytes([num])
        return byte_num
    #---------------------------------
    #函数名:get_photo
    #描述:获取图片数据
    #参数:起始地址、读取长度
    #返回:成功返回正常数据,失败返回0
    #---------------------------------/
    def get_photo(add,readlen):
        global readcmd,responseCmd
       
        cmd=readcmd+add+b'\x00\x00'+readlen+b'\x00\xFF'
        uart.write(cmd)
        while uart.any()<=0:
            continue
        data=uart.read()
        #print('data:',data)
        #print('data[0:5]:',data[0:5])
        #print('data[-5:]:',data[-5:])
        if data[0:5]==responseCmd and data[-5:]==responseCmd:
            revdata=data[5:-5]
            print('revdata:',revdata)
        else:
            revdata=0
        return revdata
    #---------------------------------
    #函数名:test
    #描述:USR按键的回调函数。
    #按键每按1次拍照1次
    #---------------------------------/
    def test():
        global num,isPhoto
        pyb.delay(30)
        if(sw()):
            sw.callback(None)#正在获取数据时 禁用回调
            isPhoto=0
            num+=1
            pyb.LED(3).on()
            #清除缓存
            uart.write(clearcmd)
    #等待模块上电完毕      
    print('wait......')
    pyb.delay(2800)
    print('init start.......')
    uart.write(initcmd)
    sw=Switch()
    sw.callback(test)
    while True:
        if uart.any()>0:
            data=uart.read()
            print('revdata:',data)
            if isFlag==0:
                #说明接收的是复位后的信息
                if data==b'Init end\r\n':
                    #复位完毕
                    print('init ok.......')
                    pyb.delay(2000)
                    isFlag=1
                    pyb.LED(2).on()
            else:
                if len(data)>=5:
                    if data[0]==118:#0x76
                        if data[2]==54:#0x36
                            if isPhoto==0:
                                #清除缓存返回
                                print('-----clear buffer ok----')
                                isPhoto=1
                                uart.write(photocmd)
                            else:
                                #拍照返回
                                print('-----taking pictures ok----')
                                uart.write(lengthcmd)
                        if data[2]==52:#0x34
                            print('photo length:',data[7],'-',data[8])
                            tlen=data[7]*256+data[8]
                            t_c=tlen//nBytes
                            t_y=tlen%nBytes
                            add=0
                            #256=[0x01,0x00] 512=[0x02,0x00]
                            length=convert_Data(nBytes)
                            name=f_name % str(num)
                            print('filename:',name)
                            for i in range(0,t_c):
                                add=convert_Data(i*nBytes)
                                #每512字节写一次
                                revdata=get_photo(add,length)
                                if revdata!=0:
                                    f=open(name,'a')
                                    f.write(revdata)
                                    f.close()
                                pyb.LED(4).toggle()
                                print('-------------',i)
                                pyb.delay(100)
                            add=convert_Data(t_c*nBytes)   
                            revdata=get_photo(add,convert_Data(t_y))
                            if revdata!=0:
                                f=open(name,'a')
                                f.write(revdata)
                                f.close()
                            pyb.LED(3).off()
                            pyb.LED(4).off()
                            pyb.delay(100)
                            print('*========================================*')
                            sw.callback(test)
                else:
                    print('-----data length error-----')


    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-11-27 13:43 , Processed in 0.125622 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.