liaison serie

Bonjour

Je suis Laurent F4FDW et radio amateur et j’ai besoin de vos connaissances pour l’arduino , je désire modifier une liaison entre un soft PC existant et l’arduino , le soft commande un générateur de fréquence DDS , ces commandes fonctionnent avec les , exemple de commande < 1000000A > me donne la fréquence de début pour 1Mhz (valeur en hertz) mais voila le soft que je voudrais utiliser attends cette commande < A1000000 > donc avec le A devant , après pas mal d’essais négatifs je demande conseil aux spécialistes , voici le code d’origine .
merci d’avance
Bonne journée
Laurent

void loop() {
//Check for character
if(Serial.available()>0){
incoming_char = Serial.read();
switch(incoming_char){
case ‘0’:
case ‘1’:
case ‘2’:
case ‘3’:
case ‘4’:
case ‘5’:
case ‘6’:
case ‘7’:
case ‘8’:
case ‘9’:
serial_input_number=serial_input_number10+(incoming_char-‘0’);
break;
case ‘A’:
//Turn frequency into FStart
Fstart_MHz = ((double)serial_input_number)/1000000;
serial_input_number=0;
break;
case ‘B’:
//Turn frequency into FStop
Fstop_MHz = ((double)serial_input_number)/1000000;
serial_input_number=0;
break;
case ‘C’:
//Turn frequency into FStart and set DDS output to single frequency
Fstart_MHz = ((double)serial_input_number)/1000000;
//SetDDSFreq(Fstart_MHz);
SetDDSFreq(Fstart_MHz * 1000000);
delay(100);
SetDDSFreq(Fstart_MHz * 1000000);
serial_input_number=0;
break;
case ‘N’:
// Set number of steps in the sweep
num_steps = serial_input_number;
serial_input_number=0;
break;
case ‘S’:
case ‘s’:
Perform_sweep();
break;
case ‘?’:
// Report current configuration to PC
Serial.print(“Start Freq:”);
Serial.println(Fstart_MHz
1000000);
Serial.print(“Stop Freq:”);
Serial.println(Fstop_MHz*1000000);
Serial.print(“Num Steps:”);
Serial.println(num_steps);
break;
}
Serial.flush();
}
}

Bonjour,
est-ce que votre logiciel PC envoie un caractère “fin de ligne” ou autre à la fin de la commande ?
Je suppose que les <> ne font pas partie du message envoyé sur le port série…
Si oui, il faut transformer le code (qui fonctionne comme une machine à états) en ajoutant une variable d’état (globale) contenant la première lettre reçue (par exemple A). Lorsqu’on reçoit la fin de ligne on exécute la commande qui a été stockée dans cette variable…
Cordialement,
Benoit

Bonjour Benoit

Effectivement les <> ne font pas partie du code , par contre le code peut s’allonger suivant la valeur de la freq.
jusqu’a 10 caractères , comme le dernier chiffre n’est pas toujours le même , il n’y a pas de fin de ligne , si vous avez un exemple simple pour me mettre sur la voie ?
merci encore pour la réponse
Bonne journée

Laurent

Bonjour,

ta description des 2 protocoles est insuffisante, il faut bien que le récepteur sache quel est la condition de fin du message envoyé :

  • caractère de fin ?
  • time out ?
  • validation à la réception du message suivant ?
    il faut que ces choses soient claires dans ton esprit, car en codant la fleur au fusil tu réduis par trop tes chances de trouver la solution

as-tu testé le fonctionnement de l'arduino vers le DDS ?

Bonjour Trimarco

La condition de la commande < f > (il y en a d’autres) est qu’elle est de 10 octets max ou un peu moins si la freq. est moindre , pour cette commande il n’y a pas d’octet de retour , j’ai bien sur testé l’arduino vers le DDS mais avec l’ancien soft PC qui a la commande inversée (la lettre à la fin) et pour le soft que je veut utiliser, NWT de DL4jal , il existe que des montages avec des PIC ce que je veut éviter .

F4fdw:
Bonjour Trimarco

La condition de la commande < f > (il y en a d’autres) est qu’elle est de 10 octets max ou un peu moins si la freq. est moindre , pour cette commande il n’y a pas d’octet de retour , j’ai bien sur testé l’arduino vers le DDS mais avec l’ancien soft PC qui a la commande inversée (la lettre à la fin) et pour le soft que je veut utiliser, NWT de DL4jal , il existe que des montages avec des PIC ce que je veut éviter .

bonjour
quelle est l’ordre de grandeur max de la récurrence de 2 envois de trames ?

J'ai pas trop compris la question !!!
dans le programme j'ai pas vu de temps d'attente entre les trames , une fois les 10 octets envoyés , la commande est terminée , une autre trame qui commence avec une lettre peut donc être envoyé .

F4fdw:
J'ai pas trop compris la question !!!
dans le programme j'ai pas vu de temps d'attente entre les trames , une fois les 10 octets envoyés , la commande est terminée , une autre trame qui commence avec une lettre peut donc être envoyé .

OK ,
je reformule : quel est le delai minimum entre 2 trames ?
reception du dernier caractere d'une trame valide et l'emission du caractère de préambule d'une trame valide suivante
?

l'ancien programme se terminait avec la lettre , ce qui confirmait la fin de la trame , mais pour le temps entre les trames , aucune idée , je pense qu'elle est très courte , l'ancien prog. est ici

https://drive.google.com/file/d/0BwlvRPOr3P29SjZRTGU5RHRKQXc/edit

F4fdw:
l'ancien programme se terminait avec la lettre , ce qui confirmait la fin de la trame , mais pour le temps entre les trames , aucune idée , je pense qu'elle est très courte , l'ancien prog. est ici

https://drive.google.com/file/d/0BwlvRPOr3P29SjZRTGU5RHRKQXc/edit

OK
si je resume ce que j'ai compris :
une trame valide est composée :
d'une lettre ( code ascii 70 pour un F)
suivie de 1 à 10 caracteres ascii representant les chiffres 0/9 ? (48=0 57=9) ?

c'est tout a fait ça , 10 octets avec le f (minuscule) et 9 chiffres max , j'aimerai juste trouver l'astuce pour inverser la lettre dans une commande quelconque .

F4fdw:
c'est tout a fait ça , 10 octets avec le f (minuscule) et 9 chiffres max , j'aimerai juste trouver l'astuce pour inverser la lettre dans une commande quelconque .

programme miniminaliste
attention aucun controle sophistiqué n'est appliqué

byte inByte;

unsigned long freq = 0;
void setup() {
  Serial.begin(57600);//

}

void loop() {


  if (Serial.available() > 0) { //  bytes dispo dans le buffer d'entrée
    inByte = Serial.read();
    if (inByte == 102) { // le byte entrant est le cractere "f"

      freq = 0;
      if (Serial.available() > 0) { // les bytes suivants sont assumés etre les bytes de frequence jusqu'a buffer d'entrée vide (aucun autre controle)
        freq = (freq * 10);
        inByte = Serial.read();
        freq = freq + (inByte - 48);
      }
      Serial.print( "F= ");
      Serial.println(freq) ;
    }
  }
}

Hum je propose une structure comme ceci, code incomplet…
il faut declarer des variables globales temporary_command et temporary_char initialisees a zero et ‘0’.
N’importe quel caractere qui n’est pas un chiffre est interprete comme une fin du chiffre precedent.

  if (incoming_char >= '0' && incoming_char <= '9') {
    temporary_number = temporary_number * 10 + (incoming_char - '0');
  } else {
    // ce n'est pas un chiffre, s'il y a une commande precedente avec un chiffre, stocker le chiffre
    switch(temporary_command) {
       case 'A': Fstart_MHz = ((double)temporary_number)/1000000; break;
       case 'B': ...
       case 'C': ...
       case 'N': ...
       default: // sinon ne rien faire
    }
    temporary_number = 0
    temporary_command = '0'; // not a command
    switch (incoming_char) {
       case 'A':
       case 'B':
       case 'C':
       case 'N':
          temporary_command = incoming_char;// garder pour plus tard
          break;
       case 'S':
          perform_sweep();
          break;
       default:
    }
  }

J'ai essayé vos 2 propositions de code mais ça ne marche pas , pour Artouste ; le f est bien lu mais pas de chiffres , inbyte et freq sont à 0 , pour Casimir pareil temporary command et number sont à 0 ????
je vais continuer les essais demain

rectification , inbyte est a 102 et freq est a 0