*本文原创作者:_橙子 ゝ,本文属FreeBuf原创奖励计划,未经许可禁止转载
生活中的美无处不在,当开始留意细节,就必然会找到很多日常生活中的美,你开始会在当中寻到乐趣,人生里有很多重要时刻,出生、毕业、结婚等等,这些都是应该留在家庭历史的故事,而偏偏很多时,都无法雇用一个专业摄影师拍照,所以教大家DIY一个属于自己的照相机。
买个单反需要几千RMB,买个普通拍立得也得几百,有点浪费money,主要是贫穷,土豪随意,最近一直在学习MicroPython,正好手上有一块开发板-TPYBoard v102,就自己瞎捣鼓,自己动手DIY了1个照相机,结果还不错哦,所以分享出来教大家一块儿做起来(*^▽^*)
材料准备
TPYBoard v102 1块
PTC06 串口摄像头模块 1个
5110显示屏 1个
照相机纸盒 1个
按键模块 2个
杜邦线 若干
TPYBoard v102
PTC06 串口摄像头模块
PTC06 串口摄像头简介
PTC06 是一款集图像采集、拍摄控制、数据压缩、串口传输于一体的工业级图像采集处理模块。其内置的高性能数字信号处理芯片实现了对原始图像的高比例压缩。产品图像输出采用标准 JPEG 格式,可方便地兼容各种图像处理软件;采用 3 线制 TTL 电平 UART 通信接口,可以方便地实现与单片机或其他微处理器连接。默认波特率为115200,其它可选波特率有 9600,19200,38400 和 57600。
通讯方式以及详细参数调试
照相机硬件接线方法
TPYBoard v102 和PTC06 串口摄像头模块,具体接线方式如下表:
TPYBoard v102 | 摄像头模块 |
---|---|
VIN | 5V |
GND | GND |
X1(UART 4 TX) | RX |
X2(UART 4 RX) | TX |
按键模块
给照相机增加两个按键开关,一个控制拍照,另一个控制复位。将TPYBoard v102上面的板载按键RST、USR引出。由于TPYBoard v102按键初始化默认为低电平。所以接按键模块时,需要把这个按键模块置为高电平,就是正负极反接,下面是接线方法。
具体接线方式如下表:
TPYBoard v102 | 按键模块黑色(复位键) |
---|---|
3.3V | GND |
GND | VCC |
RST | OUT |
TPYBoard v102 | 按键模块黄色(拍摄键) |
---|---|
GND | VCC |
3.3V | GND |
X17 | OUT |
5110显示屏(SPI通信)
5110显示屏并不是为了显示拍摄的图片,而是显示相机当前状态。
相机连接电源,当5110显示屏显示OK是,即表示相机已准备就绪,可以进行拍摄,然后我们按下黄色拍摄按键,5110显示屏会显示吃豆小人,此时表示相片正在传输,当小人完全吃豆完成就可以查看照片了。
5110显示屏与TPYBoard v102具体接线方式如下表:
TPYBoard v102 | 5110显示屏 |
---|---|
Y12 | RST |
Y11 | CE |
Y10 | DC |
Y9 | LIGHT |
Y8 | DIN |
Y6 | CLK |
3.3V | VIN |
GND | GND |
动手一起DIY
第一步:照相机镜头(一次性纸杯)
第二步:机身(纸盒)
第三步:5110机身显示状态
第四步:照相机机顶(按键)
第五步:给照相机上个色,凭个人喜爱
第六步:效果展示,现拍现卖
第一张
第二张
只要按照硬件接线方法接起线来,自己动手做个外壳就ok了,下面把程序分享给大家!!!
源代码
我们编写好main.py,并导入fond.py 和upcd8544.py(用来驱动5110显示屏,看相机状态),在这我就不公开了,需要fond.py 和upcd8544.py下载地址:
https://github.com/TPYBoard/developmentBoard/tree/master/TPYBoard-v10x-master
import pyb
from pyb import UART,Switch
import upcd8544
#-----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=0
f_name='/sd/photo%s.jpeg'
nBytes=2048#每次读取的字节数
#---------------------------------#
uart=UART(4,115200,timeout=100)#X1(UART 4 TX) X2(UART 4 RX)
#-------十进制转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
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
def test():
global num,isPhoto
pyb.delay(30)
if(sw()):
sw.callback(None)
isPhoto=0
num+=1
pyb.LED(3).on()
#清除缓存
uart.write(clearcmd)
#-------LCD5110 Init-----------#
SPI = pyb.SPI(1) #DIN=>X8-MOSI/CLK=>X6-SCK
RST = pyb.Pin('Y12')
CE = pyb.Pin('Y11')
DC = pyb.Pin('Y10')
LIGHT = pyb.Pin('Y9')
lcd_5110 = upcd8544.PCD8544(SPI, RST, CE, DC, LIGHT)
lcd_5110.lcd_write_bmp()
#------------------------------#
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()
lcd_5110.lcd_write_bmp(0)
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)
lcd_5110.clear()
lcd_5110.lcd_write_bmp(1)
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)
offset=0
for i in range(0,t_c):
offset_a=i//4
if offset<offset_a:
offset=offset_a
lcd_5110.clear()
lcd_5110.lcd_write_bmp(1,offset)
add=convert_Data(i*nBytes)
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('*========================================*')
lcd_5110.clear()
lcd_5110.lcd_write_bmp(2)
sw.callback(test)
else:
print('-----data length error-----')
*本文原创作者:_橙子 ゝ,本文属FreeBuf原创奖励计划,未经许可禁止转载
来源:freebuf.com 2018-04-10 08:00:41 by: _橙子 ゝ
请登录后发表评论
注册