Banc de vision et convoyeur

Banc de vision piloté

Fait par :

  • BOUDAOUDI Aissame
  • ANDERHUBER Tom

Objectif

L’objectif de ce projet est de réaliser un banc de vision et convoyeur pour pouvoir scanner des pièces en 3D et repérer les défauts existants. En utilisant un tapis avec un moteur pas à pas, des boutons pour gérer le tapis, des rubans de leds, un capteur de détection de pièces, une caméra et finalement un arduino UNO qui va nous permettre de lier tous ces éléments afin de les faire fonctionner.

Fonctionnement

Une caméra avec leds sur un banc de vision

Nous plaçons une pièce sur le convoyeur, cette pièce est éclairer par des leds afin d’avoir un reflet, une fois que la pièce est détecté par le capteur infrarouge, la caméra de vision prend une photo et analyse la pièce afin de vérifier la pièce et ainsi voir si cette dernière est conforme (présence d’un défaut ou non)

Afin de programmer tout cela nous utiliseront un Arduino UNO, ce dernier vas nous permettre de faire fonctionner les boutons poussoirs, le capteur infrarouge, le moteur du banc de vision et les bandeaux leds

Nous allons également utiliser anaconda afin de réaliser une liaison série qui vas nous permettre de contrôler le programme à distance via un ordinateur.

Nous avons décidé d’utiliser deux boutons et un switch.

Un bouton va gérer la fonction marche/arrêt du tapis, un deuxième bouton est pour l’instant libre, il ne fait rien, on l’a installé pour pouvoir le coder et programmer. Le switch va gérer le sens du tapis, en changeant la position du Switch on change le sens de rotation du tapis.

Partie électrique

Schéma de câblage

(Fichier disponible sur la plateforme ED campus )

  • On peut voir qu’on utilise un différentielle afin de protéger l’installation d’un défaut de tension, et couper la tension en cas de problème.

En ce qui concerne le matériel utilisé :

  • Arduino UNO
  • COnvertisseur 230V en 24V, 12V, et 5V
  • Différentielle merlin gerin multi 9 DPN vigi
  • Carte de commande Micrositch driver
  • Deux bouton, un switch
  • Un capteur de détection de pièces
  • Un Tapis avec moteur pas à pas

Plaque électronique

Partie code

On a fourni la code complet dans un fichier « ino » sur la plateforme EDCampus

Pour la partie code du projet, on a utilisé le logiciel arduino , et le langage C++ pour pouvoir donner des instructions bien précises à l’arduino et pouvoir le piloter aussi à distance en utilisant un ordinateur.

Le point de plus qui change cette année en comparant les deux projets celui de l’année dernière et l’actuel en tout ce qui est code c’est l’utilisation du TIMER, on va utiliser un Timer pour pouvoir gérer le tapis au lieu de le faire rouler avec des pas et des temporisations qui n’est pas pratique.

Bibliothèques

Pour pouvoir gérer les Leds, on utilisera une bibliothèque spécifique aux types des Leds utilisés « Adafruit_Neopixel » qu’on va intégrer dans notre code: #include <Adafruit_Neopixel.h>.

Ensuite On va créer quatre variables qu’on va utiliser pour configurer cette bibliothèque, on a choisi LED1_COUNT, LED1_PIN, LED2_COUNT et LED2_PIN, dont le rôle est de choisir un pin pour chaque ruban de leds et une autre qui va compter les leds de chaque ruban. On choisit après chaque ruban et on affecte ces variables au ruban.

//Bilbliothèque des Leds
Adafruit_NeoPixel strip1 = Adafruit_NeoPixel(LED1_COUNT, LED1_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel strip2 = Adafruit_NeoPixel(LED2_COUNT, LED2_PIN, NEO_GRB + NEO_KHZ800);

Définition des Pins

On a définit les Pins de l’Arduino comme suit :

  • Pin 1 du Switch : 7
  • Pin 2 du Switch : 8
  • Pin du premier bouton : 2
  • Pin du deuxième bouton : 13
  • Pin du timer : 9
  • Pin qui gère le sens du tapis : 5
  • Pin pour alimenter le tapis : 6
  • Pin du premier ruban des leds : 3
  • Pin du deuxième ruban des leds : 4
  • Premier Pin de la caméra : 10
  • Deuxième Pin de la caméra : 11
//Définition des Pins
# define Switch_1 7
# define Switch_2 8
# define Entree_Bouton 2
# define Entree_Bouton2 13
# define OC1a_Timer 9
# define Sens_Tapis 5
# define Alim_Tapis 6

//led pin
#define LED1_PIN  3
#define LED1_COUNT  25
#define LED2_PIN  4
#define LED2_COUNT  25

//camera pins
#define CAM1_PIN 10
#define CAM2_PIN 11

Déclaration des varaiables globales

Pour pouvoir gérer les Leds on a créé les variables suivantes : br1, br2, r1, r2, g1, g2, b1, b2, rg1_1, rg1_2, rg2_1, rg2_2. PB1_state et PB2_state pour savoir si le bouton est appuyé ou relâché.

numChars est une variable qui va nous servir dans la liaison série pour pouvoir envoyer ou recevoir un nombre limité de caractères, et receivedChars est un tableau qui va contenir les caractères envoyés ou reçu. newData est juste un booléen qui est égal soit à 0 ou 1 et qui dépend de la réception du caractère (reçu ou non). Par défaut on lu affecte la valeur 0 ( ou False.)

Ensuite passons aux variables qu’on va utiliser pour gérer nos boutons :

– lastbottonstat est la variable qui va nous informer du dernier événement appliqué sur le bouton

– currentbottonstat est l’état actuel du bouton

–  tapistat est l’état du tapis s’il est en marche ou pas.

//Déclaration variables globales

//vriables leds
int br1, br2, r1, r2, g1, g2, b1, b2, rg1_1, rg1_2, rg2_1, rg2_2;
 
int PB1_state, PB2_state; //variables boutons


const byte numChars = 200;
char receivedChars[numChars];
boolean newData = false;



//variables boutons
bool lastbottonstat=LOW;
bool currentbottonstat=LOW;
bool tapistat=LOW;

On commence notre code finalement en initialiisant la liaison en série, on va choisir une vitesse de 9600 bauds avec un délai de 300 ms, et on va mettre cette inialisation dans la fonction void setup comme suit :

Serial.begin(9600); //Liaison en série
delay(300);

Et juste après, on initialise aussi le TIMER 1 de l’arduino Uno en choisisant une fréquence d’échentillonnage de 16 MHz.

TCCR1B = 0x18; // 0001 1000, Disable Timer Clock 
TCCR1A = 0xA2; // 1010 0010

ICR1 = 1400;
OCR1A = (int) (ICR1 * 0.25);
OCR1B = (int) (ICR1 * 0.50);
TCNT1=0x0;

TCCR1B |= 1; // Prescale=1, Enable Timer Clock

Toujours dans la fonction setup, on passe à l’étape de choix de Pins. Après déclarer et affecter les Pins à des variables précis, on choisit le mode de chaque Pin.

//Choix des Pins
  pinMode(Switch_1,INPUT_PULLUP);
  pinMode(Switch_2,INPUT_PULLUP);
  pinMode(Entree_Bouton,INPUT_PULLUP);
  pinMode(Entree_Bouton2,INPUT_PULLUP);
  pinMode(OC1a_Timer, OUTPUT);  // OC1a
  pinMode(Alim_Tapis,OUTPUT);
  pinMode(Sens_Tapis,OUTPUT);
  digitalWrite(Sens_Tapis,HIGH);
  digitalWrite(Alim_Tapis,LOW);
  digitalWrite(Entree_Bouton,HIGH);
  digitalWrite(Entree_Bouton2,HIGH);
  digitalWrite(Switch_1,HIGH);
  digitalWrite(Switch_2,HIGH);

Ensuite, on configure les leds à une valeur par défaut, pour pouvoir s’activer et afficher au moins une couleur au démarrage et quand on change pas la valeur du degré soir du bleu, rouge ou vert de chaque ruban. les variables sont décrites comme suit:

  • br1/2 est le degré de luminosité des rubans
  • r1/2 est la valeur de la couleur rouge
  • b1/2 est la valeur de la couleur bleu
  • g1/2 est la valeur de la couleur verte
  • rg1-1/2 est le nombre des leds dans chaque ruban
//Configuration des Leds
  br1 = 100;
    r1 = 255;
    g1 = 255;
    b1 = 255;
    rg1_1 = 0;
    rg1_2 = LED1_COUNT-1;
    strip1.begin();
    strip1.show();

    br2 = 100;
    r2 = 255;
    g2 = 255;
    b2 = 255;
    rg2_1 = 0;
    rg2_2 = LED2_COUNT-1;
    strip2.begin();
    strip2.show();


Fonctions utilisés

recvWithStartEndMarkers()

Cette fonction sert à recevoir des caractères en utilisant la liaison en série . Après vérifier qu’il n’y a pas de nouveaux Data qui arrive on recois les caratères et on les place dans notre tableau receivedChar sinon on patiente.

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;
 
    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // terminate the string
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

ProcessNewData()

La fonction ProcessNewData sert à lire le caractères reçus. Si la valeur de newData est égale à 1 on lis les caratère reçus, si c’est

  • « Go » = Le tapis marche
  • « NoGo »: Le tapis s’arrête
  • « RightLeft » : le tapis tourne de droite à gauche
  • « LeftRight » : le tapis tourne au sens inverse de gauche à droite
  • « V » en indiquant un chiffre après: La vitesse du tapis change avec la valeur écrite après la chaîne de carctère V
  • « Led1_Go » : Lance le premier ruban de leds
  • « Led2_Go »: lance le deuxième ruban de leds
void ProcessNewData() {
    if (newData == true) {
    
        //Serial.print("The received data is :: ");
        //Serial.println(receivedChars);

        if (strcmp(receivedChars, "Go") == 0 || strcmp(receivedChars, "NoGo") == 0)
        {
            if (strcmp(receivedChars, "Go") == 0) 
              StartStopMotor(HIGH);
            else
              StartStopMotor(LOW);
        }
        if (strcmp(receivedChars, "RightLeft") == 0 || strcmp(receivedChars, "LeftRight") == 0)
        {
            if (strcmp(receivedChars, "RightLeft") == 0) 
              Direction(HIGH);
            else
              Direction(LOW);
        }
        
//##############
      if (strcmp(receivedChars, "V") == 0)
        {
           ICR1=receivedChars[1]-30*1000+receivedChars[2]-30*100+receivedChars[3]-30*10+receivedChars[4]-30;
           
        }
  

//################
        
        if (strcmp(receivedChars, "Vitesse") == 0)
        {
          Vitesse(ICR1);
        }
        else
        {
          char * pch;
          pch = strtok(receivedChars,",");
          while (pch != NULL)
          {
            
            if(strcmp(pch, "R1") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                r1 = atoi(pch);
                //strip1.fill(strip1.Color(r1, g1, b1), rg1_1, rg1_2);
              }
            }
  
            else if(strcmp(pch, "R2") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                r2 = atoi(pch);
                //strip2.fill(strip2.Color(r2, g2, b2), rg2_1, rg2_2);
              }
            }
  
            else if(strcmp(pch, "G1") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                g1 = atoi(pch);
                //strip1.fill(strip1.Color(r1, g1, b1), rg1_1, rg1_2);
              }
            }
            else if(strcmp(pch, "G2") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                g2 = atoi(pch);
                //strip2.fill(strip2.Color(r2, g2, b2), rg2_1, rg2_2);
              }
            }
            else if(strcmp(pch, "B1") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                b1 = atoi(pch);
                //strip1.fill(strip1.Color(r1, g1, b1), rg1_1, rg1_2);
              }
            }
            else if(strcmp(pch, "B2") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                b2 = atoi(pch);
                //strip2.fill(strip2.Color(r2, g2, b2), rg2_1, rg2_2);
              }
            }
            else if(strcmp(pch, "Br1") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                br1 = atoi(pch);
                strip1.setBrightness(br1);
                //strip1.fill(strip1.Color(r1, g1, b1), rg1_1, rg1_2);
              }
            }
            else if(strcmp(pch, "Br2") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                br2 = atoi(pch);
                strip2.setBrightness(br2);
                //strip2.fill(strip2.Color(r2, g2, b2), rg2_1, rg2_2);
              }
            }
            else if(strcmp(pch, "Rg1") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                rg1_1 = atoi(pch);
                pch = strtok (NULL, ",");
                if (pch != NULL)
                {
                  rg1_2 = atoi(pch);
                  strip1.fill(strip1.Color(r1, g1, b1), rg1_1, rg1_2);
                }
              }
            }
            else if(strcmp(pch, "Rg2") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                rg2_1 = atoi(pch);
                pch = strtok (NULL, ",");
                if (pch != NULL)
                {
                  rg2_2 = atoi(pch);
                  strip2.fill(strip2.Color(r2, g2, b2), rg2_1, rg2_2);
                }
              }
            }
            else if(strcmp(pch, "LED1_go") == 0)
            {
              strip1.show();
            }
            else if(strcmp(pch, "LED2_go") == 0)
            {
              strip2.show();
            }
            else if(strcmp(pch, "Sp") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                Sp = atoi(pch);
              }
            }
            else if(strcmp(pch, "Dr") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                Dr = atoi(pch);
              }
            }
            else if(strcmp(pch, "NbSteps") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                NbSteps = atoi(pch);
              }
            }
            else if(strcmp(pch, "Ret") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                Ret = atoi(pch);
              }
            }
            else if(strcmp(pch, "TrigPas1") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                TrigSteps1 = atoi(pch);
              }
            }
            else if(strcmp(pch, "TrigPas2") == 0)
            {
              pch = strtok (NULL, ",");
              if (pch != NULL)
              {
                TrigSteps2 = atoi(pch);



                
              }
            }
          
            pch = strtok (NULL, ",");
          }
        }
        
        newData = false; 
    }
}

StartMotor()

StartMotor() est la fonction principale qui lance et arrête le moteur du tapis. En utilisant les variables « currentbottonstat » et « lastbottonstat » on peut savoir si le bouton a été relâché pour pouvoir arrêter, puis faire fonctionner le tapis.

Si l’état actuel du bouton est différent de l’état précédent on alimente le tapis et on le fait tourner sinon on l’arrête et bien sûr après avoir vérifié si le tapis tourne déjà ou pas.

La variable tapistat permet de vérifier si le tapis tourne ou pas, si tapistat est à la valeur HIGH on arrête le tapis sinon on le fait tourner.

void StartMotor(){
     
    //Utilisation du bouton STOP/Marche
    currentbottonstat = digitalRead(Entree_Bouton);
     if (digitalRead(Entree_Bouton) == HIGH){
        if ( currentbottonstat != lastbottonstat )
          {
                if ( currentbottonstat == HIGH )
                {
       
                    if ( tapistat == LOW ) 
                        {
                        digitalWrite(Alim_Tapis, HIGH);
                        tapistat = HIGH;
                        }
                    else          
                    {
                      digitalWrite(Alim_Tapis, LOW);
                      tapistat = LOW;
                     }
                  }
                  else
                  {
                      if ( tapistat == HIGH ) 
                      {
                        digitalWrite(6, LOW);
                        tapistat = LOW;
                      }
                      else          
                      {
                        digitalWrite(6, HIGH);
                        tapistat = HIGH;
                      }
                   }
            }
       }
        if (digitalRead(Entree_Bouton) == LOW) 
        {  
          if ( currentbottonstat != lastbottonstat )
          {
              if ( currentbottonstat == HIGH )
              {
                  if ( tapistat == LOW ) 
                  {
                      digitalWrite(6, HIGH);
                      tapistat = HIGH;
                  }
                  else 
                  {
                      digitalWrite(6, LOW);
                      tapistat = LOW;
                  }
                }
                else
                {
                    if ( tapistat == HIGH ) 
                    {
                      digitalWrite(6, LOW);
                      tapistat = LOW;
                    }
                    else          
                    {
                      digitalWrite(6, HIGH);
                      tapistat = HIGH;
                    }
                 }
            }
          }
    lastbottonstat = currentbottonstat;
          if (digitalRead(Switch_1) == HIGH)
        {
            digitalWrite(Sens_Tapis, LOW);
        }
        if (digitalRead(Switch_2) == HIGH)
        {
            digitalWrite(Sens_Tapis, HIGH);
        }
}

Direction()

void Direction(bool RightLeft){
  digitalWrite(Sens_Tapis, RightLeft);
  }
 

StartStopMotor()

void StartStopMotor(bool GoNoGo){
  digitalWrite(Alim_Tapis, GoNoGo);
}

Vitesse()

void Vitesse(int vit){
  digitalWrite(ICR1, vit);
}

Fonction Principale

void loop() {
    recvWithStartEndMarkers(); //Données données par l'utilisateur
    ProcessNewData(); 
    
    StartMotor();
}

Contrôle du banc de vision avec du Python

Finalement pour pouvoir contrôler le banc de vision en utilisant un ordinateur, il faut être obligatoirement connecté à l’Arduino en utilisant un câble USB, et on va utiliser dy python et le logiciel Anaconda.

On lance Anaconda, et on a utilisé Spyder comme éditeur de texte pour lancer notre programme. Le programme écrit en python nous permet de gérer les leds et le moteur du tapis en utilisant les commandes qu’on a intégré dans nos fonctions. Le bout de code qui nous permet de faire cela est le suivant :

if serial_arduino is not None:

    serial_arduino.write(('<Br1,255,B1,255,G1,255,R1,255,Rg1,0,12>').encode())
    serial_arduino.write(('<LED1_go>').encode())

    serial_arduino.write(('<Br2,255,B2,255,G2,255,R2,255,Rg2,0,12>').encode())
    serial_arduino.write(('<LED2_go>').encode())


    serial_arduino.write(('<Sp,300>').encode())
    sleep(1)
    serial_arduino.write(('<Dr,0>').encode())
    serial_arduino.write(('<NbSteps,50000,TrigSteps1,500,TrigSteps2,500>').encode())

    #sleep(1)
    #serial_arduino.write(('<Go>').encode())
    #sleep(1)
    #erial_arduino.write(('<NbSteps,1500>').encode())
    #sleep(1)

Caméra

Nous utiliseront une Caméra In-Sight D900 ainsi que le logiciel Insight Explorer afin de traiter les images renvoyées par la caméra, et pour pouvoir lire les défauts détectés.

Partie Structure

On un banc qui a été fait par les étudiants de l’année précédante, avec des plaques en couleur noir ayant pour but d’absorber la lumière, et des barres métalliques pour tenir le matériel qui sera installé dessus. On a aussi une plaque de bois bien rigide, qu’on a utilisé pour poser le tapis dessus, et coller l’alimentation, la carte commande et l’arduino au-dessous.

Carte électronique

Ensuite on a le convoyeur qui lui permet de déplacer les pièces , il s’agit d’un tapis mis en rotation par un moteur .

Et la structure qui vas accueillir ces 2 éléments ainsi que les le supports leds.

Cependant la plaque ne dispose pas d’une protection électrique certifié IP2X. On a protégé la partie alimentation avec un boitier qu’on a installé en utilisant des pièces magnétiques pour pouvoir le détacher facilement, mais il faut l’installer définitivement sans pouvoir le détacher, et protéger la partie Arduino et commande.

Résultats

  • Code Fonctionnel
  • Câblage installation terminé
  • Liaison série réussie

Travail à finir

  • Installer la caméra de vision afin de rendre le système opérationnel
  • Mettre en place une protection IP2X afin de protéger l’installation (un boitier fermé que l’on ne peux ouvrir qu’a l’aide d’un outil )
  • Améliorer le câblage de l’installation

Problèmes rencontrés

  • Problème de code parce que c’est a première fois qu’in utilise ce type de logiciel et on code en langage arduino
  • Problème de liaison série et les commandes à envoyer pour pouvoir le contrôler
  • Problème de protection IP2X , parce qu’il y avait pas assez de matériel et de temps pour pouvoir bien protéger le banc
  • Problème de câblage, parce que on a pas prévu des longs câbles pour les leds
  • Prôblème de gestion de temps et d’organisaton

Codes sources


Tracker Solaire

Réalisation d’un système « Tracker Solaire »

Apprenti : Pierre SIMON

Enseignants : Frédéric STEGER – Christophe CUDEL

SYNAPTEC

PROJET GEII : Etudes et Réalisations

Année 2021 – 2022   

Sommaire 

I. Projet de GEII

1. Introduction

2. Présentation du cahier des charges

3. Evolution du projet

a. Choix du matériel

b. Carte de commande moteur et de gestion (autonomie/secteur)

c. Carte principale CI

d. Programmation ZELIO

II. Utilisation et démontage 

III. Conclusion

IV. Annexe

 

I. Projet de GEII 

1.     Introduction  

Au courant de mon année 2021-2022, nous avons choisi un projet en Etudes et Réalisations. J’avais choisi le « Tracker Solaire » en binôme avec un second étudiant de génie électrique et deux étudiants de génie mécanique pour la partie mécanique.

Illustration 1 : Coffret électrique

Nous nous intéressons donc à l’implantation d’un coffret (voir illustration 1) électrique comprenant les batteries et la carte de gestion de la motorisation, sur le pilier du panneau solaire.

Illustration 2 : Photorésistance séparées par un T

Pour déterminer la position du soleil, le « Tracker » devait s’orienter grâce à l’information de luminosité transmise par des photorésistances (voir illustration 2) séparées par un T pour une orientation d’angles de 120 degrés chacune. Cependant, de nombreux désavantages pour déterminer la position du Soleil quand la météo ne le permet pas : vérification par temps clair, par temps couvert, exposition au gel, à la pluie, au dépôt de résidus (poussière, mousse, etc…) …

Différentes approches pour vérifier ces problèmes peuvent être mises en place. Dans le cas du temps clair, il faut effectuer une mesure au luxmètre entre les différents niveaux d’éclairement (coin le plus éloigner de la position du Soleil, et le plus proche). Essais avec des tubes pour concentrer le point de mesure suivant les parties du ciel.

Pour ce qui est du cas du temps couvert, effectuer des essais similaires pour déterminer la position du Soleil (épais nuage, brouillard) si elle s’avère déterminable. J’ai donc remarqué une uniformisation de l’intensité lumineuse par temps couvert, ce qui rend l’orientation compliquée pour l’obtention d’un rendement maximal (les photorésistance sont sensibles à l’intensité lumineuse en Lux, et non à la puissance surfacique). Déterminer la puissance surfacique à différents angles d’inclinaisons, lors de ciel voilé, pour contrôler si le tracking avec module logique permet réellement de maintenir un meilleur rendement, comparé au tracking en lecture directe (photorésistances).

Dans le cas du gel des cellules de positionnement, il faut intégrer un chauffage permettant d’éviter de fausser la position par réfraction lumineuse ou perte de précision.

Le problème posé par la pluie peut s’apparenter à celui du gel, une solution similaire s’impose.

Le dépôt de résidus de différentes natures oblige un entretien régulier des cellules de positionnement.

Malheureusement, l’étudiant de génie électrique n’est pas revenu à la seconde alternance. J’ai alors discuté avec mon maître d’apprentissage, pour effectuer mon projet d’entreprise en adéquation avec le projet de GEII. Les professeurs m’avaient dit que le tracker solaire avait été démarré il y a 5 ans, mais que, soit la partie électrique n’était pas faite, soit il s’agissait de la partie mécanique. J’ai commencé à réfléchir à une réalisation utile et ludique d’une maquette entièrement réalisée au sein de mon entreprise : SYNAPTEC.

J’ai utilisé différents logiciel pour réaliser mon projet :

  • Zélio Soft V5.3 pour la programmation du module logique ZELIO
  • Target 3000 pour schémas électronique et CAO
  • Galaad et Percival pour la réalisation des circuits imprimés FAO

2. Présentation du cahier des charges

Après avoir relevé les différents soucis liés au suivi du Soleil en lecture directe (voir illustration 2 de l’introduction), j’ai décidé de prendre un module logique ZELIO de la marque « SCHNEIDER Electric ». En effet, ce module logique intègre un bloque fonction permettant de fournir une orientation AZIMUT et une ELEVATION en fonction des coordonnées GPS du site d’implantation et du fuseau horaire. C’est donc beaucoup plus pratique, peu importe la météo et l’environnement.

Les professeurs d’encadrement du projet en GEII m’ont demandé d’une part, de mettre à l’horizontal le panneau photovoltaïque si le vent devenait violent, ainsi que d’économiser l’énergie du système via un cycle de fonctionnement périodique d’environ 30 min.

Ces deux conditions primordiales m’ont amené à penser un cahier des charges relativement complexe. J’ai réfléchi à comment gérer un réveil uniquement lorsqu’il fait jour puis périodique pendant la journée, ainsi qu’une mise à l’horizontal du système lorsqu’il y a du vent, peu importe s’il fait jour ou nuit. J’en ai conclu que mon module logique seul ne pourrait en aucun cas gérer ces deux gros points. J’avais deux solutions en tête : utilisation d’un microcontrôleur ou création d’une carte électronique. J’ai alors choisi la seconde solution car elle m’a permis de me familiariser avec la logique électronique et les différents logiciels qu’on utilise, pour la machine de gravure de carte électronique.

3.     Evolution du projet

a.       Choix du matériel

Pour le choix et la gestion des orientations, mon système a besoin de précision pour le positionnement des moteurs sur les axes AZIMUT et ELEVATION je me suis donc tourné vers une extension SR3XT43BD car elle possède 2 entrées analogiques 10 Bits (soit 1024 points) contrairement aux entrées analogiques classiques qui ne comprennent que 8 Bits (256 points).

Pour le module logique ZELIO (voir illustration 3), je me suis tourné vers le SR3B262BD car il possède des sorties transistorisées. Ces sorties sont utiles pour la rapidité d’exécution et de fermeture du contact qui commande la marche des moteurs.

Le module logique SR3B262BD fonctionne sous 24V, il possède 10 entrées et 10 sorties ToR (24V) + 6 entrées analogiques 8 Bits (0-10V) :

5 entrées ToR :

  • Un fin de course sur l’orientation AZIMUT (position NORD)
  • Un fin de course sur l’orientation ELEVATION (position ARRIERE)
  • Un fin de course sur l’orientation ELEVATION (position AVANT/RANGEMENT)
  • Une entrée mode TEMPETE (envoyé depuis une carte externe CI)
  • Une entrée mode REGLAGE (définis par un interrupteur)

3 entrées analogiques 8 Bits (0 à 255 points) :

  • Courant moteur azimut (gérer le blocage moteur envoyé depuis carte externe CI)
  • Courant moteur élévation (gérer le blocage moteur envoyé depuis carte externe CI)
  • Ensoleillement (envoyé depuis carte externe CI)

5 sorties ToR :

  • Grande vitesse
  • Marche moteur AZIMUT
  • Inversion moteur AZIMUT
  • Marche moteur ELEVATION
  • Inversion moteur ELEVATION
  • Défaut(s)
  • Ordre de SOMMEIL (en fin de cycle)

Le module logique possède un écran, pratique pour les messages de défauts, ainsi que 4 boutons programmables. L’extension analogique 2 entrées analogiques 10 Bits et 2 sorties analogiques 10 Bits (0-10V) :

2 entrées analogiques 10 Bits :

  • Recopie potentiomètre AZIMUT (envoyé depuis carte externe CI)
  • Recopie potentiomètre ELEVATION (envoyé depuis carte externe CI)

 Illustration 3 : Module logique Zélio + extension et alimentation 

Pour la maquette, j’ai fait le choix d’utiliser 6 cellules photoélectriques d’une tension de 6V chacune, montée sur le système pour me délivrer une tension de 12V et d’une puissance totale de 3 Watt (nominales). Une batterie de 12V et de 2.1 Ah (mon système au repos consomme 26 mA). Deux moteurs de 12V et 25 mA en fonctionnement normal. Une alimentation 230V~/24V= et de 1.2 A, avec un disjoncteur de 2A courbe C pour le branchement sur secteur. Pour la position, j’ai deux potentiomètres de 5 kOhms, et une photorésistance pour le réveil journalier.

b. Carte de commande moteur et de gestion (autonomie/secteur)

SYNAPTEC a acquis au courant de l’année 2020 une machine d’usinage pour la réalisation de carte électronique. J’ai alors pu profiter du nouveau système l’année dernière avec mon ancien projet. Cette année, je me suis attelé à une panoplie de carte électronique pour ce projet notamment celle permettant de gérer l’orientation du système sur deux axes et de gérer entre l’alimentation par secteur, ou l’alimentation par batterie (cellule photovoltaïque) en autonomie.

INTERFACE DE COMMANDE MOTEUR + GESTION ALIMENTATION : (voir annexe)

Illustration 4 : carte électronique.

Interface de commande des moteurs : Elle possède 8 bornes en bas de l’illustration 4 et 5 qui servent à l’alimentation en grande vitesse (12V), petite vitesse (4.5V). Les commandes du module logique : grande vitesse, marche azimut, inversion azimut, marche élévation et inversion élévation. La dernière borne c’est le 0V commun à tout le système.

Illustration 5 : Circuit imprimé gestion moteur/alim.

Les commandes de marche des moteurs actionnent des optocoupleurs prévus pour moduler le signal à l’approche du point, ou bien de le hacher, augmentant ainsi la précision et la vitesse d’exécution du système. Tout ceci est géré par le module logique et les fameuses sorties transistorisées.

En sortie, comme montré sur la carte imprimée (illustration 5) en bas à gauche, la carte actionne les moteurs d’élévations et d’azimut avec l’aide des sortie +/- ME et +/-MA.

Les sorties +M1 et 0V M1 permettent de mesurer le courant moteur qui est envoyé vers la carte principale, puis vers le module logique. Idem pour les sorties +M2 et 0V M2.

CIE et CIA sont les commandes d’inversion pour la marche moteur.

Sur l’illustration 5, nous pouvons observer en haut la gestion de l’alimentation entre secteur et autonomie : en effet, lorsqu’il y a de la tension (24V) aux bornes du 0V et du +24V, les 3 relais s’enclenche, mon système se retrouve alimenté par l’alimentation secteur 230V/24V. cependant, dans le cas contraire, les système est alimenté en 12V par la batterie. Un problème se pose, mon module logique ne fonctionne qu’en 24V. Au repos, les contacts des relais aiguillent le 12V des batterie vers un convertisseur externe à la carte (12V/24V) et le 24V est envoyé sur le ZELIO, lui permettant de continuer à fonctionner en autonomie. Voici pourquoi il y a un système de gestion d’alimentation.

Quand nous sommes sur secteur, la production des panneaux solaires est aiguillée sur la sortie E10 3W, pour observer sur une ampoule l’intensité de production (il s’agit d’une maquette). Lorsque nous sommes en autonomie, la production d’énergie des cellules est déviée vers la batterie.

c. Carte principale CI

TRACKER SOLAIRE : DESCRIPTIF DE LA CARTE ET SES FONCTIONS. (Voir annexe, pages 31 et 32)

Illustration 6 : Carte principal CI.

Tout d’abord, l’existence de cette carte réside en 2 points : la gestion du mode tempête et le réveil périodique durant la journée. En effet, cela ne peut être géré par le module logique, c’est donc via une pléiade de composants que j’ai pu concevoir un système répondant au cahier des charges (illustration 6).

Illustration 7 : Circuit imprimé principal CI.

Dans un premier temps, l’orientation des potentiomètres, la gestion du courant moteurs et l’ensoleillement via la photorésistance sont amplifiés via des amplificateurs opérationnels. J’ai pu appliquer certaines notions vues en cours et me perfectionner sur l’amplification de signaux mais également sur la gestion de seuil comme pour l’ensoleillement. Une fois amplifié, l’ensoleillement entre à nouveau dans un amplificateur opérationnel mais pour y être comparé à un seuil (environ 1000 Lux). Ce seuil a pour effet de m’indiquer, sans pour autant être perturbé par la moindre petite lumière durant la nuit, quand est-ce qu’il fait jour.

Les autres signaux simplement amplifiés tels que le courant de chaque moteurs est envoyé sur mes entrées analogiques 8 Bits du module logique, pour y être traiter. Il est vrai que l’amplification de mes signaux n’est pas présente juste pour appliquer des notions vues en cours, mais également car le signal entrant directement sur le ZELIO était trop faible…

Pour ce qui est de la gestion des potentiomètres, l’AZIMUT est géré vis-à-vis la résolution maximal : 0 à 10V est égal à 0 à 1023 points dans mon programme et correspond de 0 à 360 degrés de rotation. Ayant pour origine de la mesure le NORD (0 et 360 = NORD), 90° = EST, 180°=SUD et 240°=OUEST. Mes potentiomètres ont une plage de 0 à 340° équivalent à 0 à 5kOhms (plage morte de 20°). J’ai donc dû mettre en place une réduction sur ma tige AZIMUT pour que mes 0 à 340° potentiomètres conviennent à la mesure sur 0 à 360° de rotation.

Pour la gestion de l’ELEVATION, il s’agit d’une course maximale de rotation de 0 à 180°. J’ai alors ajusté mon 0 – 10V de lecture sur mon entrée ZELIO pour faire correspondre non pas de 0 à 340° mais bel et bien de 0 à 180°. Nous avons donc une résolution de traitement de 0 à 180° valant 0 à 1023 points. Tout cet ajustement est réalisé avec le bon pont diviseur sur l’entrée de l’amplificateur opérationnel.

Ce qu’il faut retenir : mes signaux apparaissant sur mes entrées (0-10V) 10 Bits de l’extension ZELIO et (0-10V) 8 Bits du ZELIO sont amplifiés pour correspondre à la plage maximale de traitement dans le programme (0-1023 pour 10 Bits et 0-255 pour 8 Bits). Ceci correspond aux bornes de gauche et en haut sur l’illustration 7.

En haut à droite nous avons une commande venant du ZELIO : le SOMMEIL. Cette commande arrive sur la bobine du bistable d’alimentation du ZELIO, elle permet de l’auto couper une fois son cycle de fonctionnement terminé.

Son cycle de REVEIL (Illustration 8) est, quant à lui, géré par la carte CI directement avec l’utilisation du seuil 1000 Lux lançant le mode JOUR. Le mode JOUR envoie une impulsion toute les 55 secondes, ou bien 30 min via le choix du switch entouré en vert sur l’illustration 6. Les 55 secondes correspondent au cycle de test, et les 30 min, au cycle de fonctionnement normal. L’impulsion périodique possible grâce à l’utilisation d’un NE555 monté en astable.

Illustration 8 : Synoptique système REVEIL

Sur la partie de droite (Illustration 7) nous retrouvons le contact d’alimentation du ZELIO, qui peut être court-circuité par le REVEIL en cas de VENT VIOLENT, laissant 30 secondes d’alimentation au module LOGIQUE pour effectuer sa mise en sécurité. Juste en dessous, il y a la borne reliée à l’entrée VENT du ZELIO qui lui indique ou non de mettre le système à l’horizontal. Cette dernière est remise à zéro s’il n’y a pas eu de Bourrasque de puis 55 secondes ou bien 30 min (en fonction de la position du switch). En bas à gauche nous retrouvons les différentes tensions d’alimentation permettant au système de fonctionner : 24V si alimentation sur secteur, dans le cas contraire nous entrons directement en 12V sur l’entrée +12V IN (gérée depuis la carte de gestion d’alimentation décrite plus haut).

Nous détectons une bourrasque grâce à un anémomètre électronique : Le montage entouré en bleu en annexe page 32 correspond à l’anémomètre en question. Le phénomène provient de la particularité des semis conducteurs qui est : 2 mV par °C. Nous nous retrouvons donc avec un transistor T1 monté en diode et non chauffé correspondant à la référence de température. Un second transistor T2 également monté en diode mais couplé thermiquement à un troisième transistor T3. T2 est réchauffé par T3 de quelques degrés supérieurs à la température actuelle. Si un déplacement d’air survient, T1 reste à sa température actuelle, cependant T2 qui était chauffé se voit perdre des calories. T3 est doc obligé de compenser cette perte de calories commandé par l’amplificateur opérationnel, ce qui a pour effet de faire varier le signal de ce dernier. Un second amplificateur permet de comparer ce signal à un seuil de vent qu’on a défini comme pouvant être dangereux à notre maquette. Il émet donc une impulsion à chaque bourrasque via un NE555 monté en monostable déclenchant ainsi le mode tempête (voir illustration 9).

Illustration 9 : Synoptique système TEMPETE.

En bref, si on souffle sur les 2 transistors T1 et T2 en même temps, symbolisant l’anémomètre, le système se met en mode tempête ! A noter (Illustration 8) qu’à chaque seuil atteint, le système de TEMPETE réinitialise le REVEIL pour prolonger la mise en sécurité. Si aucune bourrasque ne survient pendant le temps calibré (via le switch), le REVEIL du système annule le mode TEMPETE indiqué par le DEL bleue sur l’illustration 6.

                                               d.                Programmation ZELIO

TRACKER SOLAIRE : GESTION DE L’ORIENTATION.

Illustration 10 : Gestion du bloc TRACKING  

L’illustration 10 est la partie de gestion du bloc fonction donnant la position du soleil en temps réel. Pour se faire, il faut lui entrer les coordonnées GPS du lieu d’implantation sous forme décimal (conversion GSP de degré vers décimal), ainsi que le fuseau horaire en minute signé (+120 pour l’Alsace). Les valeurs brutes d’AZIMUT sont comprises entre -18000 et +18000 :           

0 (0°/360°) pour le NORD ;               

9000 (90°) pour l’EST ;                                        

+/-18000 (180°) pour le SUD ;          

-9000 (240°) pour l’OUEST.

Les valeurs d’ELEVATION sont comprises entre -9000 à + 9000 : +9000 (90°) pour le point le plus haut à l’horizontal, 0 (0°) pour l’horizon. Les valeurs négatives correspondent à la position du Soleil sous l’Horizon.

Une fois ces valeurs comprises, j’ai effectué des règles simples : notamment diviser directement par 10 pour pouvoir utiliser mes valeurs de mots correctement.

En effet, entre -18000 et +18000 il y a 36000 valeurs, mais 36000 valeurs je ne peux pas les traiter avec des octets signés… je divise donc chaque valeurs par 10 pour me ramener à -900 à +900 pour l’ELEVATION et -1800 à +1800 pour l’AZIMUT.

Pour l’ELEVATION, il me suffit d’appliquer une règle de trois : nous avons une cours totale de 0 à 180° soit 0 à 1023 points. Cependant, le bloc fonction ne va que jusqu’à 90° donc une cours de 0 à 511 points (la moitié). Je multiplie donc la sortie de ma division par un coefficient (GAIN) égal à 512/900. Une fois fait, je peux comparer ma donnée à mon entrée 10 Bits du potentiomètre d’ELEVATION.

J’effectue la même chose pour l’AZIMUT sans oublier que mon 0 à 1023 points se fait dans le sens Nord->Est->Sud->Ouest. Or, mon bloc sort une valeur perturbante : 0=NORD, 900=EST, 1800=SUD, -1800=SUD, -900=OUEST. Je dois donc arriver à gérer quand je suis entre 0 et 1800, et quand je suis entre -1800 et 0. J’effectue donc un multiplexage changeant entre l’avant ZENITH, et l’après ZENITH. Il suffit donc de distinguer deux règles à appliquer : entre 0 et 1800 je suis coté EST, je multiplie la sortie de la division par un coefficient (GAIN) égal à 512/1800. Pour la partie OUEST, entre -1800 et 0, il faut que j’additionne ma sortie avec 1800 pour me le ramener en positif. Puis j’applique le même coefficient mais avec un offset de 512 puisque nous avons déjà parcouru la moitié de la course avec le premier réglage.

TRACKER SOLAIRE : GESTION DE L’ORIENTATION avec COMPARAISON POTENTIOMETRE

Voici la dernière partie de la programmation, effectuée à ce jour. Les différents tests m’ont permis d’ajuster et d’affiner le réglage de l’approche de la position souhaitée.

Illustration 11 : Gestion de la motorisation AZIMUT

Les ronds entourés en rouges représentent d’une part, les blocs de comparaison entre la valeur du potentiomètre AZIMUT avec la gestion du bloc TRACKING vu plus haut, et l’action sur les sortie ToR de marche et inversion moteur AZIMUT. A +/- 35 points (soit environ +/-12.3 °), le système passe de grande à petite vitesse, quand il arrive dans une plage de 6 points (environ 2.1° soit +/- 1°) encadrant la valeur de stabilisation, le moteur se coupe.

Le rond vert correspond à la gestion du bloc TRACKING

TRACKER SOLAIRE : GESTION DE L’ORIENTATION avec COMPARAISON POTENTIOMETRE

Illustration 12 : Gestion de la motorisation ELEVATION

Le rond jaune sur l’illustration 11 correspond à la marche et l’inversion moteur ELEVATION. Le rond rouge sur l’illustration 12 correspond à la gestion d’avance avec précision pour l’ELEVATION. En effet, La grande vitesse n’est effective qu’au-delà de +/-120 points (+/-21°), en dessous de +/-40 points (+/-7°) j’applique un correcteur de type hacheur envoyant des impulsions pour stabiliser autour de +/-1 points (+/-0.17°). Ce correcteur me permet également d’être très précis et rapidement.

II. Utilisation et démontage 

TRACKER SOLAIRE : Mise en route du système

Dans cette partie il faut se référer à l’illustration 1 ci-dessous, je vais expliquer comment utiliser le système Tracker Solaire. Tout d’abord, il faut s’assurer du choix de l’alimentation, si on veut être en autonomie, ou sur secteur. Pour ce faire, si on veut une alimentation par secteur il suffit de brancher la fiche électrique sur une prise 230V alternatif, puis d’enclencher le disjoncteur C2. Sinon, il suffit d’actionner le levier rouge indiquant l’utilisation de la batterie (en vérifiant que les connecteurs de la batterie sont correctement fixés).

 Illustration 1 : Module logique Zélio + extension et alimentation 

Une fois cette première partie effectuée, nous pouvons passer au choix du fonctionnement, dans un premier temps, nous allons regarder les différents interrupteurs. Le premier en haut à droite permet de choisir si on veut être en mode AUTO sur la gestion du mode JOUR, ou si on veut avoir la main sur le mode JOUR/NUIT. Dans ce dernier cas, l’interrupteur en bas à gauche du pupitre permet le réglage forcé JOUR/NUIT. Si notre système doit être lancé pour de l’autonomie, mettre l’interrupteur en haut à gauche sur position photorésistance (un symbole est dessiné).  Pour être sûr d’être en AUTONOMIE, l’interrupteur en bas à droite doit être mis sur la position AUTO.

Maintenant, il faut regarder sur la carte principale CI (illustration 2 ci-dessous) la position du switch (55’’ ou 30’) :

Illustration 2 : Carte principal CI.

Le choix de cette position détermine le temps périodique de fonctionnement en journée pour régler l’orientation du panneau photovoltaïque. Le choix est donc de 55 secondes, ou de 30 minutes. Maintenant que vous avez mis en autonomie le système, il faut s’assurer qu’il n’y est aucun défaut symbolisé par la DEL rouge sur le pupitre (voir illustration 1) ou de message(s) affiché(s) sur l’écran du module logique ZELIO (voir illustration 1).

L’indicateur 0 à 10 (voir illustration 1) nous permet de visualiser l’intensité lumineuse via la petite cellule photoélectrique.

TRACKER SOLAIRE : Démontage pour déplacer le système

Pour pouvoir déplacer le système, il faut d’abord le mettre en position de rangement. Dans un premier temps, mettre l’interrupteur de mode AUTO/REGLAGE en position REGLAGE, puis appuyer sur le bouton 1 sous l’écran du ZELIO (voir illustration 1). Attendre que le système ne bouge plus et soit orienté plein SUD sur l’axe AZIMUT et que les cellules photovoltaïques doivent pointer vers l’horizon SUD. Une fois effectué, couper l’alimentation (disjoncteur C2 ou interrupteur Batterie).

Voici la position dans laquelle le système doit se trouver avant de couper l’alimentation.

Accéder au blocage du câble plat pour pouvoir le bouger.

Déloger le câble plat pour pouvoir le bouger complétement

Déconnecter le connecteur HE10 en délogeant les ailettes de blocage.

Soulever le plateau après avoir dévisser les écrous pour pouvoir extraire le câble plat.

Dégager délicatement le câble plat et fixé le avec les pièces de blocage permettant de maintenir les plis du câble HE10.

Positionner le plateau sur son support en polyester sur les deux guides filetés.

Fixer les écrous de blocage du plateau une fois positionné.

Voici le système une fois rangé. Effectuer le cheminement inverse pour le remontage.

       III.     Conclusion

Les étudiants qui reprendront ce projet pourront se baser sur le travail effectué dans la programmation du module logique. Remplacer les potentiomètres par des codeurs en 0-10 V permettrait de ne pas utiliser les amplificateurs opérationnels dédiés. En effet, l’usage des amplificateurs est principalement là pour ne pas avoir à débourser une grande somme dans des convertisseurs analogiques (la lecture directe sur les entrées ZELIO introduirait une erreur).

La carte principal CI peut être réutilisée pour le système de mise en marche, ainsi que le cycle de réveil (30 min, ou bien dessouder les résistances définies pour 30 min et refaire le calcul pour un autre temps ; ou bien encore placer un potentiomètre pour avoir le choix sur une plage). Il faudra certainement que les futurs étudiants se procurent un véritable anémomètre, ou bien adaptent les 3 transistors pour déporter le système sur le véritable panneau solaire.

Enfin, les étudiants pourront s’appuyer sur le travail effectue pour gérer la marche des moteurs, et adapter au système à mettre en place. Idem pour le gestion d’alimentation entre le secteur ou l’autonomie, et vérifier les règles pour la récupération des informations (signaux analogiques 0-10V) de courant moteur.

En annexe, il y les schémas électroniques des cartes d’interface, ainsi que les plans de fabrication de la maquette.

Les étudiants devront très certainement trouver un moyen d’inclure la carte principale et le module logique ZELIO dans un coffret dédié au système de Tracking.

IV. Annexe 

gestion partie tempête (avec anémomètre électronique)
recopie potentiomètres
partie réveil + alim AOP

PLAN DE CONCEPTION structure du système de suivis du SOLEIL

Bloc fonction REMISE A L’EST

code source :

Projet complet

ZELIO : https://iskia.fr/dl/zip_tracker_solaire_pierre_simon.zip


Système automatisé : Robot UR3, API Siemens et caméra Cognex

L’objectif du projet était de réaliser une maquette de démonstration mettant en scène un traitement de pièces avec un convoyeur, une caméra Cognex et un Robot UR.

Le cahier des charges que nous avions établi était le suivant :

  • Réaliser un schéma de câblage du convoyeur
  • Refaire le câblage du convoyeur
  • Faire fonctionner le convoyeur
  • Refaire le câblage pneumatique
  • Faire communiquer le Robot UR, la caméra COGNEX et l’automate Siemens
  • Réaliser un programme de traitement des pièces avec le Robot UR
  • Réaliser un programme de traitement des pièces avec la caméra COGNEX
  • Faire un programme de traitement des pièces avec la CPU Siemens S7-1200

Pour répondre à ce cahier des charges, nous avons réalisé les tâches suivantes :

  • Programme Cognex
    • Organigramme
    • Communication entre les appareils
    • Programme Robot UR
    • Planification
    • Câblage pneumatique
    • Schématisation
    • Câblage électrique
    • Câblage pneumatique
    • Boitier de contrôle
    • Programme automate

Les équipements qui équipent le système sont les suivants :

  • CPU Siemens S7-1200 DC/DC/DC
  • Robot UR3
  • Caméra Cognex Insight 2000
  • Variateur Télémécanique ALTIVAR 11 0.18kW
  • Disjoncteur Merlin Gerin DT40 4A Courbe C
  • Disjoncteur Merlin Gerin DT40N 1A Courbe D
  • Alimentation 230VAC/24VDC Télémécanique ABL 7RM2401
  • Contacteur 24V Télémécanique LP1K0610BD

La communication se fait via un switch qu’il faut relier au réseau pour programmer l’automate ou se connecter à la caméra via l’application InSight Explorer.

Les équipements de la maquette représenté en figure 1 sont commandés par l’automate qui reçoit des informations des capteurs, de la caméra Cognex et qui envoie un ordre de marche au Robot UR.

Les capteurs détectent les pièces à trois niveaux et donnent les ordres suivants :

  • Présence pièce au départ => démarrage du tapis + action vérin au départ
  • Présence pièce à la caméra => lancement d’une acquisition
  • Présence pièce bonne avant le vérin => éjection de la pièce

Le scénario de la maquette est la suivante :

  1. Une pièce est introduite sur le tapis par un vérin pneumatique.
  2. La caméra Cognex prend un cliché de la pièce pour vérifier si elle est « bonne » ou « mauvaise ».
  3. Si la pièce est « bonne », elle continue sur le tapis et est éjecté par un vérin.
  4. Si la pièce est « mauvaise », le tapis s’arrête et le Robot UR prend la pièce sur le tapis.
Figure 1 : Convoyeur en configuration de marche

Commande système

Après avoir branché le convoyeur et le Robot UR, le système est commandé via une boite à bouton représenté sur la figure 2.

Figure 2 : Boite à bouton pour la commande du système

Programme automate

Le programme automate représenté ci-dessous est chargé dans la CPU Siemens et se met en route dès la mise sous tension du système.

Schéma de câblage

Le Folio 01 du schéma électrique ci-dessous représente le câblage de la partie puissance de la maquette et le folio 02 le câblage des E/S de l’automate.

Programme Caméra

Quand le capteur détecte une pièce, la caméra se déclenche et prend une photo. Pour que la caméra Cognex puisse reconnaitre les pièces bonnes ou mauvaises le principe est assez simple avec le modèle Insight 2000. En effet, il suffit d’utiliser la fonction model sur l’interface Insight, puis choisir la région de la pièce ainsi que le modèle. Le logiciel détectera automatiquement les détails sur la pièce, il faudra alors définir dans quel cas la pièce est bonne ou mauvaise (1 ou 0).

Programme robot

Pour commencer il nous fallait un signal de départ on a donc réfléchi à plusieurs solution modbus… Et on c’est alors rabattu sur un contact mouillé avec sa propre tension. Je m’explique le robot lancera sa boucle seulement si il reçoit du 24v à ses borne qui sera commander depuis un contact de l’automate Siemens. Pour continuer le scénario marche à l’aide d’une synchronisation entre la caméra et le temps de déclenchement qui donne une position approximative au robot. Il faut donc bien le positionner par rapport au repère du banc. On pourra imaginer par la suite que la position soit envoyer depuis la caméra. Le robot reçois le top départ seulement si la pièce est mauvaise il la prends et la dépose dans le bac. La pince marche en tcp nommée rg2 avec une prise directement sur le bras. On a un point d’initiation et à chaque fois une appro avant la prise et la dépose de pièce.

Programmes complets ici


DISTRIBUTEUR DE PIÈCES POUR BANC ROBOTIQUE INDUSTRIEL :

Sommaire :

•Ancien projet et objectifs
•Cahier des charges
•Fonctionnalités/Réalisation
-Distributeur de pièces
-Bras robotisé
•Matériel
•Programme des différents systèmes
-Arduino
-NodeRed
-Staubli
-Cognex
•Problèmes rencontrés
•Conclusion / Objectifs accomplis

1) Présentation de l’ancien projet :

Notre projet est basé sur l’amélioration d’un projet d’étudiants en DUT GEII de l’année précédente (Figure 1). Il consiste à créer une chaine automatisée afin de faire une démonstration lors des journées portes ouvertes de l’IUT. Le principe est simple, un automate dépose une pièce cylindrique d’une couleur quelconque sur un tapis roulant de manière aléatoire, une caméra envoie l’information de la couleur et de la position de la pièce au bras robotisé qui se chargera de déplacer la pièce pour la remettre dans le distributeur. Nous avons choisis d’améliorer ce projets, car le précédent distributeur automatisé utilisait des moteurs pas à pas, pilotés à l’aides de modules spécifique et d’une Arduino Mega (ce qui est très couteux).

Figure 1: Ancien projet

2) Cahier des Charges

Une fois que les besoins étaient définis nous avons pu établir un cahier des charges (Figure 2). Les deux fonctions principale sont:
-distribuer les pièces de manière aléatoire.
-stocker et trier ces pièces dans des compartiments.

Figure 2: Cahier des charges

3) Définition des fonctionnalités

A l’aide du cahier des charges nous avons pu définir des diagrammes FAST, afin de décrire toutes les fonctionnalités de notre projet (Figure 3.1 et 3.2).
Notre projet contient deux systèmes:

Partie distributeur de pièces (Figure 3.1):

Partie robot et caméra industrielle: (Figure 3.2):

4) Matériel

De ces différentes fonctionnalités, nous avons fait une liste de matériel, pour la création du distributeur de pièces (Figure 4):
Nous avons choisi d’utiliser un Arduino Yun car la programmation de petit systèmes embarqué comme celui-ci est très simple, de plus le Yun possède une interface Linux ce qui nous permettrait éventuellement de le relier à un serveur Node Red. Nous utilisons ces Servomoteurs, car ils ont un couple largement suffisant pour déplacer les pièces. Ils sont aussi très facilement pilotables avec la carte Arduino, car ils ne nécessitent pas de module spécifique. En revanche les capteurs de présence pièce initialement prévu n’ont pas été gardé car jugé trop encombrant pour ce qu’ils apportaient au projet.

Figure 4: Liste de matériel

5) Partie programmation

A) Programme Arduino

Le programme Arduino permet de distribuer une pièce de manière aléatoire à chaque fois que le délai d’attente a été passé. Nous utilisons la fonction rand() pour cela. Le programme a été conçue de manière modulaire, pour rajouter simplement des capteurs ou une nouvelle couleur de pièce c’est pour cela que tout est conçu sur des définitions de tableaux. Le pilotage des Servomoteurs se fait à l’aide d’une fonction ce qui permet de ne pas changer tout le programme en cas de changement du système de pilotage des actionneurs (Figure 5.1 et 5.2). On a aussi programmé un bouton poussoir, pour mettre en marche ce système. Pour éviter les problèmes de rebonds avec ce bouton, nous l’avons mis en parallèle avec une capacité (Figure 5.3).

Synoptique Arduino (Figure 5.1):

Programme Arduino (Figure 5.2):

#include <Servo.h>
#define pin_onoff 2

int temp_rotation = 420;
int pin_capteur[] = {7, 8, 7};
int valeur_pwm[][3] = {{700, 1480, 2300}, {700, 1485, 2300}, {700, 1475, 2300}};
int pin_moteur[] = {9, 10}; //11 et pin pwm obligatoire
int nbmoteur = (sizeof(pin_moteur)) / 2;
int temp_distribution = 1000;
unsigned long temp;
int distro;
bool onoff = 1;
Servo monservo;

void setup()
{
  Serial.begin(9600);
  for (int i = 0; i < nbmoteur ; i++ )
  {
    pinMode(pin_capteur[i], INPUT);
    pinMode(pin_moteur[i], OUTPUT);
  }

  //définition boutons IHM
  pinMode(pin_onoff, INPUT_PULLUP);
  pinMode(13,OUTPUT);
  attachInterrupt(digitalPinToInterrupt(pin_onoff), etat, FALLING);
  temp = millis(); //enregistre le temps écouler
  Serial.print("Durer de l'initialisation :");
  Serial.println(temp);
  Serial.print("NBMOTEUR :");
  Serial.println(nbmoteur);
}

void loop()
{
  
  if (onoff == 1) {
    if ((temp + temp_distribution) <= millis())
    {
      distro = random(0, nbmoteur);
      /*while (digitalRead(pin_capteur[distro]) == 0)
        {
        distro = random(0, nbmoteur);
        }*/
      lancement_piece(distro);
      temp = millis();
    }
  }
}



//fonction gérant le sens de rotation du servo moteur
void lancement_piece(int numero_moteur)
{
  moteur(numero_moteur, valeur_pwm[numero_moteur][0]);
  unsigned long temp = millis();
  while ((temp + temp_rotation) >= millis()) {}
  /*moteur(numero_moteur, valeur_pwm[numero_moteur][2]);
  temp = millis();
  while ((temp + temp_rotation) >= millis()) {}*/
  monservo.detach();
  //moteur(numero_moteur, valeur_pwm[numero_moteur][1]);
}

//fonction gérant le sens de rotation du servo moteur
void moteur(int numero_moteur, int valPWM)
{
  Serial.print("N° moteur:");
  Serial.print(numero_moteur);
  Serial.print("    Valeur PWM:");
  Serial.print(valPWM);
  Serial.print("    N° Pin Moteur");
  Serial.println(pin_moteur[numero_moteur]);
  monservo.attach(pin_moteur[numero_moteur]);
  monservo.writeMicroseconds(valPWM);

}
void etat() {
  temp = millis();
  if (100 + temp >= millis()) {
    onoff = !onoff;
    digitalWrite(13,onoff);
    //Serial.print("Etat On/Off : ");
    //Serial.println(onoff);
  }
}

Schéma électrique de l’Arduino:

Figure 5.3: schéma électrique de l’Arduino

Le programme est téléchargeable ici

B) Nodered

Synopsis global du transfert des données entre les différents systèmes (Figure 5.4):

Le serveur Node Red formate les données selon le destinataire et ajoute une interface web permettant ainsi des contrôles manuels.
Nous avons aussi défini aux travers de ce serveur 4 ports: Staubli receive « 1060 »; Staubli sent « 1061 »; cognex receive « 1062 »; cognex sent « 1063 » , ils permettent de faire la liaison entre la caméra et le robot (Figure 5.5).

Figure 5.5: Serveur + interface Node Red

Le fichier à importer pour recréer le serveur NodeRed est disponible ici.

C)Le Robot Staubli

Le robot (Figure 5.6), envoie des demandes de photo à la caméra jusqu’à la présence de pièces. Il attend les coordonnées ainsi que la couleur de la pièce, que la caméra va lui rendre. Une fois les données retournées, le robot ira saisir la pièce aux coordonnées indiquées et la posera au bon endroit (selon la couleur de cette pièce) (Figure 5.7 et 5.8).

Figure 5.6: Photo du robot

Synoptique du programme (Figure 5.7):

cls()
  prisetemp=prise
  deposetemp=depose
  deposetemp2=depose2

  // port receive 1060
  //port send 1061
  //S="1;300;500"


  while true
    S="0;0000;0000"  
    mult=0
    mult2=0
    couleur=0
    xpos=0
    ypos=0
    putln("Debut ")
    //  cameraSend=toString("snap",i)
    //  S=cameraReceive


    do
      clearBuffer(cameraReceive)
      clearBuffer(cameraSend)
      movej(j2,pince,rapide)
      cameraSend=toString("send",i) 
      S=cameraReceive 
      couleur=asc(S,0)-48

      put(couleur)
      putln("fin")
      delay(0.5)
    until(couleur>0)





    //teste le signe des coordonnées

    if asc(S,2)==45
      mult=-1
    endIf

    if asc(S,2)==48
      mult=1
    endIf

    if asc(S,7)==45
      mult2=-1
    endIf

    if asc(S,7)==48
      mult2=1
    endIf

    couleur=asc(S,0)-48

    xpos=mult*(asc(S,3)-48)*100+(asc(S,4)-48)*10+(asc(S,5)-48)
    put(xpos)
    put(" ")

    ypos=mult2*(asc(S,8)-48)*100+(asc(S,9)-48)*10+(asc(S,10)-48)
    put(ypos)

//gère le point de prise en fonction des coordonnées données par la cognex

    prisetemp.trsf.x=prise.trsf.x+xpos
    prisetemp.trsf.y=prise.trsf.y+ypos

    priseapp=appro(prisetemp,{0,0,-30,0,0,0})
    deposeapp=appro(deposetemp,{0,0,-30,0,0,0})
    deposeapp2=appro(deposetemp2,{0,0,-30,0,0,0})

    movej(j2,pince,lent)
    movej(priseapp,pince,rapide)
    movel(prisetemp,pince,lent)
    close(pince)
    movel(priseapp,pince,lent)

    //gère le point de dépose en fonction de la couleur
    if couleur==1

      movej(deposeapp,pince,rapide)
      movel(deposetemp,pince,lent)
      open(pince)
      movel(deposeapp,pince,lent)

    endIf

    if couleur==2

      movej(deposeapp2,pince,rapide)
      movel(deposetemp2,pince,lent)
      open(pince)
      movel(deposeapp2,pince,lent)
    endIf

    movej(j2,pince,rapide)
    putln(" fin")

  endWhile
  waitEndMove()

//Figure 5.8: Programme du robot

Le fichier du projet Staubli est disponible ici.

D) La caméra COGNEX

La caméra attend la demande d’une photo du Robot, s’il n’y a pas de pièces, alors la caméra reprend une photo jusqu’à la présence d’une pièce. Nous avons utilisé une syntaxe spécifique qui est commune au robot et à la caméra, pour la transmission de message (Figure 5.8).

Syntaxe 0;0000;0000
Explication Couleur de la pièces
(0 si absent;
1 si blanc; 2 si vert)
Coordonnées x (Premier caractère = ‘-‘ si Coordonnées négative ou ‘0’ si coordonnée positive)Coordonnées y (Premier caractère = ‘-‘ si Coordonnées négative ou ‘0’ si coordonnée positive))
Figure 5.8: Syntaxe des messages

Programme de la caméra cognex (Figure 5.9) :

La détection des pièces se fait à l’aide de la fonction « TrainPatMaxPattern »
Pour différentier deux couleurs (le vert et le blanc dans notre cas), on joue sur la luminosité.
Cela nous permet de différentier parfaitement la couleur verte de la blanche. Cependant, il arrive souvent qu’une pièce blanche soit détectée à la fois comme verte et blanche. C’est pour cela que quand une pièce est détectée comme verte et blanche, on priorise le blanc.
On a aussi créé un point de référence à l’aide de la fonction « Point », qui est le même pour le TX 60.
Enfin, toutes les coordonnées sont converties en millimètre pour pouvoir être exploitées par le robot.

Figure 5.9: Programme de la cognex

Le fichier du projet NodeRed est disponible ici.

6)Problèmes rencontrés

Les problèmes majeurs que nous avons rencontré sont :

– Chaque servomoteur a une valeur PWM différentes pour les mêmes mouvement (On as dû affiner ces valeurs par expérimentation).

– Les servomoteurs ont un courant de consommation crête bien plus élevé que ce que la datasheet donnait (1,1 A contre 1,6 A dans la réalité) ce qui créait des chutes de tension et redémarrait l’Arduino, on a donc dû surdimensionner l’alimentation.

– Les axes x et y de la caméra ne sont pas aligné avec les axes du bras robotisé ce qui empêche la bonne prise de pièces. Ce problème vient du robot Staubli, qui a son axe Y non perpendiculaire à la table.
Pour résoudre ce problème, il faut modifier le programme du Robot et mettre ceci dans les coordonnées du point de prise :

X’=X.cos(T) – Y sin(T)
Y’=X sin(T) + Y cos(T)

Ici X et Y sont les coordonnées envoyées par la caméra et T est l’angle d’écart qu’il y a entre le repère de la caméra et le repère du robot.

– La caméra positionnée au-dessus du robot est une caméra noire et blanc ce qui empêche la différenciation de plus de deux couleurs.

7) Conclusion

Ce projet fut très intéressant, il nous a permis d’appliquer les connaissances de In-sight et Staubli vu en cours directement sur un projet concret. En revanche la partie NodeRed fut une complète découverte !!

Cependant certain point reste à améliorer :
– Le système Arduino devrait être pilotable à travers l’interface web du serveur NodeRed.
– Intégrer la partie Arduino dans la maquette des DUT GMP, vu que cette maquette ne fut terminée qu’après nos séances de projets (Figure 7).
– Utiliser un condensateur pour éviter les chutes de tension plutôt que de surdimensionner l’alimentation.
– Utiliser une caméra couleur pour différencier plus de deux Couleurs.
– Calibrer les axes de la caméra et du robot TX 60.

Figure 7: Maquette des DUT GMP

Projet réalisé par :
– Erwan LAROPPE
-Louis MATHIS

Pour les curieux l’archive complète de notre projet est disponible ICI :
https://drive.google.com/drive/folders/1frOojPXsxAnuPceLYTKd4kq09x3KXn2p?usp=sharing


Bancs didactiques : Boîte de vitesse et train épicycloïdal

contexte : Les étudiants GMP avaient besoin d’un moyen simple, efficace et peu coûteux de pouvoir compter les tours que faisaient leurs maquettes de train épicycloïdale et de boite de vitesse dans le cadre de leur TP.

Nous avons récupéré la maquette réalisée par les étudiants GEII de l’année dernière. Nous avons décidé de garder le même principe avec des aimants et des capteurs à effet HALL. Mais nous avons choisi de mettre toutes notre partie à pars dans une boite qui sera brancher directement sur la maquette.


Cafetière intelligente

Sommaire :

I – Présentation du projet

II – Points a améliorer

III – Solutions mises en œuvre

1) Partie programmation

2) Partie conception

IV – Conclusion

Nili younes – CHTOUANE ZAKARIA – 2022

Présentation du projet :

 

Notre projet consiste a améliorer une cafetière connectée (Interface + boitier). L’interface affichera plusieurs informations qui faciliterons beaucoup de choses a l’utilisateur. Notamment, le nombre de café pris, par jour ou par an, la consommation électrique, journalière et annuelle, ainsi que l’état de l’alimentation de la cafetière. Cependant, le boitier nous permettra de couvrir l’interface ainsi que les fils qui lient la Raspberry au capteur et a la cafetière.

La vie est trop courte pour continuer a boire du mauvais café.

Charles-maurice De Talleyrand-périgord

Points a améliorer :

 

  • L’interface :

On devait améliorer l’esthétique de l’interface et corriger les valeurs qui s’y affichaient, notamment, la consommation électrique, le temps d’alimentation ainsi que le temps de chauffage.

  • L’alimentation :

On devait aussi mettre une unique alimentation a l’ensemble des composants électriques (Raspberry + Cafetière).

Solutions mises en œuvre :

  • Partie programmation :

On a utiliser le logiciel « Spyder » et la bibliothèque « Tkinter » qui est une bibliothèque graphique libre d’origine pour le langage Python et qui permet la création d’interfaces graphiques.

Logo Tkinter
L’interface
Nombre de café Consommation électriqueTemps d’alimentation
Le nombre de café consommé.Le nombre de Watt consommée par la cafetière.Le temps où la cafetière est allumée.
Temps de chauffage Alimentation de la cafetièreEtat de la cafetière
Le temps où la cafetière chauffe.Si la cafetière est allumée ou pas : ON / OFFSi la cafetière est branché a la prise ou pas : ON / OFF
  • Partie conception :

Le logiciel « CorelDraw » qui est un logiciel de dessin virtuel nous a permis de faire le boitier en 3D.

Boitier et interface

Conclusion

Ce projet nous a permis de travailler en équipe pour réaliser les différentes tâches et les mettre en œuvre pour finaliser le projet.

Nous tenons a remercier comme il se doit Mr. Verrier, Mr. Bazeille et Mr. Al Assaad pour leurs soutien et leurs apport de connaissance qui nous a énormément aidé à mener à bien ce projet, et Mr. DE SABBATA pour l’aide à l’IUT-Lab lors de la réalisation du boitier.


TABLE PONG

SOMMAIRE

  • Présentation du projet
  • Problèmes rencontrés
  • Solutions apportés
  • Conclusion

1 ) Présentation du projet :

Notre projet de deuxième année de DUT GEII était d’améliorer une table interactif qui avait été commencer par d’anciens élèves de GEII. Notre travail sur cette table était de rendre simple et logique son lancement ainsi que son utilisation pour optimiser au maximum les sensations du ou des joueurs. Pour se faire, nous avons dus nous penchés sur plusieurs parties : la partie programmation, la partie technique, ainsi que l’aspect visuelle et la simplicité d’utilisation.

2 ) Problèmes rencontrés :

  • Partie esthétique :

Pour la partie esthétique et technique nous devions rendre la table plus jolie et faciliter le transport de celle-ci.

  • Partie programmation :

Le but du projet était de programmer un jeu du nom de « PONG ». Ce jeu est l’un des premier jeux vidéo d’arcade.
« Développé par Allan Alcorn à partir de novembre 1972. »

3 ) Solutions apportés :

  • Partie esthétique :

Nous devions rendre le lancement du jeu plus esthétique et plus intuitif, donc, pour ce faire nous avons mis en place plusieurs menus :

  1. Menu pour choisir le nombre de joueurs.
  2. Menu pour choisir le niveau de difficulté. 
  3. Menu pour choisir le score maximum.
  • Partie programmation :

Pour rendre notre projet plus intéressant, on a dû créer plusieurs programmes pour pouvoir gérer toutes les fenêtres de jeu.

  • Programme « 1vs1 » : Jouer contre un ami.
  • Programme « 1vsIA » ; Jouer contre l’intelligence artificielle.
  • Programme « Choix difficulté » : Pour choisir le niveau de difficulté (Facile, Moyen, Try-hard).
  • Programme « Choix du score » : Pour pouvoir choisir le score max qu’on peut atteindre au cours d’une partie.
  • Programme « Choix du nombre de joueurs » : Pouvoir choisir le nombre de joueurs (1 joueur / 2 joueurs).

4 ) Conclusion :

Durant ce projet, on a dû travailler en équipe et pouvoir mettre en œuvre nos compétences en programmation. On tiens a remercier nos professeurs qui ont contribuer a la réussite de ce projet.  


Robot Suiveur

Enoal PERRAIS/ Mehdi Boumakhloufi / Mohamed Amine Fadlallah

Sommaire

1/ Description du projet et problématique

2/ Diagrammes

3/ Améliorations apportées

4/ Partie Logicielle

5/ Conclusion

1/ Description du projet et problématique

Nous avons pour projet de créer un système embarqué dans un robot qui aura de nouveaux capteurs et permettra de réaliser un suivi de ligne.

Nous avons repris le projet que nous avions choisi l’année dernière pour y ajouter des éléments supplémentaires.

L‘année précédente nous avions démarré le projet Smart car uniquement avec le châssis de la voiture et les moteurs DC pas à pas à l’intérieur.

Le châssis :

Les moteurs pas à pas double sens :

Nous lui avons ajouté de nombreuses améliorations :

  • Ajout d’ un boîtier pour y ajouter du design et contenir les composants ainsi que les capteurs.

  • Ajout de capteurs ultrasons HC-SR04 à l’avant et à l’arrière pour détecter un obstacle (la distance de l’obstacle sera indiquée sur un afficheur 7 segments et si obstacle il y a, un buzzer bippera, les leds vertes s’éteindront et les leds rouges s’allumeront)
  • Ajout d’ un capteur de centrale inertielle IMU9DOF qui calcule l’accélération sur les axes x,y et z de la voiture :
  • Un module Wifi ESP8266 qui transmet à un serveur en ligne les données des capteurs :
  • La voiture dispose d’un mode autonome et un mode manuel. Pour le mode manuel on pilotait la voiture avec un simple clavier d’ordinateur.
  • Un switch permet d’arrêter complètement le système en toute sécurité.
  • Un afficheur LCD qui permet d’afficher un texte comme le nom du projet par exemple.

2. Diagrammes

Diagramme Bête à corne :

Diagramme Pieuvre :

3/ Améliorations apportées

Cette année nous allons lui ajouter différents composants électroniques et améliorer notre système pour obtenir une meilleure performance :

  • Mode suivi de ligne grâce à des capteurs infrarouges (dans l’illustration ici nous en avons deux -> carrés rouges)

Dans la situation 1 : Les deux capteurs détectent une ligne noire et continue leur trajectoire

Dans la situation 2 : Le capteur gauche détecte la ligne noire et s’y dirige donc en tournant vers elle

Dans la situation 3 : Le capteur droit détecte la ligne noire et s’y dirige donc en tournant vers elle

Dans la situation 4 : Les deux capteurs ne détectent plus la ligne noire et donc le robot recule

Capteur TCRT5000
  • Système photovoltaïque qui se dirige vers les rayons lumineux en récupérant les photons grâce à des photorésistances

Dans ce système photovoltaïque nous trouverons différents composants :

  • Communication à distance :
    1. Xbee : de l’Arduino dans la smart car avec la Raspberry Pi via module Xbee RX TX : pilotage manuel de la voiture sur la Raspberry, allumer/éteindre des leds…

Module XBEE :

Interface Homme-machine sur l’écran de la Raspberry PI :

  • Bluetooth : On peux piloter via une application Android les leds et le moteur de la voiture avec le module HM-10

Module HM-10 :

Interface APPInventor (Android) sur le smartphone :

  • Camera thermique AMG8833 permettant d’alerter l’utilisateur d’une présence humaine.

En plaçant sa main devant la caméra (à gauche) on peux constater que sur un écran TFTLCD (à droite) les pixels correspondent à des pics de chaleurs et en l’occurrence ici en rouge c’est la main qui est détectée.

Quand une présence humaine est détectée (par une chaleur supérieure à 32°), il est écrit « Humain » en bas de l’écran.

4/ Partie Logicielle

Voici les logiciels que nous avons été amenés à utiliser tout au long du projet.

5/ Conclusion

Ce projet nous a permis de développer nos compétences dans les systèmes embarqués et dans la gestion de projet en groupe.

Nous avons su améliorer notre projet autant sur les fonctionnalités que sur l’esthétique.

Le budget de la Smart Car est également monté d’un cran et cette petite voiture peut désormais être considérée comme un véritable robot haut-de-gamme.


Microscope bas-coût

Cet article décrit le travail réalisé dans le cadre du projet « Microscope bas-coût » de deuxième année de D.U.T. Génie Electrique et Informatique Industrielle (GEII), du module d’Etudes et Réalisations. Ce projet a été mené par Amine Ghomrani et Paul-Alexandre Patry.


Contexte du projet

Le but de ce projet est l’élaboration d’un microscope low-cost (bas-coût). L’article Low-cost, sub-micron resolution, wide-field computational microscopy using opensource hardware sert de base de travail au projet. Il montre l’opportunité que représente les récentes évolutions de l’informatique et de la photographie grand public, en décrivant la fabrication et l’utilisation d’un microscope. Les principaux constituants sont un ordinateur mono-carte Raspberry Pi 3 et une caméra couleur, également de marque Raspberry. Une matrice de 256 diodes électroluminescentes (LEDs) sert à l’éclairage des échantillons à examiner.


Cahier des charges

Le projet comporte différents objectifs.

Le microscope présenté dans l’article Low-cost, sub-micron resolution, wide-field computational microscopy using opensource hardware ne permet pas un déplacement de l’échantillon autre que manuel. La structure du microscope doit de ce fait être modifiée, pour permettre un déplacement mécanique de l’échantillon sur les axes X et Y.

Le déplacement de l’échantillon sur les axes X et Y, ainsi que le déplacement de la caméra sur l’axe Z – déjà présent – doivent être, à terme, motorisés.

Une interface graphique, doit être élaborée, pour que l’utilisateur puisse interagir avec le microscope. Toutes les fonctions du microscope doivent être commandables via cette application.

Pour mener à bien le projet, nous avons différents éléments à notre disposition. L’annexe 1 de l’article présente la marche à suivre pour construire le microscope qui sert de modèle pour le projet. La liste des composants de ce microscope, ainsi que les fichiers des pièces qui nécessitent une impression 3D, sont fournis. En plus de ces éléments, trois programmes, écrits en langage Python (version 3 et supérieures), ainsi qu’un exemplaire du microscope (Figure 1), assemblé d’après les instructions de l’article, sont mis à notre disposition.

Figure 1 : Microscope construit d’après les indications de l’article Low-cost, sub-micron resolution, wide-field computational microscopy using opensource hardware

Interface graphique – µScope APP

Programmes existants et définition des fonctions de l’application

Il a été dit ci-dessus que trois programmes, écrits en langage Python, ont été fournis en début de projet. Ces trois programmes correspondent à trois modes d’éclairages différents de l’échantillon. En plus de contrôler l’éclairage, chaque programme affiche à l’écran ce que la caméra filme en direct.

Ces programmes présentent néanmoins deux inconvénients :

  1. Pour modifier l’éclairage de l’échantillon, l’utilisateur doit stopper l’exécution du programme en cours puis lancer l’exécution d’un autre programme.
  2. Le flux d’images en provenance de la caméra, et affiché à l’écran, est intangible pour le pointeur de la souris, et ne peut être déplacé, réduit ou enregistré.

De plus, ce flux d’images étant affiché par défaut en plein milieu de l’écran, l’utilisation d’autres fonctions du Raspberry Pi est impossible (Figure 2).

Figure 2

De cette première analyse des programmes existants il ressort que :

  • l’application doit permettre un contrôle fluide de l’éclairage de l’échantillon, avec la possibilité de passer facilement d’un mode d’éclairage à un autre.
  • le flux d’image reçu par la caméra doit être contenu dans une fenêtre qui puisse être déplacée, réduite ou fermée.

Une autre tâche que l’application doit pouvoir remplir, découle de la nature même du projet. Un microscope étant un outil d’observation, l’enregistrement de photographies des échantillons observés doit être possible.

L’éclairage de l’échantillon est assuré par une matrice de LEDs RGB – Red Green Blue – ce qui signifie qu’une multitude de couleurs d’éclairage peuvent être composées. Il a également été montré, via les trois programmes présentés plus haut, qu’il était possible de choisir précisément quelles LEDs de la matrice devaient être allumées ou éteintes. Cette flexibilité de l’éclairage – choix des LEDs et de la couleur – peut être exploitée pour permettre à l’utilisateur de composer un éclairage personnalisé. Elle peut aussi être appliquée au traitement d’image, en photographiant l’échantillon sous différents angles d’éclairage et avec différentes couleurs.

Enfin, le déplacement de l’échantillon devant être motorisé, l’application doit inclure le contrôle par l’utilisateur du mouvement de l’échantillon.

Développement de l’application

Environnement de développement

Le Raspberry Pi, en tant qu’ordinateur, nécessite un Système d’exploitation pour pouvoir fonctionner. Le système d’exploitation utilisé pour ce projet est le Raspberry Pi OS version « Bullseye ».

L’application est entièrement codée en langage Python, version 3.9. La partie interface graphique de l’application a été réalisée avec la librairie Tkinter. Les principales librairies utilisées sont la librairie unicornhathd développée pour le contrôle de la matrice à LEDs, par le fabricant Pimoroni, et la librairie OpenCV pour le contrôle de la caméra, l’enregistrement et le traitement d’images.

Descriptions des fichiers de l’application

Pour que l’application puisse fonctionner, il est nécessaire que tous les fichiers exécutables se trouvent dans le même dossier. Les fichiers qui constituent l’application sont les suivants :

Fichier .pyRôle
Split_vX
(X : numéro de version)
Fichier à exécuter pour lancer l’application.
Vérification de l’installation des librairies nécessaires au bon fonctionnement de l’application. Si les toutes les librairies sont installées le fichier Split_mainwindows sera appelé. Sinon le fichier Split_warnwindows sera appelé.
Split_warnwindowsAffichage dans une fenêtre de la liste des librairies manquantes sur l’appareil et nécessaires au bon fonctionnement de l’application.
Split_mainwindowsDéfinition de la fenêtre principale de l’application. Fait appel aux fonctions définies dans les fichiers Split_stepper, Split_capture et Split_unicornhathd. Appel des fichiers, Split_helpwindows, Split_infowindows et Split_advancedwindows si l’utilisateur appuie sur les boutons correspondants.
Split_helpwindowsDéfinition de la fenêtre d’aide de l’application.
Split_infowindowsDéfinition de la fenêtre d’information sur l’application.
Split_advancedwindowsDéfinition de la fenêtre des réglages avancés. Cette fenêtre réunit les éléments définis dans les fichiers Split_hatwindows et Split_capwindows.
Split_hatwindowsDéfinition des éléments de contrôle personnalisé de l’éclairage (mélangeur de couleur, éclairage progressif…). Fait appel aux fonctions définies dans les fichiers Split_capture et Split_unicornhathd.
Split_capwindowsDéfinition du bouton « Créer un film » et des fonctions utilisées pour la création de vidéos.
Split_unicornhathdDéfinition des fonctions de contrôle de la matrice à LEDs.
Split_stepperDéfinition des fonctions de contrôle des moteurs pas à pas.
Split_captureDéfinition des fonctions de traitement d’images et de sauvegarde d’images.

Le diagramme suivant décrit de manière visuelle l’ ordre dans lequel sont appelés les fichiers et si cet appel se fait systématiquement, ou est conditionné à un événement (ex. : appui sur un bouton) :

Figure 3 : Interactions entre fichiers

Contrôle des librairies

Le diagramme suivant montre le mécanisme utilisé pour vérifier la présence des librairies nécessaires au bon fonctionnement de l’application :

Figure 4 : Mécanisme d’importation des librairies

Si les librairies nécessaires au bon fonctionnement de l’application ne sont pas installées la liste des librairies manquantes sera affichée (Figure 5).

Figure 5 : exemple de message d’erreur

Utilisation du GPIO par l’application

Le schéma suivant montre les pins utilisés pour le contrôle de la matrice à LEDs et des trois moteurs pas à pas (Figure 6).

Figure 6 : Utilisation des pins du GPIO

Les moteurs pas à pas sont alimentés par une autre source que la carte Raspberry Pi. Les masses des drivers des moteurs doivent donc être reliées à la masse de l’alimentation, elle même reliée à la masse du Raspberry Pi.

La matrice à LEDs est alimentée directement par le Raspberry Pi et doit aussi être reliée à la masse de la carte.

µScope APP : description des fenêtres de l’application

Fenêtre principale

La fenêtre principale de l’application (Figure 7) est découpée en deux parties. Dans la partie gauche de la fenêtre est affiché le flux d’images en provenance de la caméra. Cet affichage se fait en temps réel. Dans la partie droite sont rassemblés les boutons de contrôles des fonctions de base de l’application.

Figure 7 : Fenêtre principale de l’application

La partie droite de la fenêtre principale est elle-même divisée en plusieurs sous parties, identifiées par des zones de descriptions.

Un bouton permet d’enregistrer l’image actuellement filmée par la caméra.

Deux boutons permettent d’allumer des modes d’éclairage prédéfinis : le bouton « Eclairage DARKFIELD » (Figure 8) et le bouton « Eclairage FULL » (Figure 9).

Le premier permet d’allumer les LEDs de la rangée extérieure de la matrice. Le but est d’obtenir un éclairage rasant de l’échantillon.

Figure 8

Le second bouton, quant à lui, permet d’allumer toutes les LEDs de la matrice. Dans les deux cas, l’éclairage est de couleur blanche.

Figure 9

Le bouton « OFF » permet d’éteindre complètement les LEDs de la matrice, qu’elles aient été allumées via la fenêtre principale, ou la fenêtre des réglages avancés.

Viennent ensuite six boutons qui permettent de déplacer l’échantillon en commandant les moteurs. Les boutons pour la commande des axes X et Y permettent de déplacer l’échantillon. Les boutons pour l’axe Z contrôlent la distance entre la caméra et l’échantillon, via la translation du support de la caméra.

Fenêtre de réglages avancés

La fenêtre des réglages avancés est scindée en trois parties (Figure 10).

Figure 10

La partie « Réglage RGB » permet à l’utilisateur de composer la couleur de l’éclairage de l’échantillon. La zone sous les trois tirettes permet de prévisualiser la couleur obtenue par le mélange des couleurs rouge, vert et bleu (Figure 11).

Figure 11 : exemple de composition d’une couleur

Le milieu de la fenêtre est occupé par les commandes de trois modes d’éclairage dits « progressifs ». Il est à noter que pour utiliser ces modes d’éclairage – ainsi que les modes dits automatiques – il faut d’abord avoir composé une couleur, à l’aide de la partie « Réglage RGB ». Dans chacun des modes d’éclairages, le niveau 0 sert à éteindre la matrice à LEDs.

Le premier de ces éclairages est un éclairage « depuis le centre ». Le niveau d’éclairage 1 allume un carré de LEDs en plein centre de la matrice. Chaque niveau d’éclairage supérieur épaissit le bord du carré d’une nouvelle rangée de LEDS, jusqu’à allumer toutes les LEDS avec le dernier niveau. En tout 8 niveaux d’éclairages sont disponibles, en exceptant le niveau 0 (Figures 12 et 13).

Figure 12 : Eclairage progressif depuis le centre de niveau 4 et de couleur bleue
Figure 13 : Résultat de la commande sur la matrice à LEDs

Le second mode d’éclairage est appelé « depuis le bord ». Le niveau d’éclairage 1 allume le carré que forment les LEDs à la périphérie de la matrice. Dans ce cas aussi, 8 niveaux d’éclairage sont disponibles, depuis le premier carré, jusqu’à l’utilisation de toutes les LEDs de la matrice (Figure 14 et 15).

Figure 14 : Eclairage progressif depuis le bord de niveau 4 et de couleur bleue
Figure 15 : Résultat de la commande sur la matrice à LEDs

Le dernier mode d’éclairage est appelé « Eclairage circulaire ». Contrairement aux modes d’éclairage précédents, celui-ci ne comprend que quatre niveaux d’éclairage. Les LEDs allumées forment un L contenu dans un quart de la matrice. Chaque niveau d’éclairage correspond à la commande d’un quart différent de la matrice (Figures 16 et 17).

Figure 16 : Eclairage circulaire de rang 2 et de couleur bleue
Figure 17 : Résultat de la commande sur la matrice à LEDs

A chaque mode d’éclairage est associé un bouton « Mode automatique ». Dans ce mode une photographie de l’échantillon est prise pour chaque niveau d’éclairage disponible. Le bouton « Créer un film » , à gauche de la fenêtre, permet de générer un film à partir de la série de photographies prises.

Fenêtre d’aide

La fenêtre d’aide est ouverte par le bouton vert marqué d’un point d’interrogation, situé dans la fenêtre principale (Figure 18).

Figure 18

Dans cette fenêtre se trouve un menu constitué de plusieurs boutons. L’utilisateur appuie sur le bouton correspondant à la partie de l’application sur laquelle il cherche des renseignements. Une fois qu’il a cliqué, la fenêtre d’aide est fermée et remplacée par une fenêtre contenant les explications recherchées (Figure 19).

Figure 19

Une fois la lecture finie, deux choix s’offrent à l’utilisateur :

  • soit fermer directement la fenêtre d’explications
  • soit appuyer sur le bouton retour, au bas de la fenêtre.

Dans le second cas, après la fermeture de la fenêtre d’explications, la fenêtre d’aide sera de nouveau affichée, permettent l’exploration des autres pages d’aides.

Fenêtre d’information

La fenêtre d’information est ouverte par le bouton bleu marqué d’un i, situé dans la fenêtre principale. Cette fenêtre rappelle brièvement dans quel contexte cette application a été développée et quelles personnes ont participés au projet (Figure 20).

Figure 20

Bibliographie

LOW-COST, SUB-MICRON RESOLUTION, WIDE-FIELD COMPUTATIONAL MICROSCOPY USING OPENSOURCE HARDWARE
OMAS AIDUKAS, ANDREW R. HARVEY, PAVAN C. KONDA, REGINA ECKERT, LAURA WALLER

TKINTER REFERENCE: A GUI FOR PYTHON
NEW MEXICO TECH COMPUTER CENTER

CAMERA PROJECTS BOOK : 39 EXPERIMENTS WITH RASPBERRY PI AND ARDUINO
IBRAHIM DOGAN
ELEKTOR INTERNATIONAL MEDIA – 2019 – ISBN : 978-1-907-92077-6
(Disponible à la Bibliothèque Universitaire, Campus Collines)


Cash Machine


Sommaire

  • Contexte et définition du problème
  • Cahier des charges fonctionnel
  • Matériel utilisé
  • Solutions techniques mises en œuvre
    • Partie électronique
    • Partie programmation
    • Partie conception
  • Conclusion du projet et amélioration possibles

Contexte et définition du problème

  • Nous accumulons beaucoup de pièces rouges
  • Leur comptage est fastidieux

Notre but est donc de trouver un moyen de trier et de calculer la somme de ces pièces automatiquement

Cahier des charges fonctionnel

Cahier des charges fonctionnel
Trier Distinguer les différentes pièces Stocker les pièces par valeur
Compter Calculer la somme total  
Calculer les sommes par valeur
Calculer la différence par rapport à un objectif
Afficher (IHM) Vue Principale Somme totale
Vue Tiroir Gestion de tous les tiroirs
Vue Objectif Fixer une valeur à atteindre et l’écart avec celle-ci
Vue Conversion Comparer la somme avec d’autre monnaies prédéfini
Coût Environ 130 €

Matériel utilisé



Solutions techniques mises en œuvre

Partie électronique

Nous avons réalisé une carte pour regrouper les résistances. Cela permet de simplifier le câblage et le rangement à l’intérieur de la boîte ce qui permet une meilleur ergonomie à lors d’action dans la boîte (tels que la récupération des pièces et changement éventuel de composants).

Nous avons mis des résistances de 3,3k Ohm afin d’enlever l’effet de rebond du signal produit par les capteurs.

Partie programmation

Interface graphique

L’IHM (interface homme-machine) permet d’interagir et de rendre compte du contenu de la tirelire.

Pour cela nous utilisons la bibliothèque Tkinter qui est une graphique libre d’origine pour le langage Python, permettant la création d’interfaces graphiques.

  • Utilisation de la bibliothèque Tkinter
  • Menu principale avec ses 3 sous-menu
from tkinter import *
Résultat final pour chaque menu
Menu tiroirMenu objectifMenu principalMenu conversion
Permet une visualisation du nombre de pièces par tiroirPermet de définir un montant à atteindreAffiche la somme et permet d’accéder aux autres menus.Convertit la somme actuelle dans la tirelire en différente monnaie

Détection pièce

Parallèlement au programme qui gère l’interface graphique, un programme détecte les impulsions des capteurs et incrémente à la somme de la tirelire la valeur qui correspond à chaque capteur.

  • Utilisation de la bibliothèque « gpiozero »
  • Incrémente la valeur de la pièce
from gpiozero import Button

Partie conception

Utilisation du logiciel CorelDRAW

Conclusion du projet et amélioration possibles

Durant ce projet nous avons du travailler en équipe pour réaliser les différentes tâches et les mettre en communs pour finaliser le projet.

En guise d’amélioration, nous aurions pu rajouter un moteur qui aurait permis un écoulement plus fluide des pièces dans l’entonnoir.

Equipe:Antoine BLOISArthur CHAUDETThéo STEIB