Forums LR PRESSE

Où il est question de trains, petits et grands

  • Advertisement

BUS et TCO, économique et versatile

Toutes les discussions sur l'Arduino !

Modérateur: MOD

BUS et TCO, économique et versatile

Publié: Ven 09 Oct 2015, 12:03 
Après quelques pérégrinations autour de l'utilisation des servos pour la commande des aiguillages, passage à la pratique pour une première version d'un système de bus, qui pour mes applications se doit d'être versatile, simple, peu onéreux, fiable, et évolutif. Je sais, ça fait pompeux à première lecture ! Ca va faire deux ans que je me suis lancé dans un projet dont je n'avais, à l'époque, pas mesuré la réelle ampleur : la réalisation d'un réseau modulaire pour des applications éducative et pédagogiques. Bien que d'apparence ce réseau n'a à ce jour pas évolué depuis 10 mois, il n'en reste pas moins que je cogite, parcours les forums de long en large pour grappiller des idées, discute avec mes camarades de club, et tente de faire ce que j'aurais dû faire avant de me lancer dans l'aventure, à savoir un sans-blanc de cahier des charges technique...
Bref, le projet a bien muri, et les premiers prototypes fonctionnels ont vu le jour ces dernières semaines. J'avais il y a quelques temps publié autour de mon alimentation (encore en développement, mais fonctionnelle), et voici donc mes réflexions autour de la commandes des appareils de voie, de la signalisation et de la rétrosignalisation.

Après nombreux essais autour de l'I2C, du CAN, et même du réseau, je me suis arrêté sur beaucoup plus simple : le bus RS485. D'abord, c'est pas cher (quelques euros par noeud), c'est simple à déployer (seulement 2 fils, en paire torsadée), les modules sont en parallèle sur le bus, plusieurs récepteurs peuvent avoir la même adresse et c'est extrêmement versatile.

Et l'arduino dans tout ça ? Et bien... C'est qu'il y en a partout ! J'ai opté pour du pro-mini (suffisant pour les modules de commande et d'acquisition), peux gourmand en énergie, de faible encombrement et (one more time) très bon marché (3 à 4€).

Par exemple, la carte de commande pour 8 aiguillages (8 servos), incluant le buffer de bus, un dip switch de sélection d'adresse, un transistor FET de commande d'alimentation (j'y reviendrai), et les connecteurs revient à moins de 20€, et nécessite une grosse demi-heure de fabrication en mode proto sur plaque "veroboard"...

Une carte de détection d'occupation (8 cantons) revient elle aussi à un tarif sensiblement équivalent.

Pour finir, et avant d'aller plus loin, le TCO - en images :
Image

Vu de derrière :
Image
Le module principal - sur une base d'arduino mega - permet la commande et la programmation de tous les modules. Il peut être complété par des modules esclaves, proches ou éloignés, complémentaires ou répéteurs.

Et une fois sous tension :
Image

Pour terminer, le mode de programmation des butés :
Image

Voilà pour aujourd'hui (c'est juste histoire de se mettre en appétit)... Je reviens (vite j'espère) avec de plus amples détails pour ceux que ça pourrait intéresser...

Cordialement...
Dernière édition par Zebulon91 le Ven 09 Oct 2015, 20:58, édité 1 fois au total.
Zebulon91
Bavard
 
Messages: 83
Inscrit le: Dim 16 Mars 2014, 17:39
Localisation: Villebon sur Yvette (91)
Âge: 50
Echelle pratiquée: HO
Prénom: Michel
Club: AMF Villebon/Yvette

Re: BUS et TCO, économique et versatile

Publié: Ven 09 Oct 2015, 16:08 
Bonjour Zebulon91,

Belle réalisation et je ne doute pas que cela va en intéresser plus d'un.
On attend la suite avec impatience.

Christian
Avatar de l’utilisateur
Arduino
Prolixe
 
Messages: 1698
Inscrit le: Mer 25 Sep 2013, 16:14

Re: BUS et TCO, économique et versatile

Publié: Ven 09 Oct 2015, 18:28 
Oui, réellement bien réalisé.

Vivement la suite.

C'est l'idée que le me fait de mon prochain TCO.
Cordialement,

Christian.
Avatar de l’utilisateur
likiki
Causant
 
Messages: 270
Inscrit le: Dim 29 Avr 2012, 14:21
Localisation: Corbeil Essonne
Âge: 51
Echelle pratiquée: H0 3R
Prénom: Christian

Re: BUS et TCO, économique et versatile

Publié: Ven 09 Oct 2015, 21:54 
Bravo, joli montage. :applause: Comme quoi on peut faire plein de choses sans investir des centaines d'euros. :D

Pourrais-tu nous en dire un peu plus sur l'afficheur que tu as utilisé ?
notix
 
Messages: 31
Inscrit le: Lun 09 Mars 2015, 21:52
Echelle pratiquée: N

Re: BUS et TCO, économique et versatile

Publié: Ven 09 Oct 2015, 22:34 
Superbe. J'ai hâte de voir la suite. :applause: :applause:
Avatar de l’utilisateur
Trusty
Bavard
 
Messages: 64
Inscrit le: Lun 03 Déc 2012, 11:04
Localisation: Melun
Âge: 56
Echelle pratiquée: N
Prénom: Thierry

Re: BUS et TCO, économique et versatile

Publié: Sam 10 Oct 2015, 05:07 
Merci :applause:
@+
12035
Avatar de l’utilisateur
12035
Loquace
 
Messages: 1219
Inscrit le: Lun 08 Déc 2008, 13:20

Re: BUS et TCO, économique et versatile

Publié: Sam 10 Oct 2015, 09:11 
Merci de l'intérêt que vous portez à ce sujet.

Au sujet de l'afficheur, c'est un petit "oLed" de 0.96" sur bus I2C, du genre de celui-là : http://eud.dx.com/product/0-96-oled-hig ... hjFx7TtlBc . Il est très simple à utiliser en utilisant les librairies d'adafruit. Mais il est fort probable que ce ne soit pas mon choix définitif pour la version finale, de par sa petite taille, et nos yeux vieillissants, la lecture n'est pas très aisée (malgré une belle définition et une très bonne qualité d'affichage). Dans la mesure où je souhaite ne mettre qu'un seul écran, je vais m'orienter vers quelque chose de plus grand, en couleur et sans doute tactile (je dispose de quelques pièces en 2,3" et 3,2" pour tester).

Je termine la validation des schémas, et reviens rapidement vous donner la suite !
A très vite.
Zebulon91
Bavard
 
Messages: 83
Inscrit le: Dim 16 Mars 2014, 17:39
Localisation: Villebon sur Yvette (91)
Âge: 50
Echelle pratiquée: HO
Prénom: Michel
Club: AMF Villebon/Yvette

Re: BUS et TCO, économique et versatile

Publié: Sam 10 Oct 2015, 22:12 
En attendant des plans et des sources... Voici des images de quelques modules :

La commande de servo (aiguillages, dételeurs, etc...) (8 à 12€) :
La carte permet de controler 8 servos, mémorise les positions min et max.

Image
Les switches permettent une sélection d'adresse facile.

et vu de dessous :
Image
Le câblage reste très simple... C'était le but !

Une autre version, avec en plus 16 entrées/sorties (via PCF8574 - I2C) (10 à 15€).

Image
Il s'agit en fait de la toute première version. Elle ne dispose pas du transistor de commande d'alimentation des servos, qui a été ajouté pour éviter un mouvement intempestif de ceux-ci à la mise sous tension.

... A suivre !
Dernière édition par Zebulon91 le Lun 12 Oct 2015, 10:07, édité 1 fois au total.
Zebulon91
Bavard
 
Messages: 83
Inscrit le: Dim 16 Mars 2014, 17:39
Localisation: Villebon sur Yvette (91)
Âge: 50
Echelle pratiquée: HO
Prénom: Michel
Club: AMF Villebon/Yvette

Re: BUS et TCO, économique et versatile

Publié: Dim 11 Oct 2015, 07:59 
Haaaaa, voilà quelque chose que j'adore.

Du montage réalisable par TOUS. :applause:

Utilisation de composants classique et d'une plaque que l'on trouve dans le commerce (et pas sérigraphié maison) puisque tout le monde n'est pas équipé du matériel nécessaire a sa fabrication. :siffle:

Les seuls outils nécessaires, un fer a souder, une pince coupante et un lame de scie a métaux. :D

Vivement la suite.
Cordialement,

Christian.
Avatar de l’utilisateur
likiki
Causant
 
Messages: 270
Inscrit le: Dim 29 Avr 2012, 14:21
Localisation: Corbeil Essonne
Âge: 51
Echelle pratiquée: H0 3R
Prénom: Christian

Re: BUS et TCO, économique et versatile

Publié: Dim 11 Oct 2015, 08:36 
Si tu veux poursuivre avec le pilotage des signaux lumineux, voilà sur quoi je travaille :

viewtopic.php?f=63&t=78559

Ça n'a pas beaucoup avancé depuis, mais je vais tâcher de m'y remettre pour finaliser un module commandé par un bus RS485 (chois pour les mêmes critères que toi). Le code est prêt, il faut que je fasse un montage de test et que je revois le module pour envoyer les commandes au module pilotant les signaux.
notix
 
Messages: 31
Inscrit le: Lun 09 Mars 2015, 21:52
Echelle pratiquée: N

Re: BUS et TCO, économique et versatile

Publié: Lun 12 Oct 2015, 09:47 
notix a écrit:Si tu veux poursuivre avec le pilotage des signaux lumineux, voilà sur quoi je travaille :

viewtopic.php?f=63&t=78559

Ça n'a pas beaucoup avancé depuis, mais je vais tâcher de m'y remettre pour finaliser un module commandé par un bus RS485 (chois pour les mêmes critères que toi). Le code est prêt, il faut que je fasse un montage de test et que je revois le module pour envoyer les commandes au module pilotant les signaux.


;) j'avais bien vu ton post en son temps ! Je regarde avec attention et intérêt ce genre de développement, afin d'y grappiller quelques bonnes idées ;) :) Pour le moment, la signalisation pour moi est assez limitée, mais j'avoue être tenté pour aller plus loin ! Je me permettrai certainement de revenir vers toi !
Zebulon91
Bavard
 
Messages: 83
Inscrit le: Dim 16 Mars 2014, 17:39
Localisation: Villebon sur Yvette (91)
Âge: 50
Echelle pratiquée: HO
Prénom: Michel
Club: AMF Villebon/Yvette

Re: BUS et TCO, économique et versatile

Publié: Lun 12 Oct 2015, 09:56 
likiki a écrit:Haaaaa, voilà quelque chose que j'adore.

Du montage réalisable par TOUS. :applause:

Utilisation de composants classique et d'une plaque que l'on trouve dans le commerce (et pas sérigraphié maison) puisque tout le monde n'est pas équipé du matériel nécessaire a sa fabrication. :siffle:

Les seuls outils nécessaires, un fer a souder, une pince coupante et un lame de scie a métaux. :D

Vivement la suite.


Effectivement, je suis assez accroc à la plaque à bande et aux composants basiques. C'est généralement bien suffisant pour ce qu'on en fait. Même si j'aimerai bien faire quelques modules en version circuit gravé, je n'ai pour le moment ni le courage, ni le temps de m'y consacrer.
Dans la liste des outils, j'ajouterais un bon foret métal de 6 ou 8mm pour fraiser les coupures de bande ;) Sinon, la plaque utilisée pour les petits modules a déjà les bandes segmentées par groupe de 3 pas... (Dispo ici : http://www.ebay.fr/itm/922D-plaque-dess ... 1493686293 )
Zebulon91
Bavard
 
Messages: 83
Inscrit le: Dim 16 Mars 2014, 17:39
Localisation: Villebon sur Yvette (91)
Âge: 50
Echelle pratiquée: HO
Prénom: Michel
Club: AMF Villebon/Yvette

Re: BUS et TCO, économique et versatile

Publié: Lun 12 Oct 2015, 21:15 
Bravo pour ce nouveau projet, je me joints à la communauté pour les compliments et j'attends avec impatience la suite. Surtout au niveau du bus de transmission qui a l'air tout simple ( nous avons plein de projets en attente au club qui n'attendent que le bus !!). :applause:
Choisir, c'est déjà renoncer!
Petitrain
Bavard
 
Messages: 57
Inscrit le: Ven 04 Juil 2014, 11:09
Localisation: Haut-Var
Âge: 67
Echelle pratiquée: HO
Prénom: Gérard
Club: CMMF Mouans-Sartout

Re: BUS et TCO, économique et versatile

Publié: Dim 25 Oct 2015, 10:41 
Voici donc, pour commencer, le module de commande des servos pour les aiguillages, dételeurs, et autre fonctions compatibles avec un servo.

Image

Basé sur un Arduino Pro/Mini 5V, choisi pour sa petite taille et son prix dérisoire, le module comporte également un contrôleur de bus (75176 ou equivalent), un transistor de commande de l'alimentation des servos, et un dip switch (optionnel) permettant la sélection de l'adresse de la carte (de 32 à 40) sans être obligé de flasher un nouveau programme.

L'ensemble de ces composant peut être assemblé, comme sur mes photos sur une petite plaque de vero-board, le nombre de liaisons étant assez limité.

Le code :
Code: Tout sélectionner
/***********************************************************************
*

* MP_Receiver
* RS485 Bus receiver for servo and digital I/O
*
* Version 1.0
*    - initial release
*   
* Version 1.1
*    - Address selection by switches.
*    - Delayed startup
*
* (c)2015 M.BO
*
*
***********************************************************************/

#include <SoftwareSerial.h>
#include <VarSpeedServo.h>
#include <EEPROM.h>
#include <ICSC_Soft.h>

//#define _DEBUG_

#define ADDR_SAVED        16
#define ADDR_ADDR         17
#define ADDR_BLOCK1       18

#define CONFIG_SAVED      69 // Value

#define AUTOSAVE_INTERVAL 30000    // 30 seconds

#define VERSION           110
#define MAX_SERVO           8
#define MAX_INPUT           0
#define MAX_OUTPUT          0

/*-----( Declare Constants and Pin Numbers )-----*/
#define SSerialRX         11  //Serial Receive pin
#define SSerialTX         10  //Serial Transmit pin
#define SSerialTxControl  12  //RS485 Direction control

#define RS485Transmit     HIGH
#define RS485Receive      LOW
#define BUS_BAUD          57600

#define ADDR0             A3
#define ADDR1             A2
#define ADDR2             A1
#define EEPROM_RESET      A6

#define POWER_PIN         A0

#define Pin13LED          13
#define MASTER_ADDRESS    100
#define SLAVE_ADDRESS     32

#define SERVO_PIN           2
#define SERVO_DEFAULT_MIN  70
#define SERVO_DEFAULT_MAX 110
#define SERVO_CENTER       90
#define DEFAULT_SPEED      30
#define FULL_SPEED         0

#define MOVE_START          1
#define MOVE_STOP           0

struct tCONFIG {
  int version;
  byte address;
  byte servo;
  byte output;
  byte input;
};

struct tSERVO {
  byte id;
  byte pin;
  byte posMin;
  byte posMax;
  byte speed;
  byte state;
  byte settingFlags; // 0=Reverse
};

struct tMOVE {
  byte id;
  byte requestedBy;
  byte state;
  byte pos;
};

struct tSPOS {
  byte id    : 8;
  bool state : 1;
};

tSERVO servoMem[MAX_SERVO];
VarSpeedServo servo[MAX_SERVO];
SoftwareSerial RS485Serial(SSerialRX, SSerialTX); // RX, TX

int byteReceived;
int byteSend;
byte myAddress = SLAVE_ADDRESS;

byte needUpdateServo = 0;
bool needEepromStore = false;
byte lastPos[6];

bool autoDetach = false;
bool blindMove = false;

void setup() {
  unsigned int address;

  #if defined _DEBUG_ 
    Serial.begin(115200);
    Serial.println("RS485 Receiver V1.1 (debug ready): ");
  #endif

  pinMode(POWER_PIN,OUTPUT);
  digitalWrite(POWER_PIN,LOW);
 
  // Address decoder
  pinMode(ADDR0,INPUT);
  pinMode(ADDR1,INPUT);
  pinMode(ADDR2,INPUT);
  pinMode(EEPROM_RESET,INPUT);
  digitalWrite(ADDR0,HIGH);
  digitalWrite(ADDR1,HIGH);
  digitalWrite(ADDR2,HIGH);
  digitalWrite(EEPROM_RESET,HIGH);

  pinMode(Pin13LED, OUTPUT);   
  pinMode(SSerialTxControl, OUTPUT);   
  digitalWrite(SSerialTxControl, RS485Receive);  // Init Transceiver   

  delay(10);
 
  myAddress = (!digitalRead(ADDR0)?1:0)
            + (!digitalRead(ADDR1)?2:0)
            + (!digitalRead(ADDR2)?4:0)
            + 32;
  #if defined _DEBUG_
    Serial.print("Address = ");
    Serial.println(myAddress);
  #endif

  // Load saved config if exists

  if ((EEPROM.read(ADDR_SAVED) == CONFIG_SAVED) /*&& (digitalRead(EEPROM_RESET)==1)*/ ) {

    #if defined _DEBUG_
      Serial.println("Restore saved settings");
    #endif

    //myAddress = EEPROM.read(ADDR_ADDR);
    for (unsigned int t=0; t<sizeof(servoMem); t++)
      *((char*)&servoMem + t) = EEPROM.read(ADDR_BLOCK1 + t);

    #if defined _DEBUG_
      for (byte i=0; i<MAX_SERVO; i++) {
        Serial.print("Servo # ");
        Serial.println(i);
        Serial.print("  Min=");
        Serial.print(servoMem[i].posMin);
        Serial.print(" / Max=");
        Serial.print(servoMem[i].posMax);
        Serial.println("");
      }
    #endif

  } else {
    if (digitalRead(EEPROM_RESET)==0) {
      Serial.println("Reset eeprom");
    } else {
      Serial.println("Initialise default Values (EEPROM Empty)");
    }
    for (byte i=0; i<MAX_SERVO; i++) {
      servoMem[i].id = i+1;
      servoMem[i].pin = SERVO_PIN + i;
      servoMem[i].posMin = SERVO_DEFAULT_MIN;
      servoMem[i].posMax = SERVO_DEFAULT_MAX;
      servoMem[i].speed = DEFAULT_SPEED;
      servoMem[i].state = 2;
    }
  }

  delay(500 * (myAddress-32)); // Startup delay to prevent collisions
 
    // Start bus
  ICSC.begin(myAddress, BUS_BAUD, &RS485Serial, SSerialTxControl);
 
  // Register callbacks
  ICSC.registerCommand(ICSC_SYS_PONG, &pinger);
  ICSC.registerCommand('Z', &getConfig);
  ICSC.registerCommand('A', &pinger);
  ICSC.registerCommand('P', &setOutputs);
  ICSC.registerCommand('T', &setOutput);
  ICSC.registerCommand('S', &setMinMax);
  ICSC.registerCommand('s', &getServoSettings);
  ICSC.registerCommand('?', &dumpState);
  ICSC.registerCommand('D', &dumpServoConfig); // Dump servo config

  // Initialize servo outputs
  blindMove = true;
  digitalWrite(13,HIGH);
  autoDetach = false;
  for (byte i=0; i<MAX_SERVO; i++) {
    setServoPos(i, (servoMem[i].state==1)?servoMem[i].posMax:servoMem[i].posMin, FULL_SPEED);
  }
  digitalWrite(POWER_PIN,HIGH);
  blindMove = false;
  delay(200);
  autoDetach = true;
  for (byte i=0; i<MAX_SERVO; i++) {
    setServoPos(i, (servoMem[i].state==1)?servoMem[i].posMax:servoMem[i].posMin, FULL_SPEED);
  }
  digitalWrite(13,LOW);
 
  sendConfig(MASTER_ADDRESS);
 
  // All done !
}

void eepromStore() {
  unsigned int address;
  static unsigned long lastTime=0;

  if ( (millis()-lastTime>AUTOSAVE_INTERVAL) || needEepromStore) {

    #if defined _DEBUG_
      Serial.println("EEPROM store settings");
    #endif 

    for (unsigned int t=0; t<sizeof(servoMem); t++) {
      #if defined _DEBUG_ 
        if (t>0) Serial.print(",");
        Serial.print( *((char*)&servoMem + t), DEC );
      #endif
      EEPROM.update(ADDR_BLOCK1 + t, *((char*)&servoMem + t) );
    }
   
    #if defined _DEBUG_
      Serial.println();
    #endif
    EEPROM.update(ADDR_ADDR,myAddress);
    EEPROM.update(ADDR_SAVED,CONFIG_SAVED);
    lastTime = millis();
    needEepromStore = false;
  }
}


/**************************************************************************

  BUS Command '@'
  Get configuration

**************************************************************************/
void getConfig(unsigned char src, char command, unsigned char len, char *data)
{
  #if defined _DEBUG_
    Serial.println("Receive config request");
  #endif
  sendConfig(src);
}

void sendConfig(unsigned char target)
{
  tCONFIG conf;
  digitalWrite(Pin13LED,HIGH);
  #if defined _DEBUG_
    Serial.println("Send config");
  #endif
 
  conf.version = VERSION;
  conf.address = myAddress;
  conf.servo = MAX_SERVO;
  conf.input = MAX_INPUT;
  conf.output = MAX_OUTPUT;
  delay(100);
  ICSC.send(target, 'Z', sizeof(conf), (char *)&conf);
  digitalWrite(Pin13LED,LOW); 
}

/**************************************************************************

  receiving a Pong
 
**************************************************************************/
void pinger(unsigned char src, char command, unsigned char len, char *data)
{
  #if defined _DEBUG_
    Serial.print("Ping reply: (");
    Serial.print(src,DEC);
    Serial.print(") ");
    for (byte i=0;i<len;i++) {
      Serial.print(data[i]);
    }
    Serial.println(); 
  #endif
}

/**************************************************************************

  BUS Command 'm'
  Send moving state

**************************************************************************/
void sendMoveState(byte source, byte id, byte moveState) {
  if (!blindMove) {
    digitalWrite(Pin13LED,HIGH);
    tMOVE mBuffer;
    mBuffer.id = id;
    mBuffer.requestedBy = source;
    mBuffer.state = moveState;
    mBuffer.pos = servoMem[id].state;
    ICSC.broadcast('m', sizeof(mBuffer), (char *)&mBuffer);
    digitalWrite(Pin13LED,LOW);
  }
}

/**************************************************************************

  BUS Command 'P'
  Set position state of a servo output

**************************************************************************/
void setOutputs(unsigned char src, char command, unsigned char len, char *data)
{
  byte i;
  digitalWrite(Pin13LED,HIGH); 
  #if defined _DEBUG_
    Serial.print("Set output (");
    Serial.println(")");
  #endif
 
  if (len==6) {
    for (i=0; i<6; i++) {
      if (servoMem[i].state != data[i]) {   
        setServoPos(i, (data[i]==1)?servoMem[i].posMax:servoMem[i].posMin, servoMem[i].speed);
        servoMem[i].state=data[i];
        lastPos[i]=data[i];
      }
    }   
  }
  digitalWrite(Pin13LED,LOW);
}

/**************************************************************************

  BUS Command 'T'
  Set position state of a single servo output

**************************************************************************/
void setOutput(unsigned char src, char command, unsigned char len, char *data)
{
  byte i;
  tSPOS in;
  digitalWrite(Pin13LED,HIGH);
  memcpy(&in, data, sizeof(in));
 
  #if defined _DEBUG_
    Serial.print("Set single output #");
    Serial.print(in.id);
    Serial.print(" to ");
    Serial.println(in.state);
  #endif

  setServoPos(in.id-1, (in.state==1)?servoMem[in.id-1].posMax:servoMem[in.id-1].posMin, servoMem[in.id-1].speed);
  servoMem[in.id-1].state = in.state;
  digitalWrite(Pin13LED,LOW);
}

/*************************************************************************

  BUS Command 'S'
  Set MIN and/or MAX position for an output.

*************************************************************************/
void setMinMax(unsigned char src, char command, unsigned char len, char *data)
{
  byte i[3];
  byte id;
  digitalWrite(Pin13LED,HIGH);
   
  memcpy(&i, data, sizeof(i));
 
  #if defined _DEBUG_
    Serial.print("Set servo setings #");
    Serial.print(i[0],DEC);
    Serial.print(" / ");
    Serial.print(i[1],DEC);
    Serial.print(" / ");
    Serial.println(i[2],DEC);
  #endif
 
  id = i[0] - 1;
  if (i[1]) {
    servoMem[id].posMax = i[2];
  } else {
    servoMem[id].posMin = i[2];
  }
  needUpdateServo = i[0];
  needEepromStore = true;
  digitalWrite(Pin13LED,LOW);
}


/**************************************************************************
 
  Update servo position

**************************************************************************/
void updateServo() {
  static unsigned long lastTime = 0;
  byte id, idStart, idStop;
 
  if (needUpdateServo>0 && needUpdateServo<=MAX_SERVO) {
    idStart = needUpdateServo-1; 
    idStop = idStart;
  } else if (needUpdateServo==255){
    idStart = 0;
    idStop = MAX_SERVO-1;
  }
  if (needUpdateServo>0) {
    if (millis()-lastTime>500) {
      for (id=idStart; id<=idStop; id++) {
        setServoPos(id, (servoMem[id].state==1)?servoMem[id].posMax:servoMem[id].posMin, FULL_SPEED);
      }
      lastTime = millis();
      needUpdateServo=0;
    }
  }
}

/**************************************************************************
 
  Send pulse to a servo

**************************************************************************/
void setServoPos(byte id, byte pos, byte speed){
  sendMoveState(0, id, MOVE_START);
  if (!servo[id].attached()) {
    servo[id].attach(servoMem[id].pin);
    delay(10);
  }
  servo[id].write( (pos<=180)?pos:180, speed, true );
  delay(50);
  if (autoDetach) {
    servo[id].detach();
    delay(10);
    digitalWrite(servoMem[id].pin,HIGH); // Prevent noisy lines !!
  }
  sendMoveState(0, id, MOVE_STOP);
}

/**************************************************************************
 
  BUS Command 's'
  Get MIN and/or MAX position for an output.

**************************************************************************/
void getServoSettings(unsigned char src, char command, unsigned char len, char *data)
{
  byte i;
  memcpy(&i, data, sizeof(i));
 
  #if defined _DEBUG_
    Serial.print("Get servo setings #");
    Serial.println(i,DEC);
  #endif
 
  delay(20);
  digitalWrite(Pin13LED,HIGH);
  ICSC.send(src, 's', sizeof(servoMem[i-1]), (char *)&servoMem[i-1]);
  digitalWrite(Pin13LED,LOW);
}

/**************************************************************************

  BUS Command '?'
  Dump all output states
 
**************************************************************************/
void dumpState(unsigned char src, char command, unsigned char len, char *data)
{
  byte i = 0;
  byte dump[MAX_SERVO];
 
  #if defined _DEBUG_
    Serial.println("Dump State.");
  #endif
 
  for (i=0; i<MAX_SERVO;i++) {
    dump[i] = servoMem[i].state;
  }
  delay(25);
  digitalWrite(Pin13LED,HIGH);
  ICSC.send(src, '!', sizeof(dump), (char *)&dump);
  digitalWrite(Pin13LED,LOW);
}

/**************************************************************************

  BUS Command 'D'
  Dump all servos config
 
**************************************************************************/
void dumpServoConfig(unsigned char src, char command, unsigned char len, char *data) {
  #if defined _DEBUG_
    Serial.println("Dump config.");
  #endif 
  for (byte i=0; i<MAX_SERVO; i++) {
    delay(25);
    digitalWrite(Pin13LED,HIGH);
    ICSC.send(src, 'D', sizeof(tSERVO), (char *)&servoMem[i]);
    digitalWrite(Pin13LED,LOW);
  }
}


/**************************************************************************

  MAIN LOOP
 
**************************************************************************/
void loop() {
  static long lastTime=0;
 
  if (millis() > lastTime+1000) {
    ICSC.send(MASTER_ADDRESS, ICSC_SYS_PING, 5, "PING");
    lastTime = millis();
  }

  ICSC.process();
 
  updateServo();
 
  eepromStore();
 
}


Désolé pour le peu de commentaire, mais globalement, je pense que c'est assez basique. J'utilise pour le bus la librairie ICSC, disponible ici :
http://sourceforge.net/projects/arduino-icsc/
Cette dernière, dans sa version d'origine ne permet d'utiliser que le port série physique, il m'a fallu l'adapter une peu pour pouvoir laisser ce port libre et utiliser un port série émulé par la lib SoftSerial.
Les sources de cette version modifiée sont ici (à copier dans le dossier Librairies du dossier arduino) : https://dl.dropboxusercontent.com/u/818 ... C_Soft.zip
pour la commande des servos, j'ai opté pour la librairie VarSpeedServo disponible ici : https://github.com/netlabtoolkit/VarSpeedServo
Cette dernière permet de gérer simplement la vitesse de mouvement des servos.

Pour le reste, c'est classique, et je reste à l'écoute de toutes questions...
Zebulon91
Bavard
 
Messages: 83
Inscrit le: Dim 16 Mars 2014, 17:39
Localisation: Villebon sur Yvette (91)
Âge: 50
Echelle pratiquée: HO
Prénom: Michel
Club: AMF Villebon/Yvette

Re: BUS et TCO, économique et versatile

Publié: Dim 25 Oct 2015, 17:58 
Bonjour,
Pour le protocole de mon bus RS-485, j'étais parti sur une librairie nommée "modbusrtu" que j'ai également modifié pour utiliser un port série "logiciel". Mais tout compte fais je trouve la libraire ICSC plus simple à utiliser. Je voudrais donc, si tu le permets, réutiliser ton code modifié avec un port série "logiciel". L'avantage que je vois dans le port série "logiciel" est de pouvoir en paramétrer plusieurs sur le module maître et ainsi de dépasser la limite de 32 modules esclaves. Etait-ce aussi ton idée ?

A propos de ICSC, à quoi sert la fonction "pinger" ?

Par contre pour le paramétrage de l'adresse du module esclave, je vais rester sur un flashage de l'EEPROM. Tu ne penses pas que la possibilité d'utiliser uniquement 8 adresses ne va te limiter à long terme ?
notix
 
Messages: 31
Inscrit le: Lun 09 Mars 2015, 21:52
Echelle pratiquée: N

Suivant

Retour vers Arduino

Qui est en ligne ?

Utilisateur(s) parcourant actuellement ce forum : Aucun utilisateur inscrit et 1 invité