礼品工程



窗外正在下雨,日历是十二月。 假期临近了,因此送礼的时间到了。 帕维尔(Pavel)同事想要一个新的笔记本电脑,女友玛莎(Masha)想要在海边有一所房子。 尽管“ tyzhprogramist”这个职业的薪水很可观,但我们并没有生活在一个无穷无尽的世界中,这意味着我无法给这些人确切的需求(即使Pasha可能是我最好的Pavel,我知道,但是Masha很好)。

这就是“廉价礼物”出现的地方。 不能给每个人昂贵的礼物,但我不想再送一盒巧克力,蜡烛或模糊的小雕像。 因此,您需要将商务与愉悦相结合-我喜欢用自己的双手去做事情,作为礼物,结果很棒。 这是一个关于我如何再次假扮成工程师并手工制作几件礼物的故事。

与主要主题略有不同


我无法立即进入主要主题,因此我将从头开始。 几年前,发布了游戏《巫师3》。 我的朋友建议我玩游戏,总的来说,我真的很喜欢这款游戏。 然后,我决定要怎么做,并给她一些与游戏有关的主题...我不会太过深入地描述游戏(Google会帮助所有人),或者说我想到的东西不多关键字“巫师,工程师,礼物”。

游戏的主要角色是一匹名为“ Roach”的马(俄语配音),英雄不时用“ Move,Roach”这个短语来驱使她。 我决定以“旋转蟑螂”为主题制作机械玩具。

自然,礼物被认为是完全没用,愚蠢但有趣的事情,因此计划如下:

  1. 有一个框本身隐藏了该机制。
  2. 该机构是轴,马正在旋转。
  3. 马运动的最大“坚韧”是值得欢迎的。 最初,甚至认为马应该像鱼一样运动,而不是像马一样运动(毕竟是蟑螂),但结果是“介于两者之间”。
  4. 所有这些将由胶合板完成,根据图纸可以使用激光将其精确切割成订单。

选择材料的主要缺点以及将按订单切割的事实是我失去了创建原型的机会,这意味着弯曲的手和不遵守“七次测量”规则的所有问题使他们很快感到自己:



尽管最后,由于间隙过大而造成的间隙机构的许多细节,实际上弥补了我弯曲零件和轴的事实。 正如他们所说,在这里,“负号减去正号”,并且该机制作为一个整体起作用了:



之后只画了一点画,结果是一个盒子:



然后有人会说有必要使盒子透明,以便可以观察内部的工作,但是实际上我最初猜测我不能从内部组装整齐干净整洁的机械装置和盒子,以免伤害内部透过盒子的透明墙壁看。 因此,不透明的盒子是必要的措施。

它只剩下包装,在盒子上系蝴蝶结,礼物就准备好了:



但是为了不让内心的孩子感到不安,在我实际上胶合了几块胶合板的情况下,想要像工程师一样的内心孩子,我决定进行一次“绘画”。 原谅我所有理解技术图纸知识的人,因为 我了解这比真实绘画更像是对绘画的模仿,但在我看来,他为一个简单的玩具增加了价值:



今天我...


有时命运与我们一起玩耍,并以某种方式暗示即将发生某些事情。 我的一台设备的故事开始时完全一样。 我订购了一些价值约5美元的小型电子产品,像往常一样,这条电子产品在路上花费了一个月,之后我收到一条短信,说包裹正在当地邮局等我。 那个盒子竟然比我预期的要大得多,并立即引起人们对其内容的怀疑。 怀疑得到了证实-在内部,除了我订购的小东西之外,还有一个三色电子墨水显示屏,对角线为4.2英寸。 我联系了卖家,他确认他在打包时弄乱了东西,但说我可以认为这是一件礼物,可以视需要使用。

命运向我暗示开始新项目的时间到了,这个项目将带有电子墨水显示屏。 在简短地熟悉了设备的规格并将显示器连接到控制器之后,我确保有关更新时间的规格对我没有影响。 屏幕更新了10秒钟以上,闪烁并试图引起我癫痫病发作:


(我没有连接显示器的早期照片,因此这里的设备已经具有更有意义的外观)

显然,您需要一个不需要复杂动画(以及一般动画)的简单设备。 然后我遇到了一个情绪日历:


心情日历是一组简单的图片和具有讽刺意味的签名。 我决定要制作一个名为“ Today I”的日历(实际上根本不是日历)……这将是一个简单的设备,每天显示一些表征当今“心理状态”的图像并对其进行描述。 此外,日历还可以具有其他功能,但是主日历恰好是“日历”-每天都有自己的图片。

电子纸模块允许显示三种颜色(黑色,红色和白色),应将其传输到模块,就像两张图片一样-黑色和白色以及红色和白色。 实际上,如果说屏幕只需要一个单色位图,那将是更正确的,每个位都决定一个像素的颜色(我不确定这个术语是否适用于电子纸,但我希望这个想法很清楚)。 可以为黑色或红色通道设置单独的位图。 因此,存在一组字节,其中设置为1的每个位将对应一个彩色像素,而所有保持0的位将是屏幕上的白色像素。 屏幕分辨率为400 x 300像素,即 对于黑白图片,将需要15,000个字节(在一个字节中编码8个像素)。 对于这三种颜色,如果不尝试将图片压缩得更紧凑,则将占用30,000个字节。 从实现的角度来看,显示器的创建者可以简单地选择每个像素两位,并存储事物的真实状态(红色为黑色,白色为白色),但这将需要相同的30,000字节,即使对于单色图像也是如此。将需要传输30,000个字节。

就像在我的其他“手工艺品”中一样,我开始为自己发明任务,以使一切都不会变成“插入接线并下载库”。 即使我们考虑了在控制器端实现某种图像压缩算法的能力,也很明显,如果没有用于图像文件的外部存储,控制器将非常沮丧。 决定使用SD卡并编写一个简单的代码包装器以使用FAT32。 当然,没有文件系统也可以直接将数据写入存储卡中,但是在我看来添加新文件不太方便,并且用自己的双手实现使用FAT32的基本操作对我来说很有趣。

重要的是要澄清我在做此类事情时会自己写东西的习惯(您不应该告诉我,我和Google都知道有很多图书馆),但是因为 在此之前,我不喜欢低级使用FAT32,这是一个相当有趣的过程。

我将不详细讨论使用FAT32和整个SD卡的细节。 互联网上充斥着有关该主题的文章(我不想将自己的故事变成规范的重述),但是我将谈论一些需要实现的事情。 不仅要实现从文件读取和写入文件的功能(我决定将某些设置和条件存储在同一SD卡上,而不是存储在EEPROM中),而且还需要实现在文件系统中搜索文件的功能(如果需要使用)以通常的方式

存储卡上的所有数据都被划分为簇(FAT32文件系统中的主要可寻址单元),并且簇已被划分为多个扇区。 为了从FAT32中的SD卡读取文件“ habr.txt”,您需要:

  1. 初始化存储卡。
  2. 读取零地址处的扇区,并检查FAT32文件系统是否具有特定的标头(如果我们认为运气好的话,可以跳过此步骤)。
  3. 读取地址零处的扇区并获得“逻辑块寻址”(LBA)。
  4. 读取接收地址(LBA)处的扇区,并从中获取必要的数据(哪个群集是根-根目录,群集中有多少扇区,等等)。
  5. 按编号读取“根目录”群集(实际上,读取是按扇区完成的,您只需要读取与该群集中的扇区一样多的扇区)即可。 它具有自己的公式,可以将群集序列号转换为物理地址。 文件信息存储在此处,因此我们在搜索所需文件时读取数据。 关于文件名还有一点琐事:文件名可以短也可以长,取决于此,数据存储在一个位置(相同结构)或其他记录中,还必须分别读取。 当找到具有所需名称的文件时,我们将获得其起始位置所在的群集(或者如果整个文件适合群集大小,则可能是整个文件)以及文件大小。 如果在此群集中找不到文件,则我们搜索下一个群集并重复文件搜索过程。
  6. 在找到的地址处读取群集。 并继续进一步读取群集,并寻找下一个群集,直到读取完所有数据为止。

在我看来,将文件系统的原理告诉那些至少已实现一次链接列表的人比较容易,因为 实际上,FAT32文件系统是一组数据块和一种表,该表指示在哪里寻找下一个数据块。 从FAT32读取任何数据都是一个过程,我们在其中读取数据,查找下一个块的地址,读取数据,查找下一个块的地址,等等。

我并未实现所有可能的方案,并简化了一些内容:

  • 所有文件都位于存储卡的根目录,并且不使用目录浏览。
  • 所有文件都有短名。
  • 启动时,控制器读取文件列表并将其存储在内存中,以免再次搜索每个文件。
  • 文件的最大数量受一个常量限制(实际上,我只绘制了几十个图像)。

简而言之,以上所有都是有说服力的理由,因为它采用了现成的库,而没有花费大量时间阅读文档,开发和调试。 我建议自己仅出于教育目的或“为了娱乐”而实施此类事情。

该显示还施加了一些限制,例如 它上的任何图像都以这种方式显示:

  1. 我们唤醒并初始化显示器(为了延长其寿命并节省能源,显示器基本上处于睡眠状态)。
  2. 我们公开了必要的通道(例如,黑色)。
  3. 我们转发图像的15000字节。
  4. 我们公开了必要的渠道(例如红色)。
  5. 我们转发图像的15000字节。
  6. 我们告诉显示器从缓冲区中提取数据。
  7. 我们等到显示完成绘制。
  8. 我们告诉显示器入睡。

对于单色图像,可以跳过步骤4和5。对于三色图像,黑白和红白色图像的传输顺序并不重要,因为 红色始终涂在黑色上,黑色仅涂在白色上,并且只有像素保持白色,即白色,黑色和白色以及红色和白色。

为了简单起见(以免增加文件总数),我决定将黑白图像和红白色图像存储为单个文件,黑白图像后紧跟着红白色:



比较这些图像的结果是这样的(在我看来,我们每个人至少一生中都像一只有角的鹿-一条腿):



实际上,这两个图像后面是另一个包含状态描述的图像(通过单击按钮,您可以获得与今天显示的图片匹配的描述)。

由于控制器的内存有限,因此永远不会将存储卡中的数据完全读取到控制器的内存中。 从存储卡中读取的图像将按扇区大小确定片段(为简单起见,我们假定此大小始终是静态的,不能随卡的不同而变化),并且属于处理卡中数据的过程。 在我的实现中,读取文件的功能将输入的簇号,文件大小和要读取的每个扇区“拉回”的回调作为输入。 这种方法使我们能够使用文件处理的几种不同功能来读取和显示图像本身或其描述。

因此,以下逻辑属于从存储卡读取图像的回调函数:

  1. 在将数据发送到显示器之前,设置所需的通道(该通道是随机确定的)。
  2. 当前一个通道的数据发送完成时,请跟踪传输的数据以切换通道。
  3. 发送从卡接收的数据。
  4. 确定已发送了必要的数据,并且可以忽略其余数据(带有说明的图像)。

我决定输入包含比屏幕上应显示的更多数据的图像,这使情况变得复杂。 即 有一些图片,它是背景,并且始终是静态的,并且与屏幕的大小相对应,并且还有一张更大的图片,您需要从中取一个随机区域(屏幕的大小)并进行显示。

这样的图像对处理程序提出了额外的要求-必须计算从屏幕的当前行传输了多少个字节,在下一次调用时需要增加多少个字节(如果该行位于扇区大小的边界上)以及应该跳过多少个字节。

在视觉上,这种情况可以显示如下:



有一个特定缓冲区,其中有一个所需大小的“窗口”(绿色部分),您只需要从此窗口读取数据,就可以从缓冲区中读取N个字节的数据。 可以将这样的阅读过程形象化:



通常,要将屏幕处理逻辑添加到始终接收512字节缓冲区的功能中,并且应该确定需要使用这512字节中的哪一个(如果确实需要某些内容),并不是一件容易的事“在额头上”。 更确切地说,与日常解决方案相比,该任务没有非标准那么复杂,因此,令人惊讶的是,解决它非常有趣。 对我来说,这就像一个“奥林匹克运动”,需要计算收缩肌肉所需的电量,以便用两把汤匙(每只手一汤匙)将水从一个桶中转移到另一个桶中。

为了更好地理解这里存在的困难,我将在此处添加另一个动画,仅“根据”集群的内容而不是整个文件的内容(所有其他信息需要单独存储):



按照计划,日历应每天显示一个新图像,即 它必须能够监视时间(即使关闭时),这意味着还需要一个实时时钟模块(RTC)。 尽管我的控制器具有内置的实时时钟,但几乎不可能为其接起电池,因为 触点未连接到板上。 我决定不强奸控制器的腿以试图焊接到他们的身上,并选择了外部中文RTC。 使用RTC的工作应该是完全简单的:

  • 打开时,从中文RTC获取时间。
  • 在内部RTC中设置时间。
  • 使用内部RTC来计算时间,直到下一次关机之前,您都不会忘记中文。

但是在这里,一切都不是那么简单,因为控制器的内部RTC以常规格式(UNIX时间戳)与时间一起工作,并且其中文朋友使用二进制编码的十进制(BCD)。 在此之前,我没有遇到过这种格式,甚至对于Arduino的现代模块都使用它,我感到非常惊讶。 格式的本质非常简单-只有一个字节,例如,存储秒数。 四个高位存储十,四个低位存储单位。 事实证明,此字节本身的十六进制表示形式包含可读时间-字节0x49对应于49秒的值(尽管在十进制系统中,此字节对应于72)。

据我了解,它发生的历史如此之久,以至于直接将RTC与屏幕编码器一起使用来创建时钟更加容易,但是我不得不用笔将BDC转换为UNIX时间戳。

除了显示器,实时时钟模块,存储卡和用于它的文件系统外,还必须将所有这些密封套包装在一个必须要制造的盒子中,即 “抽奖”。 您可以详细了解我在上一份出版物中遇到的所有痛苦,这里的内容完全相同:


(我没有计划进行批量生产,周围的所有细节都是错误的测量结果或解决方案考虑不周的结果)

结果,绘制了案例和必要的细节(图像中没有封面):



这些按钮被放置在一个单独的部分中,以便于组装(似乎我从上一个项目的时间开始还是学到了一些东西):



该装置的组装(除了前盖和后盖之外)如下所示:



显示屏通过绑带固定在箱子上。事实证明,这比螺栓连接要方便得多。

好吧,这对完美主义者来说是个地狱(电线和零件留着胡须):



原来是这样的设备,我在上面写了一本小书-说明:



后盖用螺栓固定,如果在设备内部需要进一步的暴力操作,则可以拆卸设备:



是的,在海边买房子更容易!


读完这一点的人会说:“这是简单礼物的替代品吗?!是的,您立即需要投入100500个小时的时间,这比金钱要昂贵得多!”我不会在这个话题上争论,我只是说对我来说这是一个冥想的过程,我用一块石头杀死了两只鸟-一方面,我所做的事情基本上没有人需要(很少有人会付钱给我开发一些东西这样),但是这对我来说很有趣,一个人会收到一个独特的礼物作为礼物,尽管它没有明显的负载,但是却发出微笑。

但是,为了避免需要大量时间的解决方案带来余味,我将分享一些简短的故事。

现在,一般来说,在3D打印机上打印东西已经变得非常时尚。打印设备变得更加容易使用,并且用于创建模型的软件足够简单,以使儿童能够理解。

求救


在工作中,我们开了个玩笑,那就是如果您需要帮助,您只需要大喊海鸥,肯定会有人帮助您。实际上,我不知道它的含义和玩笑的来源,但是在内部通信中,海鸥的图片经常开始出现,暗示有人需要帮助。

但是,开放式办公室和一些同事的内部谦逊使他们无法充分利用这样的机会寻求帮助。然后,一个“非工程人员”决定采取救援行动,拿出一个满载中文的“用于Arduino的MP3音乐播放器模块”,一个中文版的Arduino Nano,几根电线和几个mp3,用于录制海鸥的声音。

总的来说,在这里应该注意的是,我习惯于打折订购各种模块,在我看来,也许有一天会派上用场,或者我从朋友/熟人那里收到了这种电子产品作为礼物,他们认为这种电子产品没有用。因此,“躺着”一词并非偶然,而是非常准确地描述了事物的状态。

由于我是远离3D建模的人,因此我只是制作了一个现成的海鸥头部模型,并对其进行了必要的更改。即,根据更改,有必要:

  1. 将喙与头部分开,以其他颜色打印喙。
  2. 在所有电子设备(扬声器,播放器,arduino和电线)所在的位置做一个“空腔”。

结果是这样的(将喙分成两部分以提高打印质量):



我认为谈论代码没有意义,因为 除了初始化播放器外,还只有一个按钮单击处理程序并播放其中一个海鸥录音(通常:playSound(rand()&3);)。

之后,只需离开海鸥一起打印并收集所有东西。结果,我们有了一个成熟的“茶模拟器”(海鸥的颜色由可用的塑料决定),它连接到USB,并且当您单击海鸥头部的按钮时,它会再现“寻求帮助”:



更容易吗?


一位同事抱怨说,她在编写测试时经常分心。我们在互联网上找到眼镜的3D模型,并进行了一些小的更改:



结果,我们有了眼镜-遮光器。我们不会因自己而分心,而其他人也知道您不应分心:



很简单!


因此,创建您需要:

  1. 在矢量编辑器中查找或绘制拐杖的功能。
  2. 能够在3D编辑器中绘制2个圆柱体,一个比另一个多约0.4mm。
  3. 制作一张简单纸的能力-标签。
  4. 3D打印机(您自己或自定义的打印服务)。
  5. 打印机是普通的。

现在,为了……我们画了一个拐杖:



我们画了两个圆柱体:我们



打印零件和标签,并获得“ tyzhprogramistov”的精美礼物:



这都是为了什么?


“有时命运与我们同在,以某种方式暗示着即将发生的事情。”我一生中有好几次想实现的想法,但都在等待。如果没有来自中国的免费屏幕,我不会做电子“日历”,这意味着我什至不会处理FAT32,也不会了解RTC中使用的BCD格式。

也许有人会读这个故事(或至少看图片),然后想:“该死,如果他能做到,那么我可以做得更好!”结果,它会给附近的人带来欢乐。

窗外正在下雨,日历是十二月。假期临近了,因此送礼的时间到了。制作和接收有趣的礼物,而不仅仅是另一盒巧克力,蜡烛或小雕像。

Source: https://habr.com/ru/post/zh-CN480792/


All Articles