The Ultra-Compact Powerhouse for LoRa Debugging and Connectivity

Similar projects worth following
Next-gen USB LoRa debug tool. Runs mainline Linux on itself. Versatile JavaScript ES2015 interface allows access to every SX126x chip register easily. Up to 4GB flash storage allows long-time data collection. Works with any modern PC.


The LoShark is a USB key-sized device, designed with a keen focus on offering robust LoRa connectivity and debugging capabilities. It's engineered to operate both independently and in conjunction with a PC, opening up a versatile range of use-cases.

Video demo:

The software and design files are available in our GitHub repo.

Interested in getting one? Please visit our store.

Key Features

Compact and Portable Design

Designed with a USB key form factor, LoShark can be easily plugged into a PC or operate independently when connected to a USB power bank. This design provides unparalleled convenience and portability. It also has a nice plastic enclosure.

▲ PCB of the LoShark. Our X1501 Pico SoM is near the USB port. The HJ-68LR SiP is near the SMA port.

▲ LoShark connected to a mini laptop. A perfect combo for outdoors LoRa testing.

JavaScript Programmability with Resonance

The LoShark's primary strength is its ability to execute JavaScript (ES2015) through our runtime, Resonance. It's still in alpha state, and it will be open sourced with a free software license soon later. You can join our Discord for alpha testing at this moment.

This feature enables users to program specific tasks, serving as a powerful tool for LoRa debugging, such as capturing packets and sending LoRa messages either manually or programmatically, at minimal delay.

▲ Demo JavaScript application for the LoShark

▲ Interacting with the Semtech SX126x chip directly in a NodeJS-like console

Linux Support

The LoShark runs mainline Linux, allowing users to write bare bone Linux applications in C and C++. It's possible to expand the device's capabilities far beyond its size with careful programming.

▲ Linux is running inside the LoShark

Memory and Storage

With 8MB of DRAM, 8MB of PSRAM, and additional flash storage starting from 128MB to a maximum of 4GB, LoShark packs a punch in memory capacity for its size. This is very useful for data collection tasks, such as logging every received LoRa packet, alongside with the signal status and time.

▲Transferring files between LoShark and PC is made easy with the MTP protocol

Energy Efficient

LoShark operates at a low power consumption of 150mW while plugged into a PC and not transmitting, making it an energy-efficient solution for your LoRa needs.

▲ Power consumption of the LoShark. It can be further reduced by turning off the bright RGB LED.

X1501 Pico SoM

Featuring our X1501 Pico System on Module (SoM), the LoShark is powered by a MIPS32r2 RISC processor, with a full-featured hardware FPU, enabling users to implement complex algorithms without worrying about performance, such as audio codecs like Codec2 and Opus, and software-based error correction codes such as DSSS and LDPC.

▲ LoShark is capable of encoding 320kbps stereo Opus audio at 2.5x realtime speed

Standard SMA Socket

LoShark uses a standard SMA-F socket for RF connectivity, allowing users to easily swap antennas or connect to a power amplifier.

▲ LoShark and different compatible antennas

Real-Time Clock

The device includes an RTC, holding time configurations for at least 2 days, perfect for configuring on a PC and then operating separately with a power bank.

Programmable RGB LED Indicator

The device includes a programmable RGB LED indicator accessible via I2C, providing visible feedback and status indications to the user.

▲ LoShark doing data collection to its internal flash storage while being powered by a power bank

Adobe Portable Document Format - 478.25 kB - 07/28/2023 at 23:32


Adobe Portable Document Format - 334.59 kB - 07/28/2023 at 23:32


  • 1 × SudoMaker X1501 Pico SoM
  • 1 × HJSIP HJ-68LR
  • 1 × EPSON RX8900CE
  • 1 × Lyontek LY68L6400SLIT
  • 1 × AWINIC AW2023DNR

  • Some API changes

    Reimu NotMoe08/10/2023 at 23:35 0 comments

    After some careful thinking, I changed the JS API of Resonance a bit:

    • loadModule() now follows the naming convention of nodejs modules
    • Peripheral drivers are now split from the core of Resonance and moved to separate modules
    • Use Promise for async APIs where possible

    So now the LoShark example code looks likes this:

    // X1501 EVB
    const {SX126x} = loadModule("loshark/sx126x");
    const {GPIOControllerLinux} = loadModule("gpio/linux");
    const {SPIControllerLinux} = loadModule("spi/linux");
    const gpioa = new GPIOControllerLinux(0);
    const pa12 =, "SX126x NRST");
    const pa13 =, "SX126x DIO2");
    const pa14 =, "SX126x DIO1");
    const pa15 =, "SX126x BUSY");
    const spi0 = new SPIControllerLinux(0);
    const spidev0_3 =;
    const cfg = {
      chip: "SX1268",
      tcxo: { voltage: 0x2, timeout: 32 },
      gpio: { reset: pa12, busy: pa15, dio1: pa14, dio2: pa13 },
      spi: spidev0_3,
    mdm = new SX126x(cfg);
    mdm.on("receive", msg => console.log("packet received:", msg));
    mdm.on("signal", sig => console.log("signal:", sig));
    mdm.on("event", ev => console.log("event:", ev));"modem opened"));
    mdm.propertySet("", 62).then(console.log);
    mdm.transmit('Bonjour mes reufs').then(console.log);

    You can use the await keyword in async functions in .js files.

    Suggestions are welcomed.

  • LoShark DO run the mainline Linux kernel

    Reimu NotMoe08/02/2023 at 19:06 0 comments

    As of 2023-08-02, this comment appeared below the CNX software article. It appears to be from a upstream Linux maintainer.

    And here are my responses:

    • X1501 DO boot the latest 6.5-rc4 kernel using the X1000 target
    • It's not our fault as fixes & new drivers of the X1000/X1501 can't be mainlined
    • X1501 can't run systemd but it's still awesome with its 18mW standby power usage
    • A PSRAM is not a NOR flash

    LoShark (tested on X1501 EVB with LoShark's rootfs) running the latest rc kernel (with X1000 as target):

    This is the complete boot log. Many things are broken, as expected. But you get a working shell.
    X-Loader Build: 2023-06-28 - 19:08:31
    EPC: 0x80101c24
    stage2 inited
    uImage name: Linux-6.5.0-rc4-LoShark+
    uImage size: 1020740
    uImage load addr: 80100000
    uImage endpoint addr: 8030cff4
    Jumping to 8030cff4
    [    0.000000] Linux version 6.5.0-rc4-LoShark+ (root@Rinyuki-Laptop) (mipsel-linux-gnu-gcc (Ubuntu 9.4.0-1ubuntu1~20.04) 9.4.0, GNU ld (GNU Binutils for Ubuntu) 2.34) #11 PREEMPT Thu Aug  3 04:13:47 CST 2023
    [    0.000000] CPU0 revision is: 2ed1024f (Ingenic XBurst)
    [    0.000000] FPU revision is: 00330000
    [    0.000000] MIPS: machine is YSH & ATIL General Board CU1000-Neo
    [    0.000000] earlycon: x1000_uart0 at MMIO 0x10032000 (options '115200n8')
    [    0.000000] printk: bootconsole [x1000_uart0] enabled
    [    0.000000] **********************************************************
    [    0.000000] **                                                      **
    [    0.000000] ** This system shows unhashed kernel memory addresses   **
    [    0.000000] ** via the console, logs, and other interfaces. This    **
    [    0.000000] ** might reduce the security of your system.            **
    [    0.000000] **                                                      **
    [    0.000000] ** If you see this message and you are not debugging    **
    [    0.000000] ** the kernel, report this immediately to your system   **
    [    0.000000] ** administrator!                                       **
    [    0.000000] **                                                      **
    [    0.000000] **********************************************************
    [    0.000000] User-defined physical RAM map overwrite
    [    0.000000] Initrd not found or empty - disabling initrd
    [    0.000000] Primary instruction cache 16kB, VIVT, 4-way, linesize 32 bytes.
    [    0.000000] Primary data cache 16kB, 4-way, VIPT, no aliases, linesize 32 bytes
    [    0.000000] MIPS secondary cache 128kB, 4-way, linesize 128 bytes.
    [    0.000000] Zone ranges:
    [    0.000000]   Normal   [mem 0x0000000000000000-0x00000000007fffff]
    [    0.000000] Movable zone start for each node
    [    0.000000] Early memory node ranges
    [    0.000000]   node   0: [mem 0x0000000000000000-0x00000000007fffff]
    [    0.000000] Initmem setup node 0 [mem 0x0000000000000000-0x00000000007fffff]
    [    0.000000] Kernel command line: console=ttyS2@115200n8 earlycon mem=8M@0x0 loglevel=7 devtmpfs.mount=1 clk_ignore_unused no_hash_pointers
    [    0.000000] Dentry cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
    [    0.000000] Inode-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
    [    0.000000] Built 1 zonelists, mobility grouping off.  Total pages: 2032
    [    0.000000] mem auto-init: stack:off, heap alloc:off, heap free:off
    [    0.000000] Memory: 4812K/8192K available (2122K kernel code, 141K rwdata, 220K rodata, 644K init, 86K bss, 3380K reserved, 0K cma-reserved)
    [    0.000000] SLUB: HWalign=32, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
    [    0.000000] rcu: Preemptible hierarchical RCU implementation.
    [    0.000000] rcu: RCU calculated value of scheduler-enlistment delay is 100 jiffies.
    [    0.000000] NR_IRQS: 256
    [    0.000000] rcu: srcu_init: Setting srcu_struct sizes based on contention.
    [    0.000000] clocksource: ingenic-ost: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1274173631191 ns
    [    0.000003] sched_clock: 32 bits at 1500kHz, resolution 666ns, wraps every 1431655764658ns
    [    0.008517] Calibrating delay loop... 1002.49 BogoMIPS (lpj=501248)
    [    0.022791] pid_max: default: 4096 minimum: 301
    [    0.033908] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes, linear)
    [ 0.041296] Mountpoint-cache hash table entries: 1024 (order:...
    Read more »

View all 2 project logs

Enjoy this project?



Reimu NotMoe wrote 08/10/2023 at 17:44 point

Replying to aaaaaa:


  Are you sure? yes | no

sup wrote 08/09/2023 at 13:39 point

please add small screen and buttons

Not every person has a computer with them in an emergency situation. 5 or 10 keys is probably not a problem. The power consumption of the screen (which can be turned off without turning off the device) can be a problem I think.

  Are you sure? yes | no

Reimu NotMoe wrote 08/09/2023 at 18:13 point

Thanks for your suggestion. We have another project called the Wireless Terminal. It's a standalone LoRa handheld with T9 keypad and long battery life.

  Are you sure? yes | no

aaaaaa wrote 08/13/2023 at 18:56 point

I no need info from you

  Are you sure? yes | no

Reimu NotMoe wrote 08/04/2023 at 20:29 point

Replying to aaaaaa:

I don't know how much RAM is needed by mruby, so I can't answer this question.

The Resonance runtime is hybrid C++ and JavaScript. Identical APIs are provided in both languages. It will be released on GitHub in a week or so.

Since the LoShark runs Linux, you can just use standard GCC toolchain to cross compile your stuff and access everything with POSIX and Linux APIs. Just like on a Linux PC (but keep in mind it only has 8MB RAM).

  Are you sure? yes | no

aaaaaa wrote 08/10/2023 at 09:32 point (You probably no needed module, only object)

ruby is simplest than javascript ,and fast

  Are you sure? yes | no

zyndram wrote 08/04/2023 at 13:56 point

1. Is possible install program on it? for example meshtastic or python RNode reticullum?

2. Is any C library ? I need ruby gem or python pip

  Are you sure? yes | no

Reimu NotMoe wrote 08/04/2023 at 15:53 point

The only limiting factor is 8MB RAM and everything else is the same as other Linux SBCs. You can select various software in buildroot or build them by yourself.

  Are you sure? yes | no

aaaaaa wrote 08/04/2023 at 17:18 point

mruby can run on it (pyton too)

question is C compiler and library in C to controle device.

library is only in JS, no in C?

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates