Bonjour,
(J'ajoute ce message dans un fil existant car le titre me semble convenir parfaitement)
J'ai réalisé une simple station DCC++ basée sur un UNO + motorshield 'Deek-Robot' (clone Arduino genuine shield ) + librairie DCCPP v1.3.7
Les commandes de base moteur <t...> et fonction <f... > ont été directement OK.
J'ai par contre rencontré beaucoup de difficultés avec la lecture / écriture des CV.
Pour éviter tout effet parasite, je suis revenu à tester une situation de base : commande texte directe par le serial monitor + conection USB , décodeur ( j'ai utilisé un LAIS 860010 bon marché) hors locomotive , connecté directement à la sortie de prog (comme une voie de programmation 'propre' sans autre charge, ni résistance, ni condensateur) , moteur simulé par une résistance (avec assez de W !) + 2 leds tête bêche avec une résistance de protection.
J'ai modifié la librairie pour ajouter plus de messages de debug et en particulier regarder la valeur de 'base' pour la mesure de courant et la durée de l'impulsion de courant de la réponse du décodeur.
Je m'attends dans cette configuration à obtenir base toujours pratiquement = 0 (ou 1)
Dans le cas de readCV c'est le cas lors de la comparison du premier bit , mais ensuite non. Si 2 bits = 1 se suivent (par exemple CV1 = 3 = 11000000) la lecture du 2eme rate car base est alors beaucoup trop grand.
En fait si le décodeur ne répond pas par une pointe de courant , alors on execute toujour les 500 AnalogRead. Si on a une réponse positive la boucle est interrompue dans checkAcknowlegde par le test
if (c > ACK_SAMPLE_THRESHOLD)
return 1;
Ceci semble être apparu dans le version 1.3.7 avec la création de la fonction checkAcknowlegde . Dans le code original de Gregg E. Berman et dans les versions antérieures de la librairie cele me semble OK. Dans la nouvelle version 1.4.1, le problème est le même.
J'ai modifié le code checkAcknowlegde pour rester dans la boucle même quand le test est positif et tout ce passe bien.
int RegisterList::checkAcknowlegde(int inMonitorPin, int inBase) volatile
{
int c = 0; int d = 0;
for (int j = 0; j < ACK_SAMPLE_COUNT; j++)
{
int val = (int)analogRead(inMonitorPin);
c = (int)((val - inBase) * ACK_SAMPLE_SMOOTHING + c * (1.0 - ACK_SAMPLE_SMOOTHING));
if (c > ACK_SAMPLE_THRESHOLD){
// remain in the loop for ACK_SAMPLE_COUNT read !!
d = 1;
}
}
return d;
}
Dans le cas de WriteCvByte j'ai un problème similaire: lors de vérification qui suit l'écriture la valeur n'est pas du tout nulle. Dans mon cas le décodeur 'répond' à l'écriture par l'implusion de courant mais le code n'essaie de le lire et passe donc trop vite à la vérification. Je ne sais pas ce que d'autres décodeurs font . Dans le standard de NMRA on trouve : "Upon completion of all write operations, the Digital Decoder may respond with an acknowledgment" Les décodeurs sont donc libres de répondre ou pas.
En fait dans mon cas l'écriture marche toujours mais j'ai du modifier le code de WriteCvByte (et WriteCvBit) pout avoir la vérification correcte. J'essaie de lire la réponse du décodeur et j'ignore le résultst car on fait de toute façon la vérification ensuite.
======= begin modif code
// define base for reading response
if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN) base = RegisterList::buildBaseAcknowlegde(DCCppConfig::CurrentMonitorProg);
bWrite[0] = 0x7C + (highByte(cv) & 0x03); // any CV>1023 will become modulus(1024) due to bit-mask of 0x03
bWrite[1] = lowByte(cv);
bWrite[2] = bValue;
loadPacket(0, resetPacket, 2, 1);
loadPacket(0, bWrite, 3, 4);
loadPacket(0, resetPacket, 2, 1);
loadPacket(0, idlePacket, 2, 10);
// try to read answer + ignore results (anyhow we verify afterwards)
if (DCCppConfig::CurrentMonitorProg != UNDEFINED_PIN) ret = RegisterList::checkAcknowlegde(DCCppConfig::CurrentMonitorProg, base);
======== end modif code
J'espère que ceci peut aider un peu les problèmes rencontrés pour lire / écrire des CV.
Jean-Paul.