Commander MPXPLAY avec Arduino via port COM

Bonjour à tous,

Je suis Couin, dans l'Essonne , et je suis confronté à un problème sur lequel je butte.
J'ai posté sur la partie anglaise du forum mais je me dis qu'il y aura peut être aussi des réponses sur la partie française, donc je poste aussi ici :slight_smile:

J'ai monté un mini pc pour jouer des mp3 dans la voiture. Je l'avais déjà fais sur un véhicule précédent il y a 16 ans , en win98 et winamp + plugin LCD 2x20 car, et télécommande infra rouge.
Cette fois ci, il tourne sous DOS (charge plus rapidement et supporte mieux les coupures à l'arrache lol ).
Le lecteur est MPXPLay ( http://mpxplay.sourceforge.net/ ). Il pilote l'afficheur LCD via LPT1.

Je bloque au niveau de la partie commande. Je pourrais me contenter de hacker un clavier et mapper des boutons sur la carte contrôleur mais c'est bof bof et limité par le nombre de boutons.

Ce lecteur et censé pouvoir être piloté via le port série. Je voudrais donc le piloter via télécommande.

Dans le fichier ini d'MPX, on peut paramétrer les codes pour les différentes commandes du lecteur. Voici une partie des codes :

[serialport]
SerialEnable =1 ; - set to 1 to enable serial control
HandlerCFG =UIR,COM1,9600,6 ; - configure a handler
SerialFunc =45ba00ff0000,0b30 ; '0' - set functions (buttons) for this handler
SerialFunc =45ba807f0000,0231 ; '1'
SerialFunc =45ba40bf0000,0332 ; '2' These values are configured
SerialFunc =45bac03f0000,0433 ; '3' to my remote controller.
SerialFunc =45ba20df0000,0534 ; '4'
SerialFunc =45baa05f0000,0635 ; '5' You can declare max 99 SerialFunc lines (buttons)
SerialFunc =45ba609f0000,0736 ; '6' for one handler.
SerialFunc =45bae01f0000,0837 ; '7'
SerialFunc =45ba10ef0000,0938 ; '8'
SerialFunc =45ba906f0000,0a39 ; '9'
...

Le problème étant de savoir quels sont les codes de la télécommande.

En fouillant, j'ai trouvé un script permettant de révéler (sur le moniteur série), les codes , en décimal et en hexa, de la télécommande, en utilisant la librairie IRremote.h .
Par exemple, la touche "POWER" de la télécommande, donne à priori les codes 367671495 (DEC) ou 15EA38C7 (HEX) .
En rentrant les codes dans SerialFunc, je n’obtiens malheureusement aucun résultat.
J'ai noté que le paramètre IUR était pour un module (genre IRMan) car derrière MPX (en quittant quoi), j'ai lu qu'MPX n'avait pas pu initialisé.
Je peux changer pour COMC ou VT100, à la place de IUR. Je n'ai plus le message d'erreur mais je n'ai rien de mieux d'un point de vu commande du lecteur.

J'ai essayé des tas de scripts arduino pour envoyer des commandes série, mais sans résultat :frowning:
Seul un script a fait remettre la lecture de la musique en cours, au début (équivalent à la touche Entrée du clavier, pour le lecteur), mais ce n’était pas ce qui était demandé (bon au moins ca confirme que le port fonctionne).

J'ai passé des heures à chercher mais à ce jour (y compris en me référant à des infos trouvées dans SERIAL.C du code source d'MPX), je n'ai toujours aucun résultat :frowning:

Si quelqu'un peut me filer un petit coup de palme ca serait super sympa car là je patauge (bon même si pour un canard ca peut paraitre normal lol) complètement :frowning:

Merci et bonne fêtes :slight_smile:
Couin

Je ne connais pas votre appareil mais dans le code de conflit il semble qu’ils utilisent uniquement des minuscules pour le code de la télécommande

SerialFunc =[color=red]45ba00ff0000[/color],[color=blue]0b30[/color] ; '0'

Avez vous essayé avec 15ea38c7 au lieu de 15EA38C7?
Savez vous à quoi correspond la partie en bleu?

Il se peut que votre module ne supporte que des télécommandes parlant suivant une certaine norme - Vous avez un lien à partager sur votre « mini PC »?

J’ai fait une recherche web rapide et j’ai vu ça:

  1. Due to the DOS (or rather the mpxplay.ini keyboard config) compatibility, it's not possible to use the win button at all.

=> il se pourrait que l’histoire de la télécommande ce soit pareil et ne fonctionne pas sous DOS

Sinon sur ce lien il semble dire qu’il a dû écrire pour la version DOS un front end particulier qui balance des lignes de commande DOS

C’est peut être vieux cependant...

Bonjour ,

Merci pour votre réponse rapide :slight_smile:

Effectivement je n'ai pas testé en majuscule, je vais voir pour tester ca :slight_smile:
Le 0b30 correspond à priori au scancode de la touche correspondante au 0 sur un clavier.

Pour ce qui est de la norme télécommande, à la limite, du moment qu'arduino peut recevoir le code, après c'est à lui d'envoyer un bon code que MPXPLay pourrait comprendre. L'idée étant que l'arduino fasse la réception de la télécommande , puis envoie les ordres de pilotage à mpxplay (car à mon avis ca va être hard poru que ce soit direct en mettant le capteur IR sur le port Com).

Ce que je veux dir, c'est que dans la boucle loop, je mets un truc du genre
if (code reçu == 15EA38C7) {
envoies le code (45ba00ff0000);
}

Le lecteur MPXPlay , voici la page internet : http://mpxplay.sourceforge.net/ , la version DOS c'est Mpxplay v1.61 (DOS32A) dans Download area. (Bien que moi j'en suis resté à 1.60 mais ca change pas grand chose entre les deux).
Le code source est Mpxplay v1.61 / MMC v2.00 dans Program Source.

Merci :slight_smile:

Edit :
Ah bah on a posté en mime temps :slight_smile:

Pour le sujet en lien, alors je pense que ca concerne le mappage de touche d'un clavier direct (partie Keyboard dans le fichier .ini ) . Ca permet par exemple , de pouvoir changer de touche pour une fonction. Si on veut que play/pause de ne soit plus la touche 'p' mais la touche 'z' par exemple. Ce qui expliquerait logiquement que les touches Win (et surement d'autres sur les claviers avec des touches multimédia) ne puissent pas être prises en compte.

OK je comprends mieux - comment vous avez envoyé le code sur le port série? Sa représentation en ASCII ou en binaire?

Disons que j'ai essayé pas mal de trucs mais il y a beaucoup d'inconnues (pour moi) , dans l'équation : Je ne sais pas ce qu'il faut choisir dans la config du .ini (à savoir COMC ou VT100, je sais juste pour COM1 et 9600 bauds, mais la valeur après , alors là , mystère ) ni ce qu'arduino envoi réellement comme signal.
Du coup nos deux copains ne dovient pas se comprendre :frowning:
J'ai tenté d'envoyer des 0x0D (correspond à priori à la touche Entrée) coté arduino mais mpx n'a jamais bougé le moindre octet lol

Faudrait lire le code source du programme ... je suis sur mon mobile donc difficile de fouiller dans le zip

Ah oui sur un mobile en effet ce n'est pas évident. C’est d'ailleurs un peu pour ca que je suis plutôt réfractaire à ces appareils :slight_smile:

Par contre je peux mettre les fichiers dézippés sur mon serveur et vous envoyer le lien si vous voulez (en MP, même si j'ai vu votre signature :wink: )

Je l’ai vu sur github en fait si c’est bien cela

Faut regarder il me semble dans SERIAL.C

Sinon j’ai vu le fichier de config, il dit

Serial and parallel port control (send in N bytes on COM/LPT port, execute key-function)
;(port config for COMC and UIR : 8 data bits, 1 stop bit, no parity)
;
; HandlerCFG=handlername,portname,baud,indatalen
;  handlername : COMC, UIR, LPTC, NECIR, VT100, SERMOUS, (TCPIP) (see control\serial.c)
;  portname    : COM1 .. COM4 , LPT1 .. LPT3  (any other: ignored portname/portnumber)
;  baud        : com port setting, max. 115200 (ignored at non-COM handlers)
;  indatalen   : 1 - 16 (ignored at some handlers), or 128 at COMC : direct keyboard codes (2 bytes) (in this mode the SerialFunc lines are not required)
;
; SerialFunc=databytes_in_hexa,keyboard_code_in_hexa (2 hexa numbers = 1 byte)

Ensuite ils ont un exemple

[serialport]
SerialEnable =0               ;     - enable serial control with this
HandlerCFG   =UIR,COM1,9600,6 ;     - configure a handler
SerialFunc =45ba00ff0000,0b30 ; '0' - set functions (buttons) for this handler
SerialFunc =45ba807f0000,0231 ; '1'  
SerialFunc =45ba40bf0000,0332 ; '2'  These values are configured
...
SerialFunc =45ba6a950000,372a ; gray-'*' next album
SerialFunc =45bab04f0000,246a ; 'J' programming (juke box mode)

Ici ça dit que c’est de l'infrarouge (UIR), reçu sur COM1 à 9600 bauds sur 6 octets (Mais faudrait sans doute mettre SerialEnable =1 pour l’activer)

Et on voit ensuite l’association de 45ba00ff0000 à la commande ‘0’. Comme 45ba00ff0000 c’est plus de 6 octets en ascii c’est que le logiciel attend du binaire et on a bien 6 octets 45 ba 00 ff 00 00

Semblerait donc qu’il faut configurer votre arduino en 8 data bits, 1 stop bit, no parity soit en SERIAL_8N1 ce qui est le défaut, donc juste un Serial.begin(9600); si vous mettez en 9600 ensuite dans les param bien sûr et simuler l’entree IR en balançant avec un write les 6 octets qui vont bien sur le port série et comme c’est parametrable pas la peine de vous ennuyer à envoyer 6 octets qui correspondent plus aux télécommandes mais 1 ou 2 octets que vous définissez vous même en fonction des fonctions que vous voulez, du moment que vous changez le 6 de la définition du HandlerCFG en la bonne longueur en octets

Oui, c'est de là, SERIAL.C que je m'étais inspiré pour le 0x0D , si je me souviens bien.

Couin:
Oui, c'est de là, SERIAL.C que je m'étais inspiré pour le 0x0D , si je me souviens bien.

Mais aviez vous activé la partie série et dit commande en 1 octet? (Nb j’ai modifié mon post prétendant pendant que vous tapiez)

Si vous parlez de la ligne SerialEnable dans le .ini, je l’avais en effet passée à 1 au lieu de 0 .
Pour la commande en 1 octet, parlez vous de la ligne qui est en dessous ? (HandlerCFG, après le 9600 ? )
J'ai pensé effectivement au nombre de bits, alors j'avais essayé avec 8 à la place de 6, mais sans succès :frowning:

Oui ça semble être en octets donc je ferais

[serialport]
SerialEnable =[color=red]1[/color]               ;     - enable serial control with this
HandlerCFG   =UIR,COM1,9600,[color=red]1[/color] ;     - configure a handler
SerialFunc =[color=red]0d[/color],0b30 ; '0' - set functions (buttons) for this handler
...

Et vous faites côte arduino

if (codeRecu == 0x15EA38C7) {
   Serial.write (0x0D); 
}

Bien sûr il faut que votre mini pc voit COM1 en port série

Si ça ne fonctionne pas je testerai avec COMC au lieu de UIR

Je viens de tester (j'ai commencé par COMC car UIR, le soft doit visiblement attendre l'initialisation d'un module externe tel IRMan , qui est un petit montage avec un PIC programmable), mais malheureusement, et pourtant j'y croyais , cela ne donne rien :frowning:

Bon, la nuit (et oui moi c'est le matin , car travail de nuit) portant conseil, peut-être que j'aurais une ampoule qui va s'allumer au dessus de ma tête quand je me lèverait (bon on peut y croire non ? :smiley: )

A toute et encore merci :slight_smile:

Bonne nuit :slight_smile:

Il faudrait tester si votre mini pc sait voir le COM1 en port série avec un petit soft DOS si ça se trouve encore genre Kermit (ça doit bien faire 30 ans que je n’ai pas touché du DOS)

Hello :slight_smile:

Merci pour l'astuce Kermit, je l'ai dégotté et mis sur le mini pc.

J'ai paramétré en 9600 8n1.

Sur l'arduino, pour simplifier j'ai fais une boucle qui envoie toutes les secondes :

Serial.write(0x31);
delay(1000);

Malheureusement, je n'obtiens pas de résultat cohérents :frowning:

J’ai testé quelques codes, et j'ai mis le résultat obtenu sur kermit et sur le moniteur série d'arduino IDE :

0x31 : g au lieu de 1
"g" : L au lieu de g
0x79 : C au lieu de y

J'obtiens les mêmes résultats avec Putty sur le pc que j'utilise pour programmer l'arduino.

Pas facile d'y comprendre quelque chose :frowning:

Vous ne pouvez pas avoir la console série arduino ouverte en même temps que la connexion à votre mini pc

Vous êtes bien avec un arduino en 5V ?

Effectivement, mon post n'est pas très clair.

Dans un premier temps je programme l'arduino avec mon pc win10, puis je le débranche (usb) et je le branche sur le mini pc DOS (pour avoir le 5V de la prise USB du mini pc ) et je relie la sortie TX (sortie 1) à l'entrée RX (pin 2) de la prise DB9 que je branche sur le port COM1 du mini PC.
Je constate les résultats avec Kermit.

Dans un second temps, je fais toujours la même méthode de programmation (sur le pc win10), et via un cordon USB - DB9 (qui me crée donc un nouveau port COM sur le pc Win10), je relie la sortie TX de l'arduino à la pin2 de ce nouveau port COM (6), et je consulte ce qu'il se passe sur ce port COM6 avec Putty.
La console série Arduino consulte ce qu'il se passe sur le port COM créé par la connexion USB de l'arduino (COM4).

Mon arduino est un Mega2560 alimenté par sa prise USB.

J'espère que ca a éclairci un peu :slight_smile:

Re :slight_smile:

Alors j’ai pas eu l'ampoule hier mais je l'ai eu en fin de nuit !

En fait, le signal sortant d'Arduino étant de niveau TTL (0v pour état bas, 5v état haut) et la norme RS232 (notamment des anciens port COM) étant -25 à -3v pour état haut et +3 à +25v pour état bas (aussi bizarre que cela puisse paraitre), normal qu'avec 0 ou 5V , le pc ne comprenait rien.

Sur les ports de pc modernes, la majorité des ports COM acceptent des tensions 0 et 5V, mais il faut tout de même inverser les états.

Alors hop hop hop, une petite porte NON (un 7404) entre la sortie TX Arduino et l'entrée RX du port COM et maintenant, Kermit, aussi bien que Putty, affichent correctement !

Ne reste plus que le paramétrage d'MPX, et là on s'y retrouve par rapport à vos suggestions précédentes, puisque je suis parvenu à ce qu'Arduino joue sur la commande play/pause du lecteur.

Donc, pour résumer, on sait jamais dès fois qu'il y en aient que cela intéresse, car on trouve aucune info sur l'internet concernant ce type de montage (bon j'avoue c’est assez exotique, j'aurais aussi pu faire directement tout le player sous arduino mais alors là ca ne doit plus être le même travail lol , mais peut etre qu'un jour ... ) :

  • Un récepteur infra rouge branché sur une entrée de l'arduino, par exemple l'entrée 11.
  • On récupère les codes des touches voulues de la télécommande pour les envoyer sur la console série Arduino :
#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
 Serial.begin(9600);
 irrecv.enableIRIn(); // Initialise le recepteur
}

void loop() {
 if (irrecv.decode(&results)) {
   Serial.print(results.value);
   delay(100);
   irrecv.resume(); // Recoit la valeur suivante
 }
}

(Bien entendu je n'ai pas inventé ce code, c’est un code que j'ai glané sur la toile).

On se note les valeurs pour chaque touches, elles serviront plus tard pour faire les conditions "if" (cd if code reçu, dont je parlais précédemment).

Ensuite on fait un autre programme (oui , il ne s'agit plus d'envoyer le code télécommande sur le port série du pc, bien qu'on pourrait pousser le vice en mettant un petit interrupteur pour changer l'état d'une entrée et on fait un if aussi. On pourrait aussi mettre un petit afficheur LCD etc etc mais pas sur que ca en vaille le coup par rapport au travail nécessaire).
Dans ce programme on y utilisera les "if code reçu" pour que chaque code touche envoie le code ascii correspondant à la touche clavier qu'on veut déclencher (et donc la fonction MPXPLAY correspondante).

Par exemple, on veut que le code déclenche la touche "p" (pour play/pause) :

void loop() {
  if (irrecv.decode(&results)) {

    if (results.value == 367671495) {
    Serial.write(0x70);
    } 

// on met les autres if pour les autres touches ici 

   delay(100);
   irrecv.resume(); // Recoit la valeur suivante
  }
}

On peut mettre un délais supplémentaire sur certaines touches (par exemple si on veut pas que play/pause soit répétées trop rapidement si on appuie un peu trop longtemps sur la touche).

On prends une porte logique "NON" (7404), on relie la sortie TX de l'Arduino à une entrée de porte "NON", puis la sortie de cette porte, reliée à l'entrée RX (Pin 2 sur le connecteur DB9) du port COM.

Si le pc est vraiment vieux et nécessite vraiment des niveaux de tension RS232, rajouter un MAX232.

Dans le fichier ini d'MPXPLAY, dans le bloc [serialport] :

[serialport]
SerialEnable =1               ;     - set to 1 to enable serial control
HandlerCFG   =COMC,COM1,9600,1 ;     - configure a handler
; Les différentes fonctions que l'on veut mettre
SerialFunc =70,1970 ; 'p' play/pause

Et voilà ! Avec ça, normalement quand on appuie sur la touche Play/Pause de la télécommande, l'Arduino envoie le code pour que MPXPLAY fasse Play/Pause aussi.

En tout cas, un très grand merci à vous J-M-L :smiley: Je vais pouvoir avancer sur mon projet grâce à votre aide !

Bon, je vais me coucher :slight_smile:

Super ! Bravo

Notez que vous pourriez balancer directement les codes de la télécommande à votre mini pc

Dans le premier programme qui affiche les code modifiez le pour imprimer le code en hexa

...
void loop() {
 if (irrecv.decode(&results)) {
   Serial.println(results.value, HEX); // code en hexa
   delay(100);
   irrecv.resume(); // Recoit la valeur suivante
 }
}

Vous notez tous les codes de la télécommande

Dans le second programme vous gérez alors toutes les touches en une seule ligne:

if (irrecv.decode(&results)) {
    Serial.write((byte *) &results.value, 4); // 4 c’est sizeof(results.value). 4 octets à envoyer  cf https://github.com/z3t0/Arduino-IRremote/blob/20a4d97f6178efdfcf421e92b3a4ca668d741d9e/IRremote.h#L156
}

et il suffit ensuite d’editer Le fichier de config pour mettre les codes hexa

[serialport]
SerialEnable =1               ;     - set to 1 to enable serial control
HandlerCFG   =COMC,COM1,9600,4 ;     -  4 octets envoyés par touche de la télécommande
; Les différentes fonctions que l'on veut mettre
SerialFunc =xxxxxxxxxx,1970 ; 'p' play/pause 
...

ici le xxxxxxxxxx c’est le code hexa de la touche imprimé par le premier programme —> ATTENTION écrire les lettres en minuscule par exemple le code 0x12AAEFBA est 12aaefba (sans 0x)

Comme cela vous n’avez pas à modifier le programme arduino il est générique et le fichier de config lui est editable à tout moment pour adapter les fonctions aux touches de la télécommande

Enfin puisque vous utilisez une mega vous avez 4 ports Série matériel donc vous pourriez utiliser Serial1 par exemple pour parler au mini pc ce qui vous permettrait de conserver Serial libre pour la programmation ou le debug —> plus rien à débrancher ou rebrancher

Bonne nuit