Go Down

Topic: [résolu]Moniteur et communication série (Read 2053 times) previous topic - next topic

CaptainNapalm

Oct 17, 2012, 01:04 pm Last Edit: Nov 14, 2012, 12:18 pm by CaptainNapalm Reason: 1
Salut à tous,

Assez nouveau sur Arduino (j'ai commencé à bricoler dessus il y a un mois environ), je me frotte pour la première fois à un problème qu'une simple recherche sur le net ne suffit à résoudre. Je me tourne donc vers l'option "poser la question directement".

J'ai codé une petite interface en Python avec Kivy pour controler les 3 canaux d'une led RGB via le port série. Jusque là ça va. Le problème que je rencontre me parait vraiment étrange: si le moniteur série de l'ide arduino est ouvert, tout fonctionne bien, ma led réagit quand j'agis sur l'interface. Mais si je ferme le moniteur série, plus rien, la led s'éteint et ne répond plus, sauf parfois d'un clignotement très bref. Si je rouvre le moniteur, tout redevient normal.

Donc je me demande: le moniteur série est-il indispensable à la communication (il me semblait pas, mais j'ai peut-être raté un truc en route) ?




Grag38

Un bout de code de l'arduino nous aiderait bien.

En principe, non on n'est pas obligé d'ouvrir la console série sur l'arduino pour que çà fonctionne.

Par quel port série passes-tu ? L'usb ou le Tx/Rx de la carte directement ?

B@tto

Si ma mémoire est bonne : le problème vient du fait que le moniteur envoie un RESET (par le DTR), à la connexion et à la déco. Si tu passes par une autre interface (par exemple moi mes prog sont en VB.NET et  je n'ai pas ce problème) tu peux gérer le DTR et donc le RESET (ou non).
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

CaptainNapalm

Le code que j'utilise est le suivant:
Code: [Select]
int rpin = 9; //def des pins de couleur
int gpin = 10;
int bpin = 11;

int rval; //valeurs de led
int gval;
int bval;

int rprev = rval;
int gprev = rval;
int bprev = rval;

void setup()
{
  pinMode(rpin, OUTPUT); //def des E/S
  pinMode(gpin, OUTPUT);
  pinMode(bpin, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
 
  while (Serial.available() )
  {
      int rval = Serial.parseInt();
      int gval = Serial.parseInt();
      int bval = Serial.parseInt();
     
      if(rval >= 0 && rval <= 255 && gval >= 0 && gval <= 255 && bval >= 0 && bval <= 255 && Serial.read() == '\n')
     {
      rprev = rval;
      gprev = gval;
      bprev = bval; 
     }

      analogWrite(rpin, rprev);
      analogWrite(gpin, gprev);
      analogWrite(bpin, bprev);
  }
}


La communication se fait par USB.

Pour ce qui est du reset, j'ai vu pas mal de choses là dessus, mais je ne suis pas sûr que ça soit ça. Puisque si je n'ouvre pas le moniteur, il ne devrait pas faire de reset, et donc la communication devrait s'établir sans lui, non ?

B@tto

Bah oui mais si tu n'envois pas de commande ==> pas d'allumage des LED nan ?
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

CaptainNapalm

#5
Oct 17, 2012, 01:59 pm Last Edit: Oct 17, 2012, 02:18 pm by CaptainNapalm Reason: 1
La commande est envoyé par mon interface en Python sous la forme "ValR,ValG,ValB" que je parse avec Serial.parseInt(), et j'envoie ça dans la led avec les analogWrite. Voilà le code si vous voulez mais je pense pas que le problème soit là. Mon problème c'est que ça marche bien quand le moniteur série est ouvert, et pas quand il est fermé, et je ne comprends absolument pas pourquoi.

le code (y'a que la partie ser.write qui importe, le reste c'est de l'interface graphique)
Code: [Select]
import kivy
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.slider import Slider
from kivy.uix.label import Label
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.checkbox import CheckBox
from kivy.clock import Clock
import serial
import sys

#import ihmtest.py



#class demo(GridLayout):




class app(App):

def build(self):
self.data = str('0,0,0')
demo = GridLayout(cols = 3, rows = 3)

label1 = Label(
text = "R",
)

label2 = Label(
text = "V",
)

label3 = Label(
text = "B",
)

slider1 = Slider(
orientation = 'vertical',
pos_hint = {'x':0.5},
min = 0,
max = 255,
value = 0,
step = 1)
slider2 = Slider(
orientation = 'vertical',
pos_hint = {'x':0.5},
min = 0,
max = 255,
value = 0,
step = 1)

slider3 = Slider(
orientation = 'vertical',
pos_hint = {'x':0.5},
min = 0,
max = 255,
value = 0,
step = 1)



label4 = Label(
text = str(int(slider1.value))
)

label5 = Label(
text = str(int(slider2.value))
)

label6 = Label(
text = str(int(slider3.value))
)

demo.add_widget(label1)
demo.add_widget(label2)
demo.add_widget(label3)

demo.add_widget(slider1)
demo.add_widget(slider2)
demo.add_widget(slider3)

demo.add_widget(label4)
demo.add_widget(label5)
demo.add_widget(label6)


def on_touch_event1(slider1, value):
#print "valR = ", value
label4.text = str(int(value))
update_data()

def on_touch_event2(slider2, value):
#print "valV = ", value
label5.text = str(int(value))
update_data()

def on_touch_event3(slider3, value):
#print "valB = ", value
label6.text = str(int(value))
update_data()

def update_data():
# import serial

self.data = str(int(slider1.value)) + ',' + str(int(slider2.value)) + ',' + str(int(slider3.value)) + '\n'
SERIALPORT = "/dev/tty.usbserial-A6004nYS" ##def du port
try:
ser = serial.Serial(SERIALPORT, 9600)
except serial.SerialException:
print "no device connected - exiting"
sys.exit()
#xprint self.data

ser.write(self.data)



slider1.bind(value = on_touch_event1)
slider2.bind(value = on_touch_event2)
slider3.bind(value = on_touch_event3)

return demo


if __name__ == '__main__':
app().run()







B@tto

Je comprends plus rien xD

Ton code python ne marche que si tu lances le moniteur en même temps ?
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

CaptainNapalm

Oui c'est ça. Enfin sans le moniteur la partie python tourne (mes valeurs s'actualisent sur l'affichage), mais la led reste désespérément éteinte. Et si j'ouvre le moniteur, alors là la led réagit, et je peux faire mumuse avec les couleurs grace à mon interface.
Je sais vraiment pas où regarder pour me débarasser de ça...

B@tto

Oki alors on dirait tout simplement que tu n'ouvres pas ton port dans ton programme, je connais pas python je pourrais pas t'aider mais ça n'a pas l'air d'être coder dans la partie que tu as posté. Le moniteur ne pourrait pas s'ouvrir si le port était déjà ouvert dans ton soft
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

CaptainNapalm

J'ai tenté un truc dans l'idée de ce que tu dis: j'ai calé un ser.open() (ouverture du port donc) dans mon script juste avant le ser.write, et là j'ai un plantage qui me dit "port already open". Qu'à cela ne tienne, je vais le fermer et le rouvrir et tout ira bien. J'ai donc ajouté un ser.close() en tout début de script, et un second juste après le ser.write.
Là ça plante plus. Mais ça a toujours le même comportement vis-à-vis du moniteur (fallait s'y atendre, j'ai juste calé des bouts de code qui s'annulent les uns les autres). Le problème semble pas être là. Peut être qu'il faut que je me penche plus en détail sur mon port usb, mais j'dois avouer que je sais pas comment faire et je suis pas sur d'avoir les compétences nécessaires.

Ce serait possible que le buffer série ne soit accessible que quand le moniteur est ouvert ? Ce serait quand même moyennement logique non ?

B@tto

Ce qui est sûr c'est que le moniteur ne se lance pas si le port est déjà ouvert ailleurs (ça marche avec n'importe programme d'ailleurs, une fois l'accès autorisé il n'y que le programme en question qui a le controle du port). J'avoue que la je sèche, trop de langage différents pour moi xD
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

CaptainNapalm

Je vais aller jeter un oeil sur la gestion des ports en python alors, je trouverai peut être un truc utile. Merci pour tes réponses en tout cas.

B@tto

Demande à Jean-François, je crois que Python ça le connait ;)
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

skywodd

Bonjour,

Avant de rendre python coupable il serait bon de ce pencher sur le code arduino :smiley-mr-green:
Il y a pas mal de chose pas nette dedans ;)

Code: [Select]
const byte rpin = 9;
const byte gpin = 10;
const byte bpin = 11;
/* const = valeur constante -> valeur optimisé à la compilation */
/* int -> byte, pourquoi gâcher 2 octets (int) pour stocker un valeur <255 (1 octet) ! */

/* Les variables rval, gval et bval sont déjà déclaré EN LOCAL dans loop() */

byte rprev = 0;
byte gprev = 0;
byte bprev = 0;
/* Assigner une valeur global avec une autre variable globale NON INITIALISE -> pas bon */
/* Toujours fixer une valeur par défaut constante connu */
/* int -> byte, dans loop() tu test les valeurs pour quelles soit compris entre 0 et 255 */
/* Ps: en réalité ces variables ne servent à rien ;) (voir plus bas pourquoi) */

void setup() {
  pinMode(rpin, OUTPUT);
  pinMode(gpin, OUTPUT);
  pinMode(bpin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
 
  if (Serial.available() > 10) { /* 10 -> valeur arbitraire, à changer dans le code final */
  /* while -> if, loop() en soit est déja une boucle ! */
  /* /!\ Attendre qu'il y ai des info à lire sur Serial (ici au moins 10 char) sinon parseInt() va planter ! */
 
      int rval = Serial.parseInt();
      int gval = Serial.parseInt();
      int bval = Serial.parseInt();
     
      if(rval >= 0 && rval <= 255 && gval >= 0 && gval <= 255 && bval >= 0 && bval <= 255 && Serial.read() == '\n')
     {
  /* analogWrite() n'as besoin d'être appelé que quand on veut changer la valeur d'une pin PWM */
  /* Du coup il devient totalement inutile de stocker la valeur précédente de lapin ;) */
  rprev = rval;
  gprev = gval;
  bprev = bval; 

/* Cette partie du code ne doit être exécuté uniquement lorsque la valeur change */
/* Elle doit donc être DANS le corps du if */
  analogWrite(rpin, rprev);
  analogWrite(gpin, gprev);
  analogWrite(bpin, bprev);
  }
  }
}
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

CaptainNapalm

Salut,

En effet mon code était un peu sale. Ça se voit mieux quand quelqu'un met le doigt sur les erreurs.
Cela dit, ça ne change rien à mon problème, le comprtement reste le même. Mais bon au moins j'ai appris deux trois trucs pour mieux coder. Merci Skywodd.

Go Up