Voir les contributions

Cette section vous permet de consulter les contributions (messages, sujets et fichiers joints) d'un utilisateur. Vous ne pourrez voir que les contributions des zones auxquelles vous avez accès.


Messages - Dominique

Pages: 1 ... 138 139 [140] 141 142 ... 187
2086
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: décembre 30, 2017, 12:42:07 pm »
J’imagine que, même sous windoze, on peut ouvrir un exemple avec l’IDE, puis faire « enregistrer sous.. » en changeant le nom et l’emplacement.
Comme cela on garde bien tous les fichiers à l’intérieur du dossier du sketch.

Mais on s’eloigne...

2087
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: décembre 29, 2017, 11:00:36 am »
Et bien j’ai encore appris quelque chose ! Merci Jean-Luc !
Comme dirai ... c’est l’altitude ;)
Je vais regarder ce qu’il y a dedans.

J’ai le temps : 3 semaines à la montagne ;)

2088
Composants / Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: décembre 29, 2017, 09:59:55 am »
Dans ce cas là, rajoutez l’include suivant au début de votre .h ou .cpp : #include "Arduino.h".

Pour programmer un Teensy, c’est sûrement pas très efficace  ;D :o 8)

2089
Bus CAN / Re : Réception CAN optimale
« le: décembre 29, 2017, 12:46:56 am »
Oui c’est bien ça pour mon projet : je n’ai pas besoin de beaucoup d’identifiants pour définir tous les messages possibles du système.

J’étais sur la route toute la journée et je reviendrai sur ce sujet après une bonne nuit de repos !

2090
Vos projets / Re : TCO avec Processing
« le: décembre 27, 2017, 12:35:35 pm »
Bonjour Plume,

C'est un beau projet, fait en club ! Bravo.
Et merci de partager cette réalisation et plein d'autres.

Bonne fêtes
Dominique

2091
Bus CAN / Re : Re : Réception CAN optimale
« le: décembre 26, 2017, 07:45:44 pm »
Donc je pense que si on procède correctement on ne perd pas de message à ce niveau à condition de vider les message buffers dans l'ISR.

Merci Jean-Luc,

Dans mes versions AVR en effet, j'utilise l'ISR uniquement pour faire monter un flag et je vide les buffers de message du 2515 juste après dans la loop. L'ISR arrivant n'importe quand par rapport à la loop, il peut s'être écoulé pas mal de µs avant de vider les buffers.

Je vais donc intégrer ma routine CAN_recup() dans l'ISR à partir de maintenant. Le flag Flag_Recv n'est même plus nécessaire.

//--- Globales : Memoire circulaire pour le stockage rapide des messages recus
unsigned char _Circule[512];          // recepteur circulaire des messages CAN sous IT
unsigned int _indexW, _indexR, _Ncan; // index d'ecriture et lecture, nb d'octets a lire
byte _CANoverflow = 0;                // flag overflow (buffer _Circule plein)


//--- Interruption (ISR) CAN
void MCP2515_ISR()
{
  unsigned char len = 0;                // nombre d'octets du message
  unsigned char buf[8];                 // message
  unsigned char Id;                     // Id

  while (CAN_MSGAVAIL == CAN.checkReceive())  {
    CAN.readMsgBuf(&len, buf);          // read data, len: data length, buf: data buf
    Id = CAN.getCanId();
    if ((_Ncan+len+2) < sizeof(_Circule))  { // il reste de la place dans _Circule
      _Circule[_indexW] = Id;           // enregistrement de Id
      _indexW++;
      _Ncan++;
      if (_indexW == sizeof(_Circule))  {_indexW = 0;}
      _Circule[_indexW] = len;          // enregistrement de len
      _indexW++;
      _Ncan++;
      if (_indexW == sizeof(_Circule))  {_indexW = 0;}
      for (byte z = 0; z<len; z++)  {
        _Circule[_indexW] = buf[z];      // enregistrement du message
        _indexW++;
        _Ncan++;
        if (_indexW == sizeof(_Circule))  {_indexW = 0;}
      }
    } else {
      _CANoverflow = 1;  // depassement de la capacite de Circule
    }
  }
}

Je vais donc tester et corriger ce que j'ai écrit là http://forum.locoduino.org/index.php?topic=290.msg4254#msg4254

Amicalement

Dominique

2092
Bus CAN / Re : Réception CAN optimale
« le: décembre 26, 2017, 07:30:15 pm »
Rassures-toi Marcel, ça va venir.
Bonne fêtes.
Dominique

2093
Bus CAN / Re : Réception CAN optimale
« le: décembre 24, 2017, 12:56:37 pm »
Grandiose  ;D

A déguster sans modération !

Joyeux Noël à tous

2094
Bus CAN / Re : Re : Réception CAN optimale
« le: décembre 23, 2017, 05:04:14 pm »
Mais bon si tu trouves que c'est sans valeur ajoutée pour le forum, ok je m'adapte sans une once de contrition. Cela me va aussi.

C'est maladif chez moi, il faut que je modère  8) ??? ::)

Mais pas du tout, c'est très utile pour tout le monde car le CAN doit faire peur à beaucoup de modélistes et on est malheureusement trop peu à s'en servir. De plus tes tests confirme ceux que j'avais fait il y a 2 ans.
Il se trouve qu'au bout de quelques semaines, j'en ai eu marre des tests et je suis parti dans l'utilisation du Can dans mon projet et j'avoue que ça se passe plutôt bien.

En passant j'ai regardé tes autres contributions, toujours très interessantes et précises, et j'ai pensé ajouter un peu de mon cru à celle consacrée aux boutons poussoirs.
http://forum.locoduino.org/index.php?topic=122.msg4268#msg4268

Bonne fêtes
Dominique

2095
Bibliothèques / Re : Bouton poussoir
« le: décembre 23, 2017, 03:51:15 pm »
Bonjour,

A toutes fins utiles, je propose ici un système qui permet d'associer une Led et un Bouton, sur la même pin.

J'utilise ce système dans le module de traction de mon projet : http://forum.locoduino.org/index.php?topic=290.msg3999#msg3999

Le schéma est le suivant :



Pour chaque loco, j'ai un potentiomètre pour régler la vitesse, un bouton pour changer de direction (conditionné par la vitesse = 0) et 2 leds une verte pour indiquer la marche avant et une rouge pour indiquer la marche arrière.

De plus, chaque bouton doit être "débouncé" c'est à dire qu'il faut lire son état 2 fois avec un intervalle de quelques millisecondes (25 dans mon cas). Le principe est simple pour gérer le bouton et la led : alternativement la pin est en INPUT et en OUTPUT.

Le code est le suivant :

bool CmdMaj( bool d) {
    bool dir = d;
    bool change = false;
    bool buttonValue;
    if (millis()-previousTime >= intervalTime) {   
      previousTime = millis();   
      pinMode(pinLedVerte, INPUT);
      buttonValue = digitalRead(pinLedVerte);
      if (buttonValue != buttonVState) {    // changement d'etat de la pin
        switch (this->etat) {
          case 0:
          if (!buttonValue) {               // 1er appui
          this->etat = 1;                   // attente confirmation
          }
          break;
          case 1:
          if (!buttonValue) {               // confirmation d'appui
            buttonVState = buttonValue;     // nouvel ancien etat de la pin
            dir = !dir;                     // inversion sens de marche
            this->etat = 2;                 // appui en cours, do nothing
            change = true;                  // job done !
          }
          break;
          case 2:
          if (buttonValue) {                // relaché
            this->etat = 3;                 // attente confirmation
          }
          break;
          case 3:
          if (buttonValue) {                // relaché
            buttonVState = buttonValue;     // nouvel etat
            this->etat = 0;                 // fin process
          }
        }
      }
      pinMode(pinLedVerte, OUTPUT);
      digitalWrite(pinLedRouge, dir);
      digitalWrite(pinLedVerte, !dir);      // allume si false
    }
    return (change);
  }

Enfin, pour commander une loco avec le potentiomètre, le bouton et les leds, j'ai fait une classe :

class CmdLoco {
private :
  int pinLedVerte; // et bouton
  int pinLedRouge;
  int pinPotar;
  unsigned long previousTime ;
  unsigned int intervalTime;
  int etat; // 0 : attente, 1 : 1er changement, 2 : confirmation
  bool buttonVState;
  bool marcheAvant;
  int potValue;
 
public :
  CmdLoco(int pLV, int pLR, int pPot, int pIt) {           // constructeur
    pinLedVerte = pLV;
    pinLedRouge = pLR;
    pinPotar = pPot;
    intervalTime = pIt;
  }

  void CmdInit() {
    marcheAvant=true;
    pinMode(pinLedVerte, OUTPUT);
    pinMode(pinLedRouge, OUTPUT);
    digitalWrite(pinLedVerte, !marcheAvant);        // allume si false
    digitalWrite(pinLedRouge, marcheAvant);         // eteinte
    previousTime = millis();
    this->etat = 0;
    buttonVState = true;   
  }

  void MajLed(bool d) {
    digitalWrite(pinLedRouge, d);
    digitalWrite(pinLedVerte, !d);      // allume si false
  }

  bool CmdMaj( bool d) {
    bool dir = d;
    bool change = false;
    bool buttonValue;
    if (millis()-previousTime >= intervalTime) {   
      previousTime = millis();   
      pinMode(pinLedVerte, INPUT);
      buttonValue = digitalRead(pinLedVerte);
      if (buttonValue != buttonVState) {    // changement d'etat de la pin
        switch (this->etat) {
          case 0:
          if (!buttonValue) {               // 1er appui
          this->etat = 1;                   // attente confirmation
          }
          break;
          case 1:
          if (!buttonValue) {               // confirmation d'appui
            buttonVState = buttonValue;     // nouvel ancien etat de la pin
            dir = !dir;                     // inversion sens de marche
            this->etat = 2;                 // appui en cours, do nothing
            change = true;                  // job done !
          }
          break;
          case 2:
          if (buttonValue) {                // relaché
            this->etat = 3;                 // attente confirmation
          }
          break;
          case 3:
          if (buttonValue) {                // relaché
            buttonVState = buttonValue;     // nouvel etat
            this->etat = 0;                 // fin process
          }
        }
      }
      pinMode(pinLedVerte, OUTPUT);
      digitalWrite(pinLedRouge, dir);
      digitalWrite(pinLedVerte, !dir);      // allume si false
    }
    return (change);
  }
 
}; // fin classe CmdLoco

L'utilisation de cette classe est simple :

1) déclarer mes 12 locos dans un table :
//--- TABLE DES LOCOS
CmdLoco * gTableCloco[MaxLocos];          // Table des locos

2) Créer les objets et les initialiser :
  //--- creation des objets Cloco et de la table
  for (int L=0; L<MaxLocos; L++) {
    gTableCloco[L] = new CmdLoco(ledVerte[L],ledRouge[L],gPotPin[L], 25); // ledVerte, ledRouge, pot, intervalTime)
  }
  //--- initialisation des objets Cloco
  for (int L=0;L<MaxLocos;L++) {
    gTableCloco[L]->CmdInit();   
  }

Pour terminer, voici le bout de code qui est dans loop() pour utiliser cette classe :


// potentiometres

  for (int i = 0; i < 12; i++) {
    gSensorValue = analogRead(gPotPin[i]);
    gOutputValue = map(gSensorValue, 0, 1023, 0, 127);
    if (gOutputValue != gPot[i]) {
      gPot[i] = gOutputValue;
      gLocoSpeed[i] = gPot[i];
      gPotChange = true;
      DccDirection = gLocoDirection[i];
      if (gCurrentLoco.inverse) {DccDirection = !DccDirection;}
      DCCpp::setSpeedMain(gConfigLocos[i].registre, gConfigLocos[i].dccAddress, gLocoStepsNumber, gLocoSpeed[i], DccDirection);     
    }
  }
 
  // boutons et leds de direction

  for (int u=0;u<MaxLocos;u++) {
    if (gLocoSpeed[u] == 0) {
      if (gTableCloco[u]->CmdMaj(gLocoDirection[u])) {     
        gLocoDirection[u] = !gLocoDirection[u];
      }       
    }
  }


Chacun en déduira quelles sont les variables globales utilisées.

Bon Noël à tous

2096
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: décembre 23, 2017, 03:14:28 pm »
Normalement il n’y a pas de différence : le compilateur mettra les données du .h dans le programme.

Le découpage du source en plusieurs fichiers placés dans le même dossier que .ino n’est rien d’autre qu’une organisation plus pratique des codes sources. C’est équivalent à tout mettre dans le même fichier.

2097
Bus CAN / Re : Réception CAN optimale
« le: décembre 23, 2017, 03:09:37 pm »
Bon d’accord c’est un benchmark du bus CAN et des fonctions d’emission et réception des Arduino qui sont de bons exemples.

Plusieurs questions :
- sur quels Arduino ?
- avec quelle interface CAN (le petit chinois bleu à 8 MHz ?)?

Donc les tests sont OK et on peut passer à autre chose, par exemple les applications au modelisme qui nous intéressent ici.

Quel est ton projet personnel ?
Bien entendu le sujet du train du futur avec des modules communicant via CAN est très intéressant, mais surtout la définition des messages à échanger, qui va déterminer les risques de pertes et leurs solutions.

Je suis ravi que tu nous rejoignes sur ce terrain.

Mais Noël approche et je ne vais pas avoir beaucoup de temps.

Bon Noel en tout cas  ;D
Amicalement
Dominique

2098
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: décembre 23, 2017, 01:13:01 pm »
Bonjour,
Ca ne traite pas spécifiquement du Teensy, mais plutôt d’un projet.

On pourra le déplacer plus tard.

Bon Noël
Dominique

2099
Bus CAN / Re : Réception CAN optimale
« le: décembre 22, 2017, 10:07:07 pm »
Très belle démonstration avec un programme de test qui peut servir à plein de choses  :D

Si le but est de réduire le temps de traitement hors message CAN (c’est à dire quand il n’y a aucune chance d’en perdre), quand un message arrive, il faut ajouter le traitement qui peut être plus ou moins long.

Sur MEGA j’utilise le buffer circulaire, mais pas sur le DUE qui est infiniment plus rapide.

Lors de mes tests il y a maintenant 2 ans, j’avais développé un générateur de messages avec des données qui étaient incrémentées à l’emission pour détecter les pertes de messages à la réception.

Mais je pense que le plus utile est de définir tous les types de messages nécessaires et les circonstances de transmission. En DCC, il n’y a pas de contraintes de temps donc on peut toujours s’arranger pour ne pas en perdre.

2100
Les réseaux / Re : Projet Dominique
« le: décembre 21, 2017, 11:32:17 pm »
Je n’ai pas fait ce calcul du temps de blocage du cpu pendant un lcd.print, mais je m’en doutais.

Il y a normalement tout ce qu’il faut dans le MCP2515 pour ne pas perdre de message : le protocole contient un accusé de réception qui force l’emetteur à répéter une transmission quand il reçoit un  «acknowledge error». Le MCP2515 contient 3 buffers de réception, un avant les filtres et 2 après les filtres. Un message est d’abord reçu dans le 1er buffer et sera transmis dans l’un des 2 autres si le filtre l'autorise et si l’un des buffers est disponible. Sinon il y aura une «acknowledge error» et la transmission sera répétée.

Pour qu’un message soit répété il faut qu’il ne soit pas reçu, ni par le récepteur prévu pour cela, ni par un espion placé sur le bus Can. J’ai réalisé un tel outil pour voir le trafic sur mon bus et là j’ai commencé à perdre des messages parce qu’ils étaient réputés reçus.

C’est pour ça aussi que le choix des identifiants et des filtres est si important !

Donc, pour revenir à notre problème d’ecran LCD/i2c, je ne m’inquiète pas trop car le bus CAN peut attendre. Mais ce serait mieux d’améliorer l’afficheur, théoriquement.

Pratiquement, comme j’ai choisi le DCC, le bus CAN a relativement peu de messages à transmettre et il est toujours possible d’ajouter un peu de contrôle de flux applicatif, et encore ce n’est pas certain.

Personnellement je suis confiant pour avoir un réseau qui tourne depuis un bon moment.

En cas de problème il y a des solutions ,
- doubler le bus CAN pour alléger le trafic (mais ça fait 2 fils de plus a brancher)
- remplacer l’interface I2C du LCD par un Arduino mini qui servira de buffet d’affichage. C’est pas plus cher !
- remplacer l’i2c par du SPI.

Jean-Luc a plus d’expérience que moi sur le CAN et un bus CAN plus chargé. Il pourra éventuellement compléter ces explications.



Pages: 1 ... 138 139 [140] 141 142 ... 187