Le programme Processing est un langage de programmation open source qui permet aux utilisateurs de créer des interfaces graphiques et des applications interactives. Il est très populaire auprès des artistes et des designers, car il offre une grande flexibilité et une variété de possibilités créatives. Dans cet article, nous allons nous concentrer sur une application spécifique de Processing : une interface graphique oscilloscope numérique simple avec fenêtre de contrôle. Nous verrons comment cette application peut être utilisée pour afficher des signaux numériques et comment elle peut être personnalisée pour répondre aux besoins spécifiques de l’utilisateur.
Programme Processing : Interface graphique oscilloscope numérique simple avec fenêtre de contrôle
Description
Caractéristiques
- Reçoit sur le port série les valeurs des Y en échelle 0-1023 pour tension 0 – 5V
- Les valeurs doivent être suivie d’un saut de ligne ‘\n’
- Fenêtre taille 40% écran (modifiable dans l’entête du programme
- Quadrillage simple des niveaux de tension (1V à 5V)
- Affichage instantané de la valeur numérique de la tension mesurée en millivolts
- Affiche la limite des niveaux numériques logiques BAS et HAUT compatible carte Arduino
- Fenêtre séparée de contrôle permettant :
- de faire « pause »
- de modifier l’échelle de mesure
- de modifier la base du tracé (expérimental)
Côté Arduino, on utilisera un programme du type :
Ressources utiles
- Ce programme utilise un fichier de police. Pour créer votre propre fichier, une fois votre programme enregistré, allez dans Tools > CreateFont et créer votre fichier. Le fichier de police sera automatiquement créé dans le répertoire de votre programme.
- La police que j’ai utilisé dans ce programme est disponible dans l’archive
Ce programme utilise :
- la librairie GUI ControlP5
- une fenêtre séparée
- un bouton Toggle et 2 slider (réglage linéaire)
- ..
Archive du programme
- Cette archive contient :
- le programme Processing
- le fichier de police utilisé (répertoire data)
- l’application compilée pour Linux, Windows et Mac
Le code du programme processing
A copier / coller dans l’éditeur Processing
Installer la police dans le répertoire de votre programme via Processing > Tools > CreateFont et modifier en conséquence la ligne du fichier police dans le programme !
// généré avec le générateur de code Processing
// X. HINAULT – Janvier 2011 – tous droits réservés
// www.mon-club-elec.fr
/////////////// Description du programme ////////////
// Utilise le port Serie
// Utilise une police texte
/////////////// ENTETE DECLARATIVE ////////////
// inclusion des librairies utilisées
import processing.serial.*; // importe la librairie série processing
import controlP5.*; // importe la librairie GUI controlP5
// cette librairie doit être présente dans le répertoire /libraries du répertoire Processing
// voir ici : http://www.sojamo.de/libraries/controlP5/
// déclaration objets
// — port Série —
Serial myPort; // Création objet désignant le port série
ControlP5 controlP5; // déclare un objet principal de la librairie GUI controlP5
// — police texte —
PFont fontA; // crée un objet de police texte
// déclaration variables globales
int xPos = 1; // variable abscisse – x
int xPos0=1; // variable mémorisation xPos n-1
float yPos=1; // variable yPos – ordonnée
float yPos0=1; // variable yPos n-1
int xTextPos=50; // variable position texte dans la fenêtre
int yTextPos=50;
float coeff=1.0; // coeff mutiplicateur
float base=0.0; // base du tracé en Volt
boolean etatPause=false; // variable témoin appui sur bouton stop
// déclaration objets controlP5
Toggle togglePause; // déclare un/des objets Toggle
Slider sliderCoeff; // déclare un/ des objet Slider
Slider sliderBase; // déclare un/ des objet Slider
ControlWindow cw1; // déclare un/des objet fenetre ControlWindow
/////////////// Fonction SETUP ////////////
void setup(){ // fonction d’initialisation exécutée 1 fois au démarrage
// —- initialisation paramètres graphiques utilisés
colorMode(RGB, 255,255,255); // fixe format couleur R G B pour fill, stroke, etc…
fill(0,0,255); // couleur remplissage RGB
stroke (0,255,0); // couleur pourtour RGB
strokeWeight(1); // largeur du trait en pixels
rectMode(CORNER); // origine rectangle coin sup gauche
// — initialisation fenêtre de base —
//size(200, 200); // ouvre une fenêtre xpixels x ypixels
size(int(screen.width*0.4), int(screen.height*0.4));
// 90% de l’écran par défaut – régler au besoin –
// viser taille maxi en hauteur – taille fenêtre (x,y)
background(0,0,0); // fond fenetre en noir
// — initialisation des fonctionnalités utilisées —
//————- initialisation de la police texte – à mettre avant série —-
fontA = loadFont(« ArialMT-20.vlw »); // charge le fichier police dans l’objet police texte
// ce fichier doit être présent dans un rép <data> dans le répertoire du programme
// pour générer un fichier de police à partir des polices système aller dans Tools > create Fonts
// voir également http://processing.org/learning/text/
textFont(fontA, 10); // Initialise la police et sa taille (en pixels)
//————- initialisation port série —-
println(Serial.list()); // affiche dans la console la liste des ports séries
myPort = new Serial(this, Serial.list()[0], 115200); // Initialise une nouvelle instance du port Série
//myPort = new Serial(this, « /dev/ttyACM0 », 115200); // Initialise une nouvelle instance du port Série
myPort.bufferUntil(‘\n‘); // attendre arrivée d’un saut de ligne pour générer évènement série
//——- tracé initial ———
traceInitial();
//======== Initialisation Objets GUI ControlP5 =========
controlP5 = new ControlP5(this); // initialise l’objet principal de la librairie GUI controlP5
// typeObjet nomObjet=controlP5.addObjet(paramètres); // pour info : déclaration / initialisation possible en 1 ligne
// Textfield field = controlP5.addTextfield(« myWindowTextfield »,70,130,100,20); // exemple
//======== Initialisation Objets ControlWindow =========
// addControlWindow(String theWindowName,int theX, int theY, int theWidth, int theHeight,int theFrameRate)
cw1=controlP5.addControlWindow(« fenetre »,50,50,250,150);// ajoute une fenetre au ControlP5
// méthodes propres à l’objet ControlWindow
cw1.hideCoordinates(); //masque les coordonnées
cw1.setBackground(color(0,0,0));
cw1.frameRate(15); // fixe le nombre de rafraichissement par seconde de la fenetre
//cw1.setColorActive(color(255,0,0)); // fixe la couleur active
cw1.setTitle(« Controle Oscillo »); // titre de la fenetre
//cw1.setLocation(100, 100) ; // fixe la localisation dans la fenetre ?
//cw1..setUndecorated(true); // fixe la bordure de la fenêtre
// ajout de controles à la fenetre ControlWindow
// nomObjet.setWindow(cw1); // met l’objet dans la fenêtre
// b1.setWindow(cw1); // met l’objet dans la fenêtre
// t1.setWindow(cw1); // met l’objet dans la fenêtre
// s1.setWindow(cw1); // met l’objet dans la fenêtre
//======== Initialisation Objets Toggle =========
// addToggle(String theName, boolean theDefaultValue, float theX, float theY, int theWidth, int theHeight)
togglePause=controlP5.addToggle(« togglePause »,false,10,90,20,20); // initialise et ajoute un Button au ControlP5
// méthodes propres à l’objet Toggle
togglePause.setMode(ControlP5.DEFAULT); // fixe le mode de fonctionnement du Toggle : ControlP5.DEFAULT ou ControlP5.SWITCH
togglePause.setWindow(cw1); // met l’objet dans la fenêtre
//t2.setMode(ControlP5.SWITCH); // fixe le mode de fonctionnement du Toggle : ControlP5.DEFAULT ou ControlP5.SWITCH
// méthodes communes à tous les controles (objet Controller)
togglePause.setLabelVisible(true); // affichage des labels
togglePause.setLabel(« Pause »); // fixe label objet
togglePause.setDecimalPrecision(2); // fixe la précision
togglePause.setColorActive(color(255,0,0)); // fixe la couleur active
togglePause.setColorBackground(color(255,0,255)); // fixe couleur fond
togglePause.setColorForeground(color(0,0,255)); // fixe couleur avant
togglePause.setColorCaptionLabel(color(0,255,255)); // fixe couleur Label
togglePause.setColorValueLabel(color(0,0,255)); // fixe la couleur valeur
// setImages(PImage theImageDefault,PImage theImageOver, PImage theImageActive,PImage theImageHighlight)
// les images doivent etre de la meme taille que bouton, dans rép prog, type .jpg .png ..
// un toggle n’utilise que image Default et Active
//t1.setImages(loadImage(« imageDefault.png »),loadImage(« imageDefault.png »), loadImage(« imageActive.png »),loadImage(« imageDefault.png »));
//======== Initialisation Objets Sliders =========
// addSlider(theName, theMin, theMax, theDefaultValue, theX, theY, theW, theH)
sliderCoeff=controlP5.addSlider(« sliderCoeff »,1,10,1,10,10,100,15); // ajoute un Slider au ControlP5
sliderCoeff.setWindow(cw1); // met l’objet dans la fenêtre
//s1 = (Slider)controlP5.controller(« MonSlider1 »); // initialise l’objet Slider déclaré
// méthodes propres à l’objet Slider
sliderCoeff.setNumberOfTickMarks(10); // fixe le nombre crans – n+1 pour n valeurs
//sliderCoeff.setNumberOfTickMarks((int(s1.max())+1); // fixe le nombre crans – n+1 pour n valeurs
sliderCoeff.showTickMarks(true); // affichage des repères
sliderCoeff.setSliderMode(Slider.FLEXIBLE); // fonctionnement du slider FLEXIBLE ou FIX
// méthodes communes à tous les controles (objet Controller)
sliderCoeff.setLabelVisible(true); // affichage des labels
sliderCoeff.setLabel(« Coefficient »); // fixe label objet
sliderCoeff.setDecimalPrecision(2); // fixe la précision
sliderCoeff.setColorActive(color(255,0,0)); // fixe la couleur active
sliderCoeff.setColorBackground(color(255,255,0)); // fixe couleur fond
sliderCoeff.setColorForeground(color(0,0,255)); // fixe couleur avant
//s1.setArrayValue(new float[] {100,255} ); // fixe les valeurs min/max du Slider ?
sliderCoeff.setColorCaptionLabel(color(0,255,255)); // fixe couleur Label
sliderCoeff.setColorValueLabel(color(0,0,255)); // fixe la couleur valeur
//======== Initialisation Objets Sliders =========
// addSlider(theName, theMin, theMax, theDefaultValue, theX, theY, theW, theH)
sliderBase=controlP5.addSlider(« sliderBase »,0,4.5,0,10,50,100,15); // ajoute un Slider au ControlP5
sliderBase.setWindow(cw1); // met l’objet dans la fenêtre
//s1 = (Slider)controlP5.controller(« MonSlider1 »); // initialise l’objet Slider déclaré
// méthodes propres à l’objet Slider
sliderBase.setNumberOfTickMarks(10); // fixe le nombre crans – n+1 pour n valeurs
//sliderCoeff.setNumberOfTickMarks((int(s1.max())+1); // fixe le nombre crans – n+1 pour n valeurs
sliderBase.showTickMarks(true); // affichage des repères
sliderBase.setSliderMode(Slider.FLEXIBLE); // fonctionnement du slider FLEXIBLE ou FIX
// méthodes communes à tous les controles (objet Controller)
sliderBase.setLabelVisible(true); // affichage des labels
sliderBase.setLabel(« Base »); // fixe label objet
sliderBase.setDecimalPrecision(2); // fixe la précision
sliderBase.setColorActive(color(255,0,0)); // fixe la couleur active
sliderBase.setColorBackground(color(255,255,0)); // fixe couleur fond
sliderBase.setColorForeground(color(0,0,255)); // fixe couleur avant
//s1.setArrayValue(new float[] {100,255} ); // fixe les valeurs min/max du Slider ?
sliderBase.setColorCaptionLabel(color(0,255,255)); // fixe couleur Label
sliderBase.setColorValueLabel(color(0,0,255)); // fixe la couleur valeur
} // fin fonction Setup
/////////////// Fonction Draw ////////////
void draw() { // fonction exécutée en boucle
// while(true); // stoppe boucle draw
} // fin de la fonction draw()
/////////////// Autres Fonctions ////////////
//————- Fonction de gestion des évènements série —-
void serialEvent (Serial myPort) { // fonction appelée lors de la survenue d’un évènement série
// ******** Gestion de la valeur reçue sur le port série : **********
String inString = myPort.readStringUntil(‘\n‘); // chaine stockant la chaîne reçue sur le port Série
// saut de ligne en marque de fin
if ((inString != null) && (etatPause==false)) { // si la chaine recue n’est pas vide et toggle pause false
inString = trim(inString); // enlève espace blancs de la chaine recue
int inByte_brut=int(inString); // conversion valeur reçue en valeur numérique entiere
float inByte = float(inString); // conversion valeur reçue en valeur numérique décimale
// ré-échelonne la valeur pour affichage
inByte = map(inByte, 0, 1023, 0, height);
yPos=inByte; // l’ordonnée est la valeur reçue par le port série
yPos=yPos–(base*1023/5.0); // adaptation de la base
yPos=yPos*coeff; // adaptation coeff
//********** affichage numérique de la valeur reçue et autres calculs *****
//—- calcul de la tension à afficher ——–
float tension=float(inByte_brut);
tension=tension*5000;
tension=tension/1023;
tension=tension; // adaptation tracé
// dessin d’un rectangle sous le texte avant affichage pour effacer texte précédent
fill(0,0,0); // couleur de remplissage idem fond
stroke(255,0,0); // fixe la couleur utilisée pour le tracé en RVB
strokeWeight(1); // largeur du trait en pixels
rect(40, 20, 150, 40);
// Use fill() to change the value or color of the text
fill(255,0,0);
text( » « , xTextPos, yTextPos); //efface la valeur précédente
//text(inByte_brut, xTextPos, yTextPos);
textFont(fontA, 20);
text(tension+ » mV », xTextPos, yTextPos);
//*********** gestion du graphique *********
// trace la ligne
stroke(0,255,255); // fixe la couleur utilisée pour le tracé en RVB
strokeWeight(2); // largeur du trait en pixels
line (xPos0,height–yPos0,xPos,height–yPos); // trace une ligne en tenant compte valeur reçue
xPos0=xPos; // mémorisation xPos n-1
yPos0=yPos; // mémorisation xPos n-1
// à la fin de l’écran revient au début
if (xPos >= width) {
xPos = 0;
xPos0=0; // pour retour de la trace sans ligne
background(0,0,0); // couleur du fond
//——- tracé initial ———
traceInitial();
} // fin RAZ graphique
else {
// incrémente la position horizontale (abscisse)
xPos++;
}
} // fin condition chaine recue pas vide
} // fin de la fonction de gestion des évènements Série
void traceInitial() {
fill(0,255,0); // couleur remplissage RGB
stroke (0,255,0); // couleur pourtour RGB
strokeWeight(1); // largeur du trait en pixels
for (int i=0; i<5; i++) {
line (0,height–((height/5)*i), width–1,height–((height/5)*i));
textFont(fontA, 10);
text((i/coeff)+« V (« +int(i*1023/5/coeff)+« ) », 5, height–((height/5)*i)+12);
}
stroke (255,255,0); // couleur pourtour RGB
strokeWeight(2); // largeur du trait en pixels
fill(255,255,0); // couleur remplissage RGB
// — ligne niveau logique bas = 0.3 x Vcc pour carte Arduino (ATmega328) —-
textFont(fontA, 10);
text(« Niveau BAS », 5, (height–(0.3*coeff*height)–5));
line (0,(height–(0.3*coeff*height)), width–1,(height–(0.3*coeff*height)));
// — ligne niveau logique haut = 0.6 x Vcc pour carte Arduino (ATmega328) —
textFont(fontA, 10);
text(« Niveau HAUT », 5, (height–(0.6*coeff*height)–5));
line (0,(height–(0.6*coeff*height)), width–1,(height–(0.6*coeff*height)));
// affichage du coefficient courant
//text(inByte_brut, xTextPos, yTextPos);
fill(0,255,255);
textFont(fontA, 10);
text(« Coeff= x »+coeff,20, 10); // la coordonnée du text est point inf gauche
}
// Evènement Toggle
void togglePause(int theValue) { // fonction évènement Toggle de meme nom – reçoit la valeur
println(« Evènement Toggle Pause avec valeur = « +togglePause.getState());
etatPause=togglePause.getState(); // met à jour la variable etat pause
}
// —— gestion évènement Slider ——
void sliderCoeff(float valeur) { // fonction évènement Slider de meme nom – reçoit la valeur
println(« Evènement Slider Coeff avec valeur = « +valeur);
coeff=valeur; //MAJ variable coeff
// affichage du coefficient courant
//fill(0,0,0);
//text( » « , 10, 10); //efface la valeur précédente
// dessin d’un rectangle sous le texte avant affichage pour effacer texte précédent
fill(0,0,0); // couleur de remplissage idem fond
stroke(0,0,0); // fixe la couleur utilisée pour le tracé en RVB
strokeWeight(0); // largeur du trait en pixels
rect(10, 0, 75, 10);
//text(inByte_brut, xTextPos, yTextPos);
fill(0,255,255);
textFont(fontA, 10);
text(« Coeff= x »+coeff,20, 10); // la coordonnée du text est point inf gauche
delay(100); // évite prise en compte multiple
//traceInitial();
}
// —— gestion évènement Slider ——
void sliderBase(float valeur) { // fonction évènement Slider de meme nom – reçoit la valeur
println(« Evènement Slider Base avec valeur = « +valeur);
base=valeur; // base
delay(100); // évite prise en compte multiple
}
// —– mémo fonctions processing ——-
Articles Liés
- Javascript : Graphique Dygraphs simple
Le Javascript est un langage de programmation très populaire et puissant qui permet aux développeurs…
- Javascript : Graphique Dygraphs : afficher date à partir unixtime
Le langage de programmation Javascript est très populaire et est utilisé pour créer des applications…
- Javascript :Graphique Dygraphs simple avec timeline
Le Javascript est un langage de programmation très populaire et puissant qui permet aux développeurs…