1/160 - Echelle N

Le Forum consacré à l'Echelle N
 
AccueilAccueil  PortailPortail  ÉvènementsÉvènements  Dernières imagesDernières images  S'enregistrerS'enregistrer  Connexion  
N'hésitez pas à consulter le calendrier et les événements du forum pour voir les manifestations près de chez vous !
Le deal à ne pas rater :
Cdiscount : -30€ dès 300€ d’achat sur une sélection Apple
Voir le deal

 

 Les expérimentations de Sierramike

Aller en bas 
2 participants
AuteurMessage
sierramike
Membre
Membre
sierramike


Masculin Age : 44
Localisation : 67000 STRASBOURG
Nombre de messages : 4563
Date d'inscription : 29/10/2015

Les expérimentations de Sierramike Empty
MessageSujet: Les expérimentations de Sierramike   Les expérimentations de Sierramike Icon_minitimeSam 23 Juil 2016 - 0:43

Bonjour à tous,

Pour ne pas polluer le post de mon réseau, ni celui de iChooChoo, j'ai choisi d'ouvrir un nouveau post dans lequel je publierai mes diverses expérimentations, n'hésitez pas à poser des questions !

En général, tout part de tutos trouvés sur Internet au sujet d'un composant particulier, que je modifie ensuite pour l'adapter à mes besoins ou simplement universaliser le résultat.

Mes petites expérimentations du jour : Arduino + Module ultra-sons HC-SR04 pour détecter le passage d'un train.



Ce module effectue une mesure de distance lorsqu'il reçoit une impulsion d'au moins 10 microsecondes sur sa broche "trigger". Le système est programmé pour effectuer les mesures sur les deux modules l'un après l'autre. La distance détectée est alors inscrite sur l'afficheur LCD. Le système effectue une mesure toutes les 250 millisecondes (4 mesures par seconde).
Revenir en haut Aller en bas
sierramike
Membre
Membre
sierramike


Masculin Age : 44
Localisation : 67000 STRASBOURG
Nombre de messages : 4563
Date d'inscription : 29/10/2015

Les expérimentations de Sierramike Empty
MessageSujet: Re: Les expérimentations de Sierramike   Les expérimentations de Sierramike Icon_minitimeSam 23 Juil 2016 - 22:19

Suite des expérimentations : un module de traction automatique en analogique en utilisant la PWM.



Le sketch Arduino est conçu pour :
1) Surveiller la pression des 3 boutons Drive, Stop, Reverse
2) Configurer la FAST PWM sur la broche 9
3) Définir les vitesses de démarrage, maxi (dans chaque sens), arrêt
4) Ne pas autoriser de manoeuvre interdite (inversion de sens avant l'arrêt)

Dans un deuxième temps, le circuit de détection par ultra-son est programmé pour une sortie bas niveau (LED éteinte) en cas de détection. Cette sortie est simplement raccordée à l'entrée du bouton STOP. De cette manière, la détection du train par le module à ultra-sons va commander l'arrêt du train.

Le module de puissance LMD18200 est utilisé comme booster PWM. L'entrée PWM est raccordée à la sortie Digital 9 de l'Arduino, afin d'amplifier le signal PWM produit par l'Arduino. L'entrée "DIR" du module est connectée à la sortie Digital 7 de l'Arduino (choix arbitraire). Cette entrée permet de choisir la polarité du courant de sortie, donc le sens de circulation.

Sketch Arduino :
Code:
#define SPD_START 120  // Speed value when starting acceleration
#define SPD_STOP  0    // Speed value when ending deceleration
#define DUR_ACC   2000 // Acceleration speed (duration from START to MAX)
#define DUR_DEC   2000 // Deceleration speed (duration from actual to STOP)
#define SPD_MAX_D 200  // Maximum speed value in Drive direction
#define SPD_MAX_R 150  // Maximum speed value in Reverse direction

#define PIN_PWM 9   // Pin connected to PWM input of LMD18200 module
#define PIN_DIR 7   // Pin connected to Direction input of LMD18200 module

#define PIN_BTN_D 2 // Pin connected to "DRIVE" button (short to ground)
#define PIN_BTN_S 3 // Pin connected to "STOP" button (short to ground)
#define PIN_BTN_R 4 // Pin connected to "REVERSE" button (short to ground)

int _iActiveSpeed = 0;  // Stores actual speed
int _iTargetSpeed = 0;  // Stores speed to be reached at end of acceleration/deceleration
char _cStatus = '0';    // '0' = Steady, 'A' = Accelerate, 'D' = Decelerate
char _cDirection = 'S'; // 'S' = Stop, 'D' = Drive, 'R' = Reverse
long _lInterval = 0;    // Interval duration in milliseconds (between each increment/decrement)

void setup() {
  Serial.begin(115200);
  
  pinMode(PIN_PWM, OUTPUT);
  pinMode(PIN_DIR, OUTPUT);
  // Activate internal pullup resistors on buttons pins
  pinMode(PIN_BTN_D, INPUT_PULLUP);
  pinMode(PIN_BTN_S, INPUT_PULLUP);
  pinMode(PIN_BTN_R, INPUT_PULLUP);

  // Set fast PWM
  TCCR1B = TCCR1B & 0b11111000 | 1;

  Serial.println("Ready");
}

void loop()
{
  // Following tests prevent being able to change direction if engine is still running
  
  // If button "STOP" pressed, and status is NOT "Decelerate" and direction is NOT "STOP"
  if (digitalRead(PIN_BTN_S) == LOW)
  {
    delay(10);
    if (digitalRead(PIN_BTN_S) == LOW)
      if (_cStatus != 'D' && _cDirection != 'S')
        Stop();
  }
  // If button "DRIVE" pressed, and direction is "STOP"
  else if (digitalRead(PIN_BTN_D) == LOW)
  {
    delay(10);
    if (digitalRead(PIN_BTN_D) == LOW)
      if (_cDirection == 'S')
        Drive();
  }
  // If button "REVERSE" is pressed, and direction is "STOP"
  else if (digitalRead(PIN_BTN_R) == LOW)
  {
    delay(10);
    if (digitalRead(PIN_BTN_R) == LOW)
      if (_cDirection == 'S')
        Reverse();
  }

  // Update speed value on each loop
  Update();
}

long _lOldTimeStamp = 0;

void Update()
{
  long l = millis();
  // If interval length has been reached
  if (l > _lOldTimeStamp + _lInterval)
  {
    // Increment of decrement actual speed depending of status
    if (_cStatus == 'A')
    {
      _iActiveSpeed++;
      Serial.println(_iActiveSpeed);
    }
    else if (_cStatus == 'D')
    {
      _iActiveSpeed--;
      Serial.println(_iActiveSpeed);
    }

    // If target speed is reached, stop acceleration or deceleration
    if (_iActiveSpeed == _iTargetSpeed)
    {
      _lInterval = 0;
      _cStatus = '0';
      // If stop speed is reached, set full stop
      if (_iActiveSpeed == SPD_STOP)
      {
        _iActiveSpeed = 0;
        _cDirection = 'S';
      }
    }
    
    _lOldTimeStamp = l;
  }

  // Update output pins
  if (_cDirection == 'D')
    digitalWrite(PIN_DIR, HIGH);
  else if (_cDirection == 'R')
    digitalWrite(PIN_DIR, LOW);

  analogWrite(PIN_PWM, _iActiveSpeed);
}

// Start deceleration
void Stop()
{
  Serial.println("Stop");
  _iTargetSpeed = SPD_STOP;
  int iSteps = _iActiveSpeed - _iTargetSpeed;
  _lInterval = DUR_DEC / iSteps;
  _cStatus = 'D';
}

// Start acceleration in Drive direction
void Drive()
{
  Serial.println("Drive");
  _iTargetSpeed = SPD_MAX_D;
  int iSteps = _iTargetSpeed - _iActiveSpeed;
  _lInterval = DUR_ACC / iSteps;
  _cStatus = 'A';
  _cDirection = 'D';
}

// Start deceleration in Reverse direction
void Reverse()
{
  Serial.println("Reverse");
  _iTargetSpeed = SPD_MAX_R;
  int iSteps = _iTargetSpeed - _iActiveSpeed;
  _lInterval = DUR_ACC / iSteps;
  _cStatus = 'A';
  _cDirection = 'R';
}


Dernière édition par sierramike le Sam 23 Juil 2016 - 22:40, édité 1 fois
Revenir en haut Aller en bas
sierramike
Membre
Membre
sierramike


Masculin Age : 44
Localisation : 67000 STRASBOURG
Nombre de messages : 4563
Date d'inscription : 29/10/2015

Les expérimentations de Sierramike Empty
MessageSujet: Re: Les expérimentations de Sierramike   Les expérimentations de Sierramike Icon_minitimeSam 23 Juil 2016 - 22:21

Expérimentation suivante, très simple, la mise en oeuvre de la librairie CmdrArduino pour la génération d'un signal DCC, en application de l'excellent article sur Locoduino : http://www.locoduino.org/spip.php?article17

Revenir en haut Aller en bas
SavignyExpress
Membre
Membre
SavignyExpress


Masculin Age : 61
Localisation : yyy
Nombre de messages : 2032
Date d'inscription : 10/10/2010

Les expérimentations de Sierramike Empty
MessageSujet: Re: Les expérimentations de Sierramike   Les expérimentations de Sierramike Icon_minitimeDim 24 Juil 2016 - 11:28

Bonjour Sierramike,

C'est sympa de partager tes expérimentations avec nous.

Prévois-tu de poster les schémas ?

Tout bon dimanche et bel été.
Revenir en haut Aller en bas
sierramike
Membre
Membre
sierramike


Masculin Age : 44
Localisation : 67000 STRASBOURG
Nombre de messages : 4563
Date d'inscription : 29/10/2015

Les expérimentations de Sierramike Empty
MessageSujet: Re: Les expérimentations de Sierramike   Les expérimentations de Sierramike Icon_minitimeLun 31 Oct 2016 - 0:55

Je vais essayer d'utiliser Fritzing pour faire un petit Schéma.

En attendant, l'expérimentation de ce soir, le pilotage de la plaque tournante Fleischmann, qui n'est pas un réel succès. (Voir le sujet ici) :

[/quote]

Boutons reliés aux pins suivantes (l'appui sur un bouton provoque la mise à la masse) :
- Pin 2 : Sortie précédente
- Pin 3 : Sortie suivante
- Pin 4 : Go (lance le mouvement)
- Pin 5 : Calibration

Sorties branchées comme telles :
- Pin 9 : Entrée "DIR" du module LMD18200
- Pin 11 : Entrée "IN" d'un relais
- Pin 7 : Entrée "PWM" du module LMD18200

12V continu branché en entrée du LDM18200
Fils jaune et rouge de la plaque tournante branchés en sortie du LMD18200
Fil jaune branché aussi en position centrale du relais
Fil gris branché en contact "travail" du relais

Le relais permet de déclencher et maintenir le mouvement du pont tournant.
La pin 7 reste à l'état haut pour activer la sortie permanente du LMD18200.
La pin 9 détermine le sens de rotation du pont tournant en agissant sur la polarité du courant de sortie.

Code:
#include <ArduPress.h>

#define DEBUG

#define RELAY_ON LOW
#define RELAY_OFF HIGH

#define PIN_BUTTON_CALIB 5
#define PIN_BUTTON_MINUS 2
#define PIN_BUTTON_PLUS 3
#define PIN_BUTTON_MOVE 4

#define PIN_BRIDGEDIRECTION1 9
#define PIN_BRIDGEDIRECTION2 10
#define PIN_BRIDGEMOVE 11

#define BRIDGEPOSITIONS 48

int _iCalibrationStatus;

int _iBridgePosition;
int _iBridgeActual;

unsigned long _ulMoveForwardDelay;
unsigned long _ulMoveBackwardDelay;

ArduPress buttons = ArduPress(PIN_BUTTON_CALIB, PIN_BUTTON_MINUS, PIN_BUTTON_PLUS, PIN_BUTTON_MOVE);

void ValidateBridgePosition();
void Calibrate();
void MoveBridge();
void MoveNext();
void MovePrevious();
void SetDirection(bool bDirection);

void setup() {
  buttons.init();
#ifdef DEBUG
  Serial.begin(115200); // start serial for output
#endif

  // PWM pin of LMD18200 is on PIN 7, set it HIGH
  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);

  pinMode(PIN_BRIDGEDIRECTION1, OUTPUT);
  pinMode(PIN_BRIDGEDIRECTION2, OUTPUT);
  pinMode(PIN_BRIDGEMOVE, OUTPUT);

  digitalWrite(PIN_BRIDGEDIRECTION1, LOW);
  digitalWrite(PIN_BRIDGEDIRECTION2, LOW);
  digitalWrite(PIN_BRIDGEMOVE, RELAY_OFF);

  _iCalibrationStatus = 0;
  
  _iBridgePosition = 0;
  _iBridgeActual = 0;

  _ulMoveForwardDelay = 940;
  _ulMoveBackwardDelay = 840;

#ifdef DEBUG
      Serial.println(F("Ready!"));
#endif
}

void loop() {
  buttons.checkStatus();

  if (buttons.newPress(0)) // Button calibration, for calibration steps
  {
    Calibrate();
  }
  else if (buttons.newPress(1)) // Button "Previous", move the desired position forwards
  {
    if (_ulMoveForwardDelay == 0) // If no calibration data present, do a single default move
      MoveNext();
    else
    {
      _iBridgePosition--;
      ValidateBridgePosition();
#ifdef DEBUG
      Serial.print(F("Position requested : "));
      Serial.println(_iBridgePosition);
#endif
    }
  }
  else if (buttons.newPress(2)) // Button "Next", move the desired position backwards
  {
    if (_ulMoveBackwardDelay == 0) // If no calibration data present, do a single default move
      MovePrevious();
    else
    {
      _iBridgePosition++;
      ValidateBridgePosition();
#ifdef DEBUG
      Serial.print(F("Position requested : "));
      Serial.println(_iBridgePosition);
#endif
    }
  }
  else if (buttons.newPress(3)) // Button "Go", starts moving the bridge
  {
    MoveBridge();
  }
}

// If desired position is outside bounds, put it back into the bounds
void ValidateBridgePosition()
{
  if (_iBridgePosition >= BRIDGEPOSITIONS)
    _iBridgePosition -= BRIDGEPOSITIONS;
  if (_iBridgePosition < 0)
    _iBridgePosition += BRIDGEPOSITIONS;
}

// Calibration process :
//  1) Press button : starts moving the bridge forwards
//  2) Press button when bridge completes a full 360 : records the time needed for a forward move
//  3) Press button : starts moving the bridge backwards
//  4) Press button when bridge completes a full 360 : records the time needed for a backward move
void Calibrate()
{
  if (_iCalibrationStatus == 0) // Start calibration in forward way
  {
#ifdef DEBUG
    Serial.println(F("Starting forward calibration."));
#endif
    _iCalibrationStatus = 1;
    _ulMoveForwardDelay = millis();
    SetDirection(true);
    digitalWrite(PIN_BRIDGEMOVE, RELAY_ON);
  }
  else if (_iCalibrationStatus == 1) // End calibration in forward way (calculate delay)
  {
#ifdef DEBUG
    Serial.println(F("End of forward calibration."));
#endif
    _iCalibrationStatus = 2;
    unsigned long ulTotal = millis() - _ulMoveForwardDelay;
    _ulMoveForwardDelay = ulTotal / BRIDGEPOSITIONS;
    SetDirection(true);
    digitalWrite(PIN_BRIDGEMOVE, RELAY_OFF);
#ifdef DEBUG
    Serial.print(F("Forward delay (ms) : "));
    Serial.println(_ulMoveForwardDelay);
#endif
  }
  else if (_iCalibrationStatus == 2) // Start calibration in backard way
  {
#ifdef DEBUG
    Serial.println(F("Starting backward calibration."));
#endif
    _iCalibrationStatus = 3;
    _ulMoveBackwardDelay = millis();
    SetDirection(false);
    digitalWrite(PIN_BRIDGEMOVE, RELAY_ON);
  }
  else if (_iCalibrationStatus == 3) // End calibration in backward way (calculate delay)
  {
#ifdef DEBUG
    Serial.println(F("End of backward calibration."));
#endif
    _iCalibrationStatus = 0;
    unsigned long ulTotal = millis() - _ulMoveBackwardDelay;
    _ulMoveBackwardDelay = ulTotal / BRIDGEPOSITIONS;
    SetDirection(false);
    digitalWrite(PIN_BRIDGEMOVE, RELAY_OFF);
#ifdef DEBUG
    Serial.print(F("Backward delay (ms) : "));
    Serial.println(_ulMoveBackwardDelay);
#endif
  }
}

// Starts moving the bridge
void MoveBridge()
{
  if (_iBridgePosition != _iBridgeActual) // Do nothing if the desired position is same as actual
  {
#ifdef DEBUG
    Serial.print(F("Moving bridge from position "));
    Serial.print(_iBridgeActual);
    Serial.print(F(" to position "));
    Serial.println(_iBridgePosition);
#endif

    int iHalfOutputs = BRIDGEPOSITIONS / 2;

    int iMove = _iBridgePosition - _iBridgeActual;
    bool bDirection = (iMove > 0);
    int iAbsMove = abs(iMove);
    if (iAbsMove > iHalfOutputs) // If move is more than half turn, then move the other direction
    {
      iAbsMove -= BRIDGEPOSITIONS;
      iAbsMove = abs(iAbsMove);
      bDirection = !bDirection;
    }

    // Calculate delay
    unsigned long ulDelay = (bDirection ? _ulMoveForwardDelay : _ulMoveBackwardDelay);
    ulDelay = ulDelay * (iAbsMove - 1) + (ulDelay / 2);

    // Do the actual move
    SetDirection(bDirection);
    digitalWrite(PIN_BRIDGEMOVE, RELAY_ON);
    delay(ulDelay);
    digitalWrite(PIN_BRIDGEMOVE, RELAY_OFF);
    _iBridgeActual = _iBridgePosition;
#ifdef DEBUG
    Serial.println(F("End of move."));
#endif
  }
#ifdef DEBUG
  else
    Serial.println(F("No need to move."));
#endif
}

// Do a single move forwards
void MoveNext()
{
#ifdef DEBUG
    Serial.println(F("Single move forward."));
#endif
  SetDirection(true);
  digitalWrite(PIN_BRIDGEMOVE, RELAY_ON);
  delay(500);
  digitalWrite(PIN_BRIDGEMOVE, RELAY_OFF);
}

// Do a single move backwards
void MovePrevious()
{
#ifdef DEBUG
    Serial.println(F("Single move backward."));
#endif
  SetDirection(false);
  digitalWrite(PIN_BRIDGEMOVE, RELAY_ON);
  delay(500);
  digitalWrite(PIN_BRIDGEMOVE, RELAY_OFF);
}

void SetDirection(bool bDirection)
{
  if (bDirection)
  {
    digitalWrite(PIN_BRIDGEDIRECTION1, RELAY_ON);
    digitalWrite(PIN_BRIDGEDIRECTION2, RELAY_ON);
  }
  else
  {
    digitalWrite(PIN_BRIDGEDIRECTION1, RELAY_OFF);
    digitalWrite(PIN_BRIDGEDIRECTION2, RELAY_OFF);
  }
}
Revenir en haut Aller en bas
sierramike
Membre
Membre
sierramike


Masculin Age : 44
Localisation : 67000 STRASBOURG
Nombre de messages : 4563
Date d'inscription : 29/10/2015

Les expérimentations de Sierramike Empty
MessageSujet: Re: Les expérimentations de Sierramike   Les expérimentations de Sierramike Icon_minitimeLun 31 Oct 2016 - 0:58

J'en profite pour publier le code source de ma petite librairie "ArduPress" qui permet de se simplifier la vie pour gérer jusqu'à 8 boutons sans avoir à gérer le dé-bounce à chaque fois dans le script :

ArduPress.h :
Code:
/********************************************************************
 This is a simple buttons manager, designed to manage up to 8 buttons
 using 8 pins of the Arduino, while keeping the smallest footprint
 possible in memory. Unlike other libraries, this one uses a single
 byte in memory to keep track of 8 buttons status, and another single
 byte to store the 8 previous buttons status.
 The library handles debounce for you.
 The library uses internal Pull-up resistors. Buttons should switch
 inputs to ground.

 Written by Stephane Moitry (aka 'sierramike'). http://stephane.moitry.fr

 BSD license, check license.txt for more information.
 All text above must be included in any redistribution.
********************************************************************/

// Version 1.1 -- Oct. 30, 2016

#pragma once

class ArduPress
{
  public:
    ArduPress(unsigned char pin1);
    ArduPress(unsigned char pin1, unsigned char pin2);
    ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3);
    ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3, unsigned char pin4);
    ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3, unsigned char pin4, unsigned char pin5);
    ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3, unsigned char pin4, unsigned char pin5, unsigned char pin6);
    ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3, unsigned char pin4, unsigned char pin5, unsigned char pin6, unsigned char pin7);
    ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3, unsigned char pin4, unsigned char pin5, unsigned char pin6, unsigned char pin7, unsigned char pin8);
   void init();
    void checkStatus();
    bool statusOf(unsigned char button);
    bool hasChanged(unsigned char button);
   bool newPress(unsigned char button);

  private:
    unsigned char _quantity;
    unsigned char _pins[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    unsigned char _firstStatus = 0;
    unsigned char _status = 0;
    unsigned char _oldStatus = 0;
};

ArduPress.cpp :
Code:
#include "Arduino.h"
#include "ArduPress.h"

ArduPress::ArduPress(unsigned char pin1)
{
  _quantity = 1;
  _pins[0] = pin1;
}

ArduPress::ArduPress(unsigned char pin1, unsigned char pin2)
{
  _quantity = 2;
  _pins[0] = pin1;
  _pins[1] = pin2;
}

ArduPress::ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3)
{
  _quantity = 3;
  _pins[0] = pin1;
  _pins[1] = pin2;
  _pins[2] = pin3;
}

ArduPress::ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3, unsigned char pin4)
{
  _quantity = 4;
  _pins[0] = pin1;
  _pins[1] = pin2;
  _pins[2] = pin3;
  _pins[3] = pin4;
}

ArduPress::ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3, unsigned char pin4, unsigned char pin5)
{
  _quantity = 5;
  _pins[0] = pin1;
  _pins[1] = pin2;
  _pins[2] = pin3;
  _pins[3] = pin4;
  _pins[4] = pin5;
}

ArduPress::ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3, unsigned char pin4, unsigned char pin5, unsigned char pin6)
{
  _quantity = 6;
  _pins[0] = pin1;
  _pins[1] = pin2;
  _pins[2] = pin3;
  _pins[3] = pin4;
  _pins[4] = pin5;
  _pins[5] = pin6;
}

ArduPress::ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3, unsigned char pin4, unsigned char pin5, unsigned char pin6, unsigned char pin7)
{
  _quantity = 7;
  _pins[0] = pin1;
  _pins[1] = pin2;
  _pins[2] = pin3;
  _pins[3] = pin4;
  _pins[4] = pin5;
  _pins[5] = pin6;
  _pins[6] = pin7;
}

ArduPress::ArduPress(unsigned char pin1, unsigned char pin2, unsigned char pin3, unsigned char pin4, unsigned char pin5, unsigned char pin6, unsigned char pin7, unsigned char pin8)
{
  _quantity = 8;
  _pins[0] = pin1;
  _pins[1] = pin2;
  _pins[2] = pin3;
  _pins[3] = pin4;
  _pins[4] = pin5;
  _pins[5] = pin6;
  _pins[6] = pin7;
  _pins[7] = pin8;
}

void ArduPress::init()
{
   for (int i = 0; i < _quantity; i++)
   {
      pinMode(_pins[i], INPUT_PULLUP);
      digitalWrite(_pins[i], HIGH); //activate built-in pull-up resistor 
   }
}

void ArduPress::checkStatus()
{
  _oldStatus = _status;
  for (byte i = 0; i < _quantity; i++)
    bitWrite(_firstStatus, i, !digitalRead(_pins[i]));
  delay(50);
  for (byte i = 0; i < _quantity; i++)
  {
    if (!bitRead(_firstStatus, i) == (!digitalRead(_pins[i]) == 1))
      bitWrite(_status, i, !bitRead(_firstStatus, i));
  }
}

bool ArduPress::statusOf(unsigned char button)
{
  return bitRead(_status, button);
}

bool ArduPress::hasChanged(unsigned char button)
{
  return (bitRead(_status, button) != bitRead(_oldStatus, button));
}

bool ArduPress::newPress(unsigned char button)
{
  return (bitRead(_status, button) && !bitRead(_oldStatus, button));
}
Revenir en haut Aller en bas
sierramike
Membre
Membre
sierramike


Masculin Age : 44
Localisation : 67000 STRASBOURG
Nombre de messages : 4563
Date d'inscription : 29/10/2015

Les expérimentations de Sierramike Empty
MessageSujet: Re: Les expérimentations de Sierramike   Les expérimentations de Sierramike Icon_minitimeLun 31 Oct 2016 - 1:08

Deuxième expérimentation du jour : la génération du signal DCC.

Sur la même base que le test précédent de juillet, j'ai surtout trouvé pourquoi je n'arrivais plus à le faire marcher : j'avais branché l'entrée "PWM" sur une pin de l'Arduino pour la traction analogique, puis j'ai oublié de modifier le sketch DCC pour forcer cette pin à l'état haut ...  Embarassed

Bref, j'en ai profité pour revoir le sketch, et en faire une version à 4 boutons et virer le potentiomètre qui manque de précision.

Boutons reliés aux pins suivantes (l'appui sur un bouton provoque la mise à la masse) :
- Pin 2 : Ralentir
- Pin 3 : Accélérer
- Pin 4 : Allumer/Éteindre les feux
- Pin 5 : Stop/Changement de direction

Sorties branchées comme telles :
- Pin 9 : Entrée "DIR" du module LMD18200
- Pin 7 : Entrée "PWM" du module LMD18200

12V continu branché en entrée du LDM18200
Sortie du LMD18200 reliée aux rails

La pin 7 reste à l'état haut pour activer la sortie permanente du LMD18200.
La pin 9 génère le signal DCC qui consiste en un signal carré oscillant entre +12V et -12V, et dont la période détermine chaque bit 0 ou 1.

L'accélération et décélération fonctionne par pas de 10 jusqu'à la valeur maxi de 127.
Le bouton stop force la valeur "MIN" de 1. (0 provoque l'arrêt d'urgence brutal).
Lorsque la vitesse est à la valeur MIN (donc 1), chaque appui suivant inverse le sens de marche (donc on passe de 1 à -1 et vice versa. 1 ou -1 signifie l'arrêt, donc la locomotive n'avance pas, mais les feux correspondent au sens désiré).

[/quote]

Code:

#include <DCCPacket.h>
#include <DCCPacketQueue.h>
#include <DCCPacketScheduler.h>
#include <ArduPress.h>

#define PIN_BUTTON_STOP 5
#define PIN_BUTTON_MINUS 2
#define PIN_BUTTON_PLUS 3
#define PIN_BUTTON_LIGHT 4

#define STEP 10
#define MIN 1
#define MAX 127

ArduPress buttons = ArduPress(PIN_BUTTON_STOP, PIN_BUTTON_MINUS, PIN_BUTTON_PLUS, PIN_BUTTON_LIGHT);

DCCPacketScheduler dps;
int DCCaddr1 = 5;
byte F0 = 0;
byte bSpeed, bOldSpeed;
byte bDirection, bOldDirection;

void setup() {
  buttons.init();
  Serial.begin(115200);
  dps.setup();

  bSpeed = 0;
  bOldSpeed = 0;
  bDirection = 1;
  bOldDirection = 1;

  pinMode(7, OUTPUT);
  digitalWrite(7, HIGH);
  
  Serial.println(F("Ready!"));
}

void loop() {
  buttons.checkStatus();

  if (buttons.newPress(0)) // Button Stop
  {
    if (bSpeed == MIN)
      bDirection *= -1;
    bSpeed = MIN;
  }
  else if (buttons.newPress(1)) // Button Minus
  {
    bSpeed -= STEP;
    if (bSpeed < MIN)
      bSpeed = MIN;
  }
  else if (buttons.newPress(2)) // Button Plus
  {
    bSpeed += STEP;
    if (bSpeed > MAX)
      bSpeed = MAX;
  }
  else if (buttons.newPress(3)) // Button Light
  {
    F0 ^= 1;
    Serial.print(F("Light : "));
    Serial.println(F0, BIN);
    dps.setFunctions0to4(DCCaddr1, DCC_SHORT_ADDRESS, F0);
  }

  if ((bSpeed != bOldSpeed) || (bDirection != bOldDirection))
  {
    dps.setSpeed128(DCCaddr1, DCC_SHORT_ADDRESS, bSpeed * bDirection);
    bOldSpeed = bSpeed;
    bOldDirection = bDirection;
    Serial.print(F("New speed : "));
    Serial.print(bSpeed, DEC);
    Serial.print(F(" / Dir : "));
    Serial.println(bDirection, DEC);
  }

  dps.update();
}
Revenir en haut Aller en bas
Contenu sponsorisé





Les expérimentations de Sierramike Empty
MessageSujet: Re: Les expérimentations de Sierramike   Les expérimentations de Sierramike Icon_minitime

Revenir en haut Aller en bas
 
Les expérimentations de Sierramike
Revenir en haut 
Page 1 sur 1
 Sujets similaires
-
» Présentation de Sierramike
» Réseau de tests DCC de Sierramike
» La modeste petite collection de Sierramike

Permission de ce forum:Vous ne pouvez pas répondre aux sujets dans ce forum
1/160 - Echelle N :: Modèles réduits à l'echelle N :: Electricité / Electronique-
Sauter vers: