Auteur Sujet: Teensy 3.1, 3.2 - Sonorisation locomotive  (Lu 145117 fois)

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 3024
  • 100% Arduino et N
    • Voir le profil
Re : Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #135 le: mai 30, 2018, 02:11:22 pm »
C'est vrai, mais la bibliothèque NmraDcc (qui permet de décoder les trames DCC) n'est pas compatible avec le Teensy.

Il y a aussi la bibliothèque de Minabay.
De toute façon, tu peux toujours intégrer le code de la bibliothèque dans ton programme en gardant seulement ce qui est nécessaire. C’est faisable et il n’y a plus de problème de compatibilité.
Cordialement,
Dominique

Benoit92

  • Full Member
  • ***
  • Messages: 200
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #136 le: mai 30, 2018, 05:46:10 pm »
J'ai 2 possibilités :
1) Soit tout mettre sur un Arduino :
 - Librairie NmraDcc --> Ok
 - Commande Moteur 125 Hz par modification du Timer 2 -->Ok,
 - Feux éclairage Ok,
 - Bruitage en PWM Ok,
mais je ne sais pas si j'arriverai à gérer en même temps le bruitage et le décodage de la trame DCC (asynchrone).

2) Soit tout mettre sur un Teensy
 - Librairie NmraDcc --> NOk
- Commande Moteur -> Il faut que je puisse régler le PWM à 125 Hz (après essais, il s'avère que le moteur répond bien à cette fréquence) ,
 - Feux éclairage Ok,
 - Bruitage en TRW (wave avec header simplifié) -->Ok),

Dominique

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 3024
  • 100% Arduino et N
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #137 le: mai 30, 2018, 07:23:28 pm »
Comme je l’ai dit plus haut tu pourrais essayer d’integrer une partie du code de la bibliothèque NMRA dans ton sketch Teensy. Ce n’est pas simple mais c’est faisable en la décortiquant.
Je n’ai pas regardé pourquoi cette biblio n’est pas compatible avec le Teensy. Normalement il n’y a que des mesures de durée entre fronts montant et descendant du signal DCC pour retrouver les 0 et les 1.

J’ai un peu regardé cette bibliothèque ainsi que celle de Minabay qui me semble plus facile à utiliser mais celle de NMRA est plus « officielle ». Il faut récupérer d’abord le traitement de l’interruption qui traite chaque demi-bit, puis la construction des trames DCC. Tu ne gardes que les commandes de machines pour simplifier.

Est-ce que ça te paraît insurmontable ?
Tu as déjà fait un beau parcours jusqu’ici, ça vaudrait le coup de continuer.
« Modifié: mai 30, 2018, 07:54:01 pm par Dominique »
Cordialement,
Dominique

Benoit92

  • Full Member
  • ***
  • Messages: 200
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #138 le: mai 30, 2018, 11:47:27 pm »
Ok, Merci.
Si je reste sur l'option Teensy, il faudrait que je regarde dans la bibliothèque NmraDcc quelles sont les instructions qui sont différentes de celle de l'Arduino.
Je pense que cela va concerner principalement les instructions relatives aux interruptions ? et aux modifications des timers (nécessaire pour piloter le pont en H).
Le code suivant semble compiler sans erreur avec le teensy.
#include <NmraDcc.h>
#include <Servo.h>
void setup() {
  // put your setup code here, to run once:
}
void loop() {
  // put your main code here, to run repeatedly:

}

Ci-joint, pour information (en deux envois), NmraDcc.h et NmraDcc.cpp.

NmraDcc.h
//------------------------------------------------------------------------
//
// Model Railroading with Arduino - NmraDcc.h
//
// Copyright (c) 2008 - 2105 Alex Shepherd
//
// This source file is subject of the GNU general public license 2,
// that is available at the world-wide-web at
// http://www.gnu.org/licenses/gpl.txt
//
//------------------------------------------------------------------------
//
// file:      NmraDcc.h
// author:    Alex Shepherd
// webpage:   http://mrrwa.org/
// history:   2008-03-20 Initial Version
//            2011-06-26 Migrated into Arduino library from OpenDCC codebase
//            2014 Added getAddr to NmraDcc  Geoff Bunza
//            2015-11-06 Martin Pischky (martin@pischky.de):
//                       Experimental Version to support 14 speed steps
//                       and new signature of notifyDccSpeed and notifyDccFunc
//
//------------------------------------------------------------------------
//
// purpose:   Provide a simplified interface to decode NMRA DCC packets
//   and build DCC MutliFunction and Stationary Decoders
//
//------------------------------------------------------------------------

// Uncomment the following Line to Enable Service Mode CV Programming
#define NMRA_DCC_PROCESS_SERVICEMODE

// Uncomment the following line to Enable MutliFunction Decoder Operations
#define NMRA_DCC_PROCESS_MULTIFUNCTION

// Uncomment the following line to Enable 14 Speed Step Support
//#define NMRA_DCC_ENABLE_14_SPEED_STEP_MODE

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include "EEPROM.h"

#ifndef NMRADCC_IS_IN
#define NMRADCC_IS_IN

#define MAX_DCC_MESSAGE_LEN 6    // including XOR-Byte

typedef struct
{
uint8_t Size ;
uint8_t PreambleBits ;
uint8_t Data[MAX_DCC_MESSAGE_LEN] ;
} DCC_MSG ;

//--------------------------------------------------------------------------
//  This section contains the NMRA Assigned DCC Manufacturer Id Codes that
//  are used in projects
//
//  This value is to be used for CV8
//--------------------------------------------------------------------------

#define MAN_ID_JMRI             0x12
#define MAN_ID_DIY              0x0D
#define MAN_ID_SILICON_RAILWAY  0x21

//--------------------------------------------------------------------------
//  This section contains the Product/Version Id Codes for projects
//
//  This value is to be used for CV7
//
//  NOTE: Each Product/Version Id Code needs to be UNIQUE for that particular
//  the DCC Manufacturer Id Code
//--------------------------------------------------------------------------

// Product/Version Id Codes allocated under: MAN_ID_JMRI
 
// Product/Version Id Codes allocated under: MAN_ID_DIY

// Standard CV Addresses
#define CV_ACCESSORY_DECODER_ADDRESS_LSB       1
#define CV_ACCESSORY_DECODER_ADDRESS_MSB       9

#define CV_MULTIFUNCTION_PRIMARY_ADDRESS       1
#define CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB 17
#define CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB 18

#define CV_VERSION_ID                          7
#define CV_MANUFACTURER_ID                     8
#define CV_29_CONFIG                          29

#if defined(ESP8266)
#include <spi_flash.h>
#define MAXCV     SPI_FLASH_SEC_SIZE
#elif defined( __STM32F1__)
#define MAXCV (EEPROM_PAGE_SIZE/4 - 1) // number of storage places (CV address could be larger
// because STM32 uses virtual adresses)
#else
#define MAXCV    E2END      // the upper limit of the CV value currently defined to max memory.
#endif

typedef enum {
    CV29_LOCO_DIR            = 0b00000001, /** bit 0: Locomotive Direction: "0" = normal, "1" = reversed */
    CV29_F0_LOCATION         = 0b00000010, /** bit 1: F0 location: "0" = bit 4 in Speed and Direction instructions, "1" = bit 4 in function group one instruction */
    CV29_APS = 0b00000100, /** bit 2: Alternate Power Source (APS) "0" = NMRA Digital only, "1" = Alternate power source set by CV12 */
    CV29_ADV_ACK             = 0b00001000, /** bit 3: ACK, Advanced Acknowledge mode enabled if 1, disabled if 0 */
    CV29_SPEED_TABLE_ENABLE  = 0b00010000, /** bit 4: STE, Speed Table Enable, "0" = values in CVs 2, 4 and 6, "1" = Custom table selected by CV 25 */
    CV29_EXT_ADDRESSING      = 0b00100000, /** bit 5: "0" = one byte addressing, "1" = two byte addressing */
    CV29_OUTPUT_ADDRESS_MODE = 0b01000000, /** bit 6: "0" = Decoder Address Mode "1" = Output Address Mode */
    CV29_ACCESSORY_DECODER   = 0b10000000, /** bit 7: "0" = Multi-Function Decoder Mode "1" = Accessory Decoder Mode */
} CV_29_BITS;

typedef enum {
#ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
    SPEED_STEP_14 = 15, /**< ESTOP=0, 1 to 15 */
#endif
    SPEED_STEP_28 = 29, /**< ESTOP=0, 1 to 29 */
    SPEED_STEP_128 = 127 /**< ESTOP=0, 1 to 127 */
} DCC_SPEED_STEPS;

typedef enum {
    DCC_DIR_REV = 0,     /** The locomotive to go in the reverse direction */
    DCC_DIR_FWD = 1,     /** The locomotive should move in the forward direction */
} DCC_DIRECTION;

typedef enum {
    DCC_ADDR_SHORT,      /** Short address is used. The range is 0 to 127. */
    DCC_ADDR_LONG,       /** Long Address is used. The range is 1 to 10239 */
} DCC_ADDR_TYPE;

typedef enum
{
FN_0_4 = 1,
FN_5_8,
FN_9_12,
FN_13_20,
FN_21_28,
#ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE
  FN_0 /** function light is controlled by base line package (14 speed steps) */
#endif 
} FN_GROUP;

#define FN_BIT_00 0x10
#define FN_BIT_01 0x01
#define FN_BIT_02 0x02
#define FN_BIT_03 0x04
#define FN_BIT_04 0x08

#define FN_BIT_05 0x01
#define FN_BIT_06 0x02
#define FN_BIT_07 0x04
#define FN_BIT_08 0x08

#define FN_BIT_09 0x01
#define FN_BIT_10 0x02
#define FN_BIT_11 0x04
#define FN_BIT_12 0x08

#define FN_BIT_13 0x01
#define FN_BIT_14 0x02
#define FN_BIT_15 0x04
#define FN_BIT_16 0x08
#define FN_BIT_17 0x10
#define FN_BIT_18 0x20
#define FN_BIT_19 0x40
#define FN_BIT_20 0x80

#define FN_BIT_21 0x01
#define FN_BIT_22 0x02
#define FN_BIT_23 0x04
#define FN_BIT_24 0x08
#define FN_BIT_25 0x10
#define FN_BIT_26 0x20
#define FN_BIT_27 0x40
#define FN_BIT_28 0x80

//#define DCC_DBGVAR
#ifdef DCC_DBGVAR
typedef struct countOf_t {
    unsigned long Tel;
    unsigned long Err;
}countOf_t ;

extern struct countOf_t countOf;
#endif

class NmraDcc
{
  private:
    DCC_MSG Msg ;
   
  public:
    NmraDcc();

// Flag values to be logically ORed together and passed into the init() method
#define FLAGS_MY_ADDRESS_ONLY 0x01 // Only process DCC Packets with My Address
#define FLAGS_OUTPUT_ADDRESS_MODE 0x40  // CV 29/541 bit 6
#define FLAGS_DCC_ACCESSORY_DECODER 0x80  // CV 29/541 bit 7
void pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup);
  void init( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV );
  void initAccessoryDecoder( uint8_t ManufacturerId, uint8_t VersionId, uint8_t Flags, uint8_t OpsModeAddressBaseCV );
  uint8_t process();
  uint8_t getCV( uint16_t CV );
  uint8_t setCV( uint16_t CV, uint8_t Value);
uint8_t isSetCVReady( void );
uint16_t getAddr(void);

// #define DCC_DEBUG
#ifdef DCC_DEBUG
uint8_t getIntCount(void);
uint8_t getTickCount(void);
uint8_t getBitCount(void);
uint8_t getState(void);
  uint8_t getNestedIrqCount(void);
#endif

};

/************************************************************************************
    Call-back functions
************************************************************************************/

#if defined (__cplusplus)
extern "C" {
#endif

extern void notifyDccReset(uint8_t hardReset ) __attribute__ ((weak));
extern void notifyDccIdle(void) __attribute__ ((weak));

extern void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps ) __attribute__ ((weak));
extern void notifyDccSpeedRaw( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Raw) __attribute__ ((weak));

extern void notifyDccFunc( uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState) __attribute__ ((weak));

extern void notifyDccAccState( uint16_t Addr, uint16_t BoardAddr, uint8_t OutputAddr, uint8_t State ) __attribute__ ((weak));
extern void notifyDccAccTurnoutBoard( uint16_t BoardAddr, uint8_t OutputPair, uint8_t Direction, uint8_t OutputPower ) __attribute__ ((weak));
extern void notifyDccAccTurnoutOutput( uint16_t Addr, uint8_t Direction, uint8_t OutputPower ) __attribute__ ((weak));

extern void notifyDccSigState( uint16_t Addr, uint8_t OutputIndex, uint8_t State) __attribute__ ((weak));

extern void    notifyDccMsg( DCC_MSG * Msg ) __attribute__ ((weak));

extern uint8_t notifyCVValid( uint16_t CV, uint8_t Writable ) __attribute__ ((weak));
extern uint8_t notifyCVRead( uint16_t CV) __attribute__ ((weak));
extern uint8_t notifyCVWrite( uint16_t CV, uint8_t Value) __attribute__ ((weak));
extern uint8_t notifyIsSetCVReady(void) __attribute__ ((weak));
extern void    notifyCVChange( uint16_t CV, uint8_t Value) __attribute__ ((weak));
extern void    notifyCVResetFactoryDefault(void) __attribute__ ((weak));

extern void    notifyCVAck(void) __attribute__ ((weak));

#if defined (__cplusplus)
}
#endif

#endif


Benoit92

  • Full Member
  • ***
  • Messages: 200
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #139 le: mai 30, 2018, 11:55:52 pm »

Je donne les liens car :
Le message dépasse la limite de caractères autorisée (20000 caractères permis).

NmraDcc.h
https://github.com/mrrwa/NmraDcc/blob/master/NmraDcc.h

NmraDcc.cpp
https://github.com/mrrwa/NmraDcc/blob/master/NmraDcc.cpp

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1713
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #140 le: mai 31, 2018, 07:50:19 am »
J’ai trouvé ici :

https://www.arduinolibraries.info/libraries/nmra-dcc et ici https://github.com/mrrwa/NmraDcc

Qu’elle fonctionne sur Teensy

Citer
The library currently supports the AVR ATTiny84/85 & ATMega88/168/328/32u4 and Teensy 3.x using the INT0/1 Hardware Interrupt and micros() ONLY and no longer uses Timer0 Compare Match B, which makes it much more portable to other platforms.
« Modifié: mai 31, 2018, 07:52:23 am par Jean-Luc »
Cordialement

Benoit92

  • Full Member
  • ***
  • Messages: 200
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #141 le: mai 31, 2018, 10:35:34 pm »
A priori, le signal Dcc doit être branché sur la pin 1 (TX1) du Teensy 3.2 ?
Extrait de NmraDcc.cpp
 #elif defined(__arm__) && (defined(__MK20DX128__) || defined(__MK20DX256__))
        // Teensys 3.x
        #define MODE_TP1 pinMode( A1,OUTPUT )   // A1= PortC, Bit0
        #define SET_TP1  GPIOC_PSOR = 0x01
        #define CLR_TP1  GPIOC_PCOR = 0x01
        #define MODE_TP2 pinMode( A2,OUTPUT )   // A2= PortB Bit0
        #define SET_TP2  GPIOB_PSOR = 0x01
        #define CLR_TP2  GPIOB_PCOR = 0x01
        #define MODE_TP3 pinMode( A3,OUTPUT )   // A3 = PortB Bit1
        #define SET_TP3  GPIOB_PSOR = 0x02
        #define CLR_TP3  GPIOB_PCOR = 0x02
        #define MODE_TP4 pinMode( A4,OUTPUT )   // A4 = PortB Bit3
        #define SET_TP4  GPIOB_PSOR = 0x08
#define CLR_TP4 GPIOB_PCOR = 0x08

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1713
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #142 le: mai 31, 2018, 11:45:41 pm »
L’affectation de la pin d’interruption se fait via la méthode pin. Cette méthode est définie à la ligne 1246 de NmraDcc.cpp.

Regarde les exemples. Tu choisis la pin.
Cordialement

Benoit92

  • Full Member
  • ***
  • Messages: 200
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #143 le: juin 01, 2018, 11:35:03 am »
Si je comprends bien :
NmraDcc. cpp
void NmraDcc::pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup)
Dans mon sketch 'locomotive.ino', je dois donc ajouter la ligne suivante dans le setup.
Locomotive.ino
setup()
// Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
Dcc.pin(0, 1, 0);

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1713
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #144 le: juin 01, 2018, 01:02:19 pm »
Sur les Teensy 3.x toutes les broches peuvent engendrer une interruption externe.

Plutôt que de distinguer le vecteur d'interruption (0 ou 1 sur AVR) de la broche, Paul a donc choisi de donner le numéro de broche directement à la fonction attachInterrupt.

Par conséquent, lors de l'appel Dcc.pin, il faut que le numéro de broche et d'interruption soient les mêmes : le numéro de pin.

Au lieu de mettre ça sur TX, je mettrais ça sur une broche non utilisée pour conserver l'UART
Cordialement

Benoit92

  • Full Member
  • ***
  • Messages: 200
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #145 le: juin 02, 2018, 12:07:21 am »
Je peux donc mettre le signal DCC  sur l'entrée 2 du Teensy 3.2 (il n y a rien suivant le schémas Teensy 3.2 pinout).
Ce qui donnerait : Dcc.pin(2, 2, 0);

NmraDcc::pin( uint8_t ExtIntNum, uint8_t ExtIntPinNum, uint8_t EnablePullup)


Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1713
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #146 le: juin 02, 2018, 07:32:37 am »
Je pense oui.
Cordialement

Benoit92

  • Full Member
  • ***
  • Messages: 200
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #147 le: juin 02, 2018, 06:19:14 pm »
Concernant la commande moteur, cela semble à priori assez simple : pas besoin de modifier un timer (FTM0, FTM1 ou FTM2).

 void setup() {
      analogWriteFrequency(pin, frequency);// frequency in Hz
     analogWrite(pin, x) // 0<x<256 (0-100%) with analogWriteResolution(8); (8 = default value)
    }

Jean-Luc

  • Global Moderator
  • Hero Member
  • *****
  • Messages: 1713
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #148 le: juin 02, 2018, 06:27:41 pm »
Non

Les FTM sont tous sur 16 bits, ça permet beaucoup plus de réglages que sur les AVR
Cordialement

Benoit92

  • Full Member
  • ***
  • Messages: 200
    • Voir le profil
Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« Réponse #149 le: juin 02, 2018, 07:28:49 pm »
Si je change la fréquence sur une Pin, est ce que je change également la fréquence des Pins associées au même Timer suivant le tableau suivant ?:
Teensy 3.2
Timer                          Pin              Default Frequency
FTM0   5, 6, 9, 10, 20, 21, 22, 23          488.28 Hz
FTM1   3, 4                                            488.28 Hz
FTM2   25, 32                                        488.28 Hz