都说科技改变生活,今天来聊的这个作品可以真实的改变生活相信有车的朋友最头疼的莫过于停车问题,其他小城市还好,像深圳这样的大城市,停车问题一直困扰着有车一族:- 不知道哪里有车位可以停- 好不容易找到停车场因为方向错误或者技术不好车位被别人占了- 随意停路边容易吃罚单对于其他地方,停车场多于车辆的,停车场主面临收入问题:- 怎么让更多的车停到我这里增加收入- 我的停车场到底收入如何,如何简化做账流程- 我新建了一个停车场怎么让别人知道呢...基于以上几个痛点本人设计了一款基于腾讯云以及TencentOS Tiny实时系统打造的智能停车平台,依靠智能车位锁,智能抬杆,以及平台的管理能力,解决以上几个生活中的问题,并具有一定及广阔的商业价值
作品由设备,服务器及小程序组成:
具体系统框架图可以看下图:
设备端:
设备端采用TencentOS Tiny驱动,利用SDK里的demo程序可以快速上云,代码片段如下:
系统启动,上云:
int data_template_light_thread(void) {
int rc;
sReplyPara replyPara;
DeviceProperty *pReportDataList[TOTAL_PROPERTY_COUNT];
int ReportCont;
registerPole();
registerLock();
//init log level
IOT_Log_Set_Level(eLOG_INFO);
//init connection
TemplateInitParams init_params = DEFAULT_TEMPLATE_INIT_PARAMS;
rc = _setup_connect_init_params(&init_params);
if (rc != QCLOUD_RET_SUCCESS) {
Log_e("init params err,rc=%d", rc);
return rc;
}
void *client = IOT_Template_Construct(&init_params);
if (client != NULL) {
Log_i("Cloud Device Construct Success");
} else {
Log_e("Cloud Device Construct Failed");
return QCLOUD_ERR_FAILURE;
}
///////////////////////////////////
int first_time_report = 1;
light_power_off();
///////////////////////////////////
//init data template
_init_data_template();
//register data template propertys here
rc = _register_data_template_property(client);
if (rc == QCLOUD_RET_SUCCESS) {
Log_i("Register data template propertys Success");
} else {
Log_e("Register data template propertys Failed: %d", rc);
return rc;
}
//register data template actions here
#ifdef ACTION_ENABLED
rc = _register_data_template_action(client);
if (rc == QCLOUD_RET_SUCCESS) {
Log_i("Register data template actions Success");
} else {
Log_e("Register data template actions Failed: %d", rc);
return rc;
}
#endif
//report device info, then you can manager your product by these info, like position
rc = _get_sys_info(client, sg_data_report_buffer, sg_data_report_buffersize);
if(QCLOUD_RET_SUCCESS == rc){
rc = IOT_Template_Report_SysInfo_Sync(client, sg_data_report_buffer, sg_data_report_buffersize, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
if (rc != QCLOUD_RET_SUCCESS) {
Log_e("Report system info fail, err: %d", rc);
goto exit;
}
}else{
Log_e("Get system info fail, err: %d", rc);
}
//get the property changed during offline
rc = IOT_Template_GetStatus_sync(client, QCLOUD_IOT_MQTT_COMMAND_TIMEOUT);
if (rc != QCLOUD_RET_SUCCESS) {
Log_e("Get data status fail, err: %d", rc);
//goto exit;
}else{
Log_d("Get data status success");
}
while (IOT_Template_IsConnected(client) || rc == QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT
|| rc == QCLOUD_RET_MQTT_RECONNECTED || QCLOUD_RET_SUCCESS == rc) {
// ...
#ifdef EVENT_POST_ENABLED
eventPostCheck(client);
#endif
HAL_SleepMs(3000);
}
exit:
rc = IOT_Template_Destroy(client);
return rc;
}
其中车锁和抬杆的注册:
static pole m_pole={
.motor={.motor_pins={
{GPIOB, GPIO_PIN_5},
{GPIOB, GPIO_PIN_6},
{GPIOB, GPIO_PIN_7},
{GPIOB, GPIO_PIN_8},
}
}
};
int registerPole(){
smotor_init(&m_pole.motor);
return 0;
}
lock m_lock[]={
{
.motor={
.motor_pins={
{GPIOB, GPIO_PIN_12},
{GPIOB, GPIO_PIN_13},
},
.limit_pins={
{GPIOB, GPIO_PIN_14},
{GPIOB, GPIO_PIN_15},
},
.light_pin={GPIOC, GPIO_PIN_6},
},
},
{
.motor={.motor_pins={
{GPIOB, GPIO_PIN_9},
{GPIOC, GPIO_PIN_0},
},
.limit_pins={
{GPIOC, GPIO_PIN_1},
{GPIOC, GPIO_PIN_2},
},
.light_pin={GPIOC, GPIO_PIN_3},
},
},
};
uint8_t lock_num=sizeof(m_lock)/sizeof(m_lock[0]);
int registerLock(){
printf("lock_num = %d\n",lock_num);
for(int i=0;i<lock_num;i++){
printf("init %d start\n",i);
motor_init(&(m_lock[i].motor));
printf("init %d end\n",i);
}
return 0;
}
下发指令操作设备行为:
#ifdef ACTION_ENABLED
#include "action_config.c"
static void OnControlLockActionCallback(void *pClient, const char *pClientToken, DeviceAction *pAction){
int i;
sReplyPara replyPara;
printf("__%s__\n",__func__);
//do something base on input, just print as an sample
DeviceProperty *pActionInput = pAction->pInput;
for (i = 0; i < pAction->input_num; i++) {
if (JSTRING == pActionInput[i].type) {
Log_i("Input:[%s], data:[%s]", pActionInput[i].key, pActionInput[i].data);
HAL_Free(pActionInput[i].data);
} else {
if(JINT32 == pActionInput[i].type) {
Log_i("Input:[%s], data:[%d]", pActionInput[i].key, *((int*)pActionInput[i].data));
} else if( JFLOAT == pActionInput[i].type) {
Log_i("Input:[%s], data:[%f]", pActionInput[i].key, *((float*)pActionInput[i].data));
} else if( JUINT32 == pActionInput[i].type) {
Log_i("Input:[%s], data:[%u]", pActionInput[i].key, *((uint32_t*)pActionInput[i].data));
}
}
// sg_action_msg_arrived = true;
}
// construct output
memset((char *)&replyPara, 0, sizeof(sReplyPara));
replyPara.code = eDEAL_SUCCESS;
replyPara.timeout_ms = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
strcpy(replyPara.status_msg, "action execute success!"); //add the message about the action resault
DeviceProperty *pActionOutnput = pAction->pOutput;
//(void)pActionOutnput; //elimate warning
//TO DO: add your aciont logic here and set output properties which will be reported by action_reply
// pole *p=getPole();
// if(p == NULL){
// sg_control_pole_out_result = 1;
// }
int road=*(int *)(pActionInput[0].data);
int direction=*(int *)(pActionInput[1].data);
printf("control %dth lock direction=%s\n",road,direction?"up":"down");
lock *l=getLock(road);
printf("get lock %p\n",l);
if(l == NULL){
sg_control_lock_out_result = 1;
}
IOT_ACTION_REPLY(pClient, pClientToken, sg_data_report_buffer, sg_data_report_buffersize, pAction, &replyPara);
// DeviceProperty *actionInput_control_pole=&pAction->pInput[0];
// int direction=*(int *)actionInput_control_pole->data;
// printf("control pole direction=%s\n",direction?"up":"down");
// if(p){
// poleAction(direction,p);
// }
if(l){
lockAction(direction,l);
}
//smotor_start(direction);
}
static void OnControlPoleActionCallback(void *pClient, const char *pClientToken, DeviceAction *pAction)
{
int i;
sReplyPara replyPara;
printf("__%s__\n",__func__);
//do something base on input, just print as an sample
DeviceProperty *pActionInput = pAction->pInput;
for (i = 0; i < pAction->input_num; i++) {
if (JSTRING == pActionInput[i].type) {
Log_i("Input:[%s], data:[%s]", pActionInput[i].key, pActionInput[i].data);
HAL_Free(pActionInput[i].data);
} else {
if(JINT32 == pActionInput[i].type) {
Log_i("Input:[%s], data:[%d]", pActionInput[i].key, *((int*)pActionInput[i].data));
} else if( JFLOAT == pActionInput[i].type) {
Log_i("Input:[%s], data:[%f]", pActionInput[i].key, *((float*)pActionInput[i].data));
} else if( JUINT32 == pActionInput[i].type) {
Log_i("Input:[%s], data:[%u]", pActionInput[i].key, *((uint32_t*)pActionInput[i].data));
}
}
// sg_action_msg_arrived = true;
}
// construct output
memset((char *)&replyPara, 0, sizeof(sReplyPara));
replyPara.code = eDEAL_SUCCESS;
replyPara.timeout_ms = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
strcpy(replyPara.status_msg, "action execute success!"); //add the message about the action resault
DeviceProperty *pActionOutnput = pAction->pOutput;
//(void)pActionOutnput; //elimate warning
//TO DO: add your aciont logic here and set output properties which will be reported by action_reply
pole *p=getPole();
printf("get pole %p\n",p);
if(p == NULL){
sg_control_pole_out_result = 1;
}
IOT_ACTION_REPLY(pClient, pClientToken, sg_data_report_buffer, sg_data_report_buffersize, pAction, &replyPara);
DeviceProperty *actionInput_control_pole=&pAction->pInput[0];
int direction=*(int *)actionInput_control_pole->data;
printf("control pole direction=%s\n",direction?"up":"down");
if(p){
poleAction(direction,p);
}
//smotor_start(direction);
}
static void OnLightBlinkActionCallback(void *pClient, const char *pClientToken, DeviceAction *pAction)
{
int i;
sReplyPara replyPara;
printf("__%s__\n",__func__);
//do something base on input, just print as an sample
DeviceProperty *pActionInput = pAction->pInput;
for (i = 0; i < pAction->input_num; i++) {
if (JSTRING == pActionInput[i].type) {
Log_i("Input:[%s], data:[%s]", pActionInput[i].key, pActionInput[i].data);
HAL_Free(pActionInput[i].data);
} else {
if(JINT32 == pActionInput[i].type) {
Log_i("Input:[%s], data:[%d]", pActionInput[i].key, *((int*)pActionInput[i].data));
} else if( JFLOAT == pActionInput[i].type) {
Log_i("Input:[%s], data:[%f]", pActionInput[i].key, *((float*)pActionInput[i].data));
} else if( JUINT32 == pActionInput[i].type) {
Log_i("Input:[%s], data:[%u]", pActionInput[i].key, *((uint32_t*)pActionInput[i].data));
}
}
sg_action_msg_arrived = true;
}
// construct output
memset((char *)&replyPara, 0, sizeof(sReplyPara));
replyPara.code = eDEAL_SUCCESS;
replyPara.timeout_ms = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
strcpy(replyPara.status_msg, "action execute success!"); //add the message about the action resault
DeviceProperty *pActionOutnput = pAction->pOutput;
//(void)pActionOutnput; //elimate warning
//TO DO: add your aciont logic here and set output properties which will be reported by action_reply
IOT_ACTION_REPLY(pClient, pClientToken, sg_data_report_buffer, sg_data_report_buffersize, pAction, &replyPara);
}
static int _register_data_template_action(void *pTemplate_client)
{
int i,rc;
for (i = 0; i < TOTAL_ACTION_COUNTS; i++) {
rc = IOT_Template_Register_Action(pTemplate_client, &g_actions[i], g_actions[i].OnActionHandleCallback);
if (rc != QCLOUD_RET_SUCCESS) {
rc = IOT_Template_Destroy(pTemplate_client);
Log_e("register device data template action failed, err: %d", rc);
return rc;
} else {
Log_i("data template action=%s registered.", g_actions[i].pActionId);
}
}
return QCLOUD_RET_SUCCESS;
}
#endif
注册的时候会把每一个adction都注册一个回调函数.
服务器端代码太多了,直接贴一个图片显示一下启动流程:
小程序涉及的东西比较多,这里贴几个图片代表一下,具体所以的界面可以在下方PPT和视频里看到:
本次大赛所制作的ppt在下方,点击左右箭头可以换页
视频:视频分为两个,一个是ppt讲解,还有一个项目演示视频,不喜欢听PPT废话的童鞋可以直接看演示视频
PPT录像的麦克风不太好,所以导致有的地方有破音,还有的地方不清晰,建议调大音量或者戴上耳机效果最好
最后感谢腾讯提供的这个机会,让我有机会能真正使用上TencentOS和腾讯云这两款优秀的产品.
感谢观看.
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。