(加入了信号量、StreamBuffer队列、软件定时器)FreeRTOS 阿里云MQTT 上报温湿度 下行命令控制led三色灯

(简单版)FreeRTOS 阿里云MQTT 上报温湿度 下行命令控制led三色灯

注意:反复检查+测试之后,程序还是跑不起来的话,一定是栈的问题

           软件定时器的栈也要设大点,否则跑不起来

设置了三个任务,一个软件定时器(周期为20s)

入口函数

优先级

任务1

mqttTask06

5

挂起态

任务2

ReceiveTask5

4

信号量、发送队列xStreamBufferReceive()

任务3

buffer_task03

3

信号量、接收队列xStreamBufferSend()

任务1

void mqttTask06(void const * argument)
{
  /* USER CODE BEGIN mqttTask06 */
  /* Infinite loop */
  for(;;)
  {
	  	int               rv;

	  	char              ipaddr[16];
	  	char              gateway[16];
	  	unsigned char     wifi_flag=0;

      //连接WiFi
	  if(!(wifi_flag&FLAG_WIFI_CONNECTED))
	  {
		 if( esp8266_join_network(DEF_ROUTER_SSID,DEF_ROUTER_PWD))
		 {//0 is connect success
			 esp8266_module_init();
			 osDelay(2000);
			 continue;
		 }
		 if(esp8266_get_ipaddr(ipaddr,gateway,sizeof(ipaddr)))
		 {
			 osDelay(1000);
			 continue;
		 }
		 if(esp8266_ping_test(gateway))
		 {
			 osDelay(1000);
			 continue;
		 }
		 wifi_flag |= FLAG_WIFI_CONNECTED;
	  }

      //连接MQTT
	  if(!(wifi_flag&FLAG_SOCK_CONNECTED))
	  {
		  rv=mqtt_connect(MQTT_BROKER_HOSTNAME,MQTT_BROKER_PORT,MQTT_CLIENT_ID,MQTT_BROKER_USERNAME,MQTT_BROKER_PASSWORD);
		  if( rv )
		  {//0 is connect success
			  osDelay(2000);
			  continue;
		  }

		  mqtt_subscribe_topic(MQTT_SUB_TOPIC,Qos0,1);
		  wifi_flag |= FLAG_SOCK_CONNECTED;

		  xTimerChangePeriod(myTimer01Handle,20000,0);//定时器周期改为20s
		  xTimerStart(myTimer01Handle,0);//启动定时器
		  vTaskSuspend(NULL);//挂起(挂起自己)
	  }
  }
  /* USER CODE END mqttTask06 */
}

任务2 

void ReceiveTask5(void const * argument)
{
  /* USER CODE BEGIN buffer_task03 */
  /* Infinite loop */
  for(;;)
  {
	    unsigned char       buf[256];
		MQTTString          topicName;
		unsigned char       dup;
		int                 qos;
		unsigned char       retained;
		unsigned  short     msgid;
		unsigned  char     *payload = NULL;
		int                 payloadlen = 0;
		int                 rv;
	    char                correct_json[256]={0};
	    BaseType_t         xReturn=pdFALSE;

	    xReturn=xSemaphoreTake(myBinarySem01Handle,portMAX_DELAY);//获取信号量成功时,返回值为pdTRUE。否则进入阻塞状态
	    if( pdTRUE == xReturn )
	    {
	    	memset(buf,0,sizeof(buf));
	    	xStreamBufferReceive(xStreamBuffer,buf, sizeof(buf), portMAX_DELAY);
	    }

	    //报文解析
	    rv=MQTTDeserialize_publish(&dup,&qos,&retained,&msgid,&topicName,&payload,&payloadlen,buf,sizeof(buf));
		if( rv == 1)
		{
			printf("MQTT payload:%s\n",payload);
			aliyun_json((char *)payload,payloadlen,correct_json);//截取出标准的有效的JSON格式(代码下面有展示)
			parser_led_json(correct_json,strlen(correct_json));//JSON解析(代码下面有展示)
		}
		else
		{
			printf("ERROR:MQTTDeserialize_publish failure,rv=%d\n",rv);
		}
  /* USER CODE END buffer_task03 */
  }

任务三 

void buffer_task03(void const * argument)
{
  /* USER CODE BEGIN buffer_task03 */
  /* Infinite loop */
  for(;;)
  {
		unsigned char       buf[256];
		int                 packet_type;
	    int                 rv;

		memset(buf,0,sizeof(buf));
		if( (packet_type=MQTTPacket_read(buf,sizeof(buf),transport_getdata)) <0 )
		{
			printf("Wait aliyun command\n");
			osDelay(2000);
			continue;
		}

		if( PUBLISH == packet_type )
		{
			rv=xStreamBufferSend(xStreamBuffer,buf,sizeof(buf),portMAX_DELAY);
			if( !(rv>0) )
			{
				printf("ERROR:xStreamBufferSend\n");
			}
		}

		xSemaphoreGive( myBinarySem01Handle );
  }
  /* USER CODE END buffer_task03 */
}

软件定时器 回调函数 

//软件定时器的回调函数,定时 上报温湿度
void Callback01(void const * argument)
{
  /* USER CODE BEGIN Callback01 */
	int rv;

	rv=report_tempRH2_json();//sht20温湿度上报的函数(代码下面有展示)
	if( 0 == rv )
	{
		printf("ESP8266 MQTT publish message ok\n");
		clear_atcmd_buf();//清空串口接收的buffer
//因为每次上报成功后,阿里云会反馈一段数据回来,若此时收到阿里云下发控制led灯的命令也存在buffer中,会导致buffer溢出
	}
  /* USER CODE END Callback01 */
}

温湿度上报函数(传感器是sht20)

/*sht20*/
int report_tempRH2_json(void)
{
	char   buf[128];
	float  temperature,humidity;
	int    rv;

	if( (sht20_sample_temp_or_hum(0xF3,&temperature) <0 ) || (sht20_sample_temp_or_hum(0xF5,&humidity) <0 ))
	{
		printf("ERROR:sht20 sample data failure\n");
		return -1;
	}

	memset(buf,0,sizeof(buf));
	snprintf(buf,sizeof(buf),"{\"params\":{\"CurrentTemperature\":%.2f,\"CurrentHumidity\":%.2f}}",temperature,humidity);
	rv=mqtt_publish(MQTT_PUB_TOPIC,Qos0,buf);
	printf("MQTT publish topic [%s] with msg '%s'%s,rv=%d\n",MQTT_PUB_TOPIC,buf,rv? "failure":"ok",rv);

	return rv;
}

sht20.c 

/*
 * sht20.c
 */
#include "sht20.h"
#include <stdio.h>
#include "stm32l4xx_hal.h"
#include "tim.h"

#define CONFIG_GPIO_I2C
#ifdef  CONFIG_GPIO_I2C
#include "gpio_i2c.h"   /*GPIO模拟I2C*/
#else
#include "i2c.h"        /* I2C */
#endif

int sht20_sample_temp_or_hum(int cmd, float  *data)
{
	uint8_t           buf[2];
	unsigned short    sht20_data=0;
	int               rv;

#ifdef CONFIG_GPIO_I2C
	/*主设备向发送从设备地址信号,这里sht20的写地址是0x80,成功则返回1个字节*/
	rv=I2C_Master_Transmit(0x80,&cmd,1);
#else
	rv=HAL_I2C_Master_Transmit(&hi2c1,0x80,&cmd,1,0xFF);
#endif

	if(0!=rv)
		return -1;

	if(cmd==0xF3)/*SHT20_NO_MEASURE_TEMP_CMD=0xF3 触发温度测量,非主机模式*/
		HAL_Delay(85);
	else if(cmd==0xF5)/*SHT20_NO_MEASURE_RH_CMD=0xF5 触发湿度测量,非主机模式*/
		HAL_Delay(29);

#ifdef CONFIG_GPIO_I2C
	/*主设备向发送从设备地址信号,这里sht20的读地址是0x81,成功则返回2个字节,分别是温湿度的整数和小数,并且数据放在buf中*/
	rv=I2C_Master_Receive(0x81,buf,2);
#else
	rv=HAL_I2C_Master_Receive(&hi2c1,0x81,buf,2,0xFF);
#endif

	if(0!=rv)
		return -1;

	sht20_data=buf[0];
	sht20_data=(sht20_data<<8);
	sht20_data+=buf[1]&0xFC;
	if(cmd==0xF3)
	{
		*data= -46.85+175.72*((float)sht20_data/65536);//计算
		//printf("Temperature=%d\n",sht20_data);
	}
	else if(cmd==0xF5)
	{
		*data= -6.0+125.0*((float)sht20_data/65536);//计算
		//printf("Humidity=%d\n",sht20_data);
	}
	return *data;
}

 截取出标准的有效的JSON格式

int aliyun_json(char *payload,int payloadlen,char *correct_json)
{
	char    *ptr=NULL, *start=NULL, *end=NULL;

	ptr=strstr(payload,"LEDRGB");
	start=strchr(ptr,'{');
	end=strchr(ptr,'}');
	end++;

	if( start==NULL || end==NULL || start>end )
	{
		printf("ERROR:str not find\n");
		HAL_Delay(2000);
		return 0;
	}
	else
	{
		memcpy(correct_json,start,end-start);
	}

	return 0;
}

 JSON解析

int parser_led_json(char *json_string,int bytes)
{
	JSONStatus_t  result;
	char          save;
	char          *value;
	size_t        valen;
	int           i;

	printf("DBUG:Start parsar JSON string:%s\r\n",json_string);

	result=JSON_Validate(json_string,bytes);
	if(JSONPartial==result)
	{
		printf("WARN:JSON document is valid so far but incomplete!\r\n");
		return 0;
	}
	if(JSONSuccess!=result)
	{
		printf("ERROR:JSON document is valid JSON!\r\n");
		return -1;
	}

	for(i=0;i<LedMax;i++)
	{
		result=JSON_Search(json_string,bytes, leds[i].name,strlen(leds[i].name),&value,&valen);

		if(JSONSuccess==result)
		{
			save = value[valen];
			value[valen]='\0';

			if(!strncasecmp(value,"on",2))
			{
				printf("DBUG:turn %s ON \r\n",leds[i].name);
				turn_led(i,ON);

			}
			else if(!strncasecmp(value,"off",3))
			{
				printf("DBUG:turn %s OFF \r\n",leds[i].name);
				turn_led(i,OFF);
			}

			value[valen]=save;
		}
	}
	return 1;
}

 上层的MQTT订阅和发送功能代码 core_mqtt.c

/*+---------------+
 *|     MQTT      |
  +---------------*/
#include "core_mqtt.h"
#include "stm32l4xx_hal.h"
#include <stdio.h>
#include <string.h>

int mqtt_connect(char *host,int port,char *clientid,char *username,char *passwd)
{
	MQTTPacket_connectData     data=MQTTPacket_connectData_initializer;
	int                        rv;
	unsigned char              buf[256];
	unsigned char              sessionPresent;
	unsigned char              connack_rc;

	if(!host || port<=0 || !clientid )
	{
		printf("ERROR:Invalid input arguments\n");
	}

	if((rv=transport_open(host,port))<0)
	{
		printf("socket connect [%s:%d] failure,rv=%d\n",host,port,rv);
		return rv;
	}

	data.clientID.cstring=clientid;
	data.keepAliveInterval=MQTT_KEEP_ALIVE_TIMEOUT_SECONDS;
	data.cleansession=1;

	if( username && passwd)
	{
		data.username.cstring=username;
		data.password.cstring=passwd;
	}

	rv=MQTTSerialize_connect(buf,sizeof(buf),&data);
	if( rv<0 )
	{
		printf("MQTTSerialize_connect failure,rv=%d\n",rv);
		return -1;
	}

	if ( rv != transport_sendPacketBuffer(buf,rv) )
	{
		printf("transport_sendPackBuffer for mqtt_connect failure,rv=%d\n",rv);
		return -2;
	}

	HAL_Delay(800);

	memset(buf,0,sizeof(buf));
	rv=MQTTPacket_read(buf,sizeof(buf),transport_getdata);
	if(CONNACK != rv)
	{
		printf("MQTTPacket_read for MQTT CONNACK failure,rv=%d\n",rv);
		return -3;
	}

	if((rv=MQTTDeserialize_connack(&sessionPresent,&connack_rc,buf,sizeof(buf))) !=1 || connack_rc!=0)
	{
		printf("MQTTDeserialize_connack failire,rv=%d\n",rv);
		return -4;
	}

	return 0;
}

int mqtt_disconnect(void)
{
	int          rv;
	unsigned     buf[256];

	rv=MQTTSerialize_disconnect(buf,sizeof(buf));
	if(rv < 0 )
	{
		printf("MQTT_Serialize_disconnect failure,rv=%d\n",rv);
		return -1;
	}

	if( rv != transport_sendPacketBuffer(buf,rv) )
	{
		printf("transport_sendPacketBuffer for mqtt_disconnect failure,rv=%d\n",rv);
		return -2;
	}

	return 0;
}

int mqtt_subscribe_topic(char *topic,int qos,int msgid)
{
	MQTTString        topicString = MQTTString_initializer;
	unsigned short    submsgid;
	int               subcount,granted_qos;
	int               rv;
	unsigned char     buf[256];

	topicString.cstring = topic;

	rv=MQTTSerialize_subscribe(buf,sizeof(buf),0,msgid,1,&topicString,&qos);
	if( rv<0 )
	{
		printf("MQTTSerialize_subscribe failure,rv=%d\n",rv);
		return -1;
	}

	if( rv != transport_sendPacketBuffer(buf,rv) )
	{
		printf("transport_sendPacketBuffer for  mqtt_subscribe_topic failure,rv=%d\n",rv);
		return -2;
	}

	HAL_Delay(800);

	memset(buf,0,sizeof(buf));
	rv=MQTTPacket_read(buf,sizeof(buf),transport_getdata);
	if(SUBACK != rv)
	{
		printf("MQTTPacket_read for MQTT SUBACK failure,rv=%d\n",rv);
		return -3;
	}

	rv=MQTTDeserialize_suback(&submsgid,1,&subcount,&granted_qos,buf,sizeof(buf));
	if( !rv || submsgid!=msgid || granted_qos == 0x80)
	{
		printf("MQTTDeserialize_suback failure,rv=%d\n",rv);
		return -4;
	}

	printf("mqtt_subscribe_topic ok\n");
	return 0;
}

int mqtt_unsubscribe_topic(char *topic,int msgid)
{
	MQTTString        topicString = MQTTString_initializer;
	unsigned short    submsgid;
	int               rv;
	unsigned char     buf[256];

	rv=MQTTSerialize_unsubscribe(buf,sizeof(buf),0,msgid,1,&topicString);
	if( rv<0 )
	{
		printf("MQTTSerialize_unsubscribe failure,rv=%d\n",rv);
		return -1;
	}

	if( rv != transport_sendPacketBuffer(buf,rv) )
	{
		printf("transport_sendPacketBuffer for  mqtt_unsubscribe_topic failure,rv=%d\n",rv);
		return -2;
	}

	HAL_Delay(800);

	memset(buf,0,sizeof(buf));
	rv=MQTTPacket_read(buf,sizeof(buf),transport_getdata);
	if( UNSUBACK != rv )
	{
		printf("MQTTPacket_read for MQTT UNSUBACK failure,rv=%d\n",rv);
		return -3;
	}

	rv=MQTTDeserialize_unsuback(&submsgid,buf,sizeof(buf));
	if( !rv || submsgid!=msgid )
	{
		printf("MQTTDeserialize_unsuback failure,rv=%d\n",rv);
		return -4;
	}

	return 0;
}

int mqtt_publish(char *topic,int qos,char *payload)
{
	MQTTString         topicString = MQTTString_initializer;
	int                rv;
	unsigned char      buf[256];
	unsigned char      dup=0;
	unsigned char      retained=0;
	unsigned short     packetid=0;

	topicString.cstring = topic;

	rv=MQTTSerialize_publish(buf,sizeof(buf),dup,qos,retained,packetid,topicString,(unsigned char*)payload,strlen(payload));
	if( rv<0 )
	{
		printf("MQTTSerialize_publish failure,rv=%d\n",rv);
		return -1;
	}

	if( rv != transport_sendPacketBuffer(buf,rv) )
	{
		printf("transport_sendPacketBuffer for MQTTSerialize_publish failure,rv=%d\n",rv);
		return -2;
	}

	HAL_Delay(800);

	memset(buf,0,sizeof(buf));
	rv=MQTTPacket_read(buf,sizeof(buf),transport_getdata);
	if( PUBLISH!=rv && -1!=rv )
	{
		printf("MQTTPacket_read for MQTT PUBLISH failure,rv=%d\n",rv);
		return -3;
	}

	return 0;
}

int mqtt_pingreq(void)
{
	int                rv;
	unsigned char      buf[256];

	rv=MQTTSerialize_pingreq(buf,sizeof(buf));
	if( rv<0 )
	{
		printf("MQTTSerialize_pingreq failure,rv=%d\n",rv);
		return -1;
	}

	if( rv != transport_sendPacketBuffer(buf,rv) )
	{
		printf("transport_sendPacketBuffer for MQTTSerialize_pingreq failure,rv=%d\n",rv);
		return -2;
	}

	HAL_Delay(800);

	memset(buf,0,sizeof(buf));
	rv=MQTTPacket_read(buf,sizeof(buf),transport_getdata);
	if( PINGRESP!=rv )
	{
		printf("MQTTPacket_read for MQTT PINGRESP failure,rv=%d\n",rv);
		return -3;
	}

	return 0;
}

底层的MQTT消息发送代码 transport.c

#include "transport.h"
#include "esp8266.h"
#include <string.h>

static unsigned char     s_sock_buf[256];
static int               s_rx_bytes;

int transport_open(char* addr,int port)
{
	return esp8266_sock_connect(addr,port)? -1 : 0 ;
}

int transport_close(void)
{
	return esp8266_sock_disconnect();
}

int transport_sendPacketBuffer(unsigned char* buf,int buflen)
{
	return esp8266_sock_send(buf,buflen);
}

int transport_getdata(unsigned char* buf,int count)
{
	int     rv=0;

	if( !s_rx_bytes )
	{
		rv=esp8266_sock_recv(s_sock_buf,sizeof(s_sock_buf));


		if( !rv )
		{
			return 0;
		}

		s_rx_bytes =rv;

	}

	rv= count > s_rx_bytes ? s_rx_bytes : count;

	memcpy(buf,s_sock_buf,rv);
	s_rx_bytes -= rv;

	if( s_rx_bytes > 0 )
	{
		memmove(s_sock_buf,&s_sock_buf[rv],s_rx_bytes);
	}

	return rv;
}

void transport_clearBuf(void)
{
	memset(s_sock_buf,0,sizeof(s_sock_buf));
	s_rx_bytes = 0;
}

底层的消息发送接收 esp8266.c

/*
 * esp8266.c
 */
#include "esp8266.h"

//#define CONFIG_WIFI_DEBUG
#define CONFIG_WIFI_PRINT

#ifdef CONFIG_WIFI_DEBUG
#define wifi_dbg(format,args...) printf(format,##args)
#else
#define wifi_dbg(format,args...) do{} while(0)
#endif

#ifdef CONFIG_WIFI_PRINT
#define wifi_print(format,args...) printf(format,##args)
#else
#define wifi_print(format,args...) do{} while(0)
#endif

int send_atcmd(char *atcmd,char *expect_reply,unsigned int timeout)
{
	int          rv= 1;
	unsigned     int i;
	char         *expect;

	if( !atcmd || strlen(atcmd)<=0 )
	{
		wifi_print("ERROR:Invalid input arguments\r\n");
	}

	wifi_dbg("\r\n Start send AT command:%s,atcmd");
	clear_atcmd_buf();
	HAL_UART_Transmit(wifi_huart,(uint8_t *)atcmd,strlen(atcmd),1000);

	expect=expect_reply ? expect_reply : "OK\r\n";

	for(i=0;i<timeout;i++)
	{
		if(strstr(g_wifi_rxbuf,expect))
		{
			wifi_dbg("AT command Got expect replay '%s'\r\n",expect);
			rv = 0;
			goto CleanUp;
		}
		if(strstr(g_wifi_rxbuf,"ERROR\r\n") || strstr(g_wifi_rxbuf,"FAIL\r\n"))
		{
			rv = 2;
			goto CleanUp;
		}

		HAL_Delay(1);
	}

CleanUp:
	wifi_dbg("<<<< AT command replay:\r\n%s",g_wifi_rxbuf);
	return rv;
}

int atcmd_send_data(unsigned char *data,int bytes,unsigned int timeout)
{
	int               rv= -1;
	unsigned int      i;

	if( !data || bytes<=0 )
	{
		wifi_print("ERROR: Invalid input arguments\r\n");
		return -1;
	}

	wifi_dbg("\r\n Start AT command send [%d] bytes data\n,bytes");
	clear_atcmd_buf();
	HAL_UART_Transmit(wifi_huart,(uint8_t *)data,bytes,1000);

	for(i=0;i<timeout;i++)
	{
		if(strstr(g_wifi_rxbuf,"SEND OK\r\n"))
		{
			rv = 0;
			goto CleanUp;
		}
		if(strstr(g_wifi_rxbuf,"ERROR\r\n"))
		{
			rv = 1;
			goto CleanUp;
		}

		HAL_Delay(1);
	}

CleanUp:
	wifi_dbg("<<<< AT command replay:\r\n%s",g_wifi_rxbuf);
	return rv;
}

int esp8266_module_init(void)
{
	int    i;

	wifi_print("INFO:Reset ESP8266 module now...\r\n");
	send_atcmd("AT+RST\r\n",EXPECT_OK,500);

	for(i=0;i<6;i++)
		{
			if(!send_atcmd("AT\r\n",EXPECT_OK,500))//0 is success
			{
				wifi_print("INFO:Send AT to ESP8266 and Got replay ok\r\n");
				break;
			}
			HAL_Delay(100);
		}
	if(i>=6)
	{
		wifi_print("ERROR:Can't receive AT replay after reset\r\n");
		return -2;
	}

	if(send_atcmd("AT+CWMODE=1\r\n",EXPECT_OK,500))//0 is success
	{
		wifi_print("ERROR:Set ESP8266 work as Station mode failure\r\n");
		return -3;
	}

	if(send_atcmd("AT+CWDHCP=1,1\r\n",EXPECT_OK,500))//0 is success
	{
		wifi_print("ERROR:Enable ESP8266 Station mode DHCP failure\r\n");
		return -4;
	}

#if 0
	if(send_atcmd("AT+GMR\r\n",EXPECT_OK,500))//0 is success
	{
		wifi_print("ERROR:AT+GMR check ESP8266 reversion failure\r\n");
		return -5;
	}
#endif

	HAL_Delay(500);
	return 0;
}

int esp8266_join_network(char *ssid,char *pwd)
{
	char   atcmd[128]={0x00};
	int    i;


	if( !ssid || !pwd)
	{
		wifi_print("ERROR:Invalid input arguments\r\n");
		return -1;
	}

	snprintf(atcmd,sizeof(atcmd),"AT+CWJAP=\"%s\",\"%s\"\r\n",ssid,pwd);

	if( send_atcmd(atcmd,"CONNECTED",10000) )
	{
		wifi_print("ERROR:ESP8266 connect to '%s' failure\r\n",ssid);
	}
	wifi_print("INFO:ESP8266 connect to '%s' ok\r\n",ssid);

	for(i=0;i<10;i++)
	{
		if( !send_atcmd("AT+CIPSTA?\r\n","255.",1000))
		{
			wifi_print("INFO:ESP8266 go to IP address ok\r\n");
			return 0;
		}
		HAL_Delay(300);
	}

	wifi_print("ERROR:ESP8266 assigned IP address failure\r\n");
	return -3;
}

/*
 * AT+CIPSTA:ip:"192.168.2.100"
 * AT+CIPSTA:gateway:"192.168.2.1"
 */
static int util_parser_ipaddr(char *buf,char *key,char *ipaddr,int size)
{
	char     *start;
	char     *end;
	int      len;

	if(!buf || !key || !ipaddr)
	{
		return -1;
	}

	start =strstr(buf,key);/*ָ��ip���׵�ַi*/
	if(!start)
	{
		return -2;
	}
	start+=strlen(key)+1;/*ָ�š��ĵ�ַ*/
	end=strchr(start,'"');
	if(!end)
	{
		return -3;
	}

	len= end - start;
	len= len>size?size:len;

	memset(ipaddr,0,size);
	strncpy(ipaddr,start,len);

	return 0;
}

int esp8266_get_ipaddr(char *ipaddr,char *gateway,int ipaddr_size)
{
	if(!ipaddr || !gateway || ipaddr_size<7)
	{
		wifi_print("ERROR:Invalid input arguments\r\n");
		return -1;
	}

	if( send_atcmd("AT+CIPSTA?\r\n","255.",1000))
	{
		wifi_print("ERROR: ESP8266 AT+CIPSTA? command failure\r\n");
		return -2;
	}

	if(util_parser_ipaddr(g_wifi_rxbuf,"ip:",ipaddr,ipaddr_size))
	{
		wifi_print("ERROR: ESP8266 AT+CIPSTA?  parser IP address failure\r\n");
		return -3;
	}

	if(util_parser_ipaddr(g_wifi_rxbuf,"gateway:",gateway,ipaddr_size))
	{
		wifi_print("ERROR: ESP8266 AT+CIPSTA?  parser gateway failure\r\n");
		return -4;
	}

	wifi_print("INFO:ESP8266 got IP address [%s] gateway[%s] ok\r\n",ipaddr,gateway);
	return 0;

}

int esp8266_ping_test(char *host)
{
	char    atcmd[128]={0x00};

	if(!host)
	{
		wifi_print("ERROR:Invalid input arguments\r\n");
		return -1;
	}

	snprintf(atcmd,sizeof(atcmd),"AT+PING=\"%s\"\r\n",host);
	if(send_atcmd(atcmd,EXPECT_OK,3000))
	{
		wifi_print("ERROR:ESP8266 ping test [%s] failure\r\n",host);
		return -2;
	}

	wifi_print("INFO:ESP8266 ping test [%s] ok\r\n",host);
	return 0;
}

int esp8266_sock_connect(char *servip,int port)
{
	char    atcmd[128]={0x00};

	if(!servip || !port)
	{
		wifi_print("ERROR:Invalid input arguments\r\n");
		return -1;
	}

	send_atcmd("AT+CIPMUX=0\r\n",EXPECT_OK,1500);

	snprintf(atcmd,sizeof(atcmd),"AT+CIPSTART=\"TCP\",\"%s\",%d\r\n",servip,port);
	if(send_atcmd(atcmd,"CONNECT\r\n",1000))
	{
		wifi_print("ERROR:ESP8266 socket connect to [%s:%d] failure\r\n",servip,port);
		return -2;
	}

	wifi_print("INFO:ESP8266 socket connect to [%s:%d] ok\r\n",servip,port);
	return 0;
}

int esp8266_sock_disconnect(void)
{
	send_atcmd("AT+CIPCLOSE\r\n",EXPECT_OK,1500);
	return 0;
}

int esp8266_sock_send(unsigned char *data,int bytes)
{
	char   atcmd[128]={0x00};

	if(!data || bytes<=0)
	{
		wifi_print("ERROR:Invalid input arguments\r\n");
		return -1;
	}

	snprintf(atcmd,sizeof(atcmd),"AT+CIPSEND=%d\r\n",bytes);
	if(send_atcmd(atcmd,">",500))
	{
		wifi_print("ERROR:AT+CIPSEND command failure\r\n");
		return 0;
	}
	if(atcmd_send_data((unsigned char *)data,bytes,1000))
	{
		wifi_print("ERROR:AT+CIPSEND send data failure\r\n");
		return 0;
	}

	return bytes;
}

int esp8266_sock_recv(unsigned char *buf,int size)
{
	char     *data=NULL;
	char     *ptr=NULL;
	int      len;
	int      rv;
	int      bytes;


	if( !buf || size<=0 )
	{
		wifi_print("ERROR:Invalid input arguments\r\n");
		return -1;
	}

	if(g_wifi_rxbytes<=0)
	{
//		printf("g_wifi_rxbytes<=0\n");
//		HAL_Delay(2000);
		return 0;
	}

	if( !(ptr=strstr(g_wifi_rxbuf,"+IPD,")) || !(data=strchr(g_wifi_rxbuf,':')) )
	{
		return 0;
	}

//	printf("g_uart2_rxbuf:%s\n",g_uart2_rxbuf);

	data++;
	bytes = atoi(ptr+strlen("+IPD,"));

	len = g_wifi_rxbytes - (data-g_uart2_rxbuf);

	if( len < bytes )
	{
		wifi_dbg("+IPD data not receive over,receive again later ...\r\n");
		return 0;
	}

	memset(buf,0,size);
	rv=bytes>size?size:bytes;
	memcpy(buf,data,rv);
	clear_atcmd_buf();

	return rv;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值