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.


Messages - Benoit92

Pages: [1] 2 3 ... 12
1
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« 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

2
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« 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)
    }

3
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« 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)


4
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« 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);

5
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« 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

6
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« 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

7
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« 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


8
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« 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),

9
Composants / Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: mai 30, 2018, 01:24:15 pm »
Le Teensy 3.2 (18x36 mm) est plus petit qu’un Nano donc pour gagner de la place...
Le Pro Mini a une taille équivalente (18x33 mm) et la partie USB n’est plus nécessaire une fois le projet terminé.

Mais côté mémoire je vois mal comment se contenter de 32k de flash (AtMega328) par rapport aux 256k du Teensy, surtout pour la Ram (2k contre 64k).
C'est vrai, mais la bibliothèque NmraDcc (qui permet de décoder les trames DCC) n'est pas compatible avec le Teensy.
Donc, je suis obligé de rester sur Arduino pour assurer le décodage de la trame DCC.
J'ai déjà monté l'Arduino Nano sur une locomotive mais je n'assure que les fonctions commande moteur (pont H), éclairages et feux.

ESP32 ou Arduino Nano : je n'ai pas de préférence : j'ai déjà  5 Nano acheté pour 10,00 € chez Aliexpress.

10
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: mai 29, 2018, 11:55:44 pm »
Je vais essayer avec la librairie Teensy Audio.h : on ne sait jamais !
Sinon, je pense utiliser le principe suivant : (j'avais comparé plusieurs techniques plus avant dans ce sujet) :
2) Arduino + EncodeAudio + Bibliothèque <PCM.h> + sortie PWM
Avantages :
Qualité de son moyenne mais acceptable pour réaliser du bruitage (8 bits – 8kHz)
Fichiers « son » codé avec EncodeAudio -> fichiers « son » de petite taille
Inconvénients :
Essentiellement lié au fait que l’arduino ne possède que peu de mémoire (Flash ou RAM)

Les"sons" seront chargés dans une  SPI Flash Winbond 25Q64BVSIG (8 Mo).
Je pourrais essayer d'augmenter la résolution et la fréquence d'échantillonnage.
Je vais essayer également de tout faire tenir sur un Arduino Nano (commande moteur, éclairages diverses, bruitage) car même en travaillant à l'échelle 1, il n'y a pas tellement de place (en particulier sur la BR80= petite locomotive à vapeur 030).
Il faut que je case dans la locomotive :

 1 - Un Arduino Nano
 2 - Un pont en H (pour les moteurs)
 3 - une minicarte avec la SPI Flash Winbond 25Q64BVSIG
 4 - Une petite carte amplificatrice (son)
 5 - Un haut-parleur
 6 - Une carte de décodage Dcc + alimentation 5V + alimentation 16 V (pour les moteurs)




11
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: mai 29, 2018, 09:50:58 pm »
Bonjour,
Si j'utilise à la place du Teensy, un arduino pour lire des fichiers "son" à partir d'une SPI Flash,
comment devrais-je procéder pour :
 - Écrire dans la SPI Flash à partir d'un fichier "son" qui est situé sur le PC
 - Lire ce fichier "son" sur l'arduino (à partir de son nom de fichier)
Merci

12
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: mai 24, 2018, 09:12:46 pm »
Bon, voilà, ça marche bien. C'est un peu béton, mais ça marche.
Je pense que ce code pourrait être transcrit pour un Arduino en utilisant des fichiers codés en PWM.
Pour l'instant, je n'utilise pas encore le mixage de deux fichiers "son": Il faut que je regarde sur le site PRJC Teensy.
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

    //A0A8B14.TRW = 'a' Engine start - Pantograph up
    //A1AB814.TRW = 'z' Compressor + air release
    //A2AB814.TRW = 'e' Horn
    //A3AB814.TRW = 'r' Start driving
    //A4AB814.TRW = 't' Driving
    //A5AB814.TRW = 'y' Brake
    //A6AB814.TRW = 'u' Compressor - Air release + engine start
    //A7AB814.TRW = 'i' Uncoupling
    //A8AB814.TRW = 'o' Stop driving
    //A9AB814.TRW = 'p' Stand-by engine

const int FLASH_CHIP_SELECT = 10; 
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioPlaySerialflashRaw  playFlashRaw1;  //xy=228,273
AudioOutputAnalog        dac1;           //xy=751,337
AudioConnection          patchCord1(playFlashRaw1, 0, dac1, 0);
// GUItool: end automatically generated code

int lu;     // Données lu liaison série
int Oldlu;  // Données lu liaison série

void setup() {
    Serial.begin(9600); // Initialisation liaison série
    while (!Serial && millis()<500 );
    AudioMemory(50);// Réservation espace mémoire
    analogReference(EXTERNAL);//Configurer Amplitude 3,3V pour le DAC

//************************************
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(11); //7
  SPI.setMISO(12);
  SPI.setSCK(14);
//************************************
    delay(2000);
    if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
        while (1){
            Serial.println ("Cannot access SPI Flash chip");
            delay (10000);
        }
    }
}
    void playFile1(const char *filename)// Fonction lecture fichier audio
    {
      SerialFlashFile ff = SerialFlash.open(filename);
      Serial.print("Playing file1: ");
      Serial.println(ff);
      playFlashRaw1.play(filename);
     // Simply wait for the file to finish playing.
     while (playFlashRaw1.isPlaying()) {
     }
    }
   
void loop() {
if ( Serial.available() ) {
    lu = Serial.read();
    Serial.println(lu);
  }
  else {
    Serial.println("Rien");
  }

switch (lu) {
   case 'a':{  // Fichier à lire en boucle 
     Oldlu = 'a';   
     playFile1("A0AB814.TRW");
     break;
   }
   case 'z':{  // Fichier à lire en boucle 
      Oldlu = 'z';  // Lecture en boucle 
      playFile1("A1AB814.TRW");
      break;
   }   
           case 'e':{   // Fichier à lire une seule fois   
           playFile1("A2AB814.TRW");
           lu=Oldlu; // reprise fichier précédent
           Serial.println(lu);
           break;
           }
    case 't':{  // Fichier à lire en boucle 
     Oldlu = 't';
     playFile1("A4A814.TRW");
     break;
    }   
    case 'y':{  // Fichier à lire en boucle 
     Oldlu = 'y';
     playFile1("A5AB814.TRW");
      break;
    }   
    case 'u':{  // Fichier à lire en boucle 
      Oldlu = 'u'; 
      playFile1("A6AB814.TRW");
     break;
    }       
    case 'i':{  // Fichier à lire en boucle   
      Oldlu = 'i';
      playFile1("A7AB814.TRW");
      break;
    }   
    case 'o':{  // Fichier à lire en boucle 
      Oldlu = 'o'; 
      playFile1("A8AB814.TRW");
      break;
    } 
    case 'p':{  // Fichier à lire en boucle 
      Oldlu = 'p'; 
      playFile1("A9A814.TRW");
      break;
   }     
  }
}

13
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: mai 23, 2018, 09:04:41 pm »
Ok, merci Jean-Luc.

14
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: mai 22, 2018, 11:29:03 pm »
Bonjour,
Le code ci-dessous fonctionne bien.
Il est possible de jouer en boucle le son sélectionné en appuyant sur les touches "a", "z", "e"," r", "t", "y", "u", "i", "o", ou "p" à partir du moniteur série.
Le son tourne en boucle tant que je n'ai pas appuyé sur une autre touche.

Je souhaiterai que lorsque j'appuie sur la touche : 'e' Horn, ce fichier soit lu une seule fois et qu'ensuite, le fichier lu précédemment soit repris en boucle.
Exemple :
1) 't' Driving en boucle (par appui sur 't')
2) 'e' Horn (par appui sur 'e') : Ce fichier ne doit être lu qu'une seule fois.
3) Reprise de la lecture du fichier précédent en boucle, c'est à dire 't'Driving dans cet exemple, mais cela peut être un autre fichier.

Je ne vois pas trop par quel mécanisme, je pourrai obtenir ce résultat ?

#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
    //A0A8B14.TRW = 'a' Engine start - Pantograph up
    //A1AB814.TRW = 'z 'Compressor + air release
    //A2AB814.TRW = 'e 'Horn
    //A3AB814.TRW = 'r' Start driving
    //A4AB814.TRW = 't' Driving
    //A5AB814.TRW = 'y' Brake
    //A6AB814.TRW = 'u' Compressor - Air release + engine start
    //A7AB814.TRW = 'i' Uncoupling
    //A8AB814.TRW = 'o' Stop driving
    //A9AB814.TRW = 'p' Stand-by engine

const int FLASH_CHIP_SELECT = 10; 
// GUItool: begin automatically generated code
AudioPlaySerialflashRaw  playFlashRaw1;  //xy=228,273
AudioOutputAnalog        dac1;           //xy=751,337
AudioConnection          patchCord1(playFlashRaw1, 0, dac1, 0);
// GUItool: end automatically generated code

int lu;

void setup() {
    Serial.begin(9600);
    while (!Serial && millis()<500 );
    AudioMemory(50);
    analogReference(EXTERNAL);

//************************************
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(11); //7
  SPI.setMISO(12);
  SPI.setSCK(14);
//************************************
    delay(2000);
    if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
        while (1){
            Serial.println ("Cannot access SPI Flash chip");
            delay (10000);
        }
    }
}
void playFile(const char *filename)
{
  SerialFlashFile ff = SerialFlash.open(filename);
  Serial.print("Playing file: ");
  Serial.println(ff);

  playFlashRaw1.play(filename);
  // Simply wait for the file to finish playing.
  while (playFlashRaw1.isPlaying()) {
   }
}   

void loop() {
if ( Serial.available() ) {
    lu = Serial.read();
    Serial.println(lu);
  }
  else {
    Serial.println("Rien");
  }

switch (lu) {
  case 'a':{
    playFile("A0AB814.TRW");
    break;
   }
  case 'z':{ 
    playFile("A1AB814.TRW");
    break;
   }   
  case 'e':{   
    playFile("A2AB814.TRW");
    break;
   }
  case 't':{ 
    playFile("A4A814.TRW");
    break;
   }   
  case 'y':{ 
    playFile("A5AB814.TRW");
    break;
   }   
  case 'u':{ 
    playFile("A6AB814.TRW");
    break;
   }       
  case 'i':{ 
    playFile("A7AB814.TRW");
    break;
   }   
  case 'o':{ 
    playFile("A8AB814.TRW");
    break;
   } 
  case 'p':{ 
    playFile("A9A814.TRW");
    break;
   }     
    //  default:
    // statements
  }
}

Nota : A0A8B14.TRW est un fichier "son" avec l'extension "TRW" compatible avec la bibliothèque du Teensy.

15
Composants / Re : Teensy 3.1, 3.2 - Sonorisation locomotive
« le: mai 01, 2018, 09:11:55 pm »
Bon, après un certain nombre de discussion et d'essai sur le forum PRJC, tout marche ! ! !
A la base, il y avait un problème de synchro entre le flux de données sur la liaison "Arduino" et le script Python.
Le sketch Arduino (CopyFromSerialMC.ino) permet de charger dans la SPI Flash les données de fichier "son" sont remontées par le script Python (rawfile-uploader-mc.py)
Le sketch Arduino est lancé et démarre, puis, il s'arrête et attend le caractère "c" que le fournit le script Python lorsque celui-ci est lancé (fenêtre de commande Windows).
Ci-joint, les codes en question :
CopyFromSerialMC.ino
/*
 * This is free and unencumbered software released into the public domain.
 * ARDUINO / Teensy Modified Monitor Control added.....Apr2018......
 * Anyone is free to copy, modify, publish, use, compile, sell, or
 * distribute this software, either in source code form or as a compiled
 * binary, for any purpose, commercial or non-commercial, and by any
 * means.
 *
 * In jurisdictions that recognize copyright laws, the author or authors
 * of this software dedicate any and all copyright interest in the
 * software to the public domain. We make this dedication for the benefit
 * of the public at large and to the detriment of our heirs and
 * successors. We intend this dedication to be an overt act of
 * relinquishment in perpetuity of all present and future rights to this
 * software under copyright law.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * For more information, please refer to <http://unlicense.org>
 * -------------------------------------------------------------------------
 *
 * This is example code to 1) format an SPI Flash chip, and 2) copy raw
 * audio files (mono channel, 16 bit signed, 44100Hz) to it using the
 * SerialFlash library.  The audio can then be played back using the
 * AudioPlaySerialflashRaw object in the Teensy Audio library.
 *
 * To convert a .wav file to the proper .RAW format, use sox:
 * sox input.wav -r 44100 -b 16 --norm -e signed-integer -t raw OUTPUT.RAW remix 1,2
 *
 * Note that the OUTPUT.RAW filename must be all caps and contain only the following
 * characters: A-Z, 0-9, comma, period, colon, dash, underscore.  (The SerialFlash
 * library converts filenames to caps, so to avoid confusion we just enforce it here).
 *
 * It is a little difficult to see what is happening; aswe are using the Serial port
 * to upload files, we can't just throw out debug information.  Instead, we use the LED
 * (pin 13) to convey state.
 *
 * While the chip is being formatted, the LED (pin 13) will toggle at 1Hz rate.  When
 * the formatting is done, it flashes quickly (10Hz) for one second, then stays on
 * solid.  When nothing has been received for 3 seconds, the upload is assumed to be
 * completed, and the light goes off.
 *
 * Use the 'rawfile-uploader.py' python script (included in the extras folder) to upload
 * the files.  You can start the script as soon as the Teensy is turned on, and the
 * USB serial upload will just buffer and wait until the flash is formatted.
 *
 * This code was written by Wyatt Olson <wyatt@digitalcave.ca> (originally as part
 * of Drum Master http://drummaster.digitalcave.ca and later modified into a
 * standalone sample).
 *
 * Enjoy!
 *
 *     // xxxx ... MONITOR CONTROL ADDED ........Apr 2018.........
 *
 */

#include <SerialFlash.h>
#include <SPI.h>

const int FlashChipSelect = 10; // digital pin for flash chip CS pin
//const int FlashChipSelect = 21; // Arduino 101 built-in SPI Flash
// I coul;dn't get #define CSPIN 6 to work so put in the FlashChipSelect = 6 line .....xxxxxxxxxxxxxxxxxxxx

//Buffer sizes
#define USB_BUFFER_SIZE      256   // was 128
#define FLASH_BUFFER_SIZE    8192  //was 4096

//Max filename length (8.3 plus a null char terminator)
#define FILENAME_STRING_SIZE      13

//State machine
#define STATE_START      0
#define STATE_SIZE      1
#define STATE_CONTENT    2

//Special bytes in the communication protocol
#define BYTE_START      0x7e
#define BYTE_ESCAPE      0x7d
#define BYTE_SEPARATOR    0x7c


//SPI Pins (these are the values on the Audio board; change them if you have different ones)
//#define MOSI               11 //7
//#define MISO              12
//#define SCK               14
// #define CSPIN              6
//#define CSPIN           21  // Arduino 101 built-in SPI Flash


void setup(){
 
   pinMode(13, OUTPUT);    // Teensy LED pin
   
  Serial.begin(9600);  //Teensy serial is always at full USB speed and buffered... the baud rate here is required but ignored
 
  delay(1000);
 
  Serial.println("Enter char...  c  ...to Start Erase and Copy Files Sketch");

  while(Serial.read() != 'c');

  Serial.println("Erase and Copy Sketch Started");
 
   
  //Set up SPI
  SPI.setMOSI(11);  // uncomment these if using the alternate pins
  SPI.setMISO(12);  // these are the standard pins for the Teensy 3.2 & Audio Adaptor board conbination
  SPI.setSCK(14);
 

 if (!SerialFlash.begin(FlashChipSelect)) {
    while (1) {
      Serial.println("Unable to a access SPI Flash chip");
      delay(1000);
    }
  }
 
// Double flash LED a few times to warn Erase is about to begin ..........
  for(uint8_t i = 0; i < 3; i++){
    delay(100);
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
  delay(100);
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
    delay(1000);
  }
                 
  //We start by formatting the flash...
  uint8_t id[5];
  SerialFlash.readID(id);
  SerialFlash.eraseAll();
 
  //Flash LED at 1Hz while formatting
  while (!SerialFlash.ready()) {
    delay(500);
    digitalWrite(13, HIGH);
    delay(500);
    digitalWrite(13, LOW);
  }

  //Quickly flash LED a few times when completed, then leave the light on solid
  for(uint8_t i = 0; i < 10; i++){
    delay(100);
    digitalWrite(13, HIGH);
    delay(100);
    digitalWrite(13, LOW);
  }
  digitalWrite(13, HIGH);
 
  delay(1000);
 
  Serial.println("Full Erase Has Completed...Now Unplug USB & Plug in USB again to reset COMMS");
  Serial.println("Close Arduino Serial Monitor");
  Serial.println("Run Python rawfile-uploader-mc script from a new CMDline or batch file.");
  Serial.println("Teesny LED goes out when Copy Files has completed");
 
  //We are now going to wait for the upload program
  while(!Serial.available());
 
  SerialFlashFile flashFile;
 
  uint8_t state = STATE_START;
  uint8_t escape = 0;
  uint8_t fileSizeIndex = 0;
  uint32_t fileSize = 0;
  char filename[FILENAME_STRING_SIZE];
 
  char usbBuffer[USB_BUFFER_SIZE];
  uint8_t flashBuffer[FLASH_BUFFER_SIZE];
 
  uint16_t flashBufferIndex = 0;
  uint8_t filenameIndex = 0;
 
  uint32_t lastReceiveTime = millis();
 
    // .... We assume the serial receive part is finished when we have not received something for 3 seconds
    // ..... parenthesis added around this bit on line below........... (lastReceiveTime + 3000) > millis()....reads better...
 
  while(Serial.available() || (lastReceiveTime + 3000) > millis()){
    uint16_t available = Serial.readBytes(usbBuffer, USB_BUFFER_SIZE);
    if (available){
      lastReceiveTime = millis();
    }

    for (uint16_t usbBufferIndex = 0; usbBufferIndex < available; usbBufferIndex++){
      uint8_t b = usbBuffer[usbBufferIndex];
     
      if (state == STATE_START){
        //Start byte.  Repeat start is fine.
        if (b == BYTE_START){
          for (uint8_t i = 0; i < FILENAME_STRING_SIZE; i++){
            filename[i] = 0x00;
          }
          filenameIndex = 0;
        }
        //Valid characters are A-Z, 0-9, comma, period, colon, dash, underscore
        else if ((b >= 'A' && b <= 'Z') || (b >= '0' && b <= '9') || b == '.' || b == ',' || b == ':' || b == '-' || b == '_'){
          filename[filenameIndex++] = b;
          if (filenameIndex >= FILENAME_STRING_SIZE){
            //Error name too long
            flushError();
            return;
          }
        }
        //Filename end character
        else if (b == BYTE_SEPARATOR){
          if (filenameIndex == 0){
            //Error empty filename
            flushError();
            return;
          }
         
          //Change state
          state = STATE_SIZE;
          fileSizeIndex = 0;
          fileSize = 0;
         
        }
        //Invalid character
        else {
          //Error bad filename
          flushError();
          return;
        }
      }
      //We read 4 bytes as a uint32_t for file size
      else if (state == STATE_SIZE){
        if (fileSizeIndex < 4){
          fileSize = (fileSize << 8) + b;
          fileSizeIndex++;
        }
        else if (b == BYTE_SEPARATOR){
          state = STATE_CONTENT;
          flashBufferIndex = 0;
          escape = 0;
         
          if (SerialFlash.exists(filename)){
            SerialFlash.remove(filename);  //It doesn't reclaim the space, but it does let you create a new file with the same name.
          }
         
          //Create a new file and open it for writing
          if (SerialFlash.create(filename, fileSize)) {
            flashFile = SerialFlash.open(filename);
            if (!flashFile) {
              //Error flash file open
              flushError();
              return;
            }
          }
          else {
            //Error flash create (no room left?)
            flushError();
            return;
          }
        }
        else {
          //Error invalid length requested
          flushError();
          return;
        }
      }
      else if (state == STATE_CONTENT){
        //Previous byte was escaped; unescape and add to buffer
        if (escape){
          escape = 0;
          flashBuffer[flashBufferIndex++] = b ^ 0x20;
        }
        //Escape the next byte
        else if (b == BYTE_ESCAPE){
          //Serial.println("esc");
          escape = 1;
        }
        //End of file
        else if (b == BYTE_START){
          //Serial.println("End of file");
          state = STATE_START;
          flashFile.write(flashBuffer, flashBufferIndex);
          flashFile.close();
          flashBufferIndex = 0;
        }
        //Normal byte; add to buffer
        else {
          flashBuffer[flashBufferIndex++] = b;
        }
       
        //The buffer is filled; write to SD card
        if (flashBufferIndex >= FLASH_BUFFER_SIZE){
          flashFile.write(flashBuffer, FLASH_BUFFER_SIZE);
          flashBufferIndex = 0;
        }
      }
    }
  }

  //Success!  Turn the light off.
  digitalWrite(13, LOW);
}

void loop(){
  //Do nothing.
}

void flushError(){
  uint32_t lastReceiveTime = millis();
  char usbBuffer[USB_BUFFER_SIZE];
  //We assume the serial receive part is finished when we have not received something for 3 seconds
  // ..... parenthesis added around this bit on line below........... (lastReceiveTime + 3000) > millis()....reads better...
  while(Serial.available() || (lastReceiveTime + 3000) > millis()){
    if (Serial.readBytes(usbBuffer, USB_BUFFER_SIZE)){
      lastReceiveTime = millis();
    }
  }
}

rawfile-uploader-mc.py
#!/usr/bin/python
#
# Uploads raw audio files to Teensy + Audio board with SPI Flash on board.  To use this program, first
# load the 'CopyFromSerial' example sketch.  When it first runs, it will format the SPI flash chip
# (this may take a long time for larger chips; a 128MB chip that I am using can take almost 10 minutes,
# but smaller 16MB ones should be faster).
#
# While the chip is being formatted, the LED (pin 13) will toggle at 1Hz rate.  When the formatting is
# done, it flashes quickly (10Hz) for one second, then stays on solid.  When nothing has been received
# for 3 seconds, the upload is assumed to be completed, and the light goes off.
#
# You can start this program immediately upon plugging in the Teensy.  It will buffer and wait until
# the Teensy starts to read the serial data from USB.
#
###################

import serial, sys, os, time

if (len(sys.argv) <= 2):
print("Usage: '" + sys.argv[0] + " <port> <files>' where:\n\t<port> is the TTY USB port connected to Drum Master\n\t<files> is a list of .RAW files (bash globs work).")
sys.exit()

#Special bytes
BYTE_START = "\x7e"
BYTE_ESCAPE = "\x7d"
BYTE_SEPARATOR = "\x7c"

#Flash size (in MB).  Change this to match how much space you have on your chip.
FLASH_SIZE = 8

totalFileSize = 0;
for i, filename in enumerate(sys.argv):
if (i >= 2):
totalFileSize = totalFileSize + os.path.getsize(filename)

flashSizeBytes = FLASH_SIZE * 1024 * 1024
if (totalFileSize > flashSizeBytes):
print("Too many files selsected.\n\tTotal flash size:\t" + "{:>14,}".format(flashSizeBytes) + " bytes\n\tTotal file size:\t" + "{:>14,}".format(totalFileSize) + " bytes")
sys.exit()
#ser = serial.Serial(sys.argv[1], 9600, timeout=0, writeTimeout=None)
ser = serial.Serial(sys.argv[1])
ser.write("c")
print("Uploading " + str(len(sys.argv) - 2) + " files...")
for i, filename in enumerate(sys.argv):
if (i >= 2):
startTime = time.time();
sys.stdout.write(str(i - 1) + ": ")
sys.stdout.write(filename)
sys.stdout.flush()


f = open(filename, "rb")
fileLength = os.path.getsize(filename)
try:
encoded = []
#Start byte
encoded.append(BYTE_START)
#Filename
for byte in os.path.basename(filename):
encoded.append(byte)
#End of filename
encoded.append(BYTE_SEPARATOR)

#File length (uint32_t)
encoded.append(chr((fileLength >> 24) & 0xFF));
encoded.append(chr((fileLength >> 16) & 0xFF));
encoded.append(chr((fileLength >> 8) & 0xFF));
encoded.append(chr((fileLength >> 0) & 0xFF));
encoded.append(BYTE_SEPARATOR)

#Binary data, with escaping
for byte in f.read():
if byte == BYTE_START or byte == BYTE_ESCAPE:
encoded.append(BYTE_ESCAPE)
encoded.append(chr(ord(byte) ^ 0x20))
else:
encoded.append(byte);

#Write end of data byte
encoded.append(BYTE_START)
ser.write("".join(encoded))

finally:
f.close()

endTime = time.time();
print(" (" + str(round(fileLength / 1024 / (endTime - startTime), 2)) + " KB/s)");

print("All files uploaded")

Pour la lecture du son à partir de la SPI Flash vers le DAC (convertisseur Numérique -> Analogique), ci-joint un petit sketch "Teensy" - le choix du fichier à lire est réalisé en tapant sur une touche du clavier :
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

//#define FLASH_CHIP_SELECT 10

const int FLASH_CHIP_SELECT = 10; 
// GUItool: begin automatically generated code
AudioPlaySerialflashRaw  playFlashRaw1;  //xy=228,273
AudioOutputAnalog        dac1;           //xy=751,337
AudioConnection          patchCord1(playFlashRaw1, 0, dac1, 0);
// GUItool: end automatically generated code
int lu;
void setup() {
    Serial.begin(9600);
    while (!Serial && millis()<500 );
    AudioMemory(50);
    analogReference(EXTERNAL);

//************************************
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(11); //7
  SPI.setMISO(12);
  SPI.setSCK(14);
//************************************
    delay(2000);
    if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
        while (1){
            Serial.println ("Cannot access SPI Flash chip");
            delay (10000);
        }
    }
}
void playFile(const char *filename)
{
  SerialFlashFile ff = SerialFlash.open(filename);
  Serial.print("Playing file: ");
  Serial.println(ff);

  playFlashRaw1.play(filename);
  // Simply wait for the file to finish playing.
  while (playFlashRaw1.isPlaying()) {
   }
}   

void loop() {
if ( Serial.available() ) {
    lu = Serial.read();
    Serial.println(lu);
  }
//  else {
//    Serial.println("Rien");
//  }
switch (lu) {
  case 'a': {
    playFile("A0A814.TRW");
    break;
   }
  case 'z':{ 
    playFile("A1A814.TRW");
    break;
   }   
  case 'e':{   
    playFile("A2A814.TRW");
    break;
   }   
  case 'r':{ 
    playFile("A3A814.TRW");
    break;
   }   
  case 't':{ 
    playFile("A4A814.TRW");
    break;
   }   
  case 'y':{ 
    playFile("A5A814.TRW");
    break;
   }   
  case 'u':{ 
    playFile("A6A814.TRW");
    break;
   }       
  case 'i':{ 
    playFile("A7A814.TRW");
    break;
   }   
  case 'o':{ 
    playFile("A8A814.TRW");
    break;
   }   
//  default:
//    // statements
//  }
  }
}

Pages: [1] 2 3 ... 12