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 ... 166 167 [168] 169 170
2506
Bus CAN / Re : BreakoutBoard CAN
« le: août 29, 2015, 08:33:26 pm »
Bizarrement j'ai vu que Marklin utilise aussi des Id de 29 bits.

Franchement je n'en vois pas la justification. Mais, bon, ils font ce qu'ils veulent.

Méfies toi tout de même de la façon de faire le filtrage. Avec 2 masques et 6 filtres seulement, sur des Id de 29 bits, tu vas souffrir ! Tu as vu les questions sur le forum Arduino !

Attendons l'avis de l'expert : Jean-Luc

2507
Shields et Modules / Re : Carte « Cerveau du réseau »
« le: août 25, 2015, 01:13:47 pm »
Finalement j'étais loin du compte :

Dans ce fil sur le forum Arduino,
http://forum.arduino.cc/index.php?topic=131096.495

Un Due est capable de lire 1600 messages par seconde, connecté à une Zoé !

The Due proved a really good choice as this car is producing chatter in excess of 1600 frames per second on the main CANbus only and there is no way a smaller micro-controller can handle that, let alone push it out over real UART serial 115200.

2508
Bus CAN / Re : BreakoutBoard CAN
« le: août 23, 2015, 10:50:54 pm »
La bibliothèque est là

https://github.com/collin80/due_can

1600 messages CAN par seconde sur une Zoe de Renault parfaitement reçus par un Due : pas de souci à se faire pour nos trains  8)


2509
Bus CAN / Re : BreakoutBoard CAN
« le: août 23, 2015, 10:38:43 pm »
Bonjour,

Concernant le DUE, il y a un fil très développé sur le forum Arduino qui est consacré à la réalisation d'une carte d'extension et d'une bibliothèque.

http://forum.arduino.cc/index.php?topic=131096.480

La bibliothèque existe (Due-CAN), mais pas l'extension apparemment constituée d'un seul chip.

On y voit aussi comment utiliser les 2 bus CAN disponibles sur le Due (la doc n'en présente qu'un seul).

Qu'en pensez-vous ?

2510
Bus CAN / Re : Le bus CAN
« le: août 23, 2015, 09:52:39 pm »
Sur le fil d'à coté (BoB CAN), le cas du DUE est abordé. Il ne faut y ajouter que le 2551 car un contrôleur est déjà intégré. La carte CAN Locoduino peut se connecter à un DUE via les connecteurs ad'hoc. Mais je n'ai pas encore essayé.

Ça m'intéresse et j'ai déjà 2 DUE qui attendent.

On peut, bien-entendu, envisager une petite production de cartes en accord avec Jean-Luc, et en le déchargeant des tâches ingrates, notamment l'appro des composants. Il faudra de toute façon en faire un minimum.

2511
Bus CAN / Re : Le bus CAN
« le: août 23, 2015, 04:06:15 pm »
J'ai démarré la rédaction de l'article 130.

2512
Bus CAN / Re : Le bus CAN
« le: août 22, 2015, 06:20:06 pm »
Voici une "recette de cuisine" pour la mise en oeuvre rapide du bus CAN.

Au dela de l'installation et de la mise en oeuvre de la carte CAN Locoduino, j'ai mis au point une gestion de mémoire tampon circulaire dans laquelle les messages sont enregistrés aussitôt que possible, et exploités ensuite tranquillement par la fonction LOOP.
Comme cela, on est certain de ne rien perdre !

Le matériel se compose d'une carte Arduino (par exemple ici un Mega2560) et d'une carte CAN Locoduino.
On commence par relier à la carte CAN les broches du bus SPI du Mega : 50 (MISO), 51 (MOSI), 52 (SCK), 53 (SS : chip select CAN), ainsi que le +5V et le 0V (Gnd).
Ajoutons une liaison entre la broche INT (interruption) de la carte CAN et la broche 2 (Interruption 0) de l'Arduino.

Il faut aussi télécharger une bibliothèque qui se trouve ici : https://github.com/Seeed-Studio/CAN_BUS_Shield
Puis il faut placer le dossier téléchargé dans le dossier des autres bibliothèques (voir l'article "Installer un bibliothèque").

Ensuite on peut placer ces 2 lignes en tête de programme :

#include <SPI.h>                 // pour la bibliotheque CAN
#include "mcp_can.h"             // bibliotheque CAN

Puis il faut créer l'objet CAN comme le permet la bibliothèque :

// variables globales pour l'interface CAN
MCP_CAN CAN(53);                // Definition du CS (chip select) pin 53 (SS du bus SPI)
unsigned char Flag_Recv = 0;    // variable d'échange avec l'interruption IRQ

Ainsi, on le voit, qu'une variable "Flag_Recv" qui servira à faire savoir à la LOOP qu'un ou plusieurs messages sont arrivés "sous interruption".

Cette variable est positionnée par la routine d'interruption suivante :

/*
 *  ISR CAN (Routine de Service d'Interruption)
 *  le flag IRQ monte quand au moins un message est reçu
 *  le flag IRQ ne retombe QUE si tous les messages sont lus
 */

void MCP2515_ISR()
{
     Flag_Recv = 1;
}

Après avoir placé ces lignes de code en tête de programme, abordons le SETUP dans lquel on insère les lignes suivantes :

  /* -----------------------------------------------------
  *                       SETUP
  * -----------------------------------------------------
  */

  /////////////// INIT CAN /////////////////
 
START_INIT:

  if(CAN_OK == CAN.begin(CAN_500KBPS))       // initialisation du can bus : baudrate = 500k
  {
    Serial.println(F("CAN BUS init ok!"));
  }
  else
  {
    Serial.println(F("CAN BUS init echec !"));
    Serial.println(F("Init CAN BUS a nouveau"));
    delay(200);
    goto START_INIT;
  }


On comprend bien ici que l'instruction CAN.begin(baudrate) démarre l'interface, avec un compte-rendu "CAN_OK", sinon cela se répète car, à ce stade de l'initialisation (SETUP), si le bus CAN ne démarre pas, il est inutile d'aller plus loin.

Personnellement je n'ai jamais vu d'échec sauf si la carte CAN n'est pas (ou est mal) branchée .

Puis il faut "attacher" l'interruption 0 à la routine MCP2515_ISR() précédente :

  attachInterrupt(0, MCP2515_ISR, FALLING); // interrupt 0 (pin 2)

Enfin on définit les filtres CAN qui limiteront les messages reçus à seulement ceux qui intéressent cette réalisation :

  /*
   * set mask & filter
   */
   
  CAN.init_Mask(0, 0, 0x3ff);               // there are 2 mask in mcp2515, you need to set both of them
  CAN.init_Mask(1, 0, 0x3ff);               // a preciser
   
  CAN.init_Filt(0, 0, 0x03);                // Reception possible : Id 03 (hex)
  CAN.init_Filt(1, 0, 0x04);                // Reception possible : Id 04 (hex)
  CAN.init_Filt(2, 0, 0x30);                // Reception possible : Id 30 (hex)
  CAN.init_Filt(3, 0, 0x40);                // Reception possible : Id 40 (hex)
  CAN.init_Filt(4, 0, 0x31);                // Reception possible : Id 31 (hex)
  CAN.init_Filt(5, 0, 0x41);                // Reception possible : Id 41 (hex)

Le SETUP ayant mis en place tous les acteurs, la LOOP peut commencer son travail répétitif !

/*-----------------------------------------------------
 *                        LOOP
 *-----------------------------------------------------                       
 */

void loop()
{

  if (Flag_Recv)  {
    Flag_Recv = 0;  // Flag MCP2515 pret pour un nouvel IRQ
    CAN_recup();    // récupération  et traitement du ou des messages CAN reçus
  }


et la fonction CAN_recup() est là :

// Message recu
byte IdR;                       // Id pour la routine CAN_recup()
unsigned char lenR = 0;         // Longueur "    "       "
unsigned char bufR[8];          // buffer reception      "
// Message emis
unsigned char bufS[4];          // buffer emission

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

/*
 * Routine de récuperation des messages CAN dans la memoire circulaire _Circule
 * appelee par LOOP lorsque Flag_Recv = 1;
 */
 
void CAN_recup()
{
  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
    }
  }
}


Dans Loop, récupérer un message, en parfaite indépendance de leur réception se fait ainsi :

  // traitement d'un seul message par loop dans la memoire circulaire _Circule
   
  if (_Ncan > 2)  {                 // messages dans _Circule : au moins 3 bytes
    _Ncan--;
    RId = _Circule[_indexR];        // recup Id
    _indexR++;
    if (_indexR == sizeof(_Circule))  {_indexR = 0;}
    _Ncan--;
    Rlen = _Circule[_indexR];       // recup longueur
    _indexR++;
    if (_indexR == sizeof(_Circule))  {_indexR = 0;}
    if (_dumpCan)  {               // _dumpCan est un flag qui permet de "sortir" les messages ou non
      Serial.print("CAN id ");
      Serial.print(RId);
      Serial.print(", data ");
    }
    for (int k = 0; k < Rlen; k++)  {
      _Ncan--;
      Rbuf[k] = _Circule[_indexR];  // recup octets message
      _indexR++;
      if (_indexR == sizeof(_Circule))  {_indexR = 0;}
      if (_dumpCan)  { 
      Serial.print("0x");
      Serial.print(Rbuf[k], HEX);
      }
    } // le message est dans les globales RId, Rlen et Rbuf[..]
    Serial.println();
 

Voilà que ce je dois expliquer…


2513
Bus CAN / Re : Le bus CAN
« le: août 22, 2015, 04:11:03 pm »
Bonjour Denis,

Effectivement un TGV à 300 km/h ça fait pas loin d'1 mètre par seconde au 1/87eme.
Comme ton TGV mesure pas loin d'1m de longueur en HO, la longueur de tes cantons (supérieure au train le plus long) fait donc au moins 1 m.
Donc tu auras au maximum une détection de passage par seconde pour ce TGV. Et vu que c'est un TGV a pleine vitesse, tu lui donneras la priorité la plus haute pour les traitements.

Si ton traitement total dure 6 ms, il reste 94 ms pour piloter les trains, les aiguilles, les signaux, le décor et même le café du chef de gare.

Bon, blague à part, un seul Arduino pourrait faire le job s'il n'y a pas trop de trains en mouvement.

Maintenant, avec le CAN a 500 kb/s , les temps de transmission seront largement inférieurs au temps de détection et au temps de traitement (tes 6 ms).

De toute façon le problème ne peut pas se poser de façon aussi simple : Il y a des tas de temps de latence à compter comme, par exemple, le temps d'exécution d'un changement d'aiguille qui nécessite d'attendre l'accusé d'exécution (la fin de l'impulsion de commande du moteur dans mon cas). Imagines des enclenchements multi-aiguilles !.

Cela veut dire que chaque cycle de détection/action devra prendre plusieurs tours de LOOP dans le Central, et que l'organisation du logiciel multiprocesseur deviendra une affaire sérieuse ;)

Je reviendrai sur cette question intéressante un peu plus tard car ça concerne aussi l'architecture logicielle.


2514
Bus CAN / Re : Le bus CAN
« le: août 19, 2015, 07:36:04 pm »
J'irai même jusqu'à dire que je prépare un article pour la mise en oeuvre "à coup sûr" du bus CAN, avec la carte Locoduino qui fonctionne à merveille !

J'ai réalisé ma carte de commande des aiguilles et des dételeurs, + quelques capteurs (RFID, infrarouge et Hall notamment), ainsi qu'une carte de test pour valider tous les scenarii de communication.

A bientôt pour lire le résultat ...

2515
Vos projets / Re : Nouveau projet : un petit locodrome
« le: juillet 30, 2015, 07:02:17 am »
Je pense que ce petit réseau à automatiser ferait bien l'objet d'un exemple de modélisation en suivant les contributions de Pierre (fil "modélisation logicielle" du forum) et de Denis.

Si on considère le découpage proposé par Denis, sur la base de mon dernier plan, on a une zone à gauche incluant l'aiguille gauche, une zone à droite incluant l'aiguille droite, ces 2 zones se rejoignant à la coupure à l'arrière au milieu, et 2 zones devant entre les aiguilles, l'une entre les talons directs, l'autre entre les talons déviés des aiguilles.

Sur cette hypothèse, on pourrait définir des objets zone, aiguille, train, signal,.. qui permettraient de définir la topographie du réseau, les actions aux passage des détecteurs (mises à jour des variables d'état) et le pilotage des trains en fonction de ces variables (démarrer, accélérer, ralentir, s'arrêter).

Il faudrait alors faire le rapprochement entre la modélisation en programmation objet et le matériel (détecteurs et commande des trains, les signaux n'étant pas obligatoires d'après Guillaume).

Je tend donc la perche pour cela à Denis et à Pierre, s'ils veulent bien, qui sont bien plus en avance que moi sur ce sujet que je suis tout juste en train d'intégrer.

2516
Bus CAN / Re : Le bus CAN
« le: juillet 29, 2015, 05:42:10 pm »
Mise à jour :

La cause des pertes de message résidait dans le test de non réception (plus d'IRQ pendant 1seconde) dont le traitement consistait à vider le tampon du 2515 pour lui permettre de générer à nouveau un IRQ.
En supprimant ce vidage forcé, les pertes de messages ont disparu !

Néanmoins, avec toutes les tortures qui je lui fais subir, il reste une perte de 1 message sur 10.000 environ.

2517
Bus CAN / Re : Le bus CAN
« le: juillet 29, 2015, 08:55:22 am »
J'ai fait quelques tests entre un UNO et un MEGA:

J'ai réalisé un banc de test avec un Mega qui émet des messages CAN sur 4 IDs et 4 tailles différents toutes les 25ms ( variable en fait, avec une limite basse à 10ms) et un Uno qui les reçoit sous IT, les compte et renvoie les compteurs (message de 4 octets) au Mega.
Pour garantir la réception, les messages sont récupères dans l'IRQ du CAN dans un buffer circulaire de 256 octets et traites 1 par 1 dans la LOOP qui est assez rapide pour suivre sans problème. Le buffer ne se sature jamais.

Apparemment il faut respecter 2 règles:
- mettre le moins de traitement possible dans l'ISR, juste un flag à monter,
- vider complètement le buffer du MCP2515 à chaque LOOP si le flag est monté.

Le UNO qui teste combine le CAN, l'I2C et un timer1 pour un Watchdog. Il compte les messages reçus, les affiche et renvoie un message avec ses compteurs toutes les secondes.

J'ai mis en place le maximum de précautions:
- la surveillance de l'IRQ du 2515, avec vidage forcé si plus d'IRQ depuis 1 seconde (ça peut servir à surveiller la vie des autres modules)
- la surveillance des overflows
- un Watchdog sur la LOOP avec réinit du CAN si la librairie se bloque.

Pour le moment ça tient à l'aise les 40 messages par seconde (4 messages de taille différents repères toutes les 25 ms.)

En augmentant la cadence, je vois que ça tient encore à 100 messages par seconde.

Mais il y a quelques pertes tout de même : 6/1000 à 40 messages/sec, 17/1000 à 100 messages/sec, 1/1000 à 20 messages/sec.

Il faut donc utiliser des messages Accusés de Réception au niveau application, notamment pour confirmer l'exécution d'une commande

2518
Bibliothèques / Re : Bibliothèque LcdUI
« le: juillet 25, 2015, 07:29:29 pm »
Merci !

Et je m'aperçois que j'aurais du le savoir  :-[

2519
Bibliothèques / Re : Bibliothèque LcdUI
« le: juillet 25, 2015, 12:10:27 pm »
STP, peux-tu mettre un lien vers la bibliothèque ?

Merci d'avance

2520
Bibliothèques / Re : Bibliothèque CommandInterpreter
« le: juillet 25, 2015, 12:05:06 pm »
Je viens de tester cette bibliothèque dans mon programme de tests de performances du CAN pour réaliser diverses fonctions comme un affichage complet ou non des messages échangés, l'affichage des compteurs émis/reçus/perdus ou la variation du delay entre émissions (donc la fréquence des envois de messages)

J'atteste que ça marche nickel !!!
Bravo Jean-Luc  ;D

Pages: 1 ... 166 167 [168] 169 170