Pages: 1 2 [3] 4 5   Go Down
Author Topic: [RESOLU] Utilisation bibliothèques PCF8574 et PCF8575  (Read 6230 times)
0 Members and 1 Guest are viewing this topic.
Moselle (FR)
Offline Offline
Edison Member
*
Karma: 16
Posts: 1250
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir Skywodd,
Je continue mes tests. Pour suivre le déroulement du programme, j'ai placé des Serial.println dans les différentes fonctions. Mon programme est le même que celui de l'exemple de la librairie et la seule modification que j'ai faite et de changer CHANGE en FALLING dans enableInterrupt.
Voici les traces obtenues (> pour l'entrée et < pour la sortie) :
Après un reset
>enableInterrupt
<enableInterrupt
>attachInterrupt
<attachInterrupt

Première action sur le BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
4
5
6
7
<checkForInterrupt
<ISRgateway

Deuxième action sur BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
>ISRdemo
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
4
5
6
7
<checkForInterrupt
<ISRgateway
<ISRdemo
4
5
6
7
<checkForInterrupt
<ISRgateway

Si j'observe au scope l'évolution des signaux sur l'entrée P3 et la sortie !INT, je constate :
Premier appuie sur BP : j'ai le passage de haut vers bas de l'entrée et une franche chute de haut vers bas de la sortie INT
Pour les appuies suivants : toujours le passage de 1 vers 0 de l'entrée mais la sortie INT et moins évidente à observer.
@+
Logged

2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

C'est bien un probléme d'interruption qui se déclenche pendant une autre interruption.

Je pense avoir trouvé la source du probléme, essaye avec la dernière version du code :
https://github.com/skywodd/pcf8574_arduino_library
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Moselle (FR)
Offline Offline
Edison Member
*
Karma: 16
Posts: 1250
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour Skywodd,
Je viens de faire les premiers tests.
Le programme exemple se déroule normalement tant que l'on appuie pas sur le BP.
Lors du premier appuie il ne se passe rien.
Lors du deuxième appuie le programme se plante. Avec mes modifications pour le traçage, j'ai l'affichage de "ISR" qui est le début du message "ISRgateway" et la diode pin13 reste allumée.
Le programme n'aime pas cli().
@+
[EDIT1] Pour sortir du plantage, il faut 2 actions sur le bouton Reset !
[EDIT2] Si je laisse uniquement readGPIO() dans la partie begin(), le premier appuie sur BP ne fait plus rien !
« Last Edit: September 01, 2013, 02:29:11 am by icare » Logged

2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

IDF/SO
Offline Offline
Edison Member
*
Karma: 41
Posts: 2261
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Je vais peut-être dire une connerie, mais ce ne sera pas la première ni hélas la dernière.  smiley-mr-green

Si j'ai bien compris vous avez une collision entre plusieurs interruptions. Wire utilise les interruptions mais il existe d'autres bibliothèques I2C pour avr qui n'utilisent pas les interruptions -> peut-être une piste ?

J'avais trouvé il y a quelque temps une telle bibliothèque qui depuis sa révision 5 n'utilise plus les interruptions, mais je l'ai pas testé.
http://dsscircuits.com/articles/arduino-i2c-master-library.html
Logged

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Lors du premier appuie il ne se passe rien.
C'est déjà pas normal ...

Lors du deuxième appuie le programme se plante. Avec mes modifications pour le traçage, j'ai l'affichage de "ISR" qui est le début du message "ISRgateway" et la diode pin13 reste allumée.
Le programme n'aime pas cli().
Arf je viens de comprendre ... en faisant un cli() avant de lancer la fonction utilisateur ça bloque dans la fonction utilisateur qui elle utilise l'i2c ...
Enlève le cli voir ce que ça donne.

Si j'ai bien compris vous avez une collision entre plusieurs interruptions. Wire utilise les interruptions mais il existe d'autres bibliothèques I2C pour avr qui n'utilisent pas les interruptions -> peut-être une piste ?
Le probléme ne vient pas vraiment du conflit d'interruption mais du re-déclenchement de l'interruption sur INT lors de la lecture de l'état des broches.

[EDIT2] Si je laisse uniquement readGPIO() dans la partie begin(), le premier appuie sur BP ne fait plus rien !
Bon tente un truc, à partir de la dernière version (buggé ...)
https://github.com/skywodd/pcf8574_arduino_library/commit/86b57053e2bd8a5f904ca41b88205ecb91d90b5e#PCF8574/PCF8574.cpp

Garde juste la ligne PCattachInterrupt(pin, selfCheckFunction, FALLING); et laisse les autres lignes comme dans l'ancienne version.
-> Est-ce que ça marche (ou du moins est-ce que ça refait bien comme avant) ?

Décommente  le readGPIO(); dans la fonction updateGPIO()
-> marche / marche plus ? Est-ce que ça refait le coup des interruptions croisées ? Est-ce que le 1er appui marche ?

Ajoute le readGPIO() dans le begin()
-> mêmes questions qu'au dessus

Ensuite recommente le readGPIO(); dans la fonction updateGPIO()
-> mêmes questions qu'au dessus
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Moselle (FR)
Offline Offline
Edison Member
*
Karma: 16
Posts: 1250
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,
Je vais faire les essais tout à l'heure.
Petit test avec le PCF8574 :
Si on utilise le PCF avec 2 résistances de pullup sur SDA et SCL + 1 résistance de pullup sur INT (le bus I2C non relié) + 1 résistance de pullup avec un BP vers le GND (branché sur l'une des pins du PCF)
=> la durée de INT est égale à celle de l'action sur BP (une impulsion courte sur BP = une impulsion courte sur INT, une impulsion longue sur BP = une impulsion longue sur INT).
Rq: j'utilise un BP sans rebonds
@+
Logged

2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

Moselle (FR)
Offline Offline
Edison Member
*
Karma: 16
Posts: 1250
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,
Je viens de faire les différents tests que tu préconisais :
Situation initiale (FALLING dans PCattachInterrupt)
Après reset
>enableInterrupt
<enableInterrupt
>attachInterrupt
<attachInterrupt

Premier appuie sur BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
4
5
6
7
<checkForInterrupt
<ISRgateway

Deuxième appuie sur BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
>ISRdemo
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
4
5
6
7
<checkForInterrupt
<ISRgateway
<ISRdemo
4
5
6
7
<checkForInterrupt
<ISRgateway

On retrouve bien la situation du 30/08/2013 avec les mêmes résultats
Situation avec readGPIO() dans updateGPIO()
Après reset
>enableInterrupt
<enableInterrupt
>attachInterrupt
<attachInterrupt

Premier appuie sur BP
Il ne se passe rien l'interruption INT n'est pas détecté
Deuxième appuie sur BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
>ISRdemo
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
4
5
6
7
<checkForInterrupt
<ISRgateway
<ISRdemo
4
5
6
7
<checkForInterrupt
<ISRgateway

Situation avec readGPIO() dans begin()
Après reset
>enableInterrupt
<enableInterrupt
>attachInterrupt
<attachInterrupt

Premier appuie sur BP
Il ne se passe rien l'interruption INT n'est pas détecté
Deuxième appuie sur BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
>ISRdemo
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
4
5
6
7
<checkForInterrupt
<ISRgateway
<ISRdemo
4
5
6
7
<checkForInterrupt
<ISRgateway

Situation sans readGPIO() dans updateGPIO()
Après reset
>enableInterrupt
<enableInterrupt
>attachInterrupt
<attachInterrupt

Premier appuie sur BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
4
5
6
7
<checkForInterrupt
<ISRgateway

On détecte bien INT qui va voir dans checkForInterrupt et trouve que la pin 3 est tombée mais n’exécute pas ISRdemo
Deuxième appuie sur BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
>ISRdemo
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
4
5
6
7
<checkForInterrupt
<ISRgateway
<ISRdemo
4
5
6
7
<checkForInterrupt
<ISRgateway

On exécute ISRdemo mais avec 2 détections provenant de INT
Voila pour les tests. J'espère que ça va te donner une meilleure vision du problème.
S'il faut faire d'autres tests, il n'y a pas de problème, je suis prêt
@+
[EDIT1]
Lors du premier appuie dans checkForInterrupt():
Code:
case FALLING:
  Serial.println("falling");
if ((oldPIN & (1 << i)) && !(PIN & (1 << i))){ //<<-- cette condition est fausse -----------
  Serial.println("falling1");
intCallback[i]();
                        }
break;
Lors du deuxième appuie, elle est vrai
[EDIT2]
Peut être une piste : Dans le programme je n'ai gardé qu'une partie. Dans loop(), il ne me reste plus qu'un delay(3000) et dans setup(), j'ai commenté attachInterrupt().
Il me reste ISRgateway avec uniquement le Serial.prinln d'entrée et de sortie (juste pour signaler la trace du passage
Résultat : il faut appuyer 2 fois sur le BP pour que cela marche.
« Last Edit: September 02, 2013, 01:35:00 am by icare » Logged

2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

Moselle (FR)
Offline Offline
Edison Member
*
Karma: 16
Posts: 1250
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,
Je viens de faire un petit programme de test :

Code:
#include "PCint.h"
void setup() {
  /* Setup serial for debug */
  Serial.begin(115200);
  pinMode(8, INPUT_PULLUP);
  PCattachInterrupt(8, ISRgateway, FALLING);
}  //fin setup
/** This function will be called each time the state of a pin of the PCF8574 change */
void ISRgateway() {
  Serial.println(">ISRgateway");
//  PCF8574_checkForInterrupt();
  Serial.println("<ISRgateway");
}  //fin ISRgateway
void loop() {
  delay(3000);
}
Le BP directement sur D8 et dans cas il faut aussi 2 appuies sur BP pour avoir le message
Logged

2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Mise à jour du code effectué.
Ce coup ci je devrait avoir définitivement tordu le coup aux doubles interruptions.
https://github.com/skywodd/pcf8574_arduino_library/commit/c31e17ebfb3a22486e2319414cf203401dc10aae

Quote
On détecte bien INT qui va voir dans checkForInterrupt et trouve que la pin 3 est tombée mais n’exécute pas ISRdemo
Vu ton code de test (cf post au dessus) c'est peut être un bug de PCint.
Je pense même avoir trouvé le bug en question dans le code.

Test mon code en l'état puis tente de rajouter :
Code:
PCintLast[0] = *portInputRegister(2);
PCintLast[1] = *portInputRegister(3);
PCintLast[2] = *portInputRegister(4);
A la fin de la fonction PCattachInterrupt().
(en gros la librairie Pcint lors de la 1er interruption travaille avec un tableau non initialisé, pas tiptop tout ça)
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Moselle (FR)
Offline Offline
Edison Member
*
Karma: 16
Posts: 1250
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,
Code:
PCintLast[0] = *portInputRegister(2);
PCintLast[1] = *portInputRegister(3);
PCintLast[2] = *portInputRegister(4);
A la fin de la fonction PCattachInterrupt().
(en gros la librairie Pcint lors de la 1er interruption travaille avec un tableau non initialisé, pas tiptop tout ça)
Avec la modification proposée mon petit programme test avec BP direct sur D8 fonctionne très bien et au premier appuie sur BP on va en ISRgateway.
Le test de la librairie suit.
@+
Logged

2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

Moselle (FR)
Offline Offline
Edison Member
*
Karma: 16
Posts: 1250
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Re,
J'ai testé le code en l'état :
Après reset
>enableInterrupt
<enableInterrupt
>attachInterrupt
<attachInterrupt

Premier appuie BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
oldPIN=0b1001
PIN=0b1001
i=0b11
4
5
6
7
<checkForInterrupt
<ISRgateway

On détecte P3 falling sans passer par ISRdemo
Deuxième appuie sur BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
oldPIN=0b1001
PIN=0b1
i=0b11
falling1
>ISRdemo
>ISRgateway
>checkForInterrupt
<ISRgateway
<ISRdemo
4
5
6
7
<checkForInterrupt
<ISRgateway

On a 2 fois l'interruption est en passe par ISRdemo
Troisième appuie sur BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
oldPIN=0b1
PIN=0b11
i=0b11
4
5
6
7
<checkForInterrupt
<ISRgateway
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
oldPIN=0b11
PIN=0b1111
i=0b11
4
5
6
7
<checkForInterrupt
<ISRgateway

On a 2 fois l'interruption est en ne passe pas par ISRdemo
Cela fonctionne une fois sur deux smiley-sad
Fonctionnement identique avec la modification de PCint.h
J'ai fait la modification suivante :
Code:
       /* Avoid nested interrupt triggered by I2C rad/write */
        if(_isrIgnore)
            return;
          else
//            _isrIgnore = 1;
            _isrIgnore = 0;
Résultat du test avec la modification ci-dessus + modification PCint.h
Après reset
>enableInterrupt
<enableInterrupt
>attachInterrupt
<attachInterrupt

Premier appuie BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
oldPIN=0b11111001
PIN=0b11110001
i=0b11
falling1
>ISRdemo
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
oldPIN=0b11110001
PIN=0b11111000
i=0b11
4
5
6
7
<checkForInterrupt
<ISRgateway
<ISRdemo
4
5
6
7
<checkForInterrupt
<ISRgateway

Deuxième appuie sur BP
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
oldPIN=0b11111000
PIN=0b11110001
i=0b11
falling1
>ISRdemo
>ISRgateway
>checkForInterrupt
0
1
2
intMode=2
falling
oldPIN=0b11110001
PIN=0b11111000
i=0b11
4
5
6
7
<checkForInterrupt
<ISRgateway
<ISRdemo
4
5
6
7
<checkForInterrupt
<ISRgateway

Malgré les appels multiples cela fonctionne dès le premier appuie sur BP smiley
@+
[EDIT1] J'ai remplacé le BP sans rebonds par un BP normal avec sa résistance de pullup. Les résultats des tests sont les mêmes toujours 2 fois l'interruption sur D8 mais pas plus. Le hard semble être hors de cause.
[EDIT2] L'utilisation de _isrIgnore n'améliore pas la situation car dans ce cas le programme fonctionne une fois sur deux.
« Last Edit: September 03, 2013, 12:33:07 am by icare » Logged

2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

Moselle (FR)
Offline Offline
Edison Member
*
Karma: 16
Posts: 1250
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir Skywodd,
Pour l'instant la solution la plus satisfaisante est :
- tes modifications de PCint.h
- sans la gestion _isrIgnore
J'ai fait de nombreux essais pour les INT multiples mais sans résultats probants
@+
Logged

2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Pour l'instant la solution la plus satisfaisante est :
- tes modifications de PCint.h
- sans la gestion _isrIgnore
J'ai fait de nombreux essais pour les INT multiples mais sans résultats probants
Pour la modif de PCint, ok ce bug est réglé.
Pour la partie isrIgnore j'abandonne, un if aussi basique DEVRAIT fonctionner, ce fonctionnement en flip-flop n'as pas de sens.

J'ai fait un test expérimental (en commentaire) dans la fonction updateGPIO() sensé éviter les conflits entre les broches en INPUT_PULLUP et _PORT.
Je suis quasiment sûr que ça réglera pas le probléme mais le datasheet n'étant d'aucune aide si ça ce trouve ça peut marcher.

Edit: ce soir je tenterai un truc, j'ai remis la main sur un PCF8574.
« Last Edit: September 04, 2013, 06:24:59 am by skywodd » Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Moselle (FR)
Offline Offline
Edison Member
*
Karma: 16
Posts: 1250
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,
La répétition de l'interruption semble provenir de chekForInterrupt car si l'on commente chekForInterrupt dans ISRgateway, on n'a pas de répétition de l'interruption. Elle est unique à chaque appuie sur le BP.
Mais j'ai du mal à comprendre ce qui se passe dans cette partie du programme smiley-sad
Logged

2B OR NOT(2B) = FF
Arduino 1.0.5 + Notepad++ (sous Linux Fedora et/ou Windows)

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

La répétition de l'interruption semble provenir de chekForInterrupt car si l'on commente chekForInterrupt dans ISRgateway, on n'a pas de répétition de l'interruption. Elle est unique à chaque appuie sur le BP.
Si tu commentes checkForInterrupt() plus rien ne vas marcher ... cette fonction test la présence d'une interruption.
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

Pages: 1 2 [3] 4 5   Go Up
Jump to: