Le Bulletin du Printemps est chez l'imprimeur
(il sera distribué à partir de mi-mai)
...

Commande pont tournant

Ici on traite de tout ce qui concerne les alimentations et les automatismes, quelques soient les technologies mises en œuvre. Depuis le simple transformateur jusqu'aux divers systèmes de "pilotage" (DCC, DCS, …) en passant par les micro processeurs (Arduino et autres).
Répondre
Avatar du membre
Olivier41
Gold
Messages : 238
Enregistré le : 21 mars 2021, 11:39
A remercié : 43 fois
A été remercié : 125 fois

Commande pont tournant

Message par Olivier41 »

Bonjour

Question ouverte en deux temps:
Quelqu’un (ou plusieurs!) peut il partager un retour d’experience sur le système de commande PTC4 de pont tournantcommercialisé par NYRS aux US?
Autres solutions autres expériences bienvenues

:merci: Par avance
HO, ZÉRO, 1/35 voie étroite
Membre du CFC et CFTP
CDZ 1445
Expert en rien - Touche à tout
Avatar du membre
Rolf
Platinum
Messages : 769
Enregistré le : 07 déc. 2017, 11:14
Localisation : Allemagne
A remercié : 300 fois
A été remercié : 55 fois

Re: Commande pont tournant

Message par Rolf »

par Olivier41 » 22 févr. 2024
Bonjour
Question ...
Autres solutions ...
Désolé, pas d'experience mais je sais une solution pour un moteur pas à pas: Digitalzentrale
 
Screenshot 2024-02-22 164542.jpg
 


Rolf
Associations: CdZ / FREMO / ArgeSpur0
Avatar du membre
Olivier41
Gold
Messages : 238
Enregistré le : 21 mars 2021, 11:39
A remercié : 43 fois
A été remercié : 125 fois

Re: Commande pont tournant

Message par Olivier41 »

:merci: Rolf, c’est le but du fil de discussion recenser les solutions perso ou du commerce

Dans tous les cas, Très intéressant je vais aller regarder cela de prêt
HO, ZÉRO, 1/35 voie étroite
Membre du CFC et CFTP
CDZ 1445
Expert en rien - Touche à tout
Avatar du membre
ffayolle
Platinum
Messages : 4496
Enregistré le : 19 mai 2015, 19:39
A remercié : 203 fois
A été remercié : 128 fois

Re: Commande pont tournant

Message par ffayolle »

Bonsoir,
J'ai développé un système à base d'une carte Arduino, simple par contre car sans indexation.
Je recherche dans mes archives et je partage si cela vous intéresse.
Bonne soirée, Fabrice
Fabrice Fayolle
Avatar du membre
Olivier41
Gold
Messages : 238
Enregistré le : 21 mars 2021, 11:39
A remercié : 43 fois
A été remercié : 125 fois

Re: Commande pont tournant

Message par Olivier41 »

ffayolle a écrit : 22 févr. 2024, 20:25 Bonsoir,
J'ai développé un système à base d'une carte Arduino, simple par contre car sans indexation.
Je recherche dans mes archives et je partage si cela vous intéresse.
Bonne soirée, Fabrice
Bien sur ca permettra de recenser les différentes solutions
HO, ZÉRO, 1/35 voie étroite
Membre du CFC et CFTP
CDZ 1445
Expert en rien - Touche à tout
Avatar du membre
ffayolle
Platinum
Messages : 4496
Enregistré le : 19 mai 2015, 19:39
A remercié : 203 fois
A été remercié : 128 fois

Re: Commande pont tournant

Message par ffayolle »

Voilà une solution pour moteur classique avec décodeur DCC sur base de but Loconet
à noter que l'interface est toujours la même entre la carte Arduino et le bus Loconet
Cf. https://www.modelrailway-online.com/ard ... loconet-3/

Une photographie de la platine de commande:
Lasercut-46.jpg
Le câblage de la platine:
2024-02-23_105406.jpg
2024-02-23_105406.jpg (45.78 Kio) Vu 87 fois
Le code :

// Name
#define NAME "DCC-TT-Motor"
#define NAME2 "LocoNet protocol (Digitrax) uses to manage a TurnTable by a DCC Decoder without stepper motor"
#define NAME3 "Sounds by a DFPlayer board"

// Version & Copyright
#define VERSION "1.0 (Arduino Uno)"
#define COPYRIGHT "Fabrice Fayolle, November 2019"

// Digitrax LocoNet -> LocoNet
// DCC Throttle -> Throttle
// Sound system -> DFPlayer

// Arduino Uno
// Pin -> Use for -> Connect to
// 0
// ...
// 4 -> Signal -> SPDT ON-ON
// 5 -> Light -> SPDT ON-ON
// 6 -> Default -> Red LED (with a 220 ohms resistor)
// 7 -> LocoNet Transmit pin -> Locoshield PCB Tx pin
// 8 -> LocoNet Receive pin -> Locoshield PCB Rx pin
// 9 -> Emergency Stop -> Push button
// 10 -> Serial Rx pin -> DFPlayer PCB Tx pin
// 11 -> Serial Tx pin -> DFPlayer PCB Rx pin
// 12
// 13
// 14
// 15 -> Turntable direction -> SPDT ON-ON
// 16 -> Turntable stop -> Push button
// 17 -> Turntable brake -> Push button
// 18 -> Turntable low speed -> Push button
// 19 -> Turntable mid speed -> Push button

// INPUT
// Push button
// 1 -> Arduino Pin
// 2 -> GND
// SPDT ON-ON
// 1 -> 5V -> Normal position
// Common point -> Arduino Pin
// 2 -> GND -> Reverse position
// OUTPUT
// Digitrax LocoNet message

// Global constants and variables
const boolean Activated = LOW;

// Visual management for interlocking system
// Default lever position
const int DefaultPin = 6;

// Throttle
// Define used slots table
int used_SLOT[120];
// Define the address of the turntable DCC decoder
const int ADR_Turntable = 101;
// Define constants and variables for the turntable
boolean TT_dir = false;
const int TT_dir_PIN = 15;
const int TT_stop_PIN = 16;
const int TT_brake_PIN = 17;
#define TT_brake -0x01
const int TT_lowspeed_PIN = 18;
#define TT_lowspeed 0x03
const int TT_midspeed_PIN = 19;
#define TT_midspeed 0x40

// DFPlayer
// https://github.com/PowerBroker2/DFPlayerMini_Fast
#include <SoftwareSerial.h>
#include <DFPlayerMini_Fast.h>

// LocoNet
// https://github.com/mrrwa
#include <LocoNet.h>
// Define LocoNet Transmit Pin
#define LN_TX_PIN 7
// Emergency Stop
const int Emergency_PIN = 9;
// Pointer to a received LocoNet packet
lnMsg *LnPacket;

void slot_Init()
// Initiliaze all slots
{
for (int slot = 0; slot < 120; slot++)
{
sendOPC_xxx(OPC_RQ_SL_DATA, slot, 0);
}
}
void sendOPC_x(int OPC_Type)
// OPC_GPOFF - OPC_GPON - OPC_IDLE LocoNet Message
{
lnMsg SendPacket;
SendPacket.data[0] = OPC_Type;
LocoNet.send( &SendPacket );
switch (OPC_Type)
{
case OPC_GPOFF:
// OPC_GPOFF -> Power OFF
Serial.print("OPC_GPOFF");
break;
case OPC_GPON:
// OPC_GPON -> Power ON
Serial.print("OPC_GPON");
break;
case OPC_IDLE:
// OPC_IDLE -> Emergency Stop
Serial.print("OPC_IDLE");
break;
}
Serial.println(" LocoNet message sent");
delay(250);
return;
}
void sendOPC_xxx(int OPC_Type, int Arg1, int Arg2)
// OPC_LOCO_SPD - OPC_LOCO_DIRF - OPC_LOCO_SND - OPC_SW_REQ - OPC_MOVE_SLOTS - OPC_RQ_SL_DATA - OPC_LOCO_ADR LocoNet Message
{
lnMsg SendPacket;
SendPacket.data[0] = OPC_Type;
SendPacket.data[1] = Arg1;
SendPacket.data[2] = Arg2;
LocoNet.send( &SendPacket );
switch (OPC_Type)
{
case OPC_LOCO_SPD:
// OPC_LOCO_SPD
Serial.print ("SLOT ");
Serial.print(Arg1);
Serial.print(" : OPC_LOCO_SPD");
break;
case OPC_LOCO_DIRF:
// OPC_LOCO_DIRF
Serial.print ("SLOT ");
Serial.print(Arg1);
Serial.print(" : OPC_LOCO_DIRF");
break;
case OPC_LOCO_SND:
// OPC_LOCO_SND
Serial.print ("SLOT ");
Serial.print(Arg1);
Serial.print(" : OPC_LOCO_SND");
break;
case OPC_SW_REQ:
// OPC_SW_REQ
Serial.print ("Turnout Adr ");
Serial.print(Arg1 + 1);
Serial.print(" : OPC_SW_REQ");
break;
case OPC_MOVE_SLOTS:
// OPC_MOVE_SLOTS
Serial.print ("SLOT ");
Serial.print(Arg1);
Serial.print(" : OPC_MOVE_SLOTS");
break;
case OPC_RQ_SL_DATA:
// OPC_RQ_SL_DATA
Serial.print ("SLOT ");
Serial.print(Arg1);
Serial.print(" : OPC_RQ_SL_DATA");
break;
case OPC_LOCO_ADR:
// OPC_LOCO_ADR
Serial.print ("DCC Adr ");
Serial.print(Arg2);
Serial.print(" : OPC_LOCO_ADR");
break;
}
Serial.println(" LocoNet message sent");
delay(250);
return;
}

void LocoNet_Message_For_Lever(int SLever_dcc, int SLever_type, boolean SLever_state)
{
int sw1 = 0x00;
int sw2 = 0x00;
switch (SLever_type)
{
case 0 :
// 0 -> Not use
break;
case 1 :
// 1 -> Point
SLever_dcc = SLever_dcc - 1;
if (SLever_state)
{
sw1 |= B00100000;
sw2 |= B00100000;
}
sw1 |= B00010000;
sw1 |= (SLever_dcc >> 7) & 0x0F;
sw2 |= (SLever_dcc >> 7) & 0x0F;
sendOPC_xxx(OPC_SW_REQ, SLever_dcc & 0x7F, sw1);
sendOPC_xxx(OPC_SW_REQ, SLever_dcc & 0x7F, sw2);
break;
case 2:
// 2 -> FPL
break;
case 3:
// 3 -> Signal
break;
case 4:
// 4 -> Block signal
break;
}
return;
}

// DFPlayer
// Define DFPlayer Serial Receive and Transmit Pin
#define DFPl_RX_PIN 10
#define DFPl_TX_PIN 11
SoftwareSerial mySerial(DFPl_RX_PIN, DFPl_TX_PIN);
DFPlayerMini_Fast myMP3;

// Object "Throttle"
class Throttle
{
private:
int SLOT;
int ADR;
int SPD;
int DIRF;
int SND;
public:
void Setup(int SADR);
void Change_SPD(int SSPD);
void Change_DIRF(int SDIRF);
void Change_SND(int SSND);
}
;
void Throttle::Setup(int SADR)
{
sendOPC_xxx(OPC_LOCO_ADR, 0, SADR);
LnPacket = LocoNet.receive() ;
//while ((LnPacket->data[0] != 0xE7) | (LnPacket->data[4] != SADR))
//{
//sendOPC_xxx(OPC_LOCO_ADR, 0, SADR);
//LnPacket = LocoNet.receive();
//}
Serial.print(LnPacket->data[0], HEX);
Serial.print(" LocoNet Message Received -> DCC Adr ");
Serial.print(LnPacket->data[4]);
Serial.print(" was found in SLOT ");
Serial.println(LnPacket->data[2]);
SLOT = LnPacket->data[2];
ADR = LnPacket->data[4];
SPD = 0x00;
DIRF = 0x00;
SND = 0x00;
sendOPC_xxx(OPC_MOVE_SLOTS, SLOT, SLOT);
sendOPC_xxx(OPC_LOCO_DIRF, SLOT, DIRF);
sendOPC_xxx(OPC_LOCO_SPD, SLOT, SPD);
sendOPC_xxx(OPC_LOCO_SND, SLOT, SND);
Serial.println("Communication initialized");
int i = 0;
while (used_SLOT != 0)
{
i = i + 1;
}
used_SLOT = SLOT;
return;
}
void Throttle::Change_SPD(int SSPD)
{
if (SSPD < 0)
{
if (SPD > 0) SPD = SPD + SSPD;
}
else
{
SPD = SSPD;
}
Serial.print("SPD at ");
Serial.print((SPD * 100) / 128);
Serial.println("%");
sendOPC_xxx(OPC_LOCO_SPD, SLOT, SPD);
}
void Throttle::Change_DIRF(int SDIRF)
{
DIRF = DIRF + SDIRF;
Serial.print("DIRF:");
Serial.print(DIRF);
Serial.print("\t\tDirection: ");
Serial.print(((DIRF & 0x20) == 0) ? "<-" : "->");
Serial.print("\tFunction(s): ");
Serial.print(((DIRF & 0x10) == 0) ? "" : "F0 ");
Serial.print(((DIRF & 0x01) == 0) ? "" : "F1 ");
Serial.print(((DIRF & 0x02) == 0) ? "" : "F2 ");
Serial.println(((DIRF & 0x04) == 0) ? "" : "F3");
sendOPC_xxx(OPC_LOCO_DIRF, SLOT, DIRF);
}
void Throttle::Change_SND(int SSND)
{
SND = SND + SSND;
Serial.print("SND:");
Serial.println(SND);
sendOPC_xxx(OPC_LOCO_DIRF, SLOT, SND);
}
Throttle TT_Throttle;

void setup()
{
// Initialize Serial Port USB at 9600 baud
Serial.begin(9600);
Serial.println(NAME);
Serial.println(NAME2);
Serial.println(NAME3);
Serial.println("---------------------------------------------------------------------------");
Serial.print("Version "); Serial.print(VERSION); Serial.print(", "); Serial.println(COPYRIGHT);
Serial.println("---------------------------------------------------------------------------");
// Visual management
pinMode(DefaultPin, OUTPUT);
digitalWrite(DefaultPin, LOW);
// LocoNet
LocoNet.init(LN_TX_PIN);
pinMode(Emergency_PIN, INPUT_PULLUP);
DCC_On();
// Throttle
// Initialize used_SLOT
for (int i = 0; i < 120; i++)
{
used_SLOT = 0;
}
// Initialize Turntable INPUT
pinMode(TT_dir_PIN, INPUT_PULLUP);
pinMode(TT_stop_PIN, INPUT_PULLUP);
pinMode(TT_brake_PIN, INPUT_PULLUP);
pinMode(TT_lowspeed_PIN, INPUT_PULLUP);
pinMode(TT_midspeed_PIN, INPUT_PULLUP);
// Initialize Turntable Throttle
TT_Throttle.Setup(ADR_Turntable);
// DFPlayer
// Initialize Serial Communication at 9600 baud
//mySerial.begin(9600);
//myMP3.begin(mySerial);
//myMP3.volume(30);
//
Serial.println("Ready to use");
}

void loop()
{
// Loconet
Emergency();
// Throttle (Turntable)
Turntable_Order();
// DFPlayer
//myMP3.play(1);
}

void DCC_On()
// DCC Power ON
{
sendOPC_x(OPC_GPOFF);
delay(100);
sendOPC_x(OPC_GPON);
return;
}

void Emergency()
// Emergency Stop required
{
int i = 0;
if (digitalRead(Emergency_PIN) == Activated)
{
delay(100);
if (digitalRead(Emergency_PIN) == Activated)
{
while (digitalRead(Emergency_PIN) == Activated)
{
digitalWrite(DefaultPin, HIGH);
delay(100);
digitalWrite(DefaultPin, LOW);
delay(100);
}
Serial.println("Emergency STOP!!!");
//sendOPC_x(OPC_IDLE);
while (used_SLOT != 0)
{
sendOPC_xxx(OPC_LOCO_SPD, used_SLOT, 0x00);
i = i + 1;
}
}
}
return;
}

void Turntable_Order()
// Control Turntable Direction by a SPDT ON-ON (Input: TT_dir_PIN)
// and Turntable Speed by some Push buttons (Input: TT_stop_PIN, TT_brake_PIN, TT_lowspeed_PIN and TT_midspeed_PIN)
{
if ((digitalRead(TT_dir_PIN) == HIGH) && TT_dir)
{
TT_dir = false;
TT_Throttle.Change_DIRF(-0x20);
}
if ((digitalRead(TT_dir_PIN) == LOW) && !TT_dir)
{
TT_dir = true;
TT_Throttle.Change_DIRF(0x20);
}
if (digitalRead(TT_stop_PIN) == Activated)
{
delay(100);
if (digitalRead(TT_stop_PIN) == Activated)
{
while (digitalRead(TT_stop_PIN) == Activated)
{
digitalWrite(DefaultPin, HIGH);
delay(100);
digitalWrite(DefaultPin, LOW);
delay(100);
}
Serial.print("Stop -> Turntable ");
TT_Throttle.Change_SPD(0x00);
}
}
if (digitalRead(TT_brake_PIN) == Activated)
{
delay(100);
if (digitalRead(TT_brake_PIN) == Activated)
{
while (digitalRead(TT_brake_PIN) == Activated)
{
digitalWrite(DefaultPin, HIGH);
delay(100);
digitalWrite(DefaultPin, LOW);
delay(100);
}
Serial.print("Brake -> Turntable ");
TT_Throttle.Change_SPD(TT_brake);
}
}
if (digitalRead(TT_lowspeed_PIN) == Activated)
{
delay(100);
if (digitalRead(TT_lowspeed_PIN) == Activated)
{
while (digitalRead(TT_lowspeed_PIN) == Activated)
{
digitalWrite(DefaultPin, HIGH);
delay(100);
digitalWrite(DefaultPin, LOW);
delay(100);
}
Serial.print("Low speed -> Turntable ");
TT_Throttle.Change_SPD(TT_lowspeed);
}
}
if (digitalRead(TT_midspeed_PIN) == Activated)
{
delay(100);
if (digitalRead(TT_midspeed_PIN) == Activated)
{
while (digitalRead(TT_midspeed_PIN) == Activated)
{
digitalWrite(DefaultPin, HIGH);
delay(100);
digitalWrite(DefaultPin, LOW);
delay(100);
}
Serial.print("Mid speed -> Turntable ");
TT_Throttle.Change_SPD(TT_midspeed);
}
}
return;
}
Fabrice Fayolle
Répondre