pdf-icon

Arduino Quick Start

2. Devices & Examples

Unit UWB Arduino Tutorial

1. Preparations

2. Notes

Note
At least 2 devices are required to achieve ranging or positioning (e.g. one device as Tag and multiple devices as Anchor). (Search online for detailed principles if interested).
Pin Compatibility
Due to different pin configurations across host devices, M5Stack provides an official Pin Compatibility Table for user convenience. Please modify example programs according to actual pin connections.

3. Example Program

  • This tutorial uses one CoreS3 and two AtomS3 as main controllers, paired with three Unit UWB modules. The Unit UWB module communicates via UART. Modify pin definitions in the program according to actual circuit connections. The corresponding UART IOs after connecting to CoreS3 and AtomS3 are both G1 (RX) and G2 (TX).

  • The Unit UWB example program provides an enumeration UWB_Anchor_num for Anchor numbering settings. Users can modify the value in function setupmode() as needed (any number works in Tag mode).

  • Tag program section:

cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
/*
 * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
 *
 * SPDX-License-Identifier: MIT
 *
 *
 * @Hardwares: M5CoreS3 + Unit UWB
 * @Dependent Library:
 * M5Unified: https://github.com/m5stack/M5Unified
 * M5Unit_UWB: https://github.com/m5stack/M5Unit-UWB
 */
#include <M5Unified.h>
#include "M5_UWB.h"

M5_UWB Unit_UWB;
UWB_Mode        Unit_UWB_Mode   = UWB_Mode_Tag;
UWB_Anchor_num  Unit_UWB_Tag    = UWB_Anchor_0; // Select the anchor

bool Uwb_Init = 0;
uint8_t Tag_num       = 0;
uint8_t UI_Init_flag = 0;
void UWB_UI_display();

void setup(){
    M5.begin();
    Serial.begin(115200);
    Unit_UWB.begin(&Serial2, 22, 21, 115200);
    Uwb_Init = Unit_UWB.setupmode(Unit_UWB_Mode, Unit_UWB_Tag, (char *)"5"); // Set the UWB mode and distance value
    if(Uwb_Init){
        Serial.println("UWB Init Success");
    } else {
        Serial.println("UWB Init Failed");
    }
    M5.Display.fillScreen(WHITE);
    M5.Display.setTextColor(BLACK);
    M5.Display.setFont(&fonts::FreeMonoBold9pt7b);
    delay(100);
}

void loop(){
    Tag_num = Unit_UWB.readstring();
    UWB_UI_display();
    delay(100);
}

void UWB_UI_display(){
    if(UI_Init_flag == 0){
      M5.Display.fillScreen(WHITE);
      M5.Display.setCursor(0, 0);
      M5.Display.println("UWB Test");
      M5.Display.println("Tag Model, Distance: \r\n(uint: m)\r\n");
      UI_Init_flag = 1;
    }
    M5.Display.fillRect(0, 60, 340, 240, WHITE);
    M5.Display.setCursor(0, 60);
    M5.Display.print(Unit_UWB.DATA);
    Serial.println(Unit_UWB.DATA);
}
  • Anchor program section:
cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
/*
 * SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
 *
 * SPDX-License-Identifier: MIT
 *
 *
 * @Hardwares: AtomS3 + Unit UWB
 * @Platform Version: Arduino M5Stack Board Manager v2.1.3
 * @Dependent Library:
 * M5Unified: https://github.com/m5stack/M5Unified
 * M5Unit_UWB: https://github.com/m5stack/M5Unit-UWB
 */
#include <M5Unified.h>
#include "M5_UWB.h"

M5_UWB Unit_UWB;
UWB_Mode Unit_UWB_Mode = UWB_Mode_Base;
UWB_Anchor_num Unit_UWB_Anchor = UWB_Anchor_1; // Select the anchor point

bool Uwb_Init = 0;
uint8_t Tag_num       = 0;
uint8_t UI_Init_flag = 0;
void UWB_UI_display();

const char* getAnchornNum(UWB_Anchor_num Num) {
    switch (Num) {
        case UWB_Anchor_0:      return "Base_0";
        case UWB_Anchor_1:      return "Base_1";
        case UWB_Anchor_2:      return "Base_2";
        case UWB_Anchor_3:      return "Base_3";
        case UWB_Anchor_4:      return "Base_4";
        default:                return "Unknown";
    }
}

void setup(){
    M5.begin();
    Serial.begin(115200);
    Unit_UWB.begin(&Serial2, 1, 2, 115200);
    Uwb_Init = Unit_UWB.setupmode(Unit_UWB_Mode, Unit_UWB_Anchor, (char *)"5"); // Set the UWB mode and distance value
    if(Uwb_Init){
        Serial.println("UWB Init Success");
    } else {
        Serial.println("UWB Init Failed");
    }
    M5.Display.fillScreen(WHITE);
    M5.Display.setTextColor(BLACK);
    M5.Display.setFont(&fonts::FreeMonoBold9pt7b);
    delay(100);
}

void loop(){
    Tag_num = Unit_UWB.readstring();
    UWB_UI_display();
    delay(100);
}

void UWB_UI_display(){
    if(UI_Init_flag == 0){
      M5.Display.fillScreen(WHITE);
      M5.Display.setCursor(0, 0);
      M5.Display.println("UWB Test");
      M5.Display.println("Base Model");
      const char * current_num = getAnchornNum(Unit_UWB_Anchor);
      M5.Display.printf("Anchor: %s", current_num);
      UI_Init_flag = 1;
    }
    M5.Display.setCursor(0, 80);
    M5.Display.print(Unit_UWB.DATA);
    Serial.println(Unit_UWB.DATA);
}

3. Compile and Upload

  • Download Mode: Different devices need to enter download mode before programming. This step may vary depending on the main controller. For details, refer to the Arduino IDE Getting Started Guide and check the device-specific programming tutorial at the bottom of the page.

  • CoreS3 and AtomS3 share the same programming method: Press and hold the reset button (about 2 seconds) until the internal green LED lights up, then release. The device is now in download mode and ready for programming.

  • Select the device port and click the upload button in the top-left corner of Arduino IDE. Wait for the program to compile and upload to the device.

4. Indoor Ranging

  • Here we use two AtomS3 connected to Unit UWB modules as Anchors, and one CoreS3 connected to Unit UWB module as Tag (note: the distance between Anchor and Tag should preferably be between 5-50m).

  • Tag operation effect:

  • Anchor operation effect:

On This Page