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.


Sujets - Marc-Henri

Pages: 1 [2]
16
Composants / Etendre les entrées-sortie numériques
« le: septembre 14, 2015, 10:48:05 am »
Bonjour à tous,

Dans le cadre des réflexions sur mon nouveau réseau N, j'évalue les possibilités de cet IC de microchip qui permet d'ajouter des entrées-sorties numériques: http://ww1.microchip.com/downloads/en/DeviceDoc/21952b.pdf. Au prix de CHF 2.- pour 16 E/S supplémentaires, c'est tout à fait intéressant.

Dans un autre projet, j'avais utilisé des registres à décalage 74HC595 pour ajouter des sorties, mais ce circuit me semble plus souple car il permet la configuration individuelle de chaque pin en sortie, en entrée avec pull-up intégrée si nécessaire.

Si j'utilise ce circuit, ce sera avec l'interface I2C car le SPI est déjà utilisé par la programmation in situ du microcontrôleur. Avec un Arduino et son bootloader, on doit pouvoir travailler en SPI. Les longueurs de bus seront d'au plus 20-30 cm si sur une autre plaque et, dans ce dernier cas, les liaisons se feront avec du câble Ethernet afin de bénéficier du blindage.

Avez-vous de l'expérience avec ce composant ?

Merci d'avance pour vos contributions.
Meilleures salutations.

Marc-Henri

17
Modélisation, Architectures logicielles et matérielles / Machine à états
« le: septembre 07, 2015, 12:54:41 pm »
Bonjour à tous,

Lorsque les applications doivent gérer plusieurs événements ainsi que des timeouts, il est avantageux de les organiser sous forme d'une ou plusieurs machines à états. Une machine à états se représente sous la forme d'un diagramme états - transitions qui ensuite se traduit quasi systématiquement dans le langage de programmation.

Bien qu'ayant une longue expérience du développement de systèmes embarqués / temps réel pour l'avoir pratiqué professionnellement et maintenant en tant que hobby, l'élaboration même du diagramme à partir du comportement attendu du système me préoccupe. J'ai constaté qu'il est souvent plus simple de décrire des scénarios de fonctionnement particuliers plutôt que de généraliser tout de suite sous forme de diagramme états - transitions.

Je me demande donc s'il existe des outils qui, partant d'un ensemble de scénarios de fonctionnement, sont capables d'en déduire le diagramme d'états correspondant. J'ai trouvé plusieurs articles de recherche sur le sujet, mais aucune référence d'outils.

Le cas concret qui m'a amené à ces réflexions est la gare cachée de mon prochain réseau. Les caractéristiques de cette gare cachée sont les suivantes:
  • Elle comporte 2 voies.
  • Les 2 voies peuvent être empruntées dans les 2 sens, la gare cachée étant dans un tunnel le long d'une voie unique.
  • Si la gare contient 2 trains dans le même sens de marche, c'est le 1er arrivé qui sort en 1er.
  • Si la gare contient 2 trains en sens de marche opposés, il n'est plus nécessaire d'imposer un ordre de sortie. Chaque train peut partir n'importe quand.
  • La gare reçoit des ordres du système qui gère le reste du réseau tels que: recevoir un train d'un côté ou de l'autre, faire un sortir un train d'un côté ou de l'autre, retourner l'info s'il y a une place de libre.

Il est simple de parcourir le diagramme d'états pour retrouver les scénarios de fonctionnement et c'est ce que l'on ferait pour définir les cas test du système. Mais la synthèse du diagramme d'états à partir des scénarios est plus complexe. À défaut d'un outil, une méthode systématique applicable manuellement m'intéresserait déjà.

Qu'en pensez-vous ?

Bon début de semaine et meilleures salutations.

Marc-Henri

18
Vos projets / Bus I2C
« le: mai 12, 2015, 08:02:40 am »
Bonjour à tous,

Pour mon nouveau projet en N, j'aurai certainement plusieurs microcontrôleurs: gare cachée, gare principale, alimentations tractions. C'est avant tout pour disposer de plus de broches et aussi pour séparer les fonctionnalités.

Ce nouveau réseau étant petit (1.2 m * 0.75 m), les liaisons seront courtes. Pour cette raison, je me demande si le bus TWI (two wires interface = I2C) ne ferait pas l'affaire. Il est intégré à la plupart des microcontrôleurs Atmel. Peut-être ferait-il l'affaire pour ce réseau.

J'aimerais vous soumettre les réflexions / questions suivantes:
  • Le bus I2C n'a pas, contrairement au CAN, la notion de CRC en standard. Il serait opportun d'implanter CRC et quittance, même sur de courtes distances.
  • Quelle méthodologie employer pour mettre au point une application multi microcontrôleurs communiquant entre eux ? Linux dispose d'outils logiciels pour simuler un maître / esclave, mais avec quel hardware ? J'imagine que la même question se poserait pour le CAN !

Le site instructables.com mentionne que I2C se trouve dans les interfaces entre cartes graphiques et écrans, c'est le display data channel (http://www.instructables.com/id/Worlds-Cheapest-I2C-I-Squared-C-Adapter/?ALLSTEPS), peut-être une voie à suivre !

Qu'en pensez-vous ?

Meilleures salutations.

Marc-Henri

19
Bibliothèques / Sauvegarde de l'état en EEPROM
« le: avril 24, 2015, 08:16:25 am »
Bonjour à tous,

Pour un projet de commandes d'itinéraires en gare, je me suis trouvé confronté à la question de la sauvegarde de l'état des voies afin de la récupérer à la prochaine mise sous tension. J'ai mené les réflexions suivantes:

Sauvegarde de l'état en EEPROM avant la coupure de courant
Je n'ai pas assez d'expérience pour mettre en oeuvre un système qui détecte une baisse de la tension d'alimentation et déclenche la sauvegarde juste avant que l'alimentation ne soit coupée. Il faut probablement quelques composants supplémentaires autour de l'alimentation.

Sauvegarde de l'état en EEPROM lors de chaque changement
Pour mettre en oeuvre une telle solution, il faut tenir compte du fait que le nombre de cycles d'écritures des cellules mémoires de l'EEPROM est limité à environ 100'000 cycles. Heureusement, le nombre de lectures est illimité.

J'ai trouvé une note d'application d'Atmel (Cf. les 2 pièces jointes reprises du site d'Atmel) qui propose d'étendre cette limite en écrivant les données et les indices pour y accéder dans plusieurs cellules de mémoire. J'ai adapté ce concept à mes besoins et le fonctionnement est le suivant:

  • Il y a 2 buffers circulaires, l'un contenant les données et l'autre contenant les indices pour accéder à ces données.
  • Le buffer des indices a le même nombre d'éléments que le buffer de données, mais ils peuvent être de plus petite taille que le buffer de données.
  • Le buffer des indices permet de déterminer si un élément du buffer de données est libre ou occupé.
  • Les 2 buffers sont parcourus en même temps.
  • Le buffer des indices est initialement rempli avec des zéros. Cela se fait à l'aide d'un fichier .eep téléchargé dans le microcontrôleur via Avrdude.
  • Après écriture dans l'élément courant dans le buffer de données, l'indice est écrit à la même position dans le second buffer. Les indices sont incrémentés.
  • Pour déterminer quel élément est libre, on parcourt le buffer d'indices. Si l'élément courant contient un zéro, il est libre. Si la différence entre l'indice de l'élément courant et l'indice du précédent élément est plus grande que 1, utiliser cet élément.
  • Pour déterminer quel élément contient la dernière sauvegarde, on parcourt aussi le buffer d'indices. Si la différence entre l'indice de l'élément courant et l'indice du suivant est plus grande que 1, l'indice courant pointe vers la dernière sauvegarde.

J'ai commencé par écrire un programme de test sur mon PC. Je communiquerai la version pour AVR avec les accès effectifs à l'EEPROM prochainement.


//
//   TestBufferEeprom.c
//
//   Programme de test d'un buffer en EEPROM pour augmenter
//   le nombre de cycles d'écritures.
//
//   2013.09.17   MHP   Création.
//
//   Directives de compilation: PC ou AVR.
//

#ifdef PC
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#endif


#define   LONG_BUFFER   4
#define   INDICE_MAX   (2*LONG_BUFFER)
#define   VIDE   0xFF

uint16_t   aEtats[LONG_BUFFER];
uint8_t   aIndices[LONG_BUFFER];

static void Init(void)
{
uint8_t   i;

   for(i = 0; i < LONG_BUFFER; i++)
      aIndices[i] = VIDE;
} // Init


static void AfficherBuffer(void)
{
#ifdef PC
uint8_t i;

   printf("Après écriture\n");
   for(i = 0; i < LONG_BUFFER; i++)
      printf("aIndices[%d] = %d\t\taEtats[%d] = %d\n", i, aIndices[i], i, aEtats[i]);

   printf("\n");
#endif
} // AfficherBuffer


static uint8_t bVide(void)
{
uint8_t i;

   for(i = 0; i < LONG_BUFFER; i++)
   {
      if(aIndices[i] != VIDE)
         return(0);
   } // for

   return(1);
} // bVide


static uint8_t nTrouverPositionLecture(void)
{
uint8_t   i;

   #ifdef PC
   if(bVide())
   {
      printf("Vide, lecture impossible\n");
      exit(-1);
   } // if
   #endif

   i = 0;
   while(((aIndices[i] + 1) % INDICE_MAX) == aIndices[i+1])
      i++;

   return(i);
} // nTrouverPositionLecture


static uint8_t nTrouverPositionEcriture(void)
{
uint8_t i;

   if(!bVide())
   {
      i = nTrouverPositionLecture();
      return((i + 1) % LONG_BUFFER);
   }
   else
      return(0);
} // nTrouverPositionEcriture


static void EcrireEEPROM(uint16_t nVal)
{
uint8_t   i, j;

   i = nTrouverPositionEcriture();
   #ifdef PC
   printf("Ecriture de: %d en position: %d\n", nVal, i);
   #endif
   aEtats[i] = nVal;

   if(!bVide())
   {
      j = nTrouverPositionLecture();
      aIndices[i] = (aIndices[j] + 1) % INDICE_MAX;
   }
   else
      aIndices[i] = 0;

   AfficherBuffer();
} // EcrireEEPROM


static uint16_t nLireEEPROM(void)
{
uint8_t i;

   i = nTrouverPositionLecture();
   #ifdef PC
   printf("Position: %d, lecture: %d\n\n", i, aEtats[i]);
   #endif
   return(aEtats[i]);
} // nLireEEPROM


void main(void)
{
#ifdef PC
uint16_t nVal;

   Init();

   EcrireEEPROM(10);
   EcrireEEPROM(23);
   EcrireEEPROM(34);
   nVal = nLireEEPROM();
   EcrireEEPROM(5);
   EcrireEEPROM(30);
   nVal = nLireEEPROM();
   EcrireEEPROM(1013);
   nVal = nLireEEPROM();
   EcrireEEPROM(1012);
   EcrireEEPROM(255);
   nVal = nLireEEPROM();
   EcrireEEPROM(51);
   EcrireEEPROM(53);
   EcrireEEPROM(55);
   nVal = nLireEEPROM();
   EcrireEEPROM(125);
   nVal = nLireEEPROM();
   EcrireEEPROM(355);
   nVal = nLireEEPROM();
#endif
} // main

Le résultat de son exécution est:


Ecriture de: 10 en position: 0
Après écriture
aIndices[0] = 0      aEtats[0] = 10
aIndices[1] = 255      aEtats[1] = 0
aIndices[2] = 255      aEtats[2] = 0
aIndices[3] = 255      aEtats[3] = 0

Ecriture de: 23 en position: 1
Après écriture
aIndices[0] = 0      aEtats[0] = 10
aIndices[1] = 1      aEtats[1] = 23
aIndices[2] = 255      aEtats[2] = 0
aIndices[3] = 255      aEtats[3] = 0

Ecriture de: 34 en position: 2
Après écriture
aIndices[0] = 0      aEtats[0] = 10
aIndices[1] = 1      aEtats[1] = 23
aIndices[2] = 2      aEtats[2] = 34
aIndices[3] = 255      aEtats[3] = 0

Position: 2, lecture: 34

Ecriture de: 5 en position: 3
Après écriture
aIndices[0] = 0      aEtats[0] = 10
aIndices[1] = 1      aEtats[1] = 23
aIndices[2] = 2      aEtats[2] = 34
aIndices[3] = 3      aEtats[3] = 5

Ecriture de: 30 en position: 0
Après écriture
aIndices[0] = 4      aEtats[0] = 30
aIndices[1] = 1      aEtats[1] = 23
aIndices[2] = 2      aEtats[2] = 34
aIndices[3] = 3      aEtats[3] = 5

Position: 0, lecture: 30

Ecriture de: 1013 en position: 1
Après écriture
aIndices[0] = 4      aEtats[0] = 30
aIndices[1] = 5      aEtats[1] = 1013
aIndices[2] = 2      aEtats[2] = 34
aIndices[3] = 3      aEtats[3] = 5

Position: 1, lecture: 1013

Ecriture de: 1012 en position: 2
Après écriture
aIndices[0] = 4      aEtats[0] = 30
aIndices[1] = 5      aEtats[1] = 1013
aIndices[2] = 6      aEtats[2] = 1012
aIndices[3] = 3      aEtats[3] = 5

Ecriture de: 255 en position: 3
Après écriture
aIndices[0] = 4      aEtats[0] = 30
aIndices[1] = 5      aEtats[1] = 1013
aIndices[2] = 6      aEtats[2] = 1012
aIndices[3] = 7      aEtats[3] = 255

Position: 3, lecture: 255

Ecriture de: 51 en position: 0
Après écriture
aIndices[0] = 0      aEtats[0] = 51
aIndices[1] = 5      aEtats[1] = 1013
aIndices[2] = 6      aEtats[2] = 1012
aIndices[3] = 7      aEtats[3] = 255

Ecriture de: 53 en position: 1
Après écriture
aIndices[0] = 0      aEtats[0] = 51
aIndices[1] = 1      aEtats[1] = 53
aIndices[2] = 6      aEtats[2] = 1012
aIndices[3] = 7      aEtats[3] = 255

Ecriture de: 55 en position: 2
Après écriture
aIndices[0] = 0      aEtats[0] = 51
aIndices[1] = 1      aEtats[1] = 53
aIndices[2] = 2      aEtats[2] = 55
aIndices[3] = 7      aEtats[3] = 255

Position: 2, lecture: 55

Ecriture de: 125 en position: 3
Après écriture
aIndices[0] = 0      aEtats[0] = 51
aIndices[1] = 1      aEtats[1] = 53
aIndices[2] = 2      aEtats[2] = 55
aIndices[3] = 3      aEtats[3] = 125

Position: 3, lecture: 125

Ecriture de: 355 en position: 0
Après écriture
aIndices[0] = 4      aEtats[0] = 355
aIndices[1] = 1      aEtats[1] = 53
aIndices[2] = 2      aEtats[2] = 55
aIndices[3] = 3      aEtats[3] = 125

Position: 0, lecture: 355

Comme on écrit la même information plusieurs fois dans l'EEPROM, il faut la compacter au maximum. J'ai fait une estimation de la durée possible d'utilisation avec un tel système dans le cas de la gestion des itinéraires en gare et des buffers à 20 positions.

  • Nb. changements d'états par heure: 120. C'est réaliste car les changements d'états dépendent, dans cette application, uniquement des actions de l'utilisateur.
  • Utilisation du réseau: 2 heures par semaine -> 240 changements d'états par semaine -> 240 * 52 = 12'480 changements d'états par année.
  • Nb. cycles max = nb. d'entrées dans le buffer * nb. cycles max EEPROM = 20 * 100'000 = 2'000'000.
  • Nb. d'années d'exploitation = 2'000'000 / 12'480 = 160 années !!!

Pour la petite histoire, la limite du nombre maximal de cycles d'écritures en EEPROM s'appliquent aussi aux mémoires flash "disques" SSD qui équipent les derniers modèles de PC portables. Les techniques employées pour répartir les écritures sur plusieurs cellules sont certainement similaires.

20
Présentez vous ! / Bonjour de Savignyexpress
« le: avril 21, 2015, 11:54:24 am »
Bonjour à tous,

52 ans ingénieur informaticien avec une bonne expérience du C, même si mon activité professionnelle actuelle est orientée systèmes d'information médicaux.

Je ne pratique pas l'Arduino et je travaille directement avec les microcontrôleurs Atmega et Attiny pour des projets en modélisme ferroviaire. Il y a beaucoup de points communs entre l'Arduino et les Atmega / Attiny, donc aussi beaucoup d'opportunités d'échanges sur ce forum !

J'ai déjà réalisé plusieurs projets:
  • TCO de mon réseau N actuel avec un Attiny 2313.
  • Commande de PN avec un Attiny 2313.
  • Gestion d'itinéraires en gare avec un Atmega 8, des registres à décalage pour multiplexer la commande de 48 relais.
  • Gestion de gares cachées avec un Attiny 2313 (en cours).

Je vous renvoie vers mon blog ainsi que ma présentation sur le forum du N.

https://savignyexpress.wordpress.com/
http://le-forum-du-n.forumotions.net/t8114-reseau-epoque-iii-iv-savignyexpress

Au plaisir de partager nos expériences.
Meilleures salutations.

Pages: 1 [2]