Hades
Posts: 5
Joined: Fri Jun 28, 2013 7:03 pm

sending commands to serial port

Fri Jun 28, 2013 7:44 pm

Hello,

I have a problems sending commands to my AV-Receiver (Denon AVR-2807) which ist connected to my Pi via USB --> serial adapter (PL2303). I only have very basic knwoledge in Linux and been now searching for 2 days...

The parameters, my Denon requires are:

Code: Select all

Synchronous system :          Tone step synchronization
Communication system :        A half duplex
Communication speed :         9600bps
Character length :            8 bits
Parity control :              None
Start bit :                   1 bit
Stop bit :                    1 bit
Communication procedure :     Non procedural
Communication data length :   135 bytes (maximum) 
Specifications of the Denon-protocol can be found here: http://www.denon.de/DocumentMaster/DE/2 ... ver4_7.pdf

What I want to do (but doesn't work) is:

Code: Select all

echo -e "MUON\r" >> /dev/ttyUSB0
where "MUON<CR>" is the command to mute the Denon (as example). I want to use it from other scripts (siriproxy) and devices (e.g. fritzbox callmonitor).

I CAN connect to the AV-Receiver using

Code: Select all

screen /dev/ttyUSB0 9600
It flawlessly shows me the output of the Denon (i.e. e.g. if I change volume, mute etc.) as well as I can send commands. Minicom also works after I actived CR (Crtl-A w).

I also CAN forward the output of the Denon to a file using

Code: Select all

cat /dev/ttyUSB0 >> anyfile
However, I cannot do anything else in the meanwhile (no command prompt until Ctrl-C).

My settings for stty are the following:

Code: Select all

speed 9600 baud; rows 50; columns 130; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd cs8 -hupcl -cstopb cread -clocal -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany imaxbel -iutf8 opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isig icanon iexten echo echoe -echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
I also tried to

Code: Select all

cat testfile >> /dev/ttyUSB0
where testfile contains the echo-command as well as

Code: Select all

printf "MUON\" >> /dev/ttyUSB0
. Nothing works.

I thought (i.e. I read it somewhere) that maybe the serial port closes to fast after sending the echo command to get the whole command.

Maybe anyone can help?!

Hades.

danjperron
Posts: 3402
Joined: Thu Dec 27, 2012 4:05 am
Location: Québec, Canada

Re: sending commands to serial port

Sat Jun 29, 2013 8:14 pm

if you put a led on pin 3 does it change intensity when you send the data?

Are you using a null modem cable. Did you disable the hardware handshake?

Put 2 leds head to toe one red and the other one with an other color.

If you are usin only rx and tx, you could disable the hardware handshake by connecting pin 1,4 and 6 together, 7 and 8 together.

Daniel

Hades
Posts: 5
Joined: Fri Jun 28, 2013 7:03 pm

Re: sending commands to serial port

Sat Jun 29, 2013 9:23 pm

sorry. I do not have leds. I do not use a null modem cable. I cannot change the Pins in the cable as it's a ready-bought-adapter.

However, the connection seems to be working because with screen everything works fine, i.e. i can receive and send commands correctly.

I now have a workaround-skript which also works, however only is a workaround:

Code: Select all

screen -dmS AVR2807 /dev/ttyUSB0 9600
screen -S AVR2807 -X stuff "$1\r"
screen -S AVR2807 -X kill
Now if I call this script with e.g. the argument "MUON" the Denon mutes.

Alex.

PiGraham
Posts: 3613
Joined: Fri Jun 07, 2013 12:37 pm
Location: Waterlooville

Re: sending commands to serial port

Tue Jul 02, 2013 5:27 am

However, I cannot do anything else in the meanwhile (no command prompt until Ctrl-C).
That's how it works.

If a program doesn't require user interaction, such as piping to a file, you run it as a background task by appending '&' on the end of the command. The program will start and you will be returned to the command prompt.

So if you had a program count that counts slowly then exits:
>count
1,2,3,4,5,6,7,8,9 Done
>

Run in background:
>count &
>

The output will be lost. You probably want the output, so redirect it to a file:
> count >log.txt &
>

log.txt will eventually contain the output "1,2,3,4,5,6,7,8,9 Done"

If you want to interact with more than one process at a time you can run more than one console.
If you run X (>startx) you can launch multiple terminal windows and run different commands in each.

Without X you can press Ctrl-Alt-F2
This will switch you to a new console with a login prompt.
Your original terminal session is still there and you can switch back to it with Ctrl-Alt-F1

This also switches to X. If you ran "startx" from terminal 1 then Ctrl-Alt-F1 will switch to X (whatever is running on terminal 1).

You can also also log in from more than one ssh terminal session on your PC / Mac.
Last edited by PiGraham on Tue Jul 02, 2013 8:23 am, edited 1 time in total.

Hades
Posts: 5
Joined: Fri Jun 28, 2013 7:03 pm

Re: sending commands to serial port

Tue Jul 02, 2013 8:19 am

@PiGraham: thank's a lot. Didn't know that.

armyofme
Posts: 41
Joined: Sat Jan 12, 2013 11:28 am

Re: sending commands to serial port

Sat Nov 02, 2013 12:04 am

So pleased to find this page as I was having problems controlling my denon amp via serial and now I can control it via SSH with your script. I'm trying to integrate the script into my home control webpage but I have little scripting knowledge...could you explain what this part of the script does?

Code: Select all

stuff "$1\r"
Thanks!

Hades
Posts: 5
Joined: Fri Jun 28, 2013 7:03 pm

Re: sending commands to serial port

Sat Nov 02, 2013 9:00 pm

stuff "XYZ" tells the specified screen session to execute XYZ.
in my case I tell the screen session to execute the command "$1\r", where
$1 is the first parameter given to the script and
\r is the linefeed the denon avr needs to know the end of the command.

My script is named avrcom.sh, so if I call "avrcom MUON" from the shell, $1=MUON and the script tells the screen session to execute "MUON\r" and the denon avr mutes.

I have rewritten my script "avrcom":

Code: Select all

#! /bin/sh
# /etc/init.d/avrcom

#touch /var/lock/avr2807

case "$1" in
  start)
    if [ "$2" = "log" ]; then
      echo "Starting serial connection to AVR-2807 with logging... "
      /usr/bin/screen -dmS AVR2807 /dev/ttyUSB2 9600
    else 
      echo "Starting serial connection to AVR-2807 without logging... "
      /usr/bin/screen -dmS AVR2807 /dev/ttyUSB2 9600
    fi
  ;;
  stop)
    echo "Stopping serial connection to AVR-2807 ..."
    /usr/bin/screen -S AVR2807 -X kill
  ;;
  restart)
     echo "Restarting serial connection to AVR-2807 ..."
    /usr/bin/screen -S AVR2807 -X kill
    /usr/bin/screen -dmS AVR2807 /dev/ttyUSB2 9600
  ;;
  send)
    if [ -n "$2" ]; then
      /usr/bin/screen -S AVR2807 -X stuff "$2\r"
    else 
      echo "Usage: $0 $1 {command}"
    fi
  ;;
  cmd)
    if [ -n "$2" ]; then
      /usr/bin/screen -dmS AVR2807 /dev/ttyUSB2 9600
      /usr/bin/screen -S AVR2807 -X stuff "$2\r"
      /usr/bin/screen -S AVR2807 -X kill
    else 
      echo "Usage: $0 $1 {command}"
    fi
  ;;
  *)
    echo "Usage: $0 {start (log) | stop | restart | send|cmd command}"
    exit 1
  ;;
esac
exit 0
If you call avrcom with the following parameter
start/stop/restart: starts/stops/restarts a screen session in the background
send XYZ: sends the command XYZ to the existing screen session
cmd XYZ: opens screen session, sends command XYZ and closes the session.

logging doesn't work yet.

Hopes that helps. Feel free to copy/modify the script.

Hades.

armyofme
Posts: 41
Joined: Sat Jan 12, 2013 11:28 am

Re: sending commands to serial port

Sun Nov 03, 2013 3:09 pm

Thanks for your reply Hades - that's helped me understand better what is happening inside the script.

May be you could help me a bit further. Your scripts work great for me from SSH and I'm trying to implement them in my home webpage. Basically my webpage calls a CGI script which sends a command (tellstick) and a parameter to switch on my living room lights. This works great so I thought I could apply this to your script. Only thing is because your script uses screen it needs to be called from my main user not the www-data user that is used on the webpage. So after a bit of research I read how to use a php script to execute the script with my main user. It looks like this:

Code: Select all

<?php
exec("sudo -u armyofme /usr/lib/cgi-bin/denon_cgi");
?>
This calls the CGI script:

Code: Select all

#!/bin/bash
echo "Content-type: text/plain"
echo "" 
screen -dmS 3012CI /dev/ttyUSB0 9600
screen -S 3012CI -X stuff "$1\r"
screen -S 3012CI -X kill
This works but it is obviously not calling the parameter at this stage. This is where I am stuck. I need the php script to call the CGI script plus parameter. So after reading your above post I thought may be I could include the parameters in the webpage like with the tellstick situation. This is what my webpage looks like:

Code: Select all

<html>
<head>
<title>Home Control Page</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<body style="text-align:center" bgcolor="lavender">
</head>

    <script language="javascript">
    var m_XML = false;

    function ProcessResponse()
    {
            if (m_XML.readyState == 4)
            {
                    if (m_XML.status == 200)
                    {
                    }
            }
    }

    function Doxml(act,chan)
    {
            try
            {
                    if (! m_XML)
                    {
                            if (window.XMLHttpRequest)
                            {
                                    m_XML = new XMLHttpRequest();
                            }
                            else if (window.ActiveXObject)
                            {
                                    m_XML = new ActiveXObject("Microsoft.XMLHTTP");
                            }
                    }

                    if (m_XML)
                    {
                            m_XML.open("GET","/cgi-bin/tdtool_cgi?"+act+"&"+chan);
                            m_XML.onreadystatechange = ProcessResponse ;
                            m_XML.send(null);
                    }
            }
            catch (e)
            {
            }
    }
function Doxml4()
    {
            try
            {
                    if (! m_XML)
                    {
                            if (window.XMLHttpRequest)
                            {
                                    m_XML = new XMLHttpRequest();
                            }
                            else if (window.ActiveXObject)
                            {
                                    m_XML = new ActiveXObject("Microsoft.XMLHTTP");
                            }
                    }

                    if (m_XML)
                    {
                            m_XML.open("GET","/cgi-bin/party_cgi");
                            m_XML.onreadystatechange = ProcessResponse ;
                            m_XML.send(null);
                    }
            }
            catch (e)
            {
            }
    }
function Doxml5()
    {
            try
            {
                    if (! m_XML)
                    {
                            if (window.XMLHttpRequest)
                            {
                                    m_XML = new XMLHttpRequest();
                            }
                            else if (window.ActiveXObject)
                            {
                                    m_XML = new ActiveXObject("Microsoft.XMLHTTP");
                            }
                    }

                    if (m_XML)
                    {
                            m_XML.open("GET","/cgi-bin/capital_cgi");
                            m_XML.onreadystatechange = ProcessResponse ;
                            m_XML.send(null);
                    }
            }
            catch (e)
            {
            }
    }	
function Doxml6([color=#FF0000]$1[/color])
    {
            try
            {
                    if (! m_XML)
                    {
                            if (window.XMLHttpRequest)
                            {
                                    m_XML = new XMLHttpRequest();
                            }
                            else if (window.ActiveXObject)
                            {
                                    m_XML = new ActiveXObject("Microsoft.XMLHTTP");
                            }
                    }

                    if (m_XML)
                    {
                            m_XML.open("GET","/cgi-bin/denon.php?"+[color=#FF0000]$1[/color]);
                            m_XML.onreadystatechange = ProcessResponse ;
                            m_XML.send(null);
                    }
            }
            catch (e)
            {
            }
    }	
</script>

    <body>
    <table>
    <tr>
    <td>Living Room Main Light</td>
    <td><button type="button" onclick="Doxml('-f','1')">OFF</button></td>
    <td><button type="button" onclick="Doxml('-v60','-d1')">LOW</button></td>
    <td><button type="button" onclick="Doxml('-v120','-d1')">MID</button></td>
    <td><button type="button" onclick="Doxml('-n','1')">ON</button></td>
    </tr>
    <tr>
    [color=#FF0000]<td>Dining Room Amplifier</td>
    <td><button type="button" onclick="Doxml6('ST02OFF')">OFF</button></td>
    <td><button type="button" onclick="Doxml6('')">VOL-</button></td>
    <td><button type="button" onclick="Doxml6('')">VOL+</button></td>
    <td><button type="button" onclick="Doxml6('ST02ASIG')">ON</button></td>
    </tr>[/color]
    <tr>
    <td>Top Bedroom Main Light</td>
    <td><button type="button" onclick="Doxml('-f','5')">OFF</button></td>
    <td><button type="button" onclick="Doxml('-v60','-d5')">LOW</button></td>
    <td><button type="button" onclick="Doxml('-v90','-d5')">MID</button></td>
    <td><button type="button" onclick="Doxml('-n','5')">ON</button></td>
    </tr>
    <tr> 
    <td>Party Mode</td>
    <td><button type="button" onclick="Doxml4()">Play</button></td>
    </tr> 
    <tr> 
    <td>Capital Radio</td>
    <td><button type="button" onclick="Doxml5()">Play</button></td>
    </tr> 
    </table>
    </html>
Any ideas?

Hades
Posts: 5
Joined: Fri Jun 28, 2013 7:03 pm

Re: sending commands to serial port

Sun Nov 03, 2013 6:02 pm

sorry i can't help you with that.

armyofme
Posts: 41
Joined: Sat Jan 12, 2013 11:28 am

Re: sending commands to serial port

Sun Nov 03, 2013 6:55 pm

No problem, your help so far has been great, thank you.

Anyone else out there with any ideas?

Kendall Bennett
Posts: 1
Joined: Wed Nov 06, 2013 5:02 am

Re: sending commands to serial port

Wed Nov 06, 2013 5:05 am

Try this.

echo "This is a test message" /dev/ttyS0

Not sure about what you are running but looks like a linux build of some type. If the serial port is Com1 then ttyS0 should be that port. Think about it like hard drives Etc.

:) :D :geek:

bruce_miranda
Posts: 7
Joined: Fri Mar 28, 2014 11:52 pm

Re: sending commands to serial port

Fri Mar 28, 2014 11:59 pm

I am doing this too but for a NAD.

If I try and use the echo command I always get

Code: Select all

-bash: /dev/ttyUSB0: Device or resource busy
how do I send data to the serial port.

If I use your workaround of using the screen commands then I can send data to the NAD. But the problem is I don't know how to read the serial port using the screen command. The NAD allows you to query the settings of the amplifier by passing command. But I have not been able to get that to work.

User avatar
Richard-TX
Posts: 1549
Joined: Tue May 28, 2013 3:24 pm
Location: North Texas

Re: sending commands to serial port

Sat Mar 29, 2014 5:02 am

There is a difference between *nix and dos/windows when you hit the enter key. DOS/Win sends a newline and carriage return. where *nix sends only a newline.

Try this command

echo "This is a test message\r\n" > /dev/ttyS0
or
echo -n "This is a test message\r" > /dev/ttyS0

My feeling is that Denon is expecting a CR at EOL. I have seen some devices error when it sees a nl.

As far as your busy resource error goes, try running fuser against the device. Maybe there is a getty running on it.

Code: Select all

# fuser /dev/ttyAMA0
/dev/ttyAMA0:         2618
# ps -ef | grep 2618
root      2618     1  0 Mar28 ttyAMA0  00:00:00 /sbin/getty -L ttyAMA0 115200 vt100
Richard
Doing Unix since 1985.
The 9-25-2013 image of Wheezy can be found at:
http://downloads.raspberrypi.org/raspbian/images/raspbian-2013-09-27/2013-09-25-wheezy-raspbian.zip

User avatar
Richard-TX
Posts: 1549
Joined: Tue May 28, 2013 3:24 pm
Location: North Texas

Re: sending commands to serial port

Sat Mar 29, 2014 5:13 am

One more thing regarding serial ports.

if the default speed of the serial port is not what you need, then you have to change the speed in your script.

Code: Select all

#!/bin/sh
stty 19200  < /dev/ttyAMA0
echo "some command\r" > /dev/ttyAMA0
Richard
Doing Unix since 1985.
The 9-25-2013 image of Wheezy can be found at:
http://downloads.raspberrypi.org/raspbian/images/raspbian-2013-09-27/2013-09-25-wheezy-raspbian.zip

bruce_miranda
Posts: 7
Joined: Fri Mar 28, 2014 11:52 pm

Re: sending commands to serial port

Sat Mar 29, 2014 5:02 pm

I am not doing this on the Denon, but on a NAD. But I don't think that is the issue here. The issue is I can't talk directly to the serial port for some reason. Could it be permissions?

I'm trying this on a Raspbmc installation that has root disabled.

Code: Select all

[email protected]:~$ stty 115200  < /dev/ttyUSB0
-bash: /dev/ttyUSB0: Device or resource busy
whatever I try and do with the serial port directly I get the same message. But with screen command in a script I can send data to the serial port without a problem.

User avatar
Richard-TX
Posts: 1549
Joined: Tue May 28, 2013 3:24 pm
Location: North Texas

Re: sending commands to serial port

Sun Mar 30, 2014 1:14 am

try running your commands when logged in as root.
Richard
Doing Unix since 1985.
The 9-25-2013 image of Wheezy can be found at:
http://downloads.raspberrypi.org/raspbian/images/raspbian-2013-09-27/2013-09-25-wheezy-raspbian.zip

bruce_miranda
Posts: 7
Joined: Fri Mar 28, 2014 11:52 pm

Re: sending commands to serial port

Sun Mar 30, 2014 9:36 pm

root is disabled on raspbmc. What else can I try?

bruce_miranda
Posts: 7
Joined: Fri Mar 28, 2014 11:52 pm

Re: sending commands to serial port

Mon Mar 31, 2014 6:51 pm

Even with root I cannot send a command to the serial port via echo.

Code: Select all

[email protected]:/home/pi# stty
speed 115200 baud; line = 0;
eol = M-^?; eol2 = M-^?;
-brkint ixany
-echok
[email protected]:/home/pi# echo "\rMain.Power=On\r" > /dev/ttyUSB0
I get no errors but the amplifier does not turn on.

But if I run the following commands, it works fine.

Code: Select all

/usr/bin/screen -dmS NADC390DD /dev/ttyUSB0 115200
      /usr/bin/screen -S NADC390DD -X stuff "\rMain.Power=On\r"
      /usr/bin/screen -S NADC390DD -X kill
what else can I try.

bruce_miranda
Posts: 7
Joined: Fri Mar 28, 2014 11:52 pm

Re: sending commands to serial port

Tue Apr 01, 2014 9:46 pm

OK so only screen is able to send the commands to the Serial port. That is OK for any command I need to send the amplifier.

However the amplifier is also able to send me back the status if I send it certain commands. e.g. "Main.Balance.Leveltrim?" should Read the Balance Level trim and return it back via the serial port.

Given that I am sending this command via the screen stuff command, how do I catch what is coming back?

jayedgar
Posts: 1
Joined: Sun Jun 30, 2019 9:34 am

Re: sending commands to serial port

Sun Jun 30, 2019 9:53 am

Hades wrote:
Sat Jun 29, 2013 9:23 pm
sorry. I do not have leds. I do not use a null modem cable. I cannot change the Pins in the cable as it's a ready-bought-adapter.

However, the connection seems to be working because with screen everything works fine, i.e. i can receive and send commands correctly.

I now have a workaround-skript which also works, however only is a workaround:

Code: Select all

screen -dmS AVR2807 /dev/ttyUSB0 9600
screen -S AVR2807 -X stuff "$1\r"
screen -S AVR2807 -X kill
Now if I call this script with e.g. the argument "MUON" the Denon mutes.

Alex.
I had this configuration successfully in use with my Denon AVR for years. After upgrading the kernel to version 4.19.42 v7+ this weekend it seems to be broken. The serial commands are getting stuck. I tried to connect to the serial interface using minicom for a first check and I could not send any commands manually. However, the last command I had issued before via screen was finally sent to the AVR after some time. I guess this is when the serial gets reset by minicom. I was not able to find out more yet. Is anyone facing the same trouble?

moviebrain
Posts: 4
Joined: Mon Oct 30, 2017 5:10 am

Re: sending commands to serial port

Mon Jul 01, 2019 6:29 pm

jayedgar wrote: [quote=Hades post_id=379038 time=<a href="tel:1372541036">1372541036</a> user_id=75030]
sorry. I do not have leds. I do not use a null modem cable. I cannot change the Pins in the cable as it's a ready-bought-adapter.

However, the connection seems to be working because with screen everything works fine, i.e. i can receive and send commands correctly.

I now have a workaround-skript which also works, however only is a workaround:

Code: Select all

screen -dmS AVR2807 /dev/ttyUSB0 9600
screen -S AVR2807 -X stuff "$1\r"
screen -S AVR2807 -X kill
Now if I call this script with e.g. the argument "MUON" the Denon mutes.

Alex.
I had this configuration successfully in use with my Denon AVR for years. After upgrading the kernel to version 4.19.42 v7+ this weekend it seems to be broken. The serial commands are getting stuck. I tried to connect to the serial interface using minicom for a first check and I could not send any commands manually. However, the last command I had issued before via screen was finally sent to the AVR after some time. I guess this is when the serial gets reset by minicom. I was not able to find out more yet. Is anyone facing the same trouble?
[/quote]

Sorry I stumbled on your post. I don't know what process you used to update the kernel but assuming you are now on raspbian Buster have you updated your sources to point to the new buster repos? Try that and see if there is an update to screen, I doubt the Jessie or Stretch binary for screen works in Buster.

Return to “Automation, sensing and robotics”