Aller au contenu


Photo
- - - - -

[c+] Arduino: Questions diverses


  • Veuillez vous connecter pour répondre
81 réponses à ce sujet

#41 arthael

arthael

    Membre passionné

  • Membres
  • PipPipPip
  • 479 messages
  • Gender:Male

Posté 28 mars 2011 - 07:34

j'utilise processing, et l'a console de l'arduino m'affiche les bonne valeurs..


le code complet de l'arduino:


#include
#include


Servo mservo;

int angle = 90;

int MDAV = 2;
int MDAR = 3;
int MGAV = 4;
int MGAR = 5;

int L = 7;
int V = 8;

int BA = 9;
int BB = 10;

int Tension = 0;

int TBA = 0;
int TBB = 0;

int Move = 0;
int Cam = 0;



void setup() {

Serial.begin(115200);

MsTimer2::set(10 , serie);
MsTimer2::start();

pinMode(MDAV,OUTPUT);
pinMode(MDAR,OUTPUT);
pinMode(MGAV,OUTPUT);
pinMode(MGAR,OUTPUT);

pinMode(L,OUTPUT);
pinMode(V,OUTPUT);

pinMode(BA,OUTPUT);
pinMode(BB,OUTPUT);

mservo.attach(6);
mservo.write(angle);

digitalWrite(BA, HIGH);

delay(100);

TBA = (int) ((analogRead(Tension)*5./1024.)*2000.);

Serial.println(TBA);
delay(10);


digitalWrite(BA, LOW);
digitalWrite(BB, HIGH);

delay(100);

TBB = (int) ((analogRead(Tension)*5./1024.)*200.);
Serial.println(TBB);
delay(10);

digitalWrite(BB, LOW);
digitalWrite(BA, HIGH);




}


void loop() {

move();
cam();
Batt();

}

void cam() {

switch(Cam) {

case 1:

angle = angle + 1;

if(angle > 180)
{
angle = 180;
}

mservo.write(angle);
delay(25);
break;

case 2:

angle = angle - 1;

if(angle < 0)
{
angle = 0;
}

mservo.write(angle);
delay(25);
break;
}


}

void move() {

switch(Move) {

case 1:

digitalWrite(MDAV,HIGH);
digitalWrite(MDAR,LOW);
digitalWrite(MGAV,HIGH);
digitalWrite(MGAR,LOW);
break;

case 2:

digitalWrite(MDAV,LOW);
digitalWrite(MDAR,HIGH);
digitalWrite(MGAV,LOW);
digitalWrite(MGAR,HIGH);
break;

case 3:

digitalWrite(MDAV,LOW);
digitalWrite(MDAR,HIGH);
digitalWrite(MGAV,HIGH);
digitalWrite(MGAR,LOW);
break;

case 4:

digitalWrite(MDAV,HIGH);
digitalWrite(MDAR,LOW);
digitalWrite(MGAV,LOW);
digitalWrite(MGAR,HIGH);
break;

case 0:

ini();
break;

}
}


void ini() {

digitalWrite(MDAV,LOW);
digitalWrite(MDAR,LOW);
digitalWrite(MGAV,LOW);
digitalWrite(MGAR,LOW);

}

void Batt () {

if (TBA < 5600 && digitalRead(BA) == HIGH) {

digitalWrite(BA, LOW);
digitalWrite(BB, HIGH);

}

else if (TBB < 560 && digitalRead(BB) == HIGH) {

digitalWrite(BB, LOW);
digitalWrite(BA, HIGH);

}

else if (digitalRead(BA) == HIGH) {

TBA = (int) ((analogRead(Tension)*5./1024.)*2000.);

}

else if (digitalRead(BB) == HIGH) {

TBB = (int) ((analogRead(Tension)*5./1024.)*200.);

}

Serial.println(TBA);
delay(10);
Serial.println(TBB);
delay(10);

}

void serie () {

if (Serial.available() > 0) {


switch (Serial.read()) {

case 'd':
Move = 3;
break;

case 'q':
Move = 4;
break;

case 'z':
Move = 1;
break;

case 's':
Move = 2;
break;

case 'p':
Cam = 1;
break;

case 'm':
Cam = 2;
break;

case 'l':
digitalWrite(L,HIGH);
break;

case 0:
Move = 0;
break;

case 1:
Cam = 0;
break;

case 2:
digitalWrite(L,LOW);
break;

case 'v':
digitalWrite(V,HIGH);
break;

case 3:
digitalWrite(V,LOW);
break;

}
}
}



[/code]


le code complet processing (c'est un programme test) :


import processing.serial.*;
import processing.video.*;

Serial MySerialPort;

int[] touche = new int[10];
float[] batt = new float[4];

int x = 65;
int y = 110;


void setup() {

println(Serial.list());

MySerialPort = new Serial(this, Serial.list()[0], 115200);

size (1350, 690);
background(0, 0, 0);

PImage robot;
robot = loadImage("DSC02788.JPG");

image(robot,230,10,890,670);



rectMode(CENTER);

fill(127);
rect(x + 50, y + 50, 50, 50);
rect(x , y + 100, 50, 50);
rect(x + 50, y + 100, 50, 50);
rect(x + 100, y + 100, 50, 50);

rect(x , y + 250, 50, 50);
rect(x, y + 300, 50, 50);
rect(x , y + 450, 50, 50);
rect(x, y + 500, 50, 50);

fill(255);
text("Interface de controle", x - 5 , y - 85);
text("DELTA 1715", x + 20 , y - 65);
text("Commande Mouvement", x - 15 , y - 5);
text("Commande Camera", x - 10, y + 195);
text("Commande Fonction", x - 15, y + 395);

text("Haut", x + 50, y + 250);
text("Bas", x + 50, y + 300);
text("Eclairage", x + 50, y + 450);
text("Viseur", x + 50, y + 500);

serie();




}



void draw() {

if (MySerialPort.available() != 0) {

println(MySerialPort.read());

}



}




void keyPressed() {

switch (key) {

case 'p':

touche[4] = 'p';
break;

case 'm':

touche[5] = 'm';
break;

case 'd':

touche[0] = 'd';
break;

case 'q':

touche[1] = 'q';
break;

case 'z':

touche[2] = 'z';
break;

case 's':

touche[3] = 's';
break;


case 'l':

if (touche[6] == 'l') {
touche[6] = 2;
}
else {
touche[6] = 'l';
}

break;

case 'v':

if (touche[7] == 'v') {
touche[7] = 3;
}
else {
touche[7] = 'v';
}

break;

}

serie();

}

void keyReleased() {


switch (key) {

case 'p':

touche[4] = 1;
break;

case 'm':

touche[5] = 1;
break;

case 'd':

touche[0] = 0;
break;

case 'q':

touche[1] = 0;
break;

case 'z':

touche[2] = 0;
break;

case 's':

touche[3] = 0;
break;

}

serie();
}


void Batt () {

if (MySerialPort.read() > 100 && MySerialPort.read() < 200) {

batt[0] = (MySerialPort.read() - 105.6) * 100. / 1.5;




}

if (MySerialPort.read() > 300 && MySerialPort.read() < 400) {

batt[1] = (MySerialPort.read() - 305.6) * 100. / 1.5;

}

println(batt[0]);
println(batt[1]);

}

void serie () {


fill(225);
rect(x + 50, y + 50, 40, 40);
rect(x , y + 100, 40, 40);
rect(x + 50, y + 100, 40, 40);
rect(x + 100, y + 100, 40, 40);

rect(x , y + 250, 40, 40);
rect(x , y + 300, 40, 40);


fill(127);

if (touche[0] == 'd') {
MySerialPort.write('d');
rect(x + 100, y + 100, 40, 40);
}
else if (touche[1] == 'q') {
MySerialPort.write('q');
rect(x , y + 100, 40, 40);
}
else if (touche[2] == 'z') {
MySerialPort.write('z');
rect(x + 50, y + 50, 40, 40);
}
else if (touche[3] == 's') {
MySerialPort.write('s');
rect(x + 50, y + 100, 40, 40);
}
else {
MySerialPort.write(0);
}



if (touche[4] == 'p') {
MySerialPort.write('p');
rect(x , y + 250, 40, 40);
}
else if (touche[5] == 'm') {
MySerialPort.write('m');
rect(x , y + 300, 40, 40);
}
else {
MySerialPort.write(1);
}

if (touche[6] == 'l') {
MySerialPort.write('l');
rect(x , y + 450, 40, 40);
}

else {
fill(225);
MySerialPort.write(2);
rect(x , y + 450, 40, 40);
}

if (touche[7] == 'v') {

fill(127);
MySerialPort.write('v');
rect(x , y + 500, 40, 40);

}
else {

fill(225);
MySerialPort.write(3);
rect(x , y + 500, 40, 40);

}


fill(0);
text("Z", x + 45, y + 55);
text("Q", x - 5, y + 105);
text("S", x + 45, y + 105);
text("D", x + 95, y + 105);

text("P", x - 5 , y + 255);
text("M", x - 5, y + 305);
text("L", x - 5 , y + 455);
text("V", x - 5, y + 505);



}
[/code]

#42 Jbot

Jbot

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 801 messages
  • Gender:Male
  • Location:Paris
  • Interests:Robotics

Posté 28 mars 2011 - 08:09

Je n'ai jamais utilisé processing donc je dis surement une connerie mais :
MySerialPort.read() ne ferait il pas un read octet par octet ?

#43 Hexa Emails

Hexa Emails

    Membre passionné

  • Membres
  • PipPipPip
  • 439 messages
  • Gender:Male

Posté 28 mars 2011 - 08:13

Alors je dois t'avouer que je ne suis pas sur d'avoir compris, mais tu ne dois jamais utiliser la console de l'IDE de l'Arduino ET la liaison série Processing en même temps!

Si tu veux voir ce que tu reçois/envoies, utilise "println" sur le Processing, ça t'affichera ça en bas, là où le programme te dit si la compilation a fonctionné.



EDIT: et je suis d'accord avec JBOT, mais lire un charactère en code ASCII c'est un octet, donc je crois que c'est OK.



EDIT² : bon je vais prendre le temps de tout relire, mais en effet il y a un problème au niveau de la fonction batterie.



RE-EDIT: Bon ta fonction Batt() sur processing ne peut pas fonctionner, mais comme tu n'as pas l'air de t'en servir... ^^



Tiens, voilà un protocole de communication super-puissant et super-OPTIMISÉ ! Encore merci à PoBot quoi. quand je l'ai découvert je me suis senti vraiment débile.



Bon tournage de méninges! ;)

#44 arthael

arthael

    Membre passionné

  • Membres
  • PipPipPip
  • 479 messages
  • Gender:Male

Posté 28 mars 2011 - 08:34

si j'ai bien compris dans son code il utilise un tableau pour les valeur qu'il recoit sur l'arduino. j'ai fait plus ou moins la meme chose mais coté processing (et surement pas aussi optimiser).

et la n'est pas le probleme. la fonction Batt() je l'ai enlever pour fair des teste justement, et je m’aperçois que dans tout les cas les valeur reçu sur process ne sont pas celles envoyé par l'arduino. ni celles reçu par le serial monitor (qui sont les bonnes).

et je n'utilise pas le monitor en meme temps que le process.

#45 Jbot

Jbot

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 801 messages
  • Gender:Male
  • Location:Paris
  • Interests:Robotics

Posté 28 mars 2011 - 08:51

Comme je l'ai deja dis, je pense que tu recois octet par octet, donc quand ton arduino t'envoie 68, toi tu recois 6 (en ascii qui donne 54 en décimal par exemple) puis 8 (en ascii qui donne 56 en décimal) puis un retour à la ligne (13 en décimal).

Il faut que tu convertisse ce que tu recois de l'ascii vers du décimal et que tu ajoute les unités, dixaines, centaines, milliers etc...

#46 arthael

arthael

    Membre passionné

  • Membres
  • PipPipPip
  • 479 messages
  • Gender:Male

Posté 28 mars 2011 - 08:58

ha oui, ça correspond parfaitement au valeur que je trouve, ca envoie a la suite une série de valeur de ce genre. (je me disait bien qu'il y avait un lien ^^)

sinon j'ai trouvé ceci, qui corespond exactement a mon probleme. par contre je ne comprend pas bien ce que fait le code :/

http://forum.pobot.org/topic45.html


#47 Hexa Emails

Hexa Emails

    Membre passionné

  • Membres
  • PipPipPip
  • 439 messages
  • Gender:Male

Posté 28 mars 2011 - 09:59

Dans le code dont j'ai donné le lien, il crée ben un tableau, mais de caractères(char) (donc une chaine de caractères). Et c'est là toute la différence, car un caractère, c'est un octet en code ASCII. Il ne faut pas confondre Serial.print(6) et Serial.print("6") : l'un va renvoyer 6 et l'autre 54 (48+6).

Dans le lien que tu as fourni, ça marche d'une autre manière, plus "simple" dans un sens:
un récupère le 1er octet et on le stocke dans VAL
on décale VAL de 8 bits et on stocke le 2e octet
on recommence avec le 3e octet...[/code]
Etc... Décaler de 8 bits, c'est un peu comme faire dizaine unité etc, mais en binaire ^^
C'est plus "basique", mais moins puissant que le code que je t'ai filé (mais beaucoup moins lourd aussi)

#48 arthael

arthael

    Membre passionné

  • Membres
  • PipPipPip
  • 479 messages
  • Gender:Male

Posté 29 mars 2011 - 06:49

Dans mon cas je n'ai besoin d'envoyé que deux valeur: les tension de mes 2 batterie.
je n'ai peut être pas besoin d'un tableau. (même je crois que je commence a comprendre sont code)

dans l'autre cas, si je recopie tel quel le code, es qu'il supporte des valeur entre 600 et 7000 ??

#49 Hexa Emails

Hexa Emails

    Membre passionné

  • Membres
  • PipPipPip
  • 439 messages
  • Gender:Male

Posté 29 mars 2011 - 05:08

C'est pas si simple. Tu ne peux envoyer que un nombre, entre 0 et 255, via liaison série. Si tu envoies les niveaux de batteries sans protocoles, comment etre sur qu'il ne va pas inverser les 2 valeur ou croire, lorsque tu envoies "z" pour avancer le robot, que ce n'est pas la valeur de la batterie?

Le code que je t'ai filé permet de tout trier:
voici sont fonctionnement, entre chaque numéro on passe au caractère suivant dans la chaîne reçue:

1) on envoie S pour dire que c'est le début
2) on envoie G : il se prépare à recevoir un nombre
3)il stocke le chiffre suivant dans la variable associée à G
4) s'il y a encore un chiffre, il fait G= (G*10 + ce chiffre)
5)refaire l'étape 4 jusqu'a ce que le caractère suivant soit une lettre et pas un chiffre.

Ainsi, si on envoie "SG125" il va recevoir "S" puis "G" puis "1" puis "2" et enfin "5".
il va stocker 1 puis va faire 10*1+2=12 , puis 12*10+5=125. Testé et approuvé.

Tu peux aussi utiliser une autre variable ("D"), et en ajouter.

Ce code permet d'envoyer pas mal de variables différentes (tous les caractère ASCII moins les nombres et ptet certains trucs spéciaux, donc on va dire + de 200), et tu n'est pas limité dans la valeur! (tu peux envoyer de 0 à 9999999 et plus encore, au lieu de 0 à 255)

Remarque: le programme fonctionne aussi bien que tu envoies "SG45D32" ou "SD32G45" et tu peux juste envoyer "SG23" ou "SD45" si tu n'as pas besoin d'actualiser les toutes tes variables.

Jai un peu de mal à expliquer ça de manière claire mais crois moi c'est beaucoup plus efficace que ta méthode (pour l'avoir testé et m'être arraché les cheveux dessus ^^)

#50 arthael

arthael

    Membre passionné

  • Membres
  • PipPipPip
  • 479 messages
  • Gender:Male

Posté 29 mars 2011 - 05:28

bon ok, tu explique assez bien rassure toi :)

pour ce qui est de confondre le z avec la batterie ca risque pas, c'est pas dans le même sens :) (la batterie part du robot, le z part du pc)

ensuite pour ce qui est de différencié les deux batterie j'en multiplie une par 1000, et l'autre par 100. et aprés un simple teste me permet de les différencié.

bref, si j'utilise ce protocole pour transmettre c'est deux tension au pc, je doit donc écrire ce code en processing c'est ca ?.





#51 Hexa Emails

Hexa Emails

    Membre passionné

  • Membres
  • PipPipPip
  • 439 messages
  • Gender:Male

Posté 29 mars 2011 - 05:55

non, tu peux envoyer "simplement" 2 données de ton arduino à ton pc. C'est en gros ce que tu as trouvé sur le forum. Mais c'est peu évolutif...

Voilà le monstre: http://www.mon-club-elec.fr/pmwiki_mon_club_elec/pmwiki.php?n=MAIN.ArduinoExpertSerieGraphiquePCGraphXYCercle

c'est bien ce que je pensais, tu peut créer sous processing un "void serial.event ()" , comme un loop (ou draw) mais qui se déclenche lorsqu'il se passe des choses sur ta liaison série.

Enfin bref, lis, recopies, apprends, et fais un gros mélange bien bordélique de tout ça (comme moi j'ai fait ;) )

#52 arthael

arthael

    Membre passionné

  • Membres
  • PipPipPip
  • 479 messages
  • Gender:Male

Posté 29 mars 2011 - 08:00

bon et bien, j'ai essayé de recopié le code, puisque j'ai que deux valeur a envoyé ca devrait fonctionné assez bien..
Mais sur processing, pas moyen d'avoir la deuxième valeur (celle situé sur les bite de poid fort).

je t'envoie l'code.

arduino: (la fonction Batt est appeler environ toute les seconde)


void Batt () {

if (TBA < 560 && digitalRead(BA) == HIGH) {

digitalWrite(BA, LOW);
digitalWrite(BB, HIGH);

}

else if (TBB < 560 && digitalRead(BB) == HIGH) {

digitalWrite(BB, LOW);
digitalWrite(BA, HIGH);

}

else if (digitalRead(BA) == HIGH) {

TBA = (int) ((analogRead(Tension)*5./1024.)*200.);

}

else if (digitalRead(BB) == HIGH) {

TBB = (int) ((analogRead(Tension)*5./1024.)*200.);

}

calculOutValue (TBA,TBB);

//Serial.println(TBA);

//Serial.println(TBB);

Serial.println(outValue);

}




void calculOutValue ( int valeur_A, int valeur_B) {


outValue=0;
outValue=valeur_B;
outValue=outValue<<16;
outValue=outValue+valeur_A;

}


[/code]


processing:


void serialEvent (Serial MySerialPort) {


String inString = MySerialPort.readStringUntil('\n');

if (inString != null) {

inString = trim(inString);


int inValue = int(inString);



batt[0] = inValue & 65535;

batt[1] = inValue>>16;

batt[0] = batt[0] / 100;

batt[1] = batt[1] / 100;



}

}

[/code]

quand j'affiche le tableau Batt j'ai [0] = 6.88 (environ) et [1] = 0



#53 Hexa Emails

Hexa Emails

    Membre passionné

  • Membres
  • PipPipPip
  • 439 messages
  • Gender:Male

Posté 29 mars 2011 - 08:49

Holala en fait j'étais à coté de la plaque. (j'avais pas compris ce que tu voulais faire)

Mais ça n'empèche que normalement ça devrait marcher X)

tes communications sont uniquement processing -> arduino, sauf la batterie??? ta batterie tu la veux avec quelle précision? (1% ça te suffit?)



#54 arthael

arthael

    Membre passionné

  • Membres
  • PipPipPip
  • 479 messages
  • Gender:Male

Posté 29 mars 2011 - 08:55

bah oui j'envoie des commande a l'arduino depuis processing.

Et je veut recevoir les 2 tensions de mes deux batterie de l'arduino vers processing, a 0.1V prés ca me va.



#55 Hexa Emails

Hexa Emails

    Membre passionné

  • Membres
  • PipPipPip
  • 439 messages
  • Gender:Male

Posté 29 mars 2011 - 09:04

alors tu n'as qu'a reprendre ton principe de dépard, mais en restant dans un octet:

coté arduino

bat2=analogRead(pinbat2);

bat1= map(bat1,1,1023,0,126);
bat2= map(bat2,1,1023,127,255);

serial.print(bat1);
serial.print(bat2);[/code]

coté processing:


octetserie=MySerialPort.read();

if(octetserie <= 127) {
bat1=map(octetserie, 0,127,0,100);
}
else if(octetserie >= 127) {
bat1=map(octetserie, 127,255,0,100);
}[/code]

tu auras une précision supérieure à 1% (si tes batteries font moins de 12,7V tu auras bien ta précision à 0.1V près)

C'est donc toi qui avait la solution la plus simple depuis le début ^^


#56 arthael

arthael

    Membre passionné

  • Membres
  • PipPipPip
  • 479 messages
  • Gender:Male

Posté 29 mars 2011 - 09:18

ok la ca me va ^^ a la différence que je n'ai qu'une pin analog pour tester les deux batterie (je les teste une fois a tour de rôle dans le setup, puis je prend en compte que celle utilisé ;))





#57 Hexa Emails

Hexa Emails

    Membre passionné

  • Membres
  • PipPipPip
  • 439 messages
  • Gender:Male

Posté 29 mars 2011 - 09:28

-_-" donc pourquoi vouloir envoyer les 2?
si tu as le même pin, et que tu n'en utilise qu'un!

#58 arthael

arthael

    Membre passionné

  • Membres
  • PipPipPip
  • 479 messages
  • Gender:Male

Posté 29 mars 2011 - 09:36

par souci de simplicité: j'ai besoin des deux tension sur processing pour faire les jauge!
donc je préfère envoyé les deux en même temps même si il y en qu'une qui change a la fois..

#59 arthael

arthael

    Membre passionné

  • Membres
  • PipPipPip
  • 479 messages
  • Gender:Male

Posté 30 mars 2011 - 08:40

euh.. ca marche pas ta solution :( je reçoit des valeur très bizarre

par contre la solution du dite fonctionne, mais seulement pour une valeur (la B).
je pense qu'il y a un problème au niveau du décalage de l'octet nan ?

EDIT: j'ai résolu le problème c'est bon, j'utilise j'ai fait comme tu m'a dit mais a ma façon ^^ je multiplie une Tension par 10, l'autre par 20. j'envoie les deux avec la methode de l'oscillo. et c'est bon

#60 Hexa Emails

Hexa Emails

    Membre passionné

  • Membres
  • PipPipPip
  • 439 messages
  • Gender:Male

Posté 30 mars 2011 - 05:58

En effet j'avais une erreur dans mon programme (coté Processing) si tu as le temps de le réaissayer. mais bon je persiste à ne pas comprendre l'utilité ^@^




0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users