
This document provides an overview of the u-connectXpress software for u-blox short range modules
and describes how the products can be configured for Wi-Fi and Bluetooth Low Energy use cases.


⚡ Quick Navigation Guide for First-Time Users:
| Title | NORA-W36 series u-connectXpress |
|---|---|
| Subtitle | Stand-alone multiradio modules |
| Document type | User guide |
| Document number | UBX-23008692 |
| Version and date | 3.1.0 1-Oct-2025 |
| Disclosure restriction | C1-Public |
This document applies to the following products
| Product name | Software version |
|---|---|
| NORA-W36 series | 3.1.0 |
Disclaimer
u-blox or third parties may hold intellectual property rights in the products, names, logos, and designs included in this document. Copying, reproduction, or modification of this document or any part thereof is only permitted with the express written permission of u-blox. Disclosure to third parties is permitted for clearly public documents only.
The information contained herein is provided "as is" and u-blox assumes no liability for its use. No warranty, either express or implied, is given, including but not limited to, with respect to the accuracy, correctness, reliability, and fitness for a particular purpose of the information. This document may be revised by u-blox at any time without notice. For the most recent documents, visit www.u-blox.com.
Copyright © u-blox AG
This document describes how to set up and use u-blox short range stand-alone modules with u-connectXpress software for NORA-W36. It explains the functionality of different u-blox short range stand-alone modules and includes examples that describe how to use the software in different environments with AT commands. The document is applicable for Bluetooth® Low Energy (LE), multiradio, and Wi-Fi modules.
Several u-blox short range stand-alone modules support open software variants. For more information about the available options, see the corresponding system integration manuals for u-blox short range stand-alone modules.
For older generation modules like ODIN-W2, NINA-W15 and ANNA-B1, u-connectXpress user guide describe the functionality of these modules.
Downloading and installing

u-blox modules are developed for integration into a vast range of devices that demand a high level of reliability, such as those that are typically used in industrial and medical applications.
These professional grade modules operate over an extended temperature range and are approved for radio type application products in many countries. By choosing to use u-blox short range stand-alone modules, the cost and work involved in developing wireless communication solutions is significantly reduced.
| Concept | Definition |
|---|---|
| Host | In this document, a host refers to the device connected to a u-blox short range stand-alone module through any of the available physical interfaces. In a real application, the host is typically a microcontroller Unit (MCU) running a customer specific application. |
| Module | In this document, module refers to a u-blox stand-alone module. A module can also refer to a self-contained unit or item that is linked with similar units of a larger system that performs a defined task. |
| Remote device | A remote device in a wireless network connecting over the Bluetooth Low Energy or Wi-Fi interfaces supported in the module. |
u-blox compact and powerful stand-alone, multiradio modules are designed for the development of Internet-of-Things (IoT) applications. NORA-W36 modules include an embedded Bluetooth stack, Wi-Fi driver, IP stack, and an application for wireless data transfer. The wireless support includes Bluetooth v5.3 (Low Energy) and dual-band Wi-Fi (2.4 and 5 GHz bands).
The modules support point-to-point and point-to-multipoint configurations and can accommodate concurrent Bluetooth and Wi-Fi connections. The software provides support for micro Access Point.
They are delivered with u-connectXpress software that provides support for u-blox Bluetooth LE Serial Port Service, Generic Attribute Profile (GATT) client and server, Bluetooth beacons, simultaneous Peripheral and Central roles - all configurable from a host by means of AT commands.
Before starting with NORA-W36 configuration, ensure the following setup is complete:
Essential Hardware Connections:
Recommended:
AT commandCurrent NORA-W36 UART Settings:
📌 Connection Requirements:
| Step | Command | Expected Response | Purpose |
|---|---|---|---|
| 1 | AT | OK | Test basic communication |
| 2 | ATI | Module information | Verify module identity |
| 3 | AT+GMI | u-blox | Check manufacturer |
| 4 | AT+GMM | NORA-W36 | Check model |
| 5 | AT+GMR | Software version | Check firmware version |
📶 Wi-Fi Connection Flow:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 📋 Configure │───▶│ 🔒 Authenticate │───▶│ ✅ Connected │
│ Network │ │ & Secure │ │ & Online │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
SSID/PWD UWSC=0 Link Up
🔧 AT Commands: 🔒 Security: ✅ Status Events:
• AT+UWSCP (SSID) • WPA2/WPA3 • +UEWLU (Link)
• AT+UWSSW (Password) • Auto-negotiate • +UEWSNU (Network)
• AT+UWSC=0 (Connect) • 2048-bit keys • Ready for data!
Basic WPA2/WPA3 Station Connection:
| Step | Command | Description |
|---|---|---|
| 1 | AT+UWSCP=0,"YourSSID" | Set network name |
| 2 | AT+UWSSW=0,"YourPassword",0 | Set password (WPA2/WPA3 compatible) |
| 3 | AT+UWSC=0 | Connect to network |
| 4 | Wait for +UEWLU:0,BBBBBBBBBBB,6 | Wi-Fi link up |
| 5 | Wait for +UEWSNU | Network interface up |
| 6 | AT+UWSNST? | Check network configuration |
Full Network Configuration Response:
AT+UWSNST?
+UWSNST:0,192.168.1.59 // IPv4 address
+UWSNST:1,255.255.255.0 // Subnet mask
+UWSNST:2,192.168.1.1 // Gateway
+UWSNST:3,192.168.1.1 // Primary DNS
+UWSNST:4,0.0.0.0 // Secondary DNS
+UWSNST:5,[fe80::56f8:2aff:fe10:aad4] // IPv6 address
OK
💡 Quick Check: For basic connectivity verification, you can query just the IP address:
AT+UWSNST=0
+UWSNST:0,192.168.1.59 // IPv4 address sufficient for most use cases
OK
📱 Bluetooth LE Advertisement Flow:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 🔧 Configure │───▶│ 📡 Advertise │───▶│ 📲 Discoverable │
│ Parameters │ │ & Beacon │ │ by Devices │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
Set Interval Start Broadcast Device Scan
⚙️ Configuration: 📡 Broadcasting: 📱 Detection:
• Interval: 100ms • Device name • "NORA-W36"
• Legacy mode • BLE 5.3 compliant • RSSI signal
• Auto-connectable • Low power mode • Available services
Basic BLE Advertising Setup:
| Step | Command | Description |
|---|---|---|
| 1 | AT+UBTALS=160,160 | Set legacy advertising parameters (100ms interval) |
| 2 | AT+UBTAL | Start legacy advertising |
| 3 | Device is now discoverable | Check with smartphone BLE scanner |
Expected Result: Module appears as "NORA-W36" in Bluetooth device scans
TCP Socket Communication Flow:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 🔌 Create │───▶│ 🔗 Connect │───▶│ 📤 Send/Receive │
│ Socket │ │ to Server │ │ Data │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
USOCR=6 httpbin.org:80 HTTP GET
🔧 Socket Setup: 🔗 TCP Connection: 📊 Data Exchange:
• IPv4 TCP socket • Remote server • HTTP protocol
• System allocated • Port 80 (HTTP) • Request/Response
• Ready for connection • Bidirectional • Text-based data
After Wi-Fi connection, test TCP socket:
| Step | Command | Description |
|---|---|---|
| 1 | AT+USOCR=6 | Create TCP socket |
| 2 | AT+USOC=0,"httpbin.org",80 | Connect to test server |
| 3 | AT+USOWS=0,"GET / HTTP/1.1\r\nHost: httpbin.org\r\n\r\n" | Send HTTP request |
| 4 | AT+USORS=0,100 | Read response |
Expected Result: HTTP response from httpbin.org server
🔧 Hardware & Communication Troubleshooting:
| Issue | Symptom | Solution |
|---|---|---|
| 🔇 No response to AT | Silent or garbled text | ✅ Check baud rate (115200), TX/RX/GND wiring (CTS/RTS optional) |
ERROR responses | Commands not recognized | ✅ Check firmware version, command syntax |
| Connection timeouts | Commands hang | ✅ Check power supply stability, reset module |
📶 Wi-Fi Network Troubleshooting:
| Issue | Symptom | Quick Fix |
|---|---|---|
| 🚫 Connection fails | ERROR on AT+UWSC=0 | ✅ Verify SSID and password spelling |
| No IP address | Wi-Fi connects but no +UEWSNU | ✅ Check DHCP server, router configuration |
| 📡 Weak signal | Connection drops frequently | ✅ Move closer to router, check antenna |
Quick Debug Commands:
| Command | Purpose | Usage |
|---|---|---|
AT+USYEE=1 | Enable extended error codes | Run first to get detailed error information |
AT+USYEC? | Check last error code | Query after any failed operation |
AT+UWSST=4 | Check signal strength (RSSI) | Monitor connection quality |
After successful quick start:
The possibility of replacing serial cables with simple wireless connections is a key feature of u-blox modules. It allows system hosts to transfer data to one another over wireless Bluetooth connections that are established between u-blox modules in Central/Peripheral configuration.
Depending on the module capabilities, data from each host is transferred to local u-blox modules over a serial UART interface.
u-blox modules can be configured to automatically establish new connections and/or accept incoming connections using AT commands. For connected hosts, this means that physical serial cables can be replaced with more convenient wireless solutions.

NORA-W36 can function as either a Central or Peripheral unit, connecting to devices such as laptops, cellular phones, and tablets using the Generic Attribute Profile (GATT).

NORA-W36 can function as either a Central or Peripheral unit, connecting to devices such as laptops, cellular phones, and tablets via the u-blox Serial Port Service (SPS).

NORA-W36 can operate as a Station connecting to an Access Point.

NORA-W36 can operate as an Access Point connecting to other devices that operate as Stations.
NORA-W36 operates in the following modes:
Additionally, the module supports various low-power modes, which optimize power consumption regardless of the operating mode. See also Low power modes and Power consumption optimization.
Deep sleep is supported with the command AT+UPMDS, see AT command manual and Data sheet for more information.
u-blox modules can be configured to start in any operating mode. Once up and running, the modules can be switched between most modes. The modes are changed with a command or escape sequence sent to the module:
The module is controlled using AT commands in (default) Command mode. In this mode, the host sends control and configuration commands and indicates when data is to be sent over the UART interface.
| u-connectXpress Features | Capability in 3.1.0 |
|---|---|
| Chipset | Realtek RTL8720DF |
| Multiradio | Bluetooth Low Energy 5.3 Wi-Fi 4 dual band 2,4 and 5 GHz |
| Wi-Fi capabilities | 802.11a/b/g/n WPA2 Personal (Station & AP) and WPA3 Personal (Station only) Wi-Fi Multimedia WMM/WME/QoS (802.11e) Protected Management Frames (802.11w) Roaming using Fast BSS Transition (802.11r), Radio Measurement (802.11k), and Wireless Network Management (802.11v) |
| Wi-Fi Alliance certified | Certification ID: WFA112253 Date of Certification: 2021-06-07 |
| Bluetooth Qualification | Declaration ID: D065864 QDID: 194774 Qualification date: 2022-02-26 NORA-W36 listing date: 2024-02-19 |
| Wi-Fi Access Point | 5 Stations connected |
| TCP/UDP sockets | 6 Simultaneous sockets (Note that a listening socket requires 2 sockets) |
| MQTT Connections | 1 Connection (client) |
| BLE Central connections | 3 Peripherals connected |
| BLE Peripheral connections | 1 Central connected |
| BLE Scatternet connections (C+P) | Central with 1 Peripheral connected, advertising and allow incoming connection as Peripheral |
| BLE Link key storage | 30 Devices. The keys that are the least used are removed first when storage is full |
| Coexistence Wi-Fi, BLE and TLS | Max 1 TLS client, 1 BLE, 2 TCP Client |
| Data transfer modes | Buffer Mode (event and read data), Direct Mode (data in event), Transparent mode (like serial port cable replacement). Buffer Mode is Default, Transparent mode only supports one link. Transparent Mode has highest throughput, then Direct Mode and then Buffer Mode |
| SPS MTU size | 244 bytes, 1000 bytes can be sent in AT command |
| TCP MTU size | 1460 bytes, 1000 bytes can be sent in AT command |
| UDP MTU size | 1460 bytes, 1000 bytes can be sent in AT command |
| HTTP MTU size | 1460 bytes, 1000 bytes can be sent in AT command |
| u-connectXpress software components | Versions in 3.1.0 |
|---|---|
| Realtek SDK including Bluetooth stack and Wi-Fi drivers | 6.2 + 6.2_patch_integrated_241111_f5eb173c https://online.realtek.com/Home/Login |
| lwIP TCP/IP stack | 2.0.2 https://savannah.nongnu.org/news/?group_id=3159 |
| Mbed TLS cryptographic algorithms | 3.6.4 https://github.com/Mbed-TLS/mbedtls/releases |
| u-connectXpress MQTT client | Versions in 3.1.0 |
|---|---|
| MQTT version | 3.1.1 |
| MQTT capabilities | Publish, Subscribe, TLS, QoS, Testament and Last will |
| MQTT maximum packets size | 5k (5000) bytes for Publish and Subscribe packets |
| u-connectXpress Enterprise security | Capability in 3.1.0 |
|---|---|
| PEAP Authentication method | PEAPv0 with EAP-MSCHAPv2 |
| EAP Authentication method | EAP Transport Layer Security (EAP-TLS) |
| EAP-TLS certificate key size supported | 2048 and 4096 bits |
| u-connectXpress TLS feature | TLS capability in 3.1.0 |
|---|---|
| TLS version | TLS 1.2 and TLS 1.3 |
| TLS max number of connections | 1 |
| TLS extensions enabled by default | Server Name Indication (SNI), Maximum Fragment Length Negotiation |
| TLS Encryption keys | Advanced Encryption Standard (AES). Data Encryption Standard (DES), Rivest Cipher 4 (RC4), and the Camellia cipher are not supported. |
| X.509 security certificate formats supported | PEM (DER not supported) |
| TLS over TCP certificate key size supported | 4096 bits |
| TLS certificates | Up to 8 certifications (or certificate chains) can be stored. Certificates can be maximum 15360 bytes. |
| TLS Extensions | Server name (SNI) Max fragment length: 4096 (4) |
More information about the AT commands used in this use cases can be found in the NORA-W36 AT command manual.
This chapter covers the fundamental concepts of AT command programming with NORA-W36, including command response handling, event management, and timing considerations that are essential before diving into specific protocol implementations.
This chapter covers the fundamental concepts of event-driven programming with NORA-W36, including AT command response handling, Unsolicited Result Code (URC) event management, and data flow fundamentals that are essential before diving into specific protocol implementations.
NORA-W36 operates on an event-driven architecture where the module continuously monitors for various conditions and notifies the host application through events. This approach enables efficient, asynchronous programming patterns.
Key Concepts:
NORA-W36 generates several categories of events:
| Event Category | Purpose | Examples |
|---|---|---|
| Connection Events | Network and device connectivity | +UEBTC, +UESOC, +UEWLU |
| Data Events | Incoming data availability | +UESODA, +UESODS, +UESPSDS |
| Status Events | Module state changes | +STARTUP, +UEWSNU, +UEMQC |
| Error Events | Problem notifications | +UESOCL, +UEWLD, +UEMQDC |
| Security Events | Authentication and bonding | +UEBTB, +UEBTUC, +UEBTUPE |
Every AT command generates predictable response patterns that your application must handle:
// Command sent:
AT+UWSNST?
// Immediate response:
+UWSNST:0,192.168.1.59 // IPv4 address
+UWSNST:1,255.255.255.0 // Subnet mask
+UWSNST:2,192.168.1.1 // Gateway
+UWSNST:3,192.168.1.1 // Primary DNS
+UWSNST:4,0.0.0.0 // Secondary DNS
+UWSNST:5,[fe80:0000:0000:0000:56f8:2aff:fe10:aad4] // IPv6 address
OK
// Command sent:
AT+UWSC=0
// Immediate acknowledgment:
OK
// Later event (when connection completes):
+UEWLU:0
+UEWSNU
AT+UBTM=1
OK // Success - command accepted
// vs
AT+UBTM=1
ERROR // Failure - command rejected
AT+UBTBDL
+UBTBDL:AAAAAAAAAAAAp // Bonded device 1 (BD address)
+UBTBDL:BBBBBBBBBBBBp // Bonded device 2 (BD address)
+UBTBDL:CCCCCCCCCCCCp // Bonded device 3 (BD address)
OK // Final confirmation
AT+UWSNST?
+UWSNST:0,192.168.1.59 // IPv4 address
+UWSNST:1,255.255.255.0 // Subnet mask
+UWSNST:2,192.168.1.1 // Gateway
+UWSNST:3,192.168.1.1 // Primary DNS
+UWSNST:4,0.0.0.0 // Secondary DNS
+UWSNST:5,[fe80:0000:0000:0000:56f8:2aff:fe10:aad4] // IPv6 address
OK
Response Timeouts by Command Type:
| Command Type | Typical Timeout | Max Timeout | Example |
|---|---|---|---|
| Configuration | 1 second | 5 seconds | AT+UBTM=1 |
| Connection | 10 seconds | 30 seconds | AT+UWSC=0 |
| Data Transfer | 5 seconds | 15 seconds | AT+USOWS=0,"data" |
| Network Query | 3 seconds | 10 seconds | AT+UWSNST? |
Unsolicited Result Codes (URCs) are events generated by NORA-W36 without being prompted by a command. They provide real-time information about module status, incoming data, and connectivity changes.
URC Characteristics:
+UEBTC:0,AAAAAAAAAAAAp // Bluetooth connected
+UEBTDC:0 // Bluetooth disconnected
+UESOC:0 // Socket connected
+UESOCL:0 // Socket closed
+UEWLU:0 // Wi-Fi link up
+UEWLD:0,4 // Wi-Fi link down (reason code)
+UESODA:0,128 // 128 bytes available on socket 0
+UESODS:0,"Hello World" // Direct string data on socket 0
+UESPSDS:0,"SPS Data" // SPS string data received
+UEMQDA:0 // MQTT data available
+STARTUP // Module started/restarted
+UEWSNU // Wi-Fi station network up
+UEWSND // Wi-Fi station network down
+UEMQC:0 // MQTT connected
+UEMQDC:0 // MQTT disconnected
// Maintain connection state
connection_state = "DISCONNECTED"
// Handle connection events
if URC == "+UEBTC:0,*":
- connection_state = "BT_CONNECTED"
- start_data_monitoring()
if URC == "+UEBTDC:0":
- connection_state = "DISCONNECTED"
- stop_data_monitoring()
// Handle data events immediately
if URC == "+UESODS:0,*":
- data = extract_data_from_urc()
- process_incoming_data(data)
if URC == "+UESODA:0,*":
- bytes_available = extract_count_from_urc()
- read_buffered_data(bytes_available)
// Handle error conditions
if URC == "+UESOCL:0":
- log_error("Socket closed unexpectedly")
- attempt_reconnection()
if URC == "+UEWLD:0,4":
- log_error("Wi-Fi disconnected - reason 4")
- retry_wifi_connection()
This chapter covers advanced data handling concepts, event processing patterns, and practical implementation strategies for building robust NORA-W36 applications.
NORA-W36 supports multiple data handling modes, each optimized for different use cases:
| Data Mode | Behavior | Event Type | Best For |
|---|---|---|---|
| String Mode | Text data only | +UESODS, +UESPSDS | JSON, XML, sensor readings |
| Binary Mode | All data types | +UESODB, +UESPSDB | Files, certificates, images |
| Buffered Mode | Store until read | +UESODA | Event-driven applications |
| Direct Mode | Immediate delivery | +UESODS/+UESODB | Real-time applications |
| Transparent Mode | UART passthrough | None (direct UART) | Legacy protocol support |
Understanding Data Event Flow:
// Data arrives → stored in buffer
// Event generated:
+UESODA:0,256 // 256 bytes available on socket 0
// Host reads data:
AT+USORS=0,256
+USORS:0,256,"actual data content here..."
OK
// Data arrives → immediately delivered
+UESODS:0,"immediate data" // String data delivered directly
// No additional read command needed
// Connection sequence:
+UESOC:0 // Socket connected
+UESODA:0,128 // Data available (buffered mode)
+UESODS:0,"data" // Data delivered (direct mode)
+UESOCL:0 // Socket closed
// SPS connection sequence:
+UESPSC:0 // SPS connected
+UESPSDS:0,"Hello" // String data received
+UESPSDA:0,64 // Binary data available
+UESPSDC:0 // SPS disconnected
// MQTT lifecycle:
+UEMQC:0 // MQTT connected
+UEMQDA:0 // Data available
+UEMQPC:0,123,45 // Publish completed
+UEMQDC:0 // MQTT disconnected
function handle_event(event_string):
- if event_string.startswith("+UEBTC"):
- handle_bluetooth_connected(event_string)
- elif event_string.startswith("+UESODS"):
- handle_socket_data(event_string)
- elif event_string.startswith("+STARTUP"):
- handle_module_startup()
function process_event(event, current_state):
- switch current_state:
- case CONNECTING:
- if event == "+UESOC:0":
- transition_to_state(CONNECTED)
- case CONNECTED:
- if event.startswith("+UESODA"):
- handle_data_available(event)
function safe_event_handler(event):
- try:
- process_event(event)
- except ParseError:
- log_error("Failed to parse event: " + event)
// Continue processing other events
except ConnectionError:
- log_error("Connection lost during event processing")
- initiate_reconnection()
// Buffer events during critical operations
event_queue = []
critical_operation_active = False
function queue_or_process_event(event):
- if critical_operation_active:
- event_queue.append(event)
- else:
- process_event_immediately(event)
Event Processing Guidelines:
Memory Management:
// Simple event monitoring loop
while True:
line = read_from_uart()
if line.startswith("+"):
// This is an event (URC)
handle_event(line)
elif line in ["OK", "ERROR"]:
// This is a command response
handle_command_response(line)
elif line.startswith("+STARTUP"):
// Module restarted
reinitialize_module()
// Track multiple connection types
connection_states = {
"wifi": "DISCONNECTED",
"bluetooth": "DISCONNECTED",
"mqtt": "DISCONNECTED"
}
// Update states based on events
function update_connection_state(event):
- if "+UEWLU" in event:
- connection_states["wifi"] = "CONNECTED"
- elif "+UEWLD" in event:
- connection_states["wifi"] = "DISCONNECTED"
- elif "+UEBTC" in event:
- connection_states["bluetooth"] = "CONNECTED"
- // ... etc
// Collect data from multiple sources
data_sources = {
"socket_0": [],
"sps_0": [],
"mqtt": []
}
function handle_data_event(event):
- if "+UESODS:0" in event:
- data = extract_data(event)
- data_sources["socket_0"].append(data)
- elif "+UESPSDS:0" in event:
- data = extract_data(event)
- data_sources["sps_0"].append(data)
| Problem | Symptoms | Solution |
|---|---|---|
| Missing Events | Expected URCs not received | Check event flow control, verify module state |
| Event Overflow | Events arriving faster than processing | Implement event queue, optimize handlers |
| Parse Errors | Malformed event strings | Add robust parsing with error recovery |
| State Confusion | Application state out of sync with module | Implement state verification commands |
Enable Debug Logging:
// Log all events for analysis
function debug_log_event(event):
- timestamp = get_current_time()
- log_file.write(f"{timestamp}: {event}")
Verify Event Sources:
// Check which events are actually being generated
AT+UBTM? // Check Bluetooth mode
AT+UWSNST? // Check Wi-Fi status
AT+USOST=0 // Check socket status
This foundation in event-driven programming and data handling prepares you for implementing specific protocol use cases covered in subsequent chapters. Understanding these fundamentals is crucial for building robust IoT applications with NORA-W36.
The following Bluetooth Low Energy use case, show some functionality to get started with GATT client, GATT server and SPS.
| u-connectXpress BLE default values | 3.1.0 |
|---|---|
| BLE Mode default | ON, Central and Peripheral (Mode = 3) |
| BLE Legacy Advertising default | OFF, enable with AT+UBTAL |
The following examples use the MAC address below, this must be replaced by the real MAC address of the devices that are used.


This use case configures NORA-W36 as a Central device that operates as a GATT client and receives data.
This use case configuration is used in combination with Bluetooth GATT server.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Check that Bluetooth Central is enabled. 1: Central or 3: Central and Peripheral. If so jump to step 6. | AT+UBTM? | +UBTM:1 or +UBTM:3 |
| 2 | Enable Bluetooth 1: Central or 3: Central and Peripheral | AT+UBTM=1 or AT+UBTM=3 | OK |
| 3 | Store command | AT&W | OK |
| 4 | Restart | AT+CPWROFF | OK |
| 5 | Wait for NORA-W36 to startup | +STARTUP | |
| 6 | Connect to remote device | AT+UBTC=AAAAAAAAAAAAp | +UEBTC:0,AAAAAAAAAAAAp |
| 7 | Discover Services and look for 180D, which is the descriptor for the Heart Rate service. | AT+UBTGPSD=0 | +UBTGPSD:0,12,65535,180D |
| 8 | Discover all Service Characteristics and look for 2A37, which is the descriptior for the Heart Rate Measurement characteristics. | AT+UBTGSCD=0,12,65535 | +UBTGSCD:0,13,10,14,2A37 |
| 9 | Use the Value handle, which in this case is 14. The value can vary. Look for 2902, which is the descriptor for the notification. | AT+UBTGCDD=0,14,15 | +UBTGCDD:0,13,15,2902 |
| 10 | Enable notification on the GATT Client the Central in this example | AT+UBTGCCW=0,15,1 | OK |
| 11 | Notification is received on the GATT Client | +UEBTGCN:0,14,60 +UEBTGCN:0,14,61 +UEBTGCN:0,14,62 |


This use case configures NORA-W36 as a Peripheral device that operates as GATT server and sends notifications.
This configuration works in combination with Bluetooth GATT client.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Check that Bluetooth Peripheral is enabled 2: Peripheral and 3: Central and Peripheral. If so jump to step 6. | AT+UBTM? | +UBTM:2 or +UBTM:3 |
| 2 | Enable Bluetooth 2: Peripheral or 3: Central and Peripheral | AT+UBTM=2 or AT+UBTM=3 | OK |
| 3 | Store command | AT&W | OK |
| 4 | Restart | AT+CPWROFF | OK |
| 5 | Wait for NORA-W36 to start | +STARTUP | |
| 6 | Enable Legacy Advertising | AT+UBTAL | OK |
| 7 | Write the Heart Rate service | AT+UBTGS=180D | +UBTGS:21 |
| 8 | Write the GATT characteristic | AT+UBTGC=2A37,3A,01,01,00 | +UBTGC:30,31 |
| 9 | Activate GATT Service | AT+UBTGSA | OK |
| 10 | Wait for incoming Bluetooth connection | +UEBTC:0,BBBBBBBBBBB | |
| 11 | Get the MTU for the connection (optional) | AT+UBTCST=0,3 | +UBTCST:3,247 |
| 12 | Get the Role for the connection (optional) | AT+UBTCST=0,7 | +UBTCST:7,1 |
| 13 | Send a notification from the GATT Server using the value handle | AT+UBTGNS=0,14,60 AT+UBTGNS=0,14,61 AT+UBTGNS=0,14,62 | OK |


This use case configures NORA-W36 as a Central device that sends and receives data from another NORA-W36 module operating as a Peripheral device. The communication between the two modules is facilitated using the proprietary u-blox Serial Port Service. It is also possible to connect to other devices that supports the SPS protocol.
This use case operates in combination with Bluetooth SPS peripheral.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Check that Bluetooth Central is enabled. 1:Central or 3:Central and Peripheral. If so, jump to step 6. | AT+UBTM? | +UBTM:1 or +UBTM:3 |
| 2 | Enable Bluetooth 1:Central or 3:Central and Peripheral | AT+UBTM=1 or AT+UBTM=3 | OK |
| 3 | Store command | AT&W | OK |
| 4 | Restart | AT+CPWROFF | OK |
| 5 | Wait for NORA-W36 to start | +STARTUP | |
| 6 | Initiate Bluetooth discovery. Listen for advertising packets broadcast from Peripheral device. | AT+UBTD | +UBTD:AAAAAAAAAAAAp,-52,"NORA-W36-AAAAAA",0,10094E4F52412D5733362D414141414141 |
| 7 | Connect Bluetooth | AT+UBTC=AAAAAAAAAAAAp | +UEBTC:0,AAAAAAAAAAAAp |
| 8 | Read MTU, maximum data size | AT+UBTCST=0,3 | +UBTCST:3,247 |
| 9 | Read RSSI (optional) | AT+UBTRSS=0 | +UBTRSS:-52 |
| 10 | Connect SPS using handle of Bluetooth connection | AT+USPSC=0 | OK |
| 11 | SPS connection is up | +UESPSC:0 | |
| 12 | It is now possible to send and receive SPS data in String or Binary mode | ||
| 13 | Disconnect the SPS and Bluetooth connection | AT+UBTDC=0 | +UESPSDC:0 +UEBTDC:0 |


This use case configures NORA-W36 module as a Peripheral device that sends and receives data from another NORA-W36 module operating as a Central device. The communication between the two modules is facilitated using the proprietary u-blox Serial Port Service. It is also possible to connect to other devices that support the SPS protocol.
This use case configuration is used in combination with Bluetooth SPS central.
| Nr | Instructions | AT command | AT events |
|---|---|---|---|
| 1 | Check that Bluetooth Peripheral is enabled. 2: Peripheral and 3: Central and Peripheral. If so, jump to step 6 | AT+UBTM? | +UBTM:2 or +UBTM:3 |
| 2 | Enable Bluetooth 2: Peripheral or 3: Central and Peripheral | AT+UBTM=2 or AT+UBTM=3 | OK |
| 3 | Store command | AT&W | OK |
| 4 | Restart | AT+CPWROFF | OK |
| 5 | Wait for NORA-W36 to startup | +STARTUP | |
| 6 | Enable SPS on Peripheral | AT+USPS=1 | OK |
| 7 | Enable Legacy Advertising | AT+UBTAL | OK |
| 8 | Peripheral receives Incoming Bluetooth connection | +UEBTC:0,BBBBBBBBBBBBp | |
| 9 | Read MTU, maximum data size on both | AT+UBTCST=0,3 | +UBTCST:3,247 |
| 10 | Read RSSI (optional) | AT+UBTRSS=0 | +UBTRSS:-52 |
| 11 | Central Connect SPS using handle of Bluetooth connection | AT+USPSC=0 | +UESPSC:0 |
| 12 | It is now possible to send and receive SPS data in String or Binary mode | ||
| 13 | SPS and Bluetooth link is down | +UESPSDC:0 +UEBTDC:0 |

This use case configures NORA-W36 as a peripheral device that operates as a GATT client and receives data.
This use case configuration is used in combination with Apple iPhone using the Apple Notification Center Service (ANCS).
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Check that Bluetooth Peripheral is enabled 2: Peripheral and 3: Central and Peripheral. If so, jump to step 6. | AT+UBTM? | +UBTM:2 or +UBTM:3 |
| 2 | Enable Bluetooth 2: Peripheral or 3: Central and Peripheral | AT+UBTM=2 or AT+UBTM=3 | OK |
| 3 | Store command | AT&W | OK |
| 4 | Restart | AT+CPWROFF | OK |
| 5 | Wait for NORA-W36 to start | +STARTUP | |
| 6 | Set Apple ANCS Advertise data packet | AT+UBTAD=1115D0002D121E4B0FA4994ECEB531F40579 | OK |
| 7 | Enable Legacy Advertising | AT+UBTAL | OK |
| 8 | Peripheral receives Incoming Bluetooth connection | +UEBTC:0,BBBBBBBBBBBBp | |
| 9 | Discover Services and look for 180A that is the Device Information | AT+UBTGPSD=0 | +UBTGPSD:0,1,5,1800 +UBTGPSD:0,6,9,1801 +UBTGPSD:0,10,14,180A +UBTGPSD:0,15,19,D0611E78BBB44591A5F8487910AE4366 +UBTGPSD:0,20,24,9FA480E0496745429390D343DC5D04AE +UBTGPSD:0,25,28,180F +UBTGPSD:0,29,34,1805 +UBTGPSD:0,35,44,7905F431B5CE4E99A40F4B1E122D00D0 +UBTGPSD:0,45,56,89D3502B0F36433A8EF4C502AD55F8DC |
| 10 | Discover all Service Characteristics and look for the attribute 2A29, which describes the Manufacturer Name String characteristics | AT+UBTGSCD=0,10,14 | +UBTGSCD:0,11,02,12,2A29 +UBTGSCD:0,13,02,14,2A24 |
| 11 | Read the Manufacturer Name String Apple Inc. characteristics on handle 12 | AT+UBTGR=0,12 | +UBTGR:0,12,4170706C6520496E632E (Apple Inc.) |
Pairing
Think of pairing as the handshake that sets the foundation for a secure link
Bonding
In summary

Bluetooth Security is disabled by default and must be configured and enabled before use.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Set Bluetooth I/O Capabilities to Display Yes/No (2) | AT+UBTIOC=2 | |
| 2 | Set Only allow authenticated bonding with encrypted Bluetooth link (3) | AT+UBTBSM=3 | |
| 3 | Allow Pairing | AT+UBTPM=1 | |
| 4 | Bluetooth Bond | AT+UBTB=BBBBBBBBBBBBp | |
| 5 | Bluetooth Connected event | +UEBTC:0,BBBBBBBBBBBBp | |
| 6 | Bluetooth User Confirmation event, check the number on both devices, should be the same | +UEBTUC:BBBBBBBBBBBBp,786920 | |
| 7 | Bluetooth User Confirmation, confirm with yes | AT+UBTUC=BBBBBBBBBBBBp,1 | |
| 8 | Bluetooth Bond success | +UEBTB:BBBBBBBBBBBBp,0 | |
| 9 | Bluetooth Bonded Devices List (optional) | AT+UBTBDL | +UBTBDL:BBBBBBBBBBBBp |

Bluetooth Security is disabled by default and must be configured and enabled before use.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Check that Bluetooth Peripheral is enabled, 2: Peripheral or 3: Central and Peripheral, if so move to step 6 | AT+UBTM? | +UBTM:2 or +UBTM:3 |
| 2 | Enable Bluetooth 2: Peripheral or 3: Central and Peripheral | AT+UBTM=2 or AT+UBTM=3 | OK |
| 3 | Store command | AT&W | OK |
| 4 | Restart | AT+CPWROFF | OK |
| 5 | Wait for NORA-W36 to startup | +STARTUP | |
| 6 | Enable Legacy Advertising | AT+UBTAL | OK |
| 7 | Set Bluetooth I/O Capabilities to Display Yes/No (2) | AT+UBTIOC=2 | |
| 8 | Set Only allow authenticated bonding with encrypted Bluetooth link (3) | AT+UBTBSM=3 | |
| 9 | Allow Pairing | AT+UBTPM=1 | |
| 10 | Bluetooth Connected event | +UEBTC:0,AAAAAAAAAAAAp | |
| 11 | Bluetooth User Confirmation event, check the number on both devices, should be the same | +UEBTUC:AAAAAAAAAAAAp,786920 | |
| 12 | Bluetooth User Confirmation, confirm with yes | AT+UBTUC=AAAAAAAAAAAAp,1 | |
| 13 | Bluetooth Bond success | +UEBTB:AAAAAAAAAAAAp,0 | |
| 14 | Bluetooth Bonded Devices List (optional) | AT+UBTBDL | +UBTBDL:AAAAAAAAAAAAp |
The following Wi-Fi use cases show basic connectivity functionality to get started with Wi-Fi Station and Access Point connections.
The following examples use the MAC address below, this must be replaced by the real MAC address of the devices that are used.


Connect as a Wi-Fi station to an Access Point to get access to network.
This use case connects NORA-W36 as a Wi-Fi station to an Access Point for access to the network. The connection is set to DHCP client by default.
To use static IP the AT+UWSIPS set the IP address, gateway, subnet mask and DNS.
The NORA-W36 module supports both WPA2 Personal and WPA3 Personal security protocols when operating as a Wi-Fi station, providing enhanced wireless network protection:
| Security Protocol | Encryption | Key Benefits | Use Cases |
|---|---|---|---|
| WPA2 Personal | AES-CCMP | Industry standard, broad compatibility | Legacy networks, mixed environments |
| WPA3 Personal | AES-CCMP/GCMP-256 | Enhanced security, forward secrecy, SAE protection | Modern secure networks, IoT applications |
WPA3 Security Enhancements (Station Mode Only):
Note: WPA3 support is available for station mode only. When operating as an Access Point, NORA-W36 supports WPA2 Personal only.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Set SSID for the Network | AT+UWSCP=0,"ssid" | OK |
| 2a | Set Password (WPA2/WPA3 compatible) | AT+UWSSW=0,"password",0 | OK |
| 2b | Set Password (WPA3 only) | AT+UWSSW=0,"password",1 | OK |
| 3 | Connect Wi-Fi station | AT+UWSC=0 | OK |
| 4 | Wait for Wi-Fi interface | +UEWLU:0,BBBBBBBBBBB,6 | |
| 5 | Wait for Network interface | +UEWSNU | |
| 6 | Check IP address (optional) | AT+UWSNST? | +UWSNST:0,192.168.1.179 etc. |
| 7 | Check RSSI (optional) | AT+UWSST=4 | +UWSST:4,-66 |
| 8 | It is now possible to connect TCP and UDP, and then send and receive data in String or Binary mode. It is also possible to connect MQTT. | ||
| 9 | Disconnect Wi-Fi station | AT+UWSDC | OK |
AT+UWSSW Command Format:
AT+UWSSW=<interface_id>,<password>,<wpa_threshold>
Parameters:
interface_id: Wi-Fi interface (0 = station)password: WPA/WPA2/WPA3 password (8-63 characters)wpa_threshold: Security level selection0: Accept WPA2 or higher (WPA2/WPA3 compatible)1: Require WPA3 only (enhanced security)Security Recommendations:
wpa_threshold=1 for WPA3-only networks requiring maximum securitywpa_threshold=0 for broader compatibility with WPA2/WPA3 networksImportant Note: If NORA-W36 should connect to Wi-Fi at startup, the Connect, Store and Reset commands should be sent: AT+UWSC=0, AT&W and AT+CPWROFF. The current Wi-Fi Station state is stored in flash and NORA-W36 will try to connect using the Service Set Identifier (SSID) and password stored at startup.
The following section provides detailed documentation for key Wi-Fi station commands using the standardized format:
Purpose: Configure SSID for Wi-Fi station connection
Syntax:
AT+UWSCP=<interface_id>,<ssid>
Parameters:
interface_id: Wi-Fi interface ID (0 = station)ssid: Network SSID name (1-32 characters, quoted string)Examples:
AT+UWSCP=0,"MyNetwork" // Set SSID to "MyNetwork"
AT+UWSCP=0,"Office_WiFi_5G" // Set SSID with special characters
Response: OK on success, ERROR on failure
Notes:
AT&W followed by AT+CPWROFF to ensure safe flash storagePurpose: Set WPA/WPA2/WPA3 password and security threshold
Syntax:
AT+UWSSW=<interface_id>,<password>,<wpa_threshold>
Parameters:
interface_id: Wi-Fi interface ID (0 = station)password: WPA password (8-63 characters, quoted string)wpa_threshold: Security level0: Accept WPA2 or higher (recommended for compatibility)1: Require WPA3 only (enhanced security)Examples:
AT+UWSSW=0,"MyPassword",0 // WPA2/WPA3 compatible
AT+UWSSW=0,"SecurePass123",1 // WPA3 only
Response: OK on success, ERROR on invalid parameters
Purpose: Initiate connection to configured Wi-Fi network
Syntax:
AT+UWSC=<interface_id>
Parameters:
interface_id: Wi-Fi interface ID (0 = station)Example:
AT+UWSC=0
Response:
OK - Connection process started+UEWLU:0,<mac_address>,<channel> - Wi-Fi link established+UEWSNU - Network interface readyCommon Errors:
ERROR:1 - Invalid parametersERROR:8 - Connection timeoutERROR:16 - Authentication failedPurpose: Disconnect from current Wi-Fi network
Syntax:
AT+UWSDC[=<interface_id>]
Parameters:
interface_id: Optional Wi-Fi interface ID (default: 0)Example:
AT+UWSDC
Response: OK on success
| Issue | Symptoms | Possible Causes | Solutions |
|---|---|---|---|
| Authentication failure | ERROR on AT+UWSC=0 | Wrong password, unsupported security | Verify password, check WPA mode support |
| Connection timeout | Command hangs, no +UEWLU | Weak signal, network issues | Check RSSI with AT+UWSST=4, move closer to AP |
| No IP address | +UEWLU received but no +UEWSNU | DHCP issues, network config | Check router DHCP settings, try static IP |
| Frequent disconnections | Intermittent connectivity | Signal interference, power save | Disable power save, check for interference |
| Command | Purpose | Example Response |
|---|---|---|
AT+USYEE=1 | Enable extended error codes | OK |
AT+USYEC? | Check last error code | +USYEC:16 (auth failed) |
AT+UWSST=4 | Check signal strength | +UWSST:4,-65 (RSSI in dBm) |
AT+UWSNST? | Check network status | +UWSNST:0,192.168.1.179 + more params |
AT+UWSSC | Scan for Wi-Fi networks | +UWSSC:<bssid>,<ssid>,<channel>,<rssi>,... |
AT
OK
AT+USYEE=1
OK
AT+UWSCP=0
+UWSCP:0,"MyNetwork"
AT+UWSST=4
+UWSST:4,-45 // Good signal (-30 to -50 dBm)
AT+UWSC=0
OK
// Wait for events...
AT+USYEC?
+USYEC:16 // Error code 16 = Authentication failed

Connect as a Wi-Fi station to an Access Point using PEAP (Protected Extensible Authentication Protocol) and a RADIUS server to get access to network.
This use case connects NORA-W36 as a Wi-Fi station to an Access Point for access to the network. The connection is set to DHCP client by default.
<!--- 
--->
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Set SSID for the Network | AT+UWSCP=0,"NORA-W36 Access Point" | OK |
| 2 | Set the User and Password with TLS 1.3 | AT+UWSSP=0,2,"peap_user_name","peap_password" | OK |
| 3 | Connect Wi-Fi station | AT+UWSC=0 | OK |
| 4 | Wait for Wi-Fi interface | +UEWLU:0,BBBBBBBBBBB,6 | |
| 5 | Wait for Network interface | +UEWSNU | |
| 6 | Check IP address (optional) | AT+UWSNST=0 | +UWSNST:0,192.168.1.179 |
| 7 | Check RSSI (optional) | AT+UWSST=4 | +UWSST:4,-66 |
| 8 | It is now possible to connect TCP and UDP, and then send and receive data in String or Binary mode. It is also possible to connect MQTT. | ||
| 9 | Disconnect Wi-Fi station | AT+UWSDC | OK |
Important Note: If NORA-W36 should connect to Wi-Fi at startup the Connect, Store and Reset should be sent, AT+UWSC=0, AT&W and AT+CPWROFF, the current Wi-Fi Station state is stored in flash and NORA-W36 will try to connect using Service Set Identifier (SSID) and password stored at startup.

Connect as a Wi-Fi station to an Access Point using Extensible Authentication Protocol (EAP) and EAP Transport Layer Security (EAP-TLS) to get access to network.
This use case connects NORA-W36 as a Wi-Fi station to an Access Point for access to the network. The connection is set to DHCP client by default.
To use static IP the AT+UWSIPS set the IP address, gateway, subnet mask and DNS.
<!---
--->
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Write X.509 certificate and private key using Binary data | AT+USECUB=0,"ca.pem"{binary_content} + AT+USECUB=1,"client.pem"{binary_content} + AT+USECUB=2,"client.key"{binary_content} Note: Brackets { } should NOT be sent | OK |
| 2 | Set SSID for the Network | AT+UWSCP=0,"NORA-W36 Access Point" | OK |
| 3 | Set the certificates and key with TLS 1.3 | AT+UWSSE=0,2,"ca.pem","client.pem","client.key" | OK |
| 4 | Connect Wi-Fi station | AT+UWSC=0 | OK |
| 5 | Wait for Wi-Fi interface | +UEWLU:0,BBBBBBBBBBB,6 | |
| 6 | Wait for Network interface | +UEWSNU | |
| 7 | Check IP address (optional) | AT+UWSNST=0 | +UWSNST:0,192.168.1.179 |
| 8 | Check RSSI (optional) | AT+UWSST=4 | +UWSST:4,-66 |
| 9 | It is now possible to connect TCP and UDP, and then send and receive data in String or Binary mode. It is also possible to connect MQTT. | ||
| 10 | Disconnect Wi-Fi station | AT+UWSDC | OK |
Important Note: If NORA-W36 should connect to Wi-Fi at startup the Connect, Store and Reset should be sent, AT+UWSC=0, AT&W and AT+CPWROFF, the current Wi-Fi Station state is stored in flash and NORA-W36 will try to connect using Service Set Identifier (SSID) and password stored at startup.
TLS Version Options for EAP-TLS:
The second parameter in AT+UWSSE specifies the TLS version:
0: Disable TLS (not recommended for EAP-TLS)1: TLS 1.2 only2: TLS 1.3 only (recommended for enhanced security)3: TLS 1.2 or 1.3 (negotiate highest available)Security Recommendation: Use TLS 1.3 (parameter 2) for the strongest security posture, as it provides improved encryption algorithms, forward secrecy, and reduced handshake latency.

This use case configures NORA-W36 to act as a Wi-Fi Access Point that allows Wi-Fi Stations to connect, send, and receive data to the module.
The Wi-Fi connection has WPA2 encryption and a DHCP server that automatically assigns IP addresses to devices when they connect to the network.
The server assigns connected devices with IP addresses from 192.168.1.100 + x, where 'x' represents the additional IP addresses that can be assigned to other devices connected to the network.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Set the SSID and select network channel to 6 to define the frequency band | AT+UWAPCP="NORA-W36 Access Point",6 | OK |
| 2 | Set the Password, using WPA2 | AT+UWAPSW="mypassword" | OK |
| 3 | Activate the Wi-Fi Access point. DHCP Server is enabled by default | AT+UWAPA | OK |
| 4 | Wait for Access Point | +UEWAPU | |
| 5 | Wait for Network interface | +UEWAPNU | |
| 6 | Check the IP address of the AP (optional) | AT+UWAPNST=0 | +UWAPNST:0,192.168.1.80 |
| 7 | Station connected | +UEWAPSA:AAAAAAAAAAAA | |
| 8 | It is now possible to connect over TCP and UDP, and then send and receive data in String or Binary mode. It is also possible to connect MQTT. | ||
| 9 | Station disconnect | +UEWAPSDA:AAAAAAAAAAAA | |
| 10 | Deactivate Wi-Fi Access Point | AT+UWAPD | OK |
Note: If NORA-W36 activates Wi-Fi Access Point at startup, Activate (AT+UWAPA), Store (AT&W) and Reset (AT+CPWROFF) commands should be sent. The current Wi-Fi Access Point state is stored in flash and NORA-W36 then activates the Access Point using the stored SSID and password at startup.
IP address range is 192.168.1.100 + x to connected stations.
Security Limitation: Access Point mode supports WPA2 Personal only. WPA3 is not supported when operating as an Access Point.
AT+UWAPSW Command Format:
AT+UWAPSW=<password>
Parameters:
password: WPA2 password (8-63 characters)Security Features:
This chapter provides comprehensive security guidance for NORA-W36 implementation in production environments, covering wireless security, encryption protocols, certificate management, and operational security considerations.
Recommended Security Hierarchy (Best to Acceptable):
| Priority | Security Mode | Use Case | Implementation |
|---|---|---|---|
| 1st | WPA3 Personal | New deployments, high-security IoT | AT+UWSSW=0,"password",1 |
| 2nd | WPA2/WPA3 Compatible | Mixed environments, broader compatibility | AT+UWSSW=0,"password",0 |
| 3rd | EAP-TLS Enterprise | Corporate networks, certificate-based | AT+UWSSE=0,2,"ca.pem","client.pem","client.key" |
| 4th | PEAP Enterprise | Corporate networks, username/password | AT+UWSSP=0,2,"username","password" |
| Avoid | Open Networks | Never use in production | Not recommended |
WPA/WPA2/WPA3 Password Requirements:
✅ Strong Password Criteria:
Examples:
// Weak passwords (avoid)
AT+UWSSW=0,"password",0 // Dictionary word
AT+UWSSW=0,"12345678",0 // Sequential numbers
AT+UWSSW=0,"CompanyName",0 // Predictable
// Strong passwords (recommended)
AT+UWSSW=0,"Mx7$kL2@Rt9!uP",0 // Random strong password
AT+UWSSW=0,"BlueTree#2024$IoT",0 // Memorable but complex
Station Mode Security:
wpa_threshold=1)Access Point Mode Security:
+UEWAPSA eventsTLS Security Layer Architecture:
┌───────────── ┌───────────── ┌─────────────
│🛡 TLS 1.3 │ ── │🔒 TLS 1.2 │ ── │⚠ No TLS │
│ (Best) │ │ (Legacy) │ │ (Never!) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
Max Security Good Security No Security
🔧 TLS 1.3 Benefits: 🔧 TLS 1.2 Support: ⚠ Security Risk:
- • Forward secrecy • Legacy compatibility • Plain text data
- • 0-RTT handshake • Proven stability • No encryption
- • Modern encryption • Wide support • Vulnerable to attacks
TLS Security Hierarchy:
| Priority | TLS Version | Parameter | Use Case | Security Level |
|---|---|---|---|---|
| 1st | TLS 1.3 | 2 | New implementations, maximum security | 🛡 Highest |
| 2nd | TLS 1.2/1.3 | 3 | Transition period, server compatibility | 🔒 High |
| 3rd | TLS 1.2 | 1 | Legacy server support only | ⚠ Medium |
| Never | No TLS | 0 | Never use for secure connections | 🚫 None |
Implementation Examples:
// Best: TLS 1.3 only (recommended for new projects)
AT+USOTLS=0,2 // Socket TLS 1.3
AT+UMQTLS=0,2 // MQTT TLS 1.3
AT+UHTCTLS=0,2 // HTTP TLS 1.3
// Good: TLS 1.2/1.3 compatible (legacy support)
AT+USOTLS=0,3 // Negotiate highest available
Certificate Security Best Practices:
✅ Certificate Validation:
✅ Certificate Storage:
Certificate Upload Security:
// Upload complete certificate chain
AT+USECUB=0,"ca.pem"{binary_ca_cert} // Root CA
AT+USECUB=1,"intermediate.pem"{binary_int_cert} // Intermediate CA
AT+USECUB=2,"client.pem"{binary_client_cert} // Client certificate
AT+USECUB=3,"client.key"{binary_private_key} // Private key (secure!)
Certificate Validation Commands:
// List all certificates
AT+USECL?
// Verify specific certificate details
AT+USECD="ca.pem"
// Remove expired certificates
AT+USECR=1,"expired_cert.pem"
Recommended TLS Extension Configuration:
// Enable Server Name Indication (SNI) - Required for modern TLS
AT+USETE0=1 // Enable SNI (default: enabled)
// Enable Handshake Fragmentation - Prevents MTU issues
AT+USETE1=1 // Enable fragmentation (default: enabled)
// Store TLS extension settings
AT&W // Persist configuration
AT+CPWROFF // Reset to apply stored settings safely
Comprehensive MQTT Security Setup:
// Secure connection with TLS 1.3
AT+UMQCP=0,"secure-mqtt-broker.com",8883
AT+UMQTLS=0,2,"ca.pem","client.pem","client.key"
// Strong authentication (set connection parameters with credentials)
AT+UMQCP=0,"mqtt.broker.com",8883,"device_id_12345","device_id_12345","complex_password_67890"
// Connect securely
AT+UMQC=0
MQTT Security Checklist:
Secure HTTP Implementation:
// Always use HTTPS (port 443)
AT+UHTCCP=0,"api.secure-service.com",443
AT+UHTCTLS=0,2,"ca.pem"
// Add security headers
AT+UHTCRHAF=0,"Authorization","Bearer secure_token_here"
AT+UHTCRHAF=0,"User-Agent","NORA-W36/3.1.0"
AT+UHTCRHAF=0,"Content-Type","application/json"
// Make secure request
AT+UHTCRG=0,"/api/v1/secure-endpoint"
HTTP Security Checklist:
Secure Configuration Management:
// Change default settings
AT+UWAPCP="SecureIoTGateway_001",6 // Unique SSID
AT+UWAPSW="ComplexPassword#2024$" // Strong password
// Enable extended error reporting (development only)
AT+USYEE=1 // Enable during development
AT+USYEE=0 // Disable in production (security through obscurity)
// Store secure configuration
AT&W // Save to flash
AT+CPWROFF // Reset to apply stored settings safely
// Test configuration
AT+UWSNST=0 // Verify network status
AT+UWSSC // List available networks
Secure Power Save Configuration:
// Balance security and power efficiency
AT+UPMPSL=1 // Enable moderate power save
AT+UPMPSTO=5000 // 5-second timeout (balance responsiveness/power)
AT&W // Store settings
AT+CPWROFF // Reset to apply stored settings safely
// Security consideration: Ensure power save doesn't impact security monitoring
Security Monitoring Commands:
// Regular security health checks
AT+UWSST=4 // Monitor signal strength (detect rogue APs)
AT+UWSNST=0 // Verify network connection status, only IPv4 Address
AT+USECL? // Check certificate validity
AT+USYEC? // Check for error conditions
AT+UWSNST? // Verify network connection status, all parameters
Rapid Response Commands:
| Security Event | Immediate Action | Command |
|---|---|---|
| Suspicious connection | Disconnect immediately | AT+UWSDC |
| Authentication failure | Check credentials, reset if needed | AT+USYEC? → reconfigure |
| Certificate error | Verify and reload certificates | AT+USECL? → AT+USECR → reload |
| Weak signal | Check for interference/rogue AP | AT+UWSST=4 |
| Connection timeout | Reset network configuration | AT+UWSDC → reconfigure |
Regular Security Review (Monthly):
Security Configuration Validation:
// Complete security status check
AT+UWSCP=0 // Verify SSID configuration
AT+UWSS=0 // Check security configuration
AT+USECL? // List all certificates and expiration
AT+USYEC? // Check for any error conditions
This comprehensive security framework ensures NORA-W36 deployments maintain the highest security standards while remaining operationally efficient.
This chapter provides comprehensive performance optimization guidance for NORA-W36 deployments, covering connection optimization, power efficiency, memory management, and throughput enhancement techniques for maximum system performance.
Fast Connection Techniques:
| Optimization | Implementation | Performance Impact | Command Example |
|---|---|---|---|
| Pre-scan networks | Scan before connecting | 2-3 seconds faster | AT+UWSSC |
| Channel optimization | Use specific SSID only | 1-2 seconds faster | AT+UWSCP=0,"MyAP" |
| Aggressive power save | Disable during connection | 1-3 seconds faster | AT+UPMPSL=0 (temporarily) |
| DHCP timeout tuning | Reduce DHCP wait time | 2-5 seconds faster | System automatic |
Optimal Connection Sequence:
// Disable power save during connection (faster scanning)
AT+UPMPSL=0
// Scan for target network (get channel info)
AT+UWSSC
// Connect with specific parameters
AT+UWSCP=0,"TargetNetwork" // Set SSID (channel determined by AP)
// Verify connection quickly
AT+UWSNST=0
// Re-enable power save after connection
AT+UPMPSL=1
TCP Socket Optimization:
// Enable TCP fast recovery
AT+USORS=0,1000 // Read available data (1kB chunks)
// Use larger receive operations for bulk data
AT+USORS=0,1000 // 1kB chunks for file transfers
// Monitor socket status for optimal timing
AT+USYEE=1 // Enable extended error reporting
UDP Performance Configuration:
// UDP is inherently faster - optimize for your use case
AT+USORS=0,1000 // Standard read operations
TLS Handshake Optimization:
| TLS Version | Handshake Time | Security Level | Recommended Use |
|---|---|---|---|
| TLS 1.3 | ~2-3 seconds | Highest | New deployments |
| TLS 1.2 | ~3-4 seconds | High | Legacy compatibility |
| TLS 1.2/1.3 Auto | ~2-4 seconds | High | Mixed environments |
TLS Performance Commands:
// Fastest: TLS 1.3 with session resumption
AT+USOTLS=0,2 // TLS 1.3 for new connections
AT+USETE1=1 // Enable handshake fragmentation (faster on slow networks)
AT+USETE0=1 // Enable SNI (required for many servers)
// Pre-load certificates for faster handshake
AT+USECL? // Verify certificates are already loaded
⚡ Power Management Decision Matrix:
┌───────────── ┌───────────── ┌─────────────
│🚀 High Perf │ ── │⚖ Balanced │ ── │🔋 Low Power │
│ Mode 0 │ │ Mode 1 │ │ Mode 2 │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
Max Speed Good Balance Max Battery
⚡ Performance: ⚖ Balanced: 🔋 Power Saving:
- • No delays • Smart trade-offs • Extended battery
- • Instant response • Good responsiveness • Ideal for IoT
- • High throughput • Moderate power • Periodic updates
Power Save Performance Matrix:
| Power Mode | Power Consumption | Response Time | Throughput | Best Use Case |
|---|---|---|---|---|
| 🚀 Disabled (0) | High | Instant | Maximum | High-throughput streaming |
| ⚖ Light (1) | Medium | Medium | Good | Real-time communications |
| 🔋 Moderate (2) | Low | Long | Reduced | Periodic data updates |
Adaptive Power Management:
💡 Timeout Logic: High-performance mode uses longer timeouts to maintain sustained operation without frequent power state changes. IoT sensors use shorter timeouts for quick wake-up and responsiveness to events.
// High performance mode (data streaming)
AT+UPMPSL=0 // Disable power save
AT+UPMPSTO=30000 // Long timeout (30 seconds) for sustained performance
// Balanced mode (regular operations)
AT+UPMPSL=1 // Light power save
AT+UPMPSTO=5000 // 5-second timeout
// Power efficient mode (IoT sensors)
AT+UPMPSL=2 // Moderate power save
AT+UPMPSTO=1000 // Short timeout (1 second) for quick responsiveness
// Save configuration
AT&W
AT+CPWROFF // Reset to apply stored settings safely
Context-Aware Power Management:
// During active data transfer - maximum performance
AT+UPMPSL=0 // Disable power save
// After transfer complete - enable power save
AT+UPMPSL=1 // Light power save for quick response
// During idle periods - deep power save
AT+UPMPSL=2 // Moderate power save
// Example: Automatic switching based on socket activity
// (implement in host application logic)
Memory Allocation Best Practices:
| Resource | Optimal Size | Performance Impact | Command |
|---|---|---|---|
| Socket Operations | 1KB for bulk data | Higher throughput | AT+USORS=0,1000 |
| Certificate Storage | Minimize certificates | Faster boot/connection | AT+USECL? |
| Connection Management | Regular monitoring | Prevents issues | AT+UWSNST=0 |
Memory Monitoring Commands:
// Check certificate usage
AT+USECL? // List certificates and sizes
// Remove unused certificates
AT+USECL? // List certificates
AT+USECR=0,"old_cert.pem" // Remove unused certificates
// Remove unused certificates to free storage
AT+USECR=0,"unused.pem" // Remove unused certificates
Optimal Data Transfer Guidelines:
// For socket operations, use appropriate read/write sizes
// Socket commands will be covered in Wi-Fi Sockets section
// Focus on connection optimization and certificate management
Signal Strength Optimization:
| Signal Strength (RSSI) | Performance Level | Recommended Action |
|---|---|---|
| -30 to -50 dBm | Excellent | Maintain current position |
| -50 to -70 dBm | Good | Monitor for degradation |
| -70 to -85 dBm | Fair | Consider repositioning |
| Below -85 dBm | Poor | Reposition or use repeater |
Signal Monitoring Commands:
// Check current signal strength
AT+UWSST=4 // Signal strength in dBm
// Monitor connection quality
AT+UWSNST=0 // Network status and quality
// Scan for alternative networks
AT+UWSSC // Scan and compare signal levels
Channel Optimization Strategy:
// Scan all channels to find optimal one
AT+UWSSC
// Example: Choose less congested channel
// If scan shows:
- // Channel 1: Many APs (congested)
- // Channel 6: Few APs (better choice)
- // Channel 11: Few APs (best choice)
// Configure network (channel determined by AP)
AT+UWSCP=0,"MyNetwork" // Set SSID
Performance Comparison by Protocol:
| Protocol | Latency | Throughput | Overhead | Best Use Case |
|---|---|---|---|---|
| UDP | Lowest | Highest | Minimal | Real-time data, streaming |
| TCP | Low | High | Low | Reliable data transfer |
| TLS/TCP | Medium | Medium | Medium | Secure communications |
| HTTP/HTTPS | High | Medium | High | API calls, web services |
| MQTT | Medium | Medium | Low | IoT messaging, pub/sub |
Efficient Data Formats:
// JSON (human readable, moderate efficiency)
{"temp":23.5,"hum":65,"time":1640995200}
// Compact JSON (remove spaces, shorter keys)
{"t":23.5,"h":65,"ts":1640995200}
// Binary format (highest efficiency)
// Custom binary protocol for maximum performance
// bytes: temperature (float)
// bytes: humidity (float)
// bytes: timestamp (uint32)
// Total: 12 bytes vs 45+ bytes JSON
Key Performance Indicators:
// Connection establishment time
// Measure time between AT+UWSC and +UEWLU event
// Data transfer throughput
// Measure bytes/second during AT+USOWS/AT+USORS operations
// Power consumption monitoring
// Use external current meter with different AT+UPMPSL settings
// Certificate usage tracking
AT+USECL? // Check certificate storage regularly
Standardized Performance Tests:
| Test Type | Measurement | Target Performance | Command Sequence |
|---|---|---|---|
| Connection Speed | Time to connect | <10 seconds | AT+UWSC=0 timing |
| TCP Throughput | Bytes per second | >100 KB/s | Large AT+USOWS transfers |
| TLS Handshake | Handshake time | <5 seconds | AT+USOTLS timing |
| Power Efficiency | mA consumption | <50mA average | Current measurement |
Performance Test Sequence:
// Baseline connection test
AT+UWSC=0 // Time this command
// Target: <10 seconds to +UEWLU
// Throughput test
AT+USOCR=6 // Create TCP socket
AT+USOC=0,server,port // Connect
AT+USOWS=0,"data" // Write data (up to 1000 bytes per command)
// Measure: bytes/second throughput
// Power consumption test
AT+UPMPSL=1 // Enable power save
// Measure current draw over time
// Certificate storage test
AT+USECL? // Check certificates before/after operations
| Performance Issue | Probable Cause | Solution | Verification |
|---|---|---|---|
| Slow connection | Weak signal, channel congestion | Reposition, change channel | AT+UWSST=4 |
| Low throughput | Power save mode, small buffers | Disable power save, larger buffers | AT+UPMPSL=0 |
| High latency | Network congestion, DNS delays | Use IP instead of hostnames | AT+USOC=0,"192.168.1.100",80 |
| Memory errors | Certificate/file accumulation | Clean up unused certificates | AT+USECL? |
Regular Performance Maintenance:
| Task | Frequency | Command | Target |
|---|---|---|---|
| Signal check | Weekly | AT+UWSST=4 | RSSI >-70 dBm |
| Certificate cleanup | Monthly | AT+USECL? | Remove expired certificates |
| Power mode verification | - | - | Confirm appropriate power save settings |
| Throughput validation | - | - | Test data transfer speeds match requirements |
| Certificate monitoring | Regular | AT+USECL? | Check certificate status |
| Connection timing | - | - | Verify connection establishment <10 seconds |
| Error rate monitoring | Regular | AT+USYEC? | Check for increased error rates |
Optimal Configuration Summary:
// High-performance configuration
AT+UPMPSL=0 // Disable power save during operation
AT+USOTLS=0,2 // Use TLS 1.3 for fastest secure connections
AT+USORS=0,1000 // Optimize for 1000-byte MTU limit
AT+USYEE=1 // Enable extended error reporting
// Power-efficient configuration
AT+UPMPSL=1 // Light power save
AT+UPMPSTO=10000 // 10-second timeout
AT+USORS=0,512 // Smaller read operations for efficiency
AT&W // Save configuration
AT+CPWROFF // Reset to apply stored settings safely
This comprehensive performance framework ensures NORA-W36 implementations achieve optimal speed, efficiency, and reliability across all operating conditions.
This use case configures NORA-W36 as a Wi-Fi TCP client device that initiates a TCP connection to a specified server (listener) over a Wi-Fi network. It actively seeks to establish communication by sending a connection request to the server's IP address and port number, which the server is listening on.
The Transmission Control Protocol (TCP) is bidirectional and one socket can both send and receive data:
ATE0 turns off the AT command echo to speed up the data transmission in AT mode. The written data is not echoed back to the host, which helps to make the parsing easier.AT+USOC=0,"www.u-blox.com",80 or an IP address AT+USOC=0,"75.2.60.5",80| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Create a TCP socket | AT+USOCR=6 | +USOCR:0 |
| 2 | Connect using TCP port 5003 | AT+USOC=0,"192.168.0.200",5003 | +UESOC:0 |
| 3 | It is now possible to send and receive data using String or Binary mode | ||
| 4 | Close TCP socket | AT+USOCL=0 | +UESOCL:0 |
This use case configures NORA-W36 as a Wi-Fi TCP server (listener) that is configured to accept incoming TCP connections over a Wi-Fi network. It "listens" on a specific IP address and port number for connection requests.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Create a TCP socket | AT+USOCR=6 | +USOCR:0 |
| 2 | Start TCP server (listener) on port 5003 | AT+USOL=0,5003 | +UESOC:0 |
| 3 | Incoming TCP connection, a new handle 1 to communicate with the connection | +UESOIC:0,192.168.1.100,1 | |
| 4 | It is now possible to send and receive data using String or Binary mode | ||
| 5 | TCP connection is closed from remote side | +UESOCL:1 | |
| 6 | Close TCP listener | AT+USOCL=0 | +UESOCL:0 |
Unlike TCP, the User Datagram Protocol (UDP) is not bi-directional. Both an outgoing and incoming socket, AT+USOCR, are needed to send and receive data over UDP.
It is possible to connect using the host name, like AT+USOC=0,"www.u-blox.com",80, or the IP address AT+USOC=0,"75.2.60.5",80
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Create a UDP socket | AT+USOCR=17 | +USOCR:0 |
| 2 | Connect using UDP port 5003 | AT+USOC=0,"192.168.0.200",5003 | +UESOC:0 |
| 3 | It is now possible to send data using String or Binary mode | ||
| 4 | Close UDP socket | AT+USOCL=0 | +UESOCL:0 |
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Create a UDP socket | AT+USOCR=17 | +USOCR:0 |
| 2 | Start UDP server (listener) on port 5003 | AT+USOL=0,5003 | +UESOC:0 |
| 3 | It is now possible to receive data using String or Binary mode | ||
| 4 | Close UDP listener | AT+USOCL=0 | +UESOCL:0 |
TLS Extensions are enabled by default but in some (mostly older) TLS servers they are not supported. See https://www.rfc-editor.org/rfc/rfc6066.html.
The extensions, Server Name, Indication and Maximum Fragment Length Negotiation, are disabled with:
AT+USETE0=0 Server Name Indication, 0: Disable - 1: Enable (default)AT+USETE1=0 Maximum Fragment Length Negotiation, 0: Disable - 1: Enable (default)AT+USOC=0,"www.u-blox.com",80 or using ip address AT+USOC=0,"75.2.60.5",80 for the connections.TCP is bidirectional and one socket can both send and receive data.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Create a TCP socket | AT+USOCR=6 | +USOCR:0 |
| 2 | Add a TLS 1.3 context to a socket | AT+USOTLS=0,2 | |
| 3 | Connect using TCP port 433 | AT+USOC=0,"www.u-blox.com",433 | +UESOC:0 |
| 4 | It is now possible to send data using String or Binary mode | ||
| 5 | Close TCP socket | AT+USOCL=0 | +UESOCL:0 |
TCP is bidirectional and one socket can both send and receive data.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Write X.509 certificate and private key using Binary data | AT+USECUB=0,"ca.pem"{binary_content} + AT+USECUB=1,"client.pem"{binary_content} + AT+USECUB=2,"client.key"{binary_content} Note: Brackets { } should NOT be sent | OK |
| 2 | Create a TCP socket | AT+USOCR=6 | +USOCR:0 |
| 3 | Add a TLS 1.3 context to a socket and certificates | AT+USOTLS=0,2,"ca.pem","client.pem","client.key" | |
| 4 | Connect using TCP on port 433 | AT+USOC=0,"www.u-blox.com",433 | +UESOC:0 |
| 5 | It is now possible to send data using String or Binary mode | ||
| 6 | Close TCP socket | AT+USOCL=0 | +UESOCL:0 |
This section provides examples for creating your own certificates using OpenSSL (https://www.openssl.org/).
The examples demonstrate how to use 2048-bit or 4096-bit key lengths for different security requirements.
Prerequisites:
Step 1: Create the root CA private key
Generate 2048-bit key size (faster, suitable for most applications):
openssl genrsa -out ca.key 2048
Or generate 4096-bit key size (higher security, recommended for production):
openssl genrsa -out ca.key 4096
Step 2: Create the root CA certificate (valid for 1 year)
openssl req -x509 -sha256 -new -nodes -key ca.key -days 365 -out ca.pem
Step 3: Create server certificate signing request (CSR)
For 2048-bit key:
openssl req -newkey rsa:2048 -keyout server.key -out server.csr -nodes
Or for 4096-bit key:
openssl req -newkey rsa:4096 -keyout server.key -out server.csr -nodes
Step 4: Sign server certificate with CA (valid for 1 year)
openssl x509 -req -CA ca.pem -CAkey ca.key -in server.csr -out server.pem -days 365 -CAcreateserial
Step 5: Create client certificate signing request (CSR)
For 2048-bit key:
openssl req -newkey rsa:2048 -keyout client.key -out client.csr -nodes
Or for 4096-bit key:
openssl req -newkey rsa:4096 -keyout client.key -out client.csr -nodes
Step 6: Sign client certificate with CA (valid for 1 years)
openssl x509 -req -CA ca.pem -CAkey ca.key -in client.csr -out client.pem -days 365 -CAcreateserial
Windows Git Bash Environment:
Note: winpty is required for interactive OpenSSL commands in Git Bash on Windows.
TLS 1.2 Testing:
Set up a local TLS 1.2 server:
winpty openssl s_server -CAfile ca.pem -key server.key -cert server.pem -accept 44330 -tls1_2 -state -Verify 1
Connect to the local TLS 1.2 server:
winpty openssl s_client -connect localhost:44330 -CAfile ca.pem -key client.key -cert client.pem -tls1_2
TLS 1.3 Testing:
Set up a local TLS 1.3 server:
winpty openssl s_server -CAfile ca.pem -key server.key -cert server.pem -accept 44331 -tls1_3 -state -Verify 1
Connect to the local TLS 1.3 server:
winpty openssl s_client -connect localhost:44331 -CAfile ca.pem -key client.key -cert client.pem -tls1_3
Linux Environment:
TLS 1.2 Testing:
Set up a local TLS 1.2 server:
openssl s_server -CAfile ca.pem -key server.key -cert server.pem -accept 44330 -tls1_2 -state -Verify 1
Connect to the local TLS 1.2 server:
openssl s_client -connect localhost:44330 -CAfile ca.pem -key client.key -cert client.pem -tls1_2
TLS 1.3 Testing:
Set up a local TLS 1.3 server:
openssl s_server -CAfile ca.pem -key server.key -cert server.pem -accept 44331 -tls1_3 -state -Verify 1
Connect to the local TLS 1.3 server:
openssl s_client -connect localhost:44331 -CAfile ca.pem -key client.key -cert client.pem -tls1_3
Testing Both TLS Versions (Flexible):
For testing compatibility with both TLS 1.2 and 1.3:
// Server that accepts both TLS 1.2 and 1.3 (Windows)
winpty openssl s_server -CAfile ca.pem -key server.key -cert server.pem -accept 44332 -state -Verify 1
// Server that accepts both TLS 1.2 and 1.3 (Linux)
openssl s_server -CAfile ca.pem -key server.key -cert server.pem -accept 44332 -state -Verify 1
// Client connecting with version negotiation (will use highest available)
winpty openssl s_client -connect localhost:44332 -CAfile ca.pem -key client.key -cert client.pem // Windows
openssl s_client -connect localhost:44332 -CAfile ca.pem -key client.key -cert client.pem // Linux
Verify CA certificate key size:
openssl x509 -in ca.pem -text -noout | grep "Public-Key"
Expected output: RSA Public-Key: (4096 bit) or RSA Public-Key: (2048 bit)
Verify client certificate key size:
openssl x509 -in client.pem -text -noout | grep "Public-Key"
Expected output: RSA Public-Key: (4096 bit) or RSA Public-Key: (2048 bit)
Verify client private key size:
openssl rsa -in client.key -text -noout | grep "Private-Key"
Expected output: RSA Private-Key: (4096 bit, 2 primes) or RSA Private-Key: (2048 bit, 2 primes)
Key Size Selection:
Certificate Validity:
File Security:
*.key) with appropriate file permissionsNORA-W36 provides comprehensive certificate management capabilities for secure storage and administration of X.509 certificates and private keys.
Certificate Storage Capacity:
Certificate Management Commands:
| Command | Purpose | Example |
|---|---|---|
AT+USECL? | List all stored certificates | Shows all certificate names and types |
AT+USECD=<name> | Show certificate details | AT+USECD="client.pem" |
AT+USECR=<type>,<name> | Remove specific certificate | AT+USECR=1,"client.pem" |
AT+USECR | Remove all certificates | Clears certificate storage |
Certificate Types:
0: Root/CA certificate1: Client certificate2: Client private keyCertificate Operations Examples:
// List all stored certificates
AT+USECL?
+USECL:0,"ca-root"
+USECL:1,"device-cert"
+USECL:2,"device-key"
// View certificate details (fingerprint, size, validity dates)
AT+USECD="device-cert"
+USECD:0,A1B2C3D4E5F6... // Certificate fingerprint (hex)
+USECD:1,2048 // Certificate size in bytes (decimal)
+USECD:2,5F5E1000 // Not valid before: Unix epoch in hex (Jan 1, 2023)
+USECD:3,6586A400 // Not valid after: Unix epoch in hex (Dec 31, 2025)
// Remove specific certificate
AT+USECR=1,"old-client-cert"
// Remove all certificates (factory reset certificates)
AT+USECR
Understanding Certificate Fingerprint:
The fingerprint (+USECD:0) is a SHA-256 hash of the certificate, useful for verification and identification.
Calculate and Verify Fingerprint with OpenSSL:
# Calculate SHA-256 fingerprint using OpenSSL
openssl x509 -noout -fingerprint -sha256 -in ca.pem
Real Example:
# NORA-W36 output:
AT+USECD="ca.pem"
+USECD:0,025EF9A024DEF7FCBFD6E3717557C016BCB9C34E6BAA288111D53F9490E06CC2
# OpenSSL verification:
$ openssl x509 -noout -fingerprint -sha256 -in ca.pem
sha256 Fingerprint=02:5E:F9:A0:24:DE:F7:FC:BF:D6:E3:71:75:57:C0:16:BC:B9:C3:4E:6B:AA:28:81:11:D5:3F:94:90:E0:6C:C2
Note: NORA-W36 returns fingerprint as continuous hex string, while OpenSSL formats with colons.
Understanding Certificate Date Format:
6586A400 (hex) = 1,703,462,400 (decimal) = Dec 25, 2023 00:00:00 UTCdate -d @$((0x6586A400)) (Linux/macOS)[DateTimeOffset]::FromUnixTimeSeconds(0x6586A400).DateTimeSecurity Best Practices:
AT+USECL? to monitor stored certificatesAT+USECRAT+USECDCertificate Date Format Reference:
When using AT+USECD to check certificate validity dates, the NORA-W36 returns timestamps in hexadecimal Unix epoch format:
AT+USECD="my-certificate"
+USECD:2,61F2D000 // Not valid before: Jan 27, 2022 12:00:00 UTC
+USECD:3,6586A400 // Not valid after: Dec 25, 2023 00:00:00 UTC
Converting Hex Epoch Timestamps:
| Method | Command/Code | Example |
|---|---|---|
| Linux/macOS | date -d @$((0xHEXVALUE)) | date -d @$((0x6586A400)) |
| PowerShell | [DateTimeOffset]::FromUnixTimeSeconds(0xHEXVALUE) | [DateTimeOffset]::FromUnixTimeSeconds(0x6586A400) |
| Python | datetime.fromtimestamp(int('HEXVALUE', 16)) | datetime.fromtimestamp(int('6586A400', 16)) |
| Online Tools | Use epoch timestamp converters | Convert 1703462400 to human date |
Common Epoch Hex Values:
0x61F2D000 = 1,643,289,600 = Jan 27, 2022 12:00:00 UTC0x6586A400 = 1,703,462,400 = Dec 25, 2023 00:00:00 UTC0x677B8000 = 1,736,207,360 = Jan 7, 2025 00:16:00 UTCPassword-Protected Private Keys:
NORA-W36 supports AES-encrypted PKCS8 private keys with password protection:
// Upload encrypted private key with password
AT+USECUB=2,"secure-key","mypassword123"{binary_data}
NORA-W36 v3.1.0 introduces comprehensive TLS 1.3 support across all protocols including EAP-TLS, TCP sockets, HTTP clients, and MQTT. This enhanced security capability provides improved encryption algorithms, forward secrecy, and reduced handshake latency.
TLS Version Parameters:
All TLS-enabled AT commands support the following version parameters:
0: Disable TLS (not recommended for secure connections)1: TLS 1.2 only (legacy compatibility)2: TLS 1.3 only (recommended for new implementations)3: TLS 1.2 or 1.3 (negotiate highest available - flexible option)Protocol-Specific TLS Support:
| Protocol | AT Command | Example (TLS 1.3) | Security Benefits |
|---|---|---|---|
| EAP-TLS | AT+UWSSE | AT+UWSSE=0,2,"ca.pem","client.pem","client.key" | Enterprise Wi-Fi with latest security |
| PEAP | AT+UWSSP | AT+UWSSP=0,2,"username","password" | Protected authentication tunnel |
| TCP Socket | AT+USOTLS | AT+USOTLS=0,2,"ca.pem","client.pem","client.key" | Secure socket connections |
| MQTT | AT+UMQTLS | AT+UMQTLS=0,2,"ca.pem","client.pem","client.key" | IoT messaging security |
| HTTP | AT+UHTCTLS | AT+UHTCTLS=0,2,"ca.pem","client.pem","client.key" | Web API secure access |
TLS 1.3 Security Enhancements:
Migration Recommendations:
2) for maximum security3) during transitionNORA-W36 supports advanced TLS extensions that enhance security and compatibility with modern TLS implementations.
Available TLS Extensions:
| Extension | AT Command | Purpose | Default State |
|---|---|---|---|
| Server Name Indication (SNI) | AT+USETE0 | Identifies target server hostname | Enabled |
| Handshake Fragmentation | AT+USETE1 | Fragments large handshake messages | Enabled |
Server Name Indication (SNI):
// Enable SNI (recommended for most applications)
AT+USETE0=1
// Disable SNI (only for legacy servers)
AT+USETE0=0
// Check current SNI setting
AT+USETE0?
Handshake Fragmentation:
// Enable handshake fragmentation (recommended)
AT+USETE1=1
// Disable handshake fragmentation
AT+USETE1=0
// Check current fragmentation setting
AT+USETE1?
Configuration Best Practices:
AT&W followed by AT+CPWROFF to persist extension settings across reboots📡 MQTT Communication Overview:
┌───────────── ┌───────────── ┌─────────────
│📱 Publisher │────▶│ MQTT │◄────│📱 Subscriber│
│ (NORA-W36) │ │ Broker │ │ (Device) │
│ │ │ │ │ │
│ Sends data │ │ Routes │ │ Receives │
│ to topics │ │ messages │ │ from topics │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
Publish Msgs Topic Routing Subscribe
🔧 Features: Broker: 📊 Benefits:
- • Low bandwidth • Topic management • Decoupled comm.
- • Reliable delivery • Message routing • Scalable design
- • QoS levels (0,1,2) • Client sessions • IoT optimized
MQTT (Message Queuing Telemetry Transport) is a lightweight, publish-subscribe messaging protocol designed for IoT applications with constrained networks and devices. It enables efficient communication between devices and cloud services with minimal bandwidth and power consumption.
Key MQTT characteristics:
NORA-W36 MQTT Implementation:
MQTT provides three QoS levels to guarantee message delivery:
QoS 0 - At Most Once
AT+UMQPS=0,0,0,"temperature","25.5" // QoS 0 publish
QoS 1 - At Least Once
AT+UMQPS=0,1,0,"alert","Low battery warning" // QoS 1 publish
QoS 2 - Exactly Once
AT+UMQPS=0,2,0,"command","device_reset" // QoS 2 publish
Retained messages are stored by the broker and delivered to new subscribers immediately upon subscription:
Publishing a retained message:
AT+UMQPS=0,0,1,"device/status","online" // Retain flag = 1
Use cases for retained messages:
LWT allows devices to specify a message that the broker publishes automatically if the device disconnects unexpectedly:
Configuration example:
// Configure LWT during connection setup
AT+UMQCP=0,"broker.example.com",1883,"device123","user","pass"
LWT use cases:
Clean Session Flag:
Keep-Alive Timer:
Common MQTT Error Scenarios:
| Issue | Symptoms | Solution |
|---|---|---|
| Connection timeout | AT+UMQC=0 returns ERROR | Check network connectivity and broker address |
| Authentication failure | Connection rejected | Verify username/password credentials |
| Certificate errors | TLS connection fails | Validate CA certificate and client certificates |
| Keep-alive timeout | Unexpected disconnection | Adjust keep-alive timer or check network stability |
| Invalid client ID | Connection refused | Use unique, valid client identifier |
MQTT Connection Status:
+UEMQC:0+UEMQD:<handle>,<length>Troubleshooting Steps:
| Step | Command | Purpose |
|---|---|---|
| 1 | AT+UWSNST? | Check connection status |
| 2 | AT+UWSNST=0 | Verify Wi-Fi connectivity |
| 3 | AT+UWSST=0 | Check network interface status |
| 4 | AT+UWSSC | Check AP status |
| 5 | - | Check MQTT connection status |
| 6 | - | Validate certificates for TLS connections |
| 7 | - | Monitor keep-alive and adjust if needed |
| 8 | - | Review broker logs for additional error details |
Connection Parameters:
| Parameter | Optimal Range | Impact |
|---|---|---|
| Keep-Alive | 30-300 seconds | Network efficiency vs responsiveness |
| Clean Session | Context-dependent | Memory usage vs session persistence |
| QoS Level | 0-1 for most cases | Reliability vs performance |
| Message Size | < 1KB preferred | Network bandwidth and processing |
Best Practices:
Network Considerations:

This use case connects NORA-W36 as a Wi-Fi Station and a MQTT Broker on port 1883. In this scenario, the module connects to Mosquitto without a certificate.
Parameters and values
Before connecting to MQTT, set up Wi-Fi Connection, as described in Wi-Fi station, steps 1-5.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Check MQTT connection parameters | AT+UMQCP=0 | +UMQCP:0,<hostname>,<port>,<client_id>,<username> |
| 2 | Configure MQTT host and port | AT+UMQCP=0,"test.mosquitto.org",1883 | OK |
| 3 | Connect to MQTT broker | AT+UMQC=0 | +UEMQC:0 |
| 4 | Publish Message on topic pubtopic | AT+UMQPS=0,0,0,"pubtopic","Hello from NORA-W36" | OK |
| 5 | Subscribe on topic subtopic | AT+UMQS=0,0,"subtopic" | OK |
| 6 | Post a Message to the MQTT Broker on subtopic the message should be Hello from remote device | - | - |
| 7 | Receive Message on subtopic | +UEMQD:0,24 | |
| 8 | Read String Message | AT+UMQRS=0 | +UMQRS:0,0,"subtopic",24,"Hello from remote device" |
| 9 | Disconnect from MQTT broker | AT+UMQDC=0 | OK |
Note: Use the wildcard "*" to receive messages for all topics. Note that this option may not be supported by all brokers, like Azure.


This use case connects NORA-W36 as a Wi-Fi Station and a MQTT Broker. In this scenario, the module connects to Mosquitto using certificates.
To generate client certificate and client key, follow the procedures described on the Mosquitto web page: https://test.mosquitto.org/ssl/
Parameters and values
Note: The parameters given in this scenario use the port 8884 for connections and encryption for security.
To authenticate the client and ensure the following:
Before connecting to MQTT, set up a Wi-Fi Connection like that described in Wi-Fi station, steps 1-5.
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Configure MQTT host and port | AT+UMQCP=0,"test.mosquitto.org",8884 | OK |
| 2 | Write X.509 certificate and private key using Binary data | AT+USECUB=0,"mosquitto.org.crt"{binary_content} + AT+USECUB=1,"client.crt"{binary_content} + AT+USECUB=2,"client.key"{binary_content} Note: Brackets { } should NOT be sent | OK |
| 3 | Setup TLS 1.3 connection config | AT+UMQTLS=0,2,"mosquitto.org.crt","client.crt","client.key" | OK |
| 4 | Connect to MQTT broker | AT+UMQC=0 | +UEMQC:0 |
| 5 | Publish Message on topic pubtopic | AT+UMQPS=0,0,0,"pubtopic","Hello from NORA-W36" | OK |
| 6 | Subscribe on topic subtopic | AT+UMQS=0,0,"subtopic" | OK |
| 7 | Post a Message to the MQTT Broker on subtopic. The message should say Hello from remote device | - | - |
| 8 | Receive Message on subtopic | +UEMQD:0,24 | |
| 9 | Read String Message | AT+UMQRS=0 | +UMQRS:0,0,"subtopic",24,"Hello from remote device" |
| 10 | Disconnect from MQTT broker | AT+UMQDC=0 | OK |


Thingstream is the u-blox service delivery platform for:
This use case connects NORA-W36 as a Wi-Fi Station and a MQTT Broker. In this scenario NORA-W36 connects to Thingstream using a CA Root certificate, Client-ID, Username and Password.
Thingstream uses the AWS Root Certificate found here: https://www.amazontrust.com/repository/AmazonRootCA1.pem
Before connecting to MQTT, set up Wi-Fi Connection, like that described Wi-Fi station, steps 1-5.
The parameters and values necessary for the use case include:
Parameters and values
Before connecting to MQTT, set up Wi-Fi Connection like in steps 1-5 in Wi-Fi station
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Configure the MQTT host, port, client-ID, username and password | AT+UMQCP=0,"mqtt.thingstream.io",8883,"device:78e3d356-876f-483b-872f-3485853fAAAA","HMVK8C09FQP245O2BBBB","ofYyBB/L3GkPvo060J6Dv+t+mfrh0XpGMcf7CCCC" | OK |
| 2 | Write X.509 CA Root certificate using Binary data | AT+USECUB=0,"AmazonRootCA1.pem"{binary_content} Note: Brackets { } should NOT be sent | OK |
| 3 | Set up TLS connection config. Thingstream doesn´t use a client certificate or key - only the root CA. | AT+UMQTLS=0,1,"AmazonRootCA1.pem" | OK |
| 4 | Connect to MQTT broker | AT+UMQC=0 | +UEMQC:0 |
| 5 | Publish a message on pubtopic | AT+UMQPS=0,0,0,"pubtopic","Hello from NORA-W36" | OK |
| 6 | Subscribe on topic subtopic | AT+UMQS=0,0,"subtopic" | OK |
| 7 | Post a message to the MQTT broker on subtopic. The message should say Hello from remote device | - | - |
| 8 | Receive a message on subtopic | +UEMQD:0,24 | |
| 9 | Read String Message | AT+UMQRS=0 | +UMQRS:0,0,"subtopic",24,"Hello from remote device" |
| 10 | Disconnect from MQTT broker | AT+UMQDC=0 | OK |

Connect as a Wi-Fi Station and a MQTT Broker. In this scenario, NORA-W36 connects to Amazon AWS IoT Core using certificates.
Parameters and values
Before connecting to MQTT, set up Wi-Fi Connection like in steps 1-5 in Wi-Fi station
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Configure MQTT host and port | AT+UMQCP=0,"a3loryode2aaaa-ats.iot.us-east-2.amazonaws.com",8883 | OK |
| 2 | Write X.509 certificate and private key using Binary data | AT+USECUB=0,"AmazonRootCA1.pem"{binary_content} + AT+USECUB=1,"aws_client.crt"{binary_content} + AT+USECUB=2,"aws_priv_key.key"{binary_content} Note: Brackets { } should NOT be sent | OK |
| 3 | Setup TLS connection config | AT+UMQTLS=0,1,"AmazonRootCA1.pem","aws_client.crt","aws_priv_key.key" | OK |
| 4 | Connect to MQTT broker | AT+UMQC=0 | +UEMQC:0 |
| 5 | Publish Message on topic pubtopic | AT+UMQPS=0,0,0,"pubtopic","Hello from NORA-W36" | OK |
| 6 | Subscribe on topic subtopic | AT+UMQS=0,0,"subtopic" | OK |
| 7 | Post a Message to the MQTT Broker on subtopic the message should be Hello from remote device | - | - |
| 8 | Receive Message on subtopic | +UEMQD:0,24 | |
| 9 | Read String Message | AT+UMQRS=0 | +UMQRS:0,0,"subtopic",24,"Hello from remote device" |
| 10 | Disconnect from MQTT broker | AT+UMQDC=0 | OK |
Connect as a Wi-Fi Station and an Access Point and a MQTT Broker. In this scenario, NORA-W36 connects to Microsoft Azure using certificates.

Important Note: Azure IoT Hub isn't a full-featured MQTT broker and doesn't support all the behaviors specified in the MQTT v3.1.1 standard.
Parameters and values
Before connecting to MQTT, set up Wi-Fi Connection like in steps 1-5 in Wi-Fi station
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Configure MQTT Host, Port, Client ID and Username | AT+UMQCP=0,"iothub-test-sw.azure-devices.net",8883,"device1","iothub-test-sw.azure-devices.net/device1/" | OK |
| 2 | Write X.509 certificate and private key using Binary data | AT+USECUB=0,"AzureCa.pem"{binary_content} + AT+USECUB=1,"azure_client.crt"{binary_content} + AT+USECUB=2,"azure_priv_key.key"{binary_content} Note: Brackets { } should NOT be sent | OK |
| 3 | Setup TLS connection config | AT+UMQTLS=0,1,"AzureCa.pem","azure_client.crt","azure_priv_key.key" | OK |
| 4 | Connect to MQTT broker | AT+UMQC=0 | +UEMQC:0 |
| 5 | Publish Message on topic pubtopic | AT+UMQPS=0,0,0,"pubtopic","Hello from NORA-W36" | OK |
| 6 | Subscribe on topic subtopic | AT+UMQS=0,0,"subtopic" | OK |
| 7 | Post a Message to the MQTT Broker on subtopic the message should be Hello from remote device | - | - |
| 8 | Receive Message on subtopic | +UEMQD:0,24 | |
| 9 | Read String Message | AT+UMQRS=0 | +UMQRS:0,0,"subtopic",24,"Hello from remote device" |
| 10 | Disconnect from MQTT broker | AT+UMQDC=0 | OK |
NORA-W36 includes a comprehensive HTTP client supporting HTTP/1.1 protocol with features including GET, POST, PUT, DELETE operations. When combined with TLS, it provides secure HTTPS communication. The HTTP client simplifies web communication without requiring deep protocol knowledge.
Important Note: HTTP requests have a Maximum Transmission Unit (MTU) of 1000 bytes. This applies to both request data and response data. For larger data transfers, consider splitting the data into multiple requests or using chunked transfer encoding.
| Command | Description |
|---|---|
AT+UHTCCP | HTTP Client Connection Parameters |
AT+UHTCTLS | HTTP Client TLS Configuration |
AT+UHTCDC | HTTP Client Disconnect |
AT+UHTCGH | HTTP Client Get Header |
AT+UHTCGBB | HTTP Client Get Body Binary |
AT+UHTCGBS | HTTP Client Get Body String |
AT+UHTCRHAF | HTTP Client Request Header Add Field |
AT+UHTCRHCS | HTTP Client Request Header Custom String |
AT+UHTCRHC | HTTP Client Request Header Clear |
AT+UHTCRP | HTTP Client Request Path |
AT+UHTCRG | HTTP Client Request GET |
AT+UHTCRGH | HTTP Client Request GET Header |
AT+UHTCRD | HTTP Client Request DELETE |
AT+UHTCRDH | HTTP Client Request DELETE Header |
AT+UHTCRPOS | HTTP Client Request POST String |
AT+UHTCRPOB | HTTP Client Request POST Binary |
AT+UHTCRPOH | HTTP Client Request POST Header |
AT+UHTCRPUS | HTTP Client Request PUT String |
AT+UHTCRPUB | HTTP Client Request PUT Binary |
AT+UHTCRPUH | HTTP Client Request PUT Header |
This example demonstrates a basic HTTP GET request to retrieve data from a web server.
Target: http://httpbin.org/get (HTTP test service)
Before connecting, ensure Wi-Fi is connected as shown in Wi-Fi station.
| Nr | Instructions | AT Command | AT Response |
|---|---|---|---|
| 1 | Configure HTTP client for target server | AT+UHTCCP=0,"httpbin.org",80 | OK |
| 2 | Set request path and method | AT+UHTCRP=0,"GET","/get" | OK |
| 3 | Send GET request | AT+UHTCRG=0 | OK |
| 4 | Wait for response | +UEHTCRS:0,200,"OK" | |
| 5 | Get response headers | AT+UHTCGH=0 | +UHTCGH:0,1,"HTTP/1.1 200 OK..." |
| 6 | Get response body (string) | AT+UHTCGBS=0,1000 | +UHTCGBS:0,1000,"{"args":{}..." |
| 7 | Disconnect client | AT+UHTCDC=0 | +UEHTCDC:0 |
This example shows secure HTTPS communication with server certificate validation.
Target: https://api.github.com/repos/octocat/Hello-World (GitHub API)
| Nr | Instructions | AT Command | AT Response |
|---|---|---|---|
| 1 | Upload CA certificate for GitHub | AT+USECUB=0,"github-ca.pem"{binary certificate data} | OK |
| 2 | Configure HTTPS client | AT+UHTCCP=0,"api.github.com",443 | OK |
| 3 | Configure TLS 1.3 with certificate validation | AT+UHTCTLS=0,2,"github-ca.pem" | OK |
| 4 | Set request path | AT+UHTCRP=0,"GET","/repos/octocat/Hello-World" | OK |
| 5 | Add User-Agent header | AT+UHTCRHAF=0,"User-Agent","NORA-W36/1.0" | OK |
| 6 | Send HTTPS GET request | AT+UHTCRG=0 | OK |
| 7 | Wait for response | +UEHTCRS:0,200,"OK" | |
| 8 | Get JSON response body | AT+UHTCGBS=0,2000 | +UHTCGBS:0,2000,"{"id":123456..." |
| 9 | Disconnect client | AT+UHTCDC=0 | +UEHTCDC:0 |
This example demonstrates sending JSON data via HTTP POST request.
Target: https://httpbin.org/post (HTTP test service)
Payload: {"temperature": 25.6, "humidity": 60.2, "device": "NORA-W36"}
| Nr | Instructions | AT Command | AT Response |
|---|---|---|---|
| 1 | Configure HTTPS client | AT+UHTCCP=0,"httpbin.org",443 | OK |
| 2 | Set POST request path | AT+UHTCRP=0,"POST","/post" | OK |
| 3 | Set Content-Type header | AT+UHTCRHAF=0,"Content-Type","application/json" | OK |
| 4 | Set Content-Length header | AT+UHTCRHAF=0,"Content-Length","62" | OK |
| 5 | Send POST request with JSON body | AT+UHTCRPOS=0,"{"temperature": 25.6, "humidity": 60.2, "device": "NORA-W36"}" | OK |
| 6 | Wait for response | +UEHTCRS:0,200,"OK" | |
| 7 | Get response body | AT+UHTCGBS=0,1500 | +UHTCGBS:0,1500,"{"args":{}..." |
| 8 | Disconnect client | AT+UHTCDC=0 | +UEHTCDC:0 |
| 9 | Disconnect client | AT+UHTCDC=0 | +UEHTCDC:0 |
This example shows how to upload binary files using HTTP POST with multipart/form-data.
Target: https://httpbin.org/post
File: sensor_data.bin (256 bytes)
| Nr | Instructions | AT Command | AT Response |
|---|---|---|---|
| 1 | Configure HTTPS client | AT+UHTCCP=0,"httpbin.org",443 | OK |
| 2 | Set POST request path | AT+UHTCRP=0,"POST","/post" | OK |
| 3 | Set Content-Type for file upload | AT+UHTCRHAF=0,"Content-Type","application/octet-stream" | OK |
| 4 | Send POST request with binary data | AT+UHTCRPOB=0,{256 bytes of binary data} | OK |
| 5 | Wait for upload completion | +UEHTCRS:0,200,"OK" | |
| 6 | Get server response | AT+UHTCGBS=0,1000 | +UHTCGBS:0,1000,"{"files":..." |
| 7 | Disconnect client | AT+UHTCDC=0 | +UEHTCDC:0 |
| 9 | Disconnect client | AT+UHTCDC=0 | +UEHTCDC:0 |
This example demonstrates updating data on a server using HTTP POST method.
Target: https://httpbin.org/post
Data: Configuration update JSON
| Nr | Instructions | AT Command | AT Response |
|---|---|---|---|
| 1 | Configure HTTPS client | AT+UHTCCP=0,"httpbin.org",443 | OK |
| 2 | Set POST request path | AT+UHTCRP=0,"POST","/post" | OK |
| 3 | Add authorization header | AT+UHTCRHAF=0,"Authorization","Bearer xyz123" | OK |
| 4 | Set Content-Type | AT+UHTCRHAF=0,"Content-Type","application/json" | OK |
| 5 | Send POST request with data | AT+UHTCRPOS=0,"{"config":{"interval":30,"enabled":true}}" | OK |
| 6 | Wait for response | +UEHTCRS:0,200,"OK" | |
| 7 | Get confirmation response | AT+UHTCGBS=0,800 | +UHTCGBS:0,800,"{"json":..." |
| 9 | Disconnect client | AT+UHTCDC=0 | +UEHTCDC:0 |
This example shows how to delete resources using HTTP DELETE method.
Target: https://httpbin.org/delete
| Nr | Instructions | AT Command | AT Response |
|---|---|---|---|
| 1 | Configure HTTPS client | AT+UHTCCP=0,"httpbin.org",443 | OK |
| 2 | Set DELETE request path | AT+UHTCRP=0,"DELETE","/delete" | OK |
| 3 | Add authentication header | AT+UHTCRHAF=0,"Authorization","ApiKey abc123" | OK |
| 4 | Send DELETE request | AT+UHTCRD=0 | OK |
| 5 | Wait for deletion response | +UEHTCRS:0,200,"OK" | |
| 6 | Get deletion confirmation | AT+UHTCGBS=0,500 | +UHTCGBS:0,500,"{"url":"..." |
| 7 | Disconnect client | AT+UHTCDC=0 | +UEHTCDC:0 |
This example demonstrates advanced TLS settings including client certificates for mutual authentication.
Target: Secure API with mutual TLS authentication
Certificates: CA certificate, client certificate, and private key
| Nr | Instructions | AT Command | AT Response |
|---|---|---|---|
| 1 | Upload CA certificate | AT+USECUB=0,"server-ca.pem"{binary data} | OK |
| 2 | Upload client certificate | AT+USECUB=1,"client.crt"{binary data} | OK |
| 3 | Upload client private key | AT+USECUB=2,"client.key"{binary data} | OK |
| 4 | Configure HTTPS client | AT+UHTCCP=0,"secure-api.example.com",443 | OK |
| 5 | Configure mutual TLS 1.3 | AT+UHTCTLS=0,2,"server-ca.pem","client.crt","client.key" | OK |
| 6 | Set request path | AT+UHTCRP=0,"GET","/api/secure-data" | OK |
| 7 | Send authenticated request | AT+UHTCRG=0 | OK |
| 8 | Wait for response | +UEHTCRS:0,200,"OK" | |
| 9 | Get secure data | AT+UHTCGBS=0,1000 | +UHTCGBS:0,1000,"{"secure"..." |
| 10 | Disconnect client | AT+UHTCDC=0 | +UEHTCDC:0 |
The HTTP client returns standard HTTP status codes to indicate request results:
| Status Code | Meaning | Description |
|---|---|---|
| 200 | OK | Request successful |
| 201 | Created | Resource created successfully |
| 400 | Bad Request | Invalid request format |
| 401 | Unauthorized | Authentication required |
| 403 | Forbidden | Access denied |
| 404 | Not Found | Resource not found |
| 500 | Server Error | Internal server error |
| 503 | Service Unavailable | Server temporarily unavailable |
| Issue | Possible Cause | Solution |
|---|---|---|
| Connection timeout | Network unreachable | Check Wi-Fi connection and DNS resolution |
| Certificate error | Invalid/expired certificate | Update CA certificate or disable validation |
| 401 Unauthorized | Missing/invalid authentication | Check API key, username/password, or tokens |
| 413 Payload Too Large | Request body too large | Split large requests or use chunked transfer |
| SSL handshake failed | TLS version mismatch | Update TLS settings or certificate chain |
AT+UWSNST? (connection info)Accept-Encoding: gzip header when supportedAT+UHTCDC=0
// Connect to secure IoT platform
AT+UHTCCP=0,"iot.example.com",443
AT+UHTCTLS=0,1,"iot-ca.pem","device.crt","device.key"
AT+UHTCRP=0,"POST","/api/v1/sensors/data"
AT+UHTCRHAF=0,"Content-Type","application/json"
AT+UHTCRHAF=0,"Authorization","Bearer eyJhbGciOiJIUzI1..."
AT+UHTCRHAF=0,"X-Device-ID","NORA-W36-001"
// Send sensor reading
AT+UHTCRPOS=0,85
{"timestamp":"2025-09-25T10:30:00Z","temperature":23.5,"humidity":65,"pressure":1013}
// Expected response: HTTP 201 Created
+UEHTCRS:0,201,"Created"
AT+UHTCGBS=0,200
+UHTCGBS:0,0,45,"{"status":"success","id":"sensor_12345"}"
AT+UHTCDC=0

NORA-W36 supports Network Time Protocol (NTP) client functionality to synchronize the system clock with time servers on the internet. This ensures accurate timekeeping for applications that require time-stamped data, secure communications, or scheduled operations.
Connect as a Wi-Fi station and configure NTP to synchronize system time automatically.
This use case demonstrates how to set up NTP with multiple time servers for redundancy and verify time synchronization.
Prerequisites:
| Nr | Instructions | AT command | AT event/Response |
|---|---|---|---|
| 1 | Connect to Wi-Fi network first | See Wi-Fi station example | |
| 2 | Configure primary NTP server | AT+UNTSC=0,"pool.ntp.org" | OK |
| 3 | Configure secondary NTP server | AT+UNTSC=1,"time.google.com" | OK |
| 4 | Configure third NTP server | AT+UNTSC=2,"time.nist.gov" | OK |
| 5 | Check current system time (before sync) | AT+USYTU? | +USYTU:00000001 |
| 6 | Enable NTP client | AT+UNTE=1 | OK |
| 7 | Wait for synchronization (5-30 seconds) | ||
| 8 | Verify NTP server status | AT+UNTSC? | +UNTSC:0,"pool.ntp.org","185.255.55.20",1 + +UNTSC:1,"time.google.com","216.239.35.12",1 + +UNTSC:2,"time.nist.gov","129.6.15.28",1 |
| 9 | Check synchronized time | AT+USYTU? | +USYTU:66E7B2A4 |
| 10 | Save NTP configuration | AT&W | OK |
| 11 | Reset to apply stored settings safely | AT+CPWROFF | OK |
Note: The unix time 66E7B2A4 (hex) equals 1726468772 (decimal), which corresponds to a human-readable time like "Mon, 16 Sep 2024 10:12:52 GMT".
Configure NTP to use DHCP-provided time servers with manual fallback.
This configuration first attempts to use NTP servers provided by the network's DHCP server, falling back to manually configured servers if DHCP servers are unavailable.
| Nr | Instructions | AT command | AT event/Response |
|---|---|---|---|
| 1 | Connect to Wi-Fi network first | See Wi-Fi station example | |
| 2 | Configure fallback NTP servers | AT+UNTSC=0,"time.google.com" | OK |
| 3 | Configure additional fallback server | AT+UNTSC=1,"pool.ntp.org" | OK |
| 4 | Enable NTP with DHCP + manual fallback | AT+UNTE=2 | OK |
| 5 | Verify NTP configuration | AT+UNTE? | +UNTE:2 |
| 6 | Check which servers are being used | AT+UNTSC? | Shows DHCP or manual servers depending on availability |
| 7 | Save configuration | AT&W | OK |
| 8 | Reset to apply stored settings safely | AT+CPWROFF | OK |
Manage and troubleshoot NTP server configuration.
| Nr | Instructions | AT command | AT event/Response |
|---|---|---|---|
| 1 | Check current NTP client status | AT+UNTE? | +UNTE:1 (enabled) or +UNTE:0 (disabled) |
| 2 | View all configured servers | AT+UNTSC? | Shows all 5 server slots (0-4) with status |
| 3 | Remove a specific NTP server | AT+UNTSC=2,"" | Removes server from slot 2 |
| 4 | Add new NTP server | AT+UNTSC=2,"time.cloudflare.com" | OK |
| 5 | Disable NTP client | AT+UNTE=0 | OK |
| 6 | Re-enable NTP client | AT+UNTE=1 | OK |
Popular NTP Servers:
pool.ntp.org - Global NTP pool projecttime.google.com - Google Public NTPtime.nist.gov - US National Institute of Standardstime.cloudflare.com - Cloudflare Public NTP0.europe.pool.ntp.org, 0.asia.pool.ntp.org, etc.Troubleshooting Tips:
reachable=0, check network connectivity and firewall settingsWi-Fi roaming allows devices to maintain seamless connectivity while moving between access points (APs) in the same network. This is essential for mobile applications, large coverage areas, and enterprise environments where multiple APs provide overlapping coverage using the same Service Set Identifier (SSID).
Modern Wi-Fi networks implement several roaming standards to optimize the handoff process:
IEEE 802.11r (Fast BSS Transition - FT)
IEEE 802.11k (Radio Resource Management - RRM)
IEEE 802.11v (Wireless Network Management - WNM)
IEEE 802.11w (Protected Management Frames - PMF)
NORA-W36 supports client-initiated roaming based on RSSI thresholds and scanning algorithms. Roaming is disabled by default and must be enabled before connecting to Wi-Fi.
NORA-W36 supports roaming, it is disabled by default and needs to be enabled before connecting Wi-Fi with AT+UWSROE=1
The most important settings are the following, see AT manual for more settings:
| Command | Default | Valid values | Description |
|---|---|---|---|
AT+UWSROE=<roaming> | 0 | 0: Disable roaming 1: Enable roaming | Master roaming enable/disable |
AT+UWSROS0=<roaming_scanning_threshold> | -70 | Valid values: -95..0 | RSSI threshold to trigger scanning (dBm) |
AT+UWSROS1=<roaming_switch_limit> | 10 | Valid values: 1..50 | Minimum RSSI improvement needed (dB) |
AT+UWSROS2=<roaming_scan_interval> | 5000 | Valid values: 100..3600000 | Background scan interval (ms) |
AT+UWSROS3=<roaming_current_rssi> | 0 | 0: Disable current RSSI roaming 1: Enable current RSSI roaming | Roaming calculation mode |
AT+UWSROS4=<roaming_delay_time> | 0 | Valid values: 0..30000 | Handover delay time (ms) |
AT+UWSROS5=<roaming_all_channels> | 1 | 0: Scan current channel only 1: Scan all channels | Channel scanning scope |
With the default configuration, roaming will start when RSSI drops to -70 dBm or below. A background scan will start to find a better AP with the same SSID. It will perform roaming if an Access Point with -70 + 10 = -60 dBm or better is found.
Example configuration:
AT+UWSROE=1 // Enable roaming
AT+UWSROS0=-70 // Start scanning at -70 dBm
AT+UWSROS1=10 // Require 10 dB improvement
AT+UWSROS3=0 // Use fixed threshold mode
In some situations you want to roam based on your current RSSI instead of a fixed value. This "aggressive roaming" mode uses AT+UWSROS3=1 and typically requires lowering the switch limit to 3 dBm AT+UWSROS1=3.
Calculation: If current RSSI is -78 dBm, the target threshold becomes -78 + 3 = -75 dBm. Roaming will occur if an AP with -75 dBm or better signal is found.
Example configuration:
AT+UWSROE=1 // Enable roaming
AT+UWSROS0=-70 // Start scanning at -70 dBm
AT+UWSROS1=3 // Require only 3 dB improvement
AT+UWSROS3=1 // Use current RSSI mode
Roaming Configuration Strategies:
| Strategy | Use Case | Configuration | Commands |
|---|---|---|---|
| Stable connections | Minimal roaming, consistent connection | Higher threshold, significant improvement required | AT+UWSROS0=-80 + AT+UWSROS1=15 + AT+UWSROS3=0 |
| Aggressive roaming | Maximum signal quality | Moderate threshold, lower improvement requirement | AT+UWSROS0=-65 + AT+UWSROS1=3 + AT+UWSROS3=1 |
| Enterprise environments | High AP density | Custom based on deployment | Test and monitor for optimal settings |
For enterprise environments:
Current implementation:
Future roadmap:
By default no lower power mode is enabled in NORA-W36 to have maximal performance and response time.
In some applications power consumption is important and data throughput and latency is not that important. By enabling the low power mode this will slightly change. More power save means more latency can be expected.
Power level 0 (default, no power save) and power level 1 (moderate power save) is supported, more levels may be added in future releases.
The low power level 1 is set using the command AT+UPMPSL=1 see NORA-W36 SIM and AT command manual for more details. There is a limitation that the first AT command after the timeout (default 1 second) can't be longer than 16 bytes.
Important Note: In power level 1 only 115200 baud rate or lower is allowed.
Power Management Commands:
| Command | Purpose | Example | Default |
|---|---|---|---|
AT+UPMPSL=<level> | Set power save level | AT+UPMPSL=1 | Level 0 (no power save) |
AT+UPMPSTO=<timeout_ms> | Set active state timeout | AT+UPMPSTO=2000 | 1000ms (1 second) |
AT+UPMPSL? | Read current power level | Shows current setting | N/A |
AT+UPMPSTO? | Read current timeout | Shows timeout in ms | N/A |
Power Save Configuration Examples:
// Enable moderate power save with 2-second timeout
AT+UPMPSL=1
AT+UPMPSTO=2000
AT&W // Store settings
AT+CPWROFF // Reset to apply stored settings safely
// Check current power save configuration
AT+UPMPSL?
+UPMPSL:1 // Power save level 1 enabled
AT+UPMPSTO?
+UPMPSTO:2000 // 2000ms timeout
// Disable power save (maximum performance)
AT+UPMPSL=0
Power Save Behavior:
All low power modes save power automatically and will adjust this depending on the level.
When enabled, no further action is required by the host.
The most efficient power level is Deep sleep which is almost like a power off, no radio communication is possible in this mode.
AT+UPMDSGPIO_J9 to GNDNot sure which mode to use? Answer these questions:
👉 Most Common Choice: String Buffered Mode - Perfect for most IoT applications
---
NORA-W36 provides multiple data transmission modes optimized for different use cases and performance requirements. Understanding when to use each mode is crucial for optimal application performance and reliability.
| Mode | Data Types | Character Range | Best For | Performance |
|---|---|---|---|---|
| String Mode | Text, JSON, XML, HTML | ASCII printable (0x21-0x7E, 0xA1-0xFF) | Web APIs, sensor data, configuration | Good |
| Binary Mode | All data types | Full byte range (0x00-0xFF) | File transfers, certificates, images | Better |
| Transparent Mode | All data types | Full byte range (0x00-0xFF) | Legacy applications, streaming | Best |
| Mode | Behavior | Event Notification | Best For | Latency |
|---|---|---|---|---|
| Buffered Mode | Data stored until read | +UESODA event triggered | Applications with event-driven processing | Higher |
| Direct Mode | Data delivered immediately | Immediate data delivery events | Real-time applications, streaming | Lower |
✅ Use string mode when:
Avoid string mode when:
0x00) or control charactersExample use cases:
{"temperature":25.6,"humidity":60.2}HTTP/1.1 200 OK\r\nContent-Type: application/json✅ Use binary mode when:
0x00-0xFF)Avoid binary mode when:
Example use cases:
AT+USECUB=0,"ca.pem"{binary certificate data}✅ Use transparent mode when:
Avoid transparent mode when:
Example use cases:
---
NORA-W36 supports several modes for sending and receiving data:
0x21-0x7E, 0xA1-0xFF)0x00-0xFF)0x00-0xFF)Performance notes:
To receive data without an event and read it out, the read mode can be changed to direct mode AT+USORM=1
Socket receive mode
Syntax
AT+USORM=<receive_mode>
+UESODA - Socket Data Available Event, default mode+UESODS - Socket Data Binary Event: Incoming on TCP socket data represented as a string+UESODSF - Socket Data Binary From Event: Incoming on UDP socket data represented as a stringSPS Receive data mode
Syntax
AT+USPSRM=<receive_mode>
+UESPSDA SPS Data Available event, default mode+UESPSDS - SPS Data String eventSyntax
AT+USOWS=<socket_handle>,<string_data>
Example to write socket data
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Write Socket data in string format size | AT+USOWS=0,"Hello from NORA-W36" | OK |
Syntax
AT+USORS=<socket_handle>,<length>
+USORS:<socket_handle>,<length>,<string_data>
Example to read socket data
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Incoming Socket data | +UESODA:0,19 | |
| 2 | Reads incoming Socket data in string format | AT+USORS=0,19 | +USORS:0,19,"Hello from NORA-W36" |
Syntax
AT+USPSWS=<conn_handle>,<string_data>
Example to write SPS data
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Write SPS data in string format size | AT+USPSWS=0,"Hello from NORA-W36" | OK |
Syntax
AT+USPSRS=<socket_handle>,<length>
+USPSRS:<socket_handle>,<length>,<string_data>
Example to read SPS data
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Incoming SPS data | +UESPSDA:0,19 | |
| 2 | Reads incoming SPS data in string format | AT+USPSRS=0,19 | +USPSRS:0,19,"Hello from NORA-W36" |
The binary mode should be used when binary content is transmitted, like files and binary protocols.
See Binary data for more information about the format of the data.
Socket receive mode
Syntax
AT+USORM=<receive_mode>
+UESODA - Socket Data Available Event, default mode+UESODB - Socket Data Binary Event: Incoming on TCP socket data represented as binary data+UESODBF - Socket Data Binary From: Incoming on UDP socket data represented as binary dataSPS receive mode
Syntax
AT+USPSRM=<receive_mode>
+UESPSDA SPS Data Available event, default mode+UESPSDB - SPS Data Binary eventSee more information about Binary Data.
AT+USOWB=<socket_handle>{binary_data}
Example to write socket data
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Write Socket data in binary format size | AT+USOWB=0\x01\x00\x13Hello from NORA-W36 | OK |
Syntax
AT+USORB=<socket_handle>,<length>
+USORS:<socket_handle>{binary_data}
Example to read socket data
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Incoming Socket data | +UESODA:0,19 | |
| 2 | Reads incoming Socket data in binary format | AT+USORB=0,19 | +USORB:0\x01\x00\x13Hello from NORA-W36 |
Syntax
AT+USPSWS=<conn_handle>{binary_data}
Example to write SPS data
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Write SPS data in binary format size | AT+USPSWB=0\x01\x00\x13Hello from NORA-W36 | OK |
Syntax
AT+USORB=<socket_handle>,<length>
+USORB:<socket_handle>{binary_data}
Example to read SPS data
| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Incoming SPS data | +UESPSDA:0,19 | |
| 2 | Reads incoming SPS data in binary format | AT+USPSRB=0,19 | +USPSRB:0\x01\x00\x13Hello from NORA-W36 |
Transparent mode (TM) allows the NORA-W36 to act as a transparent bridge, forwarding all UART data directly to a remote device without AT command processing. This works similarly to Data mode in legacy u-blox short range products.
Key Features:
+++ to return to AT command modeImportant Limitations:
The AT+UTM command enters transparent mode on an existing connection.
AT+UTM=<link_type>,<handle>
Parameters:
<link_type>: Connection type0 = SPS (Bluetooth LE Serial Port Service)1 = TCP socket2 = UDP socket<handle>: Connection handle/socket ID (0-255)Return Values:
OK = Transparent mode activated successfullyERROR = Invalid parameters or no active connection
// Prerequisites: BLE connection established with SPS service
AT+UTM=0,0
OK
[Transparent mode started - all UART data forwarded to BLE device]
Hello from NORA-W36!
[Data sent transparently to remote BLE device]
+++
OK
[Back in AT command mode]
// Prerequisites: Wi-Fi connected, TCP socket created and connected
AT+USOCR=6 // Create TCP socket
+USOCR:0 // Socket ID 0 created
AT+USOCO=0,"192.168.1.100",8080 // Connect to server
OK
AT+UTM=1,0 // Enter transparent mode on socket 0
OK
[Transparent mode started - all UART data sent to TCP server]
GET / HTTP/1.1\r\nHost: example.com\r\n\r\n
[HTTP request sent transparently]
+++
OK
[Back in AT command mode]
// Prerequisites: Wi-Fi connected, UDP socket created
AT+USOCR=17 // Create UDP socket
+USOCR:1 // Socket ID 1 created
AT+USOST=1,"192.168.1.200",9000,4,"test" // Send initial data to establish endpoint
+USOST:1,4 // 4 bytes sent
AT+UTM=2,1 // Enter transparent mode on UDP socket 1
OK
[Transparent mode started - all UART data sent as UDP packets]
Hello UDP Server!
[UDP packet sent transparently]
+++
OK
[Back in AT command mode]
This example demonstrates UDP transparent mode with bidirectional communication - sending and receiving data using a single UDP socket.
Use Case: Real-time data exchange where you need immediate transparent mode without persistence.
// Prerequisites: Wi-Fi connected
AT+USOCR=17 // Create UDP socket
+USOCR:1 // Socket ID 1 created
// Bind to local port for receiving data
AT+USOB=1,5005 // Bind socket 1 to local port 5005
OK
// Set remote endpoint for outgoing data
AT+USOP=1,"192.168.1.174",5003 // Configure remote server for outgoing data
OK
// Send test data to establish connection
AT+USOST=1,"192.168.1.174",5003,4,"test" // Send initial packet
+USOST:1,4 // 4 bytes sent
// Enter transparent mode immediately
AT+UTM=2,1 // Enter transparent mode on UDP socket 1
OK
[Transparent mode active - bidirectional UDP communication]
Hello Server! // UART data → UDP packet to 192.168.1.174:5003
[Any UDP data to port 5005 → forwarded to UART]
+++ // Exit transparent mode
OK
[Back in AT command mode]
Network Configuration:
Traffic Flow:
+++ with no line ending (no CR/LF)+++OK when returning to AT modePersistent Transparent Mode (TMP) automatically enters transparent mode on startup after module reset. The connection configuration is stored in flash memory and restored on boot.
Key Differences from Basic Transparent Mode:
AT&W command)
AT+UTMP=<link_type>,<config_id>
Parameters:
<link_type>: Connection type0 = BLE SPS Link1 = Socket (TCP or UDP)<config_id>: Configuration IDAT+UBTPAT+USOP⚠️ Important Note: AT+UTMP uses different link_type values than AT+UTM:
AT+UTM: 0=SPS, 1=TCP, 2=UDP (specific socket types)AT+UTMP: 0=SPS, 1=Socket (covers both TCP and UDP)Prerequisites: Bluetooth LE must be enabled and target device address known.
| Step | Description | AT Command | Expected Response |
|---|---|---|---|
| 1 | Configure remote BLE device address | AT+UBTP=BBBBBBBBBBBB,1 | +UBTP:200 |
| 2 | Enable persistent transparent mode | AT+UTMP=0,200 | OK |
| 3 | Store configuration to flash | AT&W | OK |
| 4 | Reset module | AT+CPWROFF | OK |
| 5 | Wait for startup | (automatic) | +STARTUP |
| 6 | Persistent transparent mode active | (automatic) | (data forwarding starts) |
| 7 | Exit to AT mode when needed | +++ | OK |
Prerequisites: Wi-Fi credentials configured and target server accessible.
| Step | Description | AT Command | Expected Response |
|---|---|---|---|
| 1 | Create persistent TCP socket | AT+USOPCR=6 | +USOPCR:100 |
| 2 | Configure server IP and port | AT+USOP=100,"192.168.0.26",5003 | OK |
| 3 | Enable persistent transparent mode | AT+UTMP=1,100 | OK |
| 4 | Configure Wi-Fi connection | See Wi-Fi Station Setup | OK |
| 5 | Store all settings to flash | AT&W | OK |
| 6 | Reset module | AT+CPWROFF | OK |
| 7 | Wait for startup and Wi-Fi connection | (automatic) | +STARTUP |
| 8 | TCP connection and transparent mode active | (automatic) | (data forwarding starts) |
| 9 | Exit to AT mode when needed | +++ | OK |
Prerequisites: Wi-Fi credentials configured and target server accessible.
| Step | Description | AT Command | Expected Response |
|---|---|---|---|
| 1 | Create persistent UDP socket | AT+USOPCR=17 | +USOPCR:101 |
| 2 | Configure server IP and port | AT+USOP=101,"192.168.0.50",8080 | OK |
| 3 | Enable persistent transparent mode | AT+UTMP=1,101 | OK |
| 4 | Configure Wi-Fi connection | See Wi-Fi Station Setup | OK |
| 5 | Store all settings to flash | AT&W | OK |
| 6 | Reset module | AT+CPWROFF | OK |
| 7 | Wait for startup and Wi-Fi connection | (automatic) | +STARTUP |
| 8 | UDP socket and transparent mode active | (automatic) | (data forwarding starts) |
| 9 | Exit to AT mode when needed | +++ | OK |
This example demonstrates persistent UDP transparent mode with bidirectional communication - the NORA-W36 automatically establishes transparent mode on startup for both sending and receiving UDP data.
Use Case: IoT sensor that needs both telemetry data transmission and remote configuration commands with automatic reconnection after power cycles.
// Prerequisites: Wi-Fi credentials configured
AT+USOPCR=17 // Create persistent UDP socket
+USOPCR:100 // Persistent socket ID 100 created
// Configure local port for receiving data
AT+USOB=100,5005 // Bind to local port 5005 for incoming data
OK
// Configure remote server for outgoing data
AT+USOP=100,"192.168.1.174",5003 // Send data to server at 192.168.1.174:5003
OK
// Enable persistent transparent mode
AT+UTMP=1,100 // Socket persistent transparent mode on socket 100
OK
// Save configuration and restart
AT&W // Save settings to flash
OK
AT+CPWROFF // Power off and restart
OK
// After restart: NORA-W36 automatically enters transparent mode
// - All UART data is sent to 192.168.1.174:5003
// - All UDP data received on port 5005 is forwarded to UART
// - Bidirectional communication established automatically
Network Configuration:
Example Traffic Flow:
To Exit Transparent Mode:
+++ // Send escape sequence (no CR/LF)
OK // Back in AT command mode
Data Flow:
+++ is sent, all UART data is forwarded unmodified to the remote deviceError Handling:
AT+UMTMP? to query current persistent transparent mode statusDisabling Persistent Mode:
AT+UTMPC // Clear persistent transparent mode configuration
AT&W // Save to flash
AT+CPWROFF // Reset to apply changes
Binary data allows you to send raw bytes (like images, certificates, or any non-text data) through AT commands. This is useful when you need to transfer files, certificates, or binary content that cannot be represented as regular text.
When sending binary data with NORA-W36, you need to follow a specific format that tells the module exactly how many bytes to expect.
Every binary transmission consists of two parts:
The header always contains exactly 3 bytes in this order:
| Byte Position | Value | Description |
|---|---|---|
| Byte 1 | 0x01 | Start marker (always 0x01) |
| Byte 2 | MSB | Most Significant Byte of data length |
| Byte 3 | LSB | Least Significant Byte of data length |
Example: If your data is 2 bytes long, the header would be: 0x01, 0x00, 0x02
,) before binary data\r) before binary dataLet's send 2 bytes of data (0xFF, 0xEE) to socket 0.
0xFF, 0xEE (2 bytes)0x0002 in hexadecimal0x01, 0x00, 0x02 (start marker + length)AT+USOWB=0 + header + data
AT+USOWB=0\x01\x00\x02\xFF\xEE
Explanation:
AT+USOWB=0 = Write to socket 0\x01 = Start marker\x00 = Length high byte (0)\x02 = Length low byte (2)\xFF\xEE = Your 2 bytes of actual data⚠ Note: The curly braces { } in documentation are just for clarity - never include them in actual commands.
Let's send the text Hello from NORA-W36 as binary data.
Hello from NORA-W36 = 19 characters = 19 bytes0x0013 in hexadecimal0x00 (high byte) and 0x13 (low byte)0x01, 0x00, 0x13
AT+USOWB=0\x01\x00\x13Hello from NORA-W36
When you receive data back, it includes the same header:
+USORB:0\x01\x00\x13Hello from NORA-W36
Uploading certificates is more complex but follows the same binary data principles.
You want to upload a certificate file named ca.pem that contains 1342 bytes of certificate data.
0x053E in hex0x05 (high byte) and 0x3E (low byte)0x01, 0x05, 0x3E| Decimal Bytes | Hexadecimal | High Byte | Low Byte |
|---|---|---|---|
| 256 | 0x0100 | 0x01 | 0x00 |
| 512 | 0x0200 | 0x02 | 0x00 |
| 1024 | 0x0400 | 0x04 | 0x00 |
| 1342 | 0x053E | 0x05 | 0x3E |
AT+USECUB=0,"ca.pem"\x01\x05\x3E[certificate content here]
Breakdown:
AT+USECUB=0,"ca.pem" = Upload to slot 0, name it "ca.pem"\x01 = Binary data start marker\x05 = High byte of length (1342)\x3E = Low byte of length (1342)[certificate content] = The actual 1342 bytes of certificate data
+USECUB:1342
OK
This confirms that 1342 bytes were successfully received and stored.
ABCDojCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBkDELMAkGA1UEBhMCR0Ix\n
FzAVBgNVBAgMDlVuaXRlZCBLaW5nZG9tMQ4wDAYDVQQHDAVEZXJieTESMBAGA1UE\n
CgwJTW9zcXVpdHRvMQswCQYDVQQLDAJDQTEWMBQGA1UEAwwNbW9zcXVpdHRvLm9y\n
ZzEfMB0GCSqGSIb3DQEJARYQcm9nZXJAYXRjaG9vLm9yZzAeFw0yMzEwMDQxMDEw\n
MzJaFw0yNDAxMDIxMDEwMzJaMHwxCzAJBgNVBAYTAlNFMQ4wDAYDVQQIDAVNYWxt\n
bzEOMAwGA1UEBwwFTWFsbW8xDzANBgNVBAoMBnUtYmxveDEPMA0GA1UECwwGQUUt\n
U0hPMQ0wCwYDVQQDDARjbWFnMRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3Qub3Jn\n
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3PZc1E7uSBiB/Es1V0pU\n
XeSayY3f6vrIbnSGTb+/PERSPgPz6UoZumJjcOWbCMq7T+/dvvxox/ZU/t/XdGMq\n
MJRgN+aWRG6I4QmqYgkiAZGMuaMa+TLLEEPvL1IDKSxeVjHRNDx4yZM4zgvl6ZX7\n
oRaBqZBooNTHOtAGjlydyyz55HCZfLsE8Z3iaH7uW+/n9+2nWusfUXoJmI0STmEH\n
pJ+ZF7M+o53UilW2NKdv/R+wCzXxmKWX6PFVg4NdKspTDUOpPcxlphMQGi24E2uz\n
2k7raCQvGt32LxZc/vic4W6rNDGGNSSDVJTSx6egzfRrcCKw3T88TN87nasjc+KV\n
CQIDAQABoxowGDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DANBgkqhkiG9w0BAQsF\n
AAOCAQEAjRyNWHGtcwLT21IzJ2 // I8YL611iTUitRGkA0gF+7l0DuPtfSLPVhoyB\n
Te3FThYsn2OYfF+LrbSMlWO38Am2fqE8lTGe9EX/HZj95Wj+RnQApc9CkxGJkCb8\n
6aecuz8Vhyl2zWA5kqNrq978uMmsyX3FNRcS3mB7Vo+65R/XwThzHjSXyCyHzRMd\n
zOlrJZMuNWV2bI7vyIIp9/AdHNO6Hwnj+I5hBDvyV+T9RT2jLUTRZldGUJQBlDVj\n
QUKa8NSwzVrvoVTPAT6gcPCn4VQkwxLE/LWaNw2X8mxtyo3nXVoo291TzB8mKHUQ\n
ubOA1iBEcKtAFjqOlZSLanVNvrn5KwXY\n
-----END CERTIFICATE-----\n
+USECUB:1342
OK
Here are code examples showing how to implement binary data transmission in different programming languages.
def send_binary_data(at_command, binary_data):
- // Start with the AT command (without \r)
- message = at_command.encode('ascii')
// Add binary header
message += b'\x01' // Start marker
message += len(binary_data).to_bytes(2, 'big') // Length (2 bytes, big-endian)
// Add the actual binary data
message += binary_data
// Send to NORA-W36
serial_port.write(message)
// Example usage:
- certificate_data = open('ca.pem', 'rb').read()
- send_binary_data('AT+USECUB=0,"ca.pem"', certificate_data)
public void SendBinaryData(string atCommand, byte[] binaryData)
{
// Convert AT command to bytes
byte[] cmdBytes = System.Text.Encoding.ASCII.GetBytes(atCommand);
// Create binary header (3 bytes)
byte[] header = new byte[3];
header[0] = 0x01; // Start marker
header[1] = (byte)(binaryData.Length >> 8); // High byte of length
header[2] = (byte)(binaryData.Length & 0xFF); // Low byte of length
// Combine all parts
byte[] fullMessage = new byte[cmdBytes.Length + header.Length + binaryData.Length];
Array.Copy(cmdBytes, 0, fullMessage, 0, cmdBytes.Length);
Array.Copy(header, 0, fullMessage, cmdBytes.Length, header.Length);
Array.Copy(binaryData, 0, fullMessage, cmdBytes.Length + header.Length, binaryData.Length);
// Send to NORA-W36
serialPort.Write(fullMessage, 0, fullMessage.Length);
}
// Example usage:
- byte[] certData = File.ReadAllBytes("ca.pem");
- SendBinaryData("AT+USECUB=0,\"ca.pem\"", certData);
Binary data is used in these NORA-W36 functions:
AT+USOWB - Send binary data over network socketsAT+USECUB - Upload SSL/TLS certificates and keys0x01 + length)\r before binary data
Your data size: _____ bytes
Convert to hex: 0x____
High byte (MSB): 0x__
Low byte (LSB): 0x__
Header: 0x01 0x__ 0x__
| Data Size | Hex | Header Bytes |
|---|---|---|
| 1 byte | 0x0001 | 0x01 0x00 0x01 |
| 10 bytes | 0x000A | 0x01 0x00 0x0A |
| 256 bytes | 0x0100 | 0x01 0x01 0x00 |
| 1024 bytes | 0x0400 | 0x01 0x04 0x00 |
Network diagnostic tools are essential for troubleshooting connectivity issues and optimizing network performance. NORA-W36 provides built-in diagnostic capabilities including network status monitoring, connectivity testing, and performance measurement tools.
Before diving into specific tools, run this quick health check:
| Step | Command | Expected Result | Issue Indicator |
|---|---|---|---|
| 1 | AT | OK | No response = UART/power issue |
| 2 | ATI | Module info | Wrong info = firmware issue |
| 3 | AT+UWSNST=0 | +UWSNST:0,<IP> | No IP = connectivity issue |
| 4 | AT+UWSST=4 | Signal strength | Low RSSI = signal issue |
Purpose: Show current status of Wi-Fi station network interface.
Syntax:
AT+UWSNST=<status_id> // Query specific status parameter
AT+UWSNST? // Query all network parameters
Parameters:
status_id: Status parameter identifier (0-5)0: Station IP address1: Network subnet mask2: Default gateway address3: Primary DNS server4: Secondary DNS server5: IPv6 link-local addressExamples:
| Nr | AT command | AT event | Description |
|---|---|---|---|
| 1 | AT+UWSNST=0 | +UWSNST:0,192.168.1.179 | Query station IP address |
| 2 | AT+UWSNST=1 | +UWSNST:1,255.255.255.0 | Query subnet mask |
| 3 | AT+UWSNST=2 | +UWSNST:2,192.168.1.1 | Query gateway address |
| 4 | AT+UWSNST? | Multiple responses (see below) | Query all network parameters |
Response Format for AT+UWSNST?:
+UWSNST:0,192.168.1.179 // Station IP address
+UWSNST:1,255.255.255.0 // Network subnet mask
+UWSNST:2,192.168.1.1 // Default gateway address
+UWSNST:3,192.168.1.1 // Primary DNS server
+UWSNST:4,0.0.0.0 // Secondary DNS server
+UWSNST:5,[fe80::56f8:2aff:fe13:6310] // IPv6 link-local address
Parameter Descriptions:
+UWSNST:0,<ip_address> - Station IP address+UWSNST:1,<subnet_mask> - Network subnet mask+UWSNST:2,<gateway> - Default gateway address+UWSNST:3,<dns_primary> - Primary DNS server+UWSNST:4,<dns_secondary> - Secondary DNS server+UWSNST:5,<ipv6_address> - IPv6 link-local addressTroubleshooting Network Status:
| Response | Meaning | Next Steps |
|---|---|---|
+UWSNST:0,192.168.1.179 | Connected with valid IP | Network is working |
ERROR | Interface not available | Check Wi-Fi connection with AT+UWSC=0 |
| No response | Command timeout | Check AT command interface |
Purpose: Measure Wi-Fi signal quality for connection optimization.
Signal Quality Assessment:
| RSSI Range | Quality | Recommendation |
|---|---|---|
| > -50 dBm | Excellent | Optimal performance |
| -50 to -60 dBm | Good | Stable connection expected |
| -60 to -70 dBm | Fair | May experience occasional drops |
| < -70 dBm | Poor | Move closer to access point |
Example:
AT+UWSST=4
+UWSST:-45
OK
Signal strength: -45 dBm (Excellent)
Purpose: Test internet connectivity using a simple TCP connection.
Basic Internet Connectivity Test:
| Nr | AT command | AT event | Description |
|---|---|---|---|
| 1 | AT+USOCR=6 | +USOCR:0 | Create TCP socket |
| 2 | AT+USOC=0,"8.8.8.8",53 | +UESOC:0 | Connect to Google DNS |
| 3 | AT+USOCL=0 | OK | Close socket |
Result Interpretation:
ERROR on step 2: Internet access blocked or DNS issuesStep-by-Step Diagnosis:
AT+UWSNST=0
Expected: +UWSNST:0,<IP_ADDRESS>
If ERROR: Wi-Fi not connected
AT+UWSST=4
Expected: Signal strength > -70 dBm
If weaker: Move closer to access point
AT+USOCR=6
AT+USOC=0,"192.168.1.1",80 // Router IP
Expected: +UESOC:0
Tests local network connectivity
AT+USOC=0,"8.8.8.8",53 // Google DNS
Expected: +UESOC:0
Tests internet connectivity
Iperf is a network performance measurement tool that can measure maximum TCP and UDP bandwidth performance. NORA-W36 supports Iperf version 2 protocol as both client and server.
Key Capabilities:
Download Iperf 2:
Important Note: The Iperf implementation is experimental and may change between releases.
Syntax: AT+UDGI=<iperf_action>,<protocol_type>[,<role>,<port>,<report_interval>[,<time_boundary>,<ip_addr>[,<bidirectional>]]]
Parameters:
| Parameter | Type | Values | Description |
|---|---|---|---|
iperf_action | Integer | 1 = Start, 0 = Stop | Control iperf operation |
protocol_type | Integer | 1 = TCP, 2 = UDP | Protocol selection |
role | Integer | 1 = Server, 2 = Client | Operating mode |
port | Integer | 1-65535 | Port number (default: 5001) |
report_interval | Integer | 1-60 seconds | Reporting frequency |
time_boundary | Integer | 1-300 seconds | Test duration |
ip_addr | String | IP address | Target server IP (client mode only) |
bidirectional | Integer | 0 = Off, 1 = On | Simultaneous bidirectional test |
Purpose: Run NORA-W36 as an Iperf server to receive performance tests from external clients.
TCP Client:
From PC command line (iperf 2.0):
iperf -c <NORA-W36_IP> -p 5001 -t 10
UDP Client:
From PC command line:
iperf -c <NORA-W36_IP> -p 5001 -u -t 10 -b 10M
TCP Server:
| Nr | AT command | AT event | Description |
|---|---|---|---|
| 1 | AT+UDGI=1,1,1,5001,1 | Start TCP server on port 5001 | |
| 2 | +UEDGI:"TCP: Start TCP server!" | Server started | |
| 3 | +UEDGI:"tcp_server_func: Create socket fd = 0" | Socket created | |
| 4 | +UEDGI:"tcp_server_func: Bind socket successfully" | Port bound | |
| 5 | +UEDGI:"tcp_server_func: Listen port 5001" | Server listening |
UDP Server:
| Nr | AT command | AT event | Description |
|---|---|---|---|
| 1 | AT+UDGI=1,2,1,5002,1 | Start UDP server on port 5002 | |
| 2 | +UEDGI:"UDP: Start UDP server!" | UDP server started |
Purpose: Use NORA-W36 as an Iperf client to test performance against external servers.
TCP Server:
// From PC command line:
iperf -s -p 5001
UDP Server:
// From PC command line:
iperf -s -u -p 5001
TCP Client Test:
| Nr | AT command | AT event | Description |
|---|---|---|---|
| 1 | AT+UDGI=1,1,2,5001,1,20,"192.168.0.41" | Connect to TCP server | |
| 2 | +UEDGI:"tcp_client_func: Create socket fd = 1" | Socket created | |
| 3 | +UEDGI:"tcp_client_func: Connect to server successfully" | Connected | |
| 4 | +UEDGI:"tcp_client_func: Send 1435 KBytes in 1000 ms, 11761 Kbits/sec" | Throughput report | |
| 5 | +UEDGI:"tcp_client_func: Send 1418 KBytes in 1000 ms, 11621 Kbits/sec" | Continued testing |
UDP Client Test:
| Nr | AT command | AT event | Description |
|---|---|---|---|
| 1 | AT+UDGI=1,2,2,5001,1,10,"192.168.0.41" | UDP performance test | |
| 2 | +UEDGI:"udp_client_func: Create socket fd = 2" | UDP socket created | |
| 3 | +UEDGI:"udp_client_func: Send 1024 KBytes in 1000 ms, 8388 Kbits/sec" | UDP throughput |
TCP Performance Benchmarks:
| Throughput | Quality | Typical Use Cases |
|---|---|---|
| > 10 Mbps | Excellent | Video streaming, large file transfers |
| 5-10 Mbps | Good | Web browsing, medium file transfers |
| 1-5 Mbps | Fair | IoT data, small file transfers |
| < 1 Mbps | Poor | Sensor data only |
UDP Performance Metrics:
Common Issues and Solutions:
| Issue | Symptoms | Solution |
|---|---|---|
| Connection Failed | "Connect failed" error | Check IP address and port; Verify server is running; Check firewall settings |
| Low Throughput | < 1 Mbps performance | Check Wi-Fi signal strength (AT+UWSST=4); Move closer to access point; Check for network congestion |
| Test Timeout | No performance data | Increase time_boundary parameter; Check network stability; Verify server response |
| Socket Creation Failed | "Create socket failed" | Close existing sockets; Check available memory; Restart if necessary |
Debug Steps:
AT+UWSNST=0 // Check IP address
AT+UWSST=4 // Check signal strength
AT+USOCR=6
AT+USOC=0,"<server_ip>",<port> // Test TCP connection
Bidirectional Testing:
// Test both upload and download simultaneously
AT+UDGI=1,1,2,5001,1,30,"192.168.0.41",1
Custom Duration Testing:
// -second test with 5-second intervals
AT+UDGI=1,1,2,5001,5,60,"192.168.0.41"
Stopping Iperf Tests:
// Stop current iperf operation
AT+UDGI=0
Automated Performance Checks:
// Quick performance validation script
AT+UWSNST=0 // Check connection
AT+UWSST=4 // Check signal
AT+UDGI=1,1,2,5001,1,10,"<server_ip>" // Quick iperf test
This diagnostic approach ensures reliable network performance and helps quickly identify connectivity issues in production deployments.
Purpose: Retrieve system crash information for troubleshooting hardware and firmware issues.
Syntax:
AT+USYCI?
Response:
+USYCI:"<crash_type>","<crash_reason>","<firmware_version>"
Parameters:
crash_type: Type of system fault (e.g., "HwFault", "SwFault", "WatchdogReset")crash_reason: Specific reason for the crash (e.g., "timerEvent", "memoryError")firmware_version: Firmware version when crash occurredExample:
AT+USYCI?
+USYCI:"HwFault","timerEvent","3.1.0-150"
OK
Troubleshooting Steps:
Important: If crashes continue after firmware updates and power supply verification, contact support@u-blox.com with the complete crash information output for further analysis.
The Extended error codes provide essential debugging information to understand the reason for errors received during AT command execution. This section provides comprehensive error code documentation for immediate troubleshooting without requiring external references.
Important Note: Error codes should only be used for information and might change between versions in the future.
NORA-W36 uses a structured error code system organized by functional categories:
| Category | Code Range | Description | Common Scenarios |
|---|---|---|---|
| Common | 1-22 | General system errors | Parameter validation, memory, timeouts |
| AT Command | 31-51 | AT command parsing errors | Invalid syntax, arguments, formatting |
| Wi-Fi | 60-71 | Wi-Fi specific errors | Connection issues, configuration problems |
| GATT/Bluetooth | 91-114 | Bluetooth GATT errors | Authentication, permissions, resources |
| HTTP | 160+ | HTTP protocol errors | Header issues, response problems |
| Socket | 180+ | Socket communication errors | Binding, connection state issues |
Purpose: Retrieve the error code from the last failed AT command
Syntax:
AT+USYEC?
Response:
+USYEC:<error_code>
OK
Example:
AT+USYEC?
+USYEC:5
OK
The error code 5 indicates U_ERROR_COMMON_INVALID_PARAMETER - the parameter in the last AT command was invalid.
Purpose: Enable automatic error code reporting for all failed commands
Syntax:
AT+USYEE=<extended_errors>
Parameters:
extended_errors: 0 = disabled, 1 = enabledExample:
AT+USYEE=1
OK
AT+UWSSC
ERROR:32
The error code 32 indicates U_AT_STATUS_INVALID_COMMAND - the AT command syntax is incorrect.
Purpose: Get the last error code for socket operations
Syntax:
AT+USOE?
Response:
+USOE:<error_code>
OK
Example:
AT+USOE?
+USOE:16
OK
The error code 16 indicates U_ERROR_COMMON_NOT_CONNECTED - the socket connection is not established.
These are fundamental system errors that can occur across all functions:
| Code | Error Name | Description | Troubleshooting |
|---|---|---|---|
| 1 | U_ERROR_COMMON_BSD_ERROR | BSD system error | Check system resources and permissions |
| 2 | U_ERROR_COMMON_NOT_INITIALISED | System not initialized | Ensure proper module initialization |
| 3 | U_ERROR_COMMON_NOT_IMPLEMENTED | Feature not implemented | Use alternative commands or update firmware |
| 4 | U_ERROR_COMMON_NOT_SUPPORTED | Operation not supported | Check module capabilities and configuration |
| 5 | U_ERROR_COMMON_INVALID_PARAMETER | Invalid parameter value | Verify parameter values and ranges |
| 6 | U_ERROR_COMMON_NO_MEMORY | Insufficient memory | Free memory, reduce concurrent operations |
| 7 | U_ERROR_COMMON_NOT_RESPONDING | Module not responding | Check power supply, reset module |
| 8 | U_ERROR_COMMON_PLATFORM | Platform-specific error | Check hardware configuration |
| 9 | U_ERROR_COMMON_TIMEOUT | Operation timed out | Increase timeout, check network connectivity |
| 10 | U_ERROR_COMMON_DEVICE_ERROR | Device hardware error | Check hardware connections, reset device |
| 11 | U_ERROR_COMMON_NOT_FOUND | Resource not found | Verify resource existence and spelling |
| 12 | U_ERROR_COMMON_INVALID_ADDRESS | Invalid address format | Check IP address, MAC address format |
| 13 | U_ERROR_COMMON_TEMPORARY_FAILURE | Temporary operation failure | Retry operation after delay |
| 14 | U_ERROR_COMMON_AUTHENTICATION_FAILURE | Authentication failed | Check credentials, certificates |
| 15 | U_ERROR_COMMON_OPERATION_IN_PROGRESS | Operation already in progress | Wait for completion or cancel current operation |
| 16 | U_ERROR_COMMON_NOT_CONNECTED | Not connected to network/service | Establish connection first |
| 17 | U_ERROR_COMMON_LIMIT_REACHED | Resource limit reached | Check concurrent connections, memory usage |
| 18 | U_ERROR_COMMON_ALREADY_CREATED | Resource already exists | Use existing resource or delete first |
| 19 | U_ERROR_COMMON_END_OF_TRANSMISSION | End of data transmission | Normal completion indication |
| 19 | U_ERROR_COMMON_REMOTE_CANCELLED_TRANSMISSION | Remote cancelled transmission | Check remote peer status |
| 20 | U_ERROR_COMMON_NOT_CONFIGURED | Feature not configured | Configure feature before use |
| 21 | U_ERROR_COMMON_INVALID_RESPONSE | Invalid response received | Check protocol compliance, retry |
| 22 | U_ERROR_COMMON_UNKNOWN | Unknown error occurred | Enable extended error reporting for details |
These errors relate to AT command parsing and syntax validation:
| Code | Error Name | Description | Troubleshooting |
|---|---|---|---|
| 31 | U_AT_STATUS_NOT_IMPLEMENTED | AT command not implemented | Use alternative command or update firmware |
| 32 | U_AT_STATUS_INVALID_COMMAND | Invalid AT command syntax | Check command spelling and format |
| 33 | U_AT_STATUS_INVALID_ARGUMENTS | Invalid command arguments | Verify argument types and values |
| 34 | U_AT_STATUS_INVALID_ARGUMENT_COUNT | Wrong number of arguments | Check required vs provided parameters |
| 35 | U_AT_STATUS_INVALID_INT_ARG | Invalid integer argument | Ensure numeric values are integers |
| 36 | U_AT_STATUS_INVALID_INT_RANGE | Integer argument out of range | Check min/max parameter limits |
| 37 | U_AT_STATUS_INVALID_STR_ARG | Invalid string argument | Check string format and encoding |
| 38 | U_AT_STATUS_INVALID_STR_LENGTH | String argument too long/short | Verify string length requirements |
| 39 | U_AT_STATUS_INVALID_ENUM_ARG | Invalid enumeration value | Use only supported enumeration values |
| 40 | U_AT_STATUS_INVALID_IP_ADDR_ARG | Invalid IP address format | Use proper IPv4 format (x.x.x.x) |
| 41 | U_AT_STATUS_INVALID_MAC_ADDR_ARG | Invalid MAC address format | Use proper MAC format (xx:xx:xx:xx:xx:xx) |
| 42 | U_AT_STATUS_INVALID_BD_ADDR_ARG | Invalid Bluetooth address | Check Bluetooth address format |
| 43 | U_AT_STATUS_INVALID_BYTE_ARRAY_ARG | Invalid byte array | Check hexadecimal format |
| 44 | U_AT_STATUS_INVALID_BYTE_ARRAY_LENGTH | Byte array length mismatch | Verify expected vs actual data length |
| 45 | U_AT_STATUS_UNMATCHED_QUOTE | Unmatched quotation marks | Balance opening and closing quotes |
| 46 | U_AT_STATUS_TIMEOUT | AT command timeout | Increase timeout or check module response |
| 47 | U_AT_STATUS_BIN_CMD_EXEC_AS_STD_CMD | Binary command executed as standard | Use proper binary command format |
| 48 | U_AT_STATUS_INVALID_ESCAPE_CODE | Invalid escape sequence | Use proper escape characters |
| 49 | U_AT_STATUS_INVALID_CHARACTER | Invalid character in command | Remove unsupported characters |
| 50 | U_AT_STATUS_INVALID_INT_LIST_ARG | Invalid integer list format | Check list syntax and separators |
| 51 | U_AT_STATUS_INVALID_INT_LIST_LENGTH | Integer list length incorrect | Verify expected vs actual list size |
These errors are specific to Wi-Fi operations:
| Code | Error Name | Description | Troubleshooting |
|---|---|---|---|
| 60 | U_ERROR_WIFI_AT | Wi-Fi AT command error | Check Wi-Fi specific command syntax |
| 61 | U_ERROR_WIFI_NOT_CONFIGURED | Wi-Fi not configured | Configure Wi-Fi settings first with AT+UWSCP |
| 62 | U_ERROR_WIFI_NOT_FOUND | Wi-Fi network not found | Check SSID, scan networks with AT+UWSSC |
| 63 | U_ERROR_WIFI_INVALID_MODE | Invalid Wi-Fi mode | Use supported modes (station/AP) |
| 64 | U_ERROR_WIFI_TEMPORARY_FAILURE | Temporary Wi-Fi failure | Retry connection after delay |
| 65 | U_ERROR_WIFI_ALREADY_CONNECTED | Already connected to Wi-Fi | Disconnect first with AT+UWSDC if needed |
| 66 | U_ERROR_WIFI_ALREADY_CONNECTED_TO_SSID | Already connected to this SSID | Connection already established |
| 67 | U_ERROR_WIFI_DISCONNECTED | Wi-Fi disconnected | Re-establish connection with AT+UWSC=0 |
| 68 | U_ERROR_WIFI_ALREADY_UP | Wi-Fi interface already up | Interface already active |
| 69 | U_ERROR_WIFI_AP_NOT_STARTED | Access Point not started | Start AP mode with AT+UWAPS |
| 70 | U_ERROR_WIFI_IS_DOWN | Wi-Fi interface is down | Bring interface up first |
| 71 | U_ERROR_WIFI_ALREADY_STARTED | Wi-Fi service already started | Service already running |
These errors occur during Bluetooth GATT operations:
| Code | Error Name | Description | Troubleshooting |
|---|---|---|---|
| 91 | U_PORT_GATT_STATUS_INVALID_HANDLE | Invalid GATT handle | Use valid characteristic/service handles |
| 92 | U_PORT_GATT_STATUS_READ_NOT_PERMITTED | Read operation not allowed | Check characteristic permissions |
| 93 | U_PORT_GATT_STATUS_WRITE_NOT_PERMITTED | Write operation not allowed | Check characteristic permissions |
| 94 | U_PORT_GATT_STATUS_INVALID_PDU | Invalid Protocol Data Unit | Check data format and length |
| 95 | U_PORT_GATT_STATUS_AUTHENTICATION | Authentication required | Complete authentication process |
| 96 | U_PORT_GATT_STATUS_NOT_SUPPORTED | Operation not supported | Use supported GATT operations |
| 97 | U_PORT_GATT_STATUS_INVALID_OFFSET | Invalid data offset | Check read/write offset parameters |
| 98 | U_PORT_GATT_STATUS_AUTHORIZATION | Authorization required | Complete authorization process |
| 99 | U_PORT_GATT_STATUS_PREPARE_QUEUE_FULL | Prepare write queue full | Complete pending writes first |
| 100 | U_PORT_GATT_STATUS_ATTRIBUTE_NOT_FOUND | GATT attribute not found | Use valid attribute handles |
| 101 | U_PORT_GATT_STATUS_ATTRIBUTE_NOT_LONG | Attribute not long enough | Check attribute length requirements |
| 102 | U_PORT_GATT_STATUS_ENCRYPTION_KEY_SIZE | Insufficient encryption key size | Use stronger encryption |
| 103 | U_PORT_GATT_STATUS_INVALID_ATTRIBUTE_LEN | Invalid attribute length | Check length constraints |
| 104 | U_PORT_GATT_STATUS_UNLIKELY | Unlikely error condition | Retry operation |
| 105 | U_PORT_GATT_STATUS_INSUFFICIENT_ENCRYPTION | Insufficient encryption level | Enable proper encryption |
| 106 | U_PORT_GATT_STATUS_UNSUPPORTED_GROUP_TYPE | Unsupported group type | Use supported GATT group types |
| 107 | U_PORT_GATT_STATUS_INSUFFICIENT_RESOURCES | Insufficient system resources | Free resources, reduce load |
| 108 | U_PORT_GATT_STATUS_DB_OUT_OF_SYNC | Database out of sync | Refresh GATT database |
| 109 | U_PORT_GATT_STATUS_VALUE_NOT_ALLOWED | Value not allowed | Use permitted values only |
| 110 | U_PORT_GATT_STATUS_WRITE_REQ_REJECTED | Write request rejected | Check write permissions and format |
| 111 | U_PORT_GATT_STATUS_CCC_IMPROPER_CONF | Improper CCC configuration | Configure Client Characteristic Config properly |
| 112 | U_PORT_GATT_STATUS_PROCEDURE_IN_PROGRESS | GATT procedure in progress | Wait for completion |
| 113 | U_PORT_GATT_STATUS_OUT_OF_RANGE | Value out of range | Use values within permitted range |
| 114 | U_PORT_GATT_STATUS_UNKNOWN | Unknown GATT error | Enable extended debugging |
These errors relate to HTTP protocol operations:
| Code | Error Name | Description | Troubleshooting |
|---|---|---|---|
| 160 | U_ERROR_HTTP_HEADER_NOT_READ | HTTP header not read | Ensure headers are read before accessing body |
Note: Additional HTTP error codes may be present. Use AT+USYEC? after HTTP operations for specific codes.
These errors occur during socket operations:
| Code | Error Name | Description | Troubleshooting |
|---|---|---|---|
| 180 | U_ERROR_SOCKET_ALREADY_BOUND | Socket already bound | Close socket first with AT+USOCL |
Note: Additional socket error codes may be present. Use AT+USOE? for socket-specific error information.
Step 1: Enable Extended Error Reporting
AT+USYEE=1
OK
Step 2: Execute Command and Observe Error
AT+UWSCP=0,"InvalidSSID"
ERROR:62
Step 3: Look Up Error Code
U_ERROR_WIFI_NOT_FOUNDStep 4: Apply Solution
AT+UWSSC // Scan for networks
AT+UWSCP=0,"CorrectSSID"
OK
For Connection Issues:
// Check last error
AT+USYEC?
+USYEC:14
OK
// Error 14 = Authentication Failure
// Check credentials and security settings
AT+UWSCP=0 // Verify SSID
AT+UWSS=0 // Check security configuration
AT+UWSS? // Verify security mode
For Socket Issues:
// Check socket-specific error
AT+USOE?
+USOE:16
OK
// Error 16 = Not Connected
// Re-establish connection
AT+UWSNST=0 // Check network status
AT+USOC=0,server,port // Reconnect socket
| Error Pattern | Quick Resolution | Prevention |
|---|---|---|
| Parameter Errors (5, 35-39) | Check parameter format and ranges | Validate inputs before sending commands |
| Connection Errors (16, 62, 67) | Verify network status and reconnect | Monitor connection status regularly |
| Memory Errors (6, 107) | Free resources, reduce concurrent operations | Implement resource management |
| Authentication Errors (14, 95, 98) | Verify credentials and certificates | Use secure credential storage |
| Timeout Errors (9, 46) | Increase timeouts, check network conditions | Monitor signal strength and latency |
Enable Comprehensive Error Reporting:
// Enable comprehensive error reporting for all commands
AT+USYEE=1
// Monitor connection events
AT+UWSNST=0 // Check connection status regularly
// Check errors periodically
AT+USYEC? // Last general error
AT+USOE? // Last socket error
Wi-Fi Connection with Error Handling:
AT+UWSC
ERROR:62
AT+USYEC?
+USYEC:62
// Error 62 = Network not found, scan first
AT+UWSSC
AT+UWSC
OK
Socket Operation with Error Handling:
AT+USOC=0,"192.168.1.100",80
ERROR
AT+USOE?
+USOE:180
// Error 180 = Socket already bound, close first
AT+USOCL=0
AT+USOC=0,"192.168.1.100",80
OK
This comprehensive error code reference provides immediate debugging support without requiring external documentation, significantly enhancing the troubleshooting experience for NORA-W36 users.
This use case shows what AT commands to send to start a software update.
There are two ways to start the software update:

| Nr | Instructions | AT command | AT event |
|---|---|---|---|
| 1 | Start XMODEM protocol with AT command | AT+USYFWUS=3000000 | |
| 2 | Now NORA-W36 is ready to receive the software using the XMODEM or XMODEM-1K protocol | CCCCCCCCCCC... | |
| 3 | When the software has been downloaded the module will restart | +STARTUP | |
| 4 | Check the version of the software | AT+GMR | "4.0.0-041" |
Consider the following points when updating the software using the bootloader:
SWITCH_1 and SWITCH_2 during startup (or after reset)?| Nr | Instructions | AT command | Event |
|---|---|---|---|
| 1a | Enter the bootloader | AT+USYBL=115200 | |
| 1b | Alternatively, press SWITCH_1 and SWITCH_2 during startup or reset to enter the bootloader reset | ||
| 2 | Wait for the > prompt | > | |
| 3 | Change baud rate to up to 3 Mbit/s (optional) | r 3000000 | |
| 4 | Start XMODEM protocol with the command x | x | |
| 5 | Now NORA-W36 is ready to receive the software using the XMODEM or XMODEM-1K protocol | CCCCCCCCCCC... | |
| 6 | Wait for the prompt to indicate that the software has been downloaded successfully | > | |
| 7 | Enter the q command to restart the module | q | |
| 8 | Wait for the prompt to display that the module has restarted in AT mode | +STARTUP | |
| 9 | Check the version of the software | AT+GMR | "3.0.0-041" |
XMODEM is a file transfer protocol used for reliable data transmission over serial connections. NORA-W36 supports both standard XMODEM (128-byte blocks) and XMODEM-1K (1024-byte blocks) for firmware updates.
XMODEM uses a simple acknowledgment-based protocol where the receiver controls the transfer by requesting blocks from the sender. Each block includes error detection to ensure data integrity.
Key Features:
Block Structure:
[SOH][Block#][~Block#][128 bytes data][Checksum]
1 1 1 128 1 = 132 bytes total
Control Characters:
SOH (0x01): Start of Header - begins each blockEOT (0x04): End of Transmission - signals transfer completeACK (0x06): Acknowledge - receiver accepts blockNAK (0x15): Negative Acknowledge - receiver rejects blockCAN (0x18): Cancel - abort transferC (0x43): Request CRC mode instead of checksumBlock Structure:
[STX][Block#][~Block#][1024 bytes data][CRC-16]
1 1 1 1024 2 = 1029 bytes total
Key Differences from Standard XMODEM:
STX (0x02) instead of SOH1. Handshake Phase:
Receiver → Sender: NAK or 'C' (requests transfer start)
Sender → Receiver: First data block
2. Data Transfer Phase:
For each block:
Sender → Receiver: [Block data]
Receiver → Sender: ACK (good) or NAK (retry)
3. Completion Phase:
Sender → Receiver: EOT (end of transmission)
Receiver → Sender: ACK (confirms completion)
Timeout Conditions:
Error Recovery:
Complete working XMODEM implementations for NORA-W36 firmware updates are provided in the appendices:
Key Features of Both Implementations:
Usage Examples:
# Python implementation
python xmodem.py COM3 NORA-W36X-SW-3.1.0-150.bin 115200
# C implementation
xmodem.exe COM3 NORA-W36X-SW-3.1.0-150.bin 115200
Both implementations use identical command-line interfaces and have been proven to work reliably with NORA-W36 hardware.
Standard XMODEM vs XMODEM-1K:
| Parameter | XMODEM | XMODEM-1K |
|---|---|---|
| Block Size | 128 bytes | 1024 bytes |
| Header Size | 3 bytes | 3 bytes |
| Error Check | 1 byte checksum | 2 bytes CRC-16 |
| Total Overhead | 4 bytes (3.1%) | 5 bytes (0.5%) |
| Blocks per MB | 8,192 | 1,024 |
| ACK/NAK per MB | 8,192 | 1,024 |
| Efficiency | 96.9% | 99.5% |
Transfer Time Example (1MB firmware at 3Mbps):
Firmware Update Process:
AT+USYFWUS=3000000 to enter XMODEM modeBootloader Mode Features:
x for XMODEM, r for baud rate)Complete product information, specifications, and ordering details
Configuration and development tool for u-blox modules
Comprehensive AT command reference and syntax guide
u-blox AG
Address: Zürcherstrasse 68
8800 Thalwil
Switzerland
For further support and contact information, visit us at u-blox Support.
---
| Command | Purpose | Section |
|---|---|---|
AT+UWSCP | Wi-Fi Station Connection Parameters (SSID) | Section 8.1.4 |
AT+UWSSW | Wi-Fi Station Security/Password (WPA2/WPA3) | Section 8.1.4 |
AT+UWSSO | Wi-Fi Station Security Open | Section 8.1 |
AT+UWSC | Wi-Fi Station Connect | Section 8.1.4 |
AT+UWSDC | Wi-Fi Station Disconnect | Section 8.1.4 |
AT+UWSNST | Wi-Fi Station Network Status | Section 8.1 |
AT+UWSST | Wi-Fi Station Signal Strength (RSSI) | Section 8.1 |
| Command | Purpose | Section |
|---|---|---|
AT+UWSSP | Wi-Fi Station PEAP Security | Section 8.2 |
AT+UWSSE | Wi-Fi Station Enterprise Security (EAP-TLS) | Section 8.3 |
| Command | Purpose | Section |
|---|---|---|
AT+UWSIPS | Wi-Fi Station IP Static Configuration | Section 8.1 |
AT+UWSIPD | Wi-Fi Station IP DHCP | Section 8.1 |
| Command | Purpose | Section |
|---|---|---|
AT+UWAPCP | Wi-Fi Access Point Connection Parameters | Section 8.4 |
AT+UWAPSW | Wi-Fi Access Point Security/Password | Section 8.4 |
AT+UWAPA | Wi-Fi Access Point Activate | Section 8.4 |
AT+UWAPD | Wi-Fi Access Point Deactivate | Section 8.4 |
AT+UWAPNST | Wi-Fi Access Point Network Status | Section 8.4 |
| Command | Purpose | Section |
|---|---|---|
AT+UWSROS0 | Wi-Fi Roaming RSSI Threshold Low | Section 13 |
AT+UWSROS1 | Wi-Fi Roaming RSSI Threshold High | Section 13 |
AT+UWSROS2 | Wi-Fi Roaming Scan Interval | Section 13 |
AT+UWSROS3 | Wi-Fi Roaming Scan Duration | Section 13 |
AT+UWSROS4 | Wi-Fi Roaming Channel Time | Section 13 |
AT+UWSROS5 | Wi-Fi Roaming Home Channel Time | Section 13 |
| Command | Purpose | Section |
|---|---|---|
AT+USOCR | Create Socket (TCP/UDP) | Section 11.1 |
AT+USOC | Socket Connect | Section 11.1 |
AT+USOL | Socket Listen (Server) | Section 11.2 |
AT+USOCL | Socket Close | Section 11.1 |
| Command | Purpose | Section |
|---|---|---|
AT+USOWS | Socket Write String | Section 17.5 |
AT+USOWB | Socket Write Binary | Section 17.6 |
AT+USORS | Socket Read String | Section 17.5 |
AT+USORB | Socket Read Binary | Section 17.6 |
| Command | Purpose | Section |
|---|---|---|
AT+USOTLS | Socket TLS Configuration | Section 11.5 |
AT+USETE0 | TLS Extension - Server Name Indication | Section 11.9 |
AT+USETE1 | TLS Extension - Handshake Fragmentation | Section 11.9 |
| Command | Purpose | Section |
|---|---|---|
AT+USECUB | Certificate Upload Binary | Section 11.7 |
AT+USECL | Certificate List | Section 6.7.7 |
AT+USECD | Certificate Details/Show | Section 6.7.7 |
AT+USECR | Certificate Remove | Section 6.7.7 |
| Command | Purpose | Section |
|---|---|---|
AT+UMQCP | MQTT Client Parameters (Host/Port) | Section 12.1 |
AT+UMQC | MQTT Client Connect | Section 12.1 |
AT+UMQDC | MQTT Client Disconnect | Section 12.1 |
AT+UMQS | MQTT Subscribe | Section 12.1 |
AT+UMQS | MQTT Unsubscribe (with action=1) | Section 12.1 |
AT+UMQPS | MQTT Publish String | Section 12.1 |
AT+UMQCP | MQTT Connection Parameters (includes username/password) | Section 12.8 |
AT+UMQTLS | MQTT TLS Configuration | Section 12.9 |
| Command | Purpose | Section |
|---|---|---|
AT+UHTCCP | HTTP Client Connection Parameters | Section 13.3 |
AT+UHTCTLS | HTTP Client TLS Configuration | Section 13.4 |
AT+UHTCRG | HTTP Client Request GET | Section 13.3 |
AT+UHTCRP | HTTP Client Request POST | Section 13.5 |
AT+UHTCRPUS | HTTP Client Request PUT String | Section 13.7 |
AT+UHTCRD | HTTP Client Request DELETE | Section 13.8 |
AT+UHTCGBS | HTTP Client Get Body String | Section 13.3 |
AT+UHTCGBB | HTTP Client Get Body Binary | Section 13.6 |
AT+UHTCRHAF | HTTP Client Request Header Add Field | Section 13.5 |
AT+UHTCDC | HTTP Client Disconnect | Section 13.3 |
| Command | Purpose | Section |
|---|---|---|
AT+UBTALS | BLE Advertising Parameters | Section 7.5 |
AT+UBTAL | BLE Advertising Start | Section 7.5 |
AT+UBTALD | BLE Advertising Stop | Section 7.5 |
| Command | Purpose | Section |
|---|---|---|
AT+UBTC | BLE Connect (Central) | Section 7.1 |
AT+UBTDC | BLE Disconnect | Section 7.1 |
AT+UBTD | BLE Discovery/Scan Start | Section 7.1 |
AT+UBTSS | BLE Scan Settings | Section 7.1 |
| Command | Purpose | Section |
|---|---|---|
AT+UBTP | Bluetooth Pairing | Section 7.3 |
AT+USPSWS | SPS Write String | Section 17.5 |
AT+USPSWB | SPS Write Binary | Section 17.6 |
AT+USPSRS | SPS Read String | Section 17.5 |
AT+USPSRB | SPS Read Binary | Section 17.6 |
| Command | Purpose | Section |
|---|---|---|
AT+UBTGW | GATT Characteristic Write | Section 7.1 |
AT+UBTGR | GATT Characteristic Read | Section 7.1 |
AT+UBTGCCW | GATT Client Configuration Write (for notifications) | Section 7.1 |
| Command | Purpose | Section |
|---|---|---|
AT+UPMPSL | Power Management Sleep Level | Section 16.1 |
AT+UPMPSTO | Power Management Sleep Timeout | Section 16.1 |
AT+CPWROFF | Module Reset/Power Off | Multiple sections |
| Command | Purpose | Section |
|---|---|---|
AT+UNTE | NTP Enable/Disable and Status | Section 9.1 |
AT+UNTSC | NTP Server Configuration | Section 14.2 |
| Command | Purpose | Section |
|---|---|---|
AT+UWSNST? | Check Connection Status | Section 19.2.1 |
AT+UDGI | Diagnostic Iperf Client | Section 19.7 |
| Command | Purpose | Section |
|---|---|---|
AT+USYEC | System Extended Error Code | Section 20.2.1 |
AT+USYEE | System Extended Errors Enable | Section 20.3.6 |
AT+USOE | Socket Error | Section 20.2.3 |
| Command | Purpose | Section |
|---|---|---|
AT+UTM | Transparent Mode | Section 17.8 |
AT+UTMP | Transparent Mode Persistent | Section 17.9 |
ATE0/ATE1 | Command Echo Control | Section 11.1 |
AT&W | Store Configuration (use with AT+CPWROFF) | Multiple sections |
+++ | Escape Sequence (Exit Transparent Mode) | Section 17.8 |
AT+UWSCP=0,"YourSSID" // Set network name
AT+UWSSW=0,"YourPass",0 // Set password
AT+UWSC=0 // Connect
AT+UMQCP=0,"broker.hivemq.com",1883 // Set broker
AT+UMQC=0 // Connect
AT+UMQS=0,"test/topic" // Subscribe
AT+UHTCCP=0,"httpbin.org",80 // Set server
AT+UHTCRG=0,"/" // GET request
AT+UHTCGBS=0,500 // Read response
AT+USYEE=1 // Enable extended errors
AT+UWSST=4 // Check signal strength
AT+UWSSC // List available networks
AT+USYEC? // Check last error
// Appendix B: Enhanced Debugging and Visual Reference Guide
This appendix provides visual troubleshooting aids, standardized code examples, and enhanced debugging techniques for optimal NORA-W36 implementation and troubleshooting.
Official LED Patterns (from NORA-W36 Datasheet):
| LED Combination | Color | State | Description |
|---|---|---|---|
| LED_BLUE = Low (0) | 🔵 Blue | Connected | Wi-Fi or Bluetooth connection established |
| LED_RED + LED_BLUE = Low (0) | 🟣 Magenta | Connecting | Attempting Wi-Fi or Bluetooth connection |
| LED_RED + LED_GREEN = Low (0) | 🟡 Yellow | Not Connected | No active connections |
| LED_RED = Low (0) | 🔴 Red | Not used | Reserved for future versions |
| LED_GREEN = Low (0) | 🟢 Green | Not used | Reserved for future versions |
Quick Status Reference:
Note: LED behavior may change in future firmware versions. Refer to latest datasheet for updates.
Visual Connection Flow:
🟡 Yellow (Disconnected)
↓
AT+UWSC=0 (Start connection)
↓
🟣 Magenta (Connecting)
↓
🔵 Blue (Connected)
Troubleshooting with LEDs:
AT+USYEC?Standardized AT Command Format Template:
### B.2.2. Command name
**Purpose:** Brief description of what the command does
**Syntax:**
AT+UWSCP=<interface_id>,<ssid>
Parameters:
interface_id: Wi-Fi interface (0 = station)ssid: Network SSID name (quoted string)Response:
OK
Examples:
// Basic usage
AT+UWSCP=0,"MyNetwork"
OK
// Error case
AT+UWSCP=0,invalid_ssid
ERROR:5 // U_ERROR_COMMON_INVALID_PARAMETER
Notes: SSID must be provided as quoted string for proper parsing
Wi-Fi Connection Template:
// Step 1: Configure network
AT+UWSCP="NetworkName",<channel>
OK
// Step 2: Set security (WPA2/WPA3)
AT+UWSSW=0,"password",<wpa_mode>
OK
// Step 3: Connect
AT+UWSC
+UEWLU:0,123456789ABC,6 // Wi-Fi Link Up
OK
// Step 4: Verify Netork connection
+UEWSNU
AT+UWSNST=0
+UWSNST:0,"192.168.1.100"
OK
Socket Connection Template:
// Step 1: Create socket
AT+USOCR=<protocol> // 6=TCP, 17=UDP
+USOCR:<socket_id>
OK
// Step 2: Connect to server
AT+USOC=<socket_id>,<server_ip>,<port>
+UESOC:<socket_id>
OK
// Step 3: Send/receive data
AT+USOWS=<socket_id>,"<data_payload>"
+USOWS:<socket_id>,<bytes_sent>
OK
// Step 4: Close socket
AT+USOCL=<socket_id>
OK
Level 1: Basic Status Check
// Quick health check (30 seconds)
AT // Module responsiveness
AT+UWSNST=0 // Network status
AT+USYEC? // Last error code
Level 2: Connection Diagnostics
// Connection analysis (2 minutes)
AT+UWSSC // Network scan
AT+UWSST=4 // Signal strength
AT+UWSCP=0 // Current configuration
AT+UWSS=0 // Security settings
AT+UWSNST? // Check connection status
Level 3: Advanced Troubleshooting
// Deep diagnostics (5 minutes)
AT+USYEE=1 // Enable extended errors
AT+UWSSC // Detailed network scan
AT+USECL? // Certificate validation
AT+UWSST=4 // Signal strength check
AT+USYEC? // Check for system errors
⚠ AT Command Fails?
│
┌──────▼──────
│ AT+USYEC? │
│ Check Error │
└──────┬──────┘
│
┌────────────▼────────────
│ Error Code Range? │
└─┬─────────┬─────────┬───┘
│ │ │
┌────▼─── ┌───▼─── ┌───▼────
│ 1-22 │ │ 31-51 │ │ 60-71 │
│Common │ │AT Synt│ │ Wi-Fi │
│Errors │ │ax Err │ │Errors │
└────┬───┘ └───┬───┘ └───┬────┘
│ │ │
▼ ▼ ▼
┌───────────── ┌───────────── ┌─────────────
│🔧 Check │ │ Check │ │📶 Check │
│System │ │Command │ │Wi-Fi │
│Resources │ │Format & │ │Connection │
│& Hardware │ │Parameters │ │& Settings │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
┌───────────── ┌───────────── ┌─────────────
│• Power │ │• Syntax │ │• Network │
│• Memory │ │• Arguments │ │• Auth │
│• Sensors │ │• Quotes │ │• Signal │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
┌─────────────
│AT+UWSSC │
│Check Networks│
└─────────────┘
Health Check Sequence (Copy-paste ready):
=== NORA-W36 Health Check ===
echo "Starting health check..."
// Basic responsiveness
AT
// Network status
AT+UWSNST=0
echo "Network Status: Check response above"
// Signal quality
AT+UWSST=4
echo "Signal Strength: Check RSSI value above"
// Error status
AT+USYEC?
echo "Last Error: 0 = No errors"
// Certificate status
AT+USECL?
echo "Certificates: Check expiration dates"
echo "Health check complete!"
🆘 Module Not Responding:
// Hardware reset sequence
1. Power cycle module (3.3V off → on)
2. Wait 5 seconds
3. AT // Test basic response
4. AT&F // Factory reset
5. AT+CPWROFF // Restart with factory default settings
🆘 Connection Issues:
// Connection recovery sequence
AT+UWSDC // Disconnect from network
AT+USYEE=1 // Enable error reporting
AT+UWSSC // Scan available networks
AT+UWSC // Reconnect
AT+UWSNST=0 // Verify connection
⚡ Speed Test Commands:
// Connection speed test
AT+UWSNST? // Check connection
AT+UWSSC // List networks for signal strength
AT+UWSST=4 // Signal strength verification
⚡ Bulk Configuration:
// Fast setup sequence for development
AT+USYEE=1 // Extended errors
AT+UWSNST=0 // Connection status check
AT+UPMPSL=0 // Disable power save
⚡ Security Validation:
// Security health check
AT+UWSCP=0 // Network config
AT+UWSS=0 // Security configuration
AT+USECL? // Certificate validity
AT+UWSST=4 // Signal strength (security)
This enhanced visual reference guide provides immediate troubleshooting support with visual indicators, standardized examples, and copy-paste ready command sequences for efficient NORA-W36 development and deployment.
This Python XMODEM sender implementation has been tested with real NORA-W36 hardware for firmware updates:
#!/usr/bin/env python3
"""
XMODEM Sender for NORA-W36 Firmware Updates
===========================================
Simple and tested XMODEM-1K sender for NORA-W36 firmware updates.
Includes robust error handling and buffer management.
Usage: python xmodem.py COM3 NORA-W36X-SW-3.1.0-150.bin [115200]
"""
import serial
import time
import struct
import os
import sys
class XModemSender:
# XMODEM Protocol Constants
SOH = 0x01 # Start of Header (128-byte blocks)
STX = 0x02 # Start of Text (1K blocks)
EOT = 0x04 # End of Transmission
ACK = 0x06 # Acknowledge
NAK = 0x15 # Negative Acknowledge
CAN = 0x18 # Cancel
C = 0x43 # Request CRC mode ('C')
def __init__(self, port, baudrate=115200):
self.serial = serial.Serial(port, baudrate, timeout=15)
self.debug = True
def send_file(self, filename):
"""Send file using XMODEM-1K protocol"""
if not os.path.exists(filename):
print(f"Error: File '{filename}' not found")
return False
file_size = os.path.getsize(filename)
block_size = 1024 # Always use XMODEM-1K for firmware
total_blocks = (file_size + block_size - 1) // block_size
print(f"Sending file: {filename}")
print(f"File size: {file_size} bytes")
print(f"Total blocks: {total_blocks}")
print("Protocol: XMODEM-1K with CRC-16")
# Wait for receiver ready signal
if not self._wait_for_start():
return False
# Send all blocks
with open(filename, 'rb') as f:
block_number = 1
for block_index in range(total_blocks):
data = f.read(block_size)
if len(data) < block_size:
data += b'\x1A' * (block_size - len(data)) # Pad with SUB
if not self._send_block(block_number, data):
print(f"Error: Failed to send block {block_number}")
return False
progress = (block_index + 1) * 100 // total_blocks
print(f"Progress: {progress}% ({block_index + 1}/{total_blocks} blocks)")
# Increment block number with natural 8-bit wraparound
block_number = (block_number + 1) % 256
# Send End of Transmission
print("Sending end of transmission...")
return self._send_eot()
def _wait_for_start(self):
"""Wait for receiver ready signal"""
print("Waiting for receiver ready signal...")
# Clear buffers
self.serial.reset_input_buffer()
self.serial.reset_output_buffer()
for attempt in range(60): # 60 second timeout
char = self.serial.read(1)
if char == bytes([self.C]):
print("Receiver ready (CRC mode)")
return True
elif char == bytes([self.NAK]):
print("Receiver ready (checksum mode)")
return True
elif char == bytes([self.CAN]):
print("Transfer cancelled by receiver")
return False
elif char:
if self.debug:
print(f"Unexpected response: {char.hex()}")
time.sleep(0.1)
self.serial.reset_input_buffer()
time.sleep(1)
print("Timeout waiting for receiver")
return False
def _send_block(self, block_num, data):
"""Send a single XMODEM-1K block with retries"""
block_complement = (~block_num) & 0xFF # Bitwise complement for XMODEM protocol
for retry in range(10):
# Build block: STX + block_num + complement + data + CRC16
block = bytes([self.STX, block_num, block_complement]) + data
crc = self._calculate_crc16(data)
block += struct.pack('>H', crc)
# Send block
self.serial.write(block)
self.serial.flush()
# Special timing for bootloader
if block_num == 2:
time.sleep(0.5)
# Wait for response
response = self.serial.read(1)
if response == bytes([self.ACK]):
if self.debug:
print(f"Block {block_num} acknowledged")
return True
elif response == bytes([self.NAK]):
if self.debug:
print(f"Block {block_num} NAK, retrying...")
time.sleep(0.1)
self.serial.reset_input_buffer()
continue
elif response == bytes([self.CAN]):
print("Transfer cancelled by receiver")
return False
else:
if self.debug and response:
print(f"Unexpected response: {response.hex()}")
time.sleep(0.1)
self.serial.reset_input_buffer()
continue
print(f"Block {block_num} failed after 10 retries")
return False
def _send_eot(self):
"""Send End of Transmission"""
for attempt in range(10):
self.serial.write(bytes([self.EOT]))
self.serial.flush()
response = self.serial.read(1)
if response == bytes([self.ACK]):
print("Transfer completed successfully!")
return True
time.sleep(1)
print("Failed to get EOT acknowledgment")
return False
def _calculate_crc16(self, data):
"""Calculate CRC-16 for XMODEM (CCITT polynomial 0x1021)"""
crc = 0x0000
for byte in data:
crc ^= byte << 8
for _ in range(8):
if crc & 0x8000:
crc = (crc << 1) ^ 0x1021
else:
crc <<= 1
crc &= 0xFFFF
return crc
def nora_firmware_update(port, firmware_file, baudrate=115200):
"""Update NORA-W36 firmware using XMODEM-1K"""
print("NORA-W36 Firmware Update Tool")
print("=" * 40)
try:
# Step 1: Send AT command to enter XMODEM mode
print("Connecting to NORA-W36...")
at_serial = serial.Serial(port, 115200, timeout=5)
print(f"Entering XMODEM mode at {baudrate} baud...")
at_serial.write(f"AT+USYFWUS={baudrate}\r".encode())
response = at_serial.read(100)
if b"OK" not in response:
print(f"Warning: Unexpected response: {response}")
time.sleep(2)
at_serial.close()
time.sleep(0.5)
# Step 2: Transfer firmware using XMODEM-1K
print(f"Starting XMODEM-1K transfer at {baudrate} baud...")
xmodem = XModemSender(port, baudrate)
if xmodem.send_file(firmware_file):
print("\nFirmware update completed successfully!")
# Step 3: Check new firmware version
print("Checking firmware version...")
time.sleep(5)
for attempt in range(6):
try:
check_serial = serial.Serial(port, 115200, timeout=5)
check_serial.write(b"AT+GMR\r")
time.sleep(1)
response = check_serial.read(200)
check_serial.close()
if response and b"OK" in response:
version_lines = response.decode('utf-8', errors='ignore').strip().split('\n')
for line in version_lines:
if line.strip() and line.strip() != 'OK' and not line.startswith('AT'):
print(f"Firmware version: {line.strip()}")
return True
break
except Exception:
print(f"Module restarting (attempt {attempt + 1}/6)...")
if attempt < 5:
time.sleep(5)
return True
else:
print("Firmware update failed!")
return False
except Exception as e:
print(f"Error: {e}")
return False
def main():
if len(sys.argv) < 3:
print("XMODEM Sender for NORA-W36 Firmware Updates")
print("Usage: python xmodem.py <port> <firmware_file> [baud_rate]")
print("")
print("Examples:")
print(" python xmodem.py COM3 NORA-W36X-SW-3.1.0-150.bin")
print(" python xmodem.py COM3 NORA-W36X-SW-3.1.0-150.bin 115200")
return 1
port = sys.argv[1]
firmware_file = sys.argv[2]
baudrate = int(sys.argv[3]) if len(sys.argv) > 3 else 115200
success = nora_firmware_update(port, firmware_file, baudrate)
return 0 if success else 1
if __name__ == '__main__':
sys.exit(main())
Usage:
python xmodem.py COM3 NORA-W36X-SW-3.1.0-150.bin 115200
---
This simplified C XMODEM sender provides the same functionality as the Python version with Windows-native serial port handling:
/**
* @file xmodem.c
* @brief XMODEM Sender for NORA-W36 Firmware Updates
*
* Simple XMODEM-1K sender tested with real NORA-W36 hardware.
* Includes robust error handling and buffer management.
*
* Compilation:
* GCC/MinGW: gcc -o xmodem xmodem.c -lkernel32
* Visual Studio: cl /Fe:xmodem.exe xmodem.c kernel32.lib
*
* Directory listing: ls (Linux/macOS) or dir (Windows)
* Usage: xmodem.exe COM3 NORA-W36X-SW-3.1.0-150.bin [115200]
*/
#include <windows.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
// XMODEM Protocol Constants
#define SOH 0x01 // Start of Header (128-byte blocks)
#define STX 0x02 // Start of Text (1K blocks)
#define EOT 0x04 // End of Transmission
#define ACK 0x06 // Acknowledge
#define NAK 0x15 // Negative Acknowledge
#define CAN 0x18 // Cancel
#define SUB 0x1A // Padding character
#define C_CHAR 0x43 // Request CRC mode ('C')
#define BLOCK_SIZE 1024
#define MAX_RETRIES 10
#define TIMEOUT_MS 3000
static uint16_t calculate_crc16(const uint8_t* data, size_t length) {
uint16_t crc = 0x0000;
for (size_t i = 0; i < length; i++) {
crc ^= (uint16_t)data[i] << 8;
for (int j = 0; j < 8; j++) {
crc = (crc & 0x8000) ? (crc << 1) ^ 0x1021 : (crc << 1);
}
}
return crc;
}
static bool serial_write(HANDLE hSerial, const uint8_t* data, size_t length) {
DWORD bytesWritten;
if (!WriteFile(hSerial, data, (DWORD)length, &bytesWritten, NULL)) {
return false;
}
FlushFileBuffers(hSerial);
return bytesWritten == length;
}
static bool serial_read_byte(HANDLE hSerial, uint8_t* byte, DWORD timeout_ms) {
COMMTIMEOUTS timeouts = {0};
timeouts.ReadIntervalTimeout = timeout_ms;
timeouts.ReadTotalTimeoutConstant = timeout_ms;
SetCommTimeouts(hSerial, &timeouts);
DWORD bytesRead;
return ReadFile(hSerial, byte, 1, &bytesRead, NULL) && bytesRead == 1;
}
static void serial_flush_input(HANDLE hSerial) {
PurgeComm(hSerial, PURGE_RXCLEAR);
}
static char* format_port_name(const char* port_name) {
static char formatted_name[256];
// Check if already formatted or if it's a low COM port
if (strncmp(port_name, "\\\\.\\", 4) == 0) {
strcpy_s(formatted_name, sizeof(formatted_name), port_name);
return formatted_name;
}
// For COM ports 1-9, use simple format
if (strlen(port_name) == 4 && strncmp(port_name, "COM", 3) == 0 &&
port_name[3] >= '1' && port_name[3] <= '9') {
strcpy_s(formatted_name, sizeof(formatted_name), port_name);
return formatted_name;
}
// For COM10 and higher, use Windows extended format
if (strncmp(port_name, "COM", 3) == 0) {
snprintf(formatted_name, sizeof(formatted_name), "\\\\.\\%s", port_name);
return formatted_name;
}
// For other formats, assume it's correct
strcpy_s(formatted_name, sizeof(formatted_name), port_name);
return formatted_name;
}
static bool wait_for_start_signal(HANDLE hSerial) {
printf("Waiting for receiver ready signal...\n");
serial_flush_input(hSerial);
uint8_t byte;
DWORD start_time = GetTickCount();
while ((GetTickCount() - start_time) < 60000) { // 60 second timeout
if (serial_read_byte(hSerial, &byte, 1000)) {
if (byte == C_CHAR) {
printf("Receiver ready (CRC mode)\n");
return true;
} else if (byte == NAK) {
printf("Receiver ready (checksum mode)\n");
return true;
} else if (byte == CAN) {
printf("Transfer cancelled by receiver\n");
return false;
} else {
printf("Unexpected response: 0x%02X\n", byte);
Sleep(100);
serial_flush_input(hSerial);
}
}
}
printf("Timeout waiting for start signal\n");
return false;
}
static bool send_block(HANDLE hSerial, uint8_t block_num, const uint8_t* data) {
uint8_t block[3 + BLOCK_SIZE + 2]; // Header + data + CRC
uint8_t block_complement = ~block_num; // Bitwise complement for XMODEM protocol
// Build block: STX + block_num + complement + data + CRC16
block[0] = STX;
block[1] = block_num;
block[2] = block_complement;
memcpy(&block[3], data, BLOCK_SIZE);
uint16_t crc = calculate_crc16(data, BLOCK_SIZE);
block[3 + BLOCK_SIZE] = (crc >> 8) & 0xFF;
block[4 + BLOCK_SIZE] = crc & 0xFF;
// Send block with retries
for (int retry = 0; retry < MAX_RETRIES; retry++) {
printf("[XMODEM] Sending block %u, try %d\n", block_num, retry + 1);
if (!serial_write(hSerial, block, sizeof(block))) {
printf("[XMODEM] Failed to write block %u\n", block_num);
continue;
}
// Special timing for bootloader
if (block_num == 2) {
Sleep(500);
}
// Wait for response
uint8_t response;
if (serial_read_byte(hSerial, &response, TIMEOUT_MS)) {
printf("[XMODEM] Received response: 0x%02X\n", response);
if (response == ACK) {
printf("[XMODEM] Block %u acknowledged\n", block_num);
// Clear any additional bytes that might be in the buffer
Sleep(50);
serial_flush_input(hSerial);
return true;
} else if (response == NAK) {
printf("[XMODEM] NAK received for block %u, retrying...\n", block_num);
Sleep(100);
serial_flush_input(hSerial);
continue;
} else if (response == CAN) {
printf("[XMODEM] Cancelled by receiver\n");
return false;
} else {
printf("[XMODEM] Unexpected response 0x%02X", response);
// Read and display any additional bytes in buffer for debugging
uint8_t extra_byte;
int extra_count = 0;
printf(" - Additional bytes: ");
while (serial_read_byte(hSerial, &extra_byte, 100) && extra_count < 10) {
printf("0x%02X ", extra_byte);
extra_count++;
}
printf("\n");
Sleep(200);
serial_flush_input(hSerial);
continue;
}
} else {
printf("[XMODEM] Timeout waiting for response\n");
Sleep(100);
serial_flush_input(hSerial);
}
}
printf("[XMODEM] Failed after %d retries for block %u\n", MAX_RETRIES, block_num);
return false;
}
static bool send_eot(HANDLE hSerial) {
printf("[XMODEM] Sending EOT\n");
for (int attempt = 0; attempt < MAX_RETRIES; attempt++) {
uint8_t eot = EOT;
if (!serial_write(hSerial, &eot, 1)) {
printf("[XMODEM] Failed to send EOT\n");
continue;
}
uint8_t response;
if (serial_read_byte(hSerial, &response, TIMEOUT_MS)) {
if (response == ACK) {
printf("[XMODEM] Transfer completed successfully\n");
return true;
} else {
printf("[XMODEM] Unexpected EOT response: 0x%02X\n", response);
}
} else {
printf("[XMODEM] Timeout waiting for EOT response\n");
}
Sleep(1000);
}
printf("[XMODEM] Failed to get EOT acknowledgment\n");
return false;
}
static bool xmodem_send_file(HANDLE hSerial, const char* filename) {
FILE* file = fopen(filename, "rb");
if (!file) {
printf("Error: Could not open file '%s'\n", filename);
return false;
}
// Get file size
fseek(file, 0, SEEK_END);
long file_size = ftell(file);
fseek(file, 0, SEEK_SET);
size_t total_blocks = (file_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
printf("Sending file: %s\n", filename);
printf("File size: %ld bytes\n", file_size);
printf("Total blocks: %zu\n", total_blocks);
printf("Protocol: XMODEM-1K with CRC-16\n");
// Wait for receiver ready
if (!wait_for_start_signal(hSerial)) {
fclose(file);
return false;
}
// Send all blocks
uint8_t block_num = 1;
uint8_t data_buffer[BLOCK_SIZE];
for (size_t block_index = 0; block_index < total_blocks; block_index++) {
// Read and pad block
memset(data_buffer, SUB, BLOCK_SIZE);
size_t bytes_read = fread(data_buffer, 1, BLOCK_SIZE, file);
if (bytes_read == 0 && block_index < total_blocks - 1) {
printf("Error: Unexpected end of file\n");
fclose(file);
return false;
}
// Send block
if (!send_block(hSerial, block_num, data_buffer)) {
printf("Error: Failed to send block %u\n", block_num);
fclose(file);
return false;
}
// Progress indicator
printf("Progress: %zu%% (%zu/%zu blocks)\n",
(block_index + 1) * 100 / total_blocks,
block_index + 1, total_blocks);
// Increment block number with natural 8-bit wraparound
block_num = (block_num + 1) % 256;
}
fclose(file);
return send_eot(hSerial);
}
static HANDLE init_serial_port(const char* port_name, DWORD baud_rate) {
const char* formatted_port = format_port_name(port_name);
printf("Opening serial port: %s\n", formatted_port);
HANDLE hSerial = CreateFile(formatted_port, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hSerial == INVALID_HANDLE_VALUE) {
printf("Error: Could not open serial port %s (tried %s)\n", port_name, formatted_port);
DWORD error = GetLastError();
printf("Windows error code: %lu\n", error);
return INVALID_HANDLE_VALUE;
}
// Configure serial port
DCB dcbSerialParams = {0};
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
GetCommState(hSerial, &dcbSerialParams);
dcbSerialParams.BaudRate = baud_rate;
dcbSerialParams.ByteSize = 8;
dcbSerialParams.StopBits = ONESTOPBIT;
dcbSerialParams.Parity = NOPARITY;
dcbSerialParams.fDtrControl = DTR_CONTROL_ENABLE;
dcbSerialParams.fRtsControl = RTS_CONTROL_ENABLE;
if (!SetCommState(hSerial, &dcbSerialParams)) {
printf("Error: Could not configure serial port\n");
CloseHandle(hSerial);
return INVALID_HANDLE_VALUE;
}
return hSerial;
}
static bool nora_firmware_update(const char* port_name, const char* firmware_file, DWORD baud_rate) {
printf("NORA-W36 Firmware Update Tool\n");
printf("========================================\n");
// Step 1: Send AT command to enter XMODEM mode
printf("Connecting to NORA-W36...\n");
HANDLE hSerial = init_serial_port(port_name, 115200);
if (hSerial == INVALID_HANDLE_VALUE) {
return false;
}
printf("Entering XMODEM mode at %lu baud...\n", baud_rate);
char at_command[32];
snprintf(at_command, sizeof(at_command), "AT+USYFWUS=%lu\r", baud_rate);
if (!serial_write(hSerial, (uint8_t*)at_command, strlen(at_command))) {
printf("Error: Failed to send AT command\n");
CloseHandle(hSerial);
return false;
}
uint8_t response[100];
DWORD bytes_read = 0;
Sleep(500);
ReadFile(hSerial, response, sizeof(response) - 1, &bytes_read, NULL);
response[bytes_read] = '\0';
if (strstr((char*)response, "OK") == NULL) {
printf("Warning: Unexpected response: %s\n", response);
}
Sleep(2000);
CloseHandle(hSerial);
Sleep(500);
// Step 2: Transfer firmware using XMODEM-1K
printf("Starting XMODEM-1K transfer at %lu baud...\n", baud_rate);
hSerial = init_serial_port(port_name, baud_rate);
if (hSerial == INVALID_HANDLE_VALUE) {
return false;
}
bool success = xmodem_send_file(hSerial, firmware_file);
CloseHandle(hSerial);
if (success) {
printf("\nFirmware update completed successfully!\n");
// Step 3: Check firmware version
printf("Checking firmware version...\n");
Sleep(5000);
for (int attempt = 0; attempt < 6; attempt++) {
hSerial = init_serial_port(port_name, 115200);
if (hSerial != INVALID_HANDLE_VALUE) {
if (serial_write(hSerial, (uint8_t*)"AT+GMR\r", 7)) {
Sleep(1000);
if (ReadFile(hSerial, response, sizeof(response) - 1, &bytes_read, NULL) && bytes_read > 0) {
response[bytes_read] = '\0';
if (strstr((char*)response, "OK")) {
char* context = NULL;
char* lines = strtok_s((char*)response, "\n\r", &context);
while (lines != NULL) {
if (strlen(lines) > 0 && strcmp(lines, "OK") != 0 && strncmp(lines, "AT", 2) != 0) {
printf("Firmware version: %s\n", lines);
CloseHandle(hSerial);
return true;
}
lines = strtok_s(NULL, "\n\r", &context);
}
}
}
}
CloseHandle(hSerial);
}
printf("Module restarting (attempt %d/6)...\n", attempt + 1);
if (attempt < 5) Sleep(5000);
}
} else {
printf("\nFirmware update failed!\n");
}
return success;
}
int main(int argc, char* argv[]) {
if (argc < 3) {
printf("XMODEM Sender for NORA-W36 Firmware Updates\n");
printf("Usage: %s <port> <firmware_file> [baud_rate]\n", argv[0]);
printf("\n");
printf("Examples:\n");
printf(" %s COM3 NORA-W36X-SW-3.1.0-150.bin\n", argv[0]);
printf(" %s COM3 NORA-W36X-SW-3.1.0-150.bin 115200\n", argv[0]);
return 1;
}
const char* port_name = argv[1];
const char* firmware_file = argv[2];
DWORD baud_rate = (argc > 3) ? atol(argv[3]) : 115200;
bool success = nora_firmware_update(port_name, firmware_file, baud_rate);
return success ? 0 : 1;
}
Compilation and Usage:
# Compile with GCC/MinGW
gcc -o xmodem xmodem.c -lkernel32
# Compile with Visual Studio
cl /Fe:xmodem.exe xmodem.c kernel32.lib
# Check directory contents
dir // Windows
ls // Linux/macOS
# Use with NORA-W36X-SW-3.1.0-150.bin firmware
xmodem.exe COM3 NORA-W36X-SW-3.1.0-150.bin
Key Features:
port, firmware_file, baud_rate)