Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ body:
label: Issue checklist
description: Please double-check that you have done each of the following things before submitting the issue.
options:
- label: I searched for previous reports in [the issue tracker](https://github.com/m5stack/M5Stack/issues?q=)
- label: I searched for previous reports in [the issue tracker](https://github.com/m5stack/StackChan-BSP/issues?q=)
required: true
- label: My report contains all necessary details
required: true
12 changes: 6 additions & 6 deletions .github/workflows/clang-format-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ jobs:
strategy:
matrix:
path:
- check: './' # path to include
exclude: '' # path to exclude
#- check: 'src'
# exclude: '(Fonts)' # Exclude file paths containing "Fonts"
#- check: 'examples'
# exclude: ''
# - check: './' # path to include
# exclude: '' # path to exclude
- check: 'src'
exclude: 'src/(utils|drivers)'
- check: 'examples'
exclude: ''

steps:
- name: Checkout
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Product Name
# StackChan

## Overview

### SKU:xxx
### SKU:K151

Description of the product

Expand All @@ -12,7 +12,9 @@ Description of the product

## Required Libraries:

- [Adafruit_BMP280_Library](https://github.com/adafruit/Required_Libraries_Link)
- [M5Unified](https://github.com/m5stack/M5Unified)
- [IRremoteESP8266](https://github.com/crankyoldgit/irremoteesp8266)
- [M5Unit-NFC](https://github.com/m5stack/M5Unit-NFC)

## License

Expand Down
29 changes: 29 additions & 0 deletions examples/INA226/INA226.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
*
* SPDX-License-Identifier: MIT
*/
#include <Arduino.h>
#include <M5StackChan.h>

void setup()
{
/* Init StackChan */
M5StackChan.begin();

/* Setup display */
M5StackChan.Display().setTextSize(2);
M5StackChan.Display().setTextColor(TFT_GREENYELLOW);
M5StackChan.Display().setTextScroll(true);
}

void loop()
{
/* Get battery info from INA226 */
float voltage = M5StackChan.getBatteryVoltage();
float current = M5StackChan.getBatteryCurrent() * 1000;

M5StackChan.Display().printf("> Bat: %0.2fV %0.2fmA\n", voltage, current);

delay(1000);
}
77 changes: 77 additions & 0 deletions examples/IR/Receive/Receive.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
*
* SPDX-License-Identifier: MIT
*/
// More examples on: https://github.com/crankyoldgit/IRremoteESP8266/tree/master/examples
#include <Arduino.h>
#include <M5StackChan.h>
#include <assert.h>
#include <IRrecv.h>
#include <IRremoteESP8266.h>
#include <IRac.h>
#include <IRtext.h>
#include <IRutils.h>

const uint16_t kRecvPin = 10; // IR rx pin

const uint16_t kCaptureBufferSize = 1024;

#if DECODE_AC
// Some A/C units have gaps in their protocols of ~40ms. e.g. Kelvinator
// A value this large may swallow repeats of some protocols
const uint8_t kTimeout = 50;
#else // DECODE_AC
// Suits most messages, while not swallowing many repeats.
const uint8_t kTimeout = 15;
#endif // DECODE_AC

const uint16_t kMinUnknownSize = 12;
const uint8_t kTolerancePercentage = kTolerance; // kTolerance is normally 25%

IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
decode_results results;

void setup()
{
M5StackChan.begin();
Serial.begin(115200);

// Perform a low level sanity checks that the compiler performs bit field
// packing as we expect and Endianness is as we expect.
assert(irutils::lowLevelSanityCheck() == 0);

#if DECODE_HASH
// Ignore messages with less than minimum on or off pulses.
irrecv.setUnknownThreshold(kMinUnknownSize);
#endif // DECODE_HASH
irrecv.setTolerance(kTolerancePercentage); // Override the default tolerance.
irrecv.enableIRIn(); // Start the receiver
}

void loop()
{
// Check if the IR code has been received.
if (irrecv.decode(&results)) {
// Display a crude timestamp.
uint32_t now = millis();
Serial.printf(D_STR_TIMESTAMP " : %06u.%03u\n", now / 1000, now % 1000);
// Check if we got an IR message that was to big for our capture buffer.
if (results.overflow) Serial.printf(D_WARN_BUFFERFULL "\n", kCaptureBufferSize);
// Display the library version the message was captured with.
Serial.println(D_STR_LIBRARY " : v" _IRREMOTEESP8266_VERSION_STR "\n");
// Display the tolerance percentage if it has been change from the default.
if (kTolerancePercentage != kTolerance) Serial.printf(D_STR_TOLERANCE " : %d%%\n", kTolerancePercentage);
// Display the basic output of what we found.
Serial.print(resultToHumanReadableBasic(&results));
// Display any extra A/C info if we have it.
String description = IRAcUtils::resultAcToString(&results);
if (description.length()) Serial.println(D_STR_MESGDESC ": " + description);
yield(); // Feed the WDT as the text output can take a while to print.
// Output the results as source code
Serial.println(resultToSourceCode(&results));
Serial.println(); // Blank line between entries
yield(); // Feed the WDT (again)
}
delay(50);
}
47 changes: 47 additions & 0 deletions examples/IR/Send/Send.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
*
* SPDX-License-Identifier: MIT
*/
// More examples on: https://github.com/crankyoldgit/IRremoteESP8266/tree/master/examples
#include <Arduino.h>
#include <M5StackChan.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>

const uint16_t kIrLed = 5; // IR tx pin

IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message.

// Example of data captured by IRrecvDumpV2.ino
uint16_t rawData[67] = {9000, 4500, 650, 550, 650, 1650, 600, 550, 650, 550, 600, 1650, 650, 550,
600, 1650, 650, 1650, 650, 1650, 600, 550, 650, 1650, 650, 1650, 650, 550,
600, 1650, 650, 1650, 650, 550, 650, 550, 650, 1650, 650, 550, 650, 550,
650, 550, 600, 550, 650, 550, 650, 550, 650, 1650, 600, 550, 650, 1650,
650, 1650, 650, 1650, 650, 1650, 650, 1650, 650, 1650, 600};
// Example Samsung A/C state captured from IRrecvDumpV2.ino
uint8_t samsungState[kSamsungAcStateLength] = {0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0,
0x01, 0xE2, 0xFE, 0x71, 0x40, 0x11, 0xF0};

void setup()
{
M5StackChan.begin();
Serial.begin(115200);
irsend.begin();
}

void loop()
{
Serial.println("NEC");
irsend.sendNEC(0x00FFE01FUL);
delay(2000);
Serial.println("Sony");
irsend.sendSony(0xa90, 12, 2); // 12 bits & 2 repeats
delay(2000);
Serial.println("a rawData capture from IRrecvDumpV2");
irsend.sendRaw(rawData, 67, 38); // Send a raw data capture at 38kHz.
delay(2000);
Serial.println("a Samsung A/C state from IRrecvDumpV2");
irsend.sendSamsungAC(samsungState);
delay(2000);
}
75 changes: 75 additions & 0 deletions examples/NFC/Detect/Detect.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
*
* SPDX-License-Identifier: MIT
*/
// More examples on: https://github.com/m5stack/M5Unit-NFC/tree/main/examples
#include <Arduino.h>
#include <M5StackChan.h>
#include <M5UnitUnified.h>
#include <M5UnitUnifiedNFC.h>
#include <M5Utility.h>
#include <vector>

using namespace m5::nfc::a;

namespace {
auto& lcd = M5.Display;
m5::unit::UnitUnified Units;
m5::unit::UnitNFC unit{}; // I2C
m5::nfc::NFCLayerA nfc_a{unit};
} // namespace

void setup()
{
M5StackChan.begin();

if (!Units.add(unit, M5.In_I2C) || !Units.begin()) {
M5_LOGE("Failed to begin");
lcd.clear(TFT_RED);
while (true) {
m5::utility::delay(10000);
}
}
M5_LOGI("M5UnitUnified has been begun");
M5_LOGI("%s", Units.debugInfo().c_str());

if (lcd.width() < lcd.height()) {
lcd.setRotation(1);
}
lcd.setFont(&fonts::Font0);
lcd.fillScreen(0);
lcd.setCursor(0, 0);
}

void loop()
{
M5StackChan.update();
Units.update();

std::vector<PICC> piccs;
if (nfc_a.detect(piccs)) {
lcd.fillScreen(0);
lcd.setCursor(0, 0);
uint16_t idx{};
for (auto&& u : piccs) {
M5.Speaker.tone(6000, 5);
// detect only performs a provisional classification based on sak, so further identification is required
if (nfc_a.identify(u)) {
M5.Log.printf("PICC:%s %s %04X/%02X %u/%u\n", u.uidAsString().c_str(), u.typeAsString().c_str(), u.atqa,
u.sak, u.userAreaSize(), u.totalSize());
lcd.printf("[%2u]:PICC:<%s> %s\n", idx, u.uidAsString().c_str(), u.typeAsString().c_str());
++idx;
} else {
M5_LOGW("Failed to identify %s %s %04X/%02X %u/%u", u.uidAsString().c_str(), u.typeAsString().c_str(),
u.atqa, u.sak, u.userAreaSize(), u.totalSize());
}
}
if (idx) {
M5.Speaker.tone(3000, 10);
lcd.printf("==> %u PICC\n", idx);
M5.Log.printf("==> %u PICC\n", idx);
}
nfc_a.deactivate();
}
}
Loading
Loading