请选择 进入手机版 | 继续访问电脑版
返回官网官方微博

麦步社区-论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: MAI 表盘
查看: 5451|回复: 3

[表盘发布] 比特币行情也能在手表上看了

[复制链接]

214

主题

2514

帖子

3万

麦力

麦步团队

精华
1
阅读权限
200
在线时间
812 小时

麦步手表用户麦步工业测评协会

发表于 2016-7-12 10:32:56 | 显示全部楼层 |阅读模式
前阵子跟Arduino中文社区联合做了一个运营活动,是征集用麦步手表跟开源类硬件去结合做一些有意思的项目,募集到了一批大神,贡献了很多创意。

arduino.cn的 @Zoologist 拿到手表后先写了一个比特币行情的表盘来练手,以下是他的分享


我对手表有着深厚的感情,每当人生遇到坎坷时,或者愤怒不已的时候,我都会想象和安慰自己“我去年买了块表”。刚有taobao的时候,我买了一块卡西欧的太阳能手表,时至今日我还记得价格是 258元。十多年过去了,这块表的卖家已经消失,我从来没有给他更换过电池,这块手表依然行走完好。


古人云“穷玩车,富玩表”。为了体验一下富人的感觉,最近入手了一块麦步智能手表。对于这块手表,最重要的是可以写程序。于是我就尝试给他编写程序,听上去又在重复“屌丝玩电脑”。


首先通读API,了解这个手表的原理。简单的说,这块手表通过蓝牙连接,从而实现WIFI通讯。

因此,手机上也需要一直运行一个程序才能保持连接




目标是编写一个获取当前比特币行情。huobi 网提供了行情API http://api.huobi.com/staticmarket/ticker_btc_json.js 可以显示实时行情。例如:一次返回数据如下
{"time":"1467817886","ticker":{"open":4479,"vol":604962.2546,"symbol":"btccny","last":4522.79,"buy":4522.79,"sell":4523.03,"high":4612,"low":4467.64} }
其中的 last 就是当前的价格。

配合麦步手表提供的显示股票行情的代码,编写自己的程序如下:
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4.   
  5. #include "maibu_sdk.h"
  6. #include "maibu_res.h"
  7.   
  8.   
  9. /*Web通讯ID*/
  10. static uint32_t g_comm_id_web = 0;
  11.   
  12. /*Web request地址*/
  13. #define DATA_WEB     "http://api.huobi.com/staticmarket/ticker_btc_json.js"
  14.   
  15. /* 时间项 */
  16. #define DATE_TEXT_POS_X                      2
  17. #define DATE_TEXT_POS_Y                      6
  18. #define DATE_TEXT_SIZE_W                     70
  19. #define DATE_TEXT_SIZE_H                     14
  20.   
  21. #define TIME_TEXT_POS_X                      90
  22. #define TIME_TEXT_POS_Y                      6
  23. #define TIME_TEXT_SIZE_W                     36
  24. #define TIME_TEXT_SIZE_H                     14
  25.   
  26. static const char weekday[7][11] =
  27. {
  28.     {"周日"},
  29.     {"周一"},
  30.     {"周二"},
  31.     {"周三"},
  32.     {"周四"},
  33.     {"周五"},
  34.     {"周六"}
  35. };
  36.   
  37.   
  38. /*窗口ID*/
  39. static int32_t g_window_id = -1;
  40.   
  41. //数据提示
  42. static int32_t g_layer_id_text = -1;
  43. //数据内容
  44. static int32_t g_layer_id_data = -1;
  45.   
  46. //时间的句柄
  47. static int32_t g_layer_id_time   = -1;
  48. //日期的句柄
  49. static int32_t g_layer_id_date   = -1;
  50.   
  51. //整个窗体句柄
  52. static P_Window h_window;
  53.   
  54. void data_request_web()
  55. {
  56. /*拼接url请求地址, 注意url的缓存大小*/
  57. char url[200] = "";   
  58. sprintf(url, "%s", DATA_WEB);        
  59.   
  60. /*
  61.         拼接过滤参数,即只接受和过滤参数匹配的返回值
  62.         个人感觉这里的过滤可能是让手机做的,就是这里通知手机:json中的数据除了我制定的其他都过滤掉
  63. */
  64.   
  65. /*发送一次*/
  66. g_comm_id_web = maibu_comm_request_web(url, "last", 0);
  67. }
  68.   
  69. void add_text_layer(P_Window p_window, int32_t *p_layer_id, char *p_str, GRect *p_frame, enum GAlign align, int8_t font, enum GColor color)
  70. {
  71.     LayerText text_cfg = {p_str, *p_frame, align, font, 0};
  72.     P_Layer layer = app_layer_create_text(&text_cfg);
  73.     app_layer_set_bg_color(layer, color);
  74.   
  75.     P_Layer old_layer = app_window_get_layer_by_id(p_window, *p_layer_id);
  76.     if(old_layer)
  77.     {
  78.         *p_layer_id = app_window_replace_layer(p_window, old_layer, layer);
  79.     }
  80.     else
  81.     {
  82.         *p_layer_id = app_window_add_layer(p_window, layer);
  83.     }
  84. }
  85.   
  86. static void add_time_bar(P_Window p_window)
  87. {
  88.     /* 添加时间图层 */
  89.     uint8_t text_buf[40];
  90.     struct date_time t;
  91.     app_service_get_datetime(&t);
  92.   
  93.     memset(text_buf, 0, sizeof(text_buf));
  94.     sprintf((char *)text_buf, "%s", (char *)&weekday[t.wday][0]);
  95.     sprintf(&text_buf[6], "%02d-%02d", t.mon, t.mday);
  96.   
  97.     GRect frame;
  98.     frame.origin.x = DATE_TEXT_POS_X;
  99.     frame.origin.y = DATE_TEXT_POS_Y;
  100.     frame.size.h   = DATE_TEXT_SIZE_H;
  101.     frame.size.w   = DATE_TEXT_SIZE_W;
  102.   
  103.     add_text_layer(p_window, &g_layer_id_date, (char*)text_buf, &frame, GAlignLeft, U_ASCII_ARIAL_14, GColorWhite);
  104.   
  105.     frame.origin.x = TIME_TEXT_POS_X;
  106.     frame.origin.y = TIME_TEXT_POS_Y;
  107.     frame.size.h   = TIME_TEXT_SIZE_H;
  108.     frame.size.w   = TIME_TEXT_SIZE_W;
  109.   
  110.     memset(text_buf, 0, sizeof(text_buf));
  111.     sprintf(text_buf, "%02d:%02d", t.hour, t.min);
  112.   
  113.     add_text_layer(p_window, &g_layer_id_time, (char*)text_buf, &frame, GAlignLeft, U_ASCII_ARIAL_14, GColorWhite);
  114. }
  115.   
  116. P_Window init_btc_window()
  117. {
  118. static P_Window p_window;
  119. p_window = app_window_create();
  120. if (NULL == p_window)
  121. {
  122.         return NULL;
  123. }
  124.   
  125.     /* 添加表盘背景 */
  126.     GRect frame = {{0, 0}, {128, 128}};
  127.     GBitmap bitmap;
  128.   
  129.     res_get_user_bitmap(BMP_STOCK_BG, &bitmap);
  130.     LayerBitmap layer_bitmap = {bitmap, frame, GAlignCenter};
  131.     P_Layer layer = app_layer_create_bitmap(&layer_bitmap);
  132.     app_window_add_layer(p_window, layer);
  133.   
  134.     /* 添加时间栏 */
  135.     add_time_bar(p_window);
  136.   
  137. /*加入你的代码 begin*/
  138.   
  139. /*添加数据提示信息*/
  140. GRect frame_main = {{0, 30}, {16, 128}};
  141.     add_text_layer(p_window, &g_layer_id_text, "BTC", &frame_main, GAlignCenter, U_ASCII_ARIAL_14, GColorWhite);
  142. /*添加数据*/
  143. GRect frame_data = {{0, 60}, {16, 128}};
  144.     add_text_layer(p_window, &g_layer_id_data, "waiting", &frame_data, GAlignCenter, U_ASCII_ARIAL_14, GColorWhite);
  145. return p_window;
  146.   
  147. }
  148.   
  149. void data_comm_result_callback(enum ECommResult result, uint32_t comm_id, void *context)
  150. {
  151.   
  152. /*如果上一次请求WEB通讯失败,并且通讯ID相同,则重新发送*/
  153. if ((result == ECommResultFail) && (comm_id == g_comm_id_web))
  154. {
  155.         data_request_web();
  156. }
  157. }
  158.   
  159. static void web_recv_callback(const uint8_t *buff, uint16_t size)
  160. {
  161.     char stock_gid[10];
  162. char i;
  163.   
  164.     maibu_get_json_str(buff, "last", stock_gid, 10);
  165.   
  166. for (i=0;i<10;i++)
  167. {
  168. if (stock_gid[i]=='}')
  169.         {
  170.                stock_gid[i]=0;
  171.         }
  172. }
  173.   
  174. /*添加数据*/
  175. GRect frame_data = {{0, 60}, {16, 128}};
  176.     add_text_layer(h_window, &g_layer_id_data, stock_gid, &frame_data, GAlignCenter, U_ASCII_ARIAL_14, GColorWhite);
  177. app_window_update(h_window);
  178. }
  179.   
  180. static void watch_time_change_callback(enum SysEventType type, void *context)
  181. {
  182.     /*时间更改,分变化*/
  183.     if (type == SysEventTypeTimeChange)
  184.     {
  185.         uint8_t text_buf[40];
  186.         struct date_time t;
  187.         app_service_get_datetime(&t);
  188.   
  189.         memset(text_buf, 0, sizeof(text_buf));
  190.         sprintf((char *)text_buf, "%s", (char *)&weekday[t.wday][0]);
  191.         sprintf(&text_buf[6], "%02d-%02d", t.mon, t.mday);
  192.   
  193.         GRect frame;
  194.         frame.origin.x = DATE_TEXT_POS_X;
  195.         frame.origin.y = DATE_TEXT_POS_Y;
  196.         frame.size.h   = DATE_TEXT_SIZE_H;
  197.         frame.size.w   = DATE_TEXT_SIZE_W;
  198.   
  199.         add_text_layer(h_window, &g_layer_id_date, (char*)text_buf, &frame, GAlignLeft, U_ASCII_ARIAL_14, GColorWhite);
  200.   
  201.         frame.origin.x = TIME_TEXT_POS_X;
  202.         frame.origin.y = TIME_TEXT_POS_Y;
  203.         frame.size.h   = TIME_TEXT_SIZE_H;
  204.         frame.size.w   = TIME_TEXT_SIZE_W;
  205.   
  206.         memset(text_buf, 0, sizeof(text_buf));
  207.         sprintf(text_buf, "%02d:%02d", t.hour, t.min);
  208.   
  209.         add_text_layer(h_window, &g_layer_id_time, (char*)text_buf, &frame, GAlignLeft, U_ASCII_ARIAL_14, GColorWhite);
  210.   
  211.         app_window_update(h_window);
  212.     }
  213. }
  214.   
  215. static void data_timer_callback(date_time_t tick_time, uint32_t millis, void *context)
  216. {
  217.     data_request_web();
  218. }
  219.   
  220. int main()
  221. {
  222.   
  223. /*创建消息列表窗口*/
  224. h_window = init_btc_window();
  225.   
  226. //订阅时间改变事件
  227.     maibu_service_sys_event_subscribe(watch_time_change_callback);
  228. /*放入窗口栈显示*/
  229. g_window_id = app_window_stack_push(h_window);
  230.   
  231. data_request_web();
  232.   
  233. /*注册通讯结果回调*/
  234. maibu_comm_register_result_callback(data_comm_result_callback);
  235.   
  236. //注册网络请求回调函数
  237.     maibu_comm_register_web_callback(web_recv_callback);
  238.   
  239.     //聚合数据源每隔10s更新数据
  240.     app_window_timer_subscribe(h_window, 10000, data_timer_callback, (void *)h_window);
  241. return 0;
  242. }
复制代码


编译之后上传到手表,可以在表面看到当前的价格(因为比特币波动非常快,所以会有一点点差别)


看起来工作正常,美中不足就是屏幕有点小,如果能像美国队长那块一样大就完美了。



这块手表的一大重要特性就是采用电纸屏幕,就是那种 Kindle 的屏幕材质,不改变内容无需耗电,这样待机可以很长时间(标称21天)。说道这里,我想起来一个很老的苏联笑话:
有一个人在机场等六点的飞机,可是他忘记了带手表,于是他想找
个人问问。这时,他看见一个人提着两个巨大的手提箱吃力的走过来,手腕上戴
着一块异常漂亮的一看就知道是高科技产品的手表。
  “请问,几点了?”他问道。
  “哪个国家的时间?”那人反问。
  “哦?”他的好奇心来了,“你都知道哪些国家的时间呢?”
  “所有的国家,”那人回答道。
  “哇!那可真是一块好手表呀!”
  “还不止这些呢,这块表还有GPS卫星系统,可以随时收发电子邮件、
传真,这个彩色的屏幕可以收看NTSC制式的电视节目!”那人给他
演示,果真如此!
“哦!太棒了,我真想拥有一块这样的手表,您……您可以把它卖给我吗?”
“说实话,我已经烦透了这块表了,这样吧,900美元,如何?”
  他马上掏出支票簿,写了900美元给那人,“成交!”
 “好的,现在,它是你的了。”那人如释重负,把手表交给他,“这个是你
的手表”,然后指着地上的两个大箱子说,“这两个是电池!”
无数的科学家和工程师在不断的努力改造着我们的生活,让很多在过去看起来无法实现的事情变成现实,这是非常令人振奋和激动人心的。
特别感谢 龍坤楊 麦步手表开箱与精简Web request Demo  一文的帮助




比特币行情表盘在此:


本帖原文链接请见Arduino中文社区:链接在此

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

48

主题

670

帖子

3384

麦力

精华
0
阅读权限
200
在线时间
745 小时
发表于 2016-7-12 10:38:32 | 显示全部楼层
各种期货行情应该也都可以支持
发帖内容均来自麦步智能手表自动触发,不接受抄水表、送快递、送温暖等任何形式的关怀

17

主题

264

帖子

1494

麦力

精华
2
阅读权限
100
在线时间
64 小时

麦步手表用户麦步工业测评协会

发表于 2016-7-12 10:54:13 | 显示全部楼层
真正的大牛,不光技术活,口活也不错,口才我说的是

40

主题

1665

帖子

1万

麦力

精华
2
阅读权限
100
在线时间
1236 小时

麦步手表用户麦步工业测评协会

发表于 2016-7-12 11:40:38 | 显示全部楼层
再清风 发表于 2016-7-12 10:54
真正的大牛,不光技术活,口活也不错,口才我说的是

呵呵,你想像力还蛮丰富的啊
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|麦步官方论坛 ( 粤ICP备12052190号  

GMT+8, 2024-4-18 10:43 , Processed in 0.078216 second(s), 30 queries .

Powered by Discuz! X3.2

© 2012-2021 Comsenz Inc.

快速回复 返回顶部 返回列表