Discussions Générales > Bus DCC
Arduino + LMD18200
jpjcb66:
Bonjour à tous,
J'ai une loco Roco achetée début des années 2000 équipée d'un décodeur Roco.
Elle fonctionne normalement, lumière et moteur avec le système Roco Transfo 15V 40VA+ centrale 10761 + maus2.
J'ai en bon curieux appliqué "locoduino.org/spip.php?article14 et suivants" en lieu et place du matériel Roco.
Mon décodeur est paramétré en 01.
J'ai donc modifié les deux lignes 36 : dps.setFunctions0to4(1,DCC_SHORT_ADDRESS,F0); et 55 : dps.setSpeed128(1,DCC_SHORT_ADDRESS,speed_byte);
Le moniteur série fait bien ressortir une plage de fonctionnement entre -128 et 128 en actionnant le potar.
Mais ça doit être plus sioux que ça car il n'y a que l'éclairage de la machine qui répond au BP.
J'ai tout relu, ce n'est pas forcément évident.
Quelque chose qui vous semblera certainement évident depuis le temps que vous planchez sur le DCC m’échappe.
Si une idée passe par là..... Je continue à chercher et vais essayer avec le nouveau décodeur reçu ce matin.
Merci
Dominique:
Bonjour,
Désolé pour le retard (considérable) !!!
Pour diagnostiquer, il faudrait un peu plus de code. Mais une première expérience à faire consiste à répéter les commandes 2, 3, ou 4 fois par seconde.
Si le code marche pour l'éclairage, ça prouve que l'adresse est bonne.
Pour la vitesse, il est certain que certains décodeurs (peut-être tous) ne réagissent que si la commande est répétée.
Dites-moi si ça change, sinon, envoyez moi votre code.
Bon courage
jpjcb66:
Bonsoir Dominique,
En effet ma question date un peu. J'ai du mettre ça en stand by et passer à autre chose, dont mon aiguillage 3 voies.
Je reviendrai la semaine prochaine sur ce problème Dcc.
Merci pour la reponse même tardive, vieux motard.......
Bonne soirée.
jpjcb66:
--- Citation de: Dominique le avril 29, 2016, 09:28:42 pm ---Bonjour,
Désolé pour le retard (considérable) !!!
Pour diagnostiquer, il faudrait un peu plus de code. Mais une première expérience à faire consiste à répéter les commandes 2, 3, ou 4 fois par seconde.
Si le code marche pour l'éclairage, ça prouve que l'adresse est bonne.
Pour la vitesse, il est certain que certains décodeurs (peut-être tous) ne réagissent que si la commande est répétée.
Dites-moi si ça change, sinon, envoyez moi votre code.
Bon courage
--- Fin de citation ---
Voici le code très simple que j'ai voulu tester :
Le bouton active la lumière de la machine mais aucune réaction au potar.
Demain si j'ai le temps de câbler un pupitre j'essaierai ton code bien plus complet.
Bonne soirée et merci pour le coup d’œil.
--- Code: ---/********************
* Centrale DCC minimum avec un potentiomètre de vitesse connecté
* sur le port analogique 0,
* un bouton poussoir connecté entre le 0V et l'entrée digitale 4
* Le signal DCC est délivré sur la Pin 9, et est capable de piloter
* un booster à base de LMD18200 directement.
********************/
#include <DCCPacket.h>
#include <DCCPacketQueue.h>
#include <DCCPacketScheduler.h>
DCCPacketScheduler dps;
unsigned int analog_value;
char speed_byte, old_speed = 0;
byte count = 0;
byte prev_state = 1;
byte F0 = 0;
void setup() {
Serial.begin(9600);
dps.setup(); // initialisation de la librairie
// Bouton sur la pin 4
pinMode(4, INPUT_PULLUP);
}
void loop() {
// Lecture de l'état du bouton pour la commande de lumière F0
byte button_state = digitalRead(4); //high == relaché; low == appuyé
if(button_state && (button_state != prev_state))
{
// inversion de l'état
F0 ^= 1;
Serial.println(F0,BIN);
dps.setFunctions0to4(1,DCC_SHORT_ADDRESS,F0); // adresse DCC 1
}
prev_state = button_state;
// Potentiomètre de vitesse
analog_value = analogRead(0);
speed_byte = (analog_value >> 2)-127 ;
// Ramène la gamme 0-1023 à +126-126, l'arrêt étant le point milieu du potentiomètre
if(speed_byte != old_speed)
{
if(speed_byte == 0) // On évite l'arrêt brutal (e_stop) en remplaçant le 0 par 1
{
if(old_speed > 0) speed_byte = 1;
else speed_byte = -1;
}
Serial.print("analog = ");
Serial.println(analog_value, DEC);
Serial.print("digital = ");
Serial.println(speed_byte, DEC);
dps.setSpeed128(1,DCC_SHORT_ADDRESS,speed_byte);
old_speed = speed_byte;
}
// Cet appel est impératif pour permettre à la librairie de faire son travail
dps.update();
}
--- Fin du code ---
Dominique:
J'aurais tendance à penser qu'il faut ajouter dans le SetUp:
--- Code: ---pinMode(A0, INPUT);
--- Fin du code ---
Et bien désigner la pin analogique par A0 (plutôt que "0")
Si ça peut vous aider, j'ai écrit une classe Loco en C++ qui contient tout ce qu'on a besoin :
--- Code: ---class Loco
{
private:
byte index; // 0..MaxLOCO
byte manette;
bool etat; // arrêt (false) ou roule (true)
int adresseDCC; //
int vitesse; // cran en cours
byte prev_vitesse; //
bool dirloco; // direction avant ou arriere
bool inverse; // inversion ou non de la direction
byte maxSpeed;
byte minSpeed;
byte cran30;
byte cran60;
bool change; // true : changement vitesse, direction, et/ou F0
int potarPin;
int potarLu;
int potarPrev;
int pot[16]; // 16 lectures du potentiometre
int indexpot;
int clePin;
int cleDir;
int clePrev;
int boutonPin;
Bounce bloco;
int ledPin;
int ledAcc;
byte lumiere;
public:
// ----------- constructeur complet ------------
Loco(byte a_index, int a_adresseDCC, int a_potarPin, int a_clePin, int a_boutonPin, int a_ledPin, bool a_inverse);
void Setup();
int adrDCC();
void SetadrDCC(byte a_adresseDCC);
void SetmaxSpeed(byte a_maxSpeed);
void SetminSpeed(byte a_minSpeed);
void Setcran30(byte a_cran30);
void Setcran60(byte a_cran60);
void Rafraichir();
void Repeter();
void Nommer();
void AllerAvant();
void AllerArriere();
void SetVitesse(int a_vitesse);
void Stopper();
void SetVitesse30();
void SetVitesse60();
void ResetVitesse();
void Ralentir();
byte Lumiere();
void SetLumiere(bool a_F0);
byte Direction();
void SetDirection(bool a_Dir);
void EtatLoco();
};
// ------------ definition des methodes -----------
Loco::Loco(byte a_index, int a_adresseDCC, int a_potarPin, int a_clePin, int a_boutonPin, int a_ledPin, bool a_inverse)
{
this->index = a_index;
this->manette = this->index;
this->potarPin = a_potarPin;
this->clePin = a_clePin;
this->boutonPin = a_boutonPin;
this->bloco = Bounce();
this->ledPin = a_ledPin;
this->adresseDCC = a_adresseDCC;
this->inverse = a_inverse;
this->vitesse = 0;
this->prev_vitesse = 0;
this->dirloco = true;
this->etat = false;
this->change = false;
this->ledAcc = 0;
this->lumiere = false;
this->maxSpeed = 125;
this->minSpeed = 2;
this->cran30 = 25;
this->cran60 = 50;
this->indexpot = 0;
}
void Loco::Setup()
{
pinMode(this->ledPin, OUTPUT);
digitalWrite(this->ledPin, HIGH); // Led ON
delay (500);
digitalWrite(this->ledPin, LOW); // Led OFF
pinMode(this->boutonPin, INPUT_PULLUP); // bouton
this->bloco.attach(this->boutonPin); // input pin associée
this->bloco.interval(50); // debouce time en millisecondes
pinMode(this->clePin, INPUT_PULLUP); // direction
this->cleDir = digitalRead(this->clePin);
this->dirloco = this->cleDir;
pinMode(this->potarPin, INPUT); // speed pot
this->potarLu = 0;
this->indexpot = 0;
for (int z=0; z<16; z++) {
this->pot[z] = analogRead(this->potarPin) >> 3;
this->potarLu = this->potarLu + this->pot[z];
}
this->potarLu = this->potarLu >> 4;
this->potarPrev = this->potarLu;
this->vitesse = 00;
if (this->dirloco == 0) { // avant = 1 arriere = 0
this->vitesse = -this->vitesse;
}
digitalWrite(this->ledPin, this->ledAcc);
// chargement des parametres depuis le record en RAM
this->adresseDCC = EEPConfig[this->index].dccAddress;
this->maxSpeed = EEPConfig[this->index].MaxSpeed;
this->minSpeed = EEPConfig[this->index].MinSpeed;
this->cran30 = EEPConfig[this->index].cran30;
this->cran60 = EEPConfig[this->index].cran60;
this->inverse = EEPConfig[this->index].inverse;
}
int Loco::adrDCC()
{
return(this->adresseDCC);
}
void Loco::SetadrDCC(byte a_adresseDCC)
{
this->adresseDCC = a_adresseDCC;
}
void Loco::SetmaxSpeed(byte a_maxSpeed)
{
this->maxSpeed = a_maxSpeed;
}
void Loco::SetminSpeed(byte a_minSpeed)
{
this->minSpeed = a_minSpeed;
}
void Loco::Setcran30(byte a_cran30)
{
this->cran30 = a_cran30;
}
void Loco::Setcran60(byte a_cran60)
{
this->cran60 = a_cran60;
}
void Loco::Rafraichir()
{
this->pot[indexpot++] = analogRead(this->potarPin) >> 3; // divide by 8 to take a 0-1023 range number and make it 0-127 range.
if (indexpot > 15) {indexpot = 0;}
this->potarLu = 0;
for (int z=0; z<16; z++) {
this->potarLu = this->potarLu + this->pot[z];
}
this->potarLu = this->potarLu >> 4;
if ((this->potarLu < this->potarPrev -1)||(this->potarLu > this->potarPrev +1)) {
this->potarPrev = this->potarLu;
if (this->potarLu < this->maxSpeed) {
this->vitesse = this->potarLu;
} else {
this->vitesse = this->maxSpeed;
}
if (this->vitesse == 1) {
this->vitesse = 0; // pour eviter l'arrêt d'urgence par potar
}
this->change = true;
}
this->cleDir = digitalRead(this->clePin);
if (this->cleDir != this->clePrev && this->vitesse == 0) {
this->clePrev = this->cleDir;
this->dirloco = this->cleDir ^ this->inverse; // av1 ^ inv1 = 0, ar0 ^ inv1 = 1
this->change = true;
}
if (this->change) {
this->prev_vitesse = this->vitesse; // version sans signe vs direction
if (this->dirloco == 0) { // avant = 1 arriere = 0
this->vitesse = -this->vitesse;
}
dps.setSpeed128(this->adresseDCC,DCC_SHORT_ADDRESS,this->vitesse);
this->change = false;
bufS[0] = this->index;
if (this->lumiere) {
bitSet(bufS[0], 7); // bit 7 = lumière
}
bufS[1] = this->prev_vitesse; // vitesse sans signe, bit 7 = 0
if (this->dirloco) {
bitSet(bufS[1], 7);
}
CAN.sendMsgBuf(TId_LOCO, 0, 2, bufS); // envoi paramêtres de conduite (Index, Vit, Dir, F0)
if (_debug) {
Serial.print(this->vitesse);
Serial.print(" V loco @ ");
Serial.println(this->adresseDCC);
}
}
if (this->bloco.update()) {
if (this->bloco.rose()) { // appui = 1 relaché = 0 : inversion lumiere
if (this->lumiere) {
this->lumiere = 0;
} else {
this->lumiere = 1;
}
dps.setFunctions0to4(this->adresseDCC,DCC_SHORT_ADDRESS,this->lumiere);
digitalWrite(this->ledPin, this->lumiere);
bufS[0] = this->index;
if (this->lumiere) {
bitSet(bufS[0], 7); // bit 7 = lumière
}
CAN.sendMsgBuf(TId_F0, 0, 1, bufS); // envoi paramêtres index et F0
if (_debug) {
Serial.print(this->lumiere);
Serial.print(" F0 loco @ ");
Serial.println(this->adresseDCC);
}
}
}
}
void Loco::Repeter()
{
dps.setSpeed128(this->adresseDCC,DCC_SHORT_ADDRESS,this->vitesse);
dps.setFunctions0to4(this->adresseDCC,DCC_SHORT_ADDRESS,this->lumiere);
}
void Loco::SetVitesse(int a_vitesse) // definit la vitesse maxi
{
this->maxSpeed = a_vitesse;
if (this->prev_vitesse > a_vitesse) { // réduire la vitesse seulement si la vitesse maxi est inférieure
this->vitesse = a_vitesse;
this->prev_vitesse = a_vitesse; // version sans signe vs direction
if (this->dirloco == 0) { // avant = 1 arriere = 0
this->vitesse = -this->vitesse;
}
dps.setSpeed128(this->adresseDCC,DCC_SHORT_ADDRESS,this->vitesse);
bufS[0] = this->index;
if (this->lumiere) {
bitSet(bufS[0], 7); // bit 7 = lumière
}
bufS[1] = this->prev_vitesse; // vitesse sans signe, bit 7 = 0
if (this->dirloco) {
bitSet(bufS[1], 7);
}
CAN.sendMsgBuf(TId_LOCO, 0, 2, bufS); // envoi paramêtres de conduite (Index, Vit, Dir, F0)
if (_debug) {
Serial.print(this->vitesse);
Serial.print(" V loco @ ");
Serial.println(this->adresseDCC);
}
} // sinon pas de changement de vitesse
}
void Loco::Stopper()
{
SetVitesse(0);
}
void Loco::SetVitesse30()
{
SetVitesse(this->cran30);
}
void Loco::SetVitesse60()
{
SetVitesse(this->cran60);
}
void Loco::ResetVitesse() // remonte la vitesse maxi à maxSpeed
{
SetVitesse(this->maxSpeed);
}
void Loco::SetLumiere(bool a_F0)
{
this->lumiere = a_F0;
dps.setFunctions0to4(this->adresseDCC,DCC_SHORT_ADDRESS,this->lumiere);
digitalWrite(this->ledPin, this->lumiere);
bufS[0] = this->index;
if (this->lumiere) {
bitSet(bufS[0], 7); // bit 7 = lumière
}
CAN.sendMsgBuf(TId_F0, 0, 1, bufS); // envoi paramêtres index et F0
if (_debug) {
Serial.print(this->lumiere);
Serial.print(" F0 loco @ ");
Serial.println(this->adresseDCC);
}
}
byte Loco::Lumiere()
{
return(this->lumiere);
}
void Loco::SetDirection(bool a_Dir)
{
this->dirloco = a_Dir;
}
byte Loco::Direction()
{
return(this->dirloco);
}
--- Fin du code ---
Je n'aime pas les potentiomètres de vitesse à point milieu (on ne trouve jamais le milieu !!!), donc j'ai une clé pour la direction. D'ailleurs j'interdis le changement de sens sans passer par l'arrêt.
Tenez moi au courant !
Cordialement
Navigation
[#] Page suivante
Utiliser la version classique