Go Down

Topic: Aide pour resoudre un problème de communication TCP (Read 706 times) previous topic - next topic

arnaudf09

Bonjour à tous,
Étant débutant en programmation sous Arduino, je suis aujourd'hui confronté à un problème de communication entre un logiciel Light DMX et mon application qui communique en TCP sur le port 7348. J'aurais besoin de votre aide SVP.
L'idée:
Le fabriquant du logiciel Sweetlight utilise le protocole TCP pour communiquer avec des applications externes. J'ai donc crée une petite interface réseau, basée sur une Nano, une carte lan.

Le logiciel du fabriquant attends la consigne HELLO|NomApp|MdP. Une fois reçu, il retourne HELLO si OK ou ERROR NOT LOGGED si erreur de mot de passe Mdp. jusque la je parviens à me logger sur le soft... Ou cela se complique, c'est que je dois attendre que le soft me retourne HELLO ainsi que BEAT_ON. Une fois recu, je dois envoyer un mot BEAT qui à chaque envoie modifiera une valeur dans le soft du fabriquant.
j'utilise la librairie arduino_uip-master qui fonctionne puis que je sais communiquer avec.

Pouvez vous m'aider ?

Code: [Select]


#include <UIPEthernet.h>


EthernetClient client;
EthernetServer server = EthernetServer(7348);

signed long next;

  int BPM = 250;

  int LedPin1_D2 = 2; // Pin de la Led1.

  int BeatInput_D3 = 3;
  int BeatVariable;

 
void setup()
{
  Serial.begin(115200);

  pinMode(LedPin1_D2, OUTPUT);
  pinMode(BeatInput_D3, INPUT);

  uint8_t mac[6] = {0x54,0x55,0x58,0x10,0x00,0x24}; // 54:55:58:10:00:24
  IPAddress myIP(192,168,10,3);

  Ethernet.begin(mac,myIP);

  server.begin();

  Serial.print("localIP: ");
  Serial.println(Ethernet.localIP());
  Serial.print("subnetMask: ");
  Serial.println(Ethernet.subnetMask());
  Serial.print("gatewayIP: ");
  Serial.println(Ethernet.gatewayIP());
  Serial.print("dnsServerIP: ");
  Serial.println(Ethernet.dnsServerIP());

  next = 0; 
}



void loop()
{
  ComA2S2Live();

}



void ComA2S2Live() {

  String Str1Msg2Live = "BEAT";
//  int Str2Msg2Live = BPM;
  String Msg2Live;
 
      if (client.connect(IPAddress(192,168,10,2),7348))
        {
//          Serial.println("Client connected");

          client.println("HELLO|A2S|1234");
   

          client.println("DATA from Client");
          while(client.available()==0)
            {
//              if (next - millis() < 0)
 //               goto close;

            }
          int size;
          while((size = client.available()) > 0)
            {
              uint8_t* msg = (uint8_t*)malloc(size);
              size = client.read(msg,size);
              Serial.write(msg,size);
             
              free(msg);

            }
   
        }

}



biggil

A chaque loop tu connectes ton client, sans jamais le déconnecter. C'est pas super propre.
En fait qu'est-ce qui ne va pas ?
Le code que tu donnes se contente d'afficher les réponses du serveur.





arnaudf09

Le code que j'ai mit est reprit d'exemples de communication TCP de la librairie UIPEthernet...
j'essaie de le modifier afin de réussir à communiquer avec un logiciel.

Avec le code que j'ai, j'arrive à récupérer dans des variables les échanges entre le logiciel et mon appli...

l'idée est de
me connecter à l'application qui communique en TCP sur le port 7348,
lui envoyer HELLO|A2S|Mdp
attendre qu'elle réponde HELLO
attendre qu'elle réponde BEAT_ON
lui envoyer BEAT
attendre qu'elle réponde BEAT_OFF
Se déconnecter.


biggil

Bon, d'accord, mais c'est quoi ta question ?

Tu as un organigramme simple, une liste d'actions.
Pour chaque action tu écris le bout de code, à la queue leu-leu, et hop ça marche.
Non ?

arnaudf09

Le problème c'est que je n'y arrive pas... Ça fait 1 semaine que je suis dessus mais j'ai des problèmes...
En copiant du code dans la librairie uipEthernet, j'arrive à récupérer les mots envoyé par le software, récupérer la réponse et envoyer un mot en retour.
Les problèmes sont:
 Apparition d'une erreur de logging envoyé par le software, alors je ne sais pas pourquoi et quand j'arrive à me connecter, les communications plante...
Je comprends pas...
Je mettrai toute à l'heure mon code et le résultat...

arnaudf09

Pour récupérer les mots envoyés par le software, j'utilise le code suivant:

Code: [Select]


  if (((signed long)(millis() - next)) > 0)
    {
      next = millis() + 100; // 5000
      Serial.println("Client connect");
      // replace hostname with name of machine running tcpserver.pl
//      if (client.connect("server.local",5000))
      if (client.connect(IPAddress(192,168,10,4),7348))
        {
          Serial.println("Client connected");

          client.println("HELLO|A2S|1234"+'\r'+'\n');
         
          client.println("DATA from Client");
          while(client.available()==0)
            {
              if (next - millis() < 0)
                goto close;
            }
          int size;
          while((size = client.available()) > 0)
            {
              uint8_t* msg = (uint8_t*)malloc(size);
              size = client.read(msg,size);
              Serial.write(msg,size);


    if (msg = "ERROR|BAD PASSWORD")
      {
        Serial.print("ERROR|BAD PASSWORD");
        Serial.println(); 
      } // Fin du if (msg = "ERROR | BAD PASSWORD"


    if (msg = "HELLO")
      {
        Serial.print("HELLO Recu");
        Serial.println(); 
      } // Fin du if (msg = "HELLO")


    if (msg = "BEAT_ON")
      {
        Serial.print("BEAT_ON Recu");
        Serial.println(); 
      } // Fin du if (msg = "BEAT_ON")


    if (msg = "BEAT_OFF")
      {
        Serial.print("BEAT_OFF Recu");
        Serial.println(); 
      } // Fin du if (msg = "BEAT_OFF")

             
              free(msg);
            }
close:
          //disconnect client
          Serial.println("Client disconnect");
          client.stop();
        }
      else
        Serial.println("Client connect failed");
    }



le probleme est que j'obtiens des plantages des communications reseaux et j'ai des retours erreur bad password ou erreur non connecté...

biggil

1
il fait que tu apprennes la différence entre = et ==
avec = tu fais une affectation
avec == tu fais une comparaison

2
msg est un pointeur sur un buffet que tu as reservé
"ERROR|BAD PASSWORD" ( ou "HELLO", etc) est un pointeur sur une chaine de caractères quelque part dans la mémoire, là où le programme conserve ces chaines constantes.
Donc msg ne peut jamais être égal à "ERROR|BAD PASSWORD" ou à "HELLO" ou etc..
Pour comparer 2 chaines de caractères, il faut utiliser la fonction strcmp()



arnaudf09

Oui, je viens de faire l'expérience avec le = et ==... je débute, désolé...

pour la 2eme partie, je regarde et reviens...
Merci encore

arnaudf09


j'utilise strcmp et je n'obtiens toujours pas le resultat...


Code: [Select]


// Compare string1 à string2 et retourne 0 si egal
    if (strcmp(msg,"ERROR|NOT LOGGED") == 0)
    {
        Serial.print("ERROR NOT LOGGED");
        Serial.println();
    }
   


arnaudf09

Bon, le problème provient d'ailleurs...
Je compare via la fonction strncmp et non strcmp car ans le cas où la chaîne testée ne se termine pas par un caractère nul, il est nécessaire d'utiliser la fonction strncmp() en précisant la longueur de la chaîne à prendre en compte.
donc:

Code: [Select]


  if ( !strncmp(msg, "ERROR|NOT LOGGED", size) ) {
    // si msg contient "ERROR|NOT LOGGED" ...

  }



Le soucis ensuite vient du fait que le fabriquant du soft retourne un mot constitué du message et de 2 caractères supplémentaire qu'est le retour chariot CR et le saut de ligne LF... donc la size est non plus de 18 caractères dans mon cas mais 18-2=16 donc il a fallut faire la comparaison sur la taille - 2...
Pour info j'ai pu récupérer le message par le bout de code suivant qu'un autre utilisateur que j'oublierais pas de remercier au passage mais je le met pour ceux qui seraient confrontés a mon problème...


code correcte:

Code: [Select]

// Compare string1 à string2 et retourne 0 si egal
// size - 2 car CRLF donc 2 caractères à la fin du string
    if (strncmp(msg,"ERROR|NOT LOGGED",(size-2)) == 0)
    {
        Serial.print("ERROR NOT LOGGED");
        Serial.println();
    }



code pour récupérer le mot reçu


Code: [Select]


// Permet de décoder le mot recu en fonction de sa taille
  Serial.print(size);
  Serial.print(" : ");
  for(int car=0;car<size;car++) {
    Serial.write(msg[car]);
    Serial.write('=');
    Serial.print(msg[car], HEX);
    Serial.write(' ');
  }
  Serial.println();


je continu et je reviens

Merci à tous et @ bientot


arnaudf09

Bon, ca marche, je récupère bien mon mot envoyé, le déchiffre bien et communique bien avec le logiciel du fabriquant.

J'ai un autre problème maintenant...

Je récupère une série de valeurs variant de 0 à 1023 en provenance d'un MSEGQ7 qui est un analyseur de spectre pour sortie des valeurs correspondante à des bandes de fréquences spécifiques 63 Hz, 160 Hz, 400 Hz, 1 kHz, 2.5 kHz, 6.25 kHz and 16 kHz. je les récupères sous la forme
Code: [Select]

  SpectrumValue[i] = analogRead(MSEGQ7AnalogPin);


et j'obtiens
Code: [Select]

Valeurs du Spectre: 224 / 264 / 563 / 655 / 419 / 320 / 221 /


Ensuite je récupère la valeur analogique d'une broche de l'Arduino qui est le signal d'entrée pour ensuite le filtrer via un filtre RC ainsi qu'un bit correspondant au Beat de la musique via le code suivant:

Code: [Select]

void DetectBeat()
{
  if (InputValue > NewHigh) {
    NewHigh = InputValue * CoefficientCalculBeat;
    Counter = 0;
    Serial.println("Beat ON");
    digitalWrite(LedPin1, HIGH);
    DetectionBeat = 1;
    }
    else
    {
    Serial.println("Beat Off");
    digitalWrite(LedPin1, LOW);
    DetectionBeat = 0;
  }



Ensuite, j'ai également une broche d'entrée analogique relié à un potentiomètre afin d'ajuster la sensibilité du système.


Je voudrais trouver une formule afin de détecter la variation (fixée par une valeur) de la Bande 1 du MSGEQ7 Correspondante aux basses afin de les détecter.

Cette valeur correspond a la bande 1 du spectre
Valeurs du Spectre: 224 dans l'exemple

l'idée est d'envoyer soit un BEAT à chaque battement déterminé ou d'envoyer une valeur correspondante aux BPM dans le logiciel du fabriquant...


Le problème est que la bande 1 du spectre varie de 0 à 1024 en fonction de l'intensité musicale envoyée au MSGEQ7. Elle devrait être compensée par la valeur filtrée de la broche d'entrée analogique...

Pouvez vous une fois encore m'aider ???

Un grand merci d'avance





arnaudf09

j'ai trouvé mes réponses...
Je continue. Merci à tous sincèrement

Go Up