Code source wiki de Commutateur d' antenne

Version 25.2 par Jean-Yves Dupertuis le 27-08-2014, 11:03

Afficher les derniers auteurs
1 {{box cssClass="floatinginfobox" title="**Contents**"}}
2 {{toc /}}
3 {{/box}}
4
5
6 = Commutation d'antenne via raspberry - py =
7
8 Ce commutateur va permettre via internet de modifier l' antenne reliée au TX de la station EM.
9
10 Ce travail a été confié à un apprenant de 4ème année (M// Loris Gilliand//) .
11
12
13 = [[Fabrication>>doc:fabricationSwitch]] =
14
15
16 = Interface Homme - Machine =
17
18 Pour commuter le TX sur une autre antenne, il suffit de taper la lettre (//canal désiré) au clavier.//
19
20 L'image se modifie selon votre choix pour valider sa commutation.
21
22 Vous pouvez via la "souris" obtenir le même résultat !
23
24
25
26 (% height="656" width="809" %)
27 |=|=
28 |(((
29 == **__Première fenêtre__** ==
30 )))|
31 |(((
32 Le premier programme que j’ai écrit, commu01.py, est un programme
33 qui m’a aidé à réaliser des zones dans la fenêtre. Ce programme
34 dispose de 3 zones. Une zone pour le titre, une pour l’image et la
35 dernière n’est pas utilisée. J’utilise aussi la zone de l’image pour
36 dessiner. Actuellement, l’image représente le boîtier du commutateur
37 avec le fonctionnement interne dessiner dessus. Sur cette image,
38 j’ai décidé d’afficher la position du commutateur en dessinant une ligne
39 du point commun au canal actif. Pour quitter le programme, l’utilisateur
40 utilisera la touche q du clavier.Le code du programme est annexé
41 à la fin du document.\\
42 )))|[[image:http://212.74.133.122:81/xwiki/bin/download/Hardware/SwitchAntenna/com_1.jpg?width=1580||alt="com_1.jpg"]]
43 |(((
44 == **__Utilisation de la fenêtre__** ==
45 )))|
46 |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,
47 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
48 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.|[[image:com_2.jpg]]
49 |(((
50 == **__Zone d’aide__** ==
51 )))|
52 |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.|[[image:com_3.jpg]]
53 |(((
54 == Boutons d’indication ==
55 )))|
56 | 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.
57 \\\\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.|[[image:com_4.jpg]]
58 | |
59
60 == Finalisation [[image:com_5.jpg]] [[image:com_7.jpg]] [[image:com_8.jpg]] ==
61
62 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
63
64 les attributs image, pos, port, etat et rect. L’attribut pos représente les coordonnées du coin supérieur gauche de la case.
65
66 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.
67
68 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.
69 Vous trouverez ci-dessous l’organisation du tableau.
70
71
72 [[image:com_6.jpg]]
73
74 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.
75 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
76
77 charge aussi d’afficher une indication dans la case. Cette image d’indication est à envoyer en argument. Pour mon cas, j’utilise un
78
79 vu vert pour une sortie active et une croix rouge pour une sortie inactive.Ce programme, commu06.py, est annexé en fin de document.\\
80
81
82
83 == Interface LCD ==
84
85 On a ajouté un LCD fournit par //HB9FOX //qui permet de commuter directement sur le module la bonne Antenne.
86
87 **IMPORTANT !!** Pour ce faire le raspberry - py doit fonctionné et le programme lancé !
88
89
90 Voici le détail :
91
92
93 [[image:lcdVue.jpg]]
94
95
96 [[image:com_9.jpg]]
97
98 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
99
100 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
101 reste plus qu’à valider le changement en appuyant sur le bouton « Sélection ».Comme vous pouvez le voir sur l’image du titre,
102
103 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
104
105
106
107
108 == Câblage du module ==
109
110 Le raspberry - py travaille avec 8 GPIO qui pour des raisons de protection transite via des opto - coupleurs.
111
112 Une carte dédiée à cette protection a été développée.
113
114 Le rasbberry - py est directement relié aux entrée de ces optos et la photo montre comment relié les sorties
115
116 des optos à la carte relais. Une carte relais possède 4 relais de commutation. C'est pourquoi le module
117
118 possède 2 cartes relais.
119
120
121
122 [[image:OptoRelais.jpg]]
123
124
125
126 Depuis les sorties relais on installe le câble de la boite de commutation.
127
128
129 [[image:RelaiCommutateur.jpg]]
130
131
132 Les fils rouge sont l'arrivée du 12 Vdc depuis l'autre côté de la carte relais.
133
134 **Ne pas oublier de les relier au 12Vdc !**
135
136 == Câble ==
137
138
139 [[image:cableCommAnt.jpg]]
140
141 = Programmation Python =
142
143 Voici le code source, vous pouvez le copier directement dans un IDLE Python 2.7.
144
145 Si vous ne l'avez pas, vous pouvez le télécharger sur le site Python [[https:~~/~~/www.python.org/downloads/>>url:https://www.python.org/downloads/]].
146
147 Pour linux c'est plus simple il suffit d' ouvrir l'IDLE 2.7 déjà présent
148
149 sur votre carte raspberry - py.
150
151 **Important !! **je suis parti du principe que le port **//I2C//** est fonctionnel sur votre raspberry - py.
152
153 **Si ce n'est pas le cas, seul la distribution sans le LCD fonctionnera !**
154
155
156
157 == Source : ==
158
159 {{box}}
160 {{code langage = "python"}}
161
162 ##{{{# auteur : Gilliand Loris
163 # date : 02.06.14
164 # version 0.8
165 #
166 # amelioration depuis 0.7 : integre un lcd qui peut commander les changements
167
168 # importation bibilotheques
169 import pygame, sys, time
170 from pygame.locals import *
171 import RPi.GPIO as GPIO
172 from Adafruit_CharLCDPlate import *
173
174 # initialisation fenetre et gpio
175 pygame.init()
176 GPIO.setmode(GPIO.BCM)
177
178 # fonction qui change LA sortie active
179 def change_sortie(ligne):
180 BP1.etat = 0
181 BP2.etat = 0
182 BP3.etat = 0
183 BP4.etat = 0
184 BP1.affiche_etat(inactif)
185 BP2.affiche_etat(inactif)
186 BP3.affiche_etat(inactif)
187 BP4.affiche_etat(inactif)
188 time.sleep(0.25)
189 if ligne == 'a':
190 BP1.etat = 1
191 BP1.affiche_etat(actif)
192 elif ligne == 'b':
193 BP2.etat = 1
194 BP2.affiche_etat(actif)
195 elif ligne == 'c':
196 BP3.etat = 1
197 BP3.affiche_etat(actif)
198 elif ligne == 'd':
199 BP4.etat = 1
200 BP4.affiche_etat(actif)
201
202 # classe de creation de cases
203 class Cases:
204 def init(self,image,pos,port,init):
205 self.image = pygame.image.load(image).convert()
206 self.pos = pos
207 self.port = port
208 self.etat = init
209 self.rect = self.image.get_rect().move(self.pos)
210 GPIO.setup(self.port,GPIO.OUT)
211 GPIO.output(self.port,GPIO.LOW)
212
213 def affiche_etat(self,indicateur):
214 indicateur = pygame.image.load(indicateur).convert()
215 indi_rect = indicateur.get_rect()
216 indi_rect.centerx = self.rect.centerx - self.pos[0]
217 indi_rect.centery = self.rect.centery - self.pos[1]
218 if self.etat == 0:
219 GPIO.output(self.port,GPIO.LOW)
220 elif self.etat == 1:
221 GPIO.output(self.port,GPIO.HIGH)
222 self.image.blit(indicateur,indi_rect)
223
224 # initialisation de la fenetre
225 screen = pygame.display.set_mode((600,600))
226 clock = pygame.time.Clock()
227 # initialisation des couleurs
228 rouge = (255,0,0)
229 noir = (0,0,0)
230 blanc = (255,255,255)
231 vert = (0,255,0)
232 bleu = (0,0,255)
233
234 # initialisation des variables
235 startline = (183,149)
236 endline = (293,75)
237
238 flag_canal = 0
239
240 canal = [4,17,18,22,23,24,25,27]
241
242 # definitions des zones
243 zone1 = pygame.Surface((600,150))
244 zone1.fill(bleu)
245
246 zone2 = pygame.Surface((400,300))
247 zone2.fill(bleu)
248
249 zone3 = pygame.Surface((600,150))
250 zone3.fill(bleu)
251
252 zone4 = pygame.Surface((200,300))
253 zone4.fill(bleu)
254
255 # definitions des objets a afficher dans les zones
256 # zone 1
257 font = pygame.font.Font(None,60)
258 titre1 = font.render("HB9EM",1,noir)
259 titre2 = font.render("Commutateur d'antennes",1,noir)
260 zone1.blit(titre1,(230,30))
261 zone1.blit(titre2,(50,70))
262
263 # zone 2
264 commu = pygame.image.load("commu_antenne.bmp").convert()
265 zone2.blit(commu,(50,50))
266
267 # zone 3
268 actif = "actif_commu.bmp"
269 inactif = "inactif_commu.bmp"
270
271 BP1 = Cases("bouton_commu.bmp",(125,50),canal[1],1)
272 BP2 = Cases("bouton_commu.bmp",(225,50),canal[2],0)
273 BP3 = Cases("bouton_commu.bmp",(325,50),canal[3],0)
274 BP4 = Cases("bouton_commu.bmp",(425,50),canal[4],0)
275 grp_cases = [BP1,BP2,BP3,BP4]
276 BP1.affiche_etat(actif)
277 BP2.affiche_etat(inactif)
278 BP3.affiche_etat(inactif)
279 BP4.affiche_etat(inactif)
280
281 zone3.blit(BP1.image,BP1.rect)
282 zone3.blit(BP2.image,BP2.rect)
283 zone3.blit(BP3.image,BP3.rect)
284 zone3.blit(BP4.image,BP4.rect)
285
286 font = pygame.font.Font(None,20)
287 canal_a = font.render("canal A",1,noir)
288 canal_b = font.render("canal B",1,noir)
289 canal_c = font.render("canal C",1,noir)
290 canal_d = font.render("canal D",1,noir)
291 zone3.blit(canal_a,(125,35))
292 zone3.blit(canal_b,(225,35))
293 zone3.blit(canal_c,(325,35))
294 zone3.blit(canal_d,(425,35))
295
296 # zone 4
297 commande = font.render("Commandes :",1,noir)
298 touche_a = font.render("Selection canal A : touche a",1,noir)
299 touche_b = font.render("Selection canal B : touche b",1,noir)
300 touche_c = font.render("Selection canal C : touche c",1,noir)
301 touche_d = font.render("Selection canal D : touche d",1,noir)
302 quitter = font.render("Quitter : touche q",1,noir)
303 zone4.blit(commande,(10,20))
304 zone4.blit(touche_a,(10,60))
305 zone4.blit(touche_b,(10,80))
306 zone4.blit(touche_c,(10,100))
307 zone4.blit(touche_d,(10,120))
308 zone4.blit(quitter,(10,200))
309
310 # affichage des zones
311 screen.blit(zone1,(0,0))
312 screen.blit(zone2,(0,150))
313 screen.blit(zone3,(0,450))
314 screen.blit(zone4,(400,150))
315
316 lcd = Adafruit_CharLCDPlate()
317 lcd.begin(16,2)
318 btn = ((lcd.SELECT, '', lcd.ON),
319 (lcd.LEFT , 'Antenne 1' , lcd.ON),
320 (lcd.UP , 'Antenne 2' , lcd.ON),
321 (lcd.DOWN , 'Antenne 4' , lcd.ON),
322 (lcd.RIGHT , 'Antenne 3' , lcd.ON))
323 prev = -1
324 temp = ''
325 active = 'Antenne 1'
326 act = ' active'
327 lcd.message((active + act))
328 while 1:
329 clock.tick(30)
330 for b in btn:
331 if lcd.buttonPressed(lcd.SELECT):
332 lcd.clear()
333 lcd.message((active + act))
334 time.sleep(0.25)
335 if temp != '':
336 active = temp
337 temp = ''
338 if active == 'Antenne 1':
339 change_sortie('a')
340 endline = (293,75)
341 if active == 'Antenne 2':
342 change_sortie('b')
343 endline = (293,125)
344 if active == 'Antenne 3':
345 change_sortie('c')
346 endline = (293,175)
347 if active == 'Antenne 4':
348 change_sortie('d')
349 endline = (293,225)
350 lcd.setCursor(0,0)
351 lcd.message((active + act))
352 lcd.setCursor(0,1)
353 lcd.message(' ')
354 if lcd.buttonPressed(lcd.RIGHT):
355 temp = 'Antenne 3'
356 lcd.setCursor(0,1)
357 lcd.message(temp)
358 if lcd.buttonPressed(lcd.DOWN):
359 temp = 'Antenne 4'
360 lcd.setCursor(0,1)
361 lcd.message(temp)
362 if lcd.buttonPressed(lcd.UP):
363 temp = 'Antenne 2'
364 lcd.setCursor(0,1)
365 lcd.message(temp)
366 if lcd.buttonPressed(lcd.LEFT):
367 temp = 'Antenne 1'
368 lcd.setCursor(0,1)
369 lcd.message(temp)
370
371 for event in pygame.event.get():
372 lcd.setCursor(0,0)
373 if event.type == pygame.QUIT:
374 GPIO.cleanup()
375 sys.exit()
376 if event.type == pygame.KEYDOWN:
377 if event.key == pygame.K_q:
378 GPIO.cleanup()
379 sys.exit()
380 if event.key == pygame.K_a:
381 active = 'Antenne 1'
382 lcd.message((active + act))
383 change_sortie('a')
384 endline = (293,75)
385 if event.key == pygame.K_b:
386 active = 'Antenne 2'
387 lcd.message((active + act))
388 change_sortie('b')
389 endline = (293,125)
390 if event.key == pygame.K_c:
391 active = 'Antenne 3'
392 lcd.message((active + act))
393 change_sortie('c')
394 endline = (293,175)
395 if event.key == pygame.K_d:
396 active = 'Antenne 4'
397 lcd.message((active + act))
398 change_sortie('d')
399 endline = (293,225)
400
401 souris = pygame.mouse.get_pos()
402 souris_rect = souris[0],souris[1,[5,5]]
403 souris_rect = pygame.Rect(souris_rect)
404
405 for i in grp_cases:
406 lcd.setCursor(0,0)
407 if souris_rect.colliderect(i.rect.move((0,450))):
408 if pygame.mouse.get_pressed() == (1,0,0):
409 if i.port == canal[1]:
410 active = 'Antenne 1'
411 lcd.message((active + act))
412 change_sortie('a')
413 endline = (293,75)
414 if i.port == canal[2]:
415 active = 'Antenne 2'
416 lcd.message((active + act))
417 change_sortie('b')
418 endline = (293,125)
419 if i.port == canal[3]:
420 active = 'Antenne 3'
421 lcd.message((active + act))
422 change_sortie('c')
423 endline = (293,175)
424 if i.port == canal[4]:
425 active = 'Antenne 4'
426 lcd.message((active + act))
427 change_sortie('d')
428 endline = (293,225)
429
430 zone3.blit(BP1.image,BP1.rect)
431 zone3.blit(BP2.image,BP2.rect)
432 zone3.blit(BP3.image,BP3.rect)
433 zone3.blit(BP4.image,BP4.rect)
434 screen.blit(zone3,(0,450))
435 zone2.blit(commu,(50,50))
436 pygame.draw.line(zone2,noir,startline,endline,2)
437 screen.blit(zone2,(0,150))
438 pygame.display.update()
439 }}}##
440 {{/code}}
441 {{/box}}
442
443 [[Fichier Py>>attach:commu08.py]]
444
445
446 === Distributions 'source' sans et avec LCD ===
447
448 [[Distribution_sans_LCD.rar>>attach:Distribution.rar]]
449
450
451 [[Distribution_lcd.rar>>attach:Distribution_lcd.rar]]