#include "ir_control.h" void initIRControl() { pinMode(IR_RECEIVE_PIN, INPUT); pinMode(IR_SEND_PIN, OUTPUT); digitalWrite(IR_SEND_PIN, LOW); Serial.println("红外控制模块初始化完成"); Serial.print("接收引脚: "); Serial.println(IR_RECEIVE_PIN); Serial.print("发送引脚: "); Serial.println(IR_SEND_PIN); } bool checkIRSignalStart() { return (digitalRead(IR_RECEIVE_PIN) == LOW); } IRSignal receiveIRSignal() { IRSignal signal; signal.data = nullptr; signal.length = 0; signal.isValid = false; Serial.println("开始接收红外信号..."); // 分配内存存储信号数据 signal.data = (unsigned int*)malloc(MAX_SIGNAL_LENGTH * sizeof(unsigned int)); if (signal.data == nullptr) { Serial.println("内存分配失败"); return signal; } unsigned long startTime = micros(); unsigned long lastChange = startTime; bool currentState = HIGH; bool lastState = HIGH; // 等待信号开始(第一个低电平) while (digitalRead(IR_RECEIVE_PIN) == HIGH && (micros() - startTime) < RECEIVE_TIMEOUT_US) { delayMicroseconds(10); } if ((micros() - startTime) >= RECEIVE_TIMEOUT_US) { Serial.println("等待信号超时"); free(signal.data); signal.data = nullptr; return signal; } Serial.println("检测到信号开始"); lastChange = micros(); lastState = LOW; signal.length = 0; // 接收信号数据 while (signal.length < MAX_SIGNAL_LENGTH) { currentState = digitalRead(IR_RECEIVE_PIN); if (currentState != lastState) { // 状态改变,记录持续时间 unsigned long duration = micros() - lastChange; signal.data[signal.length] = duration; signal.length++; lastState = currentState; lastChange = micros(); } // 检查是否信号结束(高电平持续时间过长) if (currentState == HIGH && (micros() - lastChange) > SIGNAL_END_TIMEOUT_US) { Serial.println("检测到信号结束"); break; } // 总体超时检查 if ((micros() - startTime) > RECEIVE_TIMEOUT_US) { Serial.println("接收总体超时"); break; } } if (signal.length > 0) { signal.isValid = true; Serial.print("信号接收成功,长度: "); Serial.println(signal.length); // 重新分配内存以节省空间 signal.data = (unsigned int*)realloc(signal.data, signal.length * sizeof(unsigned int)); if (signal.data == nullptr) { Serial.println("内存重新分配失败"); signal.isValid = false; signal.length = 0; } } else { Serial.println("未接收到有效信号"); free(signal.data); signal.data = nullptr; } return signal; } bool sendIRSignal(const IRSignal& signal) { if (!isValidIRSignal(signal)) { Serial.println("信号无效,无法发送"); return false; } Serial.println("开始发送红外信号..."); Serial.print("信号长度: "); Serial.println(signal.length); // 禁用中断以确保精确的时序 noInterrupts(); bool state = LOW; // 红外信号通常以低电平开始 for (int i = 0; i < signal.length; i++) { digitalWrite(IR_SEND_PIN, state); delayMicroseconds(signal.data[i]); state = !state; // 切换状态 } // 确保最后是低电平 digitalWrite(IR_SEND_PIN, LOW); // 重新启用中断 interrupts(); Serial.println("信号发送完成"); return true; } void freeIRSignal(IRSignal& signal) { if (signal.data != nullptr) { free(signal.data); signal.data = nullptr; } signal.length = 0; signal.isValid = false; } IRSignal copyIRSignal(const IRSignal& source) { IRSignal copy; copy.data = nullptr; copy.length = 0; copy.isValid = false; if (!isValidIRSignal(source)) { return copy; } // 分配内存 copy.data = (unsigned int*)malloc(source.length * sizeof(unsigned int)); if (copy.data == nullptr) { Serial.println("复制信号时内存分配失败"); return copy; } // 复制数据 for (int i = 0; i < source.length; i++) { copy.data[i] = source.data[i]; } copy.length = source.length; copy.isValid = true; return copy; } void printIRSignal(const IRSignal& signal, int maxPrint) { if (!isValidIRSignal(signal)) { Serial.println("信号无效,无法打印"); return; } Serial.println("=== 红外信号数据 ==="); Serial.print("信号长度: "); Serial.println(signal.length); Serial.print("信号有效: "); Serial.println(signal.isValid ? "是" : "否"); int printCount = (maxPrint == 0) ? signal.length : min(maxPrint, signal.length); Serial.println("原始数据 (微秒):"); for (int i = 0; i < printCount; i++) { Serial.print("Index "); Serial.print(i); Serial.print(": "); Serial.print(signal.data[i]); Serial.print(" us ("); Serial.print((i % 2 == 0) ? "LOW" : "HIGH"); Serial.println(")"); } if (printCount < signal.length) { Serial.print("... 还有 "); Serial.print(signal.length - printCount); Serial.println(" 个数据点未显示"); } Serial.println("=================="); } bool isValidIRSignal(const IRSignal& signal) { return (signal.data != nullptr && signal.length > 0 && signal.isValid); }