CH340/CH341 Boards on Linux

    Preface

    I acquired these unofficial Ardruino boards through the kits I purchased from HackMakeMod. Given your financial outlook and personal values, you may want to consider purchasing genuine Arduino boards directly from the Arduino Store to help support their continued development and maintenance of the Arduino platform. (No judgement or guilt on my part, but felt it bore mentioning.)

    HackMakeMod Knockoff Boards on Linux

    It's been a few months since I took the below notes, but I wanted to share my experiences toying around with some knockoff Arduino boards, which I picked up from the lovely gentlemen over at HackMakeMod (no, this is not sponsored content). They have created a few nifty project kits if you're looking for something to learn a bit of Arduino and electronics concepts and they're pretty open about sharing their designs and code.

    This awesome project, for example, while a bit more advanced for a beginner, is super cool and if you're interested in programming, there's a lot of possibilities their little cube can open up for you.

    Anyway, here are my notes and hopefully they are of help to you if you're trying to get these knockoff CH340/CH341 boards working on Linux.

    Setup and Considerations

    Quote from the Arch Linux Wiki, which will likely be more helpful to you than my notes:

    Non-genuine Arduino boards cheap out on the interfacing chip. They are typically equipped with a Chinese CH340 or a counterfeit of the aforementioned models. The CH340 exposes itself as a proprietary UART over USB device. Here the ch341 Linux Kernel module is used, making such Arduinos show up as /dev/ttyUSBx. This naming pattern may be customized by altering udev rules.

    USB cables

    I had issues with only certain USB cords working with the clones -- I'm not sure if it's an issue with the boards or with my cords or with my Linux installation, but I felt it was worth mentioning. Ensure you're working with a high quality cable which can support the necessary transmission rates.

    • The USB-C to USB-C cable I tried did not register as a tty
    • Certain USB-C to USB-A cables would not work

    Drivers

    The mainline Linux kernel driver may have been updated since I performed the below steps, so you may not need to do this! Give the mainline driver a try first before you go through the steps below.

    Once I had a working USB connection, I found that the clones did not work out of the box for me. After a bit of research, I discovered that a CH34* driver is indeed built into the Linux kernel (including the Zen kernel, which I am using) -- however, the driver appears to have been updated by the manufacturer but does not yet appear in the kernel with these updates.

    As such, it is necessary to download the C source code for the driver and compile it. Unfortunately, this did not work out of the box either, and it was necessary to very slightly modify the source code. (Unsure if this is related to the C implementation installed on my machine or some other factor.)

    Once this is compiled and installed into the system...


    Compiling the CH34* driver

    I did not fully document the steps I took to compile the driver, but there is a README (in English) in the zip file you can download from the WCH website.

    I took this code and modified it to allow it to compile on my system:

    diff CH341SER_LINUX/driver/ch341.c CH341SER_LINUX_unmodified/CH341SER_LINUX/driver/ch341.c
    646c646
    < static long int ch341_tty_write(struct tty_struct *tty, const unsigned char *buf, long unsigned int count)
    ---
    > static int ch341_tty_write(struct tty_struct *tty, const unsigned char *buf, int count)
    

    I then compiled and installed the module following the README.


    ...the device should now register under /dev/tty* when plugged into USB.

    IDE vs CLI

    I opted to use the arduino-cli tool to interact with the code and boards. This may be a bit trickier than just using the IDE, but I thought I would share my notes in case it's useful.

    1. Search for the board
    arduino-cli board search 'D1 mini' --additional-urls 'http://arduino.esp8266.com/stable/package_esp8266com_index.json'
    
    1. Install the core
    arduino-cli core install esp8266:esp8266 --additional-urls 'http://arduino.esp8266.com/stable/package_esp8266com_index.json'
    
    1. Install any library dependencies
    arduino-cli lib install LiquidCrystal
    
    1. Compile for the given Fully Qualified Board Name (fqbn):
    arduino-cli compile --fqbn esp8266:esp8266:d1_mini_clone
    

    WiFi / Security Considerations

    This nifty library for ESP32 and ESP8266 boards can be employed to avoid storing hard-coded WiFi credentials in your sketches. If it can't connect to WiFi, it will instead act as an access point to which you can connect and enter your wifi credentials to be stored in EEPROM.

    ESP-WiFi-Config

    arduino-cli lib install "ESP-WiFi-Config"
    

    Resources