Creating a Tokyo Olympics Medal Tracker Using STM32

The Tokyo Olympics can be said to be the most special one in the history of the Olympics, postponed for a year, no audience, and an eco-friendly Olympics.

To keep track of the medal standings in real-time, I made a STM32 + ESP8266 desktop decoration for the Tokyo Olympics Medal Standings, and the final effect is as follows:

Creating a Tokyo Olympics Medal Tracker Using STM32
Creating a Tokyo Olympics Medal Tracker Using STM32
Creating a Tokyo Olympics Medal Tracker Using STM32

The principle is to use STM32 to drive ESP8266 to connect to the internet, then use the GET interface to read the returned JSON data, and then perform JSON parsing, and display it on an LCD. Using different interfaces allows for different functionalities.

Unlike before, the above two API interfaces return very short data, only a few hundred bytes, while the medal standings interface returns as much as 20KB of data. STM32 cannot handle such a large amount of data at once, so this article adopts a simple method to truncate the data to reduce the amount.

What content is included?

  • API Interface Acquisition
  • JSON Data Preprocessing
  • JSON Data Parsing
  • Display Effect

API Interface Acquisition

Before development, the first step is to find an API interface, preferably with a GET request method and returning data in JSON format. After searching online, I found that many netizens have implemented functions to get medal standings data, mostly using: Python, Java, PHP. The language doesn’t matter; what’s important is whether the API interface is what we want. Finally, I found two API interfaces.

The first interface is the official Tokyo Olympics special page from CCTV:

Creating a Tokyo Olympics Medal Tracker Using STM32

The URL is as follows:

http://2020.cctv.com/medal_list/index.shtml

Open the developer mode with F12 to find the API address requested by the page:

Creating a Tokyo Olympics Medal Tracker Using STM32

This interface returns 11KB of data, which formats to 24KB, in JSON format (part):

Creating a Tokyo Olympics Medal Tracker Using STM32

As can be seen, the data is quite complete, including ranking, gold, silver, bronze, total medal count, country ID, and country name encoded in UTF-16BE. However, the character library on the development board is GBK encoded, which is a bit challenging to handle. Let’s see if there are any other interfaces.

The second interface is the Olympic medal standings displayed on my Xiaomi phone’s negative one screen, similar to this:

Creating a Tokyo Olympics Medal Tracker Using STM32

You can open it in a browser:

http://act.e.mi.com/olympic/index.html

Open the developer mode with F12 to find the requested API address:

Creating a Tokyo Olympics Medal Tracker Using STM32

This interface returns 21KB of data, which formats to 33KB, in JSON format (part):

Creating a Tokyo Olympics Medal Tracker Using STM32
mi_json

This interface returns relatively rich data. Compared to CCTV’s data, it is larger and includes not only medal count rankings but also the image addresses of each country’s flag, update time, etc. The country name is UTF-8 encoded, which needs to be converted from UTF-8 to GBK for use on our development board.

In summary, we have obtained information from two API interfaces:

Olympic Medal Standings CCTV API Interface:

TYPE: "TCP"
PORT: "80"
IP  : "111.206.176.78"
API : "http://api.cntv.cn/olympic/getOlyMedals?serviceId=pcocean&itemcode=GEN-------------------------------"

Olympic Medal Standings Xiaomi Phone API Interface

TYPE: "TCP"
PORT: "80"
IP  : "111.206.101.253"
API : "http://act.e.mi.com/olympic/medal_rank"

To facilitate direct display of country names on the development board, we use the Xiaomi phone’s API interface.

JSON Data Preprocessing

By analyzing the data returned by the API interface, it includes medal data for the top 90 countries, with a data length of 21KB:

Creating a Tokyo Olympics Medal Tracker Using STM32
mi_json

However, we only need the data for the top 10 countries. The serial port interface buffer length is set to 2500 bytes, meaning that for the returned 21KB of data, we only receive the first 2500 bytes and then process it into standard JSON format.

The processing method is to reverse search for the position of the last } character, discard the data after {, and then add ]}, thus modifying the truncated 2500 bytes of data into standard JSON format data:

Creating a Tokyo Olympics Medal Tracker Using STM32
mi_json_deal

JSON Data Parsing

As can be seen from the above image, JSON format is quite simple, and using cJSON makes parsing very convenient. For usage, you can refer to the following article:

  • Using cJSON Library to Parse and Construct JSON Strings

Define a structure:

typedef struct medal{
    char rank[5];
    char countryname[50];
    char count[5];
    char gold[5];
    char silver[5];
    char bronze[5];
    char update_time[50];
    char countryid[10];
}medalObj;

The parsing function reads only the medal data for the top 7 countries:

uint8_t parse_mi_data(void)
{
    cJSON *root, *data_obj, *list_obj;
    char *str;
    char dest[USART2_MAX_RECV_LEN];
    char *loc;
    char gbk[50];
    char utf8[50];
    medalObj *pobj;
    medalObj obj;
    int idx;
    pobj = &obj;
    str = (char *)USART2_RX_BUF;
    memset(dest, '\0', USART2_MAX_RECV_LEN);
    loc = strrchr(str, '}');
    strncpy(dest, str, loc-str+1);
    strcat(dest, "]}");
    printf("json data size: %d bytes\r\n", strlen(dest));
    root = cJSON_Parse((const char*)dest);
    if(root != 0)
    {
        printf("JSON format ok, start parse!!!\r\n");
        data_obj = cJSON_GetObjectItem(root, "data");
        if(data_obj->type == cJSON_Array)
        {
            int size = cJSON_GetArraySize(data_obj);
            for(idx = 0; idx < size; idx++)
            {
                if(size >= 7 && idx <= 7)
                {
                    list_obj = cJSON_GetArrayItem(data_obj, idx);
                    strcpy(obj.bronze, cJSON_GetObjectItem(list_obj, "medal_bronze_count")->valuestring);
                    strcpy(obj.rank, cJSON_GetObjectItem(list_obj, "rank")->valuestring);
                    strcpy(obj.count, cJSON_GetObjectItem(list_obj, "medal_sum_count")->valuestring);
                    strcpy(obj.silver, cJSON_GetObjectItem(list_obj, "medal_silver_count")->valuestring);
                    //utf8->gbk
                    memset(utf8, '\0', sizeof(utf8));
                    memset(gbk, '\0', sizeof(gbk));
                    strcpy(utf8, cJSON_GetObjectItem(list_obj, "country_name")->valuestring);
                    SwitchToGbk(utf8, gbk);
                    strcpy(obj.countryname, gbk);
                    strcpy(obj.gold, cJSON_GetObjectItem(list_obj, "medal_gold_count")->valuestring);
                    strcpy(obj.update_time, cJSON_GetObjectItem(list_obj, "update_time")->valuestring);
                    printf("%s: %s %10s %s:%s-%s-%s\r\n",
                           pobj->rank, pobj->update_time, pobj->countryname,
                           pobj->count, pobj->gold, pobj->silver, pobj->bronze);
                        gui_show_data(48+idx*20, pobj);
                }
            }
            Show_Str_Mid(200, 225, (u8 *)pobj->update_time, 12, 120);
        } 
    }    
    else
    {
        printf("JSON format error:%s\r\n", cJSON_GetErrorPtr()); //Output JSON format error information
    }
    USART2_RX_STA = 0;
    memset(USART2_RX_BUF, 0, sizeof(USART2_RX_BUF));
    cJSON_Delete(root);
    return 0;
}

If parsing fails, it may be necessary to adjust the stack size in the startup file:

//startup_stm32f10x_hd.s
Stack_Size      EQU     0x00000C00
Heap_Size       EQU     0x00000200

Final Effect

Creating a Tokyo Olympics Medal Tracker Using STM32
Creating a Tokyo Olympics Medal Tracker Using STM32
Creating a Tokyo Olympics Medal Tracker Using STM32
Creating a Tokyo Olympics Medal Tracker Using STM32

Open Source Address

My development board has already been preloaded with a Chinese character library, so boards without a character library may not be applicable.

All code has been open-sourced on Gitee:

https://gitee.com/whik/stm32_olympic_medals

-END-

Hello everyone, I am Zhang Qiaolong, a university teacher teaching electronics. Welcome to follow me!

Leave a Comment

×