crankyoldgit / IRremoteESP8266

Infrared remote library for ESP8266/ESP32: send and receive infrared signals with multiple protocols. Based on: https://github.com/shirriff/Arduino-IRremote/
GNU Lesser General Public License v2.1
2.98k stars 832 forks source link

CD Stereo System Panasonic SA-PM03. #237

Closed forgoty closed 7 years ago

forgoty commented 7 years ago

Hey guys. I`ve got my old stereo system Panasonic SA-PM03 and i am lost remote control from it. In the internet i found this:

#
# this config file was automatically generated
# using lirc-0.8.0(all) on Tue Jun  6 14:01:27 2006
#
# contributed by
#
# brand:                       Panasonic
# model no. of remote control: EUR648100
# devices being controlled by this remote: CD Stereo System SA-PM03
#

begin remote

  name  Panasonic_EUR648100
  bits           24
  flags SPACE_ENC
  eps            30
  aeps          100

  header       3480  1763
  one           448  1300
  zero          448   425
  ptrail        448
  pre_data_bits   24
  pre_data       0x400405
  gap          74726
  toggle_bit      0

      begin codes
          KEY_POWER                0x38BC81                  #  Was: power
          KEY_SLEEP                0x386954                  #  Was: sleep
          KEY_AUX                  0x00595C                  #  Was: aux
          KEY_EJECTCD              0x5080D5                  #  Was: eject
          KEY_1                    0x380835                  #  Was: 1
          KEY_2                    0x3888B5                  #  Was: 2
          KEY_3                    0x384875                  #  Was: 3
          KEY_4                    0x38C8F5                  #  Was: 4
          KEY_5                    0x382815                  #  Was: 5
          KEY_6                    0x38A895                  #  Was: 6
          KEY_7                    0x386855                  #  Was: 7
          KEY_8                    0x38E8D5                  #  Was: 8
          KEY_9                    0x381825                  #  Was: 9
          dimmer                   0x38E9D4
          >10                      0x38211C
          KEY_0                    0x3898A5                  #  Was: 0
          program                  0x505104
          KEY_PLAY                 0x50DD88                  #  Was: playmode
          rev                      0x5092C7
          forw                     0x505207
          KEY_CANCEL               0x50C590                  #  Was: cancel
          KEY_STOP                 0x500055                  #  Was: stop
          KEY_PAUSE                0x506035                  #  Was: pause
          KEY_PLAY                 0x505005                  #  Was: play
          muting                   0x004C49
          soundvirtualizer         0x000C09
          fmmode                   0x20CCE9
          band                     0x202500
          bass-                    0x00C4C1
          bass+                    0x004441
          treble-                  0x00A4A1
          treble+                  0x002421
          KEY_VOLUMEDOWN           0x008481                  #  Was: vol-
          KEY_VOLUMEUP             0x000401                  #  Was: vol+
      end codes

end remote

And the question is: how can I convert this into a raw data to send it by irsend.sendRaw method?

rahuljawale commented 7 years ago

You might want to use sendPanasonic instead of sendRaw. Just send the same codes that you see in the file e.g to switch the system on or off send sendPanasonic (0x38BC81). My syntax might be wrong since this was typed on a phone. You could also refer to examples that are shipped with the library.

On 08-Jun-2017 5:17 AM, "Carlos Jinastio" notifications@github.com wrote:

Hey guys. I`ve got my old stereo system Panasonic SA-PM03 and i am lost remote control from it. In the internet i found this:

#

this config file was automatically generated

using lirc-0.8.0(all) on Tue Jun 6 14:01:27 2006

#

contributed by

#

brand: Panasonic

model no. of remote control: EUR648100

devices being controlled by this remote: CD Stereo System SA-PM03

#

begin remote

name Panasonic_EUR648100 bits 24 flags SPACE_ENC eps 30 aeps 100

header 3480 1763 one 448 1300 zero 448 425 ptrail 448 pre_data_bits 24 pre_data 0x400405 gap 74726 toggle_bit 0

  begin codes
      KEY_POWER                0x38BC81                  #  Was: power
      KEY_SLEEP                0x386954                  #  Was: sleep
      KEY_AUX                  0x00595C                  #  Was: aux
      KEY_EJECTCD              0x5080D5                  #  Was: eject
      KEY_1                    0x380835                  #  Was: 1
      KEY_2                    0x3888B5                  #  Was: 2
      KEY_3                    0x384875                  #  Was: 3
      KEY_4                    0x38C8F5                  #  Was: 4
      KEY_5                    0x382815                  #  Was: 5
      KEY_6                    0x38A895                  #  Was: 6
      KEY_7                    0x386855                  #  Was: 7
      KEY_8                    0x38E8D5                  #  Was: 8
      KEY_9                    0x381825                  #  Was: 9
      dimmer                   0x38E9D4
      >10                      0x38211C
      KEY_0                    0x3898A5                  #  Was: 0
      program                  0x505104
      KEY_PLAY                 0x50DD88                  #  Was: playmode
      rev                      0x5092C7
      forw                     0x505207
      KEY_CANCEL               0x50C590                  #  Was: cancel
      KEY_STOP                 0x500055                  #  Was: stop
      KEY_PAUSE                0x506035                  #  Was: pause
      KEY_PLAY                 0x505005                  #  Was: play
      muting                   0x004C49
      soundvirtualizer         0x000C09
      fmmode                   0x20CCE9
      band                     0x202500
      bass-                    0x00C4C1
      bass+                    0x004441
      treble-                  0x00A4A1
      treble+                  0x002421
      KEY_VOLUMEDOWN           0x008481                  #  Was: vol-
      KEY_VOLUMEUP             0x000401                  #  Was: vol+
  end codes

end remote

And the question is: how can I convert this into a raw data to send it by irsend.sendRaw method?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/markszabo/IRremoteESP8266/issues/237, or mute the thread https://github.com/notifications/unsubscribe-auth/AJuTpNsVOpTFdLvlSMLWymYbvzVdTZNrks5sBzabgaJpZM4Nzaod .

forgoty commented 7 years ago

Tried to sendPanasonic (0x400405, 0x38BC81). That doesnt work. I think that`s why:

void ICACHE_FLASH_ATTR IRsend::sendPanasonic(unsigned int address,
                                             unsigned long data) {
  // Set IR carrier frequency
  enableIROut(37);
  // Header
  mark(PANASONIC_HDR_MARK);
  space(PANASONIC_HDR_SPACE);
  // Address (16 bits)
  sendData(PANASONIC_BIT_MARK, PANASONIC_ONE_SPACE,
           PANASONIC_BIT_MARK, PANASONIC_ZERO_SPACE,
           address, 16, true);
  // Data (32 bits)
  sendData(PANASONIC_BIT_MARK, PANASONIC_ONE_SPACE,
           PANASONIC_BIT_MARK, PANASONIC_ZERO_SPACE,
           data, 32, true);
  // Footer
  mark(PANASONIC_BIT_MARK);
  ledOff();
}

Addrees and Data bits it is not the same length as expected. I should convert Data and Address bits to 24-bit length. But, I dont understand how to do that. By the way, PANASONIC_ONE_SPACE, PANASONIC_BIT_MARK, PANASONIC_ZERO_SPACE, PANASONIC_HDR_MARK, PANASONIC_HDR_SPACE are not the same too.

Correct me if I am wrong. Regards!

crankyoldgit commented 7 years ago

@forgoty Standard disclaimer. I'm no expert on LIRC, but I've had a tiny poke around lately on it.

For starters, IRremote etal and LIRC differ on what signifies a '0' or a '1'. e.g. IRremote has a bit value of '1' means a '0' for LIRC. LIRC having a bit value of '1' will correspond to a bit value of '0' for IRremote. In short, you'll need to bit-invert the relevant values to use in IRremote.

@rahuljawale Is right in that you are better off using sendPanasonic(), or sendPanasonic64() to send message. It will save you space and effort.

I'm going to use syntax from v2.0 pre-release as it's going to be the live version in about a week, so I suggest you download that, and use it to save yourself some effort later.

Panasonic devices use a 48 bit protocol. I won't go into the fine details of such, just accept it for now. The LIRC snippet you included says:

bits 24

That's because it also lists a prefix chunk of data that is also 24 bits. 24 + 24 = 48 bits.

So, to convert the LIRC code to a sendPanasonic64() code, you need to prepend the prefix data to the command data. e.g. 0x400405 (24 bits) followed by 0x38BC81 (KEY_POWER / 24 bits) giving you 0x40040538BC81 (48 bits). Now, remember I said LIRC uses an inverted (bit flipped) value compared to IRremote etc. so, you need to XOR it with 0xFFFFFFFFFFFF. e.g. sendPanasonic64(0x40040538BC81ULL ^ 0xFFFFFFFFFFFFULL); // the 'ULL' at the end means 'unsigned long long', needed as it is 64bits, and can fit a 48bit code in it.

That should work for you (in v2.0.0).

In versions prior to v2.0, you should be able to use the sendPanasonic() function, it breaks up the 48 bits into 16 + 32 bits. so you'd use: sendPanasonic(0x4004U ^ 0xFFFFU, 0x0538BC81UL ^ 0xFFFFFFFFUL); // U = unsigned, UL = unsigned long.

But to answer your original questions, of how to do it using sendRaw, here is how:

  1. Calculate the length of the array needed (for this protocol, others differ). 2 values for the header, 2 values per data bit (2 x 48 = 96), and 1 value for the footer. Total = 2 + 96 + 1 = 99.
  2. Get the header values. According to the LIRC code,

    header 3480 1763

so the array starts to look like: unsigned int rawData[99] = {3680, 1763, ...};

  1. For each bit of the full data, starting at the most significant bit working to the least, use the following data:

    one 448 1300 zero 448 425

That is, for every '1' bit, append ", 448, 1300" to the array, and for every '0' bit, append ", 488, 425". As the value for KEY_POWER we worked out before is 0x40040538BC81, the first nibble (half a byte) is 0x4 .. or 0b0100 in binary, would be (0) ", 488, 425", then (1) ", 448, 1300", then (0) ", 488, 425" and then (0) again ", 488, 425" So you would have built up: unsigned int rawData[99] = {3680, 1763, 488, 425, 448, 1300, 488, 425, 488, 425, ...};

  1. Once you done all the data bits, you need to append the footer, which LIRC says is:

    ptrail 448

so, add a ", 488};" and you should be done. e.g. unsigned int rawData[99] = {3680, 1763, 488, 425, 448, 1300, 488, 425, 488, 425, <all the other bits>, 448};

  1. Check you've got 99 entries in the rawData array. If not, you probably screwed up along the way.

Hope that helps.

crankyoldgit commented 7 years ago

@forgoty FYI Our library uses these values:

define PANASONIC_HDR_MARK 3456

define PANASONIC_HDR_SPACE 1728

define PANASONIC_BIT_MARK 432

define PANASONIC_ONE_SPACE 1296

define PANASONIC_ZERO_SPACE 432

LIRC is using respectively:

3480 1763 448 1300 425

Yes, the values are not exactly the same, however, the numbers are close enough that the device is never going to notice. There will be far more variation between different remotes etc, chips etc, temperature, etc etc. that will make more of a difference, but, feel free to change the values etc if it makes it work for you. e.g. values with in 50-100 of each other are close enough. The device receivers have a lot of slack in them for accepting 'bad' values. A drift of 20% is not uncommon. It's just looking for the rough pattern. i.e. It's in an analogue world, not a pure 'digital' one. ;-)

rahuljawale commented 7 years ago

Also, if I understand correctly, to use LIRC values, you could initialize IRSend as IRSend(4,true); .

Sending true to IRSend will invert the output and thus you do not need to XOR the values by yourself.

@crankyoldgit , please correct me if I am wrong here.

forgoty commented 7 years ago

Hey guys. Just noticed, that it is perfectly work with the following command: irsend.sendPanasonic(0x4004, 0x38BC81 + 0x5000000); // For Power Button It is only work for 1.1.1 version of the library. As you can see, you dont need to XOR, as @rahuljawale said before.

crankyoldgit commented 7 years ago

@rahuljawale Danger Will Robinson! Don't suggest people use the 'inverted' option of the IRsend constructor. That inverts the state of the LED. i.e. when it is normally off, it is on, when it is normally on, it is off. e.g. When sitting idle, the LED will be ON when IRSend(4,true); is set. This can cause the LED to burn out if the user is over-driving the LED. It's not the equivalent of XORing the data either. Not even close.

@forgoty See, I said I wasn't an expert on LIRC. :-) I've found in other (LIRC) sections it defaults to being inverted compared to our format(s). Glad it wasn't in this case, and that you worked it out.

It is only work for 1.1.1 version of the library.

Can you expand on this please? Does your solution not work in v1.2 or above? If so, that's a bug. Given I'm planning on releasing v2.0.0 next week, I'd like to know so I can fix it before release.

crankyoldgit commented 7 years ago

FYI, for v2.0+ You can (also) use the following based on your previous response: irsend.sendPanasonic64(0x40045000000ULL + 0x38BC81); // For Power Button

rahuljawale commented 7 years ago

@crankyoldgit , yikes! Can we keep the LED switched off till we actually start sending data?

crankyoldgit commented 7 years ago

@rahuljawale No, that is the sole purpose of that flag. Some people (well, at least one project/person) has a circuit that turns on the IR LEDs when the GPIO pin is LOW, rather than HIGH, and of course vice-versa. That's atypical of most circuits.

See #229 and this comment on #204 for reference.

forgoty commented 7 years ago

@crankyoldgit Sorry for this misunderstanding:

It is only work for 1.1.1 version of the library.

I was tested this code on the 1.1.1 version. Today, I tested this command: sendPanasonic(0x4004, 0x38BC81 + 0x5000000);// for power button And it is perfectly works at versions 1.1.1 and 1.2.0 of this library. Waiting for 2.0.0 official release.

Thanks for answers. Regards!