Arduino中Case语句用HEX值报'duplicate case value'错误求助
Arduino红外遥控器Switch Case重复值错误及指令格式问题解决
问题说明
将遥控器输出的32位HEX值(如0xE718FF00)写入switch的case语句时,编译报错error: duplicate case value;原参考代码使用两位数十六进制指令值,当前遥控器输出的是长HEX值,希望了解错误原因及获取两位数指令的方法。
错误原因
代码中ircommand被定义为int类型,而Arduino的int是16位(范围-32768~32767),无法容纳0xE718FF00这类32位的HEX值。这些超长数值会被强制截断,导致多个不同的原始HEX值截断后变成相同的int值,最终触发case重复的编译错误。和HEX值以0x开头无关,核心是变量类型与存储数据的长度不匹配。
解决方案
1. 解决重复case错误
- 将存储红外数据的变量类型改为
uint32_t或unsigned long(两者都是32位无符号整数,可完整存储decodedRawData的32位HEX值)。 - 修改switch语句的判断对象为正确类型的变量,确保每个case的HEX值都能被完整识别。
修改后的monitorIR函数示例:
void monitorIR(){ if(IrReceiver.decode()){ // 用uint32_t存储完整的原始红外数据 uint32_t ircommand = IrReceiver.decodedIRData.decodedRawData; Serial.print("Raw Data: 0x"); Serial.println(ircommand, HEX); IrReceiver.resume(); if(lastCommandReceived!=ircommand){ lastCommandReceived = ircommand; switch(ircommand){ // IR UP BUTTON - OPEN FACE case 0xE718FF00: if(facePlateCurMode == FACEPLATE_CLOSED){ facePlateOpenFx(); } break; // IR DOWN BUTTON - CLOSE FACE case 0xAD52FF00: if(facePlateCurMode == FACEPLATE_OPEN){ facePlateCloseFx(); } break; // 其余按键case保持原有HEX值即可 case 0xBA45FF00: if(facePlateCurMode == FACEPLATE_CLOSED){ ledEyesOn(); } break; case 0xB946FF00: if(facePlateCurMode == FACEPLATE_CLOSED){ ledEyesOff(); } break; case 0xB847FF00: playSoundEffect(SND_JARVIS_EXTRA_A); break; case 0xBB44FF00: playSoundEffect(SND_JARVIS_EXTRA_B); break; case 0xBF40FF00: playSoundEffect(SND_JARVIS_EXTRA_C); break; case 0xBC43FF00: playSoundEffect(SND_JARVIS_EXTRA_D); break; case 0xF807FF00: playSoundEffect(SND_JARVIS_EXTRA_E); break; case 0xEA15FF00: playSoundEffect(SND_JARVIS_EXTRA_F); break; } } } }
2. 获取两位数指令值
原参考代码使用的是IrReceiver.decodedIRData.command字段,这个字段对应遥控器的按键指令码,多数常见红外协议(如NEC、RC5)中,该指令码是8位(即两位数十六进制,如0x18、0x52)。
- 运行当前代码时,串口会打印
ircommand(即command字段)的十进制值,将其转换为十六进制就是两位数指令。比如串口打印24,对应的十六进制就是0x18。 - 若
command字段返回值异常(如0或固定值),可能是遥控器协议未被IRremote库支持,可尝试结合IrReceiver.decodedIRData.address(设备地址码)和command共同判断,或检查库的协议兼容性。
改用两位数指令的monitorIR函数示例:
void monitorIR(){ if(IrReceiver.decode()){ // 用uint8_t存储8位指令码(两位数十六进制) uint8_t ircommand = IrReceiver.decodedIRData.command; Serial.print("Command: 0x"); Serial.println(ircommand, HEX); IrReceiver.resume(); if(lastCommandReceived!=ircommand){ lastCommandReceived = ircommand; switch(ircommand){ // IR UP BUTTON - OPEN FACE,替换为对应两位数指令 case 0x18: if(facePlateCurMode == FACEPLATE_CLOSED){ facePlateOpenFx(); } break; // IR DOWN BUTTON - CLOSE FACE case 0x52: if(facePlateCurMode == FACEPLATE_OPEN){ facePlateCloseFx(); } break; // 其余按键替换为各自对应的两位数指令 case 0x45: if(facePlateCurMode == FACEPLATE_CLOSED){ ledEyesOn(); } break; case 0x46: if(facePlateCurMode == FACEPLATE_CLOSED){ ledEyesOff(); } break; case 0x47: playSoundEffect(SND_JARVIS_EXTRA_A); break; case 0x44: playSoundEffect(SND_JARVIS_EXTRA_B); break; case 0x40: playSoundEffect(SND_JARVIS_EXTRA_C); break; case 0x43: playSoundEffect(SND_JARVIS_EXTRA_D); break; case 0x07: playSoundEffect(SND_JARVIS_EXTRA_E); break; case 0x15: playSoundEffect(SND_JARVIS_EXTRA_F); break; } } } }
内容的提问来源于stack exchange,提问作者matt_soton
相关产品推荐
相关产品推荐

