interface 16 entrées/sorties avec un picaxe20X2 et pcf 8574a

cemoa

Member
Bonjour Piem et à toute la communauté
Je vous remercie pour tous vos très bons conseils, ils me permettent d'avancer mon projet.

Maintenant j'ai besoin de gérer au moins 12 cantons pour le moment. Donc j'utilise encore un 20X2 et des PCF8574A. J'ai repris le programme du clavier 16 touches que j'ai modifié pour gérer 16 entrée/sorties. Le truc fonctionne très bien pour 8 entrées sorties, mais pour 16, je ne comprends pas ce qu'il faut faire pour utiliser le 2ème PCF8574A pour passer à 16 entrées/sorties.
Pourriez vous m'aider pour comprendre le fonctionnement avec 2 pcf 8574 que j'ai en stock.
Par avance merci.

Code pour 8 entrées/sorties.
Code:
#picaxe 20x2
#no_data
Symbol io_adr = $70	'I2C addresse du 1er PCF8574AP en ecriture
Symbol io_adr2 = $72'I2C addresse du 2eme PCF8574AP en lecture
Symbol io_adr3 = $77	'i2c addresse du 3eme pcf8574ap en lecture
symbol io_adr4 = $79	'i2c addresse du 4eme pcf8574ap en lecture

symbol flag=bit0
symbol cpt=b1
symbol poidsfaible = b2
symbol num_capteur = b3
symbol octetlu = b4
symbol var_temp=b5
symbol temp = b9
symbol capteurmini=b10
symbol capteurmaxi=b11
symbol capteur=b12

hi2csetup i2cmaster, io_adr,i2cfast,i2cbyte 'addresse du 1er pcf8574ap en ecriture

		hi2cout [io_adr],(%11111111)
		hi2cout [io_adr2],(%11111111)
		hi2cout [io_adr3],(%00000000)
		hi2cout [io_adr4],(%00000000)	
		
num_capteur=255
capteurmini=0:capteurmaxi=16
'capteur=0

num_capteur=255
capteurmini=0:capteurmaxi=16 '--->8

gosub lectouche	

			sertxd("num capteur : ",#num_capteur,13,1)
var_temp =num_capteur  '-1 // 8   ; var_temp devient 0 ? 7
var_temp = dcd var_temp      ; met le bit n? (var_temp) ? 1  

if num_capteur <9 then : hi2cout [io_adr3],(var_temp)
  elseif num_capteur <17 then : hi2cout [io_adr4],(var_temp)

endif
pause 200             
reset

lectouche:
	do	
		poidsfaible=%00000000	;init ? xxxx0001	
		for cpt=1 to 8	;scann sur bits poids faible
			pause 20

			temp=not poidsfaible  or %00000000  ;
		hi2cout [io_adr],(temp)	;envoi octet

			pause 20
		hi2cin [io_adr],(octetlu)	;test sur retour octet	

			if octetlu <=254  and flag=0 and	octetlu <> temp then	;pins < 11111111 (255) c?d une touche appuyee, premier passage	
				pause 20
				lookdown octetlu,(254,253,251,247, 239,223,191,127),num_capteur	

	sertxd("temp: ",#temp,"octet lu: ",#octetlu,"num capteur: ",#num_capteur,13,1)			
				flag=1
			elseif octetlu > 254 and flag=1  then	;relachement touche	
	pause 20
			flag=0
				if num_capteur <=capteurmaxi and num_capteur>=capteurmini then retour
pause 20
			endif
			poidsfaible=poidsfaible*2	;decalage du 0 a gauche (futur 1...)
next

	loop
retour:
	return
essai de code pour 16 entrées/sorties:
Code:
#picaxe 20x2
#no_data
symbol io_adr = $70	'i2c addresse du 1er pcf8574ap en ecriture
symbol io_adr2 = $72'i2c addresse du 2eme pcf8574ap en ecriture
symbol io_adr3 = $77	'i2c addresse du 3eme pcf8574ap en lecture
symbol io_adr4 = $79	'i2c addresse du 4eme pcf8574ap en lecture

symbol flag=bit0
symbol cpt=b1
symbol poidsfaible = b2
symbol num_capteur = b3
symbol octetlu = b4
symbol var_temp=b5
symbol temp = b9
symbol capteurmini=b10
symbol capteurmaxi=b11
symbol capteur=b12

hi2csetup i2cmaster, io_adr,i2cfast,i2cbyte 'addresse du 1er pcf8574ap en ecriture

		hi2cout [io_adr],(%11111111)
		hi2cout [io_adr2],(%11111111)
		hi2cout [io_adr3],(%00000000)
		hi2cout [io_adr4],(%00000000)	
		
num_capteur=255
capteurmini=0:capteurmaxi=16 '--->8

gosub lectouche	

			sertxd("num capteur : ",#num_capteur,13,1)
var_temp =num_capteur  '-1 // 8   ; var_temp devient 0 ? 7
var_temp = dcd var_temp      ; met le bit n? (var_temp) ? 1  

if num_capteur <9 then : hi2cout [io_adr3],(var_temp)
  elseif num_capteur <17 then : hi2cout [io_adr4],(var_temp)

endif
pause 200             
reset
lectouche:
	do	
		poidsfaible=%00000000	;init ? xxxx0001	
		for cpt=1 to 16	;scann sur bits poids faible
			pause 20

			temp=not poidsfaible  or %00000000  ;
			if cpt<9 then
		hi2cout [io_adr],(temp)	;envoi octet
		elseif cpt>8 then
			
		hi2cout [io_adr2],(temp)	;envoi octet			

			pause 20
		end if
		if cpt<9 then
		hi2cin [io_adr],(octetlu)	;test sur retour octet	
	elseif cpt>8 then
		hi2cin [io_adr2],(octetlu)	;test sur retour octet	
		end if
			if octetlu <=254  and flag=0 and	octetlu <> temp then	;pins < 11110000 (240) c?d une touche appuyee, premier passage	
				pause 20
				lookdown octetlu,(254,253,251,247,239,223,191,127,246,245,243,239,231,215,183,119),num_capteur	

	sertxd("temp: ",#temp,"octet lu: ",#octetlu,"num capteur: ",#num_capteur,13,1)			
				flag=1
			elseif octetlu > 254 and flag=1  then	;relachement touche	
	pause 20
			flag=0
				if num_capteur <=capteurmaxi and num_capteur>=capteurmini then retour
pause 20
		endif


next
	loop
retour:
	return
View attachment 21154
 

PieM

Senior Member
Bonjour,
je ne comprends pas:
votre objectif est de lire les entrées de vos deux pcf.
les adresses concernées sont donc $71 et $73.
pour le picaxe, le dernier bit est à 0

donc il faut successivement adresser les deux pcf en lisant l'octet sur leur port.

donc:
hi2cin [$70],(octetlu)
....
traitement
.....

puis
hi2cin [$72],(octetlu)
....
traitement
.....

De plus avec les pcf8574A il faut utiliser le mode I2Cslow (100kHz)
ensuite, le pcf8574 a son port I/O en drain ouvert qd il est en sortie.
Sur le schéma DSN , U1, U2 (des leds?) sont connectées sur des sorties sources et non sink!
 
Last edited:

cemoa

Member
Bonjour Piem,
Après beaucoup de remu-méninge et surement quelques neuronnes en moins voici le programme et le schéma modifiés selon vos conseils, est-ce correct, puis-je faire mieux?
Les leds sur le schéma servent uniquement à visualiser le fonctionnement du programme avec VSM, en réalité il est nécessaire de passer par des uln2803 ou autres transistors car le courant de sortie des pcf 8574 est trop faible pour commander des leds, relais....

Désolé, je n'arrive pas à joindre le schéma sous aucun format.

Bonne soirée



Code:
#picaxe 20x2
#no_data
symbol io_adr = $70	'i2c addresse du 1er pcf8574ap en ecriture
symbol io_adr2 = $72'i2c addresse du 2eme pcf8574ap en lecture
symbol io_adr3 = $75	'i2c addresse du 3eme pcf8574ap en lecture
symbol io_adr4 = $77	'i2c addresse du 4eme pcf8574ap en lecture

symbol flag=bit0
symbol cpt=b1
symbol poidsfaible = b2
symbol num_capteur = b3
symbol octetlu = b4
symbol var_temp=b5
symbol capteur_1=b6
symbol capteur_10=b7
symbol temp = b9
symbol capteurmini=b10
symbol capteurmaxi=b11
symbol capteur=b12

hi2csetup i2cmaster, io_adr,i2cslow,i2cbyte 

		hi2cout [io_adr],(%00000000)
		hi2cout [io_adr2],(%00000000)
		hi2cout [io_adr3],(%11111111)
		hi2cout [io_adr4],(%11111111)	
		
num_capteur=255
capteurmini=0:capteurmaxi=16
'capteur=0

gosub lectouche	
	lookup num_capteur,("0123456789"),capteur
capteur_1=num_capteur+1
capteur_10=num_capteur+9


var_temp =num_capteur  '-1 // 8   ; var_temp devient 0 ? 7
var_temp = dcd var_temp      ; met le bit n? (var_temp) ? 1  

if cpt=>1 and cpt=<8 then : hi2cout [io_adr],(var_temp)
			sertxd("num capteur : ",#num_capteur," - capteur : ",#capteur," - capteur + 1 : ",#capteur_1,13,10,13,10)
		
  elseif cpt <17 and cpt=>9 then : hi2cout [io_adr2],(var_temp)
			sertxd("num capteur : ",#num_capteur," - capteur : ",#capteur," - capteur + 10 : ",#capteur_10,13,10)
endif
pause 200             
reset

lectouche:
	do	
		poidsfaible=%00000000
		
		for cpt=1 to 17	;scann sur bits poids faible
			temp=not poidsfaible  or %00000000
;------------------------capteurs 1 a 8
			if cpt=>1 and cpt=<8 then

		hi2cout [io_adr3],(temp)	;envoi octet
		hi2cin [io_adr],(octetlu)	;test sur retour octet	
				lookdown octetlu,(254,253,251,247, 239,223,191,127),num_capteur	
					pause 20	


;------------------------capteurs 9 a 16			
			elseif cpt <17 and cpt=>9 then
			'temp=not poidsfaible  or %00000000 
				hi2cout [io_adr4],(temp)
				hi2cin [io_adr2],(octetlu)
				lookdown octetlu,(254,253,251,247, 239,223,191,127),num_capteur	
			end if

			pause 20

				if num_capteur <=capteurmaxi and num_capteur>=capteurmini then retour
pause 20

			poidsfaible=poidsfaible*2	;decalage du 0 a gauche (futur 1...)
next
	loop
retour:
	return
 

PieM

Senior Member
Les leds sur le schéma servent uniquement à visualiser le fonctionnement du programme avec VSM, en réalité il est nécessaire de passer par des uln2803 ou autres transistors car le courant de sortie des pcf 8574 est trop faible pour commander des leds, relais....
Non! le pcf est capable de commander des leds, à condition de les connecter correctement.
Relire mon post : les leds doivent être connectées entre Vcc et la sortie (qui fournit 25mA dans ce cas).

De plus je ne comprends pas ce que vient faire la partie type lecture touche.
que doit faire votre programme ?
Il semble qu'il doit lire l'état de 16 entrées et non 1 parmi 16 et de commander des sorties individuelles, non ?
 
Last edited:

cemoa

Member
Non! le pcf est capable de commander des leds, à condition de les connecter correctement.
Relire mon post : les leds doivent être connectées entre Vcc et la sortie (qui fournit 25mA dans ce cas).

De plus je ne comprends pas ce que vient faire la partie type lecture touche.
que doit faire votre programme ?
Il semble qu'il doit lire l'état de 16 entrées et non 1 parmi 16 et de commander des sorties individuelles, non ?
bonjour PieM,
En effet câblées comme vous le dite, les sorties supportent les leds, mais comme le programme doit commander des relais, je pense devoir utiliser tout de même des uln2803.
ce programme détecte le passage d'un train sans arrêt pour commander l'alimentation d'une voie, pour cela les capteurs de passage sont des interrupteurs ILS, donc je pense qu'il est possible d'utiliser la lecture de l'état de 16 entrées ou de 1 parmi 16. Je vais essayer les 2 méthodes.
 

PieM

Senior Member
bonjour PieM,
En effet câblées comme vous le dite, les sorties supportent les leds, mais comme le programme doit commander des relais, je pense devoir utiliser tout de même des uln2803.
ce programme détecte le passage d'un train sans arrêt pour commander l'alimentation d'une voie, pour cela les capteurs de passage sont des interrupteurs ILS, donc je pense qu'il est possible d'utiliser la lecture de l'état de 16 entrées ou de 1 parmi 16. Je vais essayer les 2 méthodes.
Il me semble beaucoup plus simple de lire en direct l'état de vos ILS, d'autant plus que le pcf génère une interruption lors des changements d'état.
Le principe utilisé pour le clavier est de lire une matrice 4 lignes 4 colonnes, ce qui n'est pas le cas des capteurs ILS, vu le câblage.

Et concernant les relais, vous pouviez utiliser cette carte qui est pilotable directement avec vos sorties pcf, via les opto coupleurs intégrés!
 
Last edited:

cemoa

Member
Il me semble beaucoup plus simple de lire en direct l'état de vos ILS, d'autant plus que le pcf génère une interruption lors des changements d'état.
Le principe utilisé pour le clavier est de lire une matrice 4 lignes 4 colonnes, ce qui n'est pas le cas des capteurs ILS, vu le câblage.

Et concernant les relais, vous pouviez utiliser cette carte qui est pilotable directement avec vos sorties pcf, via les opto coupleurs intégrés!
Si il est permis d'utiliser un même PCF 8574 en lecture/écriture selon le schéma joint, le code ci-dessous est peut-être suffisant pour lire en direct les ILS, ce qui ferait bien mon affaire car j'ai besoin du restant des entrées/sorties du 20X2 pour d'autres fonctions! en simulation VSM, ça marche, maintenant faut voir en prototypage
désolé, je n'arrive pas à joindre le schéma, je dois certainement vider le fichier des pièces jointes. Je peux réessayer plus tard.

Pours les relais, je vous remercie pour votre conseil, mais j'ai déjà préparé mes cartes universelles 4 relais 2R/T.

Bonne soirée

Code:
#picaxe 20x2
#no_data
symbol io_adr = $70	
symbol io_adr2 = $72

symbol cpt=b1
symbol temp = b9

hi2csetup i2cmaster, io_adr,i2cslow,i2cbyte 

		hi2cout [io_adr],(%11111111)
		hi2cout [io_adr2],(%11111111)
do
' -------------premier pcf
	for cpt=1 to 16
	 if cpt=>1 and cpt=<8 then
hi2cin [io_adr],(temp)
if temp<255 then
hi2cout [io_adr],(temp)
end if
'-------------deuxieme pcf	
elseif cpt =>9 and cpt=<16 then
hi2cin [io_adr2],(temp)
if temp<255 then
	hi2cout [io_adr2],(temp)
end if
end if	
next

loop
reset
 

PieM

Senior Member
Très sincèrement je ne comprends rien à votre programme.
Une lecture de l'état du premier PCF > vers temp
puis écriture de temp dans le même PCF !
idem pour le second...

la finalité de votre programme est de plus en plus opaque.
désolé mais je ne pense pas pouvoir poursuivre.
 

cemoa

Member
Très sincèrement je ne comprends rien à votre programme.
Une lecture de l'état du premier PCF > vers temp
puis écriture de temp dans le même PCF !
idem pour le second...

la finalité de votre programme est de plus en plus opaque.
désolé mais je ne pense pas pouvoir poursuivre.
en effet mon idée était très mauvaise
 

westaust55

Moderator
interface 16 entrées/sorties avec un picaxe20X2

Les leds sur le schéma servent uniquement à visualiser le fonctionnement du programme avec VSM, en réalité il est nécessaire de passer par des uln2803 ou autres transistors car le courant de sortie des pcf 8574 est trop faible pour commander des leds, relais....

Désolé, je n'arrive pas à joindre le schéma sous aucun format.
@cemoa,

L'affichage d'une description schématique et simple dans les étapes permettrait à d'autres de mieux comprendre votre objectif.

Le PCF 8574A a en effet une capacité de courant très limitée pour les sortie / Source - seulement quelques microammères, il peut couler typiquement 25 milliamètres.
Si vous connectez la LED ou le relais de Vcc (5 volts) aux les sorties PCF 8574A pour qu'elles puissent ensuite s'allumer jusqu'à 25 mA est possible.

Quelle est la note actuelle des relais que vous proposez?

Un autre IC peut-être mieux à considérer est le MCP23017 par microchip. Cette puce n'a que 8 broches plus, mais elle a fourni 16 I/O sur une puce en tant que deux ports bi-directionnels à 8 broches. Ils peuvent être configurés pour être deux registres d'adresses consécutifs afin qu'une seule commande Hi2cIN puisse lire toutes les 16 broches dans une seule commande.
Le MCP23017 a été discuté sur la partie anglaise du forum avec des exemples de programmes.
 

cemoa

Member
Bonjour Westaust55

je vous remercie pour vos informations
J'ai utilisé les PCF 8574A que j'avais en stock, les relais commandés par les PCF sont des Finders 30.22.7, 12V DC. Pour le moment le fonctionnement est satisfaisant. Je vais m'intéresser au MCP23017 ainsi qu'au PCF 8575 pour la suite du projet.

Peut-être je n'ai pas la bonne méthode, je n'arrive pas joindre le fichiers DSN (192 Ko)
Désolé
 
Top