Salut,
J'ai modifié ton code. Le potentiomètre permet de régler un battement cardiaque entre 60 et 180, et modifie la vitesse de rotation du globe, j'ai simplifié le draw() ou il y avait plusieurs choses inutiles. Cette ligne est importante : b += 0.01 + (battement - 60) / 300; c'est ce qui définit la vitesse de rotation du globe. J'ai aussi changé les textures car je n'ai pas tes images, il faut que tu remettes les tiennes...
import processing.serial.*; Serial myPort; // Create object from Serial class float val; // Data received from the serial port import processing.opengl.*; PImage bg ; PImage texmap; float globeRadius = 450; float universeRadius = 2000; float[] cx, cz, sphereX, sphereY, sphereZ; float sinLUT[]; float cosLUT[]; float SINCOS_PRECISION = 0.5; int SINCOS_LENGTH = int(360.0 / SINCOS_PRECISION); float a, b ; int sDetail = 35; float battement = 80; void setup() { size(1440, 800, OPENGL); bg = loadImage("img1.jpg"); initializeSphere(sDetail); texmap = loadImage("img2.jpg"); initializeSphere(sDetail); String portName = Serial.list()[0]; myPort = new Serial(this, portName, 9600); } void draw() { background(0); translate(width/2, height/2); smooth(); specular(0, 0, 0); noStroke(); // rotation de l'univers pushMatrix(); a += 0.01; rotateY(a*2); rotateX(1 / TWO_PI); renderUniverse(); popMatrix(); // rotation du globe pushMatrix(); if ( myPort.available() > 0) { // If data is available, val = myPort.read(); // read it and store it in val battement = map(val, 0, 1023, 60, 180); } b += 0.01 + (battement - 60) / 300; rotateY(b); renderGlobe(); popMatrix(); } void renderUniverse () { textureMode (IMAGE); texturedSphere(universeRadius, bg); } void renderGlobe() { textureMode(IMAGE); texturedSphere(globeRadius, texmap); } void keyPressed() { if (key == '+') battement ++; if (key == '-') battement --; if (key == 'p') println("battement : " + battement); } void initializeSphere(int res) { sinLUT = new float[SINCOS_LENGTH]; cosLUT = new float[SINCOS_LENGTH]; for (int i = 0; i < SINCOS_LENGTH; i++) { sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION); cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION); } float delta = (float)SINCOS_LENGTH/res; float[] cx = new float[res]; float[] cz = new float[res]; // Calc unit circle in XZ plane for (int i = 0; i < res; i++) { cx[i] = -cosLUT[(int) (i*delta) % SINCOS_LENGTH]; cz[i] = sinLUT[(int) (i*delta) % SINCOS_LENGTH]; } // Computing vertexlist vertexlist starts at south pole int vertCount = res * (res-1) + 2; int currVert = 0; // Re-init arrays to store vertices sphereX = new float[vertCount]; sphereY = new float[vertCount]; sphereZ = new float[vertCount]; float angle_step = (SINCOS_LENGTH*0.5f)/res; float angle = angle_step; // Step along Y axis for (int i = 1; i < res; i++) { float curradius = sinLUT[(int) angle % SINCOS_LENGTH]; float currY = -cosLUT[(int) angle % SINCOS_LENGTH]; for (int j = 0; j < res; j++) { sphereX[currVert] = cx[j] * curradius; sphereY[currVert] = currY; sphereZ[currVert++] = cz[j] * curradius; } angle += angle_step; } sDetail = res; } // Generic routine to draw textured sphere void texturedSphere(float r, PImage t) { int v1,v11,v2; r = (r + 240 ) * 0.33; beginShape(TRIANGLE_STRIP); texture(t); float iu=(float)(t.width-1)/(sDetail); float iv=(float)(t.height-1)/(sDetail); float u=0,v=iv; for (int i = 0; i < sDetail; i++) { vertex(0, -r, 0,u,0); vertex(sphereX[i]*r, sphereY[i]*r, sphereZ[i]*r, u, v); u+=iu; } vertex(0, -r, 0,u,0); vertex(sphereX[0]*r, sphereY[0]*r, sphereZ[0]*r, u, v); endShape(); // Middle rings int voff = 0; for(int i = 2; i < sDetail; i++) { v1=v11=voff; voff += sDetail; v2=voff; u=0; beginShape(TRIANGLE_STRIP); texture(t); for (int j = 0; j < sDetail; j++) { vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1++]*r, u, v); vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2++]*r, u, v+iv); u+=iu; } // Close each ring v1=v11; v2=voff; vertex(sphereX[v1]*r, sphereY[v1]*r, sphereZ[v1]*r, u, v); vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v+iv); endShape(); v+=iv; } u=0; // Add the northern cap beginShape(TRIANGLE_STRIP); texture(t); for (int i = 0; i < sDetail; i++) { v2 = voff + i; vertex(sphereX[v2]*r, sphereY[v2]*r, sphereZ[v2]*r, u, v); vertex(0, r, 0,u,v+iv); u+=iu; } vertex(sphereX[voff]*r, sphereY[voff]*r, sphereZ[voff]*r, u, v); endShape(); }
Hors ligne
Salut,
j'ai bien étudier le code que tu m'a proposé et je n'arrive pas à tout comprendre. En fait mes valeurs de battements que j'ai ne varie qu'entre 60 et 65 lorsque je modifie la valeur potentiomètre, et je n'ai pas l'impression de voir accélérer ou décélérer la terre. Rien ne change non plus avec void keypressed ();, Cela dit println fonctionne. Je ne sais pas trop, est-ce qu'il est possible que mon programme Arduino ne soit pas adapté pour communiquer avec ce code dans Processing ? J'ai réglé la carte pour recevoir des info analogiques sur le port 0, faut-il que je serve des entrées numériques?
J'ai juste rajouté quelques données dans void draw(); comme rotateX(radians(-23));
rotateY(radians(-23)); car je souhaite que le globe tourne avec ces angles de rotations, mais rien de très important.
Hors ligne
fdrg a écrit:
En fait mes valeurs de battements que j'ai ne varie qu'entre 60 et 65 lorsque je modifie la valeur potentiomètre, et je n'ai pas l'impression de voir accélérer ou décélérer la terre.
C'est normal que tu ne vois pas grand chose changer entre 60 et 65, l'écart maximum est prévu entre 60 et 180, et donc avec une différence de 5, il ne se passe pas grand chose. Par contre, c'est bizarre que ton potentiomètre ne produise pas un écart plus important. Tu devrais tester les valeurs reçues avec un sketch très simple (juste recevoir les valeurs et les afficher en println), ça permettra de savoir s'il envoie bien des valeurs entre 0 et 1023
fdrg a écrit:
Rien ne change non plus avec void keypressed ();, Cela dit println fonctionne.
C'est normal qu'il ne se passe rien avec keypressed si ton potentiomètre est relié, les valeurs envoyées par arduino définissent le battement, en passant par dessus celles des touches. J'ai utilisé ça car je n'ai pas de potentiomètre / arduino relié, essaie le sketch sans le relier et tu pourras visualiser la "gamme" de vitesse en utilisant le clavier.
fdrg a écrit:
Je ne sais pas trop, est-ce qu'il est possible que mon programme Arduino ne soit pas adapté pour communiquer avec ce code dans Processing ? J'ai réglé la carte pour recevoir des info analogiques sur le port 0, faut-il que je serve des entrées numériques?
Oui c'est logique, le potentiomètre est un composant analogique, par contre je ne peux pas savoir si ton programme arduino déconne, envoie le si tu veux, ou testes avec le sketch très simple comme je te propose plus haut, tu verras si les valeurs sont bien envoyées.
Hors ligne
Salut et merci de ta réponse.
Désolé de ne pas me manifester plus tôt mais les joies d'un master mon appelée à l'écriture théorique! Donc malheureusement pas trop le temps de potasser mon code...
j'ai quand même essayé avec seulement void keypressed () et ca fonctionne parfaitement!
par contre je n'ai pas encore eu le temps de tester mon potentiomètre avec un code simple mais je vais m'y mettre.
voilà pour le code Arduino que j'utilise:
void setup() { // initialize the serial communication: Serial.begin(9600); } void loop() { // send the value of analog input 0: Serial.println(analogRead(0)); // wait a bit for the analog-to-digital converter // to stabilize after the last reading: delay(10); }
je donnerai des nouvelles dès que possible
à bientôt
Hors ligne
Bonjour à tous le monde!
voilà maintenant bien longtemps que je ne vous avais pas donner de nouvelles, mais la rédaction de mon mémoire me prends pas mal de temps...
Par contre j'ai quand même pu avancer dans mon programme que je tente de mettre en place. A ce sujet j'ai enfin réussi à faire correctement dialoguer mon capteur cardiaque et Processing grâce à Firmata standard chargé sur ma carte Arduino.
Maintenant il s'avère qu'un cardio-fréquencemètre n'est pas vraiment très précis, je vais donc tenter d'acquérir un oxymètre qui apparemment le serait plus, et vous tiendrais au courant.
Voilà le code Processing que j'ai obtenu, si quelqu'un avait des suggestion sur celui-ci, je suis preneur.
Par contre je rencontre encore un petit souci qui est que mon globe tourne à présent dans un sens puis dans l'autre. Je pense que c'est du à la polarité, mais je n'ai pas d'idée pour modifier cela dans mon code afin que l' globe ne tourne plus que dans un sens. Est-ce possible?
Je vous remercie.
A bientôt.
Hors ligne
Salut,
c'est la variable 'b' qui définit la rotation du globe, quelles sont ses valeurs ? Pour le savoir rajoute
println("b : " + b);
avant rotateY(b);
Tu peux copier coller les résultats ici, ça devrait permettre de comprendre pourquoi ton globe tourne comme ça
Hors ligne
Salut et merci Emoc,
j'ai rajouté ce que tu m'a conseiller dans le programme et voilà ce que j'obtiens en quelque secondes:
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 17.576666
b : 19.201666
b : 20.014166
b : 21.139166
b : 21.514166
b : 21.951666
b : 21.889166
b : 21.701666
b : 21.201666
b : 20.764166
b : 19.326666
b : 17.389166
b : 15.514167
b : 14.639167
b : 12.951667
b : 12.326667
b : 10.764167
b : 10.014167
b : 8.639167
b : 8.139167
b : 7.3891664
b : 6.8266673
b : 6.639167
b : 6.8266673
b : 7.014167
b : 8.139167
b : 8.639167
b : 9.826667
b : 10.764167
b : 12.389166
b : 13.201667
b : 14.514167
b : 15.201666
b : 15.326667
Je ne comprends pas vraiment pourquoi les valeurs augmentent puis diminues.
J'imagine que ma ligne de code d'incrémentation pour la valeur b ; soit celle de la rotation du globe n'est pas correct. Par contre je ne sais pas non plus pourquoi le globe tourne alternativement dans un sens puis dans un autre.
j'avoue que je suis un peu perdu...
Hors ligne
b correspond à l'angle de rotation Y, il est mis à jour à chaque passage dans draw(), c'est à dire selon le framerate (que tu ne définis pas, donc "aussi vite que possible"), donc l'angle est renouvelé à chaque fois
b est un angle en radians donc entre 0 et 2 x PI (env. 6.28) , par exemple quand b vaut 19.20 la rotation appliquée est de + de 3 tours! La variation de rotation est très importante, vu la liste de valeurs que tu as posté. Je pense que l'effet de rotation inverse est du à ça, c'est le même phénomène quand tu vois une roue de vélo filmée, tu peux avoir l'impression qu'elle va à l'envers mais en fait c'est qu'elle fait un tout petit moins qu'un tour complet et c'est ce moment qui est impressionné sur la pellicule.
Dans ton code b est défini par la valeur venant d'arduino puis modifié dans un 2e temps par la variable 'battement' (ce qui n'a plus d'intérêt dans ton nouveau code) Cette ligne d'incrémentation ne sert pas à grand chose, elle rajoute toujours la même valeur (0.076666...) puisque 'battement' est constant.
Il faut que tu arrives à bien comprendre ce qui sort brut de l'arduino pour voir comment tu 'mappes' ces valeurs, pour avoir une rotation correcte, là je ne comprends pas trop pourquoi tu divises la valeur d'arduino par la largeur de l'image pour ensuite remultiplier par 90 ?
Connais tu les valeurs brutes qui sortent d'arduino? (c'est à dire, ce qu'envoie ton capteur) Avec ça on pourrait probablement y arriver
Hors ligne
Merci Emoc.
En fait lorsque j'essaye de voir se qu'il se passe dans arduino et le moniteur série ne m'indique que ü. Bizarre.
Par contre j'ai changé cette ligne de code float b = arduino.analogRead(0);
à présent le globe tourne à toute vitesse.
j'obtiens ces résultats avec println()
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 0.07666667
b : 208.07666
b : 206.07666
b : 270.07666
b : 283.07666
b : 214.07666
b : 138.07666
b : 118.07667
b : 111.07667
b : 101.07667
b : 94.07667
b : 93.07667
b : 95.07667
b : 105.07667
b : 117.07667
b : 137.07666
ils ont l'air toujours aussi instables mais plus élevés.
Du coup je ne sais pas trop comment faire pour avoir les données que Arduino reçois directement
Hors ligne
fdrg a écrit:
à présent le globe tourne à toute vitesse.
C'est normal, au vu des valeurs pour des angles en radians
fdrg a écrit:
Du coup je ne sais pas trop comment faire pour avoir les données que Arduino reçois directement
A priori, à chaque passage dans draw, la valeur est lue directement sur l'entrée analogique de l'arduino, donc ce sont les valeurs qui viennent du capteur. D'ailleurs que capte réellement ce capteur et que signifient ces valeurs? Dans le petit extrait que tu donnes, on voit bien que ça dessine une courbe avec un pic à 283 puis ça descend et ça remonte.
A ta place, je ferais un graphique des valeurs reçues par le capteur (en Y) dans le temps (en X), ça te permettra de comprendre comment il fonctionne et de voir à partir de ça comment en déduire la pulsation cardiaque.
Hors ligne
Et bien mon capteur est un cardio-fréquencemètre et capte le rythme cardiaque de mon coeur via une ceinture thoracique. Maintenant je me demande si l'utilisation d'un oxymètre que l'on placerait sur un doigt ne serait pas plus précise.
Par contre je n'arrive pas à réaliser un code correcte pour faire un graphique... le voici:
En fait je ne sais pas comment faire pour que String inString interagisse par rapport à Arduino. J'ai pas mal de chose à apprendre encore!
Hors ligne
fdrg a écrit:
Et bien mon capteur est un cardio-fréquencemètre et capte le rythme cardiaque de mon coeur via une ceinture thoracique.
Oui oui, mais que transmet il ? Ce que je veux dire, c'est que je pense que le capteur permet de retrouver la pulsation cardiaque mais qu'il ne transmet pas directement la pulsation. Ce que tu veux obtenir, c'est la pulsation, 90 par exemple, si le capteur transmettait ça, 'b' oscillerait autour de 90 (une fois quelques secondes passées pour obtenir la première valeur). Mais, au vu des valeurs, ça ne marche pas comme ça
Qu'est ce qui ne marche pas dans ton code? (je n'ai pas d'arduino branché) rien ne s'affiche ? tu as des erreurs ?
Hors ligne
Je comprends mieux ta question. En fait se que je capte du cardio-fréquencemètre c'est un signal électrique qui varie à peu près entre 0 et 0,2 volt au voltmètre (mon matos est un peu vieux donc pas vraiment précis je pense).
En fait je cherche exactement à capter la pulsation pour faire varier "b", donc la vitesse de rotation du globe. Mais j'ai apparemment du boulot pour obtenir ca.
Pour mon code de graphique j'ai l'erreur me disant qu'il ne peut pas convertir int vers String.
Hors ligne
fdrg a écrit:
Mais j'ai apparemment du boulot pour obtenir ca.
Pour mon code de graphique j'ai l'erreur me disant qu'il ne peut pas convertir int vers String.
Oui, il y a un traitement à appliquer pour extraire la pulsation de ce signal.
Sinon, pour le code du graphique, arduino doit renvoyer un 'int' plutot qu'un 'string', donc pas besoin de traiter comme une chaine de caractère, l'exemple sur lequel tu te bases doit être adapté, déjà remplace
String inString = arduino.analogRead(0) ;
par
int inInt = arduino.analogRead(0) ;
et adapte la suite avec cette nouvelle variable (tu peux aussi enlever la ligne avec trim)
Hors ligne