LOCODUINO

Parlons Arduino => Composants => Discussion démarrée par: Benoit92 le décembre 23, 2017, 01:38:31 am

Titre: Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 23, 2017, 01:38:31 am
Bonjour,
Je ne sais pas si c'est le bon forum qui semble être dédié à l'Arduino.
Pour les applications gestion moteur et accessoires, l'Arduino Nano fonctionne très bien.
Par contre, pour la gestion de son (données "son" intégrés au code), la capacité mémoire est insuffisante pour générer des sons de qualité.
J'ai donc installé le logiciel de chez PJRC "Teensyduino" qui me permet d'utiliser le même IDE que l'Arduino.

1) Pour coder le son,   il semble qu'il faille passer par "wav2sketch" (au lieu de "EncodeAudio" pour l'Arduino).

Type de fichier son (par exemple) : AudioSampleCashregister.h
// Audio data converted from WAV file by wav2sketch
#include "AudioSampleCashregister.h"

// Converted from cashregister.wav, using 22050 Hz, u-law encoding
const unsigned int AudioSampleCashregister[5809] = {
0x02005AB4,0x82060707,0x03010301,0x08038287,0x81820200,0x09120407,0x15091108,0x02080611,
0x0D050D11,0x8008150C,0x93810480,0x000D8890,0x0A060406,0x06000681,0x80828702,0x89928405,
0x04820983,0x8C860D05,0x880D0004,0x84000B0B,0x8C8D8C8F,0x84829181,0x14860600,0x0A0C080C,
0x84878006,0x908B8B8D,0x0000858D,0x82800710, ....................................
};

2) Ce Header sera intégré dans un fichier *.ino :
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <Bounce.h>

// WAV files converted to code by wav2sketch
#include "AudioSampleSnare.h"        // http://www.freesound.org/people/KEVOY/sounds/82583/
#include "AudioSampleTomtom.h"       // http://www.freesound.org/people/zgump/sounds/86334/
#include "AudioSampleHihat.h"        // http://www.freesound.org/people/mhc/sounds/102790/
#include "AudioSampleKick.h"         // http://www.freesound.org/people/DWSD/sounds/171104/
#include "AudioSampleGong.h"         // http://www.freesound.org/people/juskiddink/sounds/86773/
#include "AudioSampleCashregister.h" // http://www.freesound.org/people/kiddpark/sounds/201159/

// Create the Audio components.  These should be created in the
// order data flows, inputs/sources -> processing -> outputs
//
AudioPlayMemory    sound0;
AudioPlayMemory    sound1;  // six memory players, so we can play
AudioPlayMemory    sound2;  // all six sounds simultaneously
AudioPlayMemory    sound3;
AudioPlayMemory    sound4;
AudioPlayMemory    sound5;
AudioMixer4        mix1;    // two 4-channel mixers are needed in
AudioMixer4        mix2;    // tandem to combine 6 audio sources
AudioOutputI2S     headphones;
AudioOutputAnalog  dac;     // play to both I2S audio board and on-chip DAC

// Create Audio connections between the components
//
AudioConnection c1(sound0, 0, mix1, 0);
AudioConnection c2(sound1, 0, mix1, 1);
AudioConnection c3(sound2, 0, mix1, 2);
AudioConnection c4(sound3, 0, mix1, 3);
AudioConnection c5(mix1, 0, mix2, 0);   // output of mix1 into 1st input on mix2
AudioConnection c6(sound4, 0, mix2, 1);
AudioConnection c7(sound5, 0, mix2, 2);
AudioConnection c8(mix2, 0, headphones, 0);
AudioConnection c9(mix2, 0, headphones, 1);
AudioConnection c10(mix2, 0, dac, 0);

// Create an object to control the audio shield.
//
AudioControlSGTL5000 audioShield;

// Bounce objects to read six pushbuttons (pins 0-5)
//
Bounce button0 = Bounce(0, 5);
Bounce button1 = Bounce(1, 5);  // 5 ms debounce time
Bounce button2 = Bounce(2, 5);
Bounce button3 = Bounce(3, 5);
Bounce button4 = Bounce(4, 5);
Bounce button5 = Bounce(5, 5);


void setup() {
  // Configure the pushbutton pins for pullups.
  // Each button should connect from the pin to GND.
  pinMode(0, INPUT_PULLUP);
  pinMode(1, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);

  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(10);

  // turn on the output
  audioShield.enable();
  audioShield.volume(0.5);

  // by default the Teensy 3.1 DAC uses 3.3Vp-p output
  // if your 3.3V power has noise, switching to the
  // internal 1.2V reference can give you a clean signal
  //dac.analogReference(INTERNAL);

  // reduce the gain on mixer channels, so more than 1
  // sound can play simultaneously without clipping
  mix1.gain(0, 0.4);
  mix1.gain(1, 0.4);
  mix1.gain(2, 0.4);
  mix1.gain(3, 0.4);
  mix2.gain(1, 0.4);
  mix2.gain(2, 0.4);
}

void loop() {
  // Update all the button objects
  button0.update();
  button1.update();
  button2.update();
  button3.update();
  button4.update();
  button5.update();

  // When the buttons are pressed, just start a sound playing.
  // The audio library will play each sound through the mixers
  // so any combination can play simultaneously.
  //
  if (button0.fallingEdge()) {
    sound0.play(AudioSampleSnare);
  }
  if (button1.fallingEdge()) {
    sound1.play(AudioSampleTomtom);
  }
  if (button2.fallingEdge()) {
    sound2.play(AudioSampleHihat);
  }
  if (button3.fallingEdge()) {
    sound3.play(AudioSampleKick);
  }
  if (button4.fallingEdge()) {
    // comment this line to work with Teensy 3.0.
    // the Gong sound is very long, too much for 3.0's memory
    sound4.play(AudioSampleGong);
  }
  if (button5.fallingEdge()) {
    sound5.play(AudioSampleCashregister);
  }

}


3) wav2sketch
Tout est expliqué sur le site ci-dessous ainsi que le lien pour le téléchargement de "wav2sketch.exe"
https://www.pjrc.com/teensy/td_libs_AudioPlayMemory.html
(https://zupimages.net/up/17/51/ycqd.jpg) (http://zupimages.net/viewer.php?id=17/51/ycqd.jpg)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le décembre 23, 2017, 01:13:01 pm
Bonjour,
Ca ne traite pas spécifiquement du Teensy, mais plutôt d’un projet.

On pourra le déplacer plus tard.

Bon Noël
Dominique
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 23, 2017, 03:08:43 pm
Connaissez-vous la différence entre les 2 mèthodes ?:

1) intégrer directement les données de "son" dans le code (comme train35)
ou
2) intégrer les données "son" dans un fichier xxx.h, puis faire un #include "xxx.h" dans le programme .ino
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le décembre 23, 2017, 03:14:28 pm
Normalement il n’y a pas de différence : le compilateur mettra les données du .h dans le programme.

Le découpage du source en plusieurs fichiers placés dans le même dossier que .ino n’est rien d’autre qu’une organisation plus pratique des codes sources. C’est équivalent à tout mettre dans le même fichier.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 28, 2017, 06:05:02 pm
J'essaye d'avancer sur le Teensy (ça a l'air moins "simple" que l'Arduino).
J'ai repris l'exemple/PlayFromSketch" : https://github.com/lukvog/HUGO/blob/master/libraries/Audio_master/examples/PlayFromSketch/PlayFromSketch.ino comme recommandé sur le forum "PJRC forums".
J'ai enlevé tout ce qui concerne la shield : SGTL5000 audioShield. Sur PJRC, ce circuit, associé avec un teensy permet de réaliser des projets de gestion de sons assez complexes.
Cela donne :
PlayFromSketchV0.ino
// from PlayFromSketch.ino
//#include <output_dac.h>
//#include <output_dacs.h>
//#include <output_pwm.h>
//#include <play_memory.h>
//#include <spi_interrupt.h>
#include "Arduino.h"
#include <Audio.h>
//#include <Wire.h>
//#include <Bounce.h>

// WAV files converted to code by wav2sketch
#include <AudioSampleSnare.h>        // http://www.freesound.org/people/KEVOY/sounds/82583/

// Create the Audio components.  These should be created in the
// order data flows, inputs/sources -> processing -> outputs
AudioPlayMemory    sound0;
AudioOutputAnalog  dac;     // play to both I2S audio board and on-chip DAC

// Create Audio connections between the components
//
AudioConnection c1(sound0,dac);

void setup() {

  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(10);
  analogWriteResolution(12);

  // turn on the output
//  audioShield.enable();
//  audioShield.volume(50);

  // by default the Teensy 3.1 DAC uses 3.3Vp-p output
  // if your 3.3V power has noise, switching to the
  // internal 1.2V reference can give you a clean signal
  //dac.analogReference(INTERNAL);

}

void loop() {
   sound0.play(AudioSampleSnare);

}

AudioSampleSnare.cpp
// Audio data converted from WAV file by wav2sketch
// Converted from AudioSampleSnare.wav, using 22050 Hz, u-law encoding

const unsigned int AudioSampleSnare [2817] = {
0x02002BD3,0x65636656,0x6B6A6B67,0x7071706F,0x43637171,0x29ABBA23,0x3137474C,0x3A4A544D,
0x30C1542C,0xE14F6360,0xEDDCE2E6, ............................................
};

AudioSampleSnare.h
// Audio data converted from WAV file by wav2sketch
extern const unsigned int AudioSampleSnare[2817];

Résultat de la compilation :
C:\Documents\Arduino\PlayFromSketchV0\PlayFromSketchV0.ino:13:92: fatal error: AudioSampleSnare.h: No such file or directory
compilation terminated.
Erreur de compilation pour la carte Teensy 3.2 / 3.1
J'ai fait un certain nombre d'essais, mais je ne vois pas d'où vient l'erreur (certainement une erreur de débutant!) ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: maxou9914 le décembre 28, 2017, 11:28:13 pm
Test en remplaçant  :
#include "AudioSampleSnare.h" 
Par
#include <AudioSampleSnare.h>

J'ai déjà eu le cas où le problème venait de là.

En attente de la suite  ;)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 29, 2017, 12:02:22 am
J'ai essayé, mais cela donne le même résultat.
Par contre, j'ai lu également sur eskimon.fr dans la rubrique "Organisez votre code en fichiers":
Il peut arriver que le lien avec les symboles/librairies Arduino ne se fasse pas correctement.
Dans ce cas là, rajoutez l’include suivant au début de votre .h ou .cpp : #include "Arduino.h".

Même message d'erreur!
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le décembre 29, 2017, 09:49:23 am
C’est normal que le nom du .ino que tu compiles ne soit pas le même que celui dont tu as donné le listing ?
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le décembre 29, 2017, 09:59:55 am
Dans ce cas là, rajoutez l’include suivant au début de votre .h ou .cpp : #include "Arduino.h".

Pour programmer un Teensy, c’est sûrement pas très efficace  ;D :o 8)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le décembre 29, 2017, 10:05:03 am
Mais il y a un Arduino.h dans la lib du Teensy Dominique  :)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le décembre 29, 2017, 11:00:36 am
Et bien j’ai encore appris quelque chose ! Merci Jean-Luc !
Comme dirai ... c’est l’altitude ;)
Je vais regarder ce qu’il y a dedans.

J’ai le temps : 3 semaines à la montagne ;)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 29, 2017, 11:34:31 am
J'ai repris mon post (ci-dessus) décrivant PlayFromSketch.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le décembre 29, 2017, 11:45:01 am
Juste une question : As tu bien sélectionné Teensy 3.2 / 3.1 dans Outils > Type de carte ?

Parce que je viens de télécharger https://codeload.github.com/lukvog/HUGO/zip/master, https://github.com/lukvog/HUGO, j'ai mis Audio_master dans librairies, relancé l'IDE, sélectionné Fichier > exemples  Audio_master > PlayFromSketch, je n'ai rien changé à l'exemple, et ça compile
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 29, 2017, 01:32:35 pm
Merci Jean-Luc,
J'ai bien choisi le Teensy 3.1 - 3.2 dans l'IDE pour la compilation. Mais, je vais revérifié !
Où as-tu mis les fichiers son "AudioSampleSnare.h", "AudioSampleSnare.cpp",.......... ?

Nota :
En intégrant le fichier son dans le corps du programme, ça compile, mais ce n'est pas très propre !
Opening Teensy Loader...
Le croquis utilise 31668 octets (12%) de l'espace de stockage de programmes. Le maximum est de 262144 octets.
Les variables globales utilisent 9720 octets (14%) de mémoire dynamique, ce qui laisse 55816 octets pour les variables locales. Le maximum est de 65536 octets.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le décembre 29, 2017, 02:36:19 pm
J'ai ouvert directement l'exemple

Si tu travailles sur une copie, il faut également copier les fichiers présent dans le répertoire de l'exemple dans le répertoire de ton sketch. Sinon, le compilateur ne trouvera pas ces fichiers
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 29, 2017, 02:57:55 pm
Voici mes fichiers :
(https://zupimages.net/up/17/52/dpzy.jpg) (http://zupimages.net/viewer.php?id=17/52/dpzy.jpg)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le décembre 29, 2017, 03:08:41 pm
Je sais pas quoi te dire...

J'ai recopié le dossier PlayFromSketch dans le répertoire Arduino avec mes autres sketchs. J'ai renommé ce dossier en PlayFromSketchV0 et le .ino en PlayFromSketchV0.ino

Je n'ai touché à rien d'autre

Ça compile

PS: j'utilise l'IDE 1.8.2 sur Mac OS X 10.11.6
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 29, 2017, 04:40:04 pm
.ini ????

J'ai un .ino (sur PlayFromSketchV0.ino).
PlayFromSketchV0 (dossier)
       - PlayFromSketchV0.ino --> fichier
       - AudioSampleSnare.h --> fichier
       - AudioSampleSnare.cpp --> fichier

J'ai dû rater quelque chose !
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le décembre 29, 2017, 04:44:57 pm
.ino pardon, faute de frappe, j'ai corrigé
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 29, 2017, 09:31:08 pm
Je me retrouve avec les fichiers :
PlayFromSketchV0 (dossier)
       - PlayFromSketchV0.ino --> fichier
       - AudioSampleSnare.h.ino --> fichier
       - AudioSampleSnare.cpp.ino --> fichier

J'ai fait un copier/coller "AudioSampleSnare.h" puis de AudioSampleSnare.cpp dans l'IDE Arduino et après, je les appelle avec "Ajouter un fichier . . . "
C'est peut être une mauvaise méthode ?
Je ne sais pas comment tu peux télécharger tout le dossier PlayFromSketch ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le décembre 29, 2017, 10:00:55 pm
Ben non, ni AudioSampleSnare.h ni AudioSampleSnare.cpp ne reçoivent une extension .ino

Met simplement ces deux fichiers dans le même répertoire que ton sketch
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 30, 2017, 01:29:39 am
J'ai cela, mais je ne sais comment les sauvegarder dans le même répertoire que mon sketch à part faire un copier/coller dans le bloc-notes.



(https://zupimages.net/up/17/52/5i09.jpg) (http://zupimages.net/viewer.php?id=17/52/5i09.jpg)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le décembre 30, 2017, 08:31:29 am
On ne peut pas copier des fichiers dans l’explorateur de Windows ? Genre ctrl-c puis ctrl-v ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Thierry le décembre 30, 2017, 11:25:50 am
Si bien sûr... C'est un système moderne, tout de même !
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le décembre 30, 2017, 11:27:00 am
J'aurais dû mettre un smiley  :)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le décembre 30, 2017, 12:42:07 pm
J’imagine que, même sous windoze, on peut ouvrir un exemple avec l’IDE, puis faire « enregistrer sous.. » en changeant le nom et l’emplacement.
Comme cela on garde bien tous les fichiers à l’intérieur du dossier du sketch.

Mais on s’eloigne...
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le décembre 30, 2017, 02:49:08 pm
A ne rien n'y comprendre !!
Le répertoire PlayFromSketchVZ :
(https://zupimages.net/up/17/52/4yhv.jpg) (http://zupimages.net/viewer.php?id=17/52/4yhv.jpg)

Le code :
PlayFromSketchVZ§.ino
#include <Audio.h>
#include <Wire.h>

#include "AudioSampleSnare.h"        // http://www.freesound.org/people/KEVOY/sounds/82583/

// Create the Audio components.  These should be created in the
// order data flows, inputs/sources -> processing -> outputs
AudioPlayMemory    sound0;

AudioOutputAnalog  dac;     // play to both I2S audio board and on-chip DAC

// Create Audio connections between the components
AudioConnection c1(sound0, dac);

void setup() {
  // Audio connections require memory to work.  For more
  // detailed information, see the MemoryAndCpuUsage example
  AudioMemory(10);
 }

void loop() {
     sound0.play(AudioSampleSnare);
}

AudioSampleSnare.h
// Audio data converted from WAV file by wav2sketch
#include "Arduino.h"
extern const unsigned int AudioSampleSnare[2817];

AudioSampleSnare.cpp
// Audio data converted from WAV file by wav2sketch
// Converted from AudioSampleSnare.wav, using 22050 Hz, u-law encoding

const unsigned int AudioSampleSnare [2817] = {
0x02002BD3,0x65636656,0x6B6A6B67,0x7071706F,0x43637171,.......................
};

Résultat de compilation :
C:\Users\AppData\Local\Temp\arduino_build_400327\sketch\PlayFromSketchVZ.ino.cpp.o: In function `loop':

C:\Users\Documents\Arduino\PlayFromSketchVZ/PlayFromSketchVZ.ino:23: undefined reference to `AudioSampleSnare'

collect2.exe: error: ld returned 1 exit status

Erreur de compilation pour la carte Teensy 3.2 / 3.1

Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le décembre 31, 2017, 10:10:39 am
Là visiblement le fichier AudioSampleSnare.cpp n’a pas été compilé et c’est l’éditeur de liens qui ne trouve pas le tableau.

Peux tu, dans les préférences, cocher Afficher les résultats détaillés pendant compilation ?

Question : quand ton sketch est ouvert, les autres fichiers apparaissent bien dans les onglet ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 01, 2018, 12:24:49 am
Suivant tes conseils, j'ai sélectionné "Afficher les résultats détaillés pendant compilation".
Et maintenant, cela compile ?????? A ne rien n'y comprendre !!
En enlevant cette option, cela marche aussi (heureusement, sinon ce serait plus que bizarre)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le janvier 01, 2018, 02:12:11 am
Ça coinçait en 2017. Maintenant ça marche en 2018, bonne Année   ;D
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 01, 2018, 11:14:52 am
Merci et Bonne année à tous.
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 01, 2018, 08:05:54 pm
Suivant tes conseils, j'ai sélectionné "Afficher les résultats détaillés pendant compilation".
Et maintenant, cela compile ?????? A ne rien n'y comprendre !!
En enlevant cette option, cela marche aussi (heureusement, sinon ce serait plus que bizarre)

En fait, l'IDE essaye de ne pas tout recompiler à chaque fois. Je pense que le fichier AudioSampleSnare.cpp n'avait pas été compilé mais que l'IDE ne considérait pas qu'il fallait le compiler par la suite (fichier ajouté dans le répertoire alors que l'IDE était ouvert ?). en changeant l'option, la recompilation de l'ensemble a été forcée et tout est rentré dans l'ordre.

Meilleurs vœux pour 2018.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 01, 2018, 10:00:47 pm
Merci.
Est-il possible de forcer la compilation "totale" ?
Certaines fois, lors d'une recompilation, l'IDE indique qu'il refait une compilation complète.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 01, 2018, 10:03:50 pm
Quand tu changes de cible (d'un modèle d'Arduino à l'autre), tout est forcément recompilé. Quand tu relances l'IDE également. Tu peux aussi décocher Agressively cache compiled core dans les préférences.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 02, 2018, 11:01:17 pm
Le teensy 3.2 a fonctionné avec un mini HP et un condensateur de 10 microF.
Maintenant, il refuse le téléversement avec ce message explicite :
(https://zupimages.net/up/18/01/5130.jpg) (http://zupimages.net/viewer.php?id=18/01/5130.jpg)
Pourtant, je l'ai acheté un prix "normal" 24 € chez Modchip59 sur Ebay.
J'ai contacté le vendeur qui m'a répondu qu'il m a vendu un "générique" ----> en fait une copie illégale.
Le Add-on Teensyduino qui permet d'utiliser l'IDE Arduino est écrit par le fabricant : PJRC.
Ce logiciel a reconnu que le numéro de série correspond à un Teensy frelaté.
Je ne sais pas s'il existe une autre méthode pour téléverser mon logiciel sur le Teensy.

Donc, il faut faire attention, quand c'est possible, au sérieux du vendeur!
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 02, 2018, 11:24:56 pm
Le seul autre moyen est avec un JTAG en soudant des fils sur certaines broches du micro. C’est compliqué et tu devras acheter un JTAG qui vaut 3 fois le prix d’un Teensy.

Le gars t’a vendu une contrefaçon. C’est donc une arnaque. Je serais toi j’ouvrirais un litige PayPal (si tu as payé par PayPal) et je me ferai rembourser (tiens je m’aperçois que c’est ce que suggère l’alerte). Ça lui fera les pieds. D’ailleurs je viens d’aller voir sur eBay la description et tout laisse penser que c’est un original.

Deux vendeurs sérieux :
Lextronic : https://www.lextronic.fr/5394-teensy
Exp-Tech : https://www.exp-tech.de/en/platforms/teensy/
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 03, 2018, 12:11:20 am
Merci pour les liens.
Je pense que robotshop (Canada) est également sérieux : il fait référence au constructeur PJRC.
Ils ont un site européen :
https://www.robotshop.com/eu/fr/platine-developpement-microcontroleur-usb-teensy-32-broches.html
J'en ai déjà commandé un ce matin. Je n'avais pas encore reçu tes liens.
Je vous tiens au courant des suites.

Cela peut servir à la communauté : il faut faire attention aux origines et aux vendeurs du teensy.

Remarques
J'ai déjà alerté le vendeur car l'avertissement "Counterfeit" était déjà apparu. Il m'a répondu que je ne savais pas m'en servir.
Étant débutant, je pensais que c'était peut être vrai.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 08, 2018, 11:20:28 am
Bonjour,
Nouvelles du Teensy 3.2 générique acheté chez MosdChip59
Contrairement à ce qui est indiqué sur le site Modchip59 (qui fait référence au constructeur PJRC), ce Teensy générique n’est pas compatible avec les outils de téléchargement « constructeur ».
Le téléchargement est impossible est de plus, un message d’alerte apparait « Conterfeit ».
Cependant, le téléchargement peut être effectué, mais en utilisant des procédures plus complexes.
Le revendeur ModChip59 ne veut rien reconnaître. Il indique que c’est de la diffamation et qu’il en a déjà vendu des centaines sans « problème ».
Dans cette affaire, je ne sais pas qui a les droits de propriétés industrielles.

Nota : J’ai commandé un autre Teensy à un prix légèrement inférieur chez RobotShop.
Livraison 24h00 et aucun problèmes de téléchargement.

Pourquoi ne pas créer sur le site 2 rubriques :
 - Sites à conseiller
 - Sites à éviter
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 08, 2018, 11:35:59 am
Contrairement à ce qui est indiqué sur le site Modchip59 (qui fait référence au constructeur PJRC), ce Teensy générique n’est pas compatible avec les outils de téléchargement « constructeur ».
Le téléchargement est impossible est de plus, un message d’alerte apparait « Conterfeit ».
Cependant, le téléchargement peut être effectué, mais en utilisant des procédures plus complexes.
Le revendeur ModChip59 ne veut rien reconnaître. Il indique que c’est de la diffamation et qu’il en a déjà vendu des centaines sans « problème ».
Dans cette affaire, je ne sais pas qui a les droits de propriétés industrielles.

Clairement les droits sont ceux de PJRC et c'est à eux de s'occuper de cette affaire.

Rien n'empêche ModChip59 de vendre des cartes qui vues de l'extérieur ont toutes les apparences d'un Teensy 3.2. Visiblement le logiciel qui est dans la puce qui s'occupe de l'interfaçage avec l'USB et au flashage du Teensy (le MKL02Z32VFG4 sur la schématique (https://www.pjrc.com/teensy/schematic.html)) n'a pas été copié car sinon elles ne seraient pas identifiées comme contrefaçon. Par contre ils ne peuvent pas laisser entendre qu'il s'agit de vrai Teensy, ni copier les illustrations du site de PJRC.

Citer
Pourquoi ne pas créer sur le site 2 rubriques :
 - Sites à conseiller
 - Sites à éviter

Parce qu'en mettant un article « sites à éviter », Locoduino serait attaquable en justice par les dits sites  :o
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 08, 2018, 11:50:26 am
Sinon, visuellement, les deux Teensy sont identiques ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 08, 2018, 11:57:52 am
Ils sont presque identiques visuellement.
Les toutes petites différences sont décrites sur le site PJRC.

Citer
Parce qu'en mettant un article « sites à éviter », Locoduino serait attaquable en justice par les dits sites.
Je te comprends et je suis d'accord, surtout qu'il semble avoir la gâchette facile.
C'est pour cela que je reste factuel.
Cependant, dans le cadre d'une rénovation de motos anciennes, j'ai eu affaire à des sites "pourris" (bizarrement essentiellement en France).
Certains ,après renseignements, avaient l'habitude de déposer régulièrement leur bilan.
Cela nécessite , en particulier, de vérifier le nom du gérant (s'il n'a pas également changé).

J'ai oublié de préciser que ModChip59 m'a écrit (tout se passe sur Ebay) que de toute façon, Teensy n'est pas une marque déposé en Europe.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le janvier 08, 2018, 12:52:24 pm
Après le factuel, ce serait bien d'effacer la « conclusion » et d'utiliser les mails privés pour les avis sur les commerçants tant qu’il n’y a pas un faisceau d’avis convergents.

Mieux vaut acheter chez Lextronic, je n’ai jamais eu de problème, c’est nickel.
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: msport le janvier 08, 2018, 03:07:40 pm
Parce qu'en mettant un article « sites à éviter », Locoduino serait attaquable en justice par les dits sites  :o

Et que comme déjà discuté, tout le monde n'a pas la même appréciation des risques et du cout de la sécurité.
15000 vendeurs pro en 2006 sur eBay, difficile d'évaluer tous ceux qui font de l'électronique et qui changent tous les jours.
Et puis il y a Banggood, Aliexpress ... Penser en tout cas à utiliser la protection du client.
Donc, si on est frileux et disposé à payer sa sécurité, mieux vaut se cantonner aux meilleurs de la classe, déjà cités dans ces colonnes.

Apprendre par cœur :
http://locoduino.org/spip.php?article13
Interro flash surprise semaine prochaine.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 08, 2018, 03:40:00 pm
Ok, Merci.

Quand j'intègre le fichier "son" directement dans le programme, c'est uniquement une étape  pour vérifier que "ça marche"sur le principe.
Après je crée le *.h et *.cpp des fichiers audio et je les copie dans le répertoire.
Je rajoute les <include *.h> dans  le *.ino.


Etat d’avancement du projet (provisoire)

Les fichiers "son" originaux sont convertis à l'aide de"Audacity.
1) Arduino + *.wav + carte SD + sortie PWM
Avantages :
Bonne qualité de son
Simplicité de gestion des fichiers son : *.wav
Capacité Mémoire (directement liée à la capacité de la carte SD)
Inconvénients :
« Blanc » à chaque changement de lecture de fichier « sons »
#include <SD.h>
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)
#include <PCM.h>
…………………………………………
const unsigned char sample1[] PROGMEM = {
39, 26, 26, 62, 80, 97, …………………………..
};
startPlayback(sample2, sizeof(sample2)); // sortie sur une pin PWM Arduino

3) Teensy + Wav2Sketch + Bibliothèque <Audio.h> + sortie PWM

Avantages :
Bonne qualité de son moyenne (8 bits ulaw– 11025 kHz) - ulaw est un codage qui permet d'avoir "un sentiment" de  résolution 12 bits en n'utilisant que 8 bits

Inconvénients :
Les fichiers obtenu par Wav2Sketch sont très lourds (taille supérieur au fichier *.wav original !!). Cela s’explique en partie parce que le fichier « son » est en fait codé en ASCII).

Donc, l’avantage de la capacité mémoire du Teensy est perdu
#include <Audio.h>
// Audio data converted from WAV file by wav2sketch
// Converted from Demarrage BR99.wav, using 44100 Hz, u-law encoding
const unsigned int Demarragebr99[29441] = {
0x0101CC00,0x17001724,0x2431362C,0x00800080,0xABA4980, ………………………..
};
……………………………….
       analogWriteFrequency(SoundPin, 8000); // Teensy pin 3 also changes to 8kHz
       analogWriteResolution(8);  // analogWrite value 0 to 256 (8 by default)
       analogWrite(SoundPin, DemarrageBR99); // sortie sur une pin PWM Teensy AnalogWrite (n° pin, int -> 0 to 256)

4) Teensy + EncodeAudio + sortie DAC – A14 (en cours d’essai)
Le problème est que EncodeAudio fournit un tableau de « const unsigned char » alors que le DAC demande des données « de type « int ». (analogWrite(A14, (int)val);
Réponse de Forun PJRC :
You could pretty easily make such a program, since 8 kHz is so very slow. Just use IntervalTimer to run a function that reads the next byte and do analogWrite. Also use analogWriteFrequency in setup() so the frequency is higher. Details here:

IntervalTimer:
https://www.pjrc.com/teensy/td_timin...rvalTimer.html

analogWriteFrequency:
https://www.pjrc.com/teensy/td_pulse.html

Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 09, 2018, 10:50:30 am
Bonjour

Le DAC du Teensy est sur 12 bits (0 à 4095). Si tu as des échantillons 8 bits (0 à 255) non signés, il faut à mon avis multiplier par 16 pour conserver l'amplitude.

Par ailleurs, il faudrait un ampli audio entre le Teensy et le haut-parleur, un LM386 par exemple
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 09, 2018, 11:44:22 am
1) Ok, pour l'instant, j'ai installé, pour les essais, le petit haut-parleur directement sur la sortie du Teensy (avec un condensateur de 10 MicroF placé en série) :
le son est faible, mais suffisant pour vérifier le son.
Par la suite, je mettrais effectivement un LM386 ou une petite carte intégrant un LM386.

2) J'aimerai utiliser "EncodeAudio" (8 bits-8kHz) pour piloter le DAC mais, "EncodeAudio" fournit du "const unsigned char" et le DAC n'accepte que de l' "int" (AnalogWrite (n°pin, int ->  0 to 256) ?

 3) A priori, la résolution du DAC peut être spécifiée :  analogWriteResolution ( 8 ) ;  // analogWrite value 0 to 256 (8 by default)
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 10, 2018, 11:56:48 am
2) J'aimerai utiliser "EncodeAudio" (8 bits-8kHz) pour piloter le DAC mais, "EncodeAudio" fournit du "const unsigned char" et le DAC n'accepte que de l' "int" (AnalogWrite (n°pin, int ->  0 to 256) ?

analogWrite n'a pas le même prototype sur Arduino/AVR et sur Arduino/ARM. Sur Arduino/ARM (Due, Zero, Teensy 3), les deux arguments sont des uint32_t. Donc pas de soucis pour lui passer un 8 bits non signé.

Citer
3) A priori, la résolution du DAC peut être spécifiée :  analogWriteResolution ( 8 ) ;  // analogWrite value 0 to 256 (8 by default)

Oui, j'ai regardé dans le code et ça fait ce que tu veux
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 11, 2018, 12:01:27 am
J'ai essayé d'utiliser la fonction "IntervalTimer", mais, je dois certainement très mal m'y prendre pour implémenter la fonction de lecture du tableau "son" et l'envoi de l'échantillon vers la pin A14 ( DAC ).
IntervalTimer myTimer;
  int SoundArray[sizeof(SoundArray)] ;
  int StartLok[] PROGMEM = { // from EncodeAudio
  39, 26, 26, 62, 80, 97, 90,
  };
 
    void ReadSound(int SoundArray[sizeof(SoundArray)]){ // Déclaration Fonction : lit un échatillon et l'envoi sur le DAC pin A14
          for(int i = 0; i < sizeof(SoundArray); i++){
          analogWrite(A14, SoundArray[i]);
          Serial.println(SoundArray[i]);
          return void;
          }
  }
void setup(){
       Serial.begin(9600);
       analogWriteResolution(8);  // analogWrite value 0 to 256 (8 by default)
}

void loop(){
       for(int i = 0; i < sizeof(StartLok); i++){
       SoundArray[i] = StartLok[i]
       }
       myTimer.begin(ReadSound(SoundArray[sizeof(SoundArray)]), 125); // 125 MicroS -> 8 kHz

Teensy_Sound_PWM_V2:2: error: 'SoundArray' was not declared in this scope
 int SoundArray[sizeof(SoundArray)] ;                      ^

Teensy_Sound_PWM_V2:7: error: 'SoundArray' was not declared in this scope
     void ReadSound(int SoundArray[sizeof(SoundArray)]){ // Déclaration Fonction : lit un échatillon et l'envoi sur le DAC pin A14                                   

Teensy_Sound_PWM_V2:7: error: 'SoundArray' was not declared in this scope
     void ReadSound(int SoundArray[sizeof(SoundArray)]){ // Déclaration Fonction : lit un échatillon et l'envoi sur le DAC pin A14                                       

Teensy_Sound_PWM_V2: In function 'void ReadSound(...)':
Teensy_Sound_PWM_V2:8: error: 'SoundArray' was not declared in this scope
           for(int i = 0; i < sizeof(SoundArray); i++){

Teensy_Sound_PWM_V2:11: error: expected primary-expression before 'void'
           return void;

Teensy_Sound_PWM_V2:11: error: return-statement with a value, in function returning 'void' [-fpermissive]
Teensy_Sound_PWM_V2:11: error: expected ';' before 'void'
Teensy_Sound_PWM_V2:11: error: declaration does not declare anything [-fpermissive]
Teensy_Sound_PWM_V2: In function 'void loop()':
Teensy_Sound_PWM_V2:21: error: 'SoundArray' was not declared in this scope
 int SoundArray[sizeof(SoundArray)] ;

Teensy_Sound_PWM_V2:22: warning: comparison between signed and unsigned integer expressions
         for(int i = 0; i < sizeof(StartLok); i++){
               
'SoundArray' was not declared in this scope
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 11, 2018, 07:57:08 am
Bonjour

int SoundArray[sizeof(SoundArray)] ; n’est pas une déclaration qui a du sens. Étant donné que la taille du tableau est déterminée à partir de la taille du tableau qui n’est pas connue  ???
D’ailleurs la déclaration de l’argument de ReadSound n’est pas non plus légale.

Par ailleurs ce que fait ReadSound contredit le commentaire puisqu’elle envoie tous les échantillons et non pas un seul. Comme a dit je ne sais plus qui « si les commentaires ne correspondent pas au programme alors les deux sont faux »

Ensuite je ne vois pas où l’intervalTimer est lié à la fonction ReadSound, voir https://www.pjrc.com/teensy/td_timing_IntervalTimer.html
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 11, 2018, 10:46:02 am
Bonjour et merci pour tes commentaires :
1) Création de la fonction ReadSound : elle est censée (c'est ce que j'ai essayé de faire!) avoir pour argument un tableau d'échantillons de son dont je ne connais pas à priori la taille.
Cette fonction devrait pouvoir en effet s'appliquer sur n’importe quel tableau de son (donc avec des tailles variables).

2) Ok, à vrai dire, je suis un peu perdu avec les déclarations car le  tableau de son généré par EncodeAudio est un "unsigned char" alors que AnalogWrite n'admet que les "int".

3) Ok, en y réfléchissant, tu as raison.

4) Je pensais que l'instruction suivante suffisait :
       myTimer.begin(ReadSound(SoundArray[sizeof(SoundArray)]), 125); // 125 MicroS -> 8 kHz
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 11, 2018, 01:59:23 pm
D'après ce que j'ai compris, IntervalTimer va te servir à appeler à une fréquence définie (8kHz ici) une fonction qui va envoyer un échantillon et un seul. Là tu envoies tout le tableau, donc les 8kHz ne vont pas être respectés  :).

Par ailleurs cette fonction ne peut pas prendre d'argument. Donc il faut que tu aies une variable qui donne l'index de l'échantillon courant (appelons le echantillonCourant). La fonction appelée par IntervalTimer va lire l'échantillon à l'index echantillonCourant, l'envoyer au DAC, et incrémenter echantillonCourant. Si echantillonCourant est égal à la taille du tableau, deux solutions, on recommence au début (le son est joué en boucle) ou on arrête. À cet effet, on peut décider qu'une valeur spéciale d'echantillonCourant, disons -1, signifie qu'il n'y a pas de son à jouer.

Le begin soit être appelé dans setup je pense.

Par ailleurs, le son à jouer est dans StartLok ? tu le recopies en plusieurs exemplaires dans SoundArray ? c'est le but ? Parce que si c'est le cas, ta boucle ne fait pas ça, elle ne remplit que les sizeof(Starlok), le reste de SoundArray reste non initialisé. Ensuite sizeof ne renvoie pas la taille d'un tableau mais le nombre d'octets occupés en mémoire. Si tu veux avoir le nombre d'éléments d'un tableaux d'entiers, il faut écrite sizeof(StartLok)/sizeof(int) si StartLok est un tableau d'int.

Bref, si tu veux jouer ce qu'il y a dans StartLok en boucle, tu n'as pas besoin de le copier dans SoundArray (le programme non testé et non compilé mais avec indentation correcte) :

IntervalTimer myTimer;
int StartLok[] PROGMEM = { // from EncodeAudio
  39, 26, 26, 62, 80, 97, 90
};
int echantillonCourant = 0;
 
void SendSound()
{
  analogWrite(A14, StartLok[echantillonCourant++]);
  if (echantillonCourant >= sizeof(StartLok)/sizeof(int)) {
    echantillonCourant = 0;
  }
}

void setup()
{
   analogWriteResolution(8);
   myTimer.begin(SendSound, 125);
}

void loop()
{
}
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 11, 2018, 03:43:54 pm
Merci pour ta patience.
Je vais analyser tout cela.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 11, 2018, 09:05:27 pm
Merci, ça marche super bien.
En faisant varier les microseconds dans
myTimer.begin(function, microseconds); le son de la locomotive accélère ou ralenti.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 12, 2018, 01:03:49 pm
Excellente nouvelle  :)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 13, 2018, 02:14:16 pm
1) sur la base du template que tu m'as donné, j'ai créé un fonction par son (je pense que ce sera plus lisible lorsque le son sera intégré dans le décodeur "NmraDcc".

2) Il y a certes plus de mémoires dans le Teensy (256 k), mais c'est malgré un peu juste. Je pense que pour être vraiment à l'aise, il faudrait entre 2 à 4 Mo. Il faut donc optimiser la taille des tableaux "son".
Le code en 3) donne le résultat de compilation :
Le croquis utilise 199700 octets (76%) de l'espace de stockage de programmes. Le maximum est de 262144 octets.
Les variables globales utilisent 3468 octets (5%) de mémoire dynamique, ce qui laisse 62068 octets pour les variables locales. Le maximum est de 65536 octets.

Même en déclarant les tableaux "son" en "const"
De plus  sur le Teensy, contrairement à l'arduino, ce n'est pas évident de gérer" manuellement" la mémoire Flash.

3)
IntervalTimer myTimer;

const int StartLokBR99[] PROGMEM = { // from EncodeAudio
  39, 26, 26, 62, 80, 97, 90, 59
};

const int BrakeLokBR99[] PROGMEM = { // from EncodeAudio
122, 143, 160, 164, 159, 143, 138, 131
};

const int SiffletLokBR99[] PROGMEM = { // from EncodeAudio
12, 68, 109, 132, 167, 195, 167, 142, 137, 174, 184,
};
 
const int MarcheLokBR99[] PROGMEM = { // from EncodeAudio
124, 128, 134, 124, 100, 100, 113, 110, 118, 145,
};

const int ClocheLokBR99[] PROGMEM = { // from EncodeAudio
130, 123, 118, 123, 128, 128, 128, 130, 135, 132, 130,
};

const int StandbyLokBR99[] PROGMEM = { // from EncodeAudio
130, 134, 135, 131, 124, 121, 122, 125, 129, 131

unsigned int echantillonCourant = 0;
 
void BrakeLok(){
        analogWrite(A14, BrakeLokBR99[echantillonCourant++]);
        if (echantillonCourant >= sizeof(BrakeLokBR99)/sizeof(int)) {
        echantillonCourant = 0;
        }
}

 void SiffletLok(){
        analogWrite(A14, SiffletLokBR99[echantillonCourant++]);
        if (echantillonCourant >= sizeof(SiffletLokBR99)/sizeof(int)) {
        echantillonCourant = 0;
        }
}

void StartLok(){
        analogWrite(A14, StartLokBR99[echantillonCourant++]);
        if (echantillonCourant >= sizeof(StartLokBR99)/sizeof(int)) {
        echantillonCourant = 0;
        }
}

  void MarcheLok(){
        analogWrite(A14, MarcheLokBR99[echantillonCourant++]);
        if (echantillonCourant >= sizeof(MarcheLokBR99)/sizeof(int)) {
        echantillonCourant = 0;
        }
}
void StandbyLok(){
        analogWrite(A14, StandbyLokBR99[echantillonCourant++]);
        if (echantillonCourant >= sizeof(StandbyLokBR99)/sizeof(int)) {
        echantillonCourant = 0;
       }
}

void ClocheLok (){
        analogWrite(A14, ClocheLokBR99[echantillonCourant++]);
        if (echantillonCourant >= sizeof(ClocheLokBR99)/sizeof(int)) {
        echantillonCourant = 0;
        }
}
void setup(){
       analogWriteResolution(8);
       myTimer.begin(StartLok, 500);
       myTimer.begin(BrakeLok, 125);
       myTimer.begin(SiffletLok, 125);
       myTimer.begin(ClocheLok, 125);
       myTimer.begin(StandbyLok, 125);
}

void loop()
{
}

Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 13, 2018, 08:57:37 pm
De plus  sur le Teensy, contrairement à l'arduino, ce n'est pas évident de gérer" manuellement" la mémoire Flash

C’est à dire ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 13, 2018, 11:17:29 pm
Si j'ai bien compris, sur le teensy, il n y a pas d'équivalent de la bibliothèque EEPROM.h.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 13, 2018, 11:23:13 pm
Si si. Voir https://www.pjrc.com/teensy/td_libs_EEPROM.html
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 13, 2018, 11:26:10 pm
Je suis assez étonné de l’occupation mémoire de ce programme. Il n’y a qu’une poignée de pauvres tableaux de quelques éléments.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 14, 2018, 02:11:52 pm
Ok, je vais voir pour EEPROM.

Mes fichiers son en *.wav (8 bits PCM) avant conversion par EncodeAudio prennent au total environ 110 Ko.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 15, 2018, 01:17:11 pm
Le simple fait de faire un copier/coller du programme utilise 236 Ko dans "NotePad".
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le janvier 15, 2018, 07:59:25 pm
Moi je ne trouve que 4k sur mon Mac !!

Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 16, 2018, 07:51:30 pm
Dans le code que j'ai intégré dans mon message, je n'ai pas mis la totalité des fichiers "son" pour éviter de faire exploser mon post (> 192 ko).
J'ai remplacé une partie des fichiers "son" par des petits points.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 20, 2018, 02:47:59 pm
Bonjour,
Au total, j'ai essayé les configurations suivantes :
1) - Arduino Nano + Carte SD + Bibliothèque "SoftwareSerial.h"- Sortie PWM:
            -> le temps est trop long entre chaque morceau de musique pour mon application. Cette architecture semble plutôt faite pour des lecteurs MP3.

2) - Arduino Nano + Bibliothèque "PCM.h"+ codage son "EncodeAudio"- Sortie PWM:

-> Cette architecture inspirée du le site "Train35" est intéressante en terme de temps de réponse, mais la durée des bruitages doit être très courte (32 Ko Flash Memory sur l'Arduino).

3)  - Teensy 3.2 + codage son "wav2sketch" + bibliothèque "Audio.h" - Sortie Convertisseur Numérique Analogique (DAC A14)
-> Ce contrôleur, compatible de l'arduino (instructions + IDE arduino) est plus rapide que le Nano (72 MHz au lieu de 16 Mhz), mais plus cher (environ 25 €). Il possède 256 Ko de Flash.
Le temps de réponse est bon (peut être liè surtout au performance des bibliothèques plus que la vitesse du processeur et à l'adéquation entre la bibliothèque utilisée et l'application?). La bibliothèque Audio.h est assez lourde. Elle est dédiée (en association avec une carte "son" PJRC SGTL5000") pour des applications complexes de mixage, d'effets sonores et de calcul (Transformée de Fourier).
 La capacité mémoire est à la fois trop importante pour de bruitages de type EncodeAudio" (voir 2), mais pas suffisante pour des sons complexes et de longues durées : Il faudrait à priori entre 500 Ko et 2Mo de Flash (en utilisant le codage "wav2sketch").

4) - Arduino Nano + Carte SD + Bibliothèque "TMRpcm.h"- Sortie PWM:
Cette architecture ressemble à la 1) - mais la bibliothèque utilisée est différente. Le temps de réponse est bon (pas de temps d'attente). Le manque de mémoire est compensé par la carte SD. Je crois que je vais choisir cette configuration.
Il me reste le choix entre 2 possibilités :
        4.1) Carte Arduino Nano (Décodage DCC + moteur + éclairage) + Carte Arduino Nano (Décodage DCC + commande "son") + Carte SD
               -> Problème de synchronisation avec l'arrivée d'une trame dcc valide pour le "son" de la locomotive) -> interruption ??

        4.2) Carte Arduino Nano (Décodage DCC + moteur + éclairage) + Carte Arduino Nano (piloté en liaison série Tx/Dx par le 1er Arduino Nano) + Carte SD.--> reste à essayer
              -> Je pense que la synchronisation entre la commande "son" (provenant du premier Arduino) et la lecture des "sons" sur le deuxième Arduino sera plus facile :  ??
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 20, 2018, 02:53:35 pm
Moui

Si je me souviens bien il n'y a pas que le son à gérer. Penses tu pouvoir tout caser dans un Nano ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 20, 2018, 06:21:40 pm
Aujourd'hui, je pars sur l'hypothèse de l'utilisation de 2 Arduino Nano :
Arduino 1
Gestion de la vitesse (pont en H) + l'éclairage (Feux avant/Arrière + cabine) + Pantographe (servo) + Dételage (servo)

Arduino 2
Dédié pour le son, je pense le piloter à partir de l'Arduino Nano 1 par l'intermédiaire de la liaison série Tx/Dx.
L'Arduino 2 recevra les consignes de son (vitesse, accélération, freinage, arrêt, sifflet, . . .).
Une routine ISR dans l'Arduino 2 permettra de vérifier que la consigne de son n'a pas changé.
    - Si pas de changement de consigne, la lecture continue.
    - Si changement de consigne, la lecture en cours s’arrête et la lecture du nouveau fichier commence.
-> Je vais étudier le dossier "interruptions" du forum.

Je pense qu'il vaut mieux découpler la fonction "son" des autres. Les trames DCC arrive de manière asynchrone.
Un certain nombre de trames ne concerne pas la locomotive (Adresse)
Quand je lie un fichier son, l'Arduino ne fait rien d'autre (en particulier, la vitesse n'est pas gérer pendant ce temps). Je risque de rater des trames DCC concernant la locomotive.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 20, 2018, 06:23:47 pm
Bon, c'est pas ce que je ferais  :)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 20, 2018, 09:08:42 pm
1) Tu peux m'expliquer comment tu ferais pour mon application ?

2) Si j'ai bien compris, pour la liaison série, si j'utilise Rx Tx (pin 0 et 1), je ne suis pas obligé de charger la bibliothèque "SoftwareSerial.h".
    Par contre, dans ce cas, je ne peux pas utiliser le moniteur série.

Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 22, 2018, 04:14:43 pm
1) Le Teensy en a assez sous le pied pour faire tourner la totalité de ton application

Certes tu as deux activités, le son et le décodage du DCC, qui sont concurrentes et critiques concernant le temps mais le DCC peut utiliser la fonction input capture d'un des timers pour dater les transitions du signal via le hardware et différer son traitement (tant qu'on ne diffère pas du temps minimum d'un bit). Cette fonction existe aussi sur le TIMER1 de l'AVR d'ailleurs.

2) oui

Ensuite au lieu d'un SD Card, j'explorerais du côté d'une flash SPI, comme ceci : http://www.electrodragon.com/product/spi-flash-breakout-board-winbond-w25q64fvssig-64m-bit/
Ça te permettrait d'utiliser des sons en 22kHz en 12 bits pour une meilleure qualité.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 22, 2018, 09:12:25 pm
1) Ok, je vais essayer de comprendre la fonction "Input Capture". Je ne sais pas si je dois modifier le NmraDcc.h / NmraDcc.cpp : je suis très loin d'être un Mozart de l'Arduino.
Nota : J'utilise et j'ai modifié le Timer 2 pour piloter le moteur (pont en H) à 125 Hz.

2) L'avantage d'une flash SPI par rapport à une carte SD.
Le temps d'accès ?
La mise en œuvre plus facile ?
Pour installer des fichiers dans une Flash SPI, j'installe mes fichiers sons dans des onglets différents (ajouter un fichier . . .), puis je fais des <Include> dans le programme principal (*.ino) ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 22, 2018, 10:00:58 pm
1) Paul a fait une bibliothèque pour gérer ça. https://github.com/PaulStoffregen/FreqMeasureMulti

2) le protocole d’accès est plus efficace que pour une carte SD, moins verbeux. Ça permet un débit qui sur Teensy devrait permettre de lire plusieurs canaux à 22kHz simultanément. Et puis c’est vraiment pas cher. Pour charger des données dans une flash SPI, il faut mettre sur le Teensy un programme qui va recevoir le son à partir d’un tableau comme tu l’as évoqué et l’écrire dans la flash. Paul a également une lib pour gérer un systeme de fichiers sur des flash SPI : https://github.com/PaulStoffregen/SerialFlash

Je pense que dans ton application, lire plusieurs canaux simultanément est intéressant, ça permet de superposer du sifflet au son moteur, etc
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 22, 2018, 10:22:11 pm
Note qu’un Teensy 3.2 a le SPI qui peut tourner à la moitié de la fréquence, soit 48MHz. La flash SPI monte à 62,5 MHz. Note également  que des utilisateurs overclockent le Teensy 3.2 a 120Mhz
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 24, 2018, 12:03:49 am
Je vais suivre tes conseils :
1) Je crois que pour overclocker à des fréquences supérieures à 72 MHz, il faut que le Teensy soit alimenté en 5 V et non en 3,3 V.

2) Pour la Flash SPI j'ai vu sur Aliexpress :
https://fr.aliexpress.com/item/Free-Shipping-5pcs-W25Q64B-large-capacity-FLASH-memory-module-SPI-Interface-Electronic-Component/1000001623457.html?spm=a2g0s.9042311.0.0.8NPUAB
Je mettrai un 7803 pour l'alimentation.

3) Je vais essayer de tout mettre sur un Teensy 3.2
En espérant que les consommateurs (pont en H, Led + servo) ne vont pas faire écrouler le Teensy.
C'est pour cela que je vais laisser 5 V pour une sortance globale de 250 mA ( Il parait qu'en mettant 10 v, on peut avoir une sortance globale de 500 mA !!!) -> mais,  je ne suis pas partant pour faire des signaux de fumée !!!

4) Je vais récupérer mon programme sur Arduino Nano qui fonctionne (hors génération du son).
Il faut que je commence par supprimer les modifications du Timer2 qui me permettait de piloter le pont en H à 125 Hz et remplacer ce code par :
void setup() {
      analogWriteFrequency(3, 125); // Teensy 3.0 pin 3 also changes to 125 kHz
    }
Comme d'habitude, chaque timer affecte systématiquement plusieurs pins en même temps.
"The PWM signals are created by hardware timers. PWM pins common to each timer always have the same frequency, so if you change one pin's PWM frequency, all other pins for the same timer change".
Teensy 3.1 & 3.2
Timer   PWM Pins                         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

Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 24, 2018, 10:05:31 am
J’ai pas compris l’histoire de la tension et de la sortance.

Le MCU du Teensy ne s’alimente pas au delà de 3,3V, overclocké ou non, sinon il grille.

En revanche la flash fonctionne en 3,3V et peut être alimenté par le 3,3V du régulateur du Teensy. Ce régulateur, d’après la datasheet peut fournir 500mA mais c’est une valeur extrême. Limiter à la moitié est raisonnable. Ce régulateur est alimenté via VIN à partir de l’alimentation dérivée du DCC.

Un servo sur l’entrée de commande ne consomme rien. Sur son alimentation ça dépend de sa taille mais la c’est l’alimentation dérivée du DCC qui est sollicitée. Le pont en H L298 consomme sur ses entrées de commande un courant inférieur à 100μA.

Il faudrait faire un schéma pour tout de manière à savoir de quoi on parle  :)

Ps : le module est deux fois moins cher chez electrodragon. Sur le module Ali express, la flash semble avoir été soudée à la main vu la régularité des soudures. Soudé à la main = récup. Certe le port est payant chez electrodragon. Perso je prends Bpost, l’envoi est suivi, quand je commande des carte et je suis livrée en moins de 10 jours. Il y a moins cher mais plus long.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 24, 2018, 10:53:16 am
Ok, Merci.
Plus précisément :
 - Tensy 2.0 : 5V
 - Teensy 3.1, 3.2, 3.5 --> 3,3 V - 5V Tolerant
 - Teensy LC et 3.6 --> 3,3 V
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 24, 2018, 12:24:29 pm
5V tolérant c'est pour les entrées. Ça signifie que bien que le MCU soit alimenté en 3,3V il tolère que le niveau haut d'un signal numérique appliqué sur une entrée puisse atteindre 5V. Mais en aucun cas il ne peut être alimenté au delà de 3,3V (nominal)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 26, 2018, 08:15:46 pm
En attendant de recevoir les mémoires Flash (W25Q64B/mémoire FLASH module/SPI Interface), je me pose quelques questions.
1) Comment charger la mémoire ?
A travers le Teensy ou avec un support avec interface USB type :
https://www.ebay.fr/itm/EZP2013-USB-Programmer-SPI-24-25-93-EEPROM-Flash-Bios-Chip-Software-Socket/131816395066?hash=item1eb0de913a:g:esoAAOSw9VZXOY62

2) Concernant les fichiers (*.wav convertit avec "wav2trw_16" en *.raw), j'ai vu dans des exemples que l’adresse du début du fichier  ? ou la taille du fichier? est indiqué (0xF8A00) par exemple :
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <NmraDcc.h>
#include <Servo.h>
//#include <SD.h>
//#include <Bounce.h>
#include <play_serialflash.h>

//16 Bit RAW - Converted with wav2trw -16
const unsigned int AudioSampleStandby = 0xF8A00;          //TBD Length - AudioSampleStandby.raw
const unsigned int AudioSampleSteam = 0;                  //TBD Length - AudioSampleSteam.raw
const unsigned int AudioSampleCompressor = 0xD0B00;       //TBD Length - AudioSampleCompressor.raw
const unsigned int AudioSampleAirRelease =  0xDCD00;      //TBD Length - AudioSampleAirRelease.raw
const unsigned int AudioSampleBell = 0x9500;              //TBD Length - AudioSampleBell.raw
const unsigned int AudioSampleWhistle = 0xE2100;          //TBD Length - AudioSampleWhistle.raw
const unsigned int AudioSampleShoveling = 0xE2100;        //TBD Length - AudioSampleShoveling.raw
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 27, 2018, 09:21:53 am
1) ça peut se faire avec le Teensy. Regarde cet example de SerialFlash https://github.com/PaulStoffregen/SerialFlash/blob/master/examples/CopyFromSerial/CopyFromSerial.ino il y a un script python qui discute avec la Teensy via la ligne série et lui envoie le fichier : https://github.com/PaulStoffregen/SerialFlash/tree/master/extras

2) Je ne sais pas il faudrait regarder où ces constantes sont utilisées mais des deux c’est plus probablement la taille
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 28, 2018, 12:18:18 am
Si je comprends bien, j'installe en premier rawfile-uploader.py sur le teensy  (https://github.com/PaulStoffregen/SerialFlash/blob/master/extras/rawfile-uploader.py), mais, je ne sais pas :

1) dans quelle répertoire du PC mettre mes fichiers *.raw (après conversion avec "wav2trw_16").

2) sous quelle forme, ces fichiers sont enregistrés dans la flash ?

3) quel est le mécanisme qui évite d'écraser les données dans la flash ?

3) pour lire la Flash, le nom du fichier est suffisant ou il faut spécifier des tailles ou des adresse de début de fichier)

J'ai essayé de regarder sur certains sites (dont ceux de PaulStoffregen), mais cela ne me parait pas très clair.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le janvier 28, 2018, 10:14:52 am
Non pas du tout.

Sur le Teensy le sketch CopyFromSerial doit être chargé. Ce sketch reçoit les données à mettre dans la flash de l’USB/série et les écrit dans la flash. Note qu’il efface la flash avant.

Sur ton PC, tu lances via l’invite de commande rawfile_uploader.py. Ce script python prend au moins 2 arguments, le premier est le port série où est connecté le Teensy et le second le fichier à envoyer ; on peut mettre plusieurs fichiers. Le script envoie donc les fichiers au sketch qui les écrit dans la flash. Note que le nom des fichiers est limité à 8 caractères plus 3 caractères d’extension. Il faut également mettre à la ligne 29 la taille de la flash en M octets (8 pour la flash en question)

1) où tu veux, le mieux est d’y mettre aussi le script et de travailler ensuite dans ce répertoire.

2) binaire, juste les octets qui constituent le son.

3) la bibliothèque SerialFlash gère un système de fichiers rudimentaire.

4) la bibliothèque gère un catalogue, donc le nom de fichier suffit. Regarde les exemples. Regarde également le script python.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le janvier 28, 2018, 06:50:04 pm
Merci beaucoup pour ta patience !
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 11, 2018, 12:42:36 am
Bonjour,
J'ai reçu les mémoires Spi Flash.
D'après ce que j'ai compris, je dois charger le fichier "son" brut depuis le PC (ASUS550C - Windows10) dans la Spi Flash (25Q64BVSIG)

Connexion Mémoire <-> teensy 3.2
    Memory <-> Teensy connection
    WP/IO2......................none
    DO/IO1 (MISO).......... pin 12
    HOLD/IO3...................3,3 V
    DI/IO0 (MOSI).............pin7
    CS............................pin6
    CLK...........................pin14
    VCC..........................3,3 V

    CopyFromSerial.ino
J'utilise l'option : sans audio board:
    /*
 * This is free and unencumbered software released into the public domain.
 *
 * 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!
 */
// SPI Flash 25Q64BVSIG
#include <SerialFlash.h>
#include <SPI.h>

//Buffer sizes
#define USB_BUFFER_SIZE      128 // 128
#define FLASH_BUFFER_SIZE    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               7
//#define MISO              12
//#define SCK               14
#define CSPIN              6
//#define CSPIN           21  // Arduino 101 built-in SPI Flash

void setup(){
  Serial.begin(9600);  //Teensy serial is always at full USB speed and buffered... the baud rate here is required but ignored


  pinMode(13, OUTPUT);
   
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(7);  // uncomment these if using the alternate pins
  SPI.setMISO(12);
  SPI.setSCK(14);

  if (!SerialFlash.begin(CSPIN)) {
    while (1) {
      Serial.println("Unable to access SPI Flash chip");
      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);
 
  //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
  while(Serial.available() || lastReceiveTime + 3000 > millis()){//3000
    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
  while(Serial.available() || lastReceiveTime + 3000 > millis()){
    if (Serial.readBytes(usbBuffer, USB_BUFFER_SIZE)){
      lastReceiveTime = millis();
    }
  }
}


    Raw-uploader.py (Python 2.7)
  #!/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 = 16

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])
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")

Ecran de commande Windows 
 Sur l'écran de commande Windows, je récupère les messages d'erreurs suivant :
    C:\Python27>python "rawfile-uploader.py" "com4" "AABR99.trw"
    Uploading 1 files...
    1: AABR99.trwTraceback (most recent call last):
    File "rawfile-uploader.py", line 80, in <module>
    ser.write("".join(encoded))
    File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 295, in write
    raise writeTimeoutError
    serial.serialutil.SerialTimeoutException: Write timeout


Teensy 
 Sur le teensy, la LED 13 clignote à 1Hz rate.
 
Je ne sais pas comment résoudre ce problème.

Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 11, 2018, 09:30:33 am
Il y d’entrée de jeu quelque chose que je ne comprends pas. Sur le Teensy PJRC s’est attaché à garder des numéros de broches compatibles avec l’Arduino. Par conséquent le SPI est sur les mêmes broches que sur un Uno : 10 (cs), 11 (mosi), 12 (miso) et 13 (sck). Pourquoi ce ne sont pas ces broches qui sont employées?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 11, 2018, 10:07:07 am
Tu as raison, mais, j'ai utilisé les pins qui sont déclarées dans le sketch CopyFromSerial (que j'ai réutilisé):
//SPI Pins (these are the values on the Audio board; change them if you have different ones)
[code]//SPI Pins (these are the values on the Audio board; change them if you have different ones)
//#define MOSI               7
//#define MISO              12
//#define SCK               14
#define CSPIN              6
//#define CSPIN           21  // Arduino 101 built-in SPI Flash

void setup(){
  Serial.begin(9600);  //Teensy serial is always at full USB speed and buffered... the baud rate here is required but ignored


  pinMode(13, OUTPUT);
   
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(7);  // uncomment these if using the alternate pins
  SPI.setMISO(12);
  SPI.setSCK(14);
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 11, 2018, 10:17:37 am
Avant d'essayer CopyFromSerial, je commencerais par bricoler avec la flash et le Teensy seuls. Voir si j'arrive à l'effacer, créer des fichiers, les relire. Une fois que c'est validé, je passerais à la suite.

Si la LED reste à clignoter à 1Hz, ça signifie que la flash n'est pas prête après le formattage.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 12, 2018, 01:09:17 pm
1) J'ai branché la SPI Flash de la façon suivante :
Vu de la Spi Flash
MISO DO/I01   -> 12
MOSI DI/I00 -> 11
CS -> 10
CLK -> 13    14 ?

2) J'ai lancé : Raw SerialFlash Hardware Test
Résultat dans le moniteur série :
Read Chip Identification:
  JEDEC ID:     EF 40 17
  Part Nummber: W25Q64FV
  Memory Size:  8388608 bytes
  Block Size:   65536 bytes

Reading Chip...

Writing 4096 signatures

Double Checking All Signatures:
  all 4096 signatures read ok

Checking Signature Pairs
  all 2047 signature pairs read ok

Checking Read-While-Write (Program Suspend)
  write 256 bytes at 256
  write time was 663 microseconds.
  read-while-writing: 00 00 00 00 15 F5 95 4B
  test passed, good read while writing

Checking Read-While-Erase (Erase Suspend)
  erase time was 105892 microseconds.
  erase correctly erased 65536 bytes
  read-while-erasing: 00 00 00 00 15 F5 95 4B
  test passed, good read while erasing

All Tests Passed  :-)

Test data was written to your chip.  You must run
EraseEverything before using this chip for files.

Mais, j'ai toujours le timeout sur l'écran de commande Windows lorsque je lance le script Python :rawfile-uploader.py
(rawfile-uploader.py permet d'envoyer un fichier "son" depuis le PC vers le Teensy via la liaison COM4 (USB Teensy).
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 12, 2018, 01:36:41 pm
COM4 est pas ouvert par une autre application, genre le terminal de l'IDE Arduino ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 12, 2018, 10:14:32 pm
1) J'ai essayé de fermer le port COM4 en fermant l'IDE Arduino.
J'ai le résultat suivant sur l'écran de commande Windows :
C:\Python27>python "rawfile-uploader.py" "com4" "AABR99.trw"
Uploading 1 files...
1: AABR99.trwTraceback (most recent call last):
  File "rawfile-uploader.py", line 80, in <module>
    ser.write("".join(encoded))
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 289, in write
    raise SerialException("WriteFile failed (%r)" % ctypes.WinError())
serial.serialutil.SerialException: WriteFile failed (WindowsError(22, 'Le p\xe9riph\xe9rique ne reconna\xeet pas la commande.'))

2) le Raw SerialFlash Hardware Test ne fonctionne que si le "SCK" de la Flash est sur la pin 13 du teensy (alors que dans CopyFrom Serial, il y a l'affectation suivante :
  SPI.setSCK(14);La pin 13 permet également de piloter la LED ?????
  pinMode(13, OUTPUT);
..................
 //Flash LED at 1Hz while formatting
  while (!SerialFlash.ready()) {
    delay(500);
    digitalWrite(13, HIGH);
    delay(500);
    digitalWrite(13, LOW);
  }
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 13, 2018, 08:46:14 am
1) J'ai essayé de fermer le port COM4 en fermant l'IDE Arduino.
J'ai le résultat suivant sur l'écran de commande Windows :
C:\Python27>python "rawfile-uploader.py" "com4" "AABR99.trw"
Uploading 1 files...
1: AABR99.trwTraceback (most recent call last):
  File "rawfile-uploader.py", line 80, in <module>
    ser.write("".join(encoded))
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 289, in write
    raise SerialException("WriteFile failed (%r)" % ctypes.WinError())
serial.serialutil.SerialException: WriteFile failed (WindowsError(22, 'Le p\xe9riph\xe9rique ne reconna\xeet pas la commande.'))

Ca fait penser à un problème sur le PC. Je ne pourrai pas t’en dire plus, je n’utilise pas Windows.

Citer
2) le Raw SerialFlash Hardware Test ne fonctionne que si le "SCK" de la Flash est sur la pin 13 du teensy (alors que dans CopyFrom Serial, il y a l'affectation suivante :
  SPI.setSCK(14);La pin 13 permet également de piloter la LED ?????
  pinMode(13, OUTPUT);
..................
 //Flash LED at 1Hz while formatting
  while (!SerialFlash.ready()) {
    delay(500);
    digitalWrite(13, HIGH);
    delay(500);
    digitalWrite(13, LOW);
  }

Tant que le chip select n'est pas actif, on peut faire ce que l’on veut sur SCK, MOSI et MISO.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 14, 2018, 12:06:22 am
Sur la spécification de Teensy 3.2, on a effectivement :
CS --> pin 10 au lieu de 6 ?
DOUT (MOSI)--> pin 11
DIN (MISO)--> pin 12
SCK --> pin 13
 
Je ne sais pas si le script "rawfine-uploader.py" est compatible avec Python 2 ou Python 3 ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 14, 2018, 09:09:17 am
Les branchements utilisés pour le test hardware qui rapporte un succès sont ok. Il n’y a visiblement aucun soucis entre la Teensy et la flash.

Concernant les broches alternatives, elles existent effectivement mais ce ne sont as n’importe lesquelles. Je suis très surpris que la classe SPI du Teensy permette de spécifier n’importe quelle broche. En aucun cas on ne peut placer le SPI n’importe où.

Python est a la version 2.7 sur ta machine. L’erreur se produit à l’intérieur de PySerial, pas dans le script rawfile_uploader.py. Donc il n’y a pas d’incompatibilité de version entre le script et python.

Je pense que sous Windows tu peux avoir un état de ce qui est branché sur l’USB. Si tu branches le Teensy et que tu regardes cet état qu’est ce qu’on y lit ? Y a t il des droits associés aux ports série virtuels ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 15, 2018, 12:02:00 am
Je vais voir cela.
Auparavant, j'avais tout rechargé (IDE Arduino + add-on teensy + Python 2.7 + Pyserial) sur un autre PC (PC fixe +Windows 7).
Je travaille normalement sur un portable ASUS 550C avec Windows 10.
J'ai exactement les mêmes messages d'erreur dans l'écran de commande Windows que ce soit avec Windows 7 ou 10 .
J'ai l'impression que c'est la ligne 80 :
ser.write("".join(encoded))du script "rawfile-uploader.py" qui semble poser des problèmes à windows
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: msport le mars 15, 2018, 10:31:19 am
Aucune compétence sur le sujet lui-même, mais cela mérite de regarder dans le Gestionnaire de périphériques les ports COM ouverts et de désactiver provisoirement ceux qui ne servent pas. J'ai eu un problème du même genre avec processing qui n'utilisait pas le bon.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 16, 2018, 10:41:57 am
Merci,
J'ai vérifié le formalisme du langage Python et j'ai modifié les lignes suivantes :
f = open(filename, "rb") --> f = open(filename, 'rb')et
ser.write("".join(encoded)) --> ser.write("".(encode())
Le script rawfile-uploader.py ne plante plus et indique :
All files uploaded (s'il le dit ?!)

Maintenant, il reste à vérifier que la SPI Flash se charge bien.
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 16, 2018, 02:07:35 pm
J'ai vérifié le formalisme du langage Python et j'ai modifié les lignes suivantes :
f = open(filename, "rb") --> f = open(filename, 'rb')

Soit, mais je pense que c'est la même chose. Python ne fait pas la différence entre quotes simples et doubles pour les chaines pourvu qu'on ne les mélange pas.

Citer
et
ser.write("".join(encoded)) --> ser.write("".(encode())
Le script rawfile-uploader.py ne plante plus et indique :
All files uploaded (s'il le dit ?!)

Maintenant, il reste à vérifier que la SPI Flash se charge bien.

Là par contre c'est complètement différent.

"".join(encoded)
concatène à la chaine vide l'agglomération des données de la liste encoded (qui est une variable initialisé à la liste vide à la ligne 54 et donc chaque élément est un octet à envoyer au sketch).

"".(encode()
encode la chaine vide. En l'absence d'argument, l'encodage n'est pas changé. Par conséquent la chaine vide est écrite. Comme il y a fort à parier que ser.write implémente une boucle où chaque caractère de la chaine est écrit sur le port série, la boucle ne s'exécute pas (étant donné que la chaine ne contient rien) et aucun caractère n'est envoyé ce qui explique qu'il n'y ait pas d'erreur.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 16, 2018, 11:31:55 pm
Merci Jean-Luc pour tes remarques pertinentes.
Je me retrouve donc avec le même problème de write out.
Je me demande si le fichier "AABR99.TRW" (en majuscule) est bien placé dans l'arborescence (c:\Python27\ ) pour être trouvé et lu par le script?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 17, 2018, 07:56:17 am
Je pense qu’il est trouvé et lu. Sinon une erreur se produirait à la ligne où est situé le open.

Un test simple, déplace le fichier et lance le script pour voir cette erreur.

C’est l’écriture sur le port série qui pose problème
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 17, 2018, 06:31:28 pm
Je suis coincé :
1) Le fichier à charger "AABR99.TRW" est bien placé.
2) J'ai interchangé les ports USB souris et liaison USB Teensy.
3) J'ai monté la configuration IDE Arduino + add-on teensy + Python 2.7 + Pyserial 3.4) sur un autre PC (PC fixe +Windows 7) -> même message de write out.
4) je suis allé sur le "Gestionnaire de périphériques" :à priori, rien d'étrange le port "COM4" est reconnu (voir ci-après).

C:\Python27>python -c "import serial, sys; print(sys.platform, serial.VERSION)"
('win32', '3.4')

C:\Python27>python -m serial.tools.list_ports
COM4
1 ports found

C:\Python27>Python "rawfile-uploader.py" "COM4" "AABR99.TRW"
Uploading 1 files...
1: AABR99.TRWTraceback (most recent call last):
  File "rawfile-uploader.py", line 81, in <module>
    ser.write("".join(encoded))
  File "C:\Python27\lib\site-packages\serial\serialwin32.py", line 323, in write
    raise writeTimeoutError
serial.serialutil.SerialTimeoutException: Write timeout

C:\Python27>Pause
Appuyez sur une touche pour continuer...


Je ne sais plus quoi tester !
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 17, 2018, 06:40:51 pm
Peux tu poster le code autour de la ligne 323 de C:\Python27\lib\site-packages\serial\serialwin32.py ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 17, 2018, 08:21:42 pm
 Ligne 301
def write(self, data):
        """Output the given byte string over the serial port."""
        if not self.is_open:
            raise portNotOpenError
        #~ if not isinstance(data, (bytes, bytearray)):
            #~ raise TypeError('expected %s or bytearray, got %s' % (bytes, type(data)))
        # convert data (needed in case of memoryview instance: Py 3.1 io lib), ctypes doesn't like memoryview
        data = to_bytes(data)
        if data:
            #~ win32event.ResetEvent(self._overlapped_write.hEvent)
            n = win32.DWORD()
            success = win32.WriteFile(self._port_handle, data, len(data), ctypes.byref(n), self._overlapped_write)
            if self._write_timeout != 0:  # if blocking (None) or w/ write timeout (>0)
                if not success and win32.GetLastError() not in (win32.ERROR_SUCCESS, win32.ERROR_IO_PENDING):
                    raise SerialException("WriteFile failed ({!r})".format(ctypes.WinError()))

                # Wait for the write to complete.
                #~ win32.WaitForSingleObject(self._overlapped_write.hEvent, win32.INFINITE)
                win32.GetOverlappedResult(self._port_handle, self._overlapped_write, ctypes.byref(n), True)
                if win32.GetLastError() == win32.ERROR_OPERATION_ABORTED:
                    return n.value  # canceled IO is no error
                if n.value != len(data):
Ligne 323                    raise writeTimeoutError
                return n.value
            else:
                errorcode = win32.ERROR_SUCCESS if success else win32.GetLastError()
                if errorcode in (win32.ERROR_INVALID_USER_BUFFER, win32.ERROR_NOT_ENOUGH_MEMORY,
                                 win32.ERROR_OPERATION_ABORTED):
                    return 0
                elif errorcode in (win32.ERROR_SUCCESS, win32.ERROR_IO_PENDING):
                    # no info on true length provided by OS function in async mode
                    return len(data)
                else:
                    raise SerialException("WriteFile failed ({!r})".format(ctypes.WinError()))
        else:
            return 0
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 17, 2018, 09:32:49 pm
J'ai vu éventuellement quelque chose sur la ligne de "serialwin32.py" ------>            n = win32.DWORD().
Dans l'aide Windows :
https://support.microsoft.com/fr-fr/help/817900/usb-port-may-stop-working-after-you-remove-or-insert-a-usb-device
Il propose de modifier le registre :
Si l'entrée de Registre DisableSelectiveSuspend est présente, double-cliquez dessus.
Si elle ne l'est pas, créez l'entrée.
Pour créer l'entrée, procédez comme suit :

    Dans le menu Edition, pointez sur Nouveau, puis cliquez sur DWORD.
    Tapez DisableSelectiveSuspend, puis appuyez sur ENTRÉE.
    Dans le menu Edition, cliquez sur Modifier.

Dans le champ Données de la valeur, tapez 1 pour désactiver la fonction de suspension sélective, puis cliquez sur OK.

Qu'en penses-tu ?
Cela n'a peut-être rien à voir ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 18, 2018, 12:14:16 am
Concernant la dernière question juste au dessus, je ne sais pas

Essaye ceci:

Ligne 41, tu as

ser = serial.Serial(sys.argv[1])

Met à la place

ser = serial.Serial(sys.argv[1], write_timeout=0)

pour voir
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 18, 2018, 01:08:51 am
C:\Python27>python -m serial.tools.list_ports
COM4
1 ports found

C:\Python27>Python "rawfile-uploader.py" "COM4" "AABR99.TRW"
Uploading 1 files...
1: AABR99.TRW (1613.34 KB/s)
All files uploaded

C:\Python27>Pause
Appuyez sur une touche pour continuer...

Merci Jean-Luc. Cela semble fonctionner. il faut que je regarde ce qu'il y a d'écrit dans la Flash.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 18, 2018, 09:01:50 am
Ah super  :)

1: AABR99.TRW (1613.34 KB/s)
All files uploaded

J’avais lu dans un message de Paul que l’émulation série négligeait la vitesse spécifiée et fonctionnait à la vitesse maximum possible. 1,6 MB/s c’est pas mal :)

Ca veut dire qu’en lecture de la flash  tu au moins pouvoir atteindre ce débit. Si mon compte est bon (16 bits, 44kHz)  ça permet de lire jusqu’à 18 fichiers en parallèle.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 18, 2018, 02:50:44 pm
Pour l'instant, j'essaie de voir si le fichier a été chargé dans la "Flash" avec "ListFiles.ino"
ListFiles.ino
#include <SerialFlash.h>
#include <SPI.h>

//#define FlashChipSelect  6   //6
const int FlashChipSelect = 10 ; // digital pin for flash chip CS pin
//const int FlashChipSelect = 21; // Arduino 101 built-in SPI Flash

void setup() {
  //uncomment these if using Teensy audio shield
  //SPI.setSCK(14);  // Audio shield has SCK on pin 14
  //SPI.setMOSI(7);  // Audio shield has MOSI on pin 7

  //uncomment these if you have other SPI chips connected
  //to keep them disabled while using only SerialFlash
//  pinMode(4, INPUT_PULLUP);
//  pinMode(10, INPUT_PULLUP);
//************************************
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(11);  // uncomment these if using the alternate pins
  SPI.setMISO(12);// 12
  SPI.setSCK(14); //14

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

  Serial.begin(9600);

  // wait for Arduino Serial Monitor
  while (!Serial) ;
  delay(100);
  Serial.println("All Files on SPI Flash chip:");

//  if (!SerialFlash.begin(FlashChipSelect)) {
//    error("Unable to access SPI Flash chip");
//  }

  SerialFlash.opendir();
  while (1) {
    char filename[64];
    uint32_t filesize;

    if (SerialFlash.readdir(filename, sizeof(filename), filesize)) {
      Serial.print("  ");
      Serial.print(filename);
      spaces(20 - strlen(filename));
      Serial.print("  ");
      Serial.print(filesize);
      Serial.print(" bytes");
      Serial.println();
    } else {
      break; // no more files
    }
  }
}

void spaces(int num) {
  for (int i=0; i < num; i++) {
    Serial.print(" ");
  }
}

void loop() {
}

void error(const char *message) {
  while (1) {
    Serial.println(message);
    delay(2500);
  }
}

Résultat sur le moniteur arduino/Teensy :
All Files on SPI Flash chip:

--> aucun fichier n'est présent dans la Flash !
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 18, 2018, 02:52:34 pm
Juste pour être sûr, tu es revenu à l'original pour les deux modifs mentionnées ici :

Merci,
J'ai vérifié le formalisme du langage Python et j'ai modifié les lignes suivantes :
f = open(filename, "rb") --> f = open(filename, 'rb')et
ser.write("".join(encoded)) --> ser.write("".(encode())
Le script rawfile-uploader.py ne plante plus et indique :
All files uploaded (s'il le dit ?!)

Maintenant, il reste à vérifier que la SPI Flash se charge bien.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 18, 2018, 06:41:39 pm
Suivant tes explications, je suis revenu au script d'origine avec seulement la modification suivante :
FLASH_SIZE = 64
La ligne correspondant à la concaténation du fichier est bien celle du script "rawfile_uploader.py" d'origine :
ser.write("".join(encoded))
Je commence à douter.
Le script "rawfile_uploader.py" est t-il en Python 2 ou Python 3 ?

Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 20, 2018, 09:55:02 pm
En passant en Python 3.6 (au lieu de Python 2.7), j'obtiens en lançant "rawfile-uploadr.py,  le type d’erreur suivant sur l'écran de commande Windows :
Python36>python -m serial.tools.list_ports
COM4
1 ports found
C:\Users\NexterECT\AppData\Local\Programs\Python\Python36>Python "rawfile-uploader.py" "COM4" "AABR99.TRW"
Uploading 1 files...
1: AABR99.TRWTraceback (most recent call last):
  File "rawfile-uploader.py", line 82, in <module>
    ser.write("".join(encoded))
TypeError: sequence item 17: expected str instance, int found

Nota : la ligne 82 est modifiée : ser = serial.Serial(sys.argv[1], write_timeout=0)

Donc, j'ai écrit :
ser.write("".join (str(encoded)))à la place de :
ser.write("".join(encoded))Il n'y a plus de messages d'erreur, mais le fichier AABR99.trw défile sur l'écran de commande Windows, mais ne monte pas sur le COM4 !
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 20, 2018, 11:52:05 pm
J'avais pas fait gaffe :

Tout d'abord, tu devrais éliminer les lignes de code commentée, c'est pas lisible.

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

//#define FlashChipSelect  6   //6
const int FlashChipSelect = 10 ; // digital pin for flash chip CS pin
//const int FlashChipSelect = 21; // Arduino 101 built-in SPI Flash

void setup() {
  //uncomment these if using Teensy audio shield
  //SPI.setSCK(14);  // Audio shield has SCK on pin 14
  //SPI.setMOSI(7);  // Audio shield has MOSI on pin 7

  //uncomment these if you have other SPI chips connected
  //to keep them disabled while using only SerialFlash
//  pinMode(4, INPUT_PULLUP);
//  pinMode(10, INPUT_PULLUP);
//************************************
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(11);  // uncomment these if using the alternate pins
  SPI.setMISO(12);// 12
  SPI.setSCK(14); //14


J'enlèverais les 3 lignes qui précèdent


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

  Serial.begin(9600);

  // wait for Arduino Serial Monitor
  while (!Serial) ;
  delay(100);
  Serial.println("All Files on SPI Flash chip:");

//  if (!SerialFlash.begin(FlashChipSelect)) {
//    error("Unable to access SPI Flash chip");
//  }


Si ces 3 lignes sont commentées, ça ne peut pas marcher

  SerialFlash.opendir();
  while (1) {
    char filename[64];
    uint32_t filesize;

    if (SerialFlash.readdir(filename, sizeof(filename), filesize)) {
      Serial.print("  ");
      Serial.print(filename);
      spaces(20 - strlen(filename));
      Serial.print("  ");
      Serial.print(filesize);
      Serial.print(" bytes");
      Serial.println();
    } else {
      break; // no more files
    }
  }
}

void spaces(int num) {
  for (int i=0; i < num; i++) {
    Serial.print(" ");
  }
}

void loop() {
}

void error(const char *message) {
  while (1) {
    Serial.println(message);
    delay(2500);
  }
}
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 21, 2018, 09:28:56 pm
CopyFromSerial
/*
 * This is free and unencumbered software released into the public domain.
 *
 * 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!
 */
// SPI Flash 25Q64BVSIG
#include <SPIFlash.h>
#include <SerialFlash.h>
#include <SPI.h>

//Buffer sizes
#define USB_BUFFER_SIZE      128
#define FLASH_BUFFER_SIZE    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

#define CSPIN  10

void setup(){
  Serial.begin(9600);  //Teensy serial is always at full USB speed and buffered... the baud rate here is required but ignored
  pinMode(13, OUTPUT);
   
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(11);
  SPI.setMISO(12);
  SPI.setSCK(14);

  if (!SerialFlash.begin(CSPIN)) {
    while (1) {
      Serial.println("Unable to access SPI Flash chip");
      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);

  //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
  while(Serial.available() || lastReceiveTime + 3000 > millis()){//3000
    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;
        }
      }
    }
  }

  //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
  while(Serial.available() || lastReceiveTime + 3000 > millis()){
    if (Serial.readBytes(usbBuffer, USB_BUFFER_SIZE)){
      lastReceiveTime = millis();
    }
  }
}

rawfile_uploader.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 = 64

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], write_timeout=0)

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 (str(encoded)))


finally:
f.close()

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

print("All files uploaded")

Résultat sur l'invite de commande Windows :

1) Avec ser.write("".join ((encoded)))
C:\Python36>python -m serial.tools.list_ports
COM4
1 ports found

C:\Python36>Python "rawfile-uploader.py" "COM4" "AABR99.TRW"
Uploading 1 files...
1: AABR99.TRWTraceback (most recent call last):
  File "rawfile-uploader.py", line 85, in <module>
    ser.write("".join ((encoded)))
TypeError: sequence item 17: expected str instance, int found

2) Avec ser.write("".join (str(encoded)))
C:\Python36>python -c "import serial, sys; print(sys.platform, serial.VERSION)"
win32 3.4

C:\Python36>python -m serial.tools.list_ports
COM4
1 ports found

C:\Python36>Python "rawfile-uploader.py" "COM4" "AABR99.TRW"
Uploading 1 files...
1: AABR99.TRWTraceback (most recent call last):
  File "rawfile-uploader.py", line 85, in <module>
    ser.write("".join (str(encoded)))
  File "C:\Python36\lib\site-packages\serial\serialwin32.py", line 308, in write
    data = to_bytes(data)
  File "C:\Python36\lib\site-packages\serial\serialutil.py", line 63, in to_bytes
    raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))
TypeError: unicode strings are not supported, please encode to bytes: "['(~)', 'A', 'A', 'B', 'R', '9', '9', '.', 'T', 'R', 'W', '|', '\\x00', '\\\\', 'û', '\\x04', '|', 125, 125, 46, 129, 255, 255, 2, 0, 254, 255, 3, 0, 253, 255, 2, 0, 255, 255, 0, 0, 0, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 0, 255, 255, 255, 255, 2, 0, 254, 255, 3, 0, 254, 255, 1, 0, 0, 0, 255, 255, 2, 0, 254, 255, 0, 0, 2, 0, 252, 255, 5, 0, 253, 255, 1, 0, 2, 0, 253, 255, 3, 0, 253, 255, 0, 0, 0, 0, 254, 255, 255, 255, 1, 0, 251, 255, 5, 0, 251, 255, 4, 0, 253, 255, 3, 0, 253, 255, 3, 0, 254, 255, 1, 0, 0, 0, 0, 0, 255, 255, 1, 0, 254, 255, 3, 0, 254, 255, 1, 0, 0, 0, 255, 255, 2, 0, 253, 255, 3, 0, 254, 255, 1, 0, 0, 0, 255, 255, 2, 0, 253, 255, .........................................................
 255, 255, 253, 255, 4, 0, 251, 255, 3, 0, 253, 255, 0, 0, 0, 0, 0, 0, '(~)']"
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 21, 2018, 09:44:35 pm
Mais ça marchait ça en Python 2.7  :)

Moi je pense que le premier téléversement en Python 2.7 a fonctionné.

Le sketch utilisé pour lister les fichiers avait des lignes commentées sauvagement : pas d'init du SPI, aucune chance que ça marche

Pourquoi avoir installé Python 3.6 ce qui entraine des erreurs dans l'exécution du script ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 21, 2018, 11:51:30 pm
A priori, avec Python 2.7, le script se déroulait jusqu'à la fin (All files uploaded) avec ta modification "write_timeout 0", mais rien ne montait dans la Flash.
Donc, je suis passé en Python 3.6. Et là, j'ai un message d'erreur lié au format des données :  raise TypeError('unicode strings are not supported, please encode to bytes: {!r}'.format(seq))
1) D'ailleurs, je ne sais pas si Python 2 est compatible avec Python 3 ?
2) Si c'est un problème de port COM4 sur Windows, j'ai :
- Réinstaller les ports USB
- Appliquer les updates
......?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 21, 2018, 11:54:38 pm
Mais j'ai souligné là : http://forum.locoduino.org/index.php?topic=427.msg5090#msg5090

que ces trois lignes commentées :

//  if (!SerialFlash.begin(FlashChipSelect)) {
//    error("Unable to access SPI Flash chip");
//  }

Faisait que le listing du directory ne pouvait pas marcher !

Comment sais-tu que la flash n'a pas été écrite ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 22, 2018, 10:18:00 am
1) Selon toi, il vaut mieux que je repasse en Python 2.7 ?
2) j'avais momentanément mis en commentaire les lignes suivantes :
//  if (!SerialFlash.begin(FlashChipSelect)) {
//    error("Unable to access SPI Flash chip");
//  }
Maintenant, elle sont réintégrées.

3) Comment sais-tu que la flash n'a pas été écrite ?
- Le LED du Teensy reste allumée "fixe" : le Teensy est en attente de donnée provenant du COM4
- Quand j'exécute le programme "ListFiles.ino", il y a juste écrit sur le moniteur série :"All Files on SPI Flash chip:" et rien derrière !
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 25, 2018, 05:44:34 pm
Bon, cela semble enfin marcher :
Résultats Invite commande Windows :
C:\Python27>python -c "import serial, sys; print(sys.platform, serial.VERSION)"
('win32', '3.4')

C:\Python27>python -m serial.tools.list_ports
COM4
1 ports found

C:\Python27>Python "rawfile-uploader.py" "COM4" "AR2BR99.TRW"
Uploading 1 files...
1: AR2BR99.TRW (1437.38 KB/s)
All files uploaded


ListFiles.ino (résultats moniteur série):
All Files on SPI Flash chip:
  AR2BR99.TRW           764164 bytes


Procédure :
1) Téléverser CopyFromSerial vers le Teensy
2) Fermer l'IDE ARDUINO (tout ce qui est susceptible d'interférer avec le bus série "COM"
3) Débrancher la prise USB
4) Rebrancher le bus USB (CopyFromSerial se lance automatiquement)
5) Dés que la prise USB est branchée, lancer le script :
python -c "import serial, sys; print(sys.platform, serial.VERSION)"
python -m serial.tools.list_ports
Python "rawfile-uploader.py" "COM4" "AR2BR99.TRW"
Pause
Le chargement dans la SPI Flash est un peu long (10 s pour environ  1 Mo).
Je dois maintenant récupérer les données de la SPI Flash et les sortir sur la pin14 du Teensy (Convertisseur Numérique / Analogique).
puis gérer finement (et rapidement) les fichiers "son" en fonction des commandes DCC (Mobile Station 2 Märklin) et de la vitesse de la locomotive.

Merci Jean-Luc pour tes conseils et ton soutien.





Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 25, 2018, 11:34:23 pm
Ahhhh. Super  :)

10s pour 1Mo, ça fait quand même presque du 1Mb/s, c'est pas mal :-)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 30, 2018, 11:49:31 pm
J'ai passé le programme "ReadBenchmark.ino" pour vérifier les caractéristiques de la Flash et du fichier enregistré :
#include <SerialFlash.h>
#include <SPI.h>

const int FlashChipSelect = 10; // digital pin for flash chip CS pin

void setup() {
//************************************
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(11);  // uncomment these if using the alternate pins
  SPI.setMISO(12);// 12
  SPI.setSCK(14); //14

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

  Serial.begin(9600);

  // wait for Arduino Serial Monitor
  while (!Serial) ;
  delay(100);
  Serial.println("All Files on SPI Flash chip:");

  if (!SerialFlash.begin(FlashChipSelect)) {
    while (1) {
      Serial.println("Unable to access SPI Flash chip");
      delay(2500);
    }
  }

  SerialFlash.opendir();
  int filecount = 0;
  while (1) {
    char filename[64];
    uint32_t filesize;

    if (SerialFlash.readdir(filename, sizeof(filename), filesize)) {
      Serial.print(filename);
      Serial.print(" = ");
      Serial.print(filesize);
      Serial.println(" bytes");
      SerialFlashFile file = SerialFlash.open(filename);
      if (file) {
        unsigned long usbegin = micros();
        unsigned long n = filesize;
        char buffer[256];
        while (n > 0) {
          unsigned long rd = n;
          if (rd > sizeof(buffer)) rd = sizeof(buffer);
          file.read(buffer, rd);
          n = n - rd;
        }
        unsigned long usend = micros();
        Serial.print("Read in = ");
        Serial.println(usend - usbegin);
        Serial.print("usbegin = ");             
        Serial.println(usbegin);
        Serial.print("usend = ");
        Serial.println(usend);

        Serial.print("us, speed = ");
        Serial.print((float)filesize * 1000.0 / (float)(usend - usbegin));
        Serial.println(" kbytes/sec");
        file.close();
      } else {
        Serial.println(" error reading this file!");
      }
      filecount = filecount + 1;
    } else {
      if (filecount == 0) {
        Serial.println("No files found in SerialFlash memory.");
      }
      break; // no more files
    }
  }
}

void loop() {
}
et j’obtiens sur le moniteur série :
All Files on SPI Flash chip:
AR2BR99.TRW = 764164 bytes
Read in = 401308
usbegin = 2168146
usend = 2569454
us, speed = 1904.18 kbytes/sec

----> usbegin : c'est l'adresse de départ du fichier ? en décimal ?
----> usend : c'est l'adresse de fin du fichier ? en décimal ?

Sinon, pour le son à envoyer sur le DAC, j'ai le choix entre  :
1) lire les données par paquets de 16 bits en synchronisant la vitesse de lecture avec "IntervalTimer myTimer;" et les envoyer sur le DAC.
2) utiliser les bibliothèques des exemples donnés sur PRJC :
#include <Audio.h>
#include <Wire.h>
#include <SPIFlash.h>
#include <SerialFlash.h>
#include <SPI.h>
#include "play_serialflash.h"
Mais je pense que la bibliothèque "Audio.h" ne marche que si l'on dispose d'une audioshield compatible du teensy.
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mars 31, 2018, 12:17:14 am
...
et j’obtiens sur le moniteur série :
All Files on SPI Flash chip:
AR2BR99.TRW = 764164 bytes
Read in = 401308
usbegin = 2168146
usend = 2569454
us, speed = 1904.18 kbytes/sec

----> usbegin : c'est l'adresse de départ du fichier ? en décimal ?
----> usend : c'est l'adresse de fin du fichier ? en décimal ?

 :D. Analyse le sketch, je ramasse les copies dans 1 heure :)

Citer
Sinon, pour le son à envoyer sur le DAC, j'ai le choix entre  :
1) lire les données par paquets de 16 bits en synchronisant la vitesse de lecture avec "IntervalTimer myTimer;" et les envoyer sur le DAC.
2) utiliser les bibliothèques des exemples donnés sur PRJC :
#include <Audio.h>
#include <Wire.h>
#include <SPIFlash.h>
#include <SerialFlash.h>
#include <SPI.h>
#include "play_serialflash.h"
Mais je pense que la bibliothèque "Audio.h" ne marche que si l'on dispose d'une audioshield compatible du teensy.

Non je ne crois pas, ça marche sans le shield. Il y a un outil en ligne pour construire ta chaine audio https://www.pjrc.com/teensy/gui/index.html
À partir duquel tu génères ton code. J'y vois une source qui s'appelle playRawFlash.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mars 31, 2018, 02:21:41 pm
Citer
:D. Analyse le sketch, je ramasse les copies dans 1 heure :)
Ou dans 3600000000 Microsecondes.
Ok, ce sont des temps en Microsecondes qui permettent, in fine, de calculer le débit (1904.18 kbytes/sec !).

J'espérais obtenir l'adresse de début du fichier sur la SPI Flash.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le avril 02, 2018, 11:48:17 pm
Suite à tes conseils, j'ai utilisé l'outil graphique de configuration du Teensy.
Ma configuration est :
 - Teensy 3.2 + SPI Flash Winbond 25Q64BVSIG (sans carte audio)
 - Pins used are 11(DOUT),12(DIN),14(SCK),10(CS).
 - AR2BR99.TRW chargé dans la SPI Flash.

J'aimerais envoyer ce fichier vers le DAC (A14).
Mais, je n'ai aucun son.
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

#define FLASH_CHIP_SELECT 10
 
// GUItool: begin automatically generated code
AudioPlaySerialflashRaw  playFlashRaw1;  //xy=114,184
AudioOutputAnalog        dac1;           //xy=751,337
AudioConnection          patchCord1(playFlashRaw1, dac1);
// GUItool: end automatically generated code

void setup() {
  AudioMemory(10);
  analogReference(EXTERNAL);
//************************************
//  Set up SPI Teensy without audio Card
  SPI.setMOSI(11);
  SPI.setMISO(12);
  SPI.setSCK(14);
//************************************
    Serial.begin(9600);
    while (!Serial) ;
    delay(100);
   
    if (!SerialFlash.begin(FLASH_CHIP_SELECT)) {
        while (1){
      Serial.println ("Cannot access SPI Flash chip");
      delay (1000);
        }
      }

   playFile("AR2BR99.TRW");
   delay(20000);
}
      void playFile(const char *filename){
        Serial.print("Playing file: ");
        Serial.println(filename);
        // Start playing the file. This sketch continues to
        // run while the file plays.
        playFlashRaw1.play("AR2BR99.TRW");
        delay(20000);
       }   
void loop() {

}

Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le avril 04, 2018, 09:35:08 pm
J'ai l'impression qu'il ne doit pas être possible de sortir le son issu de la SPI Flash vers le DAC du Teensy (pin A14).

Sur le site PRJC : https://www.pjrc.com/store/teensy3_audio.html , le Teensy est couplé à une carte audio qui elle possède un lecteur SD et un emplacement permettant de souder une SPI Flash. Cette carte possède en particulier un DAC qui doit être mis en œuvre grâce à la bibliothèque Audio.h (PlayFlashRaw).
Le Teensy pilote la carte audio par un bus I2C (SDA - SCL) et le bus série (Tx - Rx).
IL semble que la bibliothèque PlayRawFlash ne puisse ne mettre en œuvre que le DAC de la carte audio.
Y at-il une possibilité que le son de la SPI Flash puisse attaquer la sortie DAC A14 du Teensy?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le avril 16, 2018, 11:27:37 am
Mais oui

Lire le fichier de la flash et sortir le son sur le DAC sont deux choses séparées. Il n'y a aucune raison que ça ne fonctionne pas.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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
//  }
  }
}
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mai 23, 2018, 02:10:12 pm
Bonjour Benoit,

Dans le programme que tu viens de poster, on s'aperçoit que :


Donc, si tu veux que le son s'arrête, il suffit de mettre lu à un caractère qui n'apparaît pas dans le switch à la fin de loop

Ensuite ce que tu veux faire c'est plutôt avoir le horn superposé avec le bruit de machine ? Dans ce cas, il faut plutôt avoir plusieurs canaux et un mixer.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le mai 23, 2018, 09:04:41 pm
Ok, merci Jean-Luc.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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;
   }     
  }
}
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le mai 29, 2018, 09:59:00 pm
Si la SPI FLASH est une Carte SD, c’est facile d’y écrire des fichiers avec un PC.
Pour les restituer avec un Arduino, j’explique mon projet ici :
http://forum.locoduino.org/index.php?topic=157.60 (http://forum.locoduino.org/index.php?topic=157.60)
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mai 29, 2018, 10:31:40 pm
Non ce n'est pas une carte SD

- Écrire dans la SPI Flash à partir d'un fichier "son" qui est situé sur le PC

Il est fort possible que le sketch que tu as utilisé sur Teensy fonctionne également. Idem pour le programme côté PC

Citer
- Lire ce fichier "son" sur l'arduino (à partir de son nom de fichier)

Là par contre je doute que Audio fonctionne sur Arduino.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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)



Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le mai 30, 2018, 07:00:24 am
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).
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Thierry le mai 30, 2018, 09:14:02 am
Pour une taille comparable à un nano, il y a aussi l'ESP32 (https://www.banggood.com/fr/ESP32-Development-Board-WiFiBluetooth-Ultra-Low-Power-Consumption-Dual-Cores-ESP-32-ESP-32S-Board-p-1109512.html?cur_warehouse=CN) et les STM32 (https://www.banggood.com/fr/STM32F103C8T6-Small-System-Board-Microcontroller-STM32-ARM-Core-Board-For-Arduino-p-1058299.html?rmmds=search&cur_warehouse=CN), pas chers, et plus proches du Teensy en terme de mémoire.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le mai 30, 2018, 11:57:16 am
Du coup je ne comprends pas trop

Comme dit Dominique le Teensy est plus petit qu'un Nano. Il est beaucoup plus puissant (calcul, mémoire). Il a une sortie DAC qui évite la circuiterie externe pour lisser la PWM, il a un support en terme de bibliothèques audio qui est plus avancé, il est complètement compatible avec l'infrastructure logicielle Arduino. Et enfin tu as commencé à prototyper des choses qui marchent dessus.

Pourquoi essayer de faire entrer au chausse pied tes fonctions dans un Nano ?

D'ailleurs ça risque bien de ne pas rentrer, si tu veux par exemple mixer le bruit moteur, le klaxon et le freinage, et je ne parle pas de la fréquence du SPI qui est limité à 8MHz alors que sur Teensy tu peux monter à 24MHz.

Thierry, sur l'ESP 32 il n'y a pas de sortie DAC et la PWM est logicielle. Les STM32 ont un support Arduino limité.
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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.
Titre: Re : Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique 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é.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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),
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique 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.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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

Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc 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.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc 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.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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);
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc 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
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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)

Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le juin 02, 2018, 07:32:37 am
Je pense oui.
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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)
    }
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc 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
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 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
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le juin 02, 2018, 07:33:47 pm
Ça dépend comment c’est fait. Essaye  8)
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le juin 24, 2018, 01:07:53 am
J’essaye de faire cohabiter sur le Teensy 3.2 :
Les deux codes fonctionnent séparément.
J'ai donc rapproché les deux codes.
Le résultat est le suivant (vu sur le moniteur série) :
Dés que j'active le son (en appuyant sur la touche F1 de la MS2), le décodage de la trame DCC s'arrête durant les 5 secondes que dure le bruitage,
puis le décodage de la trame DCC reprend au début et s'arrête avant d'avoir décoder toute la trame,
puis le bruitage reprend et ainsi de suite ...
J'ai l'impression qu'il doit y avoir un conflit au niveau des ressources CPU.
Les signaux DCC arrive sur la patte RX1 (pin0) du Teensy
Cette pin est déclarée comme recevant une interruption (signal DCC) :   
[/list][/list]Dcc.pin(0, 0, 0);// Pin 0= Interrupt 0
Je ne vois pas quelle méthode utilisée pour que la fonction "son" ne vienne pas bloquer le décodage trame DCC.
Ci-après le code correspondant au problème ci-dessus :
#include <NmraDcc.h>
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

#define This_Decoder_Address 3
const int FLASH_CHIP_SELECT = 10;  // SPI Flash Chip Select (CS)
// GUItool: begin automatically generated code (Audio.h)
    AudioPlaySerialflashRaw  playFlashRaw1;  //xy=228,273
    AudioOutputAnalog        dac1;           //xy=751,337
    AudioConnection          patchCord1(playFlashRaw1, 0, dac1, 0);
// GUItool: end automatically generated code

struct CVPair
{
  uint16_t  CV;
  uint8_t   Value;
};
CVPair FactoryDefaultCVs [] =
{
// // The CV Below defines the Short DCC Address
  {CV_MULTIFUNCTION_PRIMARY_ADDRESS, This_Decoder_Address},

  // These two CVs define the Long DCC Address
  {CV_MULTIFUNCTION_EXTENDED_ADDRESS_MSB, 0},
  {CV_MULTIFUNCTION_EXTENDED_ADDRESS_LSB, This_Decoder_Address},

// ONLY uncomment 1 CV_29_CONFIG line below as approprate
  {CV_29_CONFIG,                                      0}, // Short Address 14 Speed Steps
  {CV_29_CONFIG,                       CV29_F0_LOCATION}, // Short Address 28/128 Speed Steps

  {CV_29_CONFIG, CV29_EXT_ADDRESSING | CV29_F0_LOCATION}, // Long  Address 28/128 Speed Steps 
};

NmraDcc  Dcc ;
uint8_t FactoryDefaultCVIndex = 0;

void notifyCVResetFactoryDefault()
{
//   Make FactoryDefaultCVIndex non-zero and equal to num CV's to be reset
//   to flag to the loop() function that a reset to Factory Defaults needs to be done
  FactoryDefaultCVIndex = sizeof(FactoryDefaultCVs)/sizeof(CVPair);
};

// Uncomment the #define below to print all Speed Packets
#define NOTIFY_DCC_SPEED
#ifdef  NOTIFY_DCC_SPEED
void notifyDccSpeed( uint16_t Addr, DCC_ADDR_TYPE AddrType, uint8_t Speed, DCC_DIRECTION Dir, DCC_SPEED_STEPS SpeedSteps )
{
  Serial.print("notifyDccSpeed: Addr: ");
  Serial.print(Addr,DEC);
  Serial.print( (AddrType == DCC_ADDR_SHORT) ? "-S" : "-L" );
  Serial.print(" Speed: ");
  Serial.print(Speed,DEC);
  Serial.print(" Steps: ");
  Serial.print(SpeedSteps,DEC);
  Serial.print(" Dir: ");
  Serial.println( (Dir == DCC_DIR_FWD) ? "Forward" : "Reverse" );
};
#endif

// Uncomment the #define below to print all Function Packets
#define NOTIFY_DCC_FUNC
#ifdef  NOTIFY_DCC_FUNC
  void notifyDccFunc(uint16_t Addr, DCC_ADDR_TYPE AddrType, FN_GROUP FuncGrp, uint8_t FuncState)
  {

      Serial.print("notifyDccFunc: Addr: ");
      Serial.print(Addr,DEC);
      Serial.print( (AddrType == DCC_ADDR_SHORT) ? 'S' : 'L' );
      Serial.print("  Function Group: ");
      Serial.print(FuncGrp,DEC);

    switch( FuncGrp ){
   {
      #ifdef NMRA_DCC_ENABLE_14_SPEED_STEP_MODE   
           case FN_0:
           Serial.print(" FN0: ");
           Serial.println((FuncState & FN_BIT_00) ? "1  " : "0  ");
           break;
      #endif
 
     case FN_0_4:
       if(Dcc.getCV(CV_29_CONFIG) & CV29_F0_LOCATION) // Only process Function 0 in this packet if we're not in Speed Step 14 Mode
       {
         Serial.print(" FN 0: ");
         Serial.print((FuncState & FN_BIT_00) ? "1  ": "0  ");
       }
   }
         Serial.print("FuncState:");
         Serial.print(FuncState);
         Serial.print("FN_BIT_00:");
         Serial.print(FN_BIT_00);

 //   Test Sound       
               if( (FuncState & FN_BIT_01) == 1){
               Serial.print("CabinLight:");
               playFile1("A0AB814.TRW");

              }
//               else
//              analogWrite(CabinLight,0);

        Serial.print(" FN 1-4: ");
        Serial.print((FuncState & FN_BIT_01) ? "1  ": "0  ");
        Serial.print((FuncState & FN_BIT_02) ? "1  ": "0  ");
        Serial.print((FuncState & FN_BIT_03) ? "1  ": "0  ");
        Serial.println((FuncState & FN_BIT_04) ? "1  ": "0  ");
       break;
     
     case FN_5_8:
         Serial.print(" FN 5-8: ");
         Serial.print((FuncState & FN_BIT_05) ? "1  ": "0  ");
        Serial.print((FuncState & FN_BIT_06) ? "1  ": "0  ");
        Serial.print((FuncState & FN_BIT_07) ? "1  ": "0  ");
        Serial.println((FuncState & FN_BIT_08) ? "1  ": "0  ");
       break;
   
     case FN_9_12:
       Serial.print(" FN 9-12: ");
       Serial.print((FuncState & FN_BIT_09) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_10) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_11) ? "1  ": "0  ");
       Serial.println((FuncState & FN_BIT_12) ? "1  ": "0  ");
       break;

     case FN_13_20:
       Serial.print(" FN 13-20: ");
       Serial.print((FuncState & FN_BIT_13) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_14) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_15) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_16) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_17) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_18) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_19) ? "1  ": "0  ");
       Serial.println((FuncState & FN_BIT_20) ? "1  ": "0  ");
       break;
 
     case FN_21_28:
       Serial.print(" FN 21-28: ");
       Serial.print((FuncState & FN_BIT_21) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_22) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_23) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_24) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_25) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_26) ? "1  ": "0  ");
       Serial.print((FuncState & FN_BIT_27) ? "1  ": "0  ");
       Serial.println((FuncState & FN_BIT_28) ? "1  ": "0  ");
       break; 
    }
}

#endif

// Uncomment the #define below to print all DCC Packets
#define NOTIFY_DCC_MSG
#ifdef  NOTIFY_DCC_MSG
    void notifyDccMsg( DCC_MSG * Msg)
    {
        Serial.print("notifyDccMsg: ");
        for(uint8_t i = 0; i < Msg->Size; i++)
        {
          Serial.print(Msg->Data[i], HEX);
          Serial.write(' ');
        }
        Serial.println();
    }

#endif

void setup()
{
    Serial.begin(9600); // Serial setup
    while (!Serial && millis()<500 );
    AudioMemory(50);//
    analogReference(EXTERNAL);// 3,3V
    Serial.println("NMRA Dcc Multifunction Decoder - Teensy - Spi Flash");
 
//********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);
        }
    }
    // Setup which External Interrupt, the Pin it's associated with that we're using and enable the Pull-Up
  Dcc.pin(0, 0, 0);// Pin 0= Interrupt 0
 
  // Call the main DCC Init function to enable the DCC Receiver
  Dcc.init( MAN_ID_DIY, 10, FLAGS_MY_ADDRESS_ONLY, 0 );

  // Uncomment to force CV Reset to Factory Defaults
  notifyCVResetFactoryDefault();
   }

void loop()
{
  // You MUST call the NmraDcc.process() method frequently from the Arduino loop() function for correct library operation
  Dcc.process();

  if( FactoryDefaultCVIndex && Dcc.isSetCVReady())
  {
    FactoryDefaultCVIndex--; // Decrement first as initially it is the size of the array
    Dcc.setCV( FactoryDefaultCVs[FactoryDefaultCVIndex].CV, FactoryDefaultCVs[FactoryDefaultCVIndex].Value);
  }
}
// ***********Spi Soundfile Read Function***************
    void playFile1(const char *filename)// Play audio file function
    {
      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()) {
     }
    }

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





Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le juillet 19, 2018, 11:32:36 pm
J'ai trouvé sur Ebay Allemagne une petite locomotive diesel de triage rouge (Echelle 1) pour une trentaine d'€.
J'ai changé le stator bobiné d'origine pour un rotor aimant permanent de chez ESU (+ charbons + Bandages adhérants +nettoyage complet du moteur).
J'ai récupéré certains sons sur "ESU Project".
Afin d'obtenir une grande réactivité pour la génération des sons (16 bits - 44kHz), certains fichiers son ne durent qu'environ 1 s.
Il existe certes,  des petits claquements à reprise de lecture. Je pense régler cela avec un condensateur, à moins qu'il existe une solution logicielle ?
La commande du moteur et des leds sera effectuée à partir d'un Arduino Nano.
Celui-ci enverra les ordres de lecture de son ('a', 'z', 'e', 'r', 't', 'y', 'u', 'i') avec la ligne Serial (Tx Rx).
Le Teensy 3.2 recevra les ordres de lecture de son sur la ligne Serial (Tx1 Rx1) (qui est indépendante de sa ligne Serial Tx Rx de la liaison USB - PC : avantage du Teensy).
Ci-joint, le code de génération du son du Teensy :
// Diesel Henschel DHG 500
// Teensy 3.2 + SPI Flash + Serial1(Arduino Nano)
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

    //'*' Type on Serial Monitor
    //DHG_STA.TRW = 'a' Engine start
    //DHG_STO.TRW = 'z' Stop Engine
    //DHG_HOR.TRW = 'e' Horn
    //DHG_SPE.TRW = 'r' Driving
    //DHG_BRA.TRW = 't' Brake
    //DHG_IDL.TRW = 'y' Idle
    //DHG_UNC.TRW = 'u' Uncoupling
    //DHG_ACC.TRW = 'i' Acceleration

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 Data;     // Read serial data
int PrevData;  // Read previous serial data
int i = 0;

void setup() {
    Serial.begin(9600); // Serial setup
    while (!Serial && millis()<500 );
    AudioMemory(50);//
//    analogReference(EXTERNAL);// 3,3V Amplitude 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)// Play audio file function
    {
      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() ) {
    Data = Serial.read();
    Serial.println(Data);
  }
  else {
    Serial.println("Nothing");
  }

  switch (Data) {
       case 'a':{  // Play Soundfile in loop : Start
            playFile1("DHG_STA.TRW");
                              Serial.println("DHG_STA.TRW");
            Data = 'y';
            playFile1("DHG_IDL.TRW");
                              Serial.println("DHG_IDL.TRW");
        break;
       }
      case 'z':{  // Play Soundfile in loop : Stop

           playFile1("DHG_STO.TRW");
                              Serial.println("DHG_STO.TRW");
           Data = 'o';
      break;
      }   
      case 'e':{   // Play Soundfile only once : Horn 
           playFile1("DHG_HOR.TRW");
                              Serial.println("DHG_HOR.TRW");
           Data=PrevData; // Continue with previous soundfile
           Serial.println(Data);
      break;
           }
     case 'r':{  // Play Soundfile in loop : Full Speed
           PrevData = 'r';
           playFile1("DHG_SPE.TRW");
                              Serial.println("DHG_SPE.TRW");
     break;
    }   
     case 't':{  // Play Soundfile in loop : Brake 
           PrevData = 't';
           playFile1("DHG_BRA.TRW");
           Data = 'y';
           playFile1("DHG_IDL.TRW");
     break;
    } 
     case 'y':{  // Play Soundfile in loop : Idle
         PrevData = 'y';
         playFile1("DHG_IDL.TRW");
                             Serial.println("DHG_IDL.TRW");
     break;
    }
     case 'u':{  // Play Soundfile in loop : Uncoupling
         PrevData = 'u';
         playFile1("DHG_UNC.TRW");
                             Serial.println("DHG_UNC.TRW");
         Data = 'y';
         playFile1("DHG_IDL.TRW");
                              Serial.println("DHG_IDL.TRW");
     break;
    }
     case 'i':{  // Play Soundfile in loop : Uncoupling
         PrevData = 'i';
         playFile1("DHG_ACC.TRW");
                             Serial.println("DHG_UNC.TRW");
         Data = 'r';
         playFile1("DHG_IDL.TRW");
                              Serial.println("DHG_IDL.TRW");
     break;
    }
 }
}
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Dominique le juillet 20, 2018, 01:40:09 pm
Échelle 1 !!!!

Ça doit prendre de la place dans le salon  ;D
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le juillet 20, 2018, 06:58:27 pm
En fait, j'ai commencé le modélisme ferroviaire il y a près de 50 ans avec un train Märklin  en HO.
Depuis, j'ai acheté de nombreuses locomotives, wagons, rails, caténaires ... pour réaliser des réseaux fixes.
Maintenant, je n'ai plus la place de faire un réseau fixe en HO.
Donc j'ai décidé de me mettre à l'échelle 1 et d'essayer de fabriquer le maximum de chose moi-même (partie électronique, informatique et mécanique).
L'intégration de l'électronique (Arduino, L238, Teensy, Ampli, haut parleur, alimentation, éclairages et feux) dans du HO est en effet plus compliquée (sans parler du N et du Z) par manque de place dans la locomotive.
Pour la partie mécanique, on se rapproche de l'horlogerie même en HO.

Donc je joue "à l'ancienne" : montage et démontage des rails dans le salon.
On peut aussi l'installer dans un jardin : Mon rêve si j'avais un jardin !
Si on veut laisser les rails en place, il vaut mieux utiliser les rails LGB qui sont plus résistants que les Märklin (qui sont plus réalistes).
Sinon, je pourrais également faire circuler ma 2D2 sur un réseau de club bien qu'en France contrairement de l’Allemagne et à la Suisse, l'échelle 1 soit peu développée (au profit de l'échelle O).
Le marché allemand (Ebay.de) à l'échelle 1 est assez développé et pas trop cher si on attend les bonnes opportunités.

Pour l'instant, j'ai avancé sur la partie électronique et logicielle, mais pas trop sur la partie mécanique de mon projet de 2D2.
Il faut dire que pour réaliser les roues (diamètre 60 mm), il faut que j'usine de l'inox (304L pour les connaisseurs : le 303 est plus usinable, mais introuvable) et les fraises cassent comme à Gravelotte.


Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le juillet 25, 2018, 12:13:07 am
J'essaye de faire dialoguer l'Arduino Nano avec le Teensy 3.2 avec une liaison série.
Mais, je ne récupère rien sur le moniteur série monté sur le Teensy via la liaison USB -PC.
De plus, je récupère le message suivant :
Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space

Code coté Arduino Nano (pin 7 et 8 )
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7, 8); // RX, TX
void setup()
{
  Serial.begin(9600); // USB moniteur série
  mySerial.begin (9600);// liaison série vers Teensy
}
void loop()
{
mySerial.write('a');// son démarrage moteur
}

Code coté Teensy (pin Rx1, Tx1)
#include <SoftwareSerial.h>
int Data
void setup() {
    Serial.begin(9600); // USB-PC
    while (!Serial && millis()<500 );
   Serial1.begin(9600); // liaison série vers Arduino
    while (!Serial1 && millis()<500 );
}

void loop() {
  if ( Serial1.available() ) {
    Data = Serial1.read();
    Serial.println(Data);
}

Nota : Je branche sur le PC soit la prise USB vers Arduino, soit USB vesr Teensy
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le juillet 25, 2018, 10:53:18 am
Bonjour,

C'est toi qui bloque le CPU dans playFile1 en attendant que le son finisse de jouer :

     // Simply wait for the file to finish playing.
     while (playFlashRaw1.isPlaying()) {
     }
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le juillet 25, 2018, 11:16:35 am
Merci Jean-Luc,
Par contre, je ne sais pas trop comment faire sur le Teensy  pour "et en même temps":
 - Jouer le son : playFlashRaw1
 - Recevoir les commandes de son (provenant de l'arduino) via SoftwareSerial mySerial(7, 8 ); // RX, T (sur le teensy)

Nota :
Quand je branche directement le Teensy sur le PC (liaison USB) et que je tape les commande 'a', 'z', ....... cela marche très bien.
Titre: Re : Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Jean-Luc le juillet 25, 2018, 03:05:42 pm
Merci Jean-Luc,
Par contre, je ne sais pas trop comment faire sur le Teensy  pour "et en même temps":
 - Jouer le son : playFlashRaw1
 - Recevoir les commandes de son (provenant de l'arduino) via SoftwareSerial mySerial(7, 8 ); // RX, T (sur le teensy)

Tout d'abord il faut enlever le while qui attend la fin du son et qui bloque la réception des commandes

Ensuite que veux tu faire ?

Une nouvelle commande doit-elle être mise en attente en attendant que le son termine ou bien le son en cours (si il y en a un) doit-il s'arrêter pour laisser la place au nouveau ?
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le juillet 25, 2018, 06:36:20 pm
1) J'ai essayé d'enlever le while, mais le son est catastrophique (cela donne un grésillement).

2) J'ai généré des sons globalement d'une durée de 1 à 2 s et donc je peux choisir l'option :
"Une nouvelle commande doit-elle être mise en attente en attendant que le son termine"

3) je vois sur certains exemples (pas tous) , que l'instruction "pinMode" est utilisée (je ne l'ai pas mise dans mon code) :
Ci-joint un exemple avec "pinMode"
// include the SoftwareSerial library so you can use its functions:
#include <SoftwareSerial.h>

#define rxPin 00
#define txPin 1

// set up a new serial port
SoftwareSerial mySerial =  SoftwareSerial(rxPin, txPin);

void setup()  {
  // define pin modes for tx, rx:
  pinMode(rxPin, INPUT);
  pinMode(txPin, OUTPUT);
  // set the data rate for the SoftwareSerial port
  mySerial.begin(9600);
  Serial.begin(9600);
}

void loop() {
  if (mySerial.available()>0){
  Serial.print(mySerial.read());
}
  if (Serial.available()>0){
  mySerial.print(Serial.read());
}
}
Titre: Re : Teensy 3.1, 3.2 - Sonorisation locomotive
Posté par: Benoit92 le juillet 25, 2018, 10:37:45 pm
Bon, maintenant, cela marche (petite inversion de fil).
Vu avec un oscilloscope USB que je sors quand j'ai un "gros" problème.
La liaison série entre l'Arduino Nano et le Teensy 3.2 est maintenant debuggé.

J'ai ajouté également "Serial1.clear();" car sinon, le Teensy ne voit pas les changements de commande de lecture de fichier (il reste toujours sur le même fichier).

Donc, ci-joint, le code du Teensy qui fonctionne :

// Diesel Henschel DHG 500
// Teensy 3.2 + SPI Flash + Serial1(-> Arduino Nano)
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>
#include <SoftwareSerial.h>

    //'*' Type on Serial Monitor
    //DHG_STA.TRW = 'a' Engine start
    //DHG_STO.TRW = 'z' Stop Engine
    //DHG_HOR.TRW = 'e' Horn
    //DHG_SPE.TRW = 'r' Driving
    //DHG_BRA.TRW = 't' Brake
    //DHG_IDL.TRW = 'y' Idle
    //DHG_UNC.TRW = 'u' Uncoupling
    //DHG_ACC.TRW = 'i' Acceleration

//SoftwareSerial mySerial(0, 1); // RX, TX

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

char Data;     // Read serial data
char PrevData;  // Read previous serial data
int i = 0;
int Led13 = 13;

void setup() {
    digitalWrite(Led13, HIGH);
    pinMode(Led13, OUTPUT);
    Serial.begin(9600); // Serial setup
    while (!Serial && millis()<500 );
    Serial.println("Diesel Henschel DHG 500");
   
    Serial1.begin(9600); // Serial1 setup
    while (!Serial1 && millis()<500 );
    AudioMemory(50);//
//    analogReference(EXTERNAL);// 3,3V Amplitude 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)// Play audio file function
    {
      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 ( Serial1.available() ) {
    Data = Serial1.read();
    Serial1.clear();
    Serial.println(Data);
  }
  else {
    Serial.println("Nothing");
  }

  switch (Data) {
       case 'a':{  // Play Soundfile in loop : Start
            playFile1("DHG_STA.TRW");
                              Serial.println("DHG_STA.TRW");
            Data = 'y';
            playFile1("DHG_IDL.TRW");
                              Serial.println("DHG_IDL.TRW");
        break;
       }
      case 'z':{  // Play Soundfile in loop : Stop

           playFile1("DHG_STO.TRW");
                              Serial.println("DHG_STO.TRW");
           Data = 'o';
      break;
      }   
      case 'e':{   // Play Soundfile only once : Horn 
           playFile1("DHG_HOR.TRW");
                              Serial.println("DHG_HOR.TRW");
           Data=PrevData; // Continue with previous soundfile
           Serial.println(Data);
      break;
           }
     case 'r':{  // Play Soundfile in loop : Full Speed
           PrevData = 'r';
           playFile1("DHG_SPE.TRW");
                              Serial.println("DHG_SPE.TRW");
     break;
    }   
     case 't':{  // Play Soundfile in loop : Brake 
           PrevData = 't';
           playFile1("DHG_BRA.TRW");
           Data = 'y';
           playFile1("DHG_IDL.TRW");
     break;
    } 
     case 'y':{  // Play Soundfile in loop : Idle
         PrevData = 'y';
         playFile1("DHG_IDL.TRW");
                             Serial.println("DHG_IDL.TRW");
     break;
    }
     case 'u':{  // Play Soundfile in loop : Uncoupling
         PrevData = 'u';
         playFile1("DHG_UNC.TRW");
                             Serial.println("DHG_UNC.TRW");
         Data = 'y';
         playFile1("DHG_IDL.TRW");
                              Serial.println("DHG_IDL.TRW");
     break;
    }
     case 'i':{  // Play Soundfile in loop : Uncoupling
         PrevData = 'i';
         playFile1("DHG_ACC.TRW");
                             Serial.println("DHG_UNC.TRW");
         Data = 'r';
         playFile1("DHG_IDL.TRW");
                              Serial.println("DHG_IDL.TRW");
     break;
    }
 }
}