当前位置:首页 > 公众号精选 > 嵌入式云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获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

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

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭