• Websockets Debug

    Luke Thompson04/02/2021 at 05:19 0 comments

    As with most projects, they go through phases of active work, and long periods of hibernation. This one is no different, but progress has been made since it started.

    The initial work was done purely in the esp IDF which has its advantages, but since I would like to make this easy to use and modify for anyone, I decided to switch to the Arduino framework. This also served as an excuses to rewrite a large portion of the code from scratch using what I had learned from the previous attempts. In this project log, I'll focus on the debugging framework that I wrote which uses websockets to display real-time variables and allows variables to be adjusted on the fly.

    I was inspired by the work [CNLohr] did with the esp8266 using websockets and I wanted to create my own version so I could better understand how it works and to implement a few tweaks. I wanted to have a framework which allowed me to easily track values and see how they changed over time. The driving force behind this idea was to make the control loop tuning easier by watching a graph of the response and adjust gains in real time. But having that functionality makes other parts of development much easier as well.


    The general principle behind how the system operates is to have an array of pointers to the memory addresses of the variables you want to watch and/or adjust as well as their type (float, int, etc.) and a name of some sort. Then, when a websocket connection is made, that data can be transmitted to the webpage, where a javascript program unpacks the data, displays it in a table, and graphs it. If we stick with 32 bit variable types (floats, int32_t, uint32_t) then all memory reads/writes are atomic and we don't have to worry about potential race conditions.

    Microcontroller Side (C++)

    For now, here is how the C++ side of things works. It is somewhat limited in capability, but is functional enough for now that I can move on to getting other parts of the system working:

    The wsData class consists of 2 main functions. The 'add' functions, and the 'processPacket' which handles calling the other functions ('sendNames', 'sendData', and 'updateVars') as needed. The 'add' function is pretty self explanatory in that it allows you to add a variable to the system. The function takes the address of the variable, and a char array that is used as a title and description of the variable. Since it is a C++ function, we can use overloaded functions to determine the variable type so we don't need to specify directly (unlike the original C/IDF version of this I wrote).

    The add function then populates a struct array with the pointer to the variable, a pointer to the name string, and a type field so that floats and ints can be differentiated.

    When the esp32 receives binary websocket data, it is assumed that it is a command for the wsData class, and the data is passed to the 'processPacket' method. There are 3 types of packets, corresponding to the remaining functions, of the following forms:

    S -- Setup

    The Setup packet is designated by the 'S' opcode in the first byte. It is then followed by a 16 bit number which corresponds to the variables location in the wsData array (and consequently, the order in which it was added). 16 bits is probably a bit excessive, but 255 might be limiting in the future and it only costs an extra byte for 'future-proofing'. As a note, all numbers are stored and transmitted as little-endian since that is what the xtensa cores are and I would rather push complexity into the browser than on the microcontroller.

    Following the number is a single byte which represents the variable type (currently only floats and int32_t are supported). Currently the type is represented by a character, either 'i' or 'f' for integer and float respectively.

    After the variable type, the name is transmitted as a null terminated string. Immediately after the null character follows the 2 bytes for the next variable and the cycle continues until all of...

    Read more »