Problemes de vitesse sur POV clock...

Bonjour à tous,
J’ étais sur une horloge à persistance rétinienne qui fonctionne bien, équipée de 8 leds directement cablée sur un arduino nano 328.
Pour afficher mes caractères de 85, j’ allumais chacune des 5 colonnes pendant 200 microsecondes en laissant un délai d’autant pour espacer les pixels. Pour un bel affichage j’avais avec ces valeurs une résolution de 1288 mais je pouvais monter beaucoup plus en compressant les pixels.
Aujourd’hui je suis sur une nouvelle horloge de 40 leds bleues pilotées par 5 * 74HC595 en I2C et toujours un nano 328.
Avec cette configuration je n’arrive pas à obtenir plus de 40*60 parce que le bus I2C ou l’arduino ne tourne pas assez vite j’ai l’impression…
En faisant ce bout de code :

  for (i=0; i<60; i++)
  {
  digitalWrite(verrou, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, 0b11111111);
  shiftOut(dataPin, clockPin, LSBFIRST, 0b11111111);
  shiftOut(dataPin, clockPin, LSBFIRST, 0b11111111);        
  shiftOut(dataPin, clockPin, LSBFIRST, 0b11111111);
  shiftOut(dataPin, clockPin, LSBFIRST, 0b11111111);        
  digitalWrite(verrou, HIGH); 
  delayMicroseconds (delaimicro);
  digitalWrite(verrou, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, 0b00000000);
  shiftOut(dataPin, clockPin, LSBFIRST, 0b00000000);
  shiftOut(dataPin, clockPin, LSBFIRST, 0b00000000);        
  shiftOut(dataPin, clockPin, LSBFIRST, 0b00000000);
  shiftOut(dataPin, clockPin, LSBFIRST, 0b00000000);        //init
  digitalWrite(verrou, HIGH); 
  delayMicroseconds (delaimicro);
  }

Je devrais avec ça obtenir un écran de 60 ce qui est déjà peu, et même en supprimant les deux délais j’ai au maximum 40*60…
Qu’ en pensez-vous?
L’ I2C me ralentirais? (les 5 registres sont en cascade, y a t’il meilleur moyen de les piloter?)
La fonction shiftOut trop lourde?
J’ai vu plusieurs fois cette configuration en fouillant sur google, je sais que c’est possible avec ce matériel…
Des idées?
Merci à vous pour votre aide!

Par défaut l'horloge du SPI est configurée à 4MHz elle peut encore être doublée. La librairie SPI offre cette fonction : setClockDivider()

Après pour pouvoir juger de qui ralenti il faudrait faire quelques mesures sur le SPI pour voir s'il y a des poses et de quelle durée entre les shiftOut.

Maintenant je ne vois pas l'intérêt de vider le registre à décalage puisque son contenu va être remplacé par le transfert suivant. Si tu as des images fantômes, il serait plus efficace d'utiliser la broche clear qui vide le registre à décalage d'un coup.

shiftout n’est pas un exemple de rapidité, il vaut mieux passer par une liaison plus directe. je n’ai aucun recul sur les possibilitées de dialogue arduino / 595 en hard (SPI), mais si c’est possible, mieux vaut oublier shiftout. j’a déjà programmé des 595, mais en créant moi-même ma fonction shiftout().

pour info, voici le code de la fonction shiftOut :

void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
	uint8_t i;

	for (i = 0; i < 8; i++)  {
		if (bitOrder == LSBFIRST)
			digitalWrite(dataPin, !!(val & (1 << i)));
		else	
			digitalWrite(dataPin, !!(val & (1 << (7 - i))));
			
		digitalWrite(clockPin, HIGH);
		digitalWrite(clockPin, LOW);		
	}
}

c’est relativement bien codé, à part que les digitalWrite() prennent beaucoup de temps, et c’est ça qui doit te ralentir.

fdufnews:
Par défaut l’horloge du SPI est configurée à 4MHz elle peut encore être doublée.
La librairie SPI offre cette fonction : setClockDivider()

Après pour pouvoir juger de qui ralenti il faudrait faire quelques mesures sur le SPI pour voir s’il y a des poses et de quelle durée entre les shiftOut.

Maintenant je ne vois pas l’intérêt de vider le registre à décalage puisque son contenu va être remplacé par le transfert suivant.
Si tu as des images fantômes, il serait plus efficace d’utiliser la broche clear qui vide le registre à décalage d’un coup.

Pour clarifier mon propos, je parle là de la librairie SPI qui elle utilise le périphérique SPI intégré et non pas une émulation comme le shiftOut(). Elle est rapide.
Cette librairie fait partie du package Arduino IDE

fdufnews: Pour clarifier mon propos, je parle là de la librairie SPI qui elle utilise le périphérique SPI intégré et non pas une émulation comme le shiftOut(). Elle est rapide. Cette librairie fait partie du package Arduino IDE

Justement, c'est un peu de ça dont je parle, mais n'ayant encore jamais joué avec, je préfère ne pas trop m'étaler dessus... Il est clair qu'utiliser le SPI hard est forcément plus rapide que le shiftout!

Bonjour à tous, Merci beaucoup pour vos réponses qui m'ont beaucoup aidé et désolé pour la lenteur de ma réponse. Je viens de reprendre mon projet et viens de passer du protocole I2C au protocole SPI avec très peu de modifs au niveau câblage. Résultat l'I2C était bien trop lent pour la vitesse d'affichage que je désirais et le SPI se montre parfait, j'ai désormais une résolution de 300*40 ce qui me va très bien; malgré tout il m'est impossible d'afficher plus... Dès que je déclare un tableau de 360 pixels plus rien ne marche... en repassant à 300 sans rien changer au code ça repars... Tant pis j'en resterais là et laisse ce mystère, adieu ShiftOut, place à SPI.transfer(), donc merci à tous, je suis persuadé que ça servira à d'autres débutants! Encore merci. PS: Je galère déjà sur autre chose, je crois que je vais préparer un post! ^^

Juste une rectification pour la clarté de ton propos. ShiftOut ce n'est pas de l'I²C, c'est une émulation de SPI.

kri13400: j'ai désormais une résolution de 300*40 ce qui me va très bien; malgré tout il m'est impossible d'afficher plus... Dès que je déclare un tableau de 360 pixels plus rien ne marche... en repassant à 300 sans rien changer au code ça repars...

Je pencherais pour un problème de mémoire sans le code c'est difficile de t'aider.

fdufnews:

kri13400: j'ai désormais une résolution de 300*40 ce qui me va très bien; malgré tout il m'est impossible d'afficher plus... Dès que je déclare un tableau de 360 pixels plus rien ne marche... en repassant à 300 sans rien changer au code ça repars...

Je pencherais pour un problème de mémoire sans le code c'est difficile de t'aider.

Si ma boule de cristal est juste il utilise 5 octets par colonne (40 bits) donc 1500 octets pour 300 colonnes et 1800 pour 360 colonnes. A voir comment le code est structuré mais ça ressemble bien un problème de mémoire RAM insuffisante.