Hardware button by LAN or WI-FI network

Hi to all,
I wish to create a device system that allow me to remote control VOLUMIO, not by a phone, or PC, not by the GPIO on the PI, but from an arduino board connected by LAN or WI-FI with some physical buttons and a small LCD display.

I’m not sure I’m the first on this Idea (and I’m sure many of you will find it strange), so let me explain, and please suggest if I can find something useful in other FORUM area.
VOLUMIO_NET_CONTROLLER.JPG

Basically the project is a remote controller of VOLUMIO based on TCP/IP communication.

The board I wish to use for this purpose is a ARDUINO LEONARDO ETH: http://www.arduino.org/products/boards/4-arduino-boards/arduino-leonardo-eth.
This is one possible LCD and buttons interface: https://www.sparkfun.com/products/13293

I will be glad to all of you that can suggest where to source the data that I need to send to VOLUMIO for the remote control.

I can’t advice you on arduino selection there are so many different boards :astonished: but you could just get a small and cheap one with built-in wifi.

But I can tell you that you could use ssh to send a single command that gets triggered on your arduino. It’s rather simple.

ssh pi@volumio.local mpc volume 45

Prompts for a password so I would like to advise to login using key files. Otherwise you would need to open ssh up for a user without password or save the password in your scripts.

Hi MobeyDuck,
thank you for your answer, any idea about the rest of the code (I think I need to specify the volumio address on the network and some other things…)?
Do you know where can I get all the string for each command (Play-Pause-Next-Previous)?

:smiley:

You’ll want to talk to mpc so I suggest taking a look at the man page. This is my favourite source

Ok, I have done some test using PUTTY.EXE to estabilish a SSH connection with volumio.
Login in volumio as root, password:volumio
then I tried some command:

mpc
mpc play
mpc volume 70
mpc volume +1
mpc volume -1
mpc next
mpc prev

all are working perfectly!

Now I need only to create a SSH client on my arduino…
At the moment I’m using a Arduino MEGA2560 + Ethernet2 shield (it works with ICSP and left all I/O free).

volumio SSH.JPG

Oh, yes, this is really useful!
Any idea were to source any example of sending the login string with arduino?

Now tested this sketch and I’m able to communicate (based on some example in arduino IDE), but I don’t know how to login properly:

#include <SPI.h>
#include <Ethernet2.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress volumio(192, 168, 2, 35); 
IPAddress ip(192, 168, 2, 100);

EthernetClient client;

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
//  while (!Serial) {
//    ; // wait for serial port to connect. Needed for Leonardo only
//  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(volumio, 22)) {
    Serial.println("connected");

  }
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop()
{
  // if there are incoming bytes available
  // from the server, read them and print them:
  if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

}

This is what i get as feedback in serial monitor:

connecting…
connected
SSH-2.0-OpenSSH_6.0p1 Debian-4

so… something is working…

I’ve found this, it could be helpful. arduino.stackexchange.com/questi … ssh-client

Thank you again, but your link is concerning arduino YUN, that can run LINUX.

My arduino have a really little “power” and seems there is not any way to implement the SSH protocol.

so, I decided to switch to a simplest way, I’m going to use Http calls:

Following some other example of code I found how to up and down the volume (+2 and -2 are the steps, can be adjusted as you like):

client.println("GET /command/?cmd=volume%20+2");
client.println("GET /command/?cmd=volume%20-2");

The triky thing is that you need to re-estabilish the communication with VOLUMIO before each call.
This is the complete sketch actually working fine (need to be cleaned, but working perfectly) :sunglasses: :sunglasses: :sunglasses: :sunglasses: :

[code]

#include <SPI.h>
#include <Ethernet2.h>

int comando = 0;

int VolUP = 3;
int VolDW = 4;
int NextSong = 5;
int PrevSong = 6;

int VolUP_state;
int VolDW_state;
int NextSong_state;
int PrevSong_state;

int last_VolUP_state;
int last_VolDW_state;
int last_NextSong_state;
int last_PrevSong_state;

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don’t want to use DNS (and reduce your sketch size)

IPAddress volumio(192, 168, 2, 35); // name address for VOLUMIO

// Set the static IP address to use if the DHCP fails to assign

IPAddress ip(192, 168, 2, 100);

// Initialize the Ethernet client library
// with the IP address and port of the server
// that you want to connect to (port 80 is default for HTTP):

EthernetClient client;
String serialstring;

void setup() {

pinMode(VolUP, INPUT);
pinMode(VolDW, INPUT);
pinMode(NextSong, INPUT);
pinMode(PrevSong, INPUT);
// Open serial communications and wait for port to open:
Serial.begin(9600);
Serial.println("-- VOLUMIO NET CONTROLLER --");
// start the Ethernet connection:
if (Ethernet.begin(mac) == 0) {
Serial.println(“Failed to configure Ethernet using DHCP”);
// no point in carrying on, so do nothing forevermore:
// try to congifure using IP address instead of DHCP:
Ethernet.begin(mac, ip);
}
// give the Ethernet shield a second to initialize:
delay(1000);
Serial.println(“connecting…”);

// if you get a connection, report back via serial:
if (client.connect(volumio, 80)) {
Serial.println(“connected”);
// Make a HTTP request:
}
else {
// kf you didn’t get a connection to the server:
Serial.println(“connection failed”);
}
}

void loop()
{
// Verifico stato bottoni
VolUP_state = digitalRead(VolUP);
VolDW_state = digitalRead(VolDW);
NextSong_state = digitalRead(NextSong);
PrevSong_state = digitalRead(PrevSong);
if ( VolUP_state != last_VolUP_state ||
VolDW_state != last_VolDW_state ||
NextSong_state != last_NextSong_state ||
PrevSong_state != last_PrevSong_state
){

       if (VolUP_state == HIGH) { comando = 1;}
       if (VolDW_state == HIGH) { comando = 2;}
       if (NextSong_state == HIGH) { comando = 3;}
       if (PrevSong_state == HIGH) { comando = 4;}
       ListaComandi(comando);  
         if (client.available()) 
         {
              char c = client.read();
              Serial.print(c);
         }
     }

       last_VolUP_state = VolUP_state;
       last_VolDW_state = VolDW_state;
       last_NextSong_state = NextSong_state;
       last_PrevSong_state = PrevSong_state;  

if (!client.connected()) {
Serial.println();
Serial.println(“Server disconnected try to connect again”);
client.stop();
// if there’s a successful connection:
if (client.connect(volumio, 80))
{
Serial.println(“connecting…”);
}
else
{
// if you couldn’t make a connection:
Serial.println(“connection failed”);
}

}

}[/code]

And this is the subroutine where to implement the different commands:

[code]void ListaComandi(int Ncmd)
{
switch(Ncmd){
case 1: client.println(“GET /command/?cmd=volume%20+2”);
client.println(“GET /index.php#playback”);
Serial.println(comando);
break;

           case 2: client.println("GET /command/?cmd=volume%20-2");
                   client.println("GET /index.php#playback");
                   Serial.println(comando);
                   break; 

           case 3: client.println("GET /command/?cmd=next");
                   client.println("GET /index.php#playback");  
                   Serial.println(comando);
                   break;
                   
           case 4: client.println("GET /command/?cmd=prev");
                   client.println("GET /index.php#playback");                        
                   Serial.println(comando);
                   break;
                   
         default: ; 
         break;
        }

comando = 0;

}[/code]

:mrgreen: :mrgreen: :mrgreen: :mrgreen: :mrgreen:

NOTE:
Please have a look on arduino.cc where some portion of the above code are taken. Especially this: https://www.arduino.cc/en/Tutorial/WebClientRepeating

The serial print is used for debugging only, can be removed to save computing stress on arduino.

I’m now going to implement more buttons and functions and probably I’ll use a rotary encoder for the volume command.

Thank’s a lot for the cooperation!!