Manipuler serial read

Bonjour,

Je suis un nouveau dans le monde de l'arduino et je suis entrain de faire un quadricopter pour le challenge.

J'en suis arrivé au moment ou je fais ma manette de controle à distance.

Le soucis est que je ne vois pas comment decoder mes données envoyés , je m'explique:

Ma manette est constitué de:

-joystick ( 2 valeurs analog 0 1024)

  • 4 boutons ( 0 oou 1)

Je m'imagine donc envoyer tout ca par exemple en serial sous la forme :

1 1 1 1 512 512

avec tout les boutons a 1 et les potentiometres du joystick a 512.

Le soucis est au niveau de la reception, comment exploiter le tableau buffer ces données?

Pour les bits des boutons ok, juste a incrementer la lecture du buffer bit par bit, mais comment lire les 3 bits des potentiometres?

en gros comment se retrouver avec:

bouton1 = data1( 1bit )

bouton2=data2(1 bit )
...

Pot1=dataA ( 4 bits )
Pot2=dataB( 4 bits )

Par ailleurs, la valeurs de mes potentiometres varient de 0 a 1024 , peut faire en sorte d'envoyer tout le temps 4 bits?
Par exemple au lieu d'envoyer 34 envoyer 0034 .

En esperant avoir été assez clair :slight_smile:

Un peu de lecture: [Tuto] Implémenter un protocole de communication - Tutoriels et cours - Arduino Forum
Le support de transmission n'est pas très important. Les principales librairies pour les liaisons (xbee, wifi, bluetooth) fournissent des fonctions/méthodes qui permettent de récupérer des octets ou des tableaux d'octets. La difficulté est plutôt dans la robustesse de la liaison surtout lorsque c'est un engin volant qui peut être dangereux.

Bonjour tout le monde,
Oui, il est toujours important de faire un effort dans l'écriture quand on pose une question, ce n'est jamais du temps perdu. Si la formulation est claire, on a beaucoup plus de chance de recevoir ensuite des réponses pertinentes.
Quand tu utilise BITs, je crois que tu te trompe. Un BIT est une information binaire élémentaire qui conventionnellement ne peut prendre que deux états "0" et "1".
Dans ton cas, il s'agit je pense de "DIGITS". Du reste ce terme n'est pas très correct. Digital vient des DOIGTS, mais il y a belle heurette (Heurette : Du vieux français qui a donné l’expression « belle lurette ») que l'on n'utilise plus nos appendices des mains et des pieds pour compter. Utiliser le vocable CHIFFRE reste cohérent, même si par la force des habitudes DIGIT est passé dans les us et coutumes des programmeurs.
Au passage, personnellement je trouve toujours un peu dommage d'utiliser le franglisme PIN au lieu de broche. Bref, si vous désirez défendre un peu notre langue maternelle, moyennant quelques petits changements dans nos textes on pourrait faire un grand pad du bon coté.
Sois dit en passant, plus correctement, on devrait parler d'information NUMÉRIQUE et non DIGITALE.
Ouf ... j'ai encore passablement frimé ! :slight_smile:
Revenons à tes préoccupations, car c'est le principal, ne l'oublions pas :
Si j'ai bien compris au moins l'une de tes questions, tu te demandes comment envoyer les zéro en tête quand ta valeur est inférieure à 1000.
Ce n'est pas très difficile à coder je crois. Une séquence du genre :

If (Conversion AN < 10) {Serial.print("0");
If (Conversion AN < 100) {Serial.print("0");
If (Conversion AN < 1000) {Serial.print("0");
Serial.print(MaValeurNumérique);

devrait répondre à ta question.
Amicalement : Nulentout.

Pourquoi ne pas simplement séparer les données par un caractère spécial ? Genre "," ?

A l'émission :

Serial.print(MaValeur1);
Serial.print(",");
Serial.print(MaValeur2);
Serial.print(",");
Serial.print(MaValeur3);
....

A la réception :

int i=0;
int y=0;

long SplitedBuffer[10]={0};

while(Serial.available()) {

char Buffer[20]={'\0'};

while(Serial.read()!=',' || Serial.available()!=0) {

Buffer[i++] = Serial.read();

}

SplitedBuffer[y++]=atol(Buffer);

}

Sinon utiliser strtok() et strtol()

strtok ne fonctionne pas sur avr ?

Si si :wink:

nulentout:
...
Au passage, personnellement je trouve toujours un peu dommage d'utiliser le franglisme PIN au lieu de broche. Bref, si vous désirez défendre un peu notre langue maternelle, moyennant quelques petits changements dans nos textes on pourrait faire un grand pad du bon coté.[/b]
...

:grin: :grin:
C'est souvent un imperatif dans la bonne conception d'un PCB CI :grin:

Les réponses fournies fonctionnent (et correspondent à la demande), mais en fait je crois surtout que la question initiale est mal posée : on a d'un côté un émetteur (la télécommande) et le l'autre un récepteur (quadricopter) pour lesquels il me semble plus que probable que la valeur utile soit la représentation numérique de la quantité mesurée (ie binaire), plutôt que sa représentation ASCII, non ?

Du coup il est certainement plus simple de transmettre directement cette représentation binaire plutôt que de la transformer en suite de caractères avant l'envoi et ensuite de faire l'opération inverse à la réception.

En plus d'alléger la charge du micro, cela aura de plus pour avantage que la taille de la donnée à transmettre est fixe et connue à l'avance : 2 octets, point barre.

Et pour aller encore plus loin, il est probable qu'il faudra implémenter une zone neutre sur les potentiomètres, puis filtrer les parasites/fluctuations aléatoires inhérentes à ce genre de matériel, ce qui au final donnera une valeur «utile» qui très probablement tiendra au final sur seulement 8 bits (0-255). Bingo, plus qu'un seul octet à transmettre :slight_smile:

Mince alors, je ne m'attendais vraiment pas a avoir si mal posé la question :slight_smile:

Alors je reprends

Je veux controler mon drone par le biais d'une manette consituté :

  • Un joysticks ( 2 valeurs analogues de potentiometres axes x et y )
  • 4 boutons , nous les appelerons UP DOWN LEFT RIGHT

J'utilise deux Xbee en ce qui concerne la liaison série , du coup je recois en sérial sur mes broches RX TX.
Je n'ai pas de soucis en ce qui concerne comment transmettre , ce qui m'embette c 'est la reception, et plus precisement comment transcrire ma chaine de DIGITS reçue en variables.

En effet , je veux transmettre les données de ma manette au drone sous cette forme:

UP DOWN LEFT RIGHT X Y

Par exemple si j'appuis sur UP et DOWN et je mets le stick a droite toute j'enverrai:

1 1 0 0 1024 0512

512 est la valeur lue sur ma broche ANALOG d'un axe au repos.
En gros , je passe mes variables en une chaine de DIGITS, je l'envoi, à la réception je reçois la chaîne , et le le problème est que je ne sais pas comment les passer en variables internes, pour ensuite les utiliser.

En terme de solution , j'ai pensé a utiliser un un tableau qui stockera les valeurs récupérées, de taille fixe (ici il a 17 caracteres)
Admettons que je l'appelle BUFFER , j'aurai donc quelque chose de la forme:

UP=Buffer[0];
DOWN=Buffer[2];
LEFT=Buffer[4];
RIGHT=Buffer[6];

Mais comment lire les valeurs sur 4 bits des axes x et y ?

Par ailleurs ma seconde question etait comment envoyer une variable allant de 0 à 1024 de facon a ce qu'elle prenne toujours 4 caracteres ( 0001 ou 0024 et non 1 et 24 )

En esperant que ce soit assez clair dorénavant :slight_smile:

En ce qui concerne les réponses:

fdufnews: J'ai des soucis a lire la doc, apres plusieurs dl, Word m'informe qu'elle est corrompu, suis je le seul?
Effectivement j'ai confondu bit et Digit, les valeurs 1 et 0 de mes boutons m'ont induit en erreur :slight_smile:
Enfin je crois que ce qui repond parfaitement a ma question est strtol() et strok() ! C'est exactement ce que je cherchais :), merci !

Par ailleurs ma question du : avoir 0024 au lieu de 24 , soit toujours envoyer une variable sur 4 DIGITS est toujours en suspens, je suis sur que c est tout bete , mais je ne vois pas la solution !

vouill:
Enfin je crois que ce qui repond parfaitement a ma question est strtol() et strok() ! C'est exactement ce que je cherchais :), merci !

Ou la solution que je t'ai proposé, dans les deux cas ça marche

vouill:
Par ailleurs ma question du : avoir 0024 au lieu de 24 , soit toujours envoyer une variable sur 4 DIGITS est toujours en suspens, je suis sur que c est tout bete , mais je ne vois pas la solution !

Tu te prends la tête pour rien : soit tu sépares tes données comme je te l'ai proposé (à ce moment la tu t'en fout de la taille des valeurs et tu peux transmettre tout ce que tu veux), soit comme tu n'as que des données numériques tu utilises la méthode suggérée par Haifger, soit la transmission en binaire et non en ASCII.

A l'émission :

unsigned int MaValeur 800;

Serial.write(MaValeur>>8);
Serial.write(MaValeur&255);

A la réception :

Byte1=Serial.read();
Byte2=Serial.read();
MaValeur = Byte1<<8 | Byte2;