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 - Pierre59

Pages: 1 ... 15 16 [17] 18 19
241
Vos projets / Re : PWM - Faire varier la fréquence
« le: février 03, 2017, 11:43:05 am »
Bonjour

Très bonne idée, mais la fréquence de L'Arduino Uno est de 16MHz et je pense que le nombre de "ticks" est de 256. Ce qui donne une fréquence de PWM, si je me trompe pas, de 16 000 000/1/256=62500Hz.

Pierre

242
Vos projets / Re : PWM - Faire varier la fréquence
« le: février 02, 2017, 11:12:58 am »
Bonjour

Le code ressemble bien à cela, mais il est différent pour chaque Timer utilisé (ici c'est le Timer1 sur 16 bits), il y a deux Timers 8 bits et un Timer double sur 16 bits sur ATmega328. Le mieux serait de trouver une bibliothèque qui fait ce qu'il faut.

Ma question est simple, si je veux telle ou telle fréquence, je dois mettre quoi dans quoi.
Autre question, si je modifie la fréquence, Est-ce que c'est fait définitivement dans mon MEGA?
Merci d'avance pour le partage d'expérience
Cordialement
Philippe

On n'est pas trop maitre de la fréquence PWM précise, mais on peut choisir parmi quelques fréquences de basse à haute. La fréquence et déterminée par la fréquence du processeur (quartz) 16 MHz pour l'Arduino Uno, puis par des "prescalers" qui permettent de diviser la fréquence du processeur par quelques valeurs prédéfinies (différentes pour chaque Timer), puis par le nombre de pas PWM désirés (256 valeurs possibles de rapport cyclique par exemple)

J'ai, il y a un certain temps, utilisé un ATmega8 cadencé à 8mHz pour produire 4 PWM (chacune étant réglable de 0 à 255 indépendamment) en utilisant les deux Timers 8 bit et le Timer double sur 16 bits. Les fréquences des PWM étant toutes à 31250 Hz, soit 8MHz/1/256=31250 Hz, tous les prescalers étant réglés pour diviser par 1.

Pierre

PS Toutes ces manipulations pour la PWM ne modifient en rien la fréquence de l'horloge du processeur.


243
Vos projets / Re : Re : loco LGB sans fil
« le: février 01, 2017, 06:44:36 pm »
Bonjour

On peut aussi changer la fréquence du PWM mais, ça, je ne l'ai jamais fait.

Je l'ai fait, avec une fréquence de PWM au dessus de 20kHz plus de bruit (c'est inaudible), mais il faut que le moteur de la loco supporte et que le L298n supporte aussi (sa fréquence de commutation est limitée typiquement à 25kHz (voir datasheet), personnellement j'ai utilisé un pont en H plus rapide.

Pierre

244
Bonjour

Comme le déplacement des trains était saccadé, j'ai voulu (beaucoup) augmenter le nombre de points de passage des trains. Il est difficile de partager une courbe de Bézier en "arcs" de longueur égale, par contre c'est assez facile avec un cercle, c'est pour cela que je suis passé à des courbes Bézier cubiques qui avec le nombre magique sont quasiment des cercles.

Pour le calcul des coordonnées des points de passage (méthode points() ) j'ai du me "battre" avec Processing, j'ai assaini et simplifié cela dans une nouvelle version. J'ai aussi assaini le calcul des angles pour l'orientation des trains (tangente à la courbe) et l'ai rendu plus général.

Des arcs à 45° extensibles c'est une bonne idée, mais pour moi il faut que j'ai un cercle qui passe bien dedans, c'est déjà un peu juste avec les petits arcs, il faudra que je passe aussi aux courbes de Bézier cubiques (avec peut être d'autres nombres magiques).

Pierre

245

Bonjour

Bon, pour moi il n'y a que deux systèmes "viables" pour choisir les itinéraires :

- soit par appui sur un seul bouton (comme sur le Locodrome), mais cela conduit vite à beaucoup de boutons s'il y a beaucoup d'itinéraires

- soit par appui sur deux boutons, le bouton origine puis le bouton destination (ou vice-versa), ce qui limite bien le nombre de boutons

Les boutons pouvant êtres des boutons réels :

- soit sur une sorte de clavier séparé du TCO

- soit sur le TCO

Ils peuvent êtres des boutons virtuels sur un écran graphique et "appuyés" avec la souris ou un effet tactile, cela ne change rien.

Dans le cas avec deux boutons (réels ou virtuels) mis sur le TCO il est très pratique d'implanter les boutons sur le trace des voies, dans la zone d'origine et dans la zone de destination.

Ayant longuement pratiqué diverses méthodes ce sont les seules qui ne deviennent pas fastidieuses quand on "joue" au train, si la méthode est plus compliquée on se lasse très vite et on ne "joue" plus. Ma nette préférence étant pour les deux boutons sur le trace des voies.

Pierre

246
Quand on voit comment marche la recherche d'itinéraires, on doit facilement la rendre indépendante de la gestion du réseau proprement dite.

Que cela soit un TCO sur un écran ou un TCO en dur cela ne change rien vis à vis de la gestion du TCO. Pour pouvoir faire des itinéraires à partir du TCO indépendamment du gestionnaire de réseau il faut que le TCO soit au courant de pas mal d'informations sur le réseau (topologie, aiguilles, zones, signaux, ...) et de leurs changements. Cela revient à transférer (ou à dupliquer) des parties du gestionnaire du réseau dans le TCO, avec le gros problème de maintient de la cohérence entre l'état du TCO et l'état du gestionnaire.

Comme j'en ai parlé dans le fil sur le système de Jean-Luc, j'utilise mon nouveau TCO (sur écran) pour faire circuler des trains virtuels et établir des itinéraires (avec recherche récursive) sans gestionnaire de réseau. Pour cela j'ai du ajouter au TCO des infos sur la topologie du réseau (les zones  suivantes paires et impaires), je dois gérer l'état des aiguilles, des zones et des signaux dans le TCO. Tout cela c'est des parties et des tâches du gestionnaire de réseau. Dans mon cas c'est facile car je fais circuler des trains virtuels sur un réseau tout aussi virtuel. Mais sur un réseau réel il faudra prendre en compte aussi l'interface réel avec le réseau (bus, Arduino, ...). Ce qui conduira à mettre pratiquement tout le gestionnaire de réseau dans le TCO.

Dans mon cas quand le TCO marchera bien je vais retirer tout ce qui a été rajouté (pour les itinéraires et la circulation des trains virtuels) pour les remettre dans le gestionnaire de réseau.

Je pense qu'il faut bien séparer les choses, le TCO affiche des informations fournies par le gestionnaire et il fournit au gestionnaire des demandes d'itinéraires (ou autres), mais il ne prend aucune décision. Le TCO et le gestionnaire sont deux programmes qui communiquent beaucoup entre eux, ils peuvent résider sur une seule machine (PC, Mac, PCduino, gros Arduino...) ou êtres répartis sur deux machines.

Pierre




247
Bonjour

J'ai un réseau très semblable au tien avec les mêmes volontés d'exploitation. J'ai une grand gare à double voie de passage, une coulisse exactement comme la tienne (sans tramway), avec en plus une petite gare terminus de voie unique et un dépôt.

J'utilise ma coulisse comme la tienne, quand un train arrive dans un sens un autre train part après un certain temps dans le même sens et pareil pour l'autre sens.

Pour cela j'ai deux "postes d'aiguillages", un pour la grande gare (présenté dans un post précédent) et un "poste d'aiguillage" pour la coulisse. J'ai aussi deux autres  postes pour la petite gare et pour le dépôt. Ce découpage en plusieurs postes est tout à fait conforme à ce que fait la SNCF (j'en ai parlé un peu avec l'article sur les itinéraires).

Chaque poste a ses propres itinéraires, il y a des itinéraires pour la grande gare et des itinéraires pour la coulisse (les deux autres postes ont aussi leurs itinéraires).

Pour pouvoir faire circuler des trains sur les deux ovales sans avoir besoin d'intervenir, j'ai des itinéraires "permanents" (j'en ai parlé un peu avec l'article sur les signaux) sur la grande gare et sur la coulisse.

Le poste de la coulisse a un mode automatique activable séparément sur chacun des sens, qui réalise l'alternance des trains. Je n'ai toujours pas fini la mise au point de cet automatisme et il reste des bugs (c'est pas trivial car il y a beaucoup de cas particuliers).

Ce que vous cherchez à faire (Denis et toi) c'est un peu une commande centralisée comme à la SNCF, mais à la SNCF il n'y a pas de boucles dans ce qui est commandé. Je ne sais pas trop bien comment fonctionnent ces commandes centralisées à la SNCF car je n'ai jamais eut l'occasion d'en visiter contrairement aux postes d'aiguillages classique. J'ai eu la chance de pouvoir visiter longuement des postes électromécaniques et des PRS. Mais on peut discuter sur ce sujet.

Pierre


248
Bonjour

Ce qui se passe hors de ta gare n'a pas à intervenir sur les itinéraires de la gare.

Sur l'exemple du Locodrome ce qui se passe sur la boucle n'est pas pris en compte par les itinéraires. La zone Z3 n'a pas de suivantes-paires et la zone Z4 n'a pas de suivantes-impaires. Il n'y a pas d'itinéraire possible passant par le haut de la boucle.

Pierre

249
Bonjour

Pour les trains complets, j'aime beaucoup aussi surtout quand ils se tortillent dans les successions d'aiguilles, mais concrètement c'est le premier pas pour pouvoir mettre en tête d'une rame une machine  ou vice versa. C'est nécessaire pour pour tester le gestionnaire qui est plus compliqué dans ces cas là.

Le but était bien de comparer avec le programme de Jean-Luc. Je ne pense pas que l'absence d'identifiants change grand chose, la différence est plutôt au niveau conceptuel.

Avec la liste des zones d'un itinéraire, je peux l'établir à savoir positionner les aiguilles (ce n'est pas le plus facile) ouvrir les signaux et faire le tracé sur le TCO. Mais aussi le détruire, juste fermer les signaux et le détracer. Pour positionner les aiguilles j'ai ajouté, dans la classe zone, une méthode qui fait le travail dans les cas simples (une seule aiguille ou TJD), cette méthode étant redéfinie dans les zones particulières pour les cas compliqués (plusieurs aiguilles ou TJD).

Pour l'instant je ne prends pas en compte les boucles de retournement. De toute façon un itinéraire avec une boucle de retournement c'est pas très réaliste. N'ayant pas de croisements sur mon réseau j'ai pas encore envisagé le problème.

Pour l'itinéraire le plus court, cela marche bien sur mon réseau, mais il est clair que ce n'est pas le cas du tien. Il faut trouver un critère pour choisir, après la programmation ce n'est pas trop le problème.

La déclaration des zones et de la liste des zones est assez fastidieuse, mais je ne vois pas de solutions à par écrire un programme annexe (en Processing par exemple) qui sort sur la console un bout de programme idoine, il ne reste plus qu'a faire un copier/coller !

Pour les déclarations des différentes zones, on ne peut pas simplifier non plus (le C++ est assez bavard), mais ici aussi la technique précédente peux être avantageusement utilisée utilisée. J'avais essayé, lors de l'écriture de mon premier article sur le gestionnaire, des macros C (pour le préprocesseur) cela marchait pas mal, mais ce n'était pas publiable et il n'y avait aucune détection d'erreurs.

Les deux entiers dans les constructeurs des différentes zones, ce sont les tailles des tableaux des suivantes-paires et des suivantes-impaires, j'en ai besoin pour les parcourir (problème classique avec le C/C++).

Pierre


 



250
Bonjour

Suite à ce que j’ai fait pour les TCOs en Processing et les articles ("Un gestionnaire en C++ pour votre réseau 1 2 "), je suis en train de réécrire complètement le gestionnaire de mon réseau.

J’ai commencé par la partie TCO qui en avait le plus besoin, à force de modifications pour ajouter plein de choses ce n’était plus très propre et puis les courbes de Béziers c’est quand même plus joli.

Comme pour le Locodrome je fais circuler des trains (composés de plusieurs véhicules), mais pour l’instant sans gestionnaire (j’ai juste ajouté quelques informations sur le réseau dans le TCO, avec des méthodes " suivant…() " ).

C’est très pratique car je peux peaufiner le TCO et faire pas mal d’essais pour éliminer les bugs dans la gestion du TCO.

Comme je n’ai pas pour l’instant d'itinéraires, et pour le plaisir, j’ai expérimenté la méthode de Jean-Luc, je cherche les itinéraires entre une origine et une destination. Pour cela j’ai une méthode RECURSIVE qui fait une dizaine de lignes de code qui marche très bien, quand il y a plusieurs possibilités je prend la plus courte (ce n'est pas la meilleure façon, mais c'est la plus simple et il faut bien choisir !) et je trace l’itinéraire sur le TCO comme pour le Locodrome.

Par contre pour annuler ou mémoriser un itinéraire c’est plus délicat, et puis il il a l’enclenchement d’approche à réaliser et la prise en compte des autorisations, mais c'est faisable. Inversement j’économise l’écriture d’une centaine d’itinéraires.


La base de mon réseau est la ZONE, une zone est un ensemble de voies et/ou d'appareils de voie pour lequel il ne peut y avoir qu'un seul train à la fois

Pour la recherche des itinéraires j'ajoute dans les classes zones deux méthodes qui renvoient la liste des zones suivantes paires et la liste des suivantes impaires, et dans la classe zone deux méthodes pour la recherche des itinéraires (dont une récursive) ainsi que quelques variables. Comme les classes zones ont beaucoup de références croisées entre elles, on ne peut pas tout faire dans le constructeur et il faut attendre que tous les objets zones soient construits pour établir ces références, c'est le rôle de la méthode liens() de zone qui est appelée dans le setup().

J'ai choisi de séparer la recherche des itinéraires dans le sens pair de celle du sens impair, car en pratique, pour optimiser, je marque les zones avec les marques suivantes : origine-paire, origine-impaire, destination-paire et/ou destination-impaire. Comme je clique sur le TCO sur une zone d'origine puis sur une zone de destination, cela me permet d'éliminer d'emblée les itinéraires impossibles et dans certains cas de limiter la recherche (pair/impair).

Concrètement on trouvera ci dessous le programme de la recherche récursive automatique des itinéraires appliquée au Locodrome, écrit en Processing puis en C++. Le programme a été optimisé pour qu'il y ai le moins de choses possibles sur la pile d"exécution.

L'image du Locodrome pour l'identification des zones :

Le programme en Processing :

void setup() { // programme de test
  for (Zone z : zones) z.liens(); // etablissement des liens entre zones (suivants)
  print("Z3 vers z4 "); z3.itineraireVers(z4);
  print("Z4 vers z3 "); z4.itineraireVers(z3);
  z0.occupee=true; println("occupation de la zone Z0");
  print("Z3 vers z4 "); z3.itineraireVers(z4);
  print("Z4 vers z3 "); z4.itineraireVers(z3);
}

static Zone z0=new Z0(),z1=new Z1(),z2=new Z2(),z3=new Z3(),z4=new Z4(),z5=new Z5();
static Zone[] zones={z0,z1,z2,z3,z4,z5};

static abstract class Zone {
  static Zone[] VIDE={};
  boolean occupee=false; // la zone est occupee par un train
  boolean utilisee=false; // la zone est utilisee par un autre itineraire

  abstract Zone[] suivantesPair();
  abstract Zone[] suivantesImpair();

  Zone[] suivantesPair;
  Zone[] suivantesImpair;

  static Zone destination;
  static Zone suivante;
  static boolean sensRecherche;
  static Zone[] itineraire=new Zone[10]; static int index; // itineraire courant
  static Zone[] itineraireLePlusCourt=new Zone[10]; static int longueur; // itineraire le plus court

  void liens() { suivantesPair=suivantesPair(); suivantesImpair=suivantesImpair(); }

  void copie() { // copie de l'itineraire vers le plus court
    for (longueur=0; longueur<index; longueur++) itineraireLePlusCourt[longueur]=itineraire[longueur];
  }

  void affichage() { // affichage de l'itineraire le plus court
    println(); print("itineraire ");
    for (int i=0; i<longueur; i++) print(itineraireLePlusCourt[i].getNom()+" "); println();
  }
 
  void itineraireVers(Zone d) { // methode preparatoire (non recursive)
    destination=d;
    itineraire[0]=this; index=1; // origine
    longueur=0; // remise a zero de l'itineraire le plus court
    sensRecherche=false; itineraire(); // recherche sens pair
    sensRecherche=true; itineraire(); // recherche sens impair
    if (longueur!=0) affichage(); // on a trouve un des itineraires les plus courts
  }
 
  void itineraire() { // vers destination (methode recursive)
    if (occupee)  return; // la zone est occupee (donc pas utilisable)
    if (utilisee) return; // la zone est utilisee (par un autre itineraire)
   
    if (this==destination) { // on est arrivé à destination donc on a trouvé un itineraire
      if (longueur==0)    copie(); // premier itineraire de la recherche (copie)
      if (longueur>index) copie(); // itineraire plus court que le precedent (copie)
   
    } else { // on continue a chercher
      Zone[] suivantes=sensRecherche?suivantesPair:suivantesImpair; // suivant le sens de recherche
      for (int i=0; i<suivantes.length; i++) { // pour tous les suivantes paires ou impaires
        suivante=suivantes[i];
        itineraire[index++]=suivante; // on ajoute une des zones suivantes a l'itineraire
        suivante.itineraire(); // RECURSIVITE
        index--; // on supprime la zone de l'itineraire
      }
    }
  }

  final String getNom() { return getClass().toString().substring(25) ; } // nom de zone
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static class Z3 extends Zone {
  Zone[] suivantesPair() { return VIDE; }
  Zone[] suivantesImpair() { return new Zone[] {z2}; }
}

static class Z2 extends Zone {
  Zone[] suivantesPair() { return new Zone[] {z3}; }
  Zone[] suivantesImpair() { return new Zone[] {z0,z1}; }
}

static class Z0 extends Zone {
  Zone[] suivantesPair() { return new Zone[] {z2}; }
  Zone[] suivantesImpair() { return new Zone[] {z5}; }
}

static class Z1 extends Zone {
  Zone[] suivantesPair() { return new Zone[] {z2}; }
  Zone[] suivantesImpair() { return new Zone[] {z5}; }
}

static class Z5 extends Zone {
  Zone[] suivantesPair() { return new Zone[] {z0,z1}; }
  Zone[] suivantesImpair() { return new Zone[] {z4}; }
}

static class Z4 extends Zone {
  Zone[] suivantesPair() { return new Zone[] {z5}; }
  Zone[] suivantesImpair() { return VIDE; }
}
Le programme en C++ :
class Zone;

static Zone* destination;
static Zone* suivante;
static boolean sensRecherche;
static Zone* itineraireCourant[10]; static int index; // itineraire courant
static Zone* itineraireLePlusCourt[10]; static int longueur; // itineraire le plus court

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class Zone {
public:
  boolean occupee=false; // la zone est occupee par un train
  boolean utilisee=false; // la zone est utilisee par un autre itineraire

  Zone** suivsPair;
  Zone** suivsImpair;
  int nbPair;
  int nbImpair;

  virtual Zone** suivantesPair()=0;
  virtual Zone** suivantesImpair()=0;

  Zone(int np,int ni) { // constructeur
    nbPair=np; nbImpair=ni;
  }

  void liens() { suivsPair=suivantesPair(); suivsImpair=suivantesImpair(); }

  void copie() { // copie de l'itineraire vers le plus court
    for (longueur=0; longueur<index; longueur++) itineraireLePlusCourt[longueur]=itineraireCourant[longueur];
  }

  void affichage() { // affichage de l'itineraire le plus court
    Serial.println(); Serial.print("itineraire ");
    for (int i=0; i<longueur; i++) Serial.print(itineraireLePlusCourt[i]->getNom()+" "); Serial.println();
  }
 
  void itineraireVers(Zone* d) { // methode preparatoire (non recursive)
    destination=d;
    itineraireCourant[0]=this; index=1; // origine
    longueur=0; // remise a zero de l'itineraire le plus court
    sensRecherche=false; itineraire(); // recherche sens pair
    sensRecherche=true; itineraire(); // recherche sens impair
    if (longueur!=0) affichage(); // on a trouve un des itineraires les plus courts
  }
 
  void itineraire() { // vers destination (methode recursive)
    if (occupee)  return; // la zone est occupee (donc pas utilisable)
    if (utilisee) return; // la zone est utilisee (par un autre itineraire)
   
    if (this==destination) { // on est arrivé à destination donc on a trouvé un itineraire
      if (longueur==0)    copie(); // premier itineraire de la recherche (copie)
      if (longueur>index) copie(); // itineraire plus court que le precedent (copie)
   
    } else { // on continue a chercher
      Zone** suivantes=sensRecherche?suivsPair:suivsImpair; // suivant le sens de recherche
      int nb=sensRecherche?nbPair:nbImpair;
      for (int i=0; i<nb; i++) { // pour tous les suivantes paires ou impaires
        suivante=suivantes[i];
        itineraireCourant[index++]=suivante; // on ajoute une des zones suivantes a l'itineraire
        suivante->itineraire(); // RECURSIVITE
        index--; // on supprime la zone de l'itineraire
      }
    }
  }

  virtual String getNom(); // nom de zone
};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

class Z3:public Zone {
public:
  Z3():Zone(0,1) {}
  Zone** suivantesPair();
  Zone** suivantesImpair();
  String getNom() { return "Z3"; }
};

class Z2:public Zone {
public:
  Z2():Zone(1,2) {}
  Zone** suivantesPair();
  Zone** suivantesImpair();
   String getNom() { return "Z2"; }
};

class Z0:public Zone {
public:
  Z0():Zone(1,1) {}
  Zone** suivantesPair();
  Zone** suivantesImpair();
  String getNom() { return "Z0"; }
};

class Z1:public Zone {
public:
  Z1():Zone(1,1) {}
  Zone** suivantesPair();
  Zone** suivantesImpair();
  String getNom() { return "Z1"; }
};

class Z5:public Zone {
public:
  Z5():Zone(2,1) {}
  Zone** suivantesPair();
  Zone** suivantesImpair();
  String getNom() { return "Z5"; }
};

class Z4:public Zone {
public:
  Z4():Zone(1,0) {}
  Zone** suivantesPair();
  Zone** suivantesImpair();
  String getNom() { return "Z4"; }
};

static Zone *z0=new Z0(),*z1=new Z1(),*z2=new Z2(),*z3=new Z3(),*z4=new Z4(),*z5=new Z5();
static Zone* zones[]={z0,z1,z2,z3,z4,z5};

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void setup() {
  for (int i=0; i<6; i++) zones[i]->liens(); // etablissement des liens entre zones (suivants)
  Serial.begin(9600);
  Serial.print("Z3 vers z4 "); z3->itineraireVers(z4);
  Serial.print("Z4 vers z3 "); z4->itineraireVers(z3);
  z0->occupee=true; Serial.println("occupation de la zone Z0");
  Serial.print("Z3 vers z4 "); z3->itineraireVers(z4);
  Serial.print("Z4 vers z3 "); z4->itineraireVers(z3);

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

static Zone** VIDE=new Zone*[0]{};

  Zone** Z3::suivantesPair() { return VIDE; }
  Zone** Z3::suivantesImpair() { return new Zone*[1] {z2}; }

  Zone** Z2::suivantesPair() { return new Zone*[1] {z3}; }
  Zone** Z2::suivantesImpair() { return new Zone*[2] {z0,z1}; }

  Zone** Z0::suivantesPair() { return new Zone*[1] {z2}; }
  Zone** Z0::suivantesImpair() { return new Zone*[1] {z5}; }

  Zone** Z1::suivantesPair() { return new Zone*[1] {z2}; }
  Zone** Z1::suivantesImpair() { return new Zone*[1] {z5}; }

  Zone** Z5::suivantesPair() { return new Zone*[2] {z0,z1}; }
  Zone** Z5::suivantesImpair() { return new Zone*[1] {z4}; }

  Zone** Z4::suivantesPair() { return new Zone*[1] {z5}; }
  Zone** Z4::suivantesImpair() { return VIDE; }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop() {}

Affichages des deux programmes (c'est le même pour les deux) :

Z3 vers z4
itineraire Z3 Z2 Z0 Z5 Z4
Z4 vers z3
itineraire Z4 Z5 Z0 Z2 Z3
occupation de la zone Z0
Z3 vers z4
itineraire Z3 Z2 Z1 Z5 Z4
Z4 vers z3
itineraire Z4 Z5 Z1 Z2 Z3

Et pour finir ce que cela donne avec la grande gare de mon réseau :


Pierre

251
Bonjour

Pour communiquer depuis Processing vers un Arduino on utilise la bibliothèque "Serial". Voici un exemple d'utilisation :

import processing.serial.*;

int NO_PORT=2; // n° du port USB/serie utilise pour communiquer
Serial port; // le port pour les lectures et écritures futures

void setup() {
  print("Les ports serie : ");
  println((Object[])Serial.list());
  println("Le port utilise : "+Serial.list()[NO_PORT]);
  port=new Serial(this,Serial.list()[NO_PORT],9600);
  ...
}


Ce programme liste tous les ports série, affiche le port utilisé (celui de numéro NO_PORT) et se connecte à l'Arduino par ce port.

Il doit être possible de se connecter à plusieurs Arduino en utilisant plusieurs variables "port", mais je n'ai pas essayé et il peut avoir des problèmes avec le Hub USB qui sera vraisemblablement nécessaire.

Pierre

252

Bonjour

Il y a quelque chose qui me chiffonne beaucoup, dans le LocodromeBAL, associé à l'article 3 http://www.locoduino.org/spip.php?article172, les méthodes suivantePaire() et suivanteImpaire() ne servent pas, on peut les enlever cela ne change rien, en fait elles ne sont la que pour anticiper un peu la suite (l'article 4 à paraitre).

Ce qui veut dire que la topologie du réseau n'est en fait pas décrite explicitement, malgré cela le gestionnaire fonctionne tout à fait normalement, c'est donc le train lors de ses déplacements qui décrit d'une certaine façon la topologie du réseau ???

Bien sûr ces méthodes auront une utilité par la suite.

Pierre59

253
Présentez vous ! / Re : Hello de Pyk35
« le: octobre 08, 2016, 05:01:20 pm »
Bonjour

Pour le plaisir et pour comprendre comment cela marche, j'avais fait un décodeur de locomotive il y a quelques années, voir :

http://forum.e-train.fr/viewtopic.php?f=63&t=75315&start=81

Le ATtiny13 était vraiment juste et le pont en H pas assez puissant, mais cela fonctionnait (sans CVs). Avec un ATtiny45/85, c'est réalisable.

Le décodeur est monté sur une plaque à pastilles, donc pas de PCB à faire !

Pierre

254
Bonjour

Le troisième article de la série  "Un gestionnaire en C++ pour votre réseau" ( http://www.locoduino.org/spip.php?article172 ) est paru sur le site de LOCODUINO. Après les aiguilles, les zones et les signaux, les itinéraires sont abordés, ainsi qu'un exemple complet avec un réseau minimaliste, le Locodrome. Ce gestionnaire de réseau complet est destiné à fonctionner sur un Arduino Uno (ou plus), il pourra être testé complètement par le biais d’un TCO virtuel avec circulation effective de trains (tout aussi virtuels). Ce TCO virtuel est un programme écrit en Processing qui communique avec le gestionnaire par une liaison USB/série.

On trouvera dans le fichier joint (c'est le même que celui de l'article) :
- le programme de gestion du Locodrome en C++
- le programme du TCO en Processing
- une notice d'utilisation
- un dessin du TCO et un dessin du Locodrome

Le programme de gestion de réseau, utilisé pour le Locodrome, doit être considéré comme la version de référence (pour l'instant) rendant obsolète toutes les versions antérieures.

Avec ces deux programmes on peut jouer au trains (virtuels) presque comme sur un réseau réel.

Voir aussi sur le forum : "LOCODUINO->Parlons Arduino->Vos projets->TCO en Processing" ( http://forum.locoduino.org/index.php?topic=119.15 ), pour plus d'informations sur le TCO.

Bon amusement.

Pierre59

255
Vos projets / Re : TCO en processing
« le: avril 25, 2016, 03:06:27 pm »
Bonjour

Voila l'ébauche d'un TCO qui pourrait servir pour le Locodrome dont on a parlé ici dans différents forums. Le programme est écrit en Processing suivant l'idée de Denis. Il est a priori destiné à servir de TCO au Locodrome qui doit être utilisé comme exemple du programme de gestion de réseau en C++, qui a commencé à être décrit dans un premier article (d'autres vont suivre!).



Le programme de gestion est destiné à être installé sur un Arduino qui communique avec le TCO par la liaison USB/série, le TCO est alors affiché sur l'ordinateur.

Contrairement à ce que propose Denis, ce n'est pas un éditeur de TCO, le TCO est programmé en "dur" spécifiquement pour le Locodrome (mais peut être adapté à d'autres cas). Il comporte tout ce que l'on peut espérer d'un TCO basique.

- tracé du réseau
- séparation des zones
- coloration des zones
- position des aiguilles
- implantation des signaux
- état des signaux
- nom des zones, aiguilles et signaux

Il comporte aussi 8 boutons pour les 8 itinéraires possibles, mais cela pourrait aussi se faire par des clicks sur les zones (départ, arrivée). Lors de l'appui sur un bouton un message apparait dans la console. Les deux boutons en bas à droite permettent de masquer la grille et les informations (et inversement).

En cliquant hors des boutons (ou dessus) les deux zones d'aiguilles sont colorées/décolorées (ici en rouge pour simuler l'occupation des zones) et le signal C1 change de couleur (à titre d'exemple).

Bien entendu ce programme est écrit en pure programmation objet (ici en Java). On trouvera le programme Processing en fichier accompagné (ici ce programme de démonstration est autonome et ne nécessite pas d'Arduino, juste l'IDE Processing).

Pierre

Pages: 1 ... 15 16 [17] 18 19