站内搜索
发作品签到
简易拍立得设计
专业版

简易拍立得设计

工程标签

星火计划2024

4.1w
0
0
125

简介

这个一个可以将三维空间降到二维的装置,任何被他捕捉到的空间,都会被降维到一张小纸条上,人们称他为“二向箔”,哦不,拍立得。

简介:这个一个可以将三维空间降到二维的装置,任何被他捕捉到的空间,都会被降维到一张小纸条上,人们称他为“二向箔”,哦不,拍立得。
星火计划2024

开源协议

GPL 3.0

(未经作者授权,禁止转载)
创建时间:2024-05-16 19:56:23更新时间:2024-09-05 14:36:24

描述

项目说明

  • 主控使用STM32,并移植LVGL8.2。
  • 200万像素摄像头,实现照片拍摄功能。
  • 2.8寸TFT液晶显示屏,分辨率240×320。实现照片显示、打印、删除等功能。
  • 内置热敏打印单元,可实现拍摄照片打印功能。
  • 内置500mAh锂电池,并设计有锂电池充放电管理单。无需外部电源,体积小巧,方便携带。
  • 使用波轮按键方便操作,同时提供电源开关键和拍摄按键。
  • 支持定时休眠,一键休眠和唤醒,降低功耗。

开源协议

GPL3.0
开源网址:https://gitee.com/liangzili/camera

项目属性

提示:本项目为首次公开,为本人原创项目。项目未曾在别的比赛中获奖。

更新日志

master

  • 固件程序修复摄像头清晰度差的问题。

20240720_V2.1

  • 固件程序优化热敏打印速度。
  • PCB调整DCMI为等长布线。
  • PCB调整热敏打印头和摄像头供电部分线宽。
  • PCB修复部分丝印被遮挡的问题。
  • PCB修复左下角固定孔位置。

20240521_V2.0

  • 新增LVGL8.2适配,实现更好的UI效果。
  • 新增摄像头驱动电路,减小因摄像模组带来的空间占用。
  • 优化RGB565转灰度算法,实现更合理的灰度值输出。
  • 修改电源开关位置,解决因电源开关关闭导致无法充电的问题。
  • PCB版型修改,下方开槽,方便打印纸卷放置,减小机身厚度。
  • 修复LCD FSMC_D1引脚错误。
  • 修复因VDDA、VSSA导致的STM32启动失败问题。
  • 修复STM32外围滤波电容接地问题。

20240409_V1.0

  • 项目首次发布,基本功能实现,完成验证。

硬件设计

硬件框图.png
主控:STM32F407ZG

​ 选用这款微控制器,是因为STM32F4系列提供了出色的计算能力和实时响应能力。可以为项目中摄像头、屏幕、存储卡、热敏打印头、电池管理、按键控制等提供足够的IO支持及资源支持。

屏幕:2.8寸TFT液晶屏

​ 这款2.8寸的屏幕采用240*320的分辨率,尺寸小巧的同时也能提供不错的显示效果。通过FSMC连接STM32控制器,简化了电路设计和布线,降低了系统成本和复杂度。

摄像头:OV2640摄像头模组

​ 这款200万像素的摄像头,不仅具有极高的性价比,而且完全满足本项目的图像采集需求。通过DCMI连接STM32控制器,提供了高速的数据传输能力。

热敏打印头:精芯 JX-700-48R

​ 设计一款拍立得设备,图像的打印是关键,不仅要体积小巧、重量轻,还要功耗低,而热敏打印就是不错的选择。

电池管理:TP4056

​ TP4056采用恒定电流/恒定电压(CCCV)充电模式,能够自动完成整个充电过程,包括涓流预充、恒流快速充电和恒压充电阶段,有效保证电池的健康和长寿命。

软件设计

软件界面:

PIC0001.png

受篇幅限制,这里只针对部分关键代码进行讲解。

热敏打印功能实现:

当系统检测到打印键按下时,将获取当前图片的路径,并调用如下函数,此函数用于从给定路径读取一个BMP图像文件,并将其转换为热敏打印机的数据格式进行打印。

static void PrintFile(char *path)
{
    FRESULT res;
    FIL file;                                               // 文件对象
    UINT br;                                                // 实际读取的字节数
    uint16_t line = 0;                                      // 当前打印行号
    uint16_t lineDateTemp[384];                             // 文件内容缓存,保存一行图片数据
    res = f_open(&file, path, FA_READ);
    if (res != FR_OK) 
    {
      printe("文件打开失败\n");
    }
    
    /* 从bmp头 获取图片信息 */
    BITMAPINFO hbmp;        
    res = f_read(&file, &hbmp, sizeof(BITMAPINFO), &br);
    if (res != FR_OK) 
    {
      printe("文件读取失败\n");
    }
    uint32_t bfOffBits = hbmp.bmfHeader.bfOffBits;        // 位图数据偏移量
    uint16_t w = hbmp.bmiHeader.biWidth;                  // 图象的宽度,以象素为单位
    uint16_t h = hbmp.bmiHeader.biHeight;                 // 图象的高度,以象素为单位
    printi("位图数据偏移量:%d,宽度:%d,高度:%d。\n",bfOffBits,w,h);

    f_lseek(&file, bfOffBits);                            // 移动文件指针跳过bmp文件头
    memset(lineDateTemp, 0xFF, sizeof(lineDateTemp));     // 行数据点默认为白色
    do{
      res = f_read(&file, lineDateTemp, w*2, &br);        // 一次读取1行像素,16bit,一个像素2个字节
      if(w < 384)                                               // 图片宽度小于打印宽度
      {
        memmove(lineDateTemp + (384 - w)/2, lineDateTemp, w*2); // 数据整体移动,使图像保持居中
        memset(lineDateTemp,0xFF, (384 - w)/2);                 // 填充白色
      }
      if(res != FR_OK)
      {
        printf("文件读取失败\n");
        break;
      }
      uint8_t printLine[48];                                     // 一行打印数据48字节DotS
      for(uint16_t i = 0;i < 384;i+=8)                           // 对当前 DOT点 进行处理,打印宽度
      {
        uint8_t packedByte = 0;                                  // 将8个二值化像素合并为一个字节
        for(uint8_t j = 0;j < 8;j++)                             // 3.将8个二值化后的像素(每个像素1位)合并成一个字节
        {
          uint8_t gray = RGB565ToGray(lineDateTemp[384 - i - j]);// 1.RGB565格式转灰度图,uint16_t => uint8_t
          packedByte |= GrayToBinary(gray, 127) << (7 - j);      // 2.根据灰度值设定阈值进行二值化处理,阈值为128
          if(j == 7)
          {
            printLine[i/8] = packedByte;                         // 4.将处理好的数据添加到打印数组,等待打印
          }
        }
      }
      printf("打印line%d\n",line);
      LinePrint(printLine);
      if (res != FR_OK) 
      {
        printf("f_lseek err\n");
      }
      line++;
    }while(br > 0);

    PrinterStep(80);//打印完成的出纸长度
    StopPrint();
    f_close(&file);
}
// RGB565转灰度
uint8_t RGB565ToGray(uint16_t rgb565)
{
  uint32_t gray;
  uint8_t r = (rgb565 >> 11) & 0x1F; // R 5 bits
  uint8_t g = (rgb565 >> 5) & 0x3F;  // G 6 bits
  uint8_t b = rgb565 & 0x1F;         // B 5 bits

  gray = (r*30*8 + g*59*4 + b*11*8 + 50) / 100; // 注意,这里使用的是近似的人眼感知权重:R*30%, G*59%, B*11%。加50是为了四舍五入。
  return (uint8_t)gray;                         // 确保结果在0-255范围内,尽管这里计算的结果自然就在该范围内
}
// 二值化处理
uint8_t GrayToBinary(uint8_t gray, uint8_t threshold) {
    return (gray >= threshold) ? 0 : 1;
}

结构设计

拍立得.jpg

结构文件截图.png

实物展示

IMG_20240608_092451_mini.jpg

IMG_20240608_092306_mini.jpg

物料采购

可下载附件中的表格

image.png

设计图

未生成预览图,请在编辑器重新保存一次

BOM

暂无BOM

3D模型

序号文件名称下载次数
暂无数据

附件

序号文件名称下载次数
1
4.结构设计.zip
3942
2
固件程序.zip
1089
3
演示视频.mp4
678
4
物料采购.xlsx
836
克隆工程
添加到专辑
0
0
分享
侵权投诉
知识产权声明&复刻说明

本项目为开源硬件项目,其相关的知识产权归创作者所有。创作者在本平台上传该硬件项目仅供平台用户用于学习交流及研究,不包括任何商业性使用,请勿用于商业售卖或其他盈利性的用途;如您认为本项目涉嫌侵犯了您的相关权益,请点击上方“侵权投诉”按钮,我们将按照嘉立创《侵权投诉与申诉规则》进行处理。

请在进行项目复刻时自行验证电路的可行性,并自行辨别该项目是否对您适用。您对复刻项目的任何后果负责,无论何种情况,本平台将不对您在复刻项目时,遇到的任何因开源项目电路设计问题所导致的直接、间接等损害负责。

底部导航