Atom发送红外编码(二)-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2123|回复: 0

Atom发送红外编码(二)

[复制链接]
发表于 2020-5-8 15:33 | 显示全部楼层 |阅读模式
本帖最后由 vany5921 于 2020-5-8 15:55 编辑

在上一篇中讲解了如何收发红外遥控,我们不得不通过串口监视器了解当前状态,同时一旦我们断电,我们学习的编码因为无法保存而丢失。为了解决这些问题我们对之前的代码进行补充,通过AtomMatrix的LED进行显示,并存储学习后的红外编码
====创建LED显示==========================================
我创建了三个学习遥控器的指示:1.尚未学习接收遥控信号的状态 2.等待接收遥控信号 3.学习遥控信号后等待发送
我们可以通过AtomPixelTool进行创建,下载连接https://github.com/m5stack/M5Atom
当启动AtomPixelTool后,将会有如下显示
b0ea2e34686e58e81d18459892833c9a.png
右侧是5x5的矩阵,通过修改左侧的H和W来修改垂直和水平的显示像素数。我设置为水平15像素,垂直5像素
8e3cef98109e041bdd631327e5cbc162.png
点击工具并选择保存,生成的发光数据将以c文件的形式导出
[mw_shl_code=arduino,true]
// File URLC:/Users/iCloudDrive/mp3/IRremoteLED.c
// Image Size: width=15,height=5
// Data  Size: 227
const unsigned char image_IRremoteLED[227]=
{
/* width  015 */ 0x0f,
/* height 005 */ 0x05,
/* Line   000 */ 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x55,0xff,0x7f, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xff,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line   001 */ 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xff,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line   002 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x55,0xff,0xff, 0x55,0xff,0xff, 0x00,0xff,0xff, 0x55,0xff,0xff, 0x00,0xff,0xff, //
/* Line   003 */ 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0xff,0xff, 0x00,0xff,0xff, 0x00,0xff,0xff, 0x00,0x00,0x00, //
/* Line   004 */ 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x55,0xff,0x7f, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xff,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
};[/mw_shl_code]
查看输出文件,它是一个一维数组,第一元素是宽度,第二元素是高度,第三元素是RGB的值,每个像素都有RGB三个元素,数组元素总个数为1+1+15x5x3 = 227
屏幕上的一行对应数组里的一行,通过Line xxx可以查看一行中包含的数据
void displaybuff(uint8_t *buffptr, int8_t offsetx = 0, int8_t offsety = 0)用于LED的显示,buffptr是图像数据的数组。offsetx和offsety是偏移位置,例如
图像数据数组是
matrix-data-1.png
displaybuf((uint8_t*)image_IRremoteLED, 0, 0)会显示
matrix2.png
displaybuf((uint8_t*)image_IRremoteLED, -5, 0)将显示
matrix3.png
接下来将我们上节的代码插入灯光
[mw_shl_code=arduino,true]#define FASTLED_INTERNAL
#include <M5Atom.h>
#include <IRrecv.h>
#include <IRremoteESP8266.h>
#include <IRac.h>
#include <IRtext.h>
#include <IRutils.h>

// Select IR_LED in M5Atom or M5Stack IR Unit
#define IR_LED 12  // IR LED in M5Atom
//#define IR_LED 26  // IR LED in the M5Stack IR Unit

// ============ IRremoteESP8266 TUNEABLE PARAMETERS ================
const uint16_t kRecvPin = 32;
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
// =================================================================

IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, true);
decode_results results;  // Somewhere to store the results
IRsend irsend(IR_LED);

uint16_t *rawData;        // IR message container
uint16_t dataLength = 0;  // IR message length

const unsigned char image_IRremoteLED[227]=
{
/* width  015 */ 0x0f,
/* height 005 */ 0x05,
/* Line   000 */ 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x55,0xff,0x7f, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xff,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line   001 */ 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xff,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line   002 */ 0x00,0x00,0x00, 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x55,0xff,0xff, 0x55,0xff,0xff, 0x00,0xff,0xff, 0x55,0xff,0xff, 0x00,0xff,0xff, //
/* Line   003 */ 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0xff,0xff, 0x00,0xff,0xff, 0x00,0xff,0xff, 0x00,0x00,0x00, //
/* Line   004 */ 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0xf0,0x14,0xff, 0x00,0x00,0x00, 0x55,0xff,0x7f, 0x55,0xff,0x7f, 0x55,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xff,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
};

void setup() {
  M5.begin(true, false, true); // SerialEnable = true, I2CEnable = false, DisplayEnable = true);
  Serial.printf("\n\n### IR Remote Controller ###\n");
  Serial.printf("IR Sensor Pin Number =%d \n", kRecvPin);
  irrecv.setUnknownThreshold(kMinUnknownSize);
  irsend.begin();
  M5.dis.displaybuff((uint8_t*)image_IRremoteLED, 0, 0);
}

void loop() {
  M5.update();
  if (M5.Btn.wasReleased()) {
    Serial.print("Button wasReleased(): ");
    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.Btn.pressedFor(300)) {
    irrecv.enableIRIn();
    Serial.println("M5.Btn.pressedFor(300): waiting for IR signal");
    M5.dis.displaybuff((uint8_t*)image_IRremoteLED, -10, 0);
    while (! M5.Btn.wasReleased()) {
      delay(50);
      M5.update();
    }
  } else {
    if (irrecv.decode(&results)) {
      irrecv.disableIRIn();
      if (results.overflow)
        Serial.printf(D_WARN_BUFFERFULL "\n", kCaptureBufferSize);
      rawData = resultToRawArray(&results);
      dataLength = getCorrectedRawLength(&results);
      Serial.printf("rawData[%d] : ", dataLength);
      for (int i = 0; i < dataLength; i++) {
        Serial.printf("%d, ", rawData);
      }
      Serial.println();
      M5.dis.displaybuff((uint8_t*)image_IRremoteLED, -5, 0);
    }
  }
}[/mw_shl_code]

====SPIFFS存储==============================================
SPIFFS(SPI Flash文件系统)是一个库,允许用户将数据保存到flash中。我们可以通过查看ArduinoIDE中的SPIFFS示例来了解。
a388e82b10ab78b934e7ee0603858266.png 6db6189ebfcf370d65c512eb86c55c35-1.png
要使用SPIFFS,必须先装载文件系统。上述程序中第162行的SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)是其中一部分,如果首次使用SPIFFS,需要进行格式化操作。当begin参数为true,则进行格式化操作。第40行到第70行是读取和写入文件的示例。
操作步骤
・将SPIFFS中存储文件的完整路径定义为/irdata。

・作为LED上显示的图形,添加显示图案。
・准备一个数组保存红外数据。
・在setup()中进行以下操作
・挂载SPIFFS。挂载时执行格式后会等待10秒左右,因此,显示一个表示初始化的图案。

・试着从SPIFFS内的/irdata文件向RAM读入遥控信号。
・读取成功后,在LED上显示圆圈,读取失败后在LED上显示叉。
・在loop()内进行下述操作
・点击按钮后
・如果是等待遥控器信号接收的状态,则解除等待状态,删除SPIFFS内的文件,在LED上显示叉。
・在通常的状态下,并且如果有遥控信号数据则发送。
・长按按钮的话
・在LED上显示下箭头,进入等待接收状态

・收到遥控信号后
・取出接收到的遥控信号数据写入RAM
・将写入RAM中的遥控信号数据写入SPIFFS
・在LED上显示圆圈。


最终代码
[mw_shl_code=arduino,true]#define FASTLED_INTERNAL
#include <M5Atom.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"

// Select IR_LED in M5Atom or M5Stack IR Unit
#define IR_LED 12  // IR_LED in M5Atom
//#define IR_LED 26  // IR_LED in the M5Stack IR Unit

// ============ IRremoteESP8266 Tunable Parameters ================
const uint16_t kRecvPin = 32;
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;

const unsigned char matrix_image[302]=
{
/* width  020 */ 0x14,
/* height 005 */ 0x05,
/* Line   000 */ 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0x00,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0xff,0x00,0xff, 0x00,0x00,0x00, 0x00,0xff,0x00, 0x00,0xff,0x00, 0x00,0xff,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x55,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line   001 */ 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0x00,0x00,0x00, 0xff,0x00,0xff, 0x00,0x00,0x00, 0xff,0x00,0xff, 0x00,0x00,0x00, 0x00,0xff,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xff,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x55,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
/* Line   002 */ 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0x00,0x00,0x00, 0x00,0x00,0x00, 0xff,0x00,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xff,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xff,0x00, 0x00,0x55,0xff, 0x00,0x55,0xff, 0x00,0x55,0xff, 0x00,0x55,0xff, 0x00,0x55,0xff, //
/* Line   003 */ 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0x00,0x00,0x00, 0xff,0x00,0xff, 0x00,0x00,0x00, 0xff,0x00,0xff, 0x00,0x00,0x00, 0x00,0xff,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0xff,0x00, 0x00,0x00,0x00, 0x00,0x55,0xff, 0x00,0x55,0xff, 0x00,0x55,0xff, 0x00,0x00,0x00, //
/* Line   004 */ 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0xff,0x7f, 0xff,0x00,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0xff,0x00,0xff, 0x00,0x00,0x00, 0x00,0xff,0x00, 0x00,0xff,0x00, 0x00,0xff,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x00,0x00, 0x00,0x55,0xff, 0x00,0x00,0x00, 0x00,0x00,0x00, //
};

void setup() {
  M5.begin(true, false, true); //SerialEnable = true, I2CEnable = false, DisplayEnable = 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....");
  M5.dis.displaybuff((uint8_t*)matrix_image, 0, 0);
  SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED); // activate SPIFFS
  Serial.println("Done.");
  readRawDataFromSPIFFS(); // read data if available

  if (dataLength > 0) {
    M5.dis.displaybuff((uint8_t*)matrix_image, -10, 0);
  } else {
    M5.dis.displaybuff((uint8_t*)matrix_image, -5, 0);
  }
}

void loop() {
  M5.update();
  if (M5.Btn.wasReleased()) {
    Serial.print("Button wasReleased(): ");
    if (receiving) {
      irrecv.disableIRIn();
      receiving = false;
      deleteRawDataInSPIFFS();
      dataLength = 0;
      M5.dis.displaybuff((uint8_t*)matrix_image, -5, 0);
    } 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.Btn.pressedFor(300)) {
    irrecv.enableIRIn();
    receiving = true;
    Serial.println("M5.Btn.pressedFor(500): waiting for IR signal");
    M5.dis.displaybuff((uint8_t*)matrix_image, -15, 0);
    while (! M5.Btn.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 = rawData_tmp;
        Serial.printf("%d, ", rawData);
      }
      delete[] rawData_tmp;
      Serial.println();
      writeRawDataToSPIFFS();
      M5.dis.displaybuff((uint8_t*)matrix_image, -10, 0);
      yield();             // Feed the WDT (again)
    }
  }
}

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 = file.read();
    Serial.printf("%d ", rawData8);
    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");
  }
}[/mw_shl_code]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 02:34 , Processed in 0.076501 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表