Encodeur rotatif

PieM

Senior Member
Bonjour,

sur 28X2, sauf erreur, vous pouvez utiliser une entrée interruption hard.
Donc sur interruption, soit l'autre entrée est à 1 ou à 0 donc incrémentation ou décrémentation.
 

BESQUEUT

Senior Member
Bonjour,

sur 28X2, sauf erreur, vous pouvez utiliser une entrée interruption hard.
Donc sur interruption, soit l'autre entrée est à 1 ou à 0 donc incrémentation ou décrémentation.
Oui 3 entrées : ça me plait bien comme solution, mais il faut choisir de détecter les fronts montants ou descendants.
Or ce type de codage implique de détecter tout changement d'état...
 

PieM

Senior Member
Oui 3 entrées : ça me plait bien comme solution, mais il faut choisir de détecter les fronts montants ou descendants.
Or ce type de codage implique de détecter tout changement d'état...
Non. il suffit par exemple de détecter le front montant sur la sorties codeur reliée à l'entrée INT.
qu'importe la situation: dans un sens le front montant a lieu alors que l'autre sortie codeur est à 0 et dans l'autre sens l'autre sortie codeur est à 1
Seules 2 entrées sont nécessaires et une seule sur interruption.

Une autre solution qui y ressemble, sans interruption:

faire un pulsin sur une des sorties codeur.
tester sur l'instruction suivante l'état de l'autre sortie codeur. elle sera à 1 ou a 0 selon le sens.
si la valeur de pulsin reste à 0 c'est qu'on ne touche pas au codeur.
 

BESQUEUT

Senior Member
Non. il suffit par exemple de détecter le front montant sur la sorties codeur reliée à l'entrée INT.
qu'importe la situation: dans un sens le front montant a lieu alors que l'autre sortie codeur est à 0 et dans l'autre sens l'autre sortie codeur est à 1
Seules 2 entrées sont nécessaires et une seule sur interruption.
Dans ce cas, on n'a une détection que tous les 4 changements d'état.
Avec 2 entrées, on devrait pouvoir doubler la résolution.
Et tant pis pour les fronts descendants : la résolution n'est pas critique dans ce cas.
En tout cas, merci pour ces pistes : je n'avais pas envisagé d'utiliser quand même les interruptions quitte à perdre en résolution.
Un peu d'expérimentation devrait venir à bout du problème.
 

GM39

Senior Member
Si c'est pour faire du positionnement, les fronts montant et descendant sont nécessaires sur une des entrées, sinon il y a un risque de décalage de 1 à l'inversion. Cela dépend de l'application.
 

PapyJP

Senior Member
je suis preneur de toute bonne idée pour analyser les impulsions produites par ce bidule
et en déduire l'incrémentation ou la décrémentation d'une variable.
Une façon de résoudre le pb de ce 'bidule' est d' utiliser une bascule JK.
J reçoit le signal A, CLK reçoit le signal B (tous deux positifs dans cet exemple ), K est à la masse.
Si A passe à 1 avant B ===> la sortie Q passe à 1 (et y reste tant que A reste avant B).
Si A passe à 1 après B ===> la sortie Q passe à 0 (et y reste tant que A reste après B).
Une IT sur le front montant de B ... A vous de choisir ' incrémentation ' ou ' décrémentation ' suivant Q.
 
Last edited:

PieM

Senior Member
Si c'est pour faire du positionnement, les fronts montant et descendant sont nécessaires sur une des entrées, sinon il y a un risque de décalage de 1 à l'inversion. Cela dépend de l'application.
C'est bien sûr. Toutefois, je ne pense pas que ce type de codeur manuel serve à faire du positionnement.
Sinon pour augmenter résolution et sureté dans le décodage, il faut passer par du décodage de quadrature, ce qui impose de tenir compte de chaque changement d'état comparé à l'état précedent; pas facile dans un temps limité avec un picaxe.
A moins d'utiliser un décodeur spécifique type HCTL2000.
 

BESQUEUT

Senior Member
Si c'est pour faire du positionnement, les fronts montant et descendant sont nécessaires sur une des entrées, sinon il y a un risque de décalage de 1 à l'inversion. Cela dépend de l'application.
C'est juste un bouton pour incrémenter ou décrémenter une valeur sur un écran LCD.
Cela dit, le bidule est cranté, et c'est quand même un peu gênant que le nombre ne varie que tous les 2 clics...
 

BESQUEUT

Senior Member
Une façon de résoudre le pb de ce 'bidule' est d' utiliser une bascule JK.
J reçoit le signal A, CLK reçoit le signal B (tous deux positifs dans cet exemple ), K est à la masse.
Si A passe à 1 avant B ===> la sortie Q passe à 1 (et y reste tant que A reste avant B).
Si A passe à 1 après B ===> la sortie Q passe à 0 (et y reste tant que A reste après B).
Une IT sur le front montant de B ... A vous de choisir ' incrémentation ' ou ' décrémentation ' suivant Q.
Pas sur d'avoir tout compris, mais je n'ai pas l'impression que ça améliore la détection des fronts descendants.
En outre (mais honte à moi, je ne l'avais pas indiqué dans le cahier des charges) le montage doit être le plus compact possible et ça ne m'arrange pas d'ajouter un CI.
Comme c'est un 28X2 à fond les manettes (64 mhz), et que l'encodeur est actionné à la main, donc ne peut pas tourner très vite, j'ai bon espoir de détecter les changements à la volée dans une boucle sans fin.
Mais d'abord, il faut que je fasse marcher le LCD HAC-162J
et bien évidement ce n'est pas un truc standard, donc j'ai eu un peu de mal à trouver la doc.
Je vous tiens au courant ; merci pour les avis avisés.
 

PieM

Senior Member
Il y a la solution d'un pseudo demi quadratique ...
on attends d'avoir les deux entrée à 1 et on regarde ce qui se passe après , 01 ou 10
puis on attends d'avoir les deux à 0 et on regarde ce qui se passe après , 01 ou 10
 

GM39

Senior Member
C'est un modèle à crans, vu qu'il y a 24 impulsions /tour il n'y a sans doute que 24 crans (il n'y en a pas 48 encore moins 96) dans ce cas il faut utiliser un simple comptage. Vu l'utilisation, une perte d'impulsion est sans conséquence et une solution par scrutation est suffisante.
Code:
symbol vAprec=bit0
symbol vAact=bit1
symbol vB=bit2

'initialisation
	vAact=pinC.0
	vAprec=vAact
do
	vAact=pinC.0
	vB=pinC.1
	
	if vAact=1 and vAprec=0 and vB=1 then
		inc w10
		sertxd(#w10,32)
	elseif vAact=0 and vAprec=1 and vB=1 then
		dec w10
		sertxd(#w10,32)
	endif

	vAprec=vAact
	
loop
ou plus simple vu que le décalage l'inversion est sans importance
Code:
symbol vAprec=bit0
symbol vAact=bit1
symbol vB=bit2

'initialisation
	vAact=pinC.0
	vAprec=vAact
do
	vAact=pinC.0
	vB=pinC.1
	
	if vAact=1 and vAprec=0 then
		if vB=1 then
			inc w10
			sertxd(#w10,32)
		else
			dec w10
			sertxd(#w10,32)
		endif
	endif
	vAprec=vAact
	
loop
 

BESQUEUT

Senior Member
C'est un modèle à crans, vu qu'il y a 24 impulsions /tour il n'y a sans doute que 24 crans (il n'y en a pas 48 encore moins 96) dans ce cas il faut utiliser un simple comptage. Vu l'utilisation, une perte d'impulsion est sans conséquence et une solution par scrutation est suffisante.
24 pas par tour confirmé.
Par contre, il y a bien une transition à chaque cran, à savoir successivement :
- front montant sur A
- front montant sur B
- front descendant sur A
- front descendant sur B
Tout programme qui ne détecte qu'un type de front ou une seule des entrées rate des crans.
En particulier votre programme ne détecte qu'un cran sur 4.

Code:
#picaxe 18m2

symbol VA=bit0
symbol VB=bit1
symbol VAprec=bit8
symbol VBprec=bit9

do

	
	VA=pinC.0
	VB=pinC.1
	
	' Méthode GM39 appliquée à w10
	if VA=1 and VAprec=0 and VB=1 then
		inc W10
'		sertxd (#w10,32)
		
	elseif VA=0 and VAprec=1 and VB=1 then
		dec w10
'		sertxd (#w10,32)
	endif
	
		
	if VA<>VAprec then	' Transition sur A
		if VA=0 then	' donc VAprec=1...
			if VB=0 then
				inc w11
			else
				dec w11
			endif
			
		else ' VA=1 et VAprec=0
			if VB=0 then
				dec w11
			else
				inc w11
			endif
		endif
			
		sertxd (#VAprec,#VBprec,"=>",#VA,#VB," A ",#w10,"  ",#w11,13,10)
		toggle 2
		
		
	elseif VB<>VBprec then	' Transition sur B
		if VB=0 then
			if VA=0 then
				dec w11
			else
				inc w11
			endif
			
		else ' VB=1
			if VA=0 then
				inc w11
			else
				dec w11
			endif
		endif
			
		sertxd (#VAprec,#VBprec,"=>",#VA,#VB," B ",#w10,"  ",#w11,13,10)
		toggle 3
	endif
	
	
	
	VAprec=VA
	VBprec=VB
loop
Sortie :
Code:
00=>11 A 1  1
11=>10 B 1  2
10=>00 A 1  3
00=>01 B 1  4
01=>11 A 2  5
11=>10 B 2  6
10=>00 A 2  7
00=>01 B 2  8
01=>11 A 3  9
11=>01 A 2  8
01=>00 B 2  7
00=>10 A 2  6
10=>11 B 2  5
11=>01 A 1  4
01=>00 B 1  3
00=>10 A 1  2
10=>11 B 1  1
11=>01 A 0  0
01=>00 B 0  65535
00=>10 A 0  65534
10=>11 B 0  65533
11=>01 A 65535  65532
01=>11 A 0  65533
11=>10 B 0  65534
10=>00 A 0  65535
00=>01 B 0  0
01=>11 A 1  1
On constate que w10 ne change qu'une fois sur 4.
 
Last edited:

BESQUEUT

Senior Member
Avec ce codage sur 4 bits, il y a 16 cas possibles :
- 4 correspondent à aucun changement d'état,
- 4 sont en principe impossibles,
- 4 correspondent à une incrémentation,
- 4 correspondent à une décrémentation.
En optimisant un peu, on peut simplifier le code :
Code:
#picaxe 18m2

symbol VA=bit0
symbol VB=bit1
symbol VAprec=bit8
symbol VBprec=bit9

do

	
	VA=pinC.0
	VB=pinC.1
		
	if b0<>b1 then
		if VAprec=VB then
			inc w10
		else
			dec w10
		endif
'		sertxd (#VAprec,#VBprec,"=>",#VA,#VB," b0=",#b0," ",#w10,13,10)
		sertxd (#w10," ")
	endif
	
	VAprec=VA
	VBprec=VB
loop
Les 4 transitions sont détectées par le "if b0 <> b1..."
Toute l'astuce est dans le "if VAprec=VB..."
Ça marche correctement tant que l'encodeur ne tourne pas trop vite.
Quand on "zippe", on a des transitions impossibles, voire inverses, mais impossible de savoir si c'est l'encodeur qui merde ou si c'est le programme qui saute des transitions.
 

BESQUEUT

Senior Member
Tentative d'amélioration en supposant que le programme est trop occupé par le sertxd pour prendre en charge l'arrivée d'une transition :
Code:
#picaxe 18m2

symbol VA=bit0
symbol VB=bit1
symbol VAprec=bit8
symbol VBprec=bit9
symbol Ecrire=bit16

do

	
	VA=pinC.0
	VB=pinC.1
	
	
	if b0<>b1 then
		if VAprec=VB then
			inc w10
		else
			dec w10
		endif
		ecrire=1
		
	elseif Ecrire=1 then
		sertxd (#w10," ")
		ecrire=0
	endif
	
	VAprec=VA
	VBprec=VB
loop
C'est mieux quand on zippe : parfois on passe deux ou trois valeurs d'un coup (normal , puisqu'on n'affiche que si ça ne va pas trop vite)
Mais il y a quand même des retours arrière.
 

BESQUEUT

Senior Member
Autre tentative, avec des interruptions :
Code:
#picaxe 18m2

symbol VA=bit0
symbol VB=bit1
symbol VAprec=bit2
symbol VBprec=bit3
symbol Ecrire=bit8



gosub Interrupt

do
	pause 500
	toggle 1
	if Ecrire=1 then
		sertxd (#w10," ")
		Ecrire=0
	endif	
loop

interrupt:
	VA=pinC.0
	VB=pinC.1
	if VAprec=VB then
		inc w10
	else
		dec w10
	endif

	VAprec=VA
	VBprec=VB
	Ecrire=1
	
'	b2=1-VB*2+1-VA
'	setint OR b2,%00000011

	if VA=0 then
		if VB=0 then
			setint OR %00000011,%00000011
		else
			setint OR %00000001,%00000011
		endif
	else
		if VB=0 then
			setint OR %00000010,%00000011
		else
			setint OR %00000000,%00000011
		endif
	endif
	
	return
Pas vraiment mieux.
On verra ce que ça donne sur le 28X2 à fond, mais la platine est compliquée à mettre au point, donc plus tard.
En tout cas, j'ai assez pour avancer sur mon projet.

NB:
Le compilateur n'accepte pas "setint OR b2,%00000011"
Si quelqu'un sait pourquoi ?
 

dje8269

Senior Member
En tout cas, j'ai assez pour avancer sur mon projet.
Ca ressemble à quoi un projet de BESQUEUT ? Une mini fusee à propulsion atomique pour aller voir curiosity ? ( je plaisante bien sur)
 

BESQUEUT

Senior Member
Ca ressemble à quoi un projet de BESQUEUT ? Une mini fusee à propulsion atomique pour aller voir curiosity ? ( je plaisante bien sur)
J'ai un ami qui a monté un drone (évidement complètement illégal) pour faire la traversé du continent vers la Corse... beau projet...
Mais mon sujet du moment est une tête panoramique automatique. Ça sert à faire une succession de photos horizontalement et verticalement. Ça peut aller d'une dizaine à quelques centaines, d'où les différents réglages.
Ça existe, mais c'est cher et fait pour de gros réflex, donc difficilement transportable en rando.
Le but est d'utiliser un Canon S95 ou S100, tout petit et très performant.
D'où les contraintes mécaniques et d'encombrement...
J'ai déjà fait des trucs assez subtils, mais ça prends du temps :
http://caissonvideo.blogspot.fr/
 

PieM

Senior Member
Le compilateur n'accepte pas "setint OR b2,%00000011"
Si quelqu'un sait pourquoi ?
Une variable n'est pas acceptée en fait.

PE version 6 est plus explicite :

setint OR b2,%00000011
Error: setint 'OR' only supports constants


Ce qui est bien entendu contradictoire avec la doc !!
 
Last edited:

GM39

Senior Member
En particulier votre programme ne détecte qu'un cran sur 4.
Effectivement, mais comme physiquement on ne peut pas s'arrêter entre 2 crans, il est inutile de prendre tous les fronts sinon le compteur va bondir de 4 en 4.

J'ai fait le test avec un composant de même type sur un 28X2 à 16MHz, ça fonctionne parfaitement à la vitesse la plus rapide que je peux donner sur 1/2 tour:
"1 2 3 4 5 6 7 8 9 10 9 8 7 6 5 4 3 2 1 0 65535 65534 65533 65532 65531 65530 65529 65530 65531 65532 65533 65534 65535 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 17 16 15 14 13 12 11"
 

BESQUEUT

Senior Member
Effectivement, mais comme physiquement on ne peut pas s'arrêter entre 2 crans, il est inutile de prendre tous les fronts sinon le compteur va bondir de 4 en 4.
Je ne comprends pas. Sans doute votre encodeur fonctionne-t-il différemment ?
Sur le mien, à chaque passage d'un cran, on a une des 4 transitions possibles comme montré en #14,
et votre programme ne compte qu'un cran sur 4, ce que reflète la variable w10 du même post.
Ceci est également visible en simulation en cliquant alternativement sur C.0 et C.1
Et l'axe est stable entre deux passages durs (ce que j'appelle un "cran")
 
Last edited:

GM39

Senior Member
Quand on tourne un bouton qui a des crans, on s'attend à ce que pour une rotation d'un cran le compteur varie de 1 et non de 4.

Le mien est un modèle à 20 impulsions par tour et 20 crans. (entre 2 crans il y a une séquence complète avec 4 transitions).

S'il n'y a qu'une des 4 transitions sur les 2 voies entre 2 crans, c'est qu'en réalité c'est un 6 impulsions par tour par voie et non 24 et la description est erronée.
 
Last edited:

BESQUEUT

Senior Member
(entre 2 crans il y a une séquence complète avec 4 transitions).
A quoi ça sert puisqu'on ne peut pas arrêter l'axe entre deux crans ?
Accessoirement c'est plus compliqué à fabriquer, donc fatalement plus cher !
La référence donnée en #1 indique une phase de 54° +- 15°, soit environ 1/6 tour.
Sauf erreur de ma part, 6x4 transitions = 24 transitions, ce qui correspond bien à 24 crans.
Par contre, il ne s'agit effectivement pas de 24 impulsions.
Nos posts se sont croisés :
effectivement, mon encodeur n'est pas un RE16, même s'il y ressemble à s'y méprendre : même disposition, mêmes dimensions, mais le RE16 dispose d'un capot métallique alors que le mien est tout plastique.
Le mystère est éclairci.
 
Last edited:

BESQUEUT

Senior Member
Effectivement, ça n'est pas un RE16, mais il n'y a aucune référence lisible.
Ca serait donc plutôt un truc du genre :
http://fr.farnell.com/bourns/ecw0j-b24-ac0006/codeur-6-cycles-tr/dp/109111
Mais sans l'écrou... donc encore plus cheap.
En tout cas, j'ai effectivement besoin de détecter les 4 changements ...
Il est probable que la fabrication sommaire soit responsable de choses pas catholiques en fonctionnement à vitesse élevée. ; mais l'usage prévu ne justifie pas (encore) l'acquisition d'un modèle plus fiable.
 

PieM

Senior Member
S'il s'était agit de compter des impulsions et de déterminer le sens , les solutions étaient données déjà depuis #1.
En particulier, la solution avec interruption permettait de faire du comptage sans perturber le programme.
La solution avec pusin était très rapide également et ne demande que 6 lignes de programme.
détecter les 4 fronts est un peu plus difficile car il faut passer par une table d'états et entraîne une routine spécifique peut être en utilisant le multitâche ?
 

BESQUEUT

Senior Member
S'il s'était agit de compter des impulsions et de déterminer le sens , les solutions étaient données déjà depuis #1.
En particulier, la solution avec interruption permettait de faire du comptage sans perturber le programme.
La solution avec pusin était très rapide également et ne demande que 6 lignes de programme.
détecter les 4 fronts est un peu plus difficile car il faut passer par une table d'états et entraîne une routine spécifique peut être en utilisant le multitâche ?
Les routines données en #15, #16 et #17 détectent correctement les 4 transitions, n'utilisent pas de table et sont assez courtes il me semble.
Elles feront peut-être le bonheur d'un Picaxien qui dispose d'un encodeur du même type ou qui doit détecter les 4 transitions par exemple pour un encodeur non cranté.
La réactivité sera encore meilleure avec un Picaxe plus rapide, mais en l'état c'est déjà utilisable. En outre, le X2 dispose d'interruptions hard...
Je ne suis d'ailleurs pas certain que le PICAXE soit en cause : c'est peut-être simplement l'encodeur qui loupe quelques transitions...

En tout cas merci à tous d'avoir attiré mon attention sur l'existence d'encodeurs avec une impulsion par cran et non une transition par cran. J'aurai l&#8217;&#339;il la prochaine fois...
 

PieM

Senior Member
Si on est trop rapide, il y a un risque avec les rebonds.
Exact. C'est ce que font les décodeurs spécialisées en traitant une table de valeurs: si après transition on se retrouve avec la même combinaison, l'info est est ignorée. Mais c'est lourd à gérer avec un picaxe !
 

PieM

Senior Member
Bonjour,

Petit programme de décodeur quadratique fait maison !
celui ci compte/décompte à chaque changement d'état des deux entrées ...
Il est possible de détecter une erreur.

Code:
'================================
'décodeur quadrature 
'PieM 140505
'================================

#picaxe 08M2

symbol InputA 		= pinc.3
symbol InputB 		= pinc.4
symbol Comb_act  	= b0	'combinaison actuelle
symbol Comb_Preced 	= b1	'combinaison pecédente


main:'________________________________________________

do
 	bit0 = InputA
 	bit1 = InputB
 	
	if Comb_act <> Comb_Preced then 
		b0 = b0*4 	
		bit0 = bit8
		bit1 = bit9

		select b0
		
		case 1,7,14,8
			inc w3
		case 2,4,13,11
			dec w3
		case 3,6,9,12
			'gosub error
		
		end select 
		
		
		b0 = b0/4
		b1=b0

	endif
loop
 

PieM

Senior Member
Un encore plus petit pour la route ... (36 octets)

Code:
'================================
'décodeur quadrature Version 02
'PieM 140505
'================================

#picaxe 08M2

symbol InputA 		= pinc.3
symbol InputB 		= pinc.4
symbol Comb_act  	= b0	'combinaison actuelle
symbol Comb_Preced 	= b1	'combinaison pecédente

'________________________________________________
main:

do
 	bit0 = InputA
 	bit1 = InputB
 	
	if Comb_act <> Comb_Preced then 
		Comb_Preced= Comb_Preced * 2 xor Comb_act
		if bit9 = 0 then
			inc w3
		else 
			dec w3
		endif
		Comb_Preced=Comb_act
	endif
loop
 
Last edited:

PieM

Senior Member
en plus court et plus rapide !

Code:
'================================
'décodeur quadrature Version 03
'PieM 140505
'================================

#picaxe 08M2

symbol InputA 		= pinc.3
symbol InputB 		= pinc.4

symbol Comb_act  	= b0	'combinaison actuelle
symbol Comb_Preced 	= b1	'combinaison pecédente
symbol Compt		= w3	'compteur
'________________________________________________
main:

do
 	bit0 = InputA
 	bit1 = InputB
 	
	if Comb_act <> Comb_Preced then
	    Compt = bit1 xor bit8 *2 + compt - 1
	    Comb_Preced=Comb_act
	endif
loop
 

MGU

Senior Member
en plus court et plus rapide !

Code:
'================================
'décodeur quadrature Version 03
'PieM 140505
'================================

#picaxe 08M2

symbol InputA 		= pinc.3
symbol InputB 		= pinc.4

symbol Comb_act  	= b0	'combinaison actuelle
symbol Comb_Preced 	= b1	'combinaison pecédente
symbol Compt		= w3	'compteur
'________________________________________________
main:

do
 	bit0 = InputA
 	bit1 = InputB
 	
	if Comb_act <> Comb_Preced then
	    Compt = bit1 xor bit8 *2 + compt - 1
	    Comb_Preced=Comb_act
	endif
loop
Bonjour,

Je dispose de cet encodeur :
http://www.gotronic.fr/art-encodeur-inter-ec11e15244g1-16982.htm
dit "15 impulsions", il possède 30 crans par tour et avec le petit code ci dessus, l'incrémentation est de 2 à chaque cran. Pour une incrémentation de 1, il faut s'arrêter entre deux crans.
Questions:
Peut on modifier ce code pour l'adapter à cet encodeur?
Sinon, quel encodeur faut il pour ce code?

En tout cas, merci pour ces quelques lignes.

MM
 
Last edited:
Top