基于ATtiny85轻松制作一款智能手表

发布者:Jinyu521最新更新时间:2022-07-28 来源: csdn关键字:智能手表  OLED 手机看文章 扫描二维码
随时随地手机看文章

这是基于ATtiny85系列的简约手表系列中的第三款。该款手表通过在微型64x48 OLED显示屏上绘制模拟的手表来显示时间。它使用独立的晶振控制的低功耗RTC芯片来保持每月几秒钟的时间,并在不显示时间的时候将处理器和显示器置于睡眠状态,以便使得使用寿命超过一年。


当按下手表表面上的按钮时会显示时间,并且会在显示屏上显示模拟的手表,并且带有一个移动的秒针。 30秒后显示屏将自动变暗,以保持电池的使用寿命。


简介

这款手表基于Maxim Integrated的DS2417 RTC芯片,该芯片采用一个小型6脚封装,使用32.768 kHz晶振来保持精确的时间。它可以通过1线接口与主控制器ATtiny85进行通信,该接口仅使用一个I/O引脚来发送和接收数据。因为RTC芯片主要工作是计时,ATtiny85在其不需要实际显示时间时可以在掉电模式下保持睡眠,从而大大降低了功耗。


该显示器使用一个SPI接口的小型单色64x48 OLED显示屏,具有可从Aliexpress购买,或可从Sparkfun购买类似的。显示器需要4个引脚驱动,ATtiny85刚好满足应用要求,剩余一个引脚用于1-Wire接口。您不能读取显示内存,因此要做图形,您需要写入RAM中的缓冲区,然后将其复制到显示器上。因为显示器是64x48像素,因此它需要68x48 / 8或384字节的存储器用于图形缓冲区,这也刚好在ATtiny85的能力之内。


现在显示屏变暗的总功耗约为8μA,单个CR2016电池估计超过一年的电池寿命。


电路

以下是Tiny Face手表的电路:



晶振是标准的32.768 kHz石英表晶体; Maxell指定6pf负载电容,我选择了一个MS1V-T1K晶振,其优点是可以焊接到板上,但我预计任何手表晶振都是可以的。


按钮采用的是广泛使用的微型SMD触觉开关,通常用作处理器电路板上的复位按钮。 使用了一个33kΩ电阻和0.1μF电容,确保在首次施加电源时显示屏能正常复位。


电池是一个20毫米的纽扣电池。鉴于电流消耗低,我决定使用更细小的CR2016电池,并在Mouser找到了合适的SMD电池座。或者,您可以使用CR2032电池,可以从Sparkfun购买SMD 20mm电池座。


表带需要是12mm的螺纹穿透型,我发现了一个德国的供应商。我也尝试过英国的供应商这种比较便宜的替代品,但是请注意这个会更短,如果你手腕比较小,这个表带可能不适合。


装配

对于这个项目,我使用了Seeed Studio的PCB服务,并选择蓝色PCB来匹配显示。这是布局:



手表使用SMD组件,所有组件与电池座分开焊接到电路板前面。我使用SOIC ATtiny85和0805电阻和电容,所以他们应该比较容易用手焊接。 DS2417 RTC芯片采用TSOC封装,可能是最难焊接的元件,因为它的引脚位于封装下面。


我在250°C使用Youyue 858D +热风枪将SMD组件焊接到电路板的前面,然后使用传统的烙铁将电池座焊接到电路板背面。如果没有热风枪,您可以使用细小的烙铁焊接SMD组件。


以下照片显示了安装显示屏前电路板的前面,安装显示屏的电路板和电路板的背面:



我建议在将显示器安装在电路板上之前先测试电路板。您可以通过显示器的7针连接器访问除RST之外的ISP编程所需的所有ATtiny85引脚。


程序

本节将介绍Tiny Face Watch程序的各个部分。


1-Wire接口


为了与RTC进行通信,我使用了简单的1线接口。它将RTC中的五个字节数据读入数组DataBytes [5]。第一个字节是一个配置字节,最后四个字节给出一个长整数的秒数;为了更容易理解,我定义了一个联合体,所以时间字节可以使用类似rtc.seconds进行访问:

  1. static union {

  2.   uint8_t DataBytes[5];

  3.   struct {

  4.     uint8_t control;

  5.     long seconds;

  6.   } rtc;

  7. };


显示

显示采用的是OLED。时钟表面是使用图形命令绘制线,并且这些都编辑一个缓冲区,该缓冲器为显示器上的每个像素存储一个位。这定义如下:

  1. // Screen buffer

  2. const int Buffersize = 64*6;

  3. unsigned char Buffer[Buffersize];


一旦将时钟面绘制到缓冲区中,DisplayBuffer()函数将字节复制到显示器中即可显示缓冲区的内容:

  1. void DisplayBuffer () {

  2.   PINB = 1<

  3.   // Set column address range

  4.   Command(0x21); Command(32); Command(95);

  5.   // Set page address range

  6.   Command(0x22); Command(2); Command(7);

  7.   for (int i = 0 ; i < Buffersize; i++) Data(Buffer[i]);

  8.   PINB = 1<

  9. }


SSD1306可以处理高达128x64的显示,64x48显示位于该区域的中心,因此要解决此问题,您需要选择第32至95列(含)和第2至7页(含)。


画时钟

DrawClock()函数绘制时钟面和表针位置指定的时间,以小时、分钟和秒为单位。使用了’几个技巧来避免需要三角函数,并最小化所需的乘法和除法次数。该程序基本上执行以下迭代程序360次以生成圆上的点:

  1. x = x + Delta * y;

  2. y = y-Delta * x;


其中Delta为弧度1度。使用定点运算通过存储它们乘以因子2 ^ 9来计算x和y的值

  1. void DrawClock (int hour, int minute, int second) {

  2.   int x = 0; int y = 23<<9;

  3.   for (int i=0; i<360; i++) {

  4.     int x9 = x>>9; int y9 = y>>9;

  5.     DrawTo(x9, y9);

  6.     // Hour marks

  7.     if (i%30 == 0) {

  8.       MoveTo(x9 - (x9>>3), y9 - (y9>>3));

  9.       DrawTo(x9, y9);

  10.     }

  11.     // Hour hand

  12.     if (i == hour * 30 + (minute>>1))

  13.       DrawHand(x9 - (x9>>2), y9 - (y9>>2));

  14.     // Minute hand

  15.     if (i == minute * 6 + second/10) DrawHand(x9, y9);

  16.     // Second hand

  17.     if (i == second * 6) {

  18.       MoveTo(0, 0);

  19.       DrawTo(x9, y9);

  20.     }

  21.     // Border of clock

  22.     MoveTo(x9, y9);

  23.     // if (x9 > 0) DrawTo(23, y9); else DrawTo (-23, y9);

  24.     x = x + (y9 * Delta);

  25.     y = y - ((x>>9) * Delta);

  26.   }

  27. }


它调用DrawHand()将绘制菱形小时和分针从0、0绘制到x,y:

  1. void DrawHand (int x, int y) {

  2.    int v = x/2; int u = y/2;

  3.    int w = v/5; int t = u/5;

  4.    MoveTo(0, 0);

  5.    DrawTo(v-t, u+w);

  6.    DrawTo(x, y);

  7.    DrawTo(v+t, u-w);

  8.    DrawTo(0, 0);

  9. }


线绘制由DrawTo()线绘图程序执行,它使用Bresenham线算法在两点之间画出最佳线,而不需要任何分割或乘法:

  1. void DrawTo (int x1, int y1) {

  2.   int sx, sy, e2, err;

  3.   int dx = abs(x1 - x0);

  4.   int dy = abs(y1 - y0);

  5.   if (x0 < x1) sx = 1; else sx = -1;

  6.   if (y0 < y1) sy = 1; else sy = -1;

  7.   err = dx - dy;

  8.   for (;;) {

  9.     PlotPoint(x0, y0);

  10.     if (x0==x1 && y0==y1) return;

  11.     e2 = err<<1;

  12.     if (e2 > -dy) {

  13.       err = err - dy;

  14.       x0 = x0 + sx;

  15.     }

  16.     if (e2 < dx) {

  17.       err = err + dx;

  18.       y0 = y0 + sy;

  19.     }

  20.   }

  21. }


设定时间

当您首次向手表供电时,它将检查MCUSR寄存器以检测上电复位,并运行SetTime(),以允许您将时间设置为最接近的秒数。它的工作原理如下:


等待当前时间是一分钟,然后插入电池。手表将从12:00开始,一次逐步显示一分钟。当手表显示插入电池的时间(而不是当前时间)时,按复位按钮。手表将占用您设置时间的额外秒数,并显示当前时间。它现在可以使用了。


SetTime()例程将变量secs递增300,相当于五分钟,显示步骤之间的秒数。在每个步骤中,它将值的值写入RTC,其中添加了一个偏移量,用于计算自启动过程起经过的时间。

  1. void SetTime () {

  2.   unsigned long Offset = millis();

  3.   unsigned long secs = 0;

  4.   for (;;) {

  5.     int Mins = (unsigned long)(secs / 60) % 60;

  6.     int Hours = (unsigned long)(secs / 3600) % 12;

  7.     // Write time to RTC

  8.     rtc.control = 0x0C;

  9.     rtc.seconds = secs + ((millis()-Offset)/1000);

  10.     OneWireReset();

  11.     OneWireWrite(SkipROM);

  12.     OneWireWrite(WriteClock);

  13.     OneWireWriteBytes(5);

  14.     ClearBuffer();

  15.     DrawClock(Hours, Mins, -1);

  16.     DisplayBuffer();

  17.     unsigned long Start = millis();

  18.     while (millis()-Start < 500);

  19.     secs = secs + 60;

  20.   }

  21. }


显示时间

ATtiny85通常处于睡眠模式,可忽略不计的电流。按钮连接到复位输入端口,该引脚唤醒处理器并产生复位。


主程序loop()首先读取RTC的时间到变量secs:

  1.   OneWireReset();

  2.   OneWireWrite(SkipROM);

  3.   OneWireWrite(ReadClock);

  4.   OneWireReadBytes(5);

  5.   OneWireReset();

  6.   secs = rtc.seconds;


然后计算变量Hours、Mins和Secs的值,并显示一个动画时钟,直到SleepTime过去(30秒):

  1. int Mins = (unsigned long)(secs / 60) % 60;

  2.   int Hours = (unsigned long)(secs / 3600) % 12;

  3.   int Secs = secs % 60;

  4.   unsigned long Start = millis();

  5.   unsigned long Now = Start;

  6.   while (Now-Start < SleepTime) {

  7.     ClearBuffer();

  8.     DrawClock(Hours, Mins, (Secs + (Now-Start)/1000) % 60);

  9.     DisplayBuffer();

  10.     Now = millis();

  11.   }

  12.   DisplayOff();

  13.   digitalWrite(dc,HIGH);

  14.   digitalWrite(clk,HIGH);

  15.   digitalWrite(data,HIGH);

  16.   digitalWrite(cs,HIGH);

  17.   pinMode(OneWirePin, OUTPUT); digitalWrite(OneWirePin,HIGH);

  18.   sleep_enable();

  19.   sleep_cpu();


然后熄灭显示屏,并将处理器设置成睡眠状态以最小化功耗。


其他选项

时钟面只占据显示屏中间的48x48像素,因此在显示屏的每一侧有两个8x48像素的区域,可用于显示其他信息。例如,您可以使用ATtiny85上的温度传感器来测量环境温度,并以图形显示方式将其显示在显示屏的一边。


编译程序

我使用Spence Konde的ATTiny Core编译了这个程序。在Boards菜单的ATtiny Universal标题下选择ATtinyx5 series选项。然后在子菜单下选择Timer 1 Clock: CPU, B.O.D. Disabled, ATtiny85, 8 MHz (internal)。


我使用Sparkfun的Tiny AVR编程板编程ATtiny85。选择Burn Bootloader设置合适的保险丝位,然后上传程序


关键字:智能手表  OLED 引用地址:基于ATtiny85轻松制作一款智能手表

上一篇:基于ATtiny841通过I2C总线连接GPS模块
下一篇:使用AVR微控制器控制GSM模块实现发送和接收短信

推荐阅读最新更新时间:2024-11-11 11:23

新一代谷歌眼镜将配备OLED微型显示屏
    摘要: 日前有消息显示,谷歌新一代的Google Glass测试组件将将采用一家名为“Crystal Optech”的公司所生产的配件。据最新报告显示,新一代谷歌眼镜将采用OLED显示屏,有别于目前版本所使用的LCoS显示屏。谷歌眼镜的现有显示屏供应商为Himax,这家公司早在2013年就已经被谷歌公司所收购。而据悉全新的谷歌眼镜将采用一家名为“MicroOLED”公司所生产的高分辨率OLED显示屏。     目前版本的谷歌眼镜售价为1500美元(约合人民币9400元),就在最近谷歌眼镜开放了谷歌浏览器程序。不过需要说明的是,现阶段所推出的版本仅仅针对于开发人员,而针对普通用户、支持谷歌浏览器的谷歌眼镜还没有推出市
[家用电子]
3D玻璃盖板是火花&火坑?
  在去年十月份,李星曾写过一篇《苹果双玻璃太厉害,高端盖板缺货,3D玻璃干脆熄火了》的文章,当时李星认为苹果的两家盖板供应商不但因为iPhone8系列和iPhoneX的玻璃后盖板订单增加,饱受缺工之苦,还因为磨合新增产能扩张而添加的设备,同样费尽了心思。下面就随网络通信小编一起来了解一下相关内容吧。   另外一个受到沉重打击的就是3D曲面玻璃盖板,苹果的两家玻璃盖板供应商,都去生产苹果的订单了,原来的 3D玻璃盖板 产能应付三星的订单都有困难,那还有余力去接国产手机的订单。去年上半年还热炒的3D曲面玻璃盖板,到第三季度后期,突然就熄火了!即没有主力出货的手机机型宣布采用,行业里也没有了那种3D曲面玻璃要一统高端机型天下的声音了
[网络通信]
首尾难兼顾!富士康两大面板厂建造均陷困境
近日,鸿海在美国威斯康辛州生产面板计划或生变的消息被热议。而在此时,又传来富士康广州面板厂计划也暂缓的消息。无论实际情况如何,在世界两端同时推进共价值200亿美金规模的建造工程让鸿海有些首尾难顾。    广州   据《日经新闻》报道,消息人士透露,富士康斥资人民币 610亿元的中国广州面板厂计划,也将推延至少6个月。   广东省省长马兴瑞1月28日作人民政府工作报告时指出,以重大产业项目建设带动工业投资,扎实抓好富士康广州10.5代线、广州乐金OLED、深圳华星光电11代线等项目建设。可见,富士康面板项目备受重视。   2016年年底,富士康与夏普的合资公司SDP与广州市政府签署协议,在广州增城投资610亿元人民币,建设1
[家用电子]
首尾难兼顾!富士康两大面板厂建造均陷困境
LG Display推出55英寸可弯曲OLED电视
    5月20日下午消息,液晶显示屏制造商LG Display在加拿大举办的2013年国际信息显示协会显示周(SID)上展出了采用WRGB OLED技术的55英寸可弯曲OLED电视和5英寸塑性OLED屏幕,显示了LG Display在电视和移动设备上新一代显示技术布局。    55英寸可弯曲OLED电视成亮点   LG Display此次展品涵盖电视和移动设备两个方面,均以OLED产品为主,不难看OLED已经确定成为LG Display下一代关键显示技术。其中亮点产品是55英寸可弯曲OLED电视和智能手机用5英寸塑性OLED面板。据悉,展出的采用WRGB技术的55 英寸OLED电视已经投入量产。   而针对移动设备推出的5
[家用电子]
Moto360智能手表续航出色 可待机超过两天半
    Moto360无疑成为目前最受期待的智能手表,不仅仅是其搭载的Andriod Wear操作系统,闪亮酷炫的外形也为让不少网友为之着迷。现在Moto360另一个亮点也曝光——续航,据外媒消息称这款手表的待机将超过两天半,出乎意料。 Moto360续航更出色 可待机超过两天半   来自Viscardi的消息,他们称已经得到了Moto 360的原型机,并表示Moto 360的电池续航要比LG G Watch好2.5倍,而LG G Watch很难坚持一天,这意味着Moto 360的续航时间会在两天半左右。   事实上Moto360还支持无线充电技术,也就意味着我们将不需要在续航上为这款智能手表担心多少,有这点顾虑的用户其实
[手机便携]
京东方目标明年为iPhone 15 Pro生产OLED面板
消息人士称,京东方已经设定了明年为iPhone 15 Pro系列生产OLED面板的目标,公司希望通过在OLED面板上成功应用LTPO技术来实现这一目标,将在重庆的最新工厂B12生产OLED面板。 据TheElec报道,目前为止,京东方仅为较低端的iPhone供应6.06英寸OLED面板,去年供应量达到1500万至1600万部OLED面板,远高于预期。公司还将为今年秋季推出的iPhone 14系列标准机型提供同样的面板。苹果预计今年将出货2亿部OLED iPhone,而京东方将为其中的20%(4000万-5000万部)供货。 同时,京东方在去年第四季度开始了重庆B12的第一阶段运营。该工厂是京东方第三代Gen 6(1500x1850
[手机便携]
LG V30正式发布:全面屏新旗舰
LG正式发布了旗下最新的V系列新机——LG V30,该机搭载了OLED全面屏,取消了副屏的设计,还搭载了LG最引以自豪的后置双摄像头。   LG V30正面搭载了一块6英寸P-OLED QHD(2880*1440)显示屏,屏占比高达82%,高宽比为18:9,支持HDR10,另外也支持常显模式。其它配置方面,该机搭载骁龙835处理器,辅以4GB RAM+64GB/128GB ROM,支持外置存储卡扩展。   摄像头是V30的另外一大卖点,该机后置1600万像素f1.6大光圈主摄像头+1300万像素120度广角摄像头,广角摄像头的光圈也达到了f1.9,前置500万像素自拍摄像头。   LG V30搭载了3300mAh不可拆卸电池,
[手机便携]
LCD电视面板价格持续上涨,OLED电视加速成主流
近期LCD电视面板价格持续上涨,其与OLED面板的差价正逐渐缩小。在这一趋势下,OLED面板有望加速取代LCD面板,成为电视市场的主流。 据MoneyDJ报道,市场研究公司Omdia于3月7日发布最新报告指出,今年2月份,32英寸至65英寸LCD面板价格较2020年同期增加约4.5%。其中,55英寸4K LCD面板均价从182美元涨至191美元,而65英寸LCD面板的均价也从去年同期的170美元大幅提升至242美元。 自2020年下半年以来,LCD面板市场一改之前供应过剩的情况转向供不应求,部分原因在于疫情催生居家趋势,推动电视销量快速攀升。另外,面板驱动IC(DDI)生产未能赶上电视市场需求,进一步推高了LCD面板价格。 与
[手机便携]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved