How to parse remote signal using NEC protocol?

please check my code in this simulation site..

this IR receiver always returns 1, so I inverted signal 1 and 0 on this picture
how-to-parse-remote-signal-using-nec-protocol-v0-6is1is81f2mc1

and if signal 0 is shorter then 1ms (562.5us) read as 0, and longer then 1ms(1.6875us) read as 1.

I think its working, initial state displaying well , 9 ms of 0 signal, 4.5ms of 1signal
image

, but command and inverted command, address and inverted address is not matching, and also command is changing everytime when press the same button

I think problem is on code.. but I can't find what is problem on code..
can you check code and help me..


here is my full code::

// C++ code
const int IR_PIN_NUMBER = 8;

struct TimelinePackage{
  int duration_millis;
  int readed;
  TimelinePackage(int dur, int read) {
    duration_millis=dur;
    readed=read;
  }
  void to_string(){
    Serial.println(String("duration: ") + duration_millis + String("/readed: ") + readed); 
  }
};

TimelinePackage** ReadAllTimelines(int PIN_NUMBER, int bytes_to_read);



void setup() {
  pinMode(IR_PIN_NUMBER, INPUT);
  Serial.begin(9600);
}

void loop() {
  if (digitalRead(IR_PIN_NUMBER) != 1) {
    TimelinePackage** packages= ReadAllTimelines(IR_PIN_NUMBER, 67);
//I manually calculated total bytes ((8(address/command size) * 4) * 2(0 and 1)) + 2(initial states) + 1(final byte)
    int total_writed=0;
    for(int i=0; i<67; i++){
      if(packages[i]-> readed==1){
        if(packages[i]-> duration_millis==0){
          Serial.print(0);
        }else{
          Serial.print(1);
        }
        total_writed++;
        if(total_writed==1){
          Serial.print('\t');
        }
        if(total_writed>=8 && total_writed % 8 == 0){
          Serial.print('\t');
        }
      }
    }

    Serial.print('\n');
    for(int i=0; i<67; i++){
      packages[i]->to_string();
      delete packages[i];
    }
    delete packages;
    Serial.print('\n');
  }
}
TimelinePackage** ReadAllTimelines(int PIN_NUMBER, int bytes_to_read) {
  TimelinePackage** packages = new TimelinePackage*[bytes_to_read];
  for(int i = 0; i < bytes_to_read; i++) {
    int mills_1 = millis();
    int readed = digitalRead(PIN_NUMBER);
    while(digitalRead(PIN_NUMBER) == readed) {};
    int duration = millis() - mills_1;
    packages[i] = new TimelinePackage(duration, readed);
  }
  return packages;
}

Welcome to the forum

I cannot see any code. Please post it here using code tags when you do

ooops sorry, I added code on post!

Are you coding this yourself for an assignment or is there another reason you are not using a ready made IR library to decode the NEC protocol ?

Anyway, you are certainly using some interesting coding features like double indirection. However, the main comment I have is that you are using millis() a lot and the NEC protocol has timings going down to half a millisecond. Would micros() be more appropriate for the timings of the bits following the header ?

Here, for example:

if(packages[i]-> duration_millis==0){
          Serial.print(0);
        }else{
          Serial.print(1);
        }
. . .
. . .

you appear to be treating a duration of 0 ms as a 0. But what happens if your measurements cross a rollover from one millisecond to the next ? Even a few microseconds could look like 1ms.
Also interleaving printing at 9600 baud could slow the process down and lead to lost data.

thanks, I just thought there is no function to get micro second, but it has! thanks for your precious information :grinning:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.