SuperHouse / esp-open-rtos

Open source FreeRTOS-based ESP8266 software framework
BSD 3-Clause "New" or "Revised" License
1.52k stars 491 forks source link

http_get to post data to ThingsSpeak stops working randomly #701

Open peros550 opened 5 years ago

peros550 commented 5 years ago

The following code is based on the http_get example and works nicely for the most part. It is able to post data to ThingsSpeak server. Sometimes though, it may stop sending data after some days. Then, after a while it may start working again. The rest tasks of my application are responsive when the http_get task hangs.

Any ideas on how to troubleshoot?

#define WEB_SERVER "api.thingspeak.com"
#define API_KEY  "your key goes here" 
#define FIELD1 "field1=" //temp
#define FIELD2 "field2=" //hum
#define WEB_PORT "80"
#define WEB_PATH "/update?api_key="
volatile float old_humidity_value = 0.0, old_temperature_value = 0.0;

This is called by a software timer:

void call_things_process()
{

    int successes = 0, failures = 0;
    printf("HTTP get task starting...\r\n");

    while(1) {

        const struct addrinfo hints = {
            .ai_family = AF_UNSPEC,
            .ai_socktype = SOCK_STREAM,
        };
        struct addrinfo *res;

        printf("Running DNS lookup for %s...\r\n", WEB_SERVER);
        int err = getaddrinfo(WEB_SERVER, WEB_PORT, &hints, &res);

        if (err != 0 || res == NULL) {
            printf("DNS lookup failed err=%d res=%p\r\n", err, res);
            if(res)
            freeaddrinfo(res);
            failures++;
            break;
        }

#if LWIP_IPV6
        {
            struct netif *netif = sdk_system_get_netif(0);
            int i;
            for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
                printf("  ip6 %d state %x\n", i, netif_ip6_addr_state(netif, i));
                if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)))
                    printf("  ip6 addr %d = %s\n", i, ip6addr_ntoa(netif_ip6_addr(netif, i)));
            }
        }
#endif

        struct sockaddr *sa = res->ai_addr;
        if (sa->sa_family == AF_INET) {
            printf("DNS lookup succeeded. IP=%s\r\n", inet_ntoa(((struct sockaddr_in *)sa)->sin_addr));
        }
#if LWIP_IPV6
        if (sa->sa_family == AF_INET6) {
            printf("DNS lookup succeeded. IP=%s\r\n", inet6_ntoa(((struct sockaddr_in6 *)sa)->sin6_addr));
        }
#endif

        int s = socket(res->ai_family, res->ai_socktype, 0);
        if(s < 0) {
            printf("... Failed to allocate socket.\r\n");
            freeaddrinfo(res);
           failures++;
            break;
        }

        printf("... allocated socket\r\n");

        if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
            close(s);
            freeaddrinfo(res);
            printf("... socket connect failed.\r\n");
            failures++;
            break;
        }

        printf("... connected\r\n");
        freeaddrinfo(res);

        char temp2[10];
        snprintf(temp2, sizeof(temp2),"%2.2f", old_temperature_value );
        printf("%s \n",temp2);
        printf(temp2);

        char hum1[6];
        snprintf(hum1,sizeof(hum1), "%2.2f", old_humidity_value );
        printf("%s \n",hum1 );

        char req[300]="GET " WEB_PATH API_KEY "&" FIELD1;
        strncat(req,temp2,10);
         strncat(req,"&",2);
         strncat(req,FIELD2,20);
         strncat(req,hum1,6);
         strncat(req," HTTP/1.1\r\nHost: "WEB_SERVER"\r\nUser-Agent: esp-open-rtos/0.1 esp8266\r\nConnection: close\r\n\r\n",250);

        printf("%s \n",req );

        if (old_temperature_value ==0) 
        {
            break;
        }

         printf("%s \n",req );

        if (write(s, req, strlen(req)) < 0) {
            printf("... socket send failed\r\n");
            close(s);
            failures++;
            break;
        }
        printf("... socket send success\r\n");

        static char recv_buf[128];
        int r;
        do {
            bzero(recv_buf, 128);
            r = read(s, recv_buf, 127);
            if(r > 0) {
                printf("%s", recv_buf);
            }
        } while(r > 0);

        printf("... done reading from socket. Last read return=%d errno=%d\r\n", r, errno);
        close(s);
        printf("successes = %d failures = %d\r\n", successes, failures);        
        printf("\r\nEnding!\r\n");

        break;
    }
}