前回の記事M5Stack Atomで赤外線リモコンを作る(6)学習結果をフラッシュメモリに覚えるで完成した学習リモコンプログラムをM5StickCに移植してみました。
プログラムの変更
主な変更ポイントは次の通りです。
- <M5Atom.h>の代わりに<M5StickC.h>をinclude
- 赤外線LEDのGPIOピン番号を9に変更
- 赤外線受信センサーのGPIOピン番号を33に変更
- ボタン操作部をBtnからBtnAに変更
- LED Matrixに表示している部分をLCDへの文字表示に変更
変更後のプログラムはこうなりました。
#include <M5StickC.h>
//=== IRremoteESP8266 files
#include <IRrecv.h>
#include <IRremoteESP8266.h>
#include <IRac.h>
#include <IRtext.h>
#include <IRutils.h>
//=== SPIFFS files
#include "FS.h"
#include "SPIFFS.h"
#define IR_LED 9 // IR_LED in M5StickC
// ============ IRremoteESP8266 Tunable Parameters ================
const uint16_t kRecvPin = 33;
const uint32_t kBaudRate = 115200;
const uint16_t kCaptureBufferSize = 1024;
#if DECODE_AC
const uint8_t kTimeout = 50;
#else // DECODE_AC
const uint8_t kTimeout = 15;
#endif // DECODE_AC
const uint16_t kMinUnknownSize = 12;
#define LEGACY_TIMING_INFO false
//=== SPIFFS parameters
#define FORMAT_SPIFFS_IF_FAILED true
const char *FILE_NAME = "/irdata";
//== instances for receiving and sending IR messages
IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
decode_results results; // Somewhere to store the results
IRsend irsend(IR_LED);
//== IR message container
#define BUFFER_SIZE 1024
uint16_t rawData[BUFFER_SIZE]; // IR message container
uint16_t dataLength = 0; // IR message length
//== variable for remembering mode
bool receiving = false;
void setup() {
M5.begin(true, true, true); //LCDEnable = true, PowerEnable = true, SerialEnable = true
Serial.printf("\n\n### IR Remote Controller ###\n");
Serial.printf("IR Sensor Pin Number =%d \n", kRecvPin);
irrecv.setUnknownThreshold(kMinUnknownSize);
irsend.begin();
Serial.print("Initializeing SPIFFS....");
showMessage("INITIALIZING");
SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED); // activate SPIFFS
Serial.println("Done.");
readRawDataFromSPIFFS(); // read data if available
showStatus();
}
void loop() {
M5.update();
if (M5.BtnA.wasReleased()) {
Serial.print("Button wasReleased(): ");
if (receiving) {
irrecv.disableIRIn();
receiving = false;
deleteRawDataInSPIFFS();
dataLength = 0;
showStatus();
} else if (dataLength > 0) {
Serial.printf("send rawData[%d]\n", dataLength);
irsend.sendRaw(rawData, dataLength, 38);
} else {
Serial.println("rawData[] is empty. Skip sending");
}
} else if (M5.BtnA.pressedFor(300)) { // 長押しなら赤外線信号を受信モードに遷移し、↓(下矢印)を表示
irrecv.enableIRIn();
receiving = true;
Serial.println("M5.Btn.pressedFor(500): waiting for IR signal");
showStatus();
while (! M5.BtnA.wasReleased()) { // ボタンが離されるまで待つ
delay(50);
M5.update();
}
} else { // 赤外線信号を受信していたら、信号を配列に格納し、○を表示する。
if (irrecv.decode(&results)) {
uint16_t *rawData_tmp;
irrecv.disableIRIn();
receiving = false;
if (results.overflow)
Serial.printf(D_WARN_BUFFERFULL "\n", kCaptureBufferSize);
rawData_tmp = resultToRawArray(&results);
dataLength = getCorrectedRawLength(&results);
Serial.printf("rawData[%d] : ", dataLength);
for (int i = 0; i < dataLength; i++) {
rawData[i] = rawData_tmp[i];
Serial.printf("%d, ", rawData[i]);
}
delete[] rawData_tmp;
Serial.println();
writeRawDataToSPIFFS();
showStatus();
}
}
}
void readRawDataFromSPIFFS() {
Serial.printf("reading rawData from SPIFF file: %s \n", FILE_NAME);
fs::FS fs = SPIFFS;
File file;
if (fs.exists(FILE_NAME)) {
file = fs.open(FILE_NAME);
} else {
Serial.printf("file \"%s\" not found in SPIFFS\n", FILE_NAME);
return;
}
int i = 0;
uint8_t *rawData8 = (uint8_t *)rawData;
while (file.available()) {
rawData8[i] = file.read();
Serial.printf("%d ", rawData8[i]);
i++;
}
Serial.println();
dataLength = i / 2;
file.close();
Serial.printf("dataLength = %d\n", dataLength);
for (int j = 0; j < dataLength; j++) {
Serial.printf("%d", rawData[j]);
Serial.print(" ");
}
Serial.println("done");
}
void writeRawDataToSPIFFS() {
fs::FS fs = SPIFFS;
Serial.println("writing data to SPIFF");
File file = fs.open(FILE_NAME, FILE_WRITE);
file.write((uint8_t *)rawData, dataLength * 2);
file.close();
Serial.println("done");
}
void deleteRawDataInSPIFFS() {
Serial.printf("Deleting rawData in SPIFFS: %s\r\n", FILE_NAME);
fs::FS fs = SPIFFS;
if (fs.remove(FILE_NAME)) {
Serial.println("- file deleted");
} else {
Serial.println("- deletion failed");
}
}
void showStatus() {
const char *message;
if (receiving) {
message = "RECEIVING";
} else {
if (dataLength > 0) {
message = "READY";
} else {
message = "NO DATA";
}
}
showMessage(message);
}
void showMessage(const char *message) {
M5.Lcd.fillScreen(BLACK);
M5.Lcd.setRotation(1);
M5.Lcd.setTextFont(4);
M5.Lcd.setTextColor(BLUE);
M5.Lcd.setCursor(27, 0);
M5.Lcd.print("IR Remote");
M5.Lcd.setCursor(27, 40);
M5.Lcd.print(message);
}