Auteur Sujet: Projet Dominique  (Lu 9776 fois)

DDEFF

  • Sr. Member
  • ****
  • Messages: 460
    • Voir le profil
Re: Projet Dominique
« Réponse #45 le: décembre 31, 2017, 12:14:06 pm »

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1524
  • 100% Arduino et N
    • Voir le profil
Re: Projet Dominique
« Réponse #46 le: décembre 31, 2017, 03:39:42 pm »

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1524
  • 100% Arduino et N
    • Voir le profil
Re: Projet Dominique
« Réponse #47 le: décembre 31, 2017, 05:15:47 pm »
https://www.ebay.fr/itm/1Pcs-Mpr121-Capacitive-Touch-Keypad-Shield-Module-Sensitive-Key-Keyboard-New-I-P/252906299459?hash=item3ae263e043:g:JrAAAOSwx2dYIPLs///////////// Touchpad l'adresse I2C = 0x5A ///////
Adafruit_MPR121 cap = Adafruit_MPR121();
uint16_t lasttouched = 0;
uint16_t currtouched = 0;
int Key;
// Attach the MPR121's IRQ pin to digital pin 4
const int PIN_TOUCH_IRQ = 4;
Read_Keypad///////////////////////////////////////////////////////////////////////
// LECTURE CLAVIER TACTILE
///////////////////////////////////////////////////////////////////////

byte Read_Keypad(void)
{
  uint8_t i;
  bool keydown = false;
  // Get the currently touched pads
  currtouched = cap.touched();
  for (i=0; i<12; i++) {
    // if it *is* touched and *wasnt* touched before => key down
    if ((currtouched & _BV(i)) && !(lasttouched & _BV(i)) ) {
      keydown = true;
      //Serial.print(i); Serial.println(" touched");
      break;
    }
    // if it *was* touched and now *isnt* => key up (ignored)
    if (!(currtouched & _BV(i)) && (lasttouched & _BV(i)) ) {
      keydown = false;
      //Serial.print(i); Serial.println(" released");
      break;
    }
  } 
  lasttouched = currtouched;
  switch (i) {
    case 0:  i=9;  break;
    case 1:  i=6;  break;
    case 2:  i=3;  break;
    case 3:  i=11; break;
    case 4:  i=8;  break;
    case 5:  i=5;  break;
    case 6:  i=2;  break;
    case 7:  i=0;  break;
    case 8:  i=7;  break;
    case 9:  i=4;  break;
    case 10: i=1;  break;
    case 11: i=10; break;   
  }
  if (keydown) {
    return (i);
  } else {
    return (i+12);
  }
}

On remarque le switch   // gestion du clavier tactile
   if (digitalRead(PIN_TOUCH_IRQ) == LOW) {
    int Key = Read_Keypad();
   }
    // choix registre/loco hors configuration et saisie
    if ((!gConfig)&&(!gSaisie)&&(Key < 12)) {
      gId = Key;
      gCurrentLoco = gConfigLocos[gId];
      gChange = true;
      MajLeds();
    }
        //--- saisie adresse DCC
        if ((Key >= 0)&&(Key <=9)) {
          gSaisieValeur[gSaisieValeurIndex] = Key;
          if (gSaisieValeurIndex < 3) {
            gSaisieValeurIndex++;
            lcd.setCursor(14,1);
            for (int c=0;c<gSaisieValeurIndex;c++) {
              lcd.print(gSaisieValeur[c]);
            }
            lcd.print("  ");
          }
        }
        if (Key == 10) { // back
          if (gSaisieValeurIndex > 0) {
            gSaisieValeurIndex--;
            lcd.setCursor(14,1);
            for (int c=0;c<gSaisieValeurIndex;c++) {
              lcd.print(gSaisieValeur[c]);
            }
            lcd.print("  ");
          }
        }
        if (Key == 11) { // enter
          gChange = true;
          switch (gSaisieValeurIndex) {
            case 0:
            gChange = false; // saisie vide
            break;
            case 1:
            gCurrentLoco.dccAddress = gSaisieValeur[0];
            break;
            case 2:
            gCurrentLoco.dccAddress = (gSaisieValeur[0] * 10) + gSaisieValeur[1];
            break;
            case 3:
            gCurrentLoco.dccAddress = (gSaisieValeur[0] * 100) + (gSaisieValeur[1] * 10) + gSaisieValeur[2];
            break;           
          }
          lcd.setCursor(14,1);lcd.print(gCurrentLoco.dccAddress);lcd.print("  ");
          if (gChange) {
            gConfigLocos[gId] = gCurrentLoco;   // sauvegarde dans la table des locos
            EnregistreLocoEEProm(gId);          // enregistre gCurrentLoco dans l'EEPROM
          }
          gSaisie=false; gConfig=false; gChange = true;
        }


Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1524
  • 100% Arduino et N
    • Voir le profil
Re: Projet Dominique
« Réponse #48 le: décembre 31, 2017, 05:24:57 pm »
Et maintenant le mesure de vitesse des trains !void mesureV1() {
  int v1 = digitalRead(capt1);
  if (v1 != gOldcapt1) {    // changement d'tat capt1
    gOldcapt1 = v1;
    if (v1 == 0) {          // zone occupe
      if (gModeMV1 == 0) {  // entree dans zone de mesure 1
        gModeMV1 = 1;
        gTempsMV1 = millis();
        lcd.setCursor(0,1);
        lcd.print("Vitesse 1          ");
      }
    } else {                // v1 = 1 : zone libre
      if (gModeMV1 == 1) {  // sortie et calcul vitesse
        gModeMV1 = 0;
        gTempsMV1 = millis() - gTempsMV1;
        gVitesse1 = calcul(gTempsMV1);
        lcd.setCursor(0,1);
        lcd.print("Vitesse 1 = ");
        lcd.print(gVitesse1);lcd.print(" km/h ");
        lcd.backlight();
        retrotime = millis();
      }
    }
  }
}
int calcul(unsigned long temps) {         // exemple 100 cm en 10 s => 57,6 km/h
  unsigned long VKM;
  if (temps>0) { //VKM=(gDistanceMV*5760)/temps; // 172*5760 / 10000 = 57,60 km/h
    VKM=990720/temps; // ici 172*5760 / 10000 = 57,60 km/h
    Serial.println(VKM);
  }
  return ((int)VKM);
}
« Modifié: décembre 31, 2017, 05:27:40 pm par Dominique »

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1524
  • 100% Arduino et N
    • Voir le profil
« Modifié: janvier 03, 2018, 04:07:41 pm par Dominique »

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1524
  • 100% Arduino et N
    • Voir le profil
Re: Projet Dominique
« Réponse #50 le: janvier 03, 2018, 04:50:57 pm »
Maintenant abordons oop()loop
//--- Detection d'appui sur SWenc :
  SWenc.update();
  if ( SWenc.fell() ) {     
    gSWState = !gSWState;
    gSW = true;     // appui effectif
    gConfig = true; // mode global configuration
  }
  // premier appui : mode choix parametre de configuration
  if (gSWState && gConfig ) { // passage en choix de mode
    if (gSW) {
      afficheTitre();
      gSW=false;
    }
    long newPosition = myEnc.read()/4;
    if (newPosition != oldPosition) { 
      if ( newPosition > oldPosition) {
        if (gMode < 9) gMode ++;
      } else {
        if (gMode > 0) gMode--;
      }
      oldPosition = newPosition;   
      afficheTitre();
      MajLeds();
    }
   }


La fonction afficheTitre est ici :
    // affichage titre
    void afficheTitre() {
      lcd.clear();
      lcd.print(gMode); 
      if (gMode < 10) lcd.print(' ');
      switch (gMode) {
      case 0:
        lcd.print("Inverser sens");
      break;
      case 1:
        lcd.print("Choix adresse");
      break;
      case 2:
        lcd.print("Mesure vitesse");
      break;
      case 3:
        lcd.print("Choix cran 30");
      break;
      case 4:
        lcd.print("Choix cran 60");
      break;
      case 5:
        lcd.print("Choix cran 90");
      break;
      case 6:
        lcd.print("Choix Vit Max");
      break;
      case 7:
        lcd.print("Choix Vit Min");
      break;
      case 8:
        lcd.print("Distance M/V cm");
      break;
      case 9:
        lcd.print("Erase EEProm ");
      break;
      default:
      break;   
      }
    }
  // Deuxieme appui : passage en modification de parametre
  if (!gSWState && gConfig && gSW) { // sortie du choix de mode
    gSW=false;
    switch (gMode) {
      case 0: // inverser sens
        lcd.setCursor(0,1);
        lcd.print("Normal  : taper 0 ");
        lcd.setCursor(0,2);
        lcd.print("Inverse : taper 1 ");
        gSaisie = true;
      break;
      case 1: // choix @ DCC
        lcd.setCursor(0,1);
        lcd.print("adresse DCC : ");
        gSaisie = true;
        gSaisieValeurIndex = 0;
      break;
      case 2:
        lcd.setCursor(0,1);
        lcd.print("Attente... ");
        gMesureVitesse = true;
        gSaisie = true;
        //gSaisieValeurIndex = 0;
      break;
      case 3:
        lcd.setCursor(0,1);
        lcd.print("Cran vit 30 : ");
        gSaisie = true;
        gSaisieValeurIndex = 0;
      break;
      case 4:
        lcd.setCursor(0,1);
        lcd.print("Cran vit 60 : ");
        gSaisie = true;
        gSaisieValeurIndex = 0;
      break;
      case 5:
        lcd.setCursor(0,1);
        lcd.print("Cran vit 90 : ");
        gSaisie = true;
        gSaisieValeurIndex = 0;
      break;
      case 6:
        lcd.setCursor(0,1);
        lcd.print("Cran vit max: ");
        gSaisie = true;
        gSaisieValeurIndex = 0;
      break;
      case 7:
        lcd.setCursor(0,1);
        lcd.print("Cran vit min: ");
        gSaisie = true;
        gSaisieValeurIndex = 0;
      break;
      case 8:
        lcd.setCursor(0,1);
        lcd.print("Distance M/V: ");
        gSaisie = true;
        gSaisieValeurIndex = 0;
      break;
      case 9:
        lcd.setCursor(0,2);
        lcd.print("Erase & Reset");
        EraseEEProm();
        reset();
      break;
      default:
        gConfig=false;
      break;   
    }
    gChange = true;
  }
   // gestion du clavier tactile
   if (digitalRead(PIN_TOUCH_IRQ) == LOW) {
    int Key = Read_Keypad();
    lcd.backlight();
    retrotime = millis();
    // choix registre/loco hors configuration et saisie
    if ((!gConfig)&&(!gSaisie)&&(Key < 12)) {
      gId = Key;
      gCurrentLoco = gConfigLocos[gId];
      gChange = true;
      MajLeds();
    }
    // mode saisie en configuration
    if ((gSaisie)&&(Key < 12)) {
      switch (gMode) {
       
        //--- INVERSION de SENS
        case 0:
        lcd.setCursor(0,1);
        gChange = false;
        if (gCurrentLoco.inverse) {
          lcd.print("Sens Inverse       ");
        } else {
          lcd.print("Sens Normal        ");
        }
        if (Key==0) {
          gCurrentLoco.inverse = 0; 
          gChange = true;       
        }
        if (Key==1) {
          gCurrentLoco.inverse = 1;
          gChange = true;         
          }
        // toute autre touche ne change pas le sens
        if (gChange) {
          lcd.setCursor(0,1);
          if (gCurrentLoco.inverse) {
            lcd.print("Sens Inverse       ");
          } else {
            lcd.print("Sens Normal        ");
          }
          gConfigLocos[gId] = gCurrentLoco;   // sauvegarde dans la table des locos
          EnregistreLocoEEProm(gId);          // enregistre gCurrentLoco dans l'EEPROM
        }
        gSaisie=false; gConfig=false; gChange = true;
        break;
        //--- saisie adresse DCC
        case 1:
        if ((Key >= 0)&&(Key <=9)) {
          gSaisieValeur[gSaisieValeurIndex] = Key;
          if (gSaisieValeurIndex < 3) {
            gSaisieValeurIndex++;
            lcd.setCursor(14,1);
            for (int c=0;c<gSaisieValeurIndex;c++) {
              lcd.print(gSaisieValeur[c]);
            }
            lcd.print("  ");
          }
        }
        if (Key == 10) { // back
          if (gSaisieValeurIndex > 0) {
            gSaisieValeurIndex--;
            lcd.setCursor(14,1);
            for (int c=0;c<gSaisieValeurIndex;c++) {
              lcd.print(gSaisieValeur[c]);
            }
            lcd.print("  ");
          }
        }
        if (Key == 11) { // enter
          gChange = true;
          switch (gSaisieValeurIndex) {
            case 0:
            gChange = false; // saisie vide
            break;
            case 1:
            gCurrentLoco.dccAddress = gSaisieValeur[0];
            break;
            case 2:
            gCurrentLoco.dccAddress = (gSaisieValeur[0] * 10) + gSaisieValeur[1];
            break;
            case 3:
            gCurrentLoco.dccAddress = (gSaisieValeur[0] * 100) + (gSaisieValeur[1] * 10) + gSaisieValeur[2];
            break;           
          }
          lcd.setCursor(14,1);lcd.print(gCurrentLoco.dccAddress);lcd.print("  ");
          if (gChange) {
            gConfigLocos[gId] = gCurrentLoco;   // sauvegarde dans la table des locos
            EnregistreLocoEEProm(gId);          // enregistre gCurrentLoco dans l'EEPROM
          }
          gSaisie=false; gConfig=false; gChange = true;
        }
        break;
millis()  //clignotements Led Rouge
  if (gblinkR) {
    if ((millis() - gClignoteR) > 250) {
      gClignoteR = millis();
      digitalWrite(LedModeR,!digitalRead(LedModeR));
    }
  }
  //clignotements Led Jaune
  if (gblinkJ) {
    if ((millis() - gClignoteJ) > 500) {
      gClignoteJ = millis();
      digitalWrite(LedModeJ,!digitalRead(LedModeJ));
    }
  }

  // retro-eclairage
  if ((millis() - retrotime) > eclairage) {
    lcd.noBacklight();     
  }

  // mise jour de la ligne d'etat en L3
  if ((gChange)&&(!gSaisie)) {
    StatutL3();
  }

  // surveillance courant MAXIMUM 2 A
  // affichage courant = la valeur maxi pendant 500 ms
  if ((millis() - gCurrentSampleTime) > 500) {
    gCurrentSampleTime = millis();
    lcd.setCursor(16,3);lcd.print(gCurrent*5);lcd.print(' ');
    gCurrent = 0;
  }
  int iCurrent = analogRead(A0);
  if (iCurrent > gCurrent) {
    gCurrent = iCurrent;
    if (gCurrent > CurrentMax) { // 400 * 5 = 2000 mA
    stop_DCC();
    }
  }
« Modifié: janvier 03, 2018, 05:04:53 pm par Dominique »

francisch

  • Newbie
  • *
  • Messages: 19
  • Bricoleur Linux, Arduino et N
    • Voir le profil
Re : Projet Dominique
« Réponse #51 le: janvier 06, 2019, 09:42:21 pm »
Tout d'abord je vous adresse tous mes meilleurs vœux de santé et de réussite dans vos projets.

Je lu et essayé de suivre le Projet de Dominique, mais ma culture de la programmation est trop légère beaucoup de choses m'ont échappé.

Etant sur un la réalisation d'une centrale pour 5 locos sans PC, je cherchais dans les programme de Dominique la commande pour l'arrêt d'urgence d'une seule loco (pour toutes pas de problème).
En TextCommand on envoi -1 pour la vitesse est ça marche, mais avec  DCCpp::setSpeedMain comme la vitesse est mappée dans DCCpp.cpp pas question de lui envoyé -1.
Je pensais utilisé TextCommand avec un message créé par le programme mais je ne vois pas comment faire sans PC.

Cordialement.
Francis

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1524
  • 100% Arduino et N
    • Voir le profil
Re: Projet Dominique
« Réponse #52 le: janvier 07, 2019, 09:11:11 am »
static bool DCCpp::setSpeedMain ( int nReg,
int inLocoId,
int inStepsNumber,
int inNewSpeed,
bool inForward
)
inlinestatic
For the given decoder id, set the speed and the direction on the main track.

Parameters
nReg Register number. Avoid register 0, used for one shot commands like accessories or CV programming.
inLocoId Decoder address in short or long format.
inStepsNumber According to the decoder configuration, set it to 14, 28 or 128 .
inNewSpeed Speed of the loco, between 2 and the steps number - 1 (13, 27 or 127). 0 means normal complete stop. 1 means emergency stop.
inForward True means forward move, false means backward.

francisch

  • Newbie
  • *
  • Messages: 19
  • Bricoleur Linux, Arduino et N
    • Voir le profil
Re: Projet Dominique
« Réponse #53 le: janvier 07, 2019, 01:51:50 pm »
Effectivement j'avais lu (trop vite) mais pas compris.
J'applique et cela va marcher.
Merci

francisch

  • Newbie
  • *
  • Messages: 19
  • Bricoleur Linux, Arduino et N
    • Voir le profil
Re: Projet Dominique
« Réponse #54 le: janvier 10, 2019, 02:23:23 pm »
/***************************** Driving functions */
 
 bool DCCpp::setThrottle(volatile RegisterList *inpRegs, int nReg,  int inLocoId, int inStepsNumber, int inNewSpeed, bool inForward)
 {
   int val = 0;
 
   if (panicStopped)
     val = 1;
   else
     if (inNewSpeed > 0)
       val = map(inNewSpeed, 0, inStepsNumber, 2, 127);
 
 #ifdef DCCPP_DEBUG_MODE
   Serial.print(F("DCCpp SetSpeed "));
   Serial.print(inForward?inNewSpeed:-inNewSpeed);
   Serial.print(F("/"));
   Serial.print(inStepsNumber);
   Serial.print(F(" (in Dcc "));
   Serial.print(val);
   Serial.println(F(" )"));
 #endif
« Modifié: janvier 11, 2019, 11:20:28 am par francisch »

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 465
    • Voir le profil
Re: Projet Dominique
« Réponse #55 le: janvier 11, 2019, 11:34:26 am »

francisch

  • Newbie
  • *
  • Messages: 19
  • Bricoleur Linux, Arduino et N
    • Voir le profil
Re: Projet Dominique
« Réponse #56 le: janvier 11, 2019, 01:18:01 pm »

Tony04

  • Full Member
  • ***
  • Messages: 194
    • Voir le profil
Re�: Projet Dominique
« Réponse #57 le: janvier 11, 2019, 01:41:04 pm »
Bonjour francish,

non, DCCpp gere tres bien aussi les 28 crans mais je n'ai trouve aucune doc la dessus alors que le 28 crans est tres utile pour certaines locos.

Voici comment je procede dans ma souris/centrale sans fil.

Pour le 128 crans registre=1 par defaut mais peut etre 1 chiffre defini pour chaque loco, adresse_loco=adresse DCC, vitesse 0 a 127, sens=0 ou 1  :
DCCpp::setSpeedMain(registre, adresse_loco, 128, vitesse, sens); 
Pour le 28 crans idem sauf le 28 et vitesse de 0 a 27 :
DCCpp::setSpeedMain(registre, adresse_loco, 28, vitesse, sens); 

Cordialement
Antoine

PS: J'ai enleve les accents
« Modifié: janvier 11, 2019, 03:41:23 pm par Tony04 »

Thierry

  • Global Moderator
  • Sr. Member
  • *****
  • Messages: 465
    • Voir le profil
Re: Projet Dominique
« Réponse #58 le: janvier 11, 2019, 04:10:02 pm »

Tony04

  • Full Member
  • ***
  • Messages: 194
    • Voir le profil
Re: Projet Dominique
« Réponse #59 le: janvier 11, 2019, 05:20:28 pm »
Bonsoir Thierry,

de toute facon sur les decodeurs tu ne peux pas choisir entre 28 et 128 (a ma connaissance), c'est toujours 28/128 ou autre chose, donc l'ordre de DCCpp doit effectivement etre en 128 crans mais c'est transparent pour l'utilisateur qui peux lui utiliser une plage de 28 crans.