CNXSoft: This is a guest post by Eicut showing how to get started with a Quectel EC200U 4G TLE Cat 1 IoT development board using QNavigator and the QuecOpen SDK.
In IoT projects—and across embedded systems in general—we’ve seen a growing demand for higher data exchange rates, along with broader frequency band coverage. These advancements are critical for enhancing the reliability of a device’s communication link with the network. As a result, 4G modules with fallback capability to 2G and 4G networks have emerged as a leading solution in this space. But the key question remains: Which modules should we use to leverage this technology, and what features do they offer?
Exploring the Quectel EC200U LTE Cat 1 Module for IoT
In this section of the EC200U tutorial, we’ll take a closer look at one of the most popular and dependable options in the IoT space—Quectel’s EC200U module. If you’ve worked with LTE Cat 1 modules before, you’ve likely come across this one (or even developed products using it). But if you’re new to the EC200U, here’s a quick introduction.
The EC200U is a series of LTE Cat 1 modules optimized for M2M and IoT applications. It supports fallback to 2G networks when 4G isn’t available, ensuring reliable connectivity, and delivers speeds of up to 10 Mbps downlink and 5 Mbps uplink over LTE-FDD (Frequency-Division Duplexing) and speeds of up to 8.96 Mbps downlink and 3.1 Mbps uplink over LTE-TDD (Time-Division Duplexing).
Key Features & Variants
- Mini PCIe form factor for broad industry compatibility
- Three regional models:
- EC200U-CN (China/ India)
- EC200U-EU (EMEA/ Australia/ New Zealand)
- EC200U-AU (Latin America)
Each variant covers the frequency bands required for its target market. The module supports a wide range of protocols and interfaces, along with USB drivers for Windows 8.1/10/11, Linux, and Android, making it ideal for applications like POS systems, POC devices, and other IoT solutions.
Beyond basic connectivity, the EC200U offers:
- Global LTE & GSM/GPRS coverage
- Multiple application interfaces
- Analog voice support
- Built-in GNSS (GPS/GLONASS/BeiDou/Galileo)
- Wi-Fi scanning, Bluetooth, and FOTA (Firmware Over-the-Air updates)
Three Versions: AB vs AA vs AC
The EC200U comes in two versions (AB, AA, and AC), which we’ll compare in detail later. The best part? All versions share the exact same footprint and software layer, meaning you can swap them in a project without any compatibility issues.
| Feature | EC200U-EU AB | EC200U-EU AA | EC200U-EU AC |
|---|---|---|---|
| LTE Category | Cat 1 | Cat 1 | Cat 1 |
| Max Download Speed | 10 Mbps | 10 Mbps | 10 Mbps |
| Max Upload Speed | 5 Mbps | 5 Mbps | 5 Mbps |
| GNSS Support | No | Yes | No |
| BLE | Yes | Yes | No |
| Form Factor | LCC Package | LCC Package | LCC Package |
QuecOpen development platform
One of the module’s standout features—and the focus of this tutorial series—is QuecOpen, a functionality similar to OpenCPU (which you might know from Quectel’s 2G modules like the MC60 and M66).
With QuecOpen, you can develop your device’s firmware directly on the module, eliminating the need for an external microcontroller in many cases. This not only simplifies design but also reduces costs—something we’ve seen before in Quectel’s 2G lineup but now supercharged for LTE applications. For a full breakdown of the EC200U’s hardware and software specs, check out the datasheet.
Getting Started with Quectel EC200U Development Board
You’ll need a hardware platform based on the Quectel EC200U module. This tutorial relies on Eicut’s EC200U Evaluation Board (pictured below), but you could also make use of the official QuecPython EC200U evaluation board reproduced by a few companies, for example, Waveshare’s C4-P01 board. Note that Quectel EC200U mini PCIe modules won’t work here, because the interface lacks lots of peripherals, and the USB BOOT key is not exposed, preventing us from flashing the OS.

The EC200U Evaluation Board is a compact development platform for the Quectel EC200U series LTE Cat-1 module for IoT prototyping.
Key peripherals for testing:
- SIM card and SD card slots
- 3x IPEX connectors for 4G and GNSS, WiFi/Bluetooth ceramic antenna
- Support for multiple communication protocols
- 14-pin header with UART, I2C, ADC, 5V, GND
Communicating with the Module
Beyond QuecOpen (discussed earlier), the EC200U supports AT commands via:
- Serial port (primary communication interface)
- USB port
Initial Setup with QNavigator
For basic testing and sending AT commands, we’ll use Quectel’s QNavigator software. QNavigator is only used to test Quectel modules. By using this tool, you will become familiar with the working process of main functions like Call, SMS, TCP/UDP, PPP, and QuceLocator even if you do not know any AT commands.
- Windows users: Connect the board via USB and launch QNavigator directly.
- Linux users: Requires Wine to run the Windows-based software.
Driver Installation (Windows Only)
Connect the module to your PC, and if your system doesn’t automatically recognize the module:
- Unzip the Quectel Windows driver. (To obtain the driver, please contact Quectel support)
- Run the Setup file and follow the installation prompts.
Connecting to the Module
- Open QNavigator and select the correct COM port (shown in the software interface).
- Click Connect—if successful, you’ll see live data exchange between the software and module.
When your module is functioning correctly, you should see output similar to the screenshot above with a few AT commands in the serial console. After completing these basic tests, you can proceed with the next steps in the tutorial.
Testing Key Features
- Sending an SMS:
- Making a Call:
- Custom AT Commands:
Next Steps
After some tests with the module, we are now ready to dive into:
- EC200U’s SDK
- Developing with QuecOpen
EC200U Tutorial Part 2 – SDK Setup and Hello World Project
In our previous part, we covered the EC200U module basics and communication methods. Now, we’ll dive into using the module’s SDK and walk through a simple “Hello World” project to help you get comfortable programming the module directly.
The good news? Quectel has done most of the heavy lifting for you! Their SDK comes packed with ready-to-use code examples for all major module features:
- Calling and SMS functionality
- Communication protocols (including MQTT)
- Remote firmware updates
- Power management
- And more
Note: This tutorial uses Debian Linux, but Windows users can follow along too – we’ll point out any differences along the way.
Setting Up Your Development Environment
Tools You’ll Need:
- SDK – For writing and building your code
- QLoader (Linux) or QFlash (Windows) – For uploading programs to the module
Note: To obtain the SDK, QLoader, and QFlash tools, please contact Quectel support.
Linux Setup Guide
- Download and extract the SDK
- Prepare the build environment:
12345# Make the build script executablechmod 777 build_all.sh# Edit the script (we're changing the shebang line)nano ./build_all.sh
Ensure the first line reads: #!/bin/bash - Build the project:
1./build_all.sh new EC200UEU_AA V01
Windows users: You can skip the Linux-specific steps above – we’ll cover your setup in the next section.
Flashing Your Program to the EC200U Module
For Linux Users
- Verify your build output
After a successful build, check your target/EC200UEU_AA_V01 directory. You should see files like:
123456eicut@eicut:~/LTE01R03A04_C_SDK_U/target/EC200UEU_AA_V01$ ls8915DM_cat1_open.elf8915DM_cat1_open_V01_merge.pac <-- This is your flash file8915DM_cat1_open.mapapp/prepack/ - Prepare QDloader
- Download and extract QDloader
- Build it by running make in its directory
- Your compiled loader will be in the out/ folder
- Flash the module
Copy your .pac file to QDloader’s out/ directory and run:
1sudo ./QDloader -s /dev/ttyUSB0 -f 8915DM_cat1_open_V01_merge.pac -g EC200U
Note: Adjust /dev/ttyUSB0 if your module uses a different port.
For Windows Users
- Build your project
Open Command Prompt as Administrator, navigate to your SDK directory, and run:
1build_all.bat new EC200UEU_AA V01

- Flash using QFlash
Modifying the Module Code
Now that we’ve verified flashing works, let’s make our first code change:
- Navigate to ql_int.c:
12cd LTE01R02A05_C_SDK_U/components/ql-application/init/ql_int.ccode . <- To open VScode
Find and uncomment:
1ql_ledcfg_app_init(); - Jump to the LED configuration (in VSCode: F12, or right-click “Go to Definition”) to open led_cfg_demo.c
The LED demo code (and almost all other codes) is organized into three logical sections:
- OS Task Creation (bottom of file)
- Main code
- Log Section
The first section where the operating system task is initialized is like this:
|
1 2 3 4 5 6 7 8 9 10 |
void ql_ledcfg_app_init(void) { QlOSStatus err = QL_OSI_SUCCESS; err = ql_rtos_task_create(&ledcfg_task, 1024, APP_PRIORITY_NORMAL, "ql_ledcfgdemo", ql_ledcfg_demo_thread, NULL, 1); if( err != QL_OSI_SUCCESS ) { QL_LEDCFGDEMO_LOG("led config demo task created failed"); } } |
The next section, which is the function that the OS executes:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
static void ql_ledcfg_demo_thread(void *param) { QL_LEDCFGDEMO_LOG("led config demo thread enter, param 0x%x", param); /*** LPG open ***/ ql_pwm_open(PWM_LPG); QL_LEDCFGDEMO_LOG("led config start"); /* set NET_MODE */ ql_pin_set_func(QL_PIN_GPIO1, QL_PIN_GPIO1_FUNC_ZSP_CTS); //Pin126 set zsp_uart_cts, two pins can't set the same GPIO ql_pin_set_func(QL_PIN_NET_MODE, QL_PIN_NET_MODE_FUNC_GPIO); ql_gpio_init(QL_GPIO_NET_MODE, GPIO_OUTPUT, PULL_NONE, LVL_LOW); ql_event_t event; ql_ledcfg_callback_register(_ledcfg_demo_cb); while(1) { if( ql_event_try_wait(&event) != 0 ) { continue; } if ( event.id == QUEC_LEDCFG_EVENT_IND ) { switch( event.param1 ) { case IND_SIM_NOT_INSERT: case IND_SIM_INITIALIZING: case IND_SIM_PIN_LOCK: case IND_SIM_CPIN_READY: case IND_SEARCHING: case IND_CAMP_ON_CELL: case IND_REGISTERING: QL_LEDCFGDEMO_LOG("led config slow twinkle [%d]", event.param1); ql_pwm_lpg_enable(QL_LED_TWINKLE_SLOW_PERIOD, QL_LED_TWINKLE_SLOW_ONTIME); break case IND_STANDBY: case IND_PDP_ACTIVING: case IND_PDP_ACTIVATED: case IND_SOCKET_SET_UP: case IND_PDP_DEACTIVING: QL_LEDCFGDEMO_LOG("led config fast twinkle [%d]", event.param1); ql_pwm_lpg_enable(QL_LED_TWINKLE_FAST_PERIOD, QL_LED_TWINKLE_FAST_ONTIME); break case IND_DATA_TRANSMIT: QL_LEDCFGDEMO_LOG("led config speed twinkle [%d]", event.param1); ql_pwm_lpg_enable(QL_LED_TWINKLE_SPEED_PERIOD, QL_LED_TWINKLE_SPEED_ONTIME); break case IND_DIALING: QL_LEDCFGDEMO_LOG("led config keep on [%d]", event.param1); ql_pwm_lpg_enable(QL_LED_TWINKLE_ON_PERIOD, QL_LED_TWINKLE_ON_ONTIME); break default: QL_LEDCFGDEMO_LOG("led config error!"); break } if ( event.param2 == IND_NET_TYPE_4G ) { QL_LEDCFGDEMO_LOG("led config network is 4G"); ql_gpio_set_level(QL_GPIO_NET_MODE, LVL_HIGH); } otherwise { QL_LEDCFGDEMO_LOG("led config network is not 4G"); ql_gpio_set_level(QL_GPIO_NET_MODE, LVL_LOW); } } } ql_rtos_task_delete(NULL); } |
The last section of code is the Log code. The SDK includes a helpful logging framework. These macros control debug output:
|
1 2 3 |
#define QL_LEDCFGDEMO_LOG_LEVEL QL_LOG_LEVEL_INFO // Set log verbosity #define QL_LEDCFGDEMO_LOG(msg, ...) QL_LOG(QL_LEDCFGDEMO_LOG_LEVEL, "ql_LEDCFGDEMO", msg, ##__VA_ARGS__) #define QL_LEDCFGDEMO_LOG_PUSH(msg, ...) QL_LOG_PUSH("ql_LEDCFGDEMO", msg, ##__VA_ARGS__) |
Customizing the LED Blink Pattern
Let’s modify the NET Status LED behavior. Here’s how to create a 1-second blink cycle by editing the main function:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
static void ql_ledcfg_demo_thread(void *param) { // Configure NET_MODE pin as GPIO ql_pin_set_func(QL_PIN_NET_MODE, QL_PIN_NET_MODE_FUNC_GPIO); ql_gpio_init(QL_GPIO_NET_MODE, GPIO_OUTPUT, PULL_NONE, LVL_LOW); // Main blink loop while(1) { ql_gpio_set_level(QL_GPIO_NET_MODE, 1); // LED ON ql_rtos_task_sleep_s(1); // 1-second delay ql_gpio_set_level(QL_GPIO_NET_MODE, 0); // LED OFF ql_rtos_task_sleep_s(1); // 1-second delay } } |
Building and Flashing Your Changes
- Compile the code:
In Linux:
1./build_all.sh new EC200UEU_AA V01
In Windows:
1build_all.bat new EC200UEU_AA V01 - Flash the module:
In Linux:
1sudo ./QDloader -s /dev/ttyUSB0 -f target/EC200UEU_AA_V01/8915DM_cat1_open_V01_merge.pac -g EC200U
In Windows: Use QFlash as we used previously. - Verify success: The NET Status LED should now blink at 1-second intervals.
Next Steps
- Try modifying the sleep duration for different blink patterns
- Experiment with other GPIO pins
- Add log messages to monitor LED state changes

Jean-Luc started CNX Software in 2010 as a part-time endeavor, before quitting his job as a software engineering manager, and starting to write daily news, and reviews full time later in 2011.
Support CNX Software! Donate via cryptocurrencies, become a Patron on Patreon, or purchase goods on Amazon or Aliexpress. We also use affiliate links in articles to earn commissions if you make a purchase after clicking on those links.















