18-ESP8266 SDK Development Basics Introduction--TCP server RTOS version, serial port transparent transmission, TCP client control LED

https://www.cnblogs.com/yangfengwu/p/11112015.html

 

First stipulate the agreement

aa 55 02 01 F1 4C controls the LED to light up F1 4C is the high and low bits of CRC
aa 55 02 00 30 8C controls the LED to turn off 30 8C is the high and low bits of CRC

aa 55 03 Duty cycle (four bytes with high bit in front and low bit in back) CRC check high bit, CRC check low bit

 

Set aside a question. I use the client to send aa 55 11 00 00 01 F4 WIFI received F4 01 00 00 00 01 F4 

aa 55 10 XX XX XX but there is no problem, hasn't everyone encountered this situation??? Ask for answers

I think it is a coding problem

But i tried

 

 There will be problems with several codes, and all the debugging assistants I have on hand have problems.. So do not do the PWM first, first control the LED to turn on and off

 

 

Change the agreement

00 01 70 C0 Controls the LED to light up 70 C0 is the high and low bits of CRC
00 00 B0 01 Controls the LED to go out B0 01 is the high and low bits of CRC

 

 

First, modify a small bug. In fact, we don't need to use this section, but the problem found during the test...

 

 

 

Now implement a function of transparent transmission (data sent by the TCP client is directly forwarded to the serial port after being received by the TCP server; the data received by the serial port is directly sent to the TCP client by the TCP server)

Let me talk about it first, our sending is also executed by a task

But when must this sending task be created???

After the client connects, create a sending task for this client

 

 The main reason is to avoid that the variables in the sending task do not actually exist when they come in... so create this task after the client is connected

 

Then, there is a problem to be solved. Assuming that the client is offline, should we delete the sending task?

and so

In fact, the last variable when creating a task, you can fill in this variable

 

 Then delete this task is

 

 

 

 

In fact, there is no big difference from the previous version of the program, that is, the difference above

Another is that I set the previous local variables to global

 

 

 By the way actually

These two must be global, because I can use it when sending

 

 In fact, there is nothing else... (provided that you have learned all of my previous articles)

Copy code

/*
 * ESPRSSIF MIT License
 *
 * Copyright (c) 2015 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
 *
 * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
 * it is free of charge, to any person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all copies or
 * substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include "esp_common.h"
#include "gpio.h"
#include "uart.h" 
#include "esp_timer.h" 
#include "hw_timer.h" 
#include "pwm.h" 
#include "data_dispose.h" 
xTaskHandle xHandleTcpSendDate;//The handle of the sending data task,I use 
err_t err to delete sending tasks ;//Receive error messages returned when operating all API functions
#include "espconn.h" 
#include "esp_wifi.h" 
#include "lwip/api.h" 


//typedef void (*UartCallback)(void); 


extern u8 Usart1ReadBuff[Usart1ReadLen];//Receive data array 
extern u32 Usart1ReadCnt;//Number of data received by serial port 1 
extern u32 Usart1ReadCntCopy;//Number of copies of data received by serial port 1 
extern u8 Usart1ReadFlage; //Serial port 1 received a complete data 


#define SSID "Learn8266" //Wireless name 
#define PWD "11223344" //Password 
struct softap_config soft_ap_Config;//AP mode configuration



struct netconn *conn, *newconn;//conn saves the information of its own TCP server newconn- saves the information of the connected client 
int i = 0; 
struct pbuf *q;//Use this variable to manipulate the linked list, you can look at https:// www.cnblogs.com/yangfengwu/p/5778872.html 
u32 data_len =0;//Get the number of received data 
unsigned char TcpRead[1024]={0};//Receive data buffer array, maximum receiving 1024 bytes 
struct netbuf *recvbuf;//Create a structure for receiving data, which is used for buffering data provided by lwip 


/************************** ************************************************** ** 
 * FunctionName: user_rf_cal_sector_set 
 * Description: SDK just reversed 4 sectors, used for rf init data and paramters. 
 * We add this function to force users to set rf cal sector, since 
 * we don't know which sector is free in user's application. 
 * sector map for last several sectors: ABCCC 
 * A: rf cal 
 * B: rf init data 
 * C: sdk parameters 
 * Parameters: none 
 * Returns: rf cal sector 
********* ************************************************** ********************/ 
uint32 user_rf_cal_sector_set(void) 
{ 
    flash_size_map size_map = system_get_flash_size_map(); 
    uint32 rf_cal_sec = 0; 

    switch (size_map) {
        Case FLASH_SIZE_4M_MAP_256_256: 
            rf_cal_sec = 128 -. 5; 
            BREAK; 

        case FLASH_SIZE_8M_MAP_512_512:
            rf_cal_sec = 256 - 5;
            BREAK; 

        Case FLASH_SIZE_16M_MAP_512_512: 
        Case FLASH_SIZE_16M_MAP_1024_1024: 
            rf_cal_sec = 512 -. 5; 
            BREAK; 

        Case FLASH_SIZE_32M_MAP_512_512: 
        Case FLASH_SIZE_32M_MAP_1024_1024: 
            rf_cal_sec = 1024 -. 5; 
            BREAK; 

        default: 
            rf_cal_sec = 0; 
            BREAK; 
    } 

    return rf_cal_sec; 
} 

//Serial port calling this function means that a complete piece of data has been received, and it can be processed 
void UartReadCallback()//Define a function 
{ 

} 

//Send data task
void TcpSendDateThread(void *date) 
{ 
    conn->send_timeout=5;//Set the sending timeout time , Must be added, otherwise the task will be blocked
    while(1) 
    { 
        if(Usart1ReadFlage)//Serial port receives a complete data 
        { 
            Usart1ReadFlage = 0; 
            err = netconn_write(newconn ,Usart1ReadBuff, Usart1ReadCntCopy ,NETCONN_COPY);//Send data 
            if(err != ERR_OK) 
            { 
                // Sending failed 
            } 
        } 
        vTaskDelay(10/portTICK_RATE_MS);//If there is no data to send, this will be executed, and this task delay must be added. 
    } 
    vTaskDelete(NULL); 
} 



void TcpServerThread(void *date) 
{ 
    static ip_addr_t ipaddr;/ /Store the address of the client 
    static u16_t port;//store the port number of the client 

    conn = netconn_new(NETCONN_TCP);//create a TCP

    //Attention, first of all, you must understand that whether you create a TCP server or client, or UDP, you must set the IP address and port number of the TCP server or client, or UDP. 
    //Communication between networks, This is necessary. Only if you have an IP and port number, others can communicate with you 
    netconn_bind(conn,IP_ADDR_ANY,8888); //Set the IP address of conn (TCP server) to the IP on your own network card. Set TCP server communication the port number is 8888 (regardless created TCP server or client, or UDP, are required) 

    netconn_listen (conn); // use the monitor function, indicating that create a TCP server, just as the server is to listen for client connections Well 

    // Set the task blocking time to 10ms (note, this is similar to vTaskDelay(10/portTICK_RATE_MS), but you must use this 
    //netconn_accept(conn,&newconn); function is completely blocked, if you don't set conn-> The recv_timeout program stops there, unless there is a client connection 
    conn->recv_timeout=5;//task delay 5ms 
    while(1) 
    { 
        err = netconn_accept(conn,&newconn);//Waiting for the client to connect, there is a client If connected or timed out, it will execute 
        if (err == ERR_OK)//Only the client is connected and there are no other errors before entering 
        (
            netconn_getaddr(newconn,&ipaddr,&port,0); //Get the client's IP address and port number. The last parameter 1 gets the local IP address, and 0 gets the remote IP address. 
            //Print the client's IP address 
            printf("ClientIP:%d. %d.%d.%d Connected\n",(uint8_t)(ipaddr.addr),(uint8_t)(ipaddr.addr >> 8),(uint8_t)(ipaddr.addr >> 16),(uint8_t)( ipaddr.addr >> 24)); 
            printf("Port:%d\n",port);//Print the port number of the client 


            xTaskCreate(TcpSendDateThread, "TcpSendDateThread", 1024, NULL, 9, &xHandleTcpSendDate);//Create Send data task 

            while(1)//Always receive and process data in this 
            { 
                err = netconn_recv(newconn,&recvbuf);//If the data has not been received or it is not other error information, it will not execute 
                if(err== ERR_OK)//Receive the data sent by the client 
                {
                    taskENTER_CRITICAL();//Turn off interrupts, prohibit other tasks from interrupting, and prevent errors in reading data 

                    data_len = 0; 
                    for( q = recvbuf->p; q != NULL; q = q->next) // Traverse the complete one pbuf linked list 
                    { 
                        //Determine whether the data to be copied to the cache array is greater than the remaining space of the cache array, if it is greater than 
                        // then only copy the remaining length of the data in the cache array, otherwise copy all the data 
                        if( q-> len> (1024-data_len)) 
                              memcpy(TcpRead+data_len,q->payload,(1024-data_len));//copy data 
                        else 
                                memcpy( TcpRead+data_len, q->payload, q->len ); 
                        data_len + = q->len; 
                        if(data_len> 1024)//Exceed the TCP client receiving array, jump out
                        break; 
                    } 

                    taskEXIT_CRITICAL();//Open interrupt 

                    for(i=0;i<data_len;i++) 
                    { 
                        USART_SendData(UART0, TcpRead[i]);//Send the received data to the serial port 
                    } 
                } 
                else if(err == ERR_CLSD) //The client disconnects 
                { 
                    vTaskDelete(xHandleTcpSendDate);//Delete the sending data task 
                    netconn_close(newconn);//Close the connection 
                    netconn_delete(newconn);//Delete the connection
                    printf("ClientIP:%d.%d.%d.%d Disconnected\n",(uint8_t)(ipaddr.addr),(uint8_t)(ipaddr.addr >> 8),(uint8_t)(ipaddr.addr >> 16),(uint8_t)(ipaddr.addr >> 24));
                    break;//退出
                }
            }
        }
        else
        {
            conn->recv_timeout=10;//任务延时10ms
        }
    }
    vTaskDelete(NULL);
}



void LedThread(void *date)
{
    while(1)
    {
        vTaskDelay(1000/portTICK_RATE_MS);
        GPIO_OUTPUT_SET(2,1-GPIO_INPUT_GET(2));
    }
    vTaskDelete(NULL);
}

/************************************************* ***************************** 
 * FunctionName: user_init 
 * Description: entry of user application, init user function here 
 * Parameters: none 
 * Returns: none 
*********************************************** ********************************/ 
void user_init(void) 
{ 
    GPIO_OUTPUT_SET(5, 1); 
    GPIO_OUTPUT_SET(2, 0);//Make the initial state of the two lights the same, GOIO2 is reversed, and it is on when it is 0 
// GPIO_OUTPUT_SET(5, 0); 
    uart_init_new(); 
    printf("SDK version:%s\n", system_get_sdk_version()); 
// printf("Ai-Thinker Technology Co. Ltd.\r\n%s %s\r\n", __DATE__, __TIME__); 
// printf("Hello,World!\r\n ");
// xTaskCreate(LedControl, "LedControl", 1024, NULL, 11, NULL); 
    wifi_set_opmode(STATIONAP_MODE);//Configure WiFi mode STATION + AP AP--connect to WIFI itself to realize wireless communication STATION--wifi connect to router, The mobile phone or computer is also connected to the router to realize communication 
    soft_ap_Config.ssid_len = strlen(SSID);//The length of the hotspot name is the same as your actual name length 
    memcpy(soft_ap_Config.ssid,SSID,soft_ap_Config.ssid_len);//The actual hotspot Name setting, you can set 
    memcpy(soft_ap_Config.password,PWD,strlen(PWD));//hotspot password setting 
    soft_ap_Config.authmode = AUTH_WPA2_PSK;//Encryption mode 
    soft_ap_Config.channel = 1;//channel, total support 1~13 channels 
    soft_ap_Config.max_connection = 4;//Maximum number of connections, maximum support four, default four 

    wifi_softap_set_config_current(&soft_ap_Config);//Set Wi-Fi SoftAP interface configuration, not save to Flash 
    // wifi_softap_set_config(&soft_ap_Config) ;//Set Wi-Fi SoftAP interface configuration and save to Flash

    //You can understand the following function when you click in and look at the comments. 
// espconn_init();//"espconn.h" Line 195 
// TcpServer.type = ESPCONN_TCP; //Create TCP 
// TcpServer.state = ESPCONN_NONE; / /The initial state 
// TcpServer.proto.tcp = &esptcp; //Set up TCP IP and callback function storage 
// TcpServer.proto.tcp->local_port = 8888;//Monitor port number 
// espconn_regist_connectcb(&TcpServer , TcpServerListen);//Register 
// espconn_accept(&TcpServer);//Start listening 
    UartCallbackRegister(UartReadCallback);//Pass the UartReadCallback function address and call 


    xTaskCreate(TcpServerThread, "TcpServerThread", 1024, NULL, 8, NULL); 


    xTaskCreate(LedThread, "LedThread", 1024, NULL, 11, NULL); 
}

Copy code

 

test

       

 

 

 

 

 Now write the program that controls the light to turn on and off

00 01 70 C0 Controls the LED to light up 70 C0 is the high and low bits of CRC
00 00 B0 01 Controls the LED to go out B0 01 is the high and low bits of CRC

 

simplest

 

 

Copy code

// 00 01 70 C0 controls the LED to light up 70 C0 is the CRC high and low bits 
// 00 00 B0 01 controls the LED to turn off B0 01 is the CRC high and low bits 
                    if(TcpRead[0] == 0) 
                    { 
                        if(TcpRead[1] == 0x01 && TcpRead[2] == 0x70 && TcpRead[3] == 0xC0 )//Control the LED to light up 
                        { 
                            GPIO_OUTPUT_SET(5,1); 
                        } 
                        else if(TcpRead[1] == 0x00 && TcpRead[2] == 0xB0 && TcpRead[3] == 0x01 )//Control the LED to go out 
                        { 
                            GPIO_OUTPUT_SET(5,0); 
                        } 
                    }

Copy code

 

test

 

 

 

 

 

 

 

 

 Okay, let's do C# TCP client in the next section to control LED

 

Let’s talk about it, let’s not serve the CRC... let’s learn it simply

I gave you a calculation tool

 

 

 

 

https://www.cnblogs.com/yangfengwu/p/11192594.html

Guess you like

Origin blog.csdn.net/qq_14941407/article/details/96325591