前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AIoT应用创新大赛-基于TencentOS Tiny 的远程CAN数据监控

AIoT应用创新大赛-基于TencentOS Tiny 的远程CAN数据监控

原创
作者头像
用户4136378
发布2022-03-07 13:41:27
6100
发布2022-03-07 13:41:27
举报
文章被收录于专栏:TencentOS-aiotTencentOS-aiot

一、项目背景

随着物联网的发展,生活中带有网络的电器,很是方便。也有此也对网络控制产生了兴趣,接触嵌入式底层驱动和硬件设计方面的较多,对网络控制还不是很了解,一直想要尝试下使用物联网平台和嵌入式硬件的通信控制。感谢物联网开发平台提供的如软硬件资源,来实现我这个想法,接收设备的CAN通信数据,远程发送到腾讯云的物联网开发平台IoT Expolorer。

二、硬件部分

2.1、实现这个小项目使用的硬件有如下:

a、wifi模块

b、TencentOs-Tiny开发板

c、CAN通信转换模块

d、CAN终端调试设备

2.2、硬件框图

硬件框图
硬件框图

开发板通过CAN通信转换模块接收CAN设备的帧数据,解析和数据处理后,经WIFI模块将数据发送到腾讯云平台,无线终端可在物联网开发平台或腾讯连连小程序上看到。

2.3、硬件连接实物图

硬件连接图
硬件连接图

三、软件部分

3.1、CAN驱动底层msp2515.c

代码语言:javascript
复制
//mcp2515.c
#include "pin_mux.h"
#include "clock_config.h"
#include "fsl_debug_console.h"
#include "fsl_gpio.h"
#include "mcp2515.h"
#include "led.h"



uint8_t id[4]={0x05,0x08,0x05,0x82};	 					//发送的ID地址
uint8_t rxdat[10];

gpio_pin_config_t mcp2515_output_config = {kGPIO_DigitalOutput, 0, kGPIO_NoIntmode};
gpio_pin_config_t mcp2515_input_config = {kGPIO_DigitalInput, 0, kGPIO_NoIntmode};

gpio_pin_config_t can_int_config = {kGPIO_DigitalInput, 0, kGPIO_IntFallingEdge, };

//端口初始化
void mcp2515_port_init(void)
{
	GPIO_PinInit(E53_SPI_SCK, E53_SPI_SCK_PIN, &mcp2515_output_config);   	//CAN_SCK
	GPIO_PinInit(E53_SPI_MOSI, E53_SPI_MOSI_PIN, &mcp2515_output_config);	//CAN_MOSI
	GPIO_PinInit(E53_SPI_MISO, E53_SPI_MISO_PIN, &mcp2515_input_config);	//CAN_MISO
	GPIO_PinInit(CAN_CS, CAN_CS_PIN, &mcp2515_output_config);				//CAN_CS
	//中断设置
	EnableIRQ(EXAMPLE_CAN_IRQ);
	GPIO_PinInit(EXAMPLE_CAN_GPIO, EXAMPLE_CAN_GPIO_PIN, &can_int_config);
	//使能GPIO中断
	GPIO_PortEnableInterrupts(EXAMPLE_CAN_GPIO, 1U << EXAMPLE_CAN_GPIO_PIN);


}

void EXAMPLE_CAN_IRQHandler(void)
{
    GPIO_PortClearInterruptFlags(EXAMPLE_CAN_GPIO, 1U << EXAMPLE_CAN_GPIO_PIN);

    CAN_Receive(rxdat);
    CAN_Eint_Clear();
    E53_GPIO3_TOG();

    SDK_ISR_EXIT_BARRIER;
}


void dels(uint32_t tt)
{
	uint32_t ds=0;
	for(;ds<tt;ds++);
}

uint8_t SPI_Read(void)
{
	uint8_t n=8;
	uint8_t tdata;

	E53_SPI_SCK_LOW();
	while(n--)
	{
		dels(100);
		E53_SPI_SCK_HIGH();
		tdata=tdata<<1;
		if( 1 == GPIO_PinRead(E53_SPI_MISO, E53_SPI_MISO_PIN))
			tdata=tdata|0x01;
		else
			tdata=tdata&0xfe;
		E53_SPI_SCK_LOW();
	}
	return tdata;
}


void SPI_Write(uint8_t ch)
{
	uint8_t n=8;

	E53_SPI_SCK_LOW();
	while(n--)
	{
		E53_SPI_SCK_LOW();
		dels(100);
		if((ch&0x80)==0x80)
		{
			E53_SPI_MOSI_HIGH();
		}
		else
		{
			E53_SPI_MOSI_LOW();
		}
		dels(100);
		E53_SPI_SCK_HIGH();
		dels(100);
		ch=ch<<1;
	}
}

void SPI_ByteWrite(uint8_t addr, uint8_t value)
{
	CAN_CS_LOW();
	SPI_Write(CAN_WRITE);
	SPI_Write(addr);
	SPI_Write(value);
	CAN_CS_HIGH();
}

uint8_t SPI_ByteRead(uint8_t addr)
{
	uint8_t tempdata;

	CAN_CS_LOW();
	SPI_Write(CAN_READ);
	SPI_Write(addr);
	tempdata=SPI_Read();
	CAN_CS_HIGH();
	return tempdata;
}


void SPI_Reset(void)
{
	CAN_CS_LOW();
	SPI_Write(CAN_RESET);
	CAN_CS_HIGH();
}


void SPI_BitModityMcp2515(uint8_t addr, uint8_t mask, uint8_t udata)
{

     CAN_CS_LOW();
     SPI_Write(CAN_BIT_MODIFY);
     SPI_Write(addr);
     SPI_Write(mask);
     SPI_Write(udata);
     CAN_CS_HIGH();
     return;
}

//写连续N个字节数据
void SPI_WriteRegister(uint8_t addr, uint8_t *dat, uint8_t length)
{
	uint8_t i;

	CAN_CS_LOW();
	SPI_Write(CAN_WRITE);
	SPI_Write(addr);
	for (i=0; i<length ;i++ )
	{
		SPI_Write(*dat++);
	}
	CAN_CS_HIGH();
}

//MCP2515初始化
void Init_MCP2515(void)
{
	uint8_t temp[4] = { 0, 0, 0, 0 };

	mcp2515_port_init();

	SPI_Reset();
	dels(1000);
	SPI_BitModityMcp2515(CANCTRL,0xE0,0x80);

	SPI_ByteWrite(CNF1,CAN_100Kbps);

	SPI_ByteWrite(CNF2,0x80|PHSEG1_3TQ|PRSEG_1TQ);

	SPI_ByteWrite(CNF3,PHSEG2_3TQ);

 	SPI_ByteWrite(CANINTF,0x00);
 	SPI_ByteWrite(CANINTE,0x01);

	SPI_ByteWrite(RXB0CTRL,0x60);
	SPI_ByteWrite(RXB1CTRL,0x60);

	SPI_ByteWrite(RXF0SIDH,0x01);
	SPI_ByteWrite(RXF0SIDL,0x08);
	SPI_ByteWrite(RXF0EID8,0x05);
	SPI_ByteWrite(RXF0EID0,0x11);

	SPI_ByteWrite(RXM0SIDH,0xff);
	SPI_ByteWrite(RXM0SIDL,0xff);
	SPI_ByteWrite(RXM0EID8,0xff);
	SPI_ByteWrite(RXM0EID0,0xff);

//	SPI_WriteRegister( RXF0SIDH, temp, 4 );
	SPI_WriteRegister( RXF1SIDH, temp, 4 );
	SPI_WriteRegister( RXF2SIDH, temp, 4 );
	SPI_WriteRegister( RXF3SIDH, temp, 4 );
	SPI_WriteRegister( RXF4SIDH, temp, 4 );
	SPI_WriteRegister( RXF5SIDH, temp, 4 );
//	SPI_WriteRegister( RXM0SIDH, temp, 4 );
	SPI_WriteRegister( RXM1SIDH, temp, 4 );

	SPI_ByteWrite( BFPCTRL, 0 );
	SPI_ByteWrite( TXRTSCTRL, 0 );
	SPI_BitModityMcp2515(CANCTRL,0xE0,0x00);

}


void CAN_Send(uint8_t *CAN_TX_Buf)
{
	SPI_BitModityMcp2515(TXB0CTRL,0x08,0x00);
	SPI_ByteWrite(TXB0SIDH,id[0]);
	SPI_ByteWrite(TXB0SIDL,id[1]);
	SPI_ByteWrite(TXB0EID8,id[2]);
	SPI_ByteWrite(TXB0EID0,id[3]);

	SPI_ByteWrite(TXB0DLC,DLC_8);
	SPI_ByteWrite(TXB0D0,CAN_TX_Buf[0]);
	SPI_ByteWrite(TXB0D1,CAN_TX_Buf[1]);
	SPI_ByteWrite(TXB0D2,CAN_TX_Buf[2]);
	SPI_ByteWrite(TXB0D3,CAN_TX_Buf[3]);
	SPI_ByteWrite(TXB0D4,CAN_TX_Buf[4]);
	SPI_ByteWrite(TXB0D5,CAN_TX_Buf[5]);
	SPI_ByteWrite(TXB0D6,CAN_TX_Buf[6]);
	SPI_ByteWrite(TXB0D7,CAN_TX_Buf[7]);
	CAN_CS_LOW();
	SPI_Write(CAN_RTS | 0x01);
	CAN_CS_HIGH();

}

void CAN_Receive(uint8_t *CAN_RX_Buf)
{
	CAN_RX_Buf[0]=SPI_ByteRead(RXB0D0);
	CAN_RX_Buf[1]=SPI_ByteRead(RXB0D1);
	CAN_RX_Buf[2]=SPI_ByteRead(RXB0D2);
	CAN_RX_Buf[3]=SPI_ByteRead(RXB0D3);
	CAN_RX_Buf[4]=SPI_ByteRead(RXB0D4);
	CAN_RX_Buf[5]=SPI_ByteRead(RXB0D5);
	CAN_RX_Buf[6]=SPI_ByteRead(RXB0D6);
	CAN_RX_Buf[7]=SPI_ByteRead(RXB0D7);
	SPI_ByteWrite(CANINTF,0);
	//while(SPI_ByteRead(CANINTF)!=0);
}

void CAN_Eint_Clear(void)
{
	SPI_ByteWrite(CANINTF,0);
}

3.2、MQTT腾讯云上传部分程序

代码语言:javascript
复制
void mqttclient_task(void)
{
    int error;
    
    int lightness = 0;
    int dat[10];
    
    mqtt_client_t *client = NULL;
    
    mqtt_message_t msg;
    
    k_event_flag_t match_flag;
    
    char  host_ip[20];
    
    memset(&msg, 0, sizeof(msg));
    
#ifdef USE_ESP8266 
    esp8266_sal_init(esp8266_port);
    
    esp8266_join_ap("TP-LINK_0F58", "hhyf1bhhyf1b");
#endif


#ifdef USE_EC600S
    ec600s_sal_init(HAL_UART_PORT_0);
#endif

    mqtt_log_init();

    client = mqtt_lease();
    
    tos_event_create(&report_result_event, (k_event_flag_t)0u);
    
    /* Domain Format: <your product ID>.iotcloud.tencentdevices.com */
    tos_sal_module_parse_domain("C161S8COPH.iotcloud.tencentdevices.com",host_ip,sizeof(host_ip));
    
    /*
        These infomation is generated by mqtt_config_gen.py tool in "TencentOS-tiny\tools" directory.
    */
    mqtt_set_port(client, "1883");
    mqtt_set_host(client, host_ip);

    mqtt_set_client_id(client, "C161S8COPHCAN_DEVICE");
    mqtt_set_user_name(client, "C161S8COPHCAN_DEVICE;12010126;6SFTL;1647175200");
    mqtt_set_password(client, "aa2a5bc2a3ba7c40959f7f07d925b402163424ea;hmacsha1");
    mqtt_set_clean_session(client, 1);

    error = mqtt_connect(client);
    
    //MQTT_LOG_D("mqtt connect error is %#0x", error);
    
    error = mqtt_subscribe(client, "$thing/down/property/C161S8COPH/CAN_DEVICE", QOS0, tos_topic_handler);
    
    //MQTT_LOG_D("mqtt subscribe error is %#0x", error);
    
    while (1) {
        memset(&msg, 0, sizeof(msg));
        
        //lightness=rxdat[0];
        dat[0]=rxdat[0];
        dat[1]=rxdat[1];
        dat[2]=rxdat[2];
        snprintf(report_buf, sizeof(report_buf), REPORT_DATA_TEMPLATE, dat[0]);

        msg.qos = QOS0;
        msg.payload = (void *) report_buf;
        
        error = mqtt_publish(client, "$thing/up/property/C161S8COPH/CAN_DEVICE", &msg);
        
        //MQTT_LOG_D("mqtt publish error is %#0x", error);

        snprintf(report_buf, sizeof(report_buf), REPORT_DATA2_TEMPLATE, dat[1]);
		msg.qos = QOS0;
		msg.payload = (void *) report_buf;
		error = mqtt_publish(client, "$thing/up/property/C161S8COPH/CAN_DEVICE", &msg);

		snprintf(report_buf, sizeof(report_buf), REPORT_DATA3_TEMPLATE, dat[2]);
		msg.qos = QOS0;
		msg.payload = (void *) report_buf;
		error = mqtt_publish(client, "$thing/up/property/C161S8COPH/CAN_DEVICE", &msg);

        
        tos_event_pend(&report_result_event, 
                       report_success|report_fail,
                       &match_flag,
                       TOS_TIME_FOREVER,
                       TOS_OPT_EVENT_PEND_ANY | TOS_OPT_EVENT_PEND_CLR);
        
        if (match_flag == report_success) {
            printf("report to Tencent IoT Explorer success\r\n");
        
        }else if (match_flag == report_fail){
            printf("report to Tencent IoT Explorer fail\r\n");
        }
        
        tos_task_delay(1000);
    }
}

3.3、程序源码

gitee地址:https://gitee.com/gtizhanghui/rt1062-tencentos.git

三、程序运行

3.1、CAN发送数据

程序运行CAN通信一直以1S间隔向外发送帧数据,表示CAN通信正常。手动发送CAN数据命令。

CAN收发
CAN收发

3.2、物联网数据监测平台接收的数据

物联网数据平台
物联网数据平台

3.3、手机腾讯连连小程序接收的数据

腾讯连连小程序
腾讯连连小程序

四、后记

通过此次活动实践后,对TencentOS Tiny和腾讯的网络平台有了了解,由于时间原因和对物联网传输的MQTT协议的了解不够深入,还有功能没有实现,自己设计的E53板有转CAN和RS485模块,只实现了CAN通信功能,后续在深入学习MQTT和TencentOS系统后,继续完善更多的功能。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
物联网开发平台
腾讯云物联网开发平台(IoT Explorer)是面向智慧生活与产业物联应用的一站式物联网PaaS平台,为各行业用户提供一站式设备智能化服务。平台提供海量设备连接与消息通信能力,基于腾讯连连小程序应用开发能力、音视频能力及AI增值服务,聚合腾讯生态内容能力。提升传统行业设备智能化的效率,降低用户的开发运维成本。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档