Figure out how to control Lyngdorf amplifier using UART from ESP32

Thanks, will try that as the first step

There’s also this alternative approach for UART sensors.

Potentially an easier entry point.

2 Likes

Yes I was just looking for that :slight_smile:

2 Likes

Looking at the linked information for the protocol the alternative approach using the uart debugging will not be a good fit. The packets are all binary format of variable length, so there is no good delimiter to split the data. If the amp only responds with one packet to each request the timeout might work.

Here were two esphome custom components with multiple different sensors that implement binary protocols. Might be able to leverage some of this for your project.

I’d also search to see if there are any existing c++ projects that implement the controls for the amp. Might be able to migrate that into esphome.

2 Likes

Thanks, will have a look!

Ok, so not making much progress here sad to say. Have built a physical connector that I think is pinned correctly between the ESP32 and RJ12 connector, plugged it in and nothing exploded :slight_smile: . Did it with a cross over setup, rx-tx and tx-rx, guess that is the right way to do it?

Interesting the ground pin is not mentioned in the ESPHome UART docs, should this NOT be used, it is standard for RS232?

Still struggling to figure out how to send and receive, so right now not even capable of figuring out is anything is actually getting to the AMP and if the pinout is correct.

Testing a simple swith to send a “power off” command (think I got it right), but can see no responses from the AMP.

This is the current config:

esphome:
  name: esp-stereo

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# UART Serial interface
uart:
  baud_rate: 57600
  tx_pin: GPIO17
  rx_pin: GPIO16
  rx_buffer_size: 256
  data_bits: 8
  parity: NONE
  stop_bits: 1
  debug:
    direction: BOTH
    dummy_receiver: false
    sequence:
      - lambda: UARTDebug::log_binary(direction, bytes, ',');

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxx"

ota:
  password: "xxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp-Stereo Fallback Hotspot"
    password: "xxxxxx"

captive_portal:

#test serial hex input, request for power toggle

switch:

  - platform: uart
    name: "Off"
    data: [0x06, 0x01, 0x00, 0x75, 0x00, 0x7C]'

And this is the log I get when toggling the switch:

INFO Reading configuration /config/esphome/esp-stereo.yaml...
INFO Starting log output from esp-stereo.local using esphome API
INFO Successfully connected to esp-stereo.local
[12:30:59][I][app:102]: ESPHome version 2022.11.3 compiled on Nov 28 2022, 09:13:40
[12:30:59][C][wifi:504]: WiFi:
[12:30:59][C][wifi:362]:   Local MAC: C8:F0:9E:9E:10:4C
[12:30:59][C][wifi:363]:   SSID: [redacted]
[12:30:59][C][wifi:364]:   IP Address: 192.168.2.59
[12:30:59][C][wifi:366]:   BSSID: [redacted]
[12:30:59][C][wifi:367]:   Hostname: 'esp-stereo'
[12:30:59][C][wifi:369]:   Signal strength: -35 dB ▂▄▆█
[12:30:59][C][wifi:373]:   Channel: 6
[12:30:59][C][wifi:374]:   Subnet: 255.255.255.0
[12:30:59][C][wifi:375]:   Gateway: 192.168.2.1
[12:30:59][C][wifi:376]:   DNS1: 192.168.2.1
[12:30:59][C][wifi:377]:   DNS2: 0.0.0.0
[12:30:59][C][logger:293]: Logger:
[12:30:59][C][logger:294]:   Level: DEBUG
[12:30:59][C][logger:295]:   Log Baud Rate: 115200
[12:30:59][C][logger:296]:   Hardware UART: UART0
[12:30:59][C][uart.arduino_esp32:108]: UART Bus 1:
[12:30:59][C][uart.arduino_esp32:109]:   TX Pin: GPIO17
[12:30:59][C][uart.arduino_esp32:110]:   RX Pin: GPIO16
[12:30:59][C][uart.arduino_esp32:112]:   RX Buffer Size: 256
[12:30:59][C][uart.arduino_esp32:114]:   Baud Rate: 57600 baud
[12:30:59][C][uart.arduino_esp32:115]:   Data Bits: 8
[12:30:59][C][uart.arduino_esp32:116]:   Parity: NONE
[12:30:59][C][uart.arduino_esp32:117]:   Stop bits: 1
[12:30:59][C][uart.switch:040]: UART Switch 'Off'
[12:30:59][C][captive_portal:088]: Captive Portal:
[12:30:59][C][mdns:103]: mDNS:
[12:30:59][C][mdns:104]:   Hostname: esp-stereo
[12:30:59][C][ota:093]: Over-The-Air Updates:
[12:30:59][C][ota:094]:   Address: esp-stereo.local:3232
[12:30:59][C][ota:097]:   Using Password.
[12:30:59][C][api:138]: API Server:
[12:30:59][C][api:139]:   Address: esp-stereo.local:6053
[12:30:59][C][api:141]:   Using noise encryption: YES
[12:32:16][D][switch:013]: 'Off' Turning ON.
[12:32:16][D][switch:037]: 'Off': Sending state ON
[12:32:16][D][uart.switch:020]: 'Off': Sending data...
[12:32:16][D][switch:037]: 'Off': Sending state OFF
[12:32:16][D][uart_debug:196]: >>> 0b00000110 (0x06),0b00000001 (0x01),0b00000000 (0x00),0b01110101 (0x75),0b00000000 (0x00),0b01111100 (0x7C)

I have read so many threads (including the ones you guys pointed to, thanks!), but no luck and getting more confused rather than less :slight_smile:, the best one I have found that seemed to be close to my case is : Need Help using RS232 to control a receiver - Configuration - Home Assistant Community (home-assistant.io), if you scroll down to Nathan Carr post in that thread.

I right now would need help with the following:

  • to ensure that the command I´m sending is correct according to the command code manual I linked to earlier (do not get the address thing they write about in the beginning, cannot see it in the example they include)
  • be sure that my config would capture any ack comming back from the AMP is my command gets to it

Thanks for the help.
Br
/Micke

Like Nick said, first step is probably too try to see some data being received in the debug.

Did you tinker much with that?

I notice you have dummy_receiver: false
I think it needs to be true.

While it sounds like the debug approach won’t be useful for your solution, it’s probably still the best first step to confirm your wiring is ok.

For a start, the manual says on page two that no ACK is received on a power off command.

But fundamentally I think the problem is that you need the address of the amplifier. To get that I think you need to send command 66 and observe the return packets. (see page 13).

Lol, feel a bit stupid, yes you are correct, but have tried commands that do have an ack, same result. Will check the reference you pointed to.

The rx-tx crossover looks correct, the GND needs to be shared.

Were you using a ttl to rs232 converter? ESP32 should be on the ttl side and amp on the rs232 side.

With the esp32 connected to the ttl to rs232 converter you can jumper the rs232 rx and tx together to get a loop back of the sent data. That will confirm the all the wiring to and from the amp.

1 Like

The thing is, I don’t know that you can expect an ACK unless you send a packet to the correct address.

Thinking on this further, I wonder if using a higher level language may make things easier. Perhaps CircuitPython or something.

Hmm, I might be wrong, but my impression was that the dymmy_reviever will create a “fake” response by emulating an endpoint? Think I have seen examples in the forum where the response turns up with the debug active but no dummy_reciever.

Nope, just connected the ESP directly to the amp using a modified RJ12.

Have the same idea, the amp will not respond if it is not the correct address.

Might be missing something fundamental, but the example they give in the beginning does not make sense to me:

My interpretation is that this is the address. Checking my amp it has the link address 1 set (I checked this using the menu). Do not understand the PROD_DEV_CODE above the table, cannot find any other references to this in the documentation, my impression was that this would be the addressing to use, but seems to be unrelated.

Right now I´m going back to square one, not sure if the pinout config for the RJ12 is correct, though that this was a standard for RS232, but googling this it seems to be all over the place, so have asked Lyngdorf for the correct pinout used.

The address is sent in the 2nd and 3rd bytes, so there are 65535 possible addresses.

The PRODUCT_DEV_CODE is returned by command 200, which puts it in byte 23 of the answer - see page 46.

The example given in the quote in your last post does exactly that. It sends C8 hex (200 dec) to device with address 0001 and in the return 07 is in byte 23. 7 tells that it is a TDA2200+ RoomP.

1 Like

Thanks for the explanation. I think I might be in over my head :slight_smile: .
Got the pin-out from Lyngdorf for the RS232 cable and have connected the cabling to the ESP32 according to this:
RJ12 DB9 Pinout
(my notes in blue)

The config for UART is as follows:

# UART Serial interface
uart:
  baud_rate: 57600
  tx_pin: GPIO17
  rx_pin: GPIO16
  rx_buffer_size: 256
  data_bits: 8
  parity: NONE
  stop_bits: 1
  debug:
    direction: BOTH
    dummy_receiver: false
    sequence:
      - lambda: UARTDebug::log_binary(direction, bytes, ',');

Not 100% on this conf. but verified the baud rate on the amp at least, the rest is more or less the defaults.

Set up a switch that send the following command:

#test serial hex input, request for dev info

switch:

  - platform: uart
    name: "Comm test"
    data: [0x05, 0x01, 0x00, 0xc8, 0xce]

The amp reports having the “link address” 1, so I guess that 0x01 0x00 should be correct to address it.
This gives me the following log:

[21:22:46][VV][api.service:558]: on_switch_command_request: SwitchCommandRequest {
  key: 3250616424
  state: YES
}
[21:22:46][D][switch:013]: 'Comm test' Turning ON.
[21:22:46][D][switch:037]: 'Comm test': Sending state ON
[21:22:46][VV][api.service:156]: send_switch_state_response: SwitchStateResponse {
  key: 3250616424
  state: YES
}
[21:22:46][D][uart.switch:020]: 'Comm test': Sending data...
[21:22:46][D][switch:037]: 'Comm test': Sending state OFF
[21:22:46][VV][api.service:156]: send_switch_state_response: SwitchStateResponse {
  key: 3250616424
  state: NO
}
[21:22:46][D][uart_debug:196]: >>> 0b00000101 (0x05),0b00000001 (0x01),0b00000000 (0x00),0b11001000 (0xC8),0b11001110 (0xCE)
[21:22:50][VV][api.service:470]: on_ping_request: PingRequest {}
[21:22:50][VV][api.service:043]: send_ping_response: PingResponse {}

My expectation would be to get something back from the amp, but nothing. Just to test I also reversed the Tx/Rx connection, same result.

Any ideas on what to test to try to figure this out?

How? Looks from the manual that there is a method to set the baud rate on various devices (eg command code 204), but it doesn’t say a default. I would try 9600.

I really think you should be using a TTL/RS232 interface.

Have you tried the Show Address command?

The amp lets you set the baud rate using the standard interface (buttons) and display, so verified the rate and that is also where the “link address” is showed.
Looking to get hold of the original cable for RS232 from Lyndorf, I can then connect from my laptop and verify that it is working in default setup, can use portsniffer to look at the actual commands as well over the wire.

Will check the “show address” command, missed that one.

Also asked them to clarify the pinout on the RJ12 as well, realized late yesterday that it is possible to interpret in different ways.