Ah oui ! l'essayer c'est l'adopter !
je viens de lancer, ça sort du 10kHz !
J'ai fait des essais de mon côté sur le SPI hardware et je suis très très loin de ça ! (Avec un code qui je dois dire ne ressemble en rien)
Évidemment je vais étudier ça de très près. A première vue, je suis juste surpris de voir un seul SPI.beginTransaction dans le setup (et jamais de endTransaction... qui laisserait la main pour autre chose ?)
Mais en tous cas le résultat brut est là, à moi de l'intégrer (dans tous les sens du terme).
________________
APRES PRISE EN MAIN _______________________
J'ai en effet bien besoin d'aide, merci pour la proposition et c'est fort agréable de savoir qu'il y a une hot-line dédiée!
Après étude de ton code et différents essais, voici ce que je comprends (mais peut-être pas) et ce que je ne comprends pas (et ça c'est certain) :
1 - comprends :
- le code en l'état ne fonctionne pas, c'est un bout de code qui pourrait aider
- sa structure permet de faire du daisy-chainning très simplement (si c'est bien ça, c'est très astucieux)
2 - comprends pas :
- SPI.beginTransaction dans le setup
- ligne 6 : #define spi_latch_pin 19
// pin19 // PORTB permet l'instruction bitSet choisir une autre broche semble tout aussi possible
- ligne 32 : bitClear(PORTB, 0);
// pin19 // prépare le latch La broche 19 n'est pas sur le port B mais D et il faudrait écrire sur le bit 2 et non 0
- if (PWMx[bit0to7] >= cran) bitSet(byte_to_spi, bit0to7);
pas plutôt : if (PWMx[bit0to7] < cran) bitSet(byte_to_spi, bit0to7);
car si le cran dépasse la consigne PWM "bit0to7", ça doit provoquer le falling, non ? C'est en tous cas comme ça que ça fonctionne avec mon code.
(détail, à propos de "bit0to7" : il me semble que "byte0to7" serait plus exact et facile à comprendre. De plus, pour normaliser et comme en réalité ces datas représentent la PWM
à appliquer à une section donnée, ça pourrait donc encore plus clairement s'écrire : if (PWMx[section] < cran) bitSet(byte_to_spi, section)
3 - comprends pas bien : le choix de bitSet pour construire la trame (voir mes essais)
Pour ma part, voici mes maigres avancées :
- le passage au SPI hardware a un effet très modeste, le gain n'est que d'une 20aine de %
- devant me plier au protocole SPI, j'ai des difficultés à construire la trame. Elle est limitée par le protocole à 32bits ce qui fait que je ne peux pas atteindre les 40PWM "imposées" sans devoir faire du daisy-chainning (ou définir deux esclaves). Mais donc ça se solutionne
Le plus ennuyeux est que la construction de la trame est semble-il ce qui ralentit le code à tel point que le bénéfice du SPI rapide disparaît presque complètement
Voici le nouveau code, avec une syntaxe quasiment normalisé pour que les échanges soient plus faciles.
Dans lequel j'ai essayé deux méthodes pour construire la trame : utiliser des bitWrite est TROIS FOIS moins rapide que l'autre, d'où mon interrogation, plus haut, sur bitSet (que j'ai donc eu l'idée d'essayer, mais il nécessite un "if" et le résultat est encore plus dégradé qu'avec bitWrite)
/* ARDUINO MEGA */
#include <SPI.h>
//#include "SPIDaisyChain.h"
#define crans 128
const int8_t howmany_74HC = 4;
boolean pin74HC[howmany_74HC*8] = { 0 }; // data-table, matching with the state of the 74HC595 ouputs
// 40 pseudos PWM à émuler - pour chaque PWM, la valeur donne le cran de consigne
uint8_t PWM[40] = { 54, 64, 105, 94, 109, 80, 130, 0, 54, 64, 105, 94, 109, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0, 54, 64, 105, 94, 109, 34, 73, 0 };
uint32_t count;
uint32_t chain;
void setup() {
Serial.begin(115200);
DDRF |= B00001010; // A1 & A3 = output
SPI.begin();
}
void writeSlave1() { // https://www.arduino.cc/en/Hacking/PinMapping2560
PORTF &= B11111101; // PIN A1 (latch) = LOW
SPI.beginTransaction(SPISettings(16000000, MSBFIRST, SPI_MODE0));
SPI.transfer(chain);
SPI.endTransaction();
PORTF |= B00000010; // => HIGH
}
void setRegistersSlave1() { // Place les pins des 74HC595 à l'état HAUT ou BAS
for (uint8_t cran(0) ; cran<crans ; cran++) {
chain = 0;
for(uint8_t section(0) ; section<howmany_74HC*8 ; section++) {
chain = chain<<1;
pin74HC[section]=cran<PWM[section];
// bitWrite(chain, section, pin74HC[section]);
chain = pin74HC[section] + chain;
}
writeSlave1();
}
}
void loop() {
setRegistersSlave1();
count++;
if (millis() > 3000) {
Serial.print(count/3);Serial.println("Hz");
Serial.end();
}
}