【转载】基于M5StickC的智能马桶遥控器
智能马桶是个好东西,上面有各种各样舒服的功能,通常配有一个遥控器,为了以防遥控器哪天坏掉又没法单独配,利用M5StickC来提前做一个遥控器备份。由于M5StickC只具备IR发射功能,因此使用IR unit先来对遥控器编码进行读取,通过IRremote8266这个库找到IRrecvDumpV2这个示例,先按示例获取到遥控码,再通过sendRaw进行发送。运行环境准备:
M5StickC
[*]Arduino 1.8.10
[*]ESP32 Arduino 1.0.4
[*]M5StickC 0.1.0
[*]IRremoteESP8266 2.6.6
马桶型号
[*]TOTO NEOREST AH3
遥控信号
以下信号数据是对实际遥控信号的分析。按下按钮时,每个信号重复发送3次。
功能信号1信号2注
马桶盖开关0x2008000E0E-
坐垫开关0x200800F6F6-
大0x200800B0B0-
小0x2008008888-
eco 小0x200800B6B6-
臀洗0x20080060600x2008AC802C注1、2
轻柔0x20080060600x2008ACA804注1、2
冲洗0x20080010100x2008AC40EC注1、2
停止0x20080000000x2008AADA70注1
按摩0x200800E0E0-
干燥0x200800C0C0
-
注3
去臭0x2008007C7C-
注1:“ 臀洗 / 轻柔 /冲洗/ 停止”按钮输出两种信号:“ Move On / Off”和“ Wash”。注2:实际的遥控器处于一种状态,如果在洗涤停止时按“臀洗/轻柔/冲洗”,则仅发送信号2(洗涤),而在洗涤时按信号,则发送信号1(“移动开/关”)。信号2(清洁)都被发送,并且由于该实施方式没有实际问题,所以信号1和信号2都总是被发送。
注3:遥控器还具有干燥状态,如果在干燥过程中再次按下“干燥”按钮,将发送与“停止”相同的信号。
实例
连接了连接到M5StickC的IR REMOTE单元以进行遥控器的红外信号分析,使用接收针脚编号33执行IRrecvDumpV2
远程控制程序将发送信号作为菜单显示在屏幕上,并通过按钮操作进行选择和发送。
使用按钮B /电源按钮前进/返回菜单项
使用按钮A发送选择的信号
M5StickC程序
#include <M5StickC.h>
#include <Arduino.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
const uint16_t kIrLed = 9;// M5StickC GPIO pin to use.
IRsend irsend(kIrLed);// Set the GPIO to be used to sending the message.
// IR Data for TOTO Washlet Neorest AH3
struct {
std::string name;
uint64_t data1;
uint64_t data2;
} ir_data[] = {
{"Op/Cl Lid",0x2008000E0E, 0}, // Open Close Lid
{"Op/Cl Seat", 0x200800F6F6, 0}, // Open Close Seat
{"Full Flush", 0x200800B0B0, 0}, // Full Flush
{"Half Flush", 0x2008008888, 0}, // Half Flush
{"eco Flush",0x200800B6B6, 0}, // eco Half Flush
{"Wash Rear",0x2008006060, 0x2008AC802C}, // move on/off + Wash Rear
{"Soft Rear",0x2008006060, 0x2008ACA804}, // move on/off + Soft Rear
{"Bidet", 0x2008001010, 0x2008AC40EC}, // move on/off + Bidet
{"Stop", 0x2008000000, 0x2008AADA70}// move off + Stop Wash
};
int data_count = sizeof(ir_data) / sizeof(ir_data);
int ix = 0;
int x_offset0 =3;
int x_offset1 =5;
int x_offset2 = 15;
int y_offset1 = 12;
int y_offset2 = 30;
int height = 14;
void sendToto(uint64_t data) {
irsend.sendGeneric(
6000,3000, // headermark, headerspace,
600, 1600, // onemark, onespace,
600, 600, // zeromark, zerospace,
600,40000, // footermark, gap,
data, 39, // data, nbits,
38, true, // frequency,MSBfirst,
2, kDutyDefault); // repeat, dutycycle (kDutyDefault = 50 %)
}
void setup() {
M5.begin();
irsend.begin();
M5.Axp.ScreenBreath(9); // Brightness (7-15)
M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
M5.Lcd.drawString("<< Washlet >>", x_offset0, y_offset1);
M5.Lcd.setTextColor(TFT_ORANGE, TFT_BLACK);
M5.Lcd.drawString(">", x_offset1, y_offset2);
M5.Lcd.drawString(ir_data.name.c_str(), x_offset2, y_offset2);
M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
for (int i = 1; i < data_count; i ++) {
M5.Lcd.drawString(ir_data.name.c_str(), x_offset2, y_offset2 + i * height);
}
}
void loop() {
M5.update();
if (M5.BtnA.wasPressed()) {
Serial.println(ir_data.name.c_str());
sendToto(ir_data.data1);
if (ir_data.data2 != 0) {
delay(40);
sendToto(ir_data.data2);
}
}
if (M5.BtnB.wasPressed() || M5.Axp.GetBtnPress() > 0) {
M5.Lcd.setTextColor(TFT_BLACK, TFT_BLACK);
M5.Lcd.drawString(">",x_offset1, y_offset2 + ix * height);
M5.Lcd.setTextColor(TFT_WHITE, TFT_BLACK);
M5.Lcd.drawString(ir_data.name.c_str(), x_offset2, y_offset2 + ix * height);
if (M5.BtnB.wasPressed()) {
ix ++;
if (ix == data_count) {
ix = 0;
}
} else {
ix --;
if (ix < 0) {
ix = data_count - 1;
}
}
M5.Lcd.setTextColor(TFT_ORANGE, TFT_BLACK);
M5.Lcd.drawString(">",x_offset1, y_offset2 + ix * height);
M5.Lcd.drawString(ir_data.name.c_str(), x_offset2, y_offset2 + ix * height);
}
}
遥控信号分析程序
该程序分析IRrecvDumpV2采集的原始数据,并将其转换为信号数据。我用Python编写了它,然后在Mac上运行了它,但是看起来像这样,因此可以将其合并到IRrecvDumpV2中。在不确认规格等的情况下,根据实际值调整值范围的判断值。
import re
import fileinput
HDR_MARK =6000
HDR_SPACE=3000
BIT_MARK = 600
ZERO_SPACE = 600
ONE_SPACE=1600
GAP = 40000
for line in fileinput.input():
line = line.strip()
if len(line) == 0:
continue
m = re.match('uint16_t rawData\[\d+\] = {([^}]+)};', line)
if m:
print(line)
print()
raw = list(map(lambda x: int(x), m.group(1).split(',')))
while len(raw) >= 2:
mark= raw.pop(0) # Skip Header Mark
space = raw.pop(0) # Skip Header Space
data = 0
bit_length = 0
while len(raw) >= 2:
mark= raw.pop(0)
space = raw.pop(0)
if (BIT_MARK-200) <= mark <= (BIT_MARK+200):
if (ZERO_SPACE-200) <= space <= (ZERO_SPACE+200):
print('0', end='')
data = data << 1
bit_length += 1
elif (ONE_SPACE-200) <= space <= (ONE_SPACE+200):
print('1', end='')
data = data << 1 | 1
bit_length += 1
elif (GAP-10000) < space < (GAP+10000):
break
else:
print()
print('Space Error:', space)
else:
print()
print('BitMark Error:', mark)
print('0x{:X}{:d} bit'.format(data, bit_length))
print()
这是通过使用上述程序处理“马桶盖打开/关闭”按钮的原始数据来确认输出3次0x2008000E0E信号的示例。
$ python TOTO_Washlet.py Raw_Data.txt
uint16_t rawData = {5984, 2958,606, 544,580, 1658,582, 544,574, 544,576, 544,582, 540,576, 544,576, 544,576, 544,578, 516,604, 546,576, 1662,576, 544,578, 520,600, 546,578, 544,578, 544,578, 542,578, 546,578, 542,580, 542,576, 520,600, 544,576, 548,578, 544,576, 544,578, 520,602, 1658,578, 1636,602, 1636,600, 546,578, 544,576, 544,578, 544,576, 544,578, 1662,576, 1636,602, 1660,578, 546,578, 39116,5960, 2960,602, 546,578, 1636,600, 522,604, 540,580, 518,602, 544,578, 544,578, 544,576, 544,576, 544,578, 522,600, 1634,604, 518,602, 518,602, 548,574, 548,574, 544,578, 544,576, 546,576, 544,578, 544,580, 516,602, 548,576, 544,578, 546,576, 544,578, 542,578, 1660,580, 1632,602, 1660,576, 544,578, 546,576, 518,604, 544,578, 546,574, 1658,582, 1656,578, 1662,576, 544,578, 38872,5984, 2958,604, 520,604, 1636,602, 542,578, 544,576, 546,576, 520,602, 542,578, 522,604, 542,578, 544,576, 550,572, 1634,604, 562,576, 544,578, 544,578, 546,576, 548,578, 544,576, 546,574, 544,576, 544,578, 546,578, 542,578, 544,576, 522,600, 546,578, 544,578, 1634,602, 1660,578, 1660,576, 544,576, 548,572, 544,576, 546,578, 544,576, 1660,578, 1636,602, 1658,578, 544,578};// UNKNOWN 450EA3E
0100000000010000000000000001110000011100x2008000E0E39 bit
0100000000010000000000000001110000011100x2008000E0E39 bit
0100000000010000000000000001110000011100x2008000E0E39 bit
页:
[1]