Eh bien, comme je l'ai annoncé ce matin, voici le résumé du code. C'est la première fois que je le fais, j'espère que c'est compris.
Nous commençons par l'introduction des variables et ainsi de suite :
Ceci concerne les multiplexeurs, MCP23017, trois sont définis, MCP0, MCP1 et MCP2.
//***************************************************
// Se define el valor ID para identificar origen:
// ID < FIRST_ID_MCP => arduino
// ID >= FIRST_ID_MCP and <FIRST_ID_MCP+16 => MCP0
// ID >= FIRST_ID_MCP+16 and <FIRST_ID_MCP+32 => MCP1
// ID >= FIRST_ID_MCP+32 => MCP2
//***************************************************
//////////////////////MCP23017///////////
#include <Wire.h>
#include <Adafruit_MCP23017.h>
Adafruit_MCP23017 mcp0;
Adafruit_MCP23017 mcp1;
Adafruit_MCP23017 mcp2;
#define addr0 0
#define addr1 1
#define addr2 2
const byte maxaccessories = 32;
#define FIRST_DCC_MCP 16 // primera dirección para los MCP (central Lenz)
#define FIRST_ID_MCP 10 // primer número de orden de los MCP
///////////////////////////////////////////////////////////////////////////////
Il continue avec les termes de la bibliothèque Commanders, pour gérer 16 boutons poussoirs en série, et avec la structure de chaque accessoire :
////__________ COMMANDERS ________________________________________________
#include <Commanders.h>
// Analog push buttons
ButtonsCommanderAnalogPushes pushes;
#define NUMBER_OF_ANALOG_PUSHES 16
int pushes_values[NUMBER_OF_ANALOG_PUSHES] =
{ 58,114,174,233,290,348,404,463,519,578,638,698,760,824,889,955 };
unsigned long pushes_ids[NUMBER_OF_ANALOG_PUSHES] =
{101,102,103,104,105,106,107,108,109,110,111,112,123,114,115,116};
////_______________________________________________________________________
//////////////////////////////////////
// Estructura de cada accesorio //////
typedef struct {
int address; // User Configurable. DCC address to respond to
int ID; // User Configurable. para identificar MCP0 ó MCP1
byte outputPin; // User Configurable. Arduino pin where accessory is connected to
byte onoff; // User Configurable. Initial state of accessory output: 1=on, 0=off (ON = pin LOW)
byte onoffmcp; // User Configurable. Initial state of accessory mcp: 1=on, 0=off (ON = pin LOW)
byte previous; // User Configurable. The previous reading from the input pin
byte dccstate; // Internal use. DCC state of accessory: 1=on, 0=off
}
DCCAccessoryAddress;
DCCAccessoryAddress accessory[maxaccessories];
void ConfigureDecoderFunctions()
{
for (int k = 0; k <16; k++)
{
accessory[FIRST_ID_MCP+k].address = FIRST_DCC_MCP+k; // DCC address empezando en FIRST_DCC_MCP
accessory[FIRST_ID_MCP+k].outputPin = k;
accessory[FIRST_ID_MCP+k].ID = FIRST_ID_MCP+k;
}
for (int k = 16; k <32; k++)
{
accessory[FIRST_ID_MCP+k].address = FIRST_DCC_MCP+k; // DCC address empezando en FIRST_DCC_MCP
accessory[FIRST_ID_MCP+k].outputPin = k-16;
accessory[FIRST_ID_MCP+k].ID = FIRST_ID_MCP+k;
}
} // END ConfigureDecoderFunctions
//____________________________
Le setup:
void setup()
{
Serial.begin(115200);
Commanders::begin();
DccCommander.begin(0x00, 0x00, digitalPinToInterrupt(2));
pushes.begin(A1, NUMBER_OF_ANALOG_PUSHES, pushes_ids, pushes_values, 20);
ConfigureDecoderFunctions();
DCC.SetBasicAccessoryDecoderPacketHandler(BasicAccDecoderPacket_Handler, true);
mcp0.begin(addr0);
mcp1.begin(addr1);
mcp2.begin(addr2);
for(int k=0; k<16; k++)
{
mcp0.pinMode(accessory[FIRST_ID_MCP+k].outputPin, OUTPUT);
mcp0.digitalWrite(accessory[FIRST_ID_MCP+k].outputPin, LOW);
accessory[FIRST_ID_MCP+k].previous = LOW;
}
for(int k=16; k<32; k++)
{
mcp1.pinMode(accessory[FIRST_ID_MCP+k].outputPin, OUTPUT);
mcp1.digitalWrite(accessory[FIRST_ID_MCP+k].outputPin, LOW);
accessory[FIRST_ID_MCP+k].previous = LOW;
}
} // END setup
Le loop (uniquement pour les cinq premiers boutons-poussoirs):
void loop()
{
DCC.loop(); // Loop DCC library
activation();
unsigned long ret;
ret = Commanders::loop();
switch(ret)
{
//******** Guardavias ************
case 101: // Orden = 28
pulsadoresmcp1(28);
break;
//******** Estación ************
case 102: // Orden = 11
pulsadoresmcp0(11);
break;
case 103: // Orden = 12
pulsadoresmcp0(12);
break;
case 104: // Orden = 10
pulsadoresmcp0(10);
break;
//******** Farolas (Doble circuito, 14 y 15)************
case 105: // Orden = 14 y 15
pulsadoresmcp0(14);
pulsadoresmcp0(15);
break;
} ///////////// // End switch ret
} //END loop
Enfin, les différentes fonctions définies : l'activation des accessoires :
void activation()
{
static int addr = 0;
if( ++addr >= maxaccessories ) addr = 0; // Next address to test
if (accessory[addr].dccstate) accessory[addr].onoff = 1;
else accessory[addr].onoff = 0;
if ((accessory[addr].onoff==1) && (!accessory[addr].onoffmcp))
{
if (accessory[addr].ID < FIRST_ID_MCP+16) {
mcp0.digitalWrite(accessory[addr].outputPin, HIGH);
}
if (accessory[addr].ID > FIRST_ID_MCP+15) {
mcp1.digitalWrite(accessory[addr].outputPin, HIGH);
}
accessory[addr].onoffmcp = true;
}
if ((accessory[addr].onoff==0) && (accessory[addr].onoffmcp))
{
if (accessory[addr].ID < FIRST_ID_MCP+16) {
mcp0.digitalWrite(accessory[addr].outputPin, LOW);
}
if (accessory[addr].ID > FIRST_ID_MCP+15) {
mcp1.digitalWrite(accessory[addr].outputPin, LOW);
}
accessory[addr].onoffmcp = false;
}
}///// FIN ACTIVACION //////////////////////
Celles relatives aux boutons poussoirs de Commanders
//////////////////
// Pulsadores MCP0
/////////////////
void pulsadoresmcp0(int orden)
{
if (accessory[orden].previous == HIGH) {
if (accessory[orden].onoffmcp == HIGH) accessory[orden].onoffmcp = LOW;
else accessory[orden].onoffmcp = HIGH;
}
mcp0.digitalWrite(accessory[orden].outputPin, !accessory[orden].onoffmcp);
accessory[orden].previous = !accessory[orden].onoffmcp;
} //END Pulsadores MCP0
//------------------------------------------------------
//////////////////
// Pulsadores MCP1
//////////////////
void pulsadoresmcp1(int orden)
{
if (accessory[orden].previous == HIGH) {
if (accessory[orden].onoffmcp == HIGH) accessory[orden].onoffmcp = LOW;
else accessory[orden].onoffmcp = HIGH;
}
mcp1.digitalWrite(accessory[orden].outputPin, !accessory[orden].onoffmcp);
accessory[orden].previous = !accessory[orden].onoffmcp;
} //END Pulsadores MCP1
Et la gestion des paquets DCC
///////////////////////////////
// DCC accessory packet handler
///////////////////////////////
void BasicAccDecoderPacket_Handler(int address, boolean activate, byte data)
{
// Convert NMRA packet address format to human address
address -= 1;
address *= 4;
address += 1;
address += (data & 0x06) >> 1;
boolean enable = (data & 0x01) ? 1 : 0;
for (int i=0; i<maxaccessories; i++)
{
if (address == accessory[i].address)
{
if (enable) accessory[i].dccstate = 1;
else accessory[i].dccstate = 0;
}
}
} //END BasicAccDecoderPacket_Handler
Et avec tout ça, que se passe-t-il ? Eh bien, il se trouve que, tel que le code est, les boutons poussoirs fonctionnent parfaitement, allumant et éteignant les lumières correspondantes, mais la partie DCC ne fonctionne pas (les lumières s'allument et s'éteignent de manière erratique).
Cependant, si j'annule (commente) la sentence
// ret = Commanders::loop();
ensuite les boutons poussoirs cessent de fonctionner (évident), mais la partie DCC fonctionne parfaitement ! !!
Quelqu'un peut-il m'expliquer ? ! !!!!
Muchas gracias a todos ppor vuestro interés.
Un saludo,
Juan.