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

Pages: 1 ... 39 40 [41] 42 43 ... 45
601
Bus DCC / Re : DCC & CVs
« le: janvier 30, 2016, 08:20:12 pm »
De mon côté, j'ai trouvé un schéma (http://usuaris.tinet.cat/fmco/dccgen_en.html) qui pourrait faire le même boulot, même si je trouve le tien plus simple et compréhensible...

602
Infos et bonnes affaires / Re : Gestion git avec automatisme
« le: janvier 28, 2016, 11:37:07 pm »
Je t'ai ajouté dans le groupe locoduino. Tu devrais le trouver maintenant.

603
Infos et bonnes affaires / Re : Gestion git avec automatisme
« le: janvier 28, 2016, 10:58:07 pm »
Sur ta page de ton projet sur git.framasoft.org, tu vas dans le menu settings tout en bas à gauche, et dans la fenêtre principale, tu descends tout en bas, il y a une section 'Transfer project' : tu donnes locoduino.org comme nouveau propriétaire, et tu valides. Attention, c'est définitif. Après ça il te faudra détruire ton dépot local, et le recréer en clonant le nouveau !

604
Shields et Modules / Re : Carte Servomoteurs DCC + CAN
« le: janvier 28, 2016, 10:35:09 am »
Du coup, si tu as du rab, je suis partant pour deux aussi ! Je vais tâcher d'adapter UAD pour qu'il sache piloter tout ça.

605
Bibliothèques / Re : Bibliothèque Wire I2C
« le: janvier 28, 2016, 10:33:03 am »
Soit repartir sur l'option a) avec une petite couche de protocole logiciel.

Je me demande quand même si le mieux ne serait pas de faire une nouvelle bibliothèque NewWire intégrant tes idées et simplifiant/sécurisant l'accès à la communication I2C maître ou esclave...

606
Infos et bonnes affaires / Re : Gestion git avec automatisme
« le: janvier 26, 2016, 11:28:15 pm »
Je vais voir ce que je peux faire :)

607
Infos et bonnes affaires / Re : Gestion git avec automatisme
« le: janvier 25, 2016, 08:45:02 pm »
Je te rassure, Perl, Python et tous les autres (comme Powershell très puissant et je crois uniquement chez cro$oft) sont disponibles sous Windows. Il y a même des clones de Bash qui circulent. Mais il faut bien le reconnaître, les scripts ne sont pas la tasse de thé des utilisateurs Windows, plutôt celle des bidouilleurs de tous poils sur les systèmes exotiques :) ou des vieux comme moi. Malgré tout il est possible de faire beaucoup de choses aussi, et notamment de piloter une application comme Git en ligne de commande avec assez de facilité !

608
Vos projets / Re : Contrôle numérique des aiguillages
« le: janvier 13, 2016, 08:50:07 pm »
Voilà un projet qu'il est très intéressant !

En développant UAD, j'ai dû revoir certaines idées préconçues à propos des moteurs à bobine.
Il y a pour ma bibliothèque trois types de ces moteurs : les classiques Jouef/Marklin/etc avec deux bobines comme tu as déjà décrit.
Mais il y a aussi les moteurs Kato et Rokuhan qui sont mono bobine : c'est l'inversion de polarité qui fait le choix de la direction.
Enfin il y a les dételeurs, eux aussi mono bobine mais avec une durée d'activation nettement plus importante que les aiguillages. elle doit pour moi être réglée spécialement pour cet usage.
Si on voulait être complet, il faudrait aussi traiter les servo moteurs et les moteurs à mouvement lent comme les Seep, Cobalt, et autre Tortoise...

J'ai traité le mouvement concurrent de plusieurs moteurs différemment en permettant de construire des groupes d'accessoires à manipuler ensembles, mais de manière séquentielle ou simultanée... Ton approche de la non simultanéité d'alimentation par un délai de mise en route est très intéressante...

Enfin, comme tu le dis, un bouton pour 'reseter' tous les moteurs dans une position de départ théorique, ou pour remettre en conformité avec ce que l'Arduino croit savoir de la position de chaque aiguille est une bonne idée. Et quid de la sauvegarde de la position courante de chacune en EEPROM pour repartir avec les bonnes données après une extinction du système ? A noter que je n'ai rien fait de tout ça dans UAD !

609
Présentez vous ! / Re : Bonjour
« le: janvier 06, 2016, 01:44:37 pm »
Bienvenue parmi nous pour cette nouvelle année ! Et n'hésites pas à nous détailler ton projet.

610
Bibliothèques / Re : Bouton poussoir
« le: janvier 06, 2016, 01:21:00 pm »
Bonjour, et bravo pour ta bibliothèque !

Quelques remarques d'un vieux développeur à propos de ton code source.

D'abord, il est bien structuré/formaté et documenté. C'est un plaisir à lire !

Quelques pistes d'amélioration:

  • Tu utilises 'const' abondamment, ce qui est plutôt bien, même si l'intérêt sur les valeurs de retour est discutable... Par contre une fonction peut elle même être const si elle ne touche pas à 'this'. C'est le cas de toutes à part actualiser() et le constructeur bien sûr... Ça donnerai:

        bool estEnfonce() const;

    et cela permettrai à un utilisateur de déclarer sa propre fonction const s'il le souhaite, ce qui n'est pas possible si l'une des fonctions appelées ne l'est pas !
  • Ces mêmes fonctions sont très simples et parfaitement éligibles à 'inline'. Ce mot clé 'advanced user' du langage C permet de ne compiler une fonction que si elle est utilisée quelque part, contrairement aux fonctions classiques dans le cpp qui sont compilées même si elles ne sont pas utilisées ! En compilant l'exemple 'bouton 1' avec ta bibliothèque j'ai besoin de 2860 octets, avec ma version seulement 2782 ! Note que pour pouvoir compiler, j'en ai profité pour passer tes constantes d'état à l'intérieur de la classe, ce qui simplifie encore le .cpp .
  • Enfin, et c'est plus une façon de faire venant d'une longue expérience des langages objet, je suis partisan de mettre un 'this->' devant l’accès à chaque élément d'une classe (donnée, fonction) afin d'être sûr que là on parle bien de quelque chose appartenant à l'objet en cours, et pas d'une variable locale...

Pour info, les fichiers d'exemple devraient être en .ino. Le .pde est plutôt destiné aux scripts 'Processing', même si l'IDE Arduino l'accepte.
Et pour terminer ma liste de critiques (que j'espère constructive !), tu devrais lire mon article http://www.locoduino.org/spip.php?article146 'Monter une bibliothèque' qui décrit tous les fichiers annexes nécessaires à ajouter dans le fichier zip pour pouvoir la gérer depuis le Gestionnaire de l'IDE 1.6.* ...

611
Débuter / Re : commande servo par inter
« le: décembre 31, 2015, 02:16:43 pm »
Salut, merci pour tes vœux, et recevez tous aussi mes meilleurs vœux pour cette nouvelle année en espérant qu'elle soit meilleure à tous points de vue que 2015. Ça ne devrait pas  être difficile !

J'ai jeté un coup d’œil à ton code et tenté de le compiler avec l'IDE 1.6.7 .
Il y a effectivement quelques erreurs de syntaxe, mais rien de bien compliqué !

1 : les espaces ne sont pas permis dans les identifiants : nom de fonction, de variable, de structure, etc... C'est la première correction : changer 'evenementServo DEVIE' en 'evenementServo_DEVIE'. Idem pour le DROIT bien sûr.

2 : la déclaration d'une variable consiste à donner un type et un nom. C'était le rôle de la ligne

 int numPoussoir = (analogRead(pinPoussoirs) + 64) / 128;

qui faisait à la fois la déclaration  'int numPoussoir' et l'affectation 'numPoussoir = (analogRead(pinPoussoirs) + 64) / 128;'. Le langage C/C++ permet de faire les deux en même temps... Dans ton cas, cela signifie simplement que tu dois écrire

 int numPoussoir = 4;

ou

 int numPoussoir;
 numPoussoir = 4;

pour déclarer la variable numPoussoir en tant que entier, et y affecter 4 comme valeur.

3 : Attention aux accolades et autres parenthèses ou point-virgules ! Le langage est complètement intolérants aux fautes de syntaxe ! Dans loop(), il manquait l'accolade fermante du test sur EVENEMENT_DROIT.

4 : Pour une raison que j'ignore, la ligne

byte evenement = lireEvenement(&numServo);

était en remarque. Comme la variable 'evenement' n'était plus déclarée, les tests qui suivaient sur sa valeur ne pouvaient fonctionner ! Encore une fois, le langage ne permet pas d'approximation et ne peux pas travailler sur quelque chose qui n'est pas déclaré.

5 : Les variables EVENEMENT_DROIT et EVENEMENT_DEVIE n'existent pas !

6 : La ligne

servoMoteur[numServo].objetServo.attach(servoMoteur[numServo].pin);

était dans un 'switch', mais en dehors de tout 'case', ce qui est interdit ! Je l'ai donc sortie du 'switch' sans vraiment savoir quel comportement tu voulais... Parce que le attach ne devrait être fait QUE dans le setup !

7 : Je me suis permis de reformatter ton code avant de le poster ici. Comme l'a dit Denis, un formattage correct ne donne pas un code qui marche, mais un formattage incorrect donne du code difficile à mettre au point, puis à maintenir ! A ce sujet, il y a plusieurs écoles quant au placement des accolades. Certains, comme Jean-Luc, sont partisans du format avec l'accolade ouvrante à la fin de la ligne

if () {
  ...
}

que j'ai longtemps pratiqué et qui permet de gagner une ligne sur celui que je préconise maintenant avec l'accolade ouvrante toute seule sur sa ligne et au niveau du premier caractère de l'instruction associée (if, for, switch...), et avec l'accolade fermante encore seule et sur la même colonne :

if ()
{
  ...
}

il est à mon avis plus simple à lire, mais ce n'est que mon avis. Une fois ton choix fait, tu dois te l'imposer, et toujours formatter ton code en le respectant. La pire des situations étant bien entendu le mélange des deux !

// A PRIORI PAS DE MODIFICATION
#include <Servo.h>
 
const byte SERVO_A_ANGLE_MIN = 0;
const byte SERVO_A_ANGLE_MAX = 1;
const byte SERVO_EN_MOUVEMENT_VERS_ANGLE_MAX = 2;
const byte SERVO_EN_MOUVEMENT_VERS_ANGLE_MIN = 3;

const boolean DROIT = true;     // MODIFICATION PROG     
const boolean DEVIE = false;    // MODIFICATION PROG
 
const int angleMin = 1250;
const int angleMax = 1750;
 
struct DescripteurServo {
  Servo objetServo;
  int vitesse;
  int angle;
  int pin;
  byte etatServo;
};

struct DescripteurServo servoMoteur[4];
 
const byte NON_PRESSE = 0;
const byte ENFONCE = 1;
const byte PRESSE = 2;
 
byte etatAutomate = NON_PRESSE;
int etatPoussoir = -1;
 
const byte AUCUN_EVENEMENT = 0;
const byte EVENEMENT_PRESSE = 1;
const byte EVENEMENT_RELACHE = 2;

//variable pour les inters

boolean ancienA0  = HIGH;
boolean nouveauA0 = HIGH;
boolean ancienA1  = HIGH;
boolean nouveauA1 = HIGH;
boolean ancienA2  = HIGH;
boolean nouveauA2 = HIGH;
boolean ancienA3  = HIGH;
boolean nouveauA3 = HIGH;

                        //const int pinPoussoirs = 0; // A SUPPRIMER

// MODIFICATION DE LirePoussoirs et Lire Evenement AFIN D’AVOIR LE NUMERO
// ET L’ETAT DE L’INTER

int lirePoussoirs()
{
  int resultat;
//  int numPoussoir = (analogRead(pinPoussoirs) + 64) / 128;  //  A SUPPRIMER

  int numPoussoir = 4;                     // Ou faut il déclarer numPoussoir ?

  nouveauA0 = digitalRead(A0);   
  if (ancienA0 != nouveauA0)
  {
    ancienA0 = nouveauA0;
    numPoussoir = 0;
  }
  else
  {
    nouveauA1 = digitalRead(A1);
    if (ancienA1 != nouveauA1)
    {
      ancienA1 = nouveauA1;
      numPoussoir = 1;
    }
    else
    {
      nouveauA2 = digitalRead(A2);
      if (ancienA2 != nouveauA2)
      {
        ancienA2 = nouveauA2;
        numPoussoir = 2;
      }
      else
      {
        nouveauA3 = digitalRead(A3);
        if  (ancienA3 != nouveauA3)
        {
          ancienA3 = nouveauA3;
          numPoussoir = 3;
        }                                 
      }
    }
  }

  int nouvelEtatPoussoir = etatPoussoir; /* à priori rien ne change */
 
  switch (etatAutomate)
  {
    case NON_PRESSE:
      if (numPoussoir < 4)
        etatAutomate = ENFONCE;
      break;
     
    case ENFONCE:
      if (numPoussoir < 4)
      {
        etatAutomate = PRESSE;
        nouvelEtatPoussoir = numPoussoir;
      }
      else
        etatAutomate = NON_PRESSE;
       
      break;
     
    case PRESSE:
      if (numPoussoir == 4)
      {
        etatAutomate = NON_PRESSE;
        nouvelEtatPoussoir = -1;
      }
      break;
  }
   
  return nouvelEtatPoussoir;
}

byte lireEvenement(int *inpNumPoussoir)
{
  byte evenement;
  int nouvelEtatPoussoir = lirePoussoirs();
   
  if (nouvelEtatPoussoir == etatPoussoir)
    evenement = AUCUN_EVENEMENT;
  if (nouvelEtatPoussoir >= 0 && etatPoussoir == -1)
    evenement = EVENEMENT_PRESSE;
  if (nouvelEtatPoussoir == -1 && etatPoussoir >= 0)
    evenement = EVENEMENT_RELACHE;
 
  etatPoussoir = nouvelEtatPoussoir;
  *inpNumPoussoir = etatPoussoir;
   
  return evenement;
}

// A PRIORI PAS DE MODIFICATION
void setup()
{
  /* Initialisation des servos */
  int numServo;
 
  for (numServo = 0; numServo < 4; numServo++)
  {
    servoMoteur[numServo].angle = angleMin;
    servoMoteur[numServo].vitesse = 0;
    servoMoteur[numServo].etatServo = SERVO_A_ANGLE_MIN;
    servoMoteur[numServo].pin = numServo + 2;
    servoMoteur[numServo].objetServo.attach(servoMoteur[numServo].pin);
  }
 
  /* Initialisation des inters */ 
  pinMode(A0, INPUT_PULLUP);    //  BP 0
  pinMode(A1, INPUT_PULLUP);    //  BP 1
  pinMode(A2, INPUT_PULLUP);    //  BP 2
  pinMode(A3, INPUT_PULLUP);    //  BP 3     
}

// A PRIORI PAS DE MODIFICATION
void gereServo(int numServo)
{
  servoMoteur[numServo].objetServo.writeMicroseconds(servoMoteur[numServo].angle);
 
  servoMoteur[numServo].angle += servoMoteur[numServo].vitesse;
 
  if (servoMoteur[numServo].angle > angleMax)
  {
    servoMoteur[numServo].angle = angleMax;
    servoMoteur[numServo].vitesse = 0;
    servoMoteur[numServo].objetServo.detach();
    servoMoteur[numServo].etatServo = SERVO_A_ANGLE_MAX;
  }
  else
    if (servoMoteur[numServo].angle < angleMin)
    {
    servoMoteur[numServo].angle = angleMin;
    servoMoteur[numServo].vitesse = 0;
    servoMoteur[numServo].objetServo.detach();
    servoMoteur[numServo].etatServo = SERVO_A_ANGLE_MIN;
    }
}

//MODIFICATION J’AI PRIS DROIT = VERS ANGLE MAX ( A VERIFIER)
void evenementServo_DROIT (int numServo)
{
  servoMoteur[numServo].objetServo.attach(servoMoteur[numServo].pin);
  switch (servoMoteur[numServo].etatServo)
  {
    case SERVO_EN_MOUVEMENT_VERS_ANGLE_MIN:
      servoMoteur[numServo].vitesse =  1;
      servoMoteur[numServo].etatServo = SERVO_EN_MOUVEMENT_VERS_ANGLE_MAX;
      break;
  } 
}

//MODIFICATION J’AI PRIS DEVIE = VERS ANGLE MIN ( A VERIFIER)
void evenementServo_DEVIE (int numServo)
{
  servoMoteur[numServo].objetServo.attach(servoMoteur[numServo].pin);
  switch (servoMoteur[numServo].etatServo)
  {
    case SERVO_EN_MOUVEMENT_VERS_ANGLE_MAX:
      servoMoteur[numServo].vitesse = -1;
      servoMoteur[numServo].etatServo = SERVO_EN_MOUVEMENT_VERS_ANGLE_MIN;
      break;
  }
}

//MODIFICATION
void loop()
{
  int numServo;
 
  for (numServo = 0; numServo < 4; numServo++)
    gereServo(numServo);
 
  byte evenement = lireEvenement(&numServo);
 
  if (evenement == EVENEMENT_PRESSE)
    evenementServo_DROIT(numServo);

  if (evenement == EVENEMENT_RELACHE)
    evenementServo_DEVIE(numServo);
 
  delay(3);
}

612
Bibliothèques / UniversalAccessoryDecoder 420
« le: décembre 20, 2015, 02:36:19 pm »
Suite à plusieurs demandes, je me suis penché sur la consommation mémoire de UAD qui semblait à tout le monde (moi compris) excessive... De fait avec plus de 1400 octets de mémoire dynamique occupés pour l'exemple Full livré avec la version 4.15, ça laissait peu de place pour le fonctionnement. Je n'avais testé que sur un Mega, et ça marchait bien, mais sur un Uno , que nenni !

Après quelques heures d'optimisation, j'ai fait deux grosses amélios que je vais détailler ici parce que cela peut servir à beaucoup de monde...

Dcc_decoder.h/c : Ce bout de code utilisé fréquemment dans les décodeurs d'accessoires Dcc chez nous et ailleurs, est prévu pour beaucoup de choses, y compris la configuration du décodeur par des CVs. Et pour que cela marche, ce source tient une liste des valeurs courantes de toutes les CVs, soit 259 ! Dans le cas de UAD, seules certaines parmi les 29 premières sont utilisées, alors j'ai réduit cette liste à 29, soit 230 octets de gain ! Pour ceux que cela intéressent en tant que fichiers autonomes, il peuvent récupérer ces sources depuis la forge Framasoft https://git.framasoft.org/locoduino.org/UniversalAccessoryDecoder/tree/V4.

SerialCommander : Dans ce source je tente de piloter les accessoires à travers la liaison série fournie par les classes Serial et Serial1, 2 et 3 lorsqu'elles sont disponibles. Mais il y a deux gros bémols : mon source n'est pas opérationnel... J'aurais dû prendre le temps de m'inspirer de ce que Denis a écrit sur le sujet (article non publié...) mais ce n'est pas le cas ! Le second bémol, c'est que chaque classe Serial déclare en dur et en interne un buffer de lecture, un tampon de 150 caractères pris sur la mémoire dynamique. Et comme j'avais quand même tenté de faire les choses bien, j'avais permis d'utiliser les quatre interfaces séries lorsque le matériel le permet, ce sont 600 octets qui partaient en fumée même si le SerialCommander n'était pas utilisé ! Parce que l'IDE Arduino compile tous les sources du répertoire de la bibliothèque, même ceux qui ne sont appelés ou inclus par personne !

Voilà, au final, ce sont 619 octets de mémoire dynamique qui sont utilisés sur le même exemple en version 4.20 . C'est quand même beaucoup mieux et devrait permettre de piloter des accessoires avec un Uno ou un Nano !

614
Présentez vous ! / Re : Bonjour
« le: décembre 13, 2015, 03:49:40 pm »
Bienvenue parmi nous. On est là pour aider, alors n'hésites pas !

615
Vos projets / Re : Va et vient à trois autorails
« le: novembre 26, 2015, 02:43:16 pm »
Une demande aussi importante, toutes proportions gardées, impose l'écriture d'un véritable article sur le sujet ! Ainsi chacun verrait comment faire et reproduirai le schéma pour lui !

Pages: 1 ... 39 40 [41] 42 43 ... 45