Commutation d'antenne via raspberry - py

Ce commutateur va permettre via internet de modifier l' antenne reliée au TX de la station EM.

Ce travail a été confié à un apprenant de 4ème année (M Loris Gilliand) .

Fabrication

Interface Homme - Machine

Pour commuter le TX sur une autre antenne, il suffit de taper la lettre (canal désiré) au clavier.

L'image se modifie selon votre choix pour valider sa commutation.

Vous pouvez via la "souris" obtenir le même résultat !

 

Première fenêtre

 

Le premier programme que j’ai écrit, commu01.py, est un programme
qui m’a aidé à réaliser des zones dans la fenêtre. Ce programme
dispose de 3 zones. Une zone pour le titre, une pour l’image et la
dernière n’est pas utilisée. J’utilise aussi la zone de l’image pour
dessiner. Actuellement, l’image représente le boîtier du commutateur
avec le fonctionnement interne dessiner dessus. Sur cette image,
j’ai décidé d’afficher la position du commutateur en dessinant une ligne
du point commun au canal actif. Pour quitter le programme, l’utilisateur
utilisera la touche q du clavier.Le code du programme est annexé
à la fin du document.

com_1.jpg 

Utilisation de la fenêtre

 
La première modification que j’ai faite dans mon programme est la modification du canal sélectionner sur l’image. J’ai donc choisi, qu’à l’aide du clavier, l’utilisateur pourra faire bouger la sortie. Pour le faire,
il pourra utiliser les touches a, b, c et d du clavier. La fenêtre en elle-même n’a pas changé. Pour faire bouger le commutateur, j’utilise Pygame pour dessiner des lignes. Il demande un point de départ, un point d’arrivée et une épaisseur. J’ai donc noté les coordonnées des points A, B, C et D lors de la création de l’image et j’ai finalement utilisé ces coordonnées dans le programme. Une fois une touche pressée, je
supprime l’ancienne ligne en affichant l’image pardessus et je redessine la nouvelle ligne aux nouvelles coordonnées. Le code du programme (commu02.py) est annexé à la fin du document.
com_2.jpg

Zone d’aide

 
Comme le changement de canal fonctionne, j’ai décidé d’ajouter une zone d’aide. Cette zone contiendra les différentes commandes que l’utilisateur peut utilisé. J’ai placé cette zone sur la droite de l’image ce qui m’a fait redéfinir l’emplacement de l’image dans la zone centrale et la position des lignes à afficher. Le code du programme (commu03.py) est annexé à la fin du document.com_3.jpg

Boutons d’indication

 
 L’étape suivante dans l’amélioration de mon programme est d’afficher sur des « boutons » l’état de chaque sorties. Ces « boutons » sont représentés par des carrés noirs. Une sortie active a un vu vert dans son carré alors qu’une sortie inactive a une croix rouge.J’appel ces indicateurs « boutons » car, prochainement, l’utilisateur pourra utiliser la souris pour activer une sortie. Pour le moment, les commandes se font encore au clavier. Le code du programme (commu04.py) est annexé à la fin du document.


Après avoir utiliser les boutons comme indicateurs, j’ai décidé de rendre possible le changement d’état à la souris. Maintenant, il est donc possible de cliquer sur une case pour l’activer. Le code du programme (commu05.py) est annexé à la fin du document.
com_4.jpg
  

Finalisation                                    com_5.jpg   com_7.jpg    com_8.jpg

La finalisation du projet c’est fait par la création d’une classe pour les boutons de commande. Cette classe crée une case vide avec

les attributs image, pos, port, etat et rect. L’attribut pos représente les coordonnées du coin supérieur gauche de la case.

L’attribut port représente le n° du GPIO qui sera attribué à cette case. Les numéros des GPIO sont stockés dans le tableau appelé canal.

Il faut donc créer la case avec l’argument canal[...] pour le port. Le tableau contient 8 infos donc il est possible de créer jusqu'à 8 cases.
Vous trouverez ci-dessous l’organisation du tableau.

com_6.jpg

Par exemple, en créant une case à l’aide de la classe avec l’argument canal[0] pour le port, le GPIO 4 (pin 7) sera assigné à l’objet.
La classe dispose d’une seule méthode. Cette méthode est utilisée pour changer l’état du port. En changeant l’état, la méthode se

charge aussi d’afficher une indication dans la case. Cette image d’indication est à envoyer en argument. Pour mon cas, j’utilise un

vu vert pour une sortie active et une croix rouge pour une sortie inactive.Ce programme, commu06.py, est annexé en fin de document.

Interface LCD

On a ajouté un LCD fournit par HB9FOX qui permet de commuter directement sur le module la bonne Antenne.

IMPORTANT !! Pour ce faire le raspberry - py doit fonctionné et le programme lancé !

Voici le détail :

lcdVue.jpg

com_9.jpg

L’antenne activée est affichée sur la première ligne de l’écran. Lorsque l’on souhaite changer d’antenne, il faut appuyer sur

un des 4 boutons. Après avoir pressé le bouton, l’antenne qu’il active sera affichée sur la deuxième ligne. Il ne
reste plus qu’à valider le changement en appuyant sur le bouton « Sélection ».Comme vous pouvez le voir sur l’image du titre,

l’antenne 1 est activée et l’antenne 4 présélectionnée. Si l’utilisateur presse le bouton de sélection, l’antenne 4 sera activée

Câblage du module

Le raspberry - py travaille avec 8 GPIO qui pour des raisons de protection transite via des opto - coupleurs.

Une carte dédiée à cette protection a été développée.

Le rasbberry - py est directement relié aux entrée de ces optos et la photo montre comment relié les sorties

des optos à la carte relais. Une carte relais possède 4 relais de commutation. C'est pourquoi le module

possède 2 cartes relais.

OptoRelais.jpg

Depuis les sorties relais on installe le câble de la boite de commutation.

RelaiCommutateur.jpg

Les fils rouge sont l'arrivée du 12 Vdc depuis l'autre côté de la carte relais.

Ne pas oublier de les relier au 12Vdc !

Câble

cableCommAnt.jpg

Programmation Python

Voici le code source, vous pouvez le copier directement dans un IDLE Python 2.7.

Si vous ne l'avez pas, vous pouvez le télécharger sur le site Python https://www.python.org/downloads/.

Pour linux c'est plus simple il suffit d' ouvrir l'IDLE 2.7 déjà présent

sur votre carte raspberry - py.

Important !! je suis parti du principe que le port I2C est fonctionnel sur votre raspberry - py.

Si ce n'est pas le cas, seul la distribution sans le LCD fonctionnera !

Source :


# auteur : Gilliand Loris
# date : 02.06.14
# version 0.8
#
# amelioration depuis 0.7 : integre un lcd qui peut commander les changements 

# importation bibilotheques
import pygame, sys, time
from pygame.locals import *
import RPi.GPIO as GPIO
from Adafruit_CharLCDPlate import *

# initialisation fenetre et gpio
pygame.init()
GPIO.setmode(GPIO.BCM)

# fonction qui change LA sortie active
def change_sortie(ligne):
    BP1.etat = 0
    BP2.etat = 0
    BP3.etat = 0
    BP4.etat = 0
    BP1.affiche_etat(inactif)
    BP2.affiche_etat(inactif)
    BP3.affiche_etat(inactif)
    BP4.affiche_etat(inactif)
    time.sleep(0.25)
   if ligne == 'a':
        BP1.etat = 1
        BP1.affiche_etat(actif)
   elif ligne == 'b':
        BP2.etat = 1
        BP2.affiche_etat(actif)
   elif ligne == 'c':
        BP3.etat = 1
        BP3.affiche_etat(actif)
   elif ligne == 'd':
        BP4.etat = 1
        BP4.affiche_etat(actif)

# classe de creation de cases
class Cases:
   def init(self,image,pos,port,init):
       self.image = pygame.image.load(image).convert()
       self.pos = pos
       self.port = port
       self.etat = init
       self.rect = self.image.get_rect().move(self.pos)
        GPIO.setup(self.port,GPIO.OUT)
        GPIO.output(self.port,GPIO.LOW)

   def affiche_etat(self,indicateur):
        indicateur = pygame.image.load(indicateur).convert()
        indi_rect = indicateur.get_rect()
        indi_rect.centerx = self.rect.centerx - self.pos[0]
        indi_rect.centery = self.rect.centery - self.pos[1]
       if self.etat == 0:
            GPIO.output(self.port,GPIO.LOW)
       elif self.etat == 1:
            GPIO.output(self.port,GPIO.HIGH)
       self.image.blit(indicateur,indi_rect)

# initialisation de la fenetre
screen = pygame.display.set_mode((600,600))
clock = pygame.time.Clock()
# initialisation des couleurs
rouge = (255,0,0)
noir = (0,0,0)
blanc = (255,255,255)
vert = (0,255,0)
bleu = (0,0,255)

# initialisation des variables
startline = (183,149)
endline = (293,75)

flag_canal = 0

canal = [4,17,18,22,23,24,25,27]

# definitions des zones
zone1 = pygame.Surface((600,150))
zone1.fill(bleu)

zone2 = pygame.Surface((400,300))
zone2.fill(bleu)

zone3 = pygame.Surface((600,150))
zone3.fill(bleu)

zone4 = pygame.Surface((200,300))
zone4.fill(bleu)

# definitions des objets a afficher dans les zones
# zone 1
font = pygame.font.Font(None,60)
titre1 = font.render("HB9EM",1,noir)
titre2 = font.render("Commutateur d'antennes",1,noir)
zone1.blit(titre1,(230,30))
zone1.blit(titre2,(50,70))

# zone 2
commu = pygame.image.load("commu_antenne.bmp").convert()
zone2.blit(commu,(50,50))

# zone 3
actif = "actif_commu.bmp"
inactif = "inactif_commu.bmp"

BP1 = Cases("bouton_commu.bmp",(125,50),canal[1],1)
BP2 = Cases("bouton_commu.bmp",(225,50),canal[2],0)
BP3 = Cases("bouton_commu.bmp",(325,50),canal[3],0)
BP4 = Cases("bouton_commu.bmp",(425,50),canal[4],0)
grp_cases = [BP1,BP2,BP3,BP4]
BP1.affiche_etat(actif)
BP2.affiche_etat(inactif)
BP3.affiche_etat(inactif)
BP4.affiche_etat(inactif)

zone3.blit(BP1.image,BP1.rect)
zone3.blit(BP2.image,BP2.rect)
zone3.blit(BP3.image,BP3.rect)
zone3.blit(BP4.image,BP4.rect)

font = pygame.font.Font(None,20)
canal_a = font.render("canal A",1,noir)
canal_b = font.render("canal B",1,noir)
canal_c = font.render("canal C",1,noir)
canal_d = font.render("canal D",1,noir)
zone3.blit(canal_a,(125,35))
zone3.blit(canal_b,(225,35))
zone3.blit(canal_c,(325,35))
zone3.blit(canal_d,(425,35))

# zone 4
commande = font.render("Commandes :",1,noir)
touche_a = font.render("Selection canal A : touche a",1,noir)
touche_b = font.render("Selection canal B : touche b",1,noir)
touche_c = font.render("Selection canal C : touche c",1,noir)
touche_d = font.render("Selection canal D : touche d",1,noir)
quitter = font.render("Quitter : touche q",1,noir)
zone4.blit(commande,(10,20))
zone4.blit(touche_a,(10,60))
zone4.blit(touche_b,(10,80))
zone4.blit(touche_c,(10,100))
zone4.blit(touche_d,(10,120))
zone4.blit(quitter,(10,200))

# affichage des zones
screen.blit(zone1,(0,0))
screen.blit(zone2,(0,150))
screen.blit(zone3,(0,450))
screen.blit(zone4,(400,150))

lcd = Adafruit_CharLCDPlate()
lcd.begin(16,2)
btn = ((lcd.SELECT, '', lcd.ON),
       (lcd.LEFT , 'Antenne 1' , lcd.ON),
       (lcd.UP , 'Antenne 2' , lcd.ON),
       (lcd.DOWN , 'Antenne 4' , lcd.ON),
       (lcd.RIGHT , 'Antenne 3' , lcd.ON))
prev = -1
temp = ''
active = 'Antenne 1'
act = ' active'
lcd.message((active + act))
while 1:
    clock.tick(30)
   for b in btn:
           if lcd.buttonPressed(lcd.SELECT):
                lcd.clear()
                lcd.message((active + act))
                time.sleep(0.25)
               if temp != '':
                    active = temp
                    temp = ''
               if active == 'Antenne 1':
                    change_sortie('a')
                    endline = (293,75)
               if active == 'Antenne 2':
                    change_sortie('b')
                    endline = (293,125)
               if active == 'Antenne 3':
                    change_sortie('c')
                    endline = (293,175)
               if active == 'Antenne 4':
                    change_sortie('d')
                    endline = (293,225)
                lcd.setCursor(0,0)
                lcd.message((active + act))
                lcd.setCursor(0,1)
                lcd.message('                ')
           if lcd.buttonPressed(lcd.RIGHT):
                temp = 'Antenne 3'
                lcd.setCursor(0,1)
                lcd.message(temp)
           if lcd.buttonPressed(lcd.DOWN):
                temp = 'Antenne 4'
                lcd.setCursor(0,1)
                lcd.message(temp)
           if lcd.buttonPressed(lcd.UP):
                temp = 'Antenne 2'
                lcd.setCursor(0,1)
                lcd.message(temp)
           if lcd.buttonPressed(lcd.LEFT):
                temp = 'Antenne 1'
                lcd.setCursor(0,1)
                lcd.message(temp)

   for event in pygame.event.get():
        lcd.setCursor(0,0)
       if event.type == pygame.QUIT:
            GPIO.cleanup()
            sys.exit()
       if event.type == pygame.KEYDOWN:
           if event.key == pygame.K_q:
                GPIO.cleanup()
                sys.exit()
           if event.key == pygame.K_a:
                active = 'Antenne 1'
                lcd.message((active + act))
                change_sortie('a')
                endline = (293,75)
           if event.key == pygame.K_b:
                active = 'Antenne 2'
                lcd.message((active + act))
                change_sortie('b')
                endline = (293,125)
           if event.key == pygame.K_c:
                active = 'Antenne 3'
                lcd.message((active + act))
                change_sortie('c')
                endline = (293,175)
           if event.key == pygame.K_d:
                active = 'Antenne 4'
                lcd.message((active + act))
                change_sortie('d')
                endline = (293,225)

    souris = pygame.mouse.get_pos()
    souris_rect = souris[0],souris[1,[5,5]]
    souris_rect = pygame.Rect(souris_rect)

   for i in grp_cases:
        lcd.setCursor(0,0)
       if souris_rect.colliderect(i.rect.move((0,450))):
           if pygame.mouse.get_pressed() == (1,0,0):
               if i.port == canal[1]:
                    active = 'Antenne 1'
                    lcd.message((active + act))
                    change_sortie('a')
                    endline = (293,75)
               if i.port == canal[2]:
                    active = 'Antenne 2'
                    lcd.message((active + act))
                    change_sortie('b')
                    endline = (293,125)
               if i.port == canal[3]:
                    active = 'Antenne 3'
                    lcd.message((active + act))
                    change_sortie('c')
                    endline = (293,175)
               if i.port == canal[4]:
                    active = 'Antenne 4'
                    lcd.message((active + act))
                    change_sortie('d')
                    endline = (293,225)

    zone3.blit(BP1.image,BP1.rect)
    zone3.blit(BP2.image,BP2.rect)
    zone3.blit(BP3.image,BP3.rect)
    zone3.blit(BP4.image,BP4.rect)
    screen.blit(zone3,(0,450))
    zone2.blit(commu,(50,50))
    pygame.draw.line(zone2,noir,startline,endline,2)
    screen.blit(zone2,(0,150))
    pygame.display.update()

Fichier Py

Distributions 'source' sans et avec LCD

Distribution_sans_LCD.rar

Distribution_lcd.rar

Tags: