較長的紅外線發射會導致接收失敗

  • 環境
    ** 硬體:BW16
    *** 紅外線發射GPIO:PA26 PA25
    ** 前置:按教學更新firmware及設定Arduino IDE
    ** Board ver: 3.0.11
    ** IDE: Arduino 1.8.16 / MacOS 10.14.6
  • 步驟
  1. 在Arduino IDE上讀取AmebaIRDevice → IRSendRaw範例
  2. 將irRawSignal置換為已在lirc驗證過的電視開關的raw code,長度為63
  3. 編譯及上傳
  4. 按下RST後確認電視每兩秒觸發一次開或關
  • 測項:
  1. 將irRawSignal置換為已在lirc驗證過的冷氣訊號,長度為439

  2. 編譯及上傳

  3. 預期:冷氣可被設定
    實際:冷氣未接受訊號

  4. 將irRawSignal置換為另一個已在lirc驗證過的另一台冷氣訊號,長度為108

  5. 編譯及上傳

  6. 預期:冷氣可被設定
    實際:冷氣未接受訊號

已排除因素:

  • 紅外線距離
  • 頻率測試:36700, 37000, 38000, 40000
  • 已測試過 PROGMEM
1 Like

Hi @Victor
BW16 pin脚有限,不是所有的都支援IR,可參考這裏查看,BW16可用的IR pin脚

PA26應該只能做recv pin

Hi @xidameng ,

對的抱歉,是我上面誤植了,我確實是使用PA25。

因為我同時也修改了這段程式碼,一般的使用者不太會同時使用IR Recv& IR emitter。

所以問題是存在的。

我試了一下3.1.0發現問題仍然存在,想請問一下這個是已確認SDK的問題還是我應該要作怎樣的修改?

@wyy
Please help to take a look, thanks!

测试了一下,BW16 确定是可以用 IR 的,IRSendRaw 发出的信号在 logic analyzer 分析上也是对的。
@Victor 能把你的 code 打出来吗?我想看看能不能用 logic analyzer 抓到

Hi @wyy 前面有提到在短的部份沒問題,但長的似乎有問題。

失敗的兩個範例(在lirc上永遠成功)

522,3555,505,534,507,533 
,508,533,508,595,508,533 
,510,531,508,534,508,595 
,507,534,507,533,507,534 
,507,595,508,535,509,534 
,504,534,508,593,514,528 
,509,531,508,533,508,595 
,510,530,508,534,508,532 
,508,597,506,533,507,533 
,508,533,508,596,506,534 
,507,533,508,533,508,597 
,506,533,507,534,506,534 
,507,586,507,1531,508,533 
,510,531,508,595,508,533 
,508,534,506,533,508,586 
,508,1532,506,525,507,1522
,508,1585,507,1523,507,1534
,505,532,508,533,509,3412
3520,1770,432,457,432,1331,
460,432,431,459,457,433,
432,457,432,459,456,442,
459,433,431,457,460,430,
434,458,431,458,432,1332,
458,432,457,442,432,459,
430,460,431,459,460,431,
431,460,455,1309,431,1333,
456,1317,456,434,434,457,
431,1333,430,459,433,456,
433,461,427,492,400,466,
457,438,453,433,430,460,
431,458,458,435,431,460
,456,433,432,495,404,457
,433,460,432,458,433,458
,456,431,433,459,431,463
,428,468,432,458,431,458
,432,485,407,458,445,446
,432,456,431,459,433,466
,460,432,429,1361,403,1334
,430,458,458,460,429,435
,430,461,430,464,433,10101

,3477,1772,432,460,431,1332
,433,457,457,436,430,486
,404,460,456,433,432,495
,430,459,406,456,459,432
,433,458,435,482,430,1308
,430,462,455,441,433,457
,458,460,404,459,433,457
,431,458,433,1331,458,1309
,429,1342,433,457,458,432
,457,1309,430,459,434,456
,459,431,433,458,456,417
,458,457,457,435,455,433
,459,432,432,458,457,435
,431,457,432,467,442,1324
,432,457,433,460,429,458
,458,1308,429,1333,457,432
,460,440,433,457,434,460
,429,458,433,1332,432,1331
,458,1279,459,457,458,441
,433,457,458,432,459,414
,476,460,404,458,432,457
,433,458,459,1314,432,1332
,456,1307,432,1332,434,1334
,430,1332,431,1332,455,435
,431,467,436,1328,460,430
,432,1330,433,1332,432,457
,458,433,431,459,456,444
,439,451,456,434,436,453
,434,456,432,459,431,458
,432,460,431,467,458,432
,434,1330,432,1332,456,1285
,454,461,430,485,429,435
,433,467,431,461,430,458
,457,432,460,432,457,432
,461,1304,457,1308,431,1341
,432,460,449,443,454,433
,432,458,431,459,457,434
,458,1279,456,494,433,430
,432,461,454,408,481,434
,456,434,432,460,431,459
,456,443,458,1309,443,443
,432,457,433,459,432,457
,458,433,458,431,433,468
,431,458,434,459,431,486
,429,436,456,459,405,458
,432,458,434,465,459,433
,431,458,432,458,458,435
,430,456,434,459,454,435
,457,443,431,461,455,1307
,431,460,456,1308,430,456
,434,1332,433,1329,433,465
,431

上面這兩個是對應不同的裝置,也排除發射距離的問題(已盡可能將測試距離縮短在50cm,且我將原先在lirc上的IR emitter換裝到bw16上進行相關測試)

有几个问题,

  1. IRDevice library 确实不能发太长的 code,默认设定长度是 75 个,这个需要改
  2. 你给的这些 lirc code 有什么格式或者单位吗?还是对频率要求很高?
    • 按照 Arduino IRDevice 用的算法,用 40KHz 频率,一个周期是 25us
    • 500 到 524 都会输出 20 周期,根本分辨不开 504 和 514 的差别
    • 525 到 549 都会输出 21 周期,跟 20 周期差不了多少,硬件应该很难分辨

Hi @wyy,

  1. 這個再麻煩您加入release, 另外我想順便再提一個change。現在的IRDevice.cpp:166-180 實際上會判斷只要任一pin腳定義錯誤就會直接返回,但實務上我們可能只需要一個pin(send or recv),所以我建議如果setPins的parameter list仍然需要維持send and recv,我希望可以用0來定義該pin腳不使用(設定)。修改如下(或者你需要我直接開PR也可)
#define NOT_SET_PIN 0
if (receivePin == PA26) {
        PAD_PullCtrl(_PA_26, PullNone);
        Pinmux_Config(_PA_26, PINMUX_FUNCTION_IR);
    } else if (receivePin != NOT_SET_PIN) {
        printf("Hardware IR functionality is not supported on selected receive pin!\r\n");
        return;
    }

//    if (transmitPin == 3) {
    if (transmitPin == PA25) {
        Pinmux_Config(_PA_25, PINMUX_FUNCTION_IR);
    } else if (transmitPin != NOT_SET_PIN) {
        printf("Hardware IR functionality is not supported on selected transmit pin!\r\n");
        return;
    }
  1. 抱歉其實我對IR沒那麼熟,如你可以看到的實際上硬體可能對頻率准確度要求沒那麼高,所以才會出現504/514這個狀況。而這個頻率是實際上我拿搖控器去錄製的。目前因為還沒有空去解原始的頻率格式,所以會先以錄製重播的方式來設定我需要的功能。這兩個比較長的lirc code一個應該是NEC的格式一個是Panasonic的格式。如果有需要我可以提供完整的lirc.conf

Hi @Victor

  1. 确实是只需要一个 pin,但是应该不能用 0,因为 Arduino 里面 0 也是个 pin。我的想法是把 setPins 的功能分成 setTxPin 和 setRxPin,然后多加一个单pin 的 begin,用 IR_MODE_TX 和 IR_MODE_RX 来分辨需要的 set__Pin
  2. 既然是自己录制的,那就能解释那些小差别了。
    • 第一段 code 里面的时间长度上确实有点像 NEC。NEC 用的时间长度大概是 560us 和 1690us,那些 5xx 和 15xx 的号码应该都是这两种。但是整体结构不太像 NEC,没有 NEC 开头的 9000 和 4500,没有 8 个 bit 后的 logical inversion,也有点太长了。
    • 第二段 code 应该是 panasonic 吧,我对 Panasonic 不熟,网上找的的时间段为 435us, 435 x 3 ≈ 1300, 435 x 4 ≈ 1750, 435 x 8 ≈ 3500。这些也大概跟第二段 code 里的时间段吻合。

还麻烦你提供 lirc.conf,不知道这个会不会有用

Hi @wyy

  1. 沒問題,或者是取unsign int最大值也是個方法。但我會希望長度的部份可以先提供,TX/RX pin這個我可以自己修改IRDevice.cpp

  2. 兩個lirc conf檔如下(請再自行修改為txt或conf)
    sampo.test.lircd.conf.xml (1.2 KB)
    panasonic.test.lircd.conf.xml (4.2 KB)

Hi @Victor,

可以尝试用这两个修改过的文件代替 IRDevice.cppIRDevice.h

  1. 单 pin 模式可以用 void begin(uint8_t irPin, uint32_t irMode, uint32_t freq) 启动。
  2. 发射数据长度,应该只要有足够 ram 就行,测试过了 1000 的长度。

Hi @wyy ,

感謝!我剛試了一下單pin模式以及上面的兩個指令,目標的接收器都能正確接收了。

原先還真沒找到長度的部份在哪邊,我會再diff一下3.1.0的部份

原先的长度限制是在 IR_DataStruct.irBuf 的大小,之前用的是 standard SDK 里面的 NEC 示例设置,所以只能在 75 长度以下

原來如此,感謝解釋!