当前位置:首页 > 公众号精选 > 嵌入式云IOT技术圈
[导读]如下图所示,这就是腾讯定制开发板EVB_G0开发板啦.

如下图所示,这就是腾讯定制开发板EVB_G0开发板啦:

关于这款开发板的介绍,详细资料可以参考以下TencentOS官方公众号的两篇DIY作品的文章:

TencentOS Tiny手把手教您自制智能甲醛监测仪

基于TencentOS Tiny&腾讯连连的炫酷物联网智能灯,你值得拥有!

1、DIY项目展示

为了DIY这个简单的小项目,我把它改造成下面这个样子,也加了不少模块,有些功能并没有实现:

先来看下目前的基本功能演示:

2、项目整体框架

3、项目软件主要逻辑

3.1、STM32CubeMX配置

这个模板直接拷贝TencentOS tiny官方内核BSP包里的,然后我自己再加了一些别的配置进去做了下简单的修改。

3.2、云端与设备交互逻辑

在没有云端指令下发时,设备会定时上传当前环境的光强数值到腾讯云平台,当有云端指令下发时,主要分为以下几种情况:

  • 控制E53_SC1模组上的电灯亮灭
  • 控制外接RGB浪漫彩灯定时闪烁
  • 控制热敏打印机打一周(周一~周日)情书
  • 控制热敏打印机打印云端下发的字符串根据云平台规定,编写如下Json数据模板脚本:
{ "version": "1.0", "profile": { "ProductId": "WONYDFWVJO", "CategoryId": "539" }, "properties": [
    { "id": "power_switch", "name": "电灯开关", "desc": "控制灯光", "required": true, "mode": "rw", "define": { "type": "bool", "mapping": { "0": "关灯", "1": "开灯" }
      }
    },
    { "id": "power_switch1", "name": "浪漫彩灯", "desc": "控制彩灯", "required": true, "mode": "rw", "define": { "type": "bool", "mapping": { "0": "关彩灯", "1": "开彩灯" }
      }
    },
    { "id": "lx", "name": "光照强度", "desc": "光照强度", "mode": "r", "define": { "type": "int", "min": "0", "max": "20000", "start": "0", "step": "1", "unit": "lx" }, "required": false },
    { "id": "week", "name": "一周情书", "desc": "一周的情书", "mode": "rw", "define": { "type": "enum", "mapping": { "0": "Monday", "1": "Tuesday", "2": "Wednesday", "3": "Thursday", "4": "Friday", "5": "Saturday", "6": "Sunday" }
      }, "required": false },
    { "id": "cloud_print", "name": "云打印机", "desc": "通过云端下发字符串控制打印机打印数据", "mode": "rw", "define": { "type": "string", "min": "0", "max": "2048" }, "required": false }
  ], "events": [], "actions": []
}

在腾讯云平台以及腾讯连连小程序上数据模板展示效果如下:

光强属于上行指令:

memset(report_topic_name, 0, sizeof(report_topic_name));
size = snprintf(report_topic_name, TOPIC_NAME_MAX_SIZE, "$thing/up/property/%s/%s", product_id, device_name); if (size < 0 || size > sizeof(report_topic_name) - 1)
{ printf("pub topic content length not enough! content size:%d  buf size:%d", size, (int)sizeof(report_topic_name));
}

当设备上线时,平台会收到上行数据,定时显示当前环境下的光强数值:

while (1)
{
  // 读取光照强度,数据存放在 e53_value
  e53_value = e53_scl_read_data(); printf("e53 value %.0f lx\r\n", e53_value);
  memset(e53_str, 0, sizeof(e53_str));
  sprintf(e53_str, "%.0f lx(lm/m2)", e53_value);
  OLED_Clear();
  OLED_ShowString(0, 0, (uint8_t*)"TencentOS-tiny", 16);
  OLED_ShowString(0, 2, (uint8_t*)e53_str, 16);
  // 1. 构造上报的JSON
  memset(payload, 0, sizeof(payload));
  snprintf(payload, sizeof(payload), REPORT_LX_DATA_TEMPLATE, e53_value);
  // 2. 向数据模板 topic 发布光照强度信息 if (tos_tf_module_mqtt_pub(report_topic_name, QOS0, payload) != 0)
  { printf("module mqtt pub fail\n"); break;
  } else { printf("module mqtt pub success\n");
  }
  tos_sleep_ms(7000);
}

除了光强以外,其余的参数属性属于下行指令,当平台下发指令时,会触发MQTT做数据订阅功能时的回调函数:default_message_handler,这部分在初始化的时候就设计好了,代码如下:

// 5. 订阅数据模板 topic
size = snprintf(report_reply_topic_name, TOPIC_NAME_MAX_SIZE, "$thing/down/property/%s/%s", product_id, device_name); if (size < 0 || size > sizeof(report_reply_topic_name) - 1)
{ printf("sub topic content length not enough! content size:%d  buf size:%d", size, (int)sizeof(report_reply_topic_name));
} if (tos_tf_module_mqtt_sub(report_reply_topic_name, QOS0, default_message_handler) != 0)
{ printf("module mqtt sub fail\n");
} else { printf("module mqtt sub success\n");
}

该函数会依次对下发的指令进行匹配处理,下发的指令格式是Json,这里我们采用CJson来对数据进行解析:

/***************************************************************
* 函数名称: default_message_handler
* 说    明: IoT Explorer下行数据处理
***************************************************************/
static void default_message_handler(mqtt_message_t* msg)
{
    cJSON *root;
    cJSON *params;
    cJSON *method;
    cJSON *week_love;
    cJSON *power_switch;
    cJSON *power_switch1;
    cJSON *cloud_print ;
    root = cJSON_Parse(msg->payload + 1); if (!root)
    { printf("Invalid json root\r\n"); return;
    }
    method = cJSON_GetObjectItem(root, "method"); if (!method)
    { printf("Invalid json method\r\n");
        cJSON_Delete(root); return;
    } if (0 != strncmp(method->valuestring, "control", sizeof("control") - 1))
    {
        cJSON_Delete(root); return;
    }
    //获取参数
    params = cJSON_GetObjectItem(root, "params"); if (!params)
    { printf("Invalid json params\r\n");
        cJSON_Delete(root); return;
    }
    //获取power_switch参数
    power_switch = cJSON_GetObjectItem(params, "power_switch"); if (power_switch)
        iot_explorer_handle_power_switch(power_switch->valueint);
    //获取power_switch1参数
    power_switch1 = cJSON_GetObjectItem(params, "power_switch1"); if (power_switch1)
        iot_explorer_handle_power_switch1(power_switch1->valueint);
    //获取week参数
    week_love = cJSON_GetObjectItem(params, "week"); if(week_love)
        iot_explorer_handle_week(week_love->valueint);
    //获取cloud_print参数
    cloud_print = cJSON_GetObjectItem(params, "cloud_print"); if(cloud_print)
        iot_explorer_handle_string(cloud_print->valuestring);
    cJSON_Delete(root);
}

参数功能如下:

  • power_switch 参数

控制E53模块上的电灯

调用iot_explorer_handle_power_switch函数处理。

/***************************************************************
* 函数名称: iot_explorer_handle_power_switch
* 说    明: 根据power switch控制开关
***************************************************************/
static void iot_explorer_handle_power_switch(int power_switch)
{ if (0 == power_switch)
    { printf("iot-explorer close the light\r\n");
        LED_CLOSE;
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
        OLED_Clear();
        OLED_ShowString(0, 0, (uint8_t*)"Close Led", 16);
    } else { printf("iot-explorer open the light\r\n");
        LED_OPEN;
        HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
        OLED_Clear();
        OLED_ShowString(0, 0, (uint8_t*)"Open Led", 16);
    }
}
  • power_switch1 参数

控制彩灯

调用iot_explorer_handle_power_switch1函数处理。

/***************************************************************
* 函数名称: iot_explorer_handle_power_switch
* 说    明: 根据power switch控制彩灯开关
***************************************************************/
static void iot_explorer_handle_power_switch1(int power_switch)
{ if (0 == power_switch)
    { printf("iot-explorer close the color light\r\n");
        Controld_Color_LED = 0 ;
        OLED_Clear();
        OLED_ShowString(0, 0, (uint8_t*)"Close Color Led", 16);
    } else { printf("iot-explorer open the color light\r\n");
        Controld_Color_LED = 1 ;
        OLED_Clear();
        OLED_ShowString(0, 0, (uint8_t*)"Open Color Led", 16);
    }
}
  • week 参数

控制热敏打印机打印一周的某一天的情书

调用iot_explorer_handle_week函数处理。

/***************************************************************
* 函数名称: iot_explorer_handle_week
* 说    明: 根据week控制打印机
***************************************************************/
static void iot_explorer_handle_week(int week)
{
  //略...
}
  • cloud_print 参数

控制热敏打印机打印下行字符串

调用iot_explorer_handle_string函数处理。

/***************************************************************
* 函数名称: iot_explorer_handle_string
* 说    明: 根据string控制打印机打印字符串
***************************************************************/
static void iot_explorer_handle_string(char *str)
{
    /*收到情书,则蜂鸣器鸣叫3声进行提醒*/
    uint8_t count = 0 ; for(count = 0 ; count < 6 ; count++) { HAL_GPIO_TogglePin(BUZZER_GPIO_Port, BUZZER_Pin); tos_task_delay(500); } HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_RESET); printf("云端数据:%s\n", str);
    OLED_Clear();
    OLED_ShowString(0, 0, (uint8_t*)str, 16);
}

3.3、热敏打印机模块

热敏打印机用的是上次参加腾讯连连比赛MC-EH205:

【腾讯连连IoT开发大赛】基于TencentOS tiny云打印机&智能达特甲醛探测系统

之前MCU用的是M4的架构,但厂家提供了M3对应的lib和头文件却可以直接被编译兼容,所以驱动起来非常简单,只需要包含对应的库然后调用对应的函数即可:

而本次用的是M0的架构MCU,编译的时候提示不兼容,所以lib也就不适用了,但是没关系,直接参考指令集手册来驱动打印机模块也是可以的。

根据项目要求,我们需要提供发送指令和发送数据的两个函数:

//发送单个字节给打印机
void Printf_send_byte(uint8_t data)
{
    /*调度器上锁*/
    tos_knl_sched_lock();
    HAL_UART_Transmit(&huart3, &data, 1, 1000); while(__HAL_UART_GET_FLAG(&huart3, UART_FLAG_TXE) != SET);

    /*调度器解锁*/
    tos_knl_sched_unlock();
}


//发送字符串给打印机
static void Printf_send_command(char* str)
{
    /*调度器上锁*/
    tos_knl_sched_lock(); while(*str)
    {
        Printf_send_byte(*str);
        str++;
    }
    /*调度器解锁*/
    tos_knl_sched_unlock();
}

模块上电需要发送初始化指令:

/*初始化打印设备*/
void init_print_device(void)
{
 Printf_send_byte(0x1B);
 Printf_send_byte(0x40);
}

手册说明如下:

接下来就可以愉快的发送字符串给模块打印纸条了,如果发送的字符串显示在纸条上需要对齐的话,则需要根据需求发送文本对齐指令,然后再发送字符串,这样的话打印出来的效果就会按照设定要求进行:

如下所示:

模块的可玩性很高,指令集也兼容了市面上常见的热敏打印机,可以开发出很多有趣好玩的产品。

4、项目开源地址

本节代码已同步到码云的代码仓库中,获取方法如下:

码云仓库:

https://gitee.com/morixinguan/personal-open-source-project/tree/master/6.Love_Letter_printer

获取项目方法:

git clone https://gitee.com/morixinguan/personal-open-source-project.git

我还将之前做的一些项目以及练习例程在近期内全部上传完毕,与大家一起分享交流,如果有任何问题或者对该项目感兴趣,欢迎加我微信:morixinguan一起交流学习。


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

新品播报!米尔电子发布了基于海思Hi3093高性能MPU的MYC-LHi3093核心板及开发板, 此款核心板支持openEuler embedded OS欧拉系统,丰富生态,可实现100%全国产自主可控。不仅如此,米尔基...

关键字: 核心板 PLC 开发板

米尔电子发布的瑞萨第一款MPU生态板卡——瑞米派(Remi Pi)自上市当天200套售罄,获得不少新老用户的青睐。为感谢大家的支持,米尔加推300套瑞米派活动,以补贴价198元回馈大家,抢完即止!

关键字: 瑞米派 树莓派 开发板

2023年12月,米尔电子联合战略合作伙伴全志科技,率先业内发布了国产第一款T527核心板及开发板,这款高性能、高性价比、八核A55的国产核心板吸引了广大客户关注,为积极响应客户需求,米尔基于全志T527核心板现已批量上...

关键字: 开发板 核心板 处理器

IEC61850是变电站自动化系统(SAS)中通信系统和分散能源(DER)管理的国际标准。它通过标准的实现,实现了智能变电站的工程运作标准化。使得智能变电站的工程实施变得规范、统一和透明,在电力和储能系统中应用非常广泛。

关键字: 开发板 核心板 智能变电站

业内消息,据洛图科技新一期《中国智能盒子线上零售市场追踪》报告,2023 年中国智能盒子(智能机顶盒)出货量惨淡,年度整体销量 313 万台,较 2022 年下降 27.5%。

关键字: 电视盒子 出货量 腾讯 小米 天猫魔盒

近日,米尔电子和瑞萨电子共同定义和开发了瑞萨第一款MPU生态开发板——瑞米派(Remi Pi)正式上市了!在各种Pi板卡琳琅满目的当下,Remi Pi是一款与众不同的开发板,他兼顾了严肃产品开发和爱好者创意实现两种需要。

关键字: 树莓派 单板 开发板

业内消息,近日北京市规自委官网显示,北京市海淀区学院路北端A、B、C、J地块B4综合性商业金融服务业用地、B23研发设计用地完成出让,最终由腾讯科技(北京)有限公司底价摘得,成交价格为底价64.2亿元。

关键字: 腾讯

最新消息,《英雄联盟》开发商拳头游戏(Riot Games)公司首席执行官 Dylan·Jadeja 近日发布全员信,表示将于近期裁员 11%,共涉及 530 名员工。

关键字: 英雄联盟 裁员 拳头游戏 腾讯

业内消息,近日深圳市迅雷网络技术有限公司及旗下深圳市迅雷网文化有限公司新增两则开庭公告,原告为腾讯科技(北京)有限公司、重庆腾讯信息技术有限公司,其中一起案件原告还包括深圳市腾讯计算机系统有限公司,案由均为不正当竞争纠纷...

关键字: 腾讯 迅雷

以下内容中,小编将对单片机开发板的相关内容进行着重介绍和阐述,希望本文能帮您增进对单片机开发板的了解,和小编一起来看看吧。

关键字: 单片机 开发板 单片机开发板
关闭
关闭