Auteur Topic: Analoog rijden met geluid - het project.  (gelezen 73201 keer)

0 leden en 1 gast bekijken dit topic.

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #100 Gepost op: 15 oktober 2018, 22:52:17 »
Dank je, Mark.
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #101 Gepost op: 22 oktober 2018, 21:49:48 »
Geluid en lichtmodules: het overzicht

Het project loopt op zijn eind: tijd voor een overzicht. Ik heb nog wel een paar locs waar t.z.t. geluid in komt, maar die vallen dan onder de 'gewone' verbeteringen...
In dit bericht (en 2 volgende: het past niet in één) alle informatie bij elkaar: sketches, aansluitschema's en MP3 bestanden om te downloaden.

Ik ben nu 6 maanden na de eerste experimenten met geluid aan boord. Er zijn nu 11 geluidsmodules ingebouwd (waarvan 3 ook met schakelbare verlichting) en één lichtmodule (zonder geluid).




Op spoor 1 alle locs met ruisgenerator op basis van DigiSpark of ATtiny: BR91, BR70, BR64, BR78 en BR38.
Op spoor 2 alle locs en treinstel met MP3 speler (en Arduino, DigiSpark of ATtiny): BR57, V160, V100, BR50 en VT98
Achter het station de bagagewagon met meerdere geluiden (Arduino met MP3 speler) en de donderbussen met lichtmodule (ATtiny)


De pulsbreedte besturing

Een beschrijving, video en sketch staat in dit bericht:
http://www.h0modelspoor.nl/index.php?topic=3183.msg53480#msg53480


Ruisgenerator

De ruisgenerator sketch is nog wat aangepast. De nieuwste sketch is deze:

/*
 * RUISGENERATOR STOOMTREIN
 * Stoomtrein geluiden met rijstroom afhankelijk "puffen" van ruis. Voor analoog rijden met geluid.
 * Rijstroom met pulsbreedtebesturing is nodig: de pulsbreedte wordt omgerekend naar puf-snelheid.
 *
 * Eenvoudige extra geluidsfuncties:
 * 1: fluitje (lijkt meer op een telefoon) - uit voor sommige modellen
 * 2: sissen
 * 3: remmen
 * 4: stilte (vrijloop)
 * Functies werken redelijk bij langzaam rijden en goed bij stilstand en snel rijden
 *
 * versie 1.3 - 19 sep 2018
 */


// --- DEFINITIES ----

// kies de loc om te compileren: zet precies één definitie op 'true'
#define BR38 false
#define BR64 false                     // nieuwste versie nog niet geladen
#define BR70 false                     // @ ATtiny (van DigiSpark)
#define BR78 false                     
#define BR91 true                      // @ ATtiny (los). Bootloader branden met BOD op 4.3V en clock op 16 MHz                     

#define ruisPin       1                // pin voor aansturen van speaker: pin 1 of 0 (0 = 5 sec. vertraging)
#define rijPin1       2                // rijstroom meting
#define rijPin2       4                // rijstroom meting

//geluidsdefinities per type loc

#if BR38
  // definities voor slagen BR38. ("paa tsjie poe tsjoe...")
  #define Startfreq1  1000             // laagste frequentie ruis slag 1
  #define Eindfreq1   3000             // hoogste frequentie ruis slag 1
  #define Startfreq2  1240             // laagste frequentie ruis slag 2
  #define Eindfreq2   5400             // hoogste frequentie ruis slag 2
  #define Startfreq3   800             // laagste frequentie ruis slag 3
  #define Eindfreq3   2200             // hoogste frequentie ruis slag 3 
  #define Startfreq4   900             // laagste frequentie ruis slag 4
  #define Eindfreq4   4500             // hoogste frequentie ruis slag 4
  // berekening snelheid
  #define pulsbreedtestil   34         // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax    72         // pulsbreedte waar de maximum snelheid (pufritme) wordt bereikt 
  #define langstePuf       280         // langste puf (in ms) - langzaam rijden
  #define kortstePuf        56         // kortste puf (in ms) - topsnelheid (minimum ligt rond 50ms)
  // opstart geluid
  #define BeginSis        2150         // lengte van het sisgeluid bij starten (en korte stroomonderbrekingen)
#endif

#if BR64
  // definities voor slagen BR64. ("paa tsjie paa tsjoe...")
  #define Startfreq1  1000             // laagste frequentie ruis slag 1
  #define Eindfreq1   3000             // hoogste frequentie ruis slag 1
  #define Startfreq2  1300             // laagste frequentie ruis slag 2
  #define Eindfreq2   5500             // hoogste frequentie ruis slag 2
  #define Startfreq3  1000             // laagste frequentie ruis slag 3
  #define Eindfreq3   3000             // hoogste frequentie ruis slag 3 
  #define Startfreq4   940             // laagste frequentie ruis slag 4
  #define Eindfreq4   2500             // hoogste frequentie ruis slag 4
  // berekening snelheid
  #define pulsbreedtestil   32         // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax    56         // pulsbreedte waar de maximum snelheid (pufritme) wordt bereikt 
  #define langstePuf       190         // langste puf (in ms) - langzaam rijden
  #define kortstePuf        60         // kortste puf (in ms) - topsnelheid (minimum ligt rond 50ms)
  // opstart geluid
  #define BeginSis        3530         // lengte van het sisgeluid bij starten (en korte stroomonderbrekingen)
#endif

#if BR70
  // definities voor slagen BR70 ("tsjoe, tsjie, tsjoe, tsjie")
  #define Startfreq1  1700             // laagste frequentie ruis slag 1
  #define Eindfreq1   3900             // hoogste frequentie ruis slag 1
  #define Startfreq2  2000             // laagste frequentie ruis slag 2
  #define Eindfreq2   4100             // hoogste frequentie ruis slag 2
  #define Startfreq3  1720             // laagste frequentie ruis slag 3
  #define Eindfreq3   3930             // hoogste frequentie ruis slag 3 
  #define Startfreq4  1980             // laagste frequentie ruis slag 4
  #define Eindfreq4   4050             // hoogste frequentie ruis slag 4
  // berekening snelheid
  #define pulsbreedtestil   28         // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax    65         // pulsbreedte waar de maximum snelheid (pufritme) wordt bereikt 
  #define langstePuf       375         // langste puf (in ms) - langzaam rijden
  #define kortstePuf        50         // kortste puf (in ms) - topsnelheid (minimum ligt rond 50ms)
  // opstart geluid
  #define BeginSis        1150         // lengte van het sisgeluid bij starten (en korte stroomonderbrekingen)
#endif

#if BR78
  // definities voor slagen BR78. ("paa tsjoe paa tsjie...")
  #define Startfreq1  1000             // laagste frequentie ruis slag 1
  #define Eindfreq1   3000             // hoogste frequentie ruis slag 1
  #define Startfreq2   900             // laagste frequentie ruis slag 2 900
  #define Eindfreq2   4500             // hoogste frequentie ruis slag 2 2500
  #define Startfreq3  1000             // laagste frequentie ruis slag 3
  #define Eindfreq3   3000             // hoogste frequentie ruis slag 3 
  #define Startfreq4  1240             // laagste frequentie ruis slag 4
  #define Eindfreq4   5400             // hoogste frequentie ruis slag 4
  // berekening snelheid
  #define pulsbreedtestil   34         // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax    64         // pulsbreedte waar de maximum snelheid (pufritme) wordt bereikt 
  #define langstePuf       290         // langste puf (in ms) - langzaam rijden
  #define kortstePuf        58         // kortste puf (in ms) - topsnelheid (minimum ligt rond 50ms)
  // opstart geluid
  #define BeginSis        1800         // lengte van het sisgeluid bij starten (en korte stroomonderbrekingen)
#endif

#if BR91
  #define rijPin1        3             // rijstroom meting, afwijkende pin
  // definities voor slagen BR91: 1e hoog, laatste wat lager dan de 2 middelste slagen ("tsjie, tsja, tsja, tsjoe")
  #define Startfreq1  1500             // laagste frequentie ruis slag 1
  #define Eindfreq1   4850             // hoogste frequentie ruis slag 1
  #define Startfreq2  1800             // laagste frequentie ruis slag 2
  #define Eindfreq2   4000             // hoogste frequentie ruis slag 2
  #define Startfreq3  1800             // laagste frequentie ruis slag 3
  #define Eindfreq3   4000             // hoogste frequentie ruis slag 3 
  #define Startfreq4  1750             // laagste frequentie ruis slag 4
  #define Eindfreq4   3900             // hoogste frequentie ruis slag 4
  // berekening snelheid
  #define pulsbreedtestil   34         // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax    82         // pulsbreedte waar de maximum snelheid (pufritme) wordt bereikt 
  #define langstePuf       260         // langste puf (in ms) - langzaam rijden
  #define kortstePuf        60         // kortste puf (in ms) - topsnelheid (minimum ligt rond 50ms)
  // opstart geluid
  #define BeginSis        1750         // lengte van het sisgeluid bij starten (en korte stroomonderbrekingen)
#endif

// algemene geluidsdefinities
#define pauze                0.33      // factor puf/pauze (elke slag heeft voor een deel stilte)
//#define RemLaag           3200         // frequentiebereik voor remgeluid
//#define RemHoog           3800
#define RemLaag           3000         // frequentiebereik voor remgeluid
#define RemHoog           3600
#define SisLaag           3000         // frequentiebereik voor sisgeluid
#define SisHoog           5500

// definities voor de meting van de rijstroom
#define pullup               false     // geeft aan of de interne pullup weerstand gebruikt moet worden
#define maxpulsperiode       5000      // hoe lang wachten (minimaal 2x periode rijstroom PWM)

// Frequenties (Periodes) op de rijstroom
#define rijPeriode            2020     // rijstroom puls in us
#define functie_01_Periode    1500     // Periode (freq.) functie 1
#define functie_02_Periode    1250     // Periode (freq.) functie 2
#define functie_03_Periode     990     // Periode (freq.) functie 3
#define functie_04_Periode     790     // Periode (freq.) functie 4
#define functie_05_Periode     590     // Periode (freq.) functie 5 - niet gebruikt
#define functie_06_Periode     450     // Periode (freq.) functie 6 - niet gebruikt
#define pulsruis                80     // maximaal verschil in gemeten Periodes (ruis)
#define minhoog                100     // minimaal "hoog" signaal

// --- CONSTANTES ---

const float sqrtpbstil = 100*sqrt(10);
const float sqrtpbmax  = 100*sqrt(10+pulsbreedtemax-pulsbreedtestil);


// ---- VARIABLEN ----

// puf-geluid variabelen: 4 slagen (is tweezijdige tweecylinder loc)
unsigned int ruisStartFreq[] {Startfreq1, Startfreq2, Startfreq3, Startfreq4};  // hoogste frequentie puf-ruis per slag
unsigned int ruisEindFreq[]  {Eindfreq1,  Eindfreq2,  Eindfreq3,  Eindfreq4 };  // laagste frequentie puf-ruis per slag
int slag = 0;

// rijstroom variabelen
int rijpin[] {rijPin1, rijPin2};
int vooruit = 1;                      // richting: bepaalt welke pin wordt uitgelezen voor de rijstroom puls
double pulsbreedteHoog;
double pulsbreedteLaag;
double pulsPeriode;
float pulsbreedte = 0;                // pulsbreedte in %
int functie = 0;                      // speciale functie frequentie gemeten

unsigned int  puf;                    // lengte puf-slag (ms)
unsigned long pze;                    // pauze tot aan klok stand(ms)


// --- FUNCTIES ---

// Functie: maak puf geluid (één slag)
// Geeft ruis voor een deel van de opgegeven lengte en stil voor de resterende tijd (factor definitie)
// De ruisfrequentie neemt langzaam af om enigszins de volume afname te simuleren.
// input: lengte van de slag (in ms)
//        laagste frequentie van de ruis
//        hoogste frequentie van de ruis
// output: tijd tot einde pauze van de puf
unsigned long maakPuf(int lengte, unsigned int laag, unsigned int hoog) {
  unsigned int  freq;
  unsigned long mils;
  float factor = 1 - (0.09/lengte);
  mils = millis() + (1-pauze) * lengte;
  while (millis() < mils) {
    freq = random (laag, hoog);
    tone (ruisPin,freq);
    laag = laag*factor;
    hoog = hoog*factor;
  }
  noTone(ruisPin);
  return millis() + (lengte * pauze);                         // pauze tijd tussen de puffen
}

// Functie: Afspelen van ruis.
// Gebruikt voor sissen en remgeluid. Constant ruis-geluid gedurende de opgegeven lengte (in ms).
// input: lengte van de slag (in ms)
//        laagste frequentie van de ruis
//        hoogste frequentie van de ruis
void speelRuis(unsigned int lengte, unsigned int laag, unsigned int hoog) {
  unsigned int  freq;
  unsigned long mils;
  mils = millis() + lengte;
  while (millis() < mils) {
    freq = random (laag, hoog);   
    tone (ruisPin,freq);
  }
  noTone(ruisPin);
}

// Functie: Afspelen van een 'fluitje'
// Afwisselend een hoge en lage frequentie met een kleine frequentie variatie.
// input: lengte (in ms)
void speelFluitje(unsigned int lengte) {
  unsigned int  freq;
  unsigned long mils;

  mils = millis() + lengte;
  while (millis() < mils) {
    tone (ruisPin,random (2100,2120));
    delay (20);
    tone (ruisPin,random (2400,2430));
    delay (18);
  }
  noTone(ruisPin);
}

// MEET DE PULS OP DE RiJSTROOM
void meetPuls() {
  // puls meting variabelen: lengte 'hoog', 'laag' en trillingstijd (periode). Alle tijden in us.
  pulsbreedteHoog = pulseIn(rijpin[vooruit], HIGH, maxpulsperiode);
  pulsbreedteLaag = pulseIn(rijpin[vooruit], LOW, maxpulsperiode );
  pulsPeriode = pulsbreedteHoog + pulsbreedteLaag;
}

// HERKEN FUNCTIE-FREQUENTIE
// functie voor het checken van functie-frequenties
// op de puls (functietoets).
int getFunctie () {
  int f = 0;
 
  if (abs (pulsPeriode - functie_01_Periode) < pulsruis) { f = 1;}
  if (abs (pulsPeriode - functie_02_Periode) < pulsruis) { f = 2;}
  if (abs (pulsPeriode - functie_03_Periode) < pulsruis) { f = 3;}
  if (abs (pulsPeriode - functie_04_Periode) < pulsruis) { f = 4;}

  return f;
}

void setup() {
  pinMode     (ruisPin,OUTPUT);
 
  pinMode     (rijpin[0],INPUT);
  digitalWrite(rijpin[0],pullup);
  pinMode     (rijpin[1],INPUT);
  digitalWrite(rijpin[1],pullup);
  delay(100);                               // even wachten op opladen elco (stabiele voeding)

  speelRuis (BeginSis, SisLaag,SisHoog);    // sissen bij opstarten
}

void loop() {
  // Pulsbreedte bepalen
  vooruit = !vooruit;                       // wissel de pin waarop de rijstroom wordt gemeten
  do {
    vooruit = !vooruit;                     // wissel de pin waarop de rijstroom wordt gemeten
    meetPuls(); 
  } while (pulsbreedteHoog < minhoog || pulsbreedteLaag < pulsruis); // 'hoog' signaal alleen op actieve rijpin 
  pulsbreedte = 100 * pulsbreedteHoog / pulsPeriode;
  functie = getFunctie();
 
  // speciale geluidsfunctie gevonden
  if (functie) {
    // als speciale functie is gevonden, controleer de functie frequentie nogmaals.
    // Hiermee wordt onterecht meten voorkomen (door bijvoorbeeld storing op de stroomopname).
    delay (5);                                         // korte pauze tussen de metingen
    meetPuls();
    if (functie == getFunctie()) {                     // nog steeds dezelfde funtie op de rijstrrom
      switch (functie) {                               // speel functie 1, 2, 3 of 4.
#if BR70
        case 1:
          speelFluitje(1800);                          // fluitje afspelen, 1,8 sec.
        break;
#endif
        case 2:
          speelRuis (3000, SisLaag,SisHoog);           // sissen, 3 sec.
        break;
         case 3:
          speelRuis (3600, RemLaag,RemHoog);           // remgeluid 3,6 sec.
        break;
         case 4:
          pze = millis()+ 4500;                        // 4,5 sec. stilte = vrijloop
        break;
      }
    }
  }
  else {                                               // geen speciale functie, dan rij-geluid
    // rijgeluid
    // tweecylinder = 4 puf slagen met verschil in de slagen (volgens definities van de loc)
    if (pulsbreedte > pulsbreedtestil && millis() > pze) {                   // lok rijdt en er is nu geen puf-pauze of vrijloop
      // puf slag berekenen
      if (pulsbreedte > pulsbreedtemax) {
        pulsbreedte = pulsbreedtemax;
      }
      puf = map(100 * sqrt (10+pulsbreedte-pulsbreedtestil), sqrtpbstil, sqrtpbmax, langstePuf, kortstePuf);  // reken pulssbreedte % om naar puf-tijd
      pze = maakPuf(puf, ruisStartFreq [slag], ruisEindFreq [slag]);         // maak puf-ruis. Functie geeft resterende pauze-tijd terug
      // volgende puf-slag (volgnummer 0-3)
      if (slag < 3) {
        slag++;
      }
      else {
        slag = 0;
      }
    }
  }                                                     // einde functie spelen / rijgeluid
}                                                       // einde hoofd-lus

Deze sketch werkt zowel voor de DigiSpark en als voor de ATtiny. Per loc definitie wordt aangegeven of er ee DigiSpark of ATtiny is ingebouwd: bij het compileren van de sketch worden dan de juiste instellingen gebruikt.


Dit is zijn de algemene aansluitschema's, al kunnen de gebruikte pinnen per loc anders zijn.





(de rest in volgend bericht)
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #102 Gepost op: 22 oktober 2018, 22:06:49 »
Geluidsmodules met MP3 speler

De sketch. Deze is bruikbaar voor Arduino, DigiSpark en ATtiny. Ook hier wordt per loc met de juiste instellingen gecompileerd. Dat maakt de sketch ingewikkelder, maar het is (was) eenvoudiger om één programma te hebben zodat wijzigingen in de software maar één keer hoeven te worden gedaan.

/* GELUIDSMODULE
 * Rijstroom afhankelijk geluid voor analoge modeltreinen.
 * Module vereist rijstroom met pulsbreedte modulatie en heeft dan de volgende functies:
 *    - Startgeluid (starten van een motor, bijvoorbeeld
 *    - Stationair geluid
 *    - Rijstroom afhankelijke geluiden tijdens het rijden
 *    - Tot 6 geluidsfuncties, te bedienen met frequentie-veranderingen op de rijstroom
 *    - 1 lichtschakel functie (op één van de 6 functies)
 * Per loc of treinstel worden de pinnen, snelheid en geluiden gedefinieerd.
 * De geluiden staan per set (loc) in in map op de de geheugenkaart, d.w.z.
 *    - voor één loc is alleen map "01" op de geheugenkaart van de MP3 speler beschikbaar.
 *    - voor een geluidswagon worden mappen "01" t/m "06" gebruikt: één set per loc.
*/
#define versie "2.0, 7 Oktober 2018 - Rob van Deursen"
// ----- ALGEMENE DEFINITIES -----

// ----- definities voor het compileren -----
// definieer voor welke geluidsmodule wordt gecompileerd (zet deze op "true"), selecteer 1 module.
// voor DigiSpark: zet in IDE "board" op "Digispark (default 16.5 MHz)" by compileren / uploaden.
#define BR24                false        // BR24 @ Digispark
#define BR50                false        // BR50 @ Arduino
#define BR57                false        // BR57 @ ATtiny (gebruikt bibliotheken voor Arduino) - BOD op 2.7v
#define BR78                false        // BR78 @ Digispark
#define V100                false        // V100 @ Arduino
#define V160                false        // V160 @ DigiSpark
#define VT98                true         // VT98 @ Arduino (railbus)
#define geluidswagon        false        // Tot 6 locs. Nu 5 locs: BR70, BR38, BR24, V60 en V160 @ Arduino

// probleemoplosser zet informatie op de seriele bus (seriele monitor). Zet deze aan bij het oplossen van problemen
#define probleemoplosser    false      // diverse status info naar seriele monitor j/n (werkt niet voor DigiSpark)

// ----- algemene MP3 en functietoets indeling ------
// geluidsbestanden 001.mp3 t/m 006.mp3: speciale geluidsfuncties
//                  009.mp3:             startgeluid
//                  010.mp3:             stationair
//                  011.mp3 en hoger:    rijgeluiden (opvolgende snelheden)
#define startgeluid              9       // 009.mp3
#define stationair              10       // 010.mp3
                                         // rijden vanaf bestand 011.mp3 en hoger (opvolgend na stationair)
#define geluidsfunctie1          1       // 001.mp3 fluit of hoorn
#define geluidsfunctie2          2       // 002.mp3 bel (of korte fluit/hoorn)
#define geluidsfunctie3          3       // 003.mp3 rem of vrijloop (afhankelijk van loc of treinstel)
#define geluidsfunctie4          4       // 004.mp3 stoom afblazen of motor uitzetten
//      geluidsfuncties 5 en 6:             gedefinieerd per geluidsmodule

// EEPROM geheugenlocaties
#define licht1adr                0
#define licht2adr                1
#define geluidadr                2                   

// ----- DEFINITIES PER GELUIDSMODULE -----

// === BR24 @ DigiSpark ===
#if BR24
  #define DigiSpark           true
// ----- pin definities ------
                                         // pin 3 op DigiSpark niet gebruiken: heeft 1k5 pullup naar 5V en USB
  #define rijPin1                1       // digitale pin voor PWM rijspanning richting 1 met LED
  #define rijPin2                4       // digitale pin voor PWM rijspanning richting 2

  #define MP3RX                  2       // serieel receive (van MP3 speler)
  #define MP3TX                  0       // serieel transmit (naar MP3 speler)
  //#define lichtPin               -        geen lichtfunctie DigiSpark

// ----- rijstroom en geluid/licht instellingen -----
  #define aantalSnelheden        5       // aantal snelheidsstappen loc
  #define pulsbreedtestil       26       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax        56       // pulsbreedte waarbij de maximum snelheid wordt bereikt 

  #define geluidsfunctie5        5       // 005.mp3, waterpomp
  #define geluidsfunctie6        6       // 006.mp3, kolen scheppen
  #define lichtfunctie           0       // geen lichtfunctie
  #define lichtsterkte           0       // lichtsterkte (0-255)

  //MP3 speler (DFplayer)
  #define volume                28       // geluidsvolume (0-47)
  #define equalizer              0       // equaliser 0-5: normal, pop, rock, jazz, classic, base
  #define MP3monster             0       // bemonster intervaltijd MP3 speler (ms) (0 = geen)
  #define geluid                 1       // geluid altijd aan in map "01"
#endif

// === BR50 @ Arduino ===
#if BR50
  #define Arduino             true
// ----- pin definities ------
  #define rijPin1                3       // digitale pin voor PWM rijspanning richting 1
  #define rijPin2                5       // digitale pin voor PWM rijspanning richting 2

  #define MP3RX                  7       // serieel receive (van MP3 speler)
  #define MP3TX                  6       // serieel transmit (naar MP3 speler)
  #define lichtPin              11       //

// ----- rijstroom en geluid/licht instellingen -----
  #define aantalSnelheden        8       // aantal snelheidsstappen loc
  #define pulsbreedtestil       26       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax        66       // pulsbreedte waarbij de maximum snelheid wordt bereikt 

  #define geluidsfunctie5        5       // 005.mp3, korte fluit
  #define geluidsfunctie6        6       // 006.mp3, kolen scheppen
  #define lichtfunctie           0       // geen lichtfunctie
  #define lichtsterkte           0       // lichtsterkte (0-255)

  //MP3 speler (DFplayer)
  #define volume                28       // geluidsvolume (0-47)
  #define equalizer              5       // equaliser 0-5: normal, pop, rock, jazz, classic, base
  #define MP3monster          3000       // bemonster intervaltijd MP3 speler (ms) (0 = geen)
  #define geluid                 1       // geluid altijd aan in map "01" van MP3 speler.
  #define MP3inittijd         1500       // initialisatietijd MP3 speler (ms)
#endif

// === BR57 @ ATtiny ===
#if BR57
  #define ATtiny             true
// ----- pin definities ------
  #define rijPin1                1       // digitale pin voor PWM rijspanning richting 1
  #define rijPin2                2       // digitale pin voor PWM rijspanning richting 2

  #define MP3RX                  4       // serieel receive (van MP3 speler)
  #define MP3TX                  3       // serieel transmit (naar MP3 speler)
  #define lichtPin               0       //

// ----- rijstroom en geluid/licht instellingen -----
  #define aantalSnelheden        7       // aantal snelheidsstappen loc
  #define pulsbreedtestil       22       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax        76       // pulsbreedte waarbij de maximum snelheid wordt bereikt 

  #define geluidsfunctie5        5       // 005.mp3, korte fluit
  #define geluidsfunctie6        6       // 006.mp3, Veiligheidsventiel
  #define lichtfunctie           0       // geen lichtfunctie
  #define lichtsterkte           0       // lichtsterkte (0-255)

  //MP3 speler (DFplayer)
  #define volume                23       // geluidsvolume (0-47)
  #define equalizer              5       // equaliser 0-5: normal, pop, rock, jazz, classic, base
  #define MP3monster          3000       // bemonster intervaltijd MP3 speler (ms) (0 = geen)
  #define geluid                 1       // geluid altijd aan in map "01" van MP3 speler.
#endif

// === BR78 @ DigiSpark ===
#if BR78
  #define DigiSpark           true
// ----- pin definities ------
                                         // pin 3 op DigiSpark niet gebruiken: heeft 1k5 pullup naar 5V en USB
  #define rijPin1                1       // digitale pin voor PWM rijspanning richting 1 met LED
  #define rijPin2                4       // digitale pin voor PWM rijspanning richting 2

  #define MP3RX                  2       // serieel receive (van MP3 speler)
  #define MP3TX                  0       // serieel transmit (naar MP3 speler)
  //#define lichtPin               -        geen lichtfunctie DigiSpark

// ----- rijstroom en geluid/licht instellingen -----
  #define aantalSnelheden        8       // aantal snelheidsstappen loc
  #define pulsbreedtestil       30       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax        70       // pulsbreedte waarbij de maximum snelheid wordt bereikt 

  #define geluidsfunctie5        5       // 005.mp3, korte fluit
  #define geluidsfunctie6        6       // 006.mp3, kolen scheppen
  #define lichtfunctie           0       // geen lichtfunctie
  #define lichtsterkte           0       // lichtsterkte (0-255)

  //MP3 speler (DFplayer)
  #define volume                25       // geluidsvolume (0-47)
  #define equalizer              0       // equaliser 0-5: normal, pop, rock, jazz, classic, base
  #define MP3monster             0       // bemonster intervaltijd MP3 speler (ms) (0 = geen)
  #define geluid                 1       // geluid altijd aan in map "01"
#endif

// === V100 @ Arduino ===
#if V100
  #define Arduino             true
// ----- pin definities ------
  #define rijPin1                6       // digitale pin voor PWM rijspanning richting 1
  #define rijPin2                7       // digitale pin voor PWM rijspanning richting 2

  #define MP3RX                  9       // serieel receive (van MP3 speler)
  #define MP3TX                  8       // serieel transmit (naar MP3 speler)
  #define lichtPin              11       // licht

// ----- rijstroom en geluid/licht instellingen -----
  #define aantalSnelheden        1       // aantal snelheidsstappen loc
  #define pulsbreedtestil       33       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax        40       // pulsbreedte waarbij de maximum snelheid wordt bereikt 

  #define geluidsfunctie5        0       // 0 = geen geluidsfunctie
  #define geluidsfunctie6        6       // 006.wav
  #define lichtfunctie           5       // lichtfunctie op 5 (kabineverlichting aan/uit)
  #define lichtsterkte         200       // lichtsterkte (0-255)

  //MP3 speler (DFplayer)
  #define volume                22       // geluidsvolume (0-47)
  #define equalizer              0       // equaliser 0-5: normal, pop, rock, jazz, classic, base
  #define MP3monster             0       // bemonster intervaltijd MP3 speler (ms) (0 = geen)
  #define geluid                 1       // geluid altijd aan in map "01"
#endif
// === V160 @ DigiSpark ===
#if V160
  #define DigiSpark           true
// ----- pin definities ------
  #define rijPin1                1       // digitale pin voor PWM rijspanning richting 1 met LED
  #define rijPin2                4       // digitale pin voor PWM rijspanning richting 2

  #define MP3RX                  2       // serieel receive (van MP3 speler)
  #define MP3TX                  0       // serieel transmit (naar MP3 speler)
  //#define lichtPin               -        geen lichtfunctie DigiSpark

// ----- rijstroom en geluid/licht instellingen -----
  #define aantalSnelheden        3       // aantal snelheidsstappen loc
  #define pulsbreedtestil       19       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax        61       // pulsbreedte waarbij de maximum snelheid wordt bereikt 

  #define geluidsfunctie5        5       // 005.mp3
  #define geluidsfunctie6        6       // 006.mp3
  #define lichtfunctie           0       // geen lichtfunctie
  #define lichtsterkte           0       // lichtsterkte (0-255)

  //MP3 speler (DFplayer)
  #define volume                32       // geluidsvolume (0-47)
  #define equalizer              1       // equaliser 0-5: normal, pop, rock, jazz, classic, base
  #define MP3monster             0       // bemonster intervaltijd MP3 speler (ms) (0 = geen)
  #define geluid                 1       // geluid altijd aan in map "01"
#endif

// === VT98 (RAILBUS) @ Arduino ===
#if VT98
  #define Arduino             true
// ----- pin definities ------
  #define rijPin1                6       // digitale pin voor PWM rijspanning richting 1 met LED
  #define rijPin2                7       // digitale pin voor PWM rijspanning richting 2

  #define MP3RX                  9       // serieel receive (van MP3 speler)
  #define MP3TX                  8       // serieel transmit (naar MP3 speler)
  #define lichtPin              11       // licht

// ----- rijstroom en geluid/licht instellingen -----
  #define aantalSnelheden        3       // aantal snelheidsstappen loc
  #define pulsbreedtestil       26       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax        72       // pulsbreedte waarbij de maximum snelheid wordt bereikt 

  #define geluidsfunctie5        5       //
  #define geluidsfunctie6        0       // geen geluid (alleen lichtfunctie)
  #define lichtfunctie           6       // lichtfunctie op 6
  #define lichtsterkte         255       // lichtsterkte (0-255)

  //MP3 speler (DFplayer)
  #define volume                24       // geluidsvolume (0-47)
  #define equalizer              5       // equaliser 0-5: normal, pop, rock, jazz, classic, base
  #define MP3monster             0       // bemonster intervaltijd MP3 speler (ms) (0 = geen)
  #define geluid                 1       // geluid altijd aan in map "01"
#endif

// === GELUIDSWAGON (tot maximaal 6 geluiden sets) @ Arduino  ===
// geluidswagon werkt als volgt:
// Met functie 1 t/m 6 wordt de geluids-set aan gezet. Voor elke loc of treinstel is er een set (map) op de MP3 speler.
// Geluid kan worden uitgezet met functie nummer gedefinieerd met selecteerGeluidUit (standaard is dit functie 4),
// Om een andere loc te kiezen: zet het geluid uit, en druk vervolgens 1 seconde op de functietoets van de nieuwe loc.
// Zodra deze aan is, begint het startgeluid van de loc. Daarna werkt het rijgeluid en de geluidsfuncties.
// Let op: serieel TX/RX anders dan bij andere Arduino modules

#if geluidswagon   
  #define uitgebreidLicht        true    // meerdere lichtfuncties
  #define Arduino                true
// ----- pin definities ------
  #define rijPin1                6       // digitale pin voor PWM rijspanning richting 1
  #define rijPin2                7       // digitale pin voor PWM rijspanning richting 2

  #define MP3RX                  8       // serieel receive (van MP3 speler)
  #define MP3TX                  9       // serieel transmit (naar MP3 speler)
  #define lichtPin              10       // (PWM) pin voor licht (sluitlichten)
  #define lichtPin2             11       // (PWM) pin voor licht (binnenverlichting)


// ----- rijstroom en geluid/licht instellingen -----
  // loc 01: BR70
  #define aantalSnelhedenLoc01   8       // aantal snelheidsstappen loc
  #define pulsbreedtestil01     26       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax01      64       // pulsbreedte waarbij de maximum snelheid wordt bereikt 
  // loc 02: BR38
  #define aantalSnelhedenLoc02   8       // aantal snelheidsstappen loc
  #define pulsbreedtestil02     30       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax02      72       // pulsbreedte waarbij de maximum snelheid wordt bereikt 
  // loc 03: BR24
  #define aantalSnelhedenLoc03   5       // aantal snelheidsstappen loc
  #define pulsbreedtestil03     26       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax03      56       // pulsbreedte waarbij de maximum snelheid wordt bereikt 
  // loc 04: V60
  #define aantalSnelhedenLoc04   2       // aantal snelheidsstappen loc
  #define pulsbreedtestil04     25       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax04      45       // pulsbreedte waarbij de maximum snelheid wordt bereikt 
  // loc 05: V160
  #define aantalSnelhedenLoc05   3       // aantal snelheidsstappen loc
  #define pulsbreedtestil05     26       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax05      56       // pulsbreedte waarbij de maximum snelheid wordt bereikt 
  // loc 06
  #define aantalSnelhedenLoc06   0       // aantal snelheidsstappen loc
  #define pulsbreedtestil06     22       // pulsbreedte in % waaronder loc stil staat
  #define pulsbreedtemax06      72       // pulsbreedte waarbij de maximum snelheid wordt bereikt 
  // gezamenlijke definities
  #define geluidsfunctie5        0       // (0 = geen functie)
  #define geluidsfunctie6        0       // (0 = geen functie)
  #define selecteerGeluidUit     4       // selecteer geluid uit met deze functie (geluid gaat weer aan met toets 1 t/m 6 per loc)
  #define lichtfunctie           5       // functie 5 is sluitlicht aan/uit
  #define lichtsterkte          20       // lichtsterkte (0-255)
  #define lichtfunctie2          6       // functie 6 is binnenverlichting aan/uit
  #define lichtsterkte2         50       // lichtsterkte (0-255)
  // MP3 speler (DFplayer)
  #define volume                18       // geluidsvolume (0-47)
  #define equalizer              1       // equaliser 0-5: normal, pop, rock, jazz, classic, base
  #define MP3monster             0       // bemonster intervaltijd MP3 speler (ms) (0 = geen)
#endif

// Frequenties (Periodes) op de rijstroom
#define rijPeriode            2020       // rijstroom puls in us
#if ATtiny
  #define functie_01_Periode  1350       // Periode (freq.) functie 1
  #define functie_02_Periode  1190       // Periode (freq.) functie 2
#else
  #define functie_01_Periode  1500       // Periode (freq.) functie 1
  #define functie_02_Periode  1250       // Periode (freq.) functie 2
#endif
#define functie_03_Periode     990       // Periode (freq.) functie 3
#define functie_04_Periode     790       // Periode (freq.) functie 4
#define functie_05_Periode     590       // Periode (freq.) functie 5
#define functie_06_Periode     450       // Periode (freq.) functie 6

// ----- ALGEMENE DEFINITIES -----

// technische definities MP3 speler
#define Start_Byte            0x7E
#define Version_Byte          0xFF
#define Command_Length        0x06
#define End_Byte              0xEF
#define Acknowledge           0x00

// Definities voor de elektronica
#define pullup               false       // geeft aan of de interne pullup weerstand gebruikt moet worden
#define maxpulsperiode        5000       // hoe lang wachten (minimaal 2x periode rijstroom PWM)
#if !MP3inittijd
  #define MP3inittijd         1000       // initialisatietijd MP3 speler (ms)
#endif
#if DigiSpark
  #define pulsruis              80       // maximaal verschil in gemeten Periodes (ruis)
  #define minhoog               90       // minimaal "hoog" signaal
#else
  #define pulsruis              70
  #define minhoog              100       // minimaal "hoog" signaal
#endif

// ---- libraries en objecten ----
  // kies juist serial bibliotheek voor Arduino c.q. Digispark
#if (DigiSpark)                          // DigiSpark definities
  #include <SoftSerial.h>                // SoftSerial en TinyPinChange voor DigiSpark               
  #include <TinyPinChange.h>
  SoftSerial MP3Serial(MP3RX, MP3TX);    // RX, TX
#else                                    // Arduino definities (ook voor ATTiny)
  #include <EEPROM.h>                    // EEPROM om licht aan/uit en geluid aan/uit te onthouden
  #include <SoftwareSerial.h>            // SoftwareSerial voor mp3 op Arduino
  SoftwareSerial MP3Serial(MP3RX, MP3TX);      // RX, TX
#endif


// --- CONSTANTES EN VARIABELEN---

// ----- voor alle configuraties -----
// rijstroom variabelen
int rijpin[] {rijPin1, rijPin2};
int vooruit = 1;                          // richting: bepaalt welke pin wordt uitgelezen voor de rijstroom puls
double pulsbreedteHoog;
double pulsbreedteLaag;
double pulsPeriode;
float pulsbreedte = 0;                    // pulsbreedte in %
int snelheid = 0;
int vorigeSnelheid = 0;
const float sqrtpbstil = 100*sqrt(10);    // basiswaarde omrekenen pulsbreedte naar snelheid

// variabelen voor speciale functies op de rijstroom
int functie = 0;                          // speciale functie frequentie gemeten
int lopendeFunctie = 0;                   // > 0 : er wordt een speciale functie uitgevoerd
int licht;                                // licht sterkte of uit (0);
int licht2;                               // licht sterkte of uit (0);
 
// variabelen voor de MP3 speler
int MP3speler;                            // geeft MP3 status aan (van MP3Status functie) 0=geen info, 1=klaar, 2=speelt, 4=fout
long unsigned int MP3count = 0;           // millis waarde om status MP3 speler op te vragen
int geluidsfunctie []  {geluidsfunctie1, geluidsfunctie2, geluidsfunctie3, geluidsfunctie4, geluidsfunctie5, geluidsfunctie6}; 


// ----- configuratie afhankelijk -----

// voor de geluidswagon zijn definities als array variabelen opgenomen, omdat deze per geluid set (loc) verschillend zijn.
// geluidsmodules voor een enkele loc of treinstel hebben deze waarden als een enkele, vaste definitie.
#if geluidswagon                          // geluidswagon tot 6 verschillende geluiden, andere slechts 1
  int aantalSnelheden[] {aantalSnelhedenLoc01, aantalSnelhedenLoc02, aantalSnelhedenLoc03, aantalSnelhedenLoc04,aantalSnelhedenLoc05, aantalSnelhedenLoc06};
  int pulsbreedtestil[] {pulsbreedtestil01, pulsbreedtestil02, pulsbreedtestil03, pulsbreedtestil04, pulsbreedtestil05, pulsbreedtestil06};
  int pulsbreedtemax[]  {pulsbreedtemax01,  pulsbreedtemax02,  pulsbreedtemax03,  pulsbreedtemax04,  pulsbreedtemax05,  pulsbreedtemax06 };
  int geluidAanteller = 0;                // teller om geluid aan te zetten (tijd tussen2x dezelfde functietoets indrukken)
  int geluid = 0;                         // geluid volgnummer (0 = uit)
  float sqrtpbmax[] {                     // maximale pulsbreedte omgerekend
    100*sqrt(10+pulsbreedtemax01 - pulsbreedtestil01),
    100*sqrt(10+pulsbreedtemax02 - pulsbreedtestil02),
    100*sqrt(10+pulsbreedtemax03 - pulsbreedtestil03),
    100*sqrt(10+pulsbreedtemax04 - pulsbreedtestil04),
    100*sqrt(10+pulsbreedtemax05 - pulsbreedtestil05),
    100*sqrt(10+pulsbreedtemax06 - pulsbreedtestil06),
  };
#else
  const float sqrtpbmax  = 100*sqrt(10+pulsbreedtemax - pulsbreedtestil);    // maximale pulsbreedte omgerekend
#endif


// --- FUNCTIES ---

// RIJSTROOM PULSMETING
// Meet de rijstroom op een van de pinnen en geeft vult de gemeten pulswaarden in.
void meetPuls() {
  // puls meting variabelen: lengte 'hoog', 'laag' en trillingstijd (periode). Alle tijden in us.
  pulsbreedteHoog = pulseIn(rijpin[vooruit], HIGH, maxpulsperiode);
  pulsbreedteLaag = pulseIn(rijpin[vooruit], LOW, maxpulsperiode );
  pulsPeriode = pulsbreedteHoog + pulsbreedteLaag;
}
// ===

// HERKEN FUNCTIE-FREQUENTIE
// functie voor het checken van functie-frequenties
// op de puls (functietoets).
int getFunctie () {
  int f = 0;
  if (abs (pulsPeriode - functie_01_Periode) < pulsruis) { f = 1;}
  if (abs (pulsPeriode - functie_02_Periode) < pulsruis) { f = 2;}
  if (abs (pulsPeriode - functie_03_Periode) < pulsruis) { f = 3;}
  if (abs (pulsPeriode - functie_04_Periode) < pulsruis) { f = 4;}
  if (abs (pulsPeriode - functie_05_Periode) < pulsruis) { f = 5;}
  if (abs (pulsPeriode - functie_06_Periode) < pulsruis) { f = 6;}
  return f;
}
//===

// START SPECIALE FUNCTIE
// Bekijkt of er een geluidsdefinitie is voor de opgegeven functie en start deze.
// Geeft terug of de geluidsfunctie gestart is (en moet blijven lopen).
// input:  functie nummer (1-6)
// output: functie nummer (als gestart), anders 0
int startFunctie(int f) {
  int lopen = 0;                   // volgende functie wacht op aflopen MP3 geluid
  //geluid afspelen?
  if (geluidsfunctie [f-1] > 0){   // geluid is gedefinieerd (0 = geen geluid)
    speelGeluid(geluid, geluidsfunctie [f-1]);
    lopen = f;                     // als er geluid is zet lopende functie
    delay (100);
   }
  return lopen;                    // 0 = niet wachten, > 0 is wachten op einde geluid 
}
//===


#if geluidswagon
// GELUID AAN of UIT ZETTEN
// alleen voor geluidswagon
// zet geluids volgnummer variable en slaat deze op.
// geluid 0 = geen geluid, 1-6 is volgnummer van map op MP3 speler
// input:  functie nummer.

bool geluidAanUit(int fun) {
  bool aanUit = false;
  if (geluid) {                                   // geluid staat al aan
    if (fun == selecteerGeluidUit) {              // functie: geluid uit
      speelGeluid (geluid, selecteerGeluidUit);   // speel afzet-geluid af
      geluid = 0;                                 // geluid gaat straks uit
      EEPROM.write(geluidadr,geluid);                     // onthou dat geluid uit is op EEPROM geheugen
      delay (2000);                               // geluid laten afspelen
      aanUit=true;                       
    } 
  }
  else {                                          // geluid is uit
    geluid = fun;
    if (geluid && aantalSnelheden[geluid-1] > 0) {    // er is een definitie voor deze loc (volgnummer)
      if (lopendeFunctie == geluid ) {            // starten als 2x dezelfde functie is gedetecteerd
        EEPROM.write(geluidadr,geluid);                   // zet gewenste loc aan
        speelGeluid (geluid, startgeluid);        // speel startgeluid af
        delay (1000);                             // even wachten
        aanUit=true;                             
      }
      else {                                      // deze functie 1e keer
        lopendeFunctie = geluid;                  // onthou deze functie
        geluid = 0;
        geluidAanteller = 50;
        delay (1000);                             // functietoets 1 seconde indrukken om geluid te starten
      }
    } else {
      geluid = 0;                                 // geen geluid of definitie
      if (geluidAanteller > 0) {
        geluidAanteller--;
      }
    }
  }
  return aanUit;
}
#endif


// GELUID AFSPELEN
// stuurt commando 'afspelen geluidsbestand' naar de MP3 speler
// input: - nummer van de map op SD kaart (0 = geen geluid)
//        - nummer van MP3 bestand
void speelGeluid(int mapnummer, int bestandnummer) {
  if (mapnummer) {                        // geluid staat aan (map > 0 )
    execute_CMD(0x0F, mapnummer, bestandnummer);
    delay(200);
#if probleemoplosser
    Serial.print("Geluidsbestand gestart: ");
    Serial.println(bestandnummer);
#endif
  }
}
//===

// START MP3 SPELER
// functie start de MP3 speler. Geeft eventueel eerst een reset.
// input:  reset y/n
void startMP3(boolean rst) {
#if probleemoplosser
  Serial.println("MP3 speler initialisatie");
#endif
  if (rst) {
    execute_CMD(0x0C, 0, 0);          // stuur reset commando
    delay (200);
  }
  execute_CMD(0x3F, 0, 0);            // initialiseer MP3 speler
  delay (MP3inittijd);                // wacht tot initialisatie klaar is
  execute_CMD(0x06, 0, volume);       // zet het geluidsvolumevolume
  delay (80);
  execute_CMD(0x07, 0, equalizer);    // equalizer
  delay (80);
}
//===


// STATUS VAN MP3 SPELER LEZEN
// output: 0 = geen info
//         1 = mp3 klaar (speelt niet)
//         2 = mp3 speelt
//         3 = fout
//         4 = onbekend
int MP3status () {
  int m = 4;                       // standaard: onbekend
  int t = 0;
  byte b;
  int bstat;                       // status byte
  int btrack;                      // bestand nummer
#if MP3monster
  if (  !MP3Serial.available() ) {        // nog niets ontvangen 
    if (MP3count < millis() ) {
       execute_CMD (0x42,0,0);            // query huidig bestand dat wordt afgespeeld
       MP3count = millis() + MP3monster;  // volgende MP3 'monster' tijdstip zetten
       delay (20);
     }
   }
#endif

  if (MP3Serial.available() > 9) {        // er is een bericht op de seriele bus
    while(MP3Serial.available()) {        // serieel uitlezen
      t++;
      b = MP3Serial.read();
      if (t == 4) {                       // dit is de status byte
        bstat = b;
      }
      if (t == 7) {                       // dit is het bestandsnummer
        btrack = b;
      }
      if (t == 10){                       // meer dan 1 bericht
        t=0;
      }
#if probleemoplosser
      Serial.print(b,HEX);
      Serial.print(".");
#endif
    }
#if MP3monster
    MP3count = millis() + MP3monster;     //  volgende MP3 'monster'
#endif
    switch (bstat) {
      case 0x3F:                    // initialisatie parameters ontvangen
        m = 1;                      // speler is klaar
      break;
      case 0x3D:                    // eind van een bestand
        m = 1;                      // speler is klaar
      break;
     
#if MP3monster
      case 0x42:                    // antwoord op status (monster)
        if (btrack > 0) {
          m = 2;                    // bestand speelt
        } else {
          m = 1;                    // er speelt geen bestand, speler is kaar
        }   
      break;
 #endif
 
      case 0x40:                    // fout in transmissie
        m = 3;                      // fout
      break;
    }
#if probleemoplosser
    Serial.print("|| MP3 antwoordbyte: ");
    Serial.print(bstat,HEX);
    Serial.print(" - Bestand#: ");
    Serial.print(btrack);
    Serial.print(", status: ");
    Serial.println(m);
#endif
  }
  return m;
}
//===

// SERIËLE COMMANDOS VERSTUREN
// Commando's naar MP3 speler versturen
void execute_CMD(byte CMD, byte Par1, byte Par2) // Excecute the command and parameters
{
  // Bereken checksum (2 bytes)
  int16_t checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);

  // Bouw het commando op
  byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge, Par1, Par2, checksum >> 8, checksum & 0xFF, End_Byte};

  // Verstuur commando naar MP3 speler
  for (byte k=0; k<10; k++)
  {
    MP3Serial.write( Command_line[k]);
  }
}
//===

// ----- HOOFDPROGRAMMA -----

// ----- initialisatie -----
void setup() {
  // versie en configuratie op seriele poort (monitor), alleen voor Arduino
#if Arduino
  Serial.begin(9600);
  Serial.print("GELUIDSMODULE versie "); Serial.println(versie);
  Serial.print("Pin configuratie: rijstroom op digitale pin ");
  Serial.print(rijpin[0]); Serial.print(" en "); Serial.print(rijpin[1]);
  Serial.print(", serieel tx/rx op pin ");
  Serial.print(MP3TX); Serial.print(" en "); Serial.println(MP3RX);
  Serial.print("MP3 instellingen: volume = ");
  Serial.print(volume); Serial.print(", equalizer = "); Serial.println(equalizer);
  Serial.print("MP3 inittijd (ms): "); Serial.print(MP3inittijd); Serial.print(", ");
  Serial.print("MP3 bemonstering (ms): "); Serial.println(MP3monster);
  Serial.println("-- einde configuratie info --");
  // lichtfunctie alleen voor Arduino, niet voor DigiSpark
  licht  = EEPROM.read(licht1adr);           // laatste licht waarde uit EEPROM
  pinMode     (lichtPin,OUTPUT);
  analogWrite (lichtPin,licht);              // licht aan of uit: waarde uit EEPROM
#endif

#if uitgebreidLicht                          // 2e lichtfunctie geïnstalleerd
  licht2 = EEPROM.read(licht2adr);           // laatste licht waarde uit EEPROM
  pinMode     (lichtPin2,OUTPUT);
  analogWrite (lichtPin2,licht2);            // licht aan of uit: waarde uit EEPROM
#endif

  // Alleen voor geluidswagon kan geluid worden aan en uitgezet.
#if geluidswagon
  geluid = constrain (EEPROM.read(geluidadr), 0, 6);          // laatste geluid waarde uit EEPROM (0 = geen geluid)
  if (geluid && aantalSnelheden [geluid - 1] == 0) {  // geen juiste waarde (bijvoorbeeld eerste opstart)
    geluid = 1;                             // zet bij ongeldige waarde het geluid volgnummer op "1".
    EEPROM.write (geluidadr,1);
  }
#endif


  // intialiseren pinnen en MP3speler
  pinMode     (rijpin[0],INPUT);
  digitalWrite(rijpin[0],pullup);
  pinMode     (rijpin[1],INPUT);
  digitalWrite(rijpin[1],pullup);
  delay (200);
 
  // geluidsmodule starten
  MP3Serial.begin(9600);                    // start seriele communicatie met MP3 speler           
  startMP3(false);                          // intialiseren volume en equaliser
#if (!geluidswagon)
  while (MP3status() != 1)  {               // wacht op bericht dat initialisatie klaar is
  }
#endif
  speelGeluid (geluid, startgeluid);        // speel startgeluid af
}

// ----- hoofdlus ------
void loop() {
  // Pulsbreedte bepalen
  do {
    vooruit = !vooruit;                     // wissel de pin waarop de rijstroom wordt gemeten
    meetPuls(); 
#if Arduino
  } while (pulsPeriode > rijPeriode + pulsruis || pulsbreedteHoog < minhoog  || pulsbreedteLaag < pulsruis);    // Arduino meet soms enig "laag" op passieve pin
#else
  } while (pulsbreedteHoog < minhoog);      // 'hoog' signaal alleen op actieve rijpin
#endif
//----
  MP3speler = MP3status();
  switch (MP3speler) { 
     
    case 1:                                        // bestand klaar (MP3 speelt niet)
      lopendeFunctie = 0;                          // er loopt dan geen speciale functie meer
      speelGeluid(geluid, snelheid + stationair);  // geluidsbestand vanaf stationair / stilstand
      vorigeSnelheid = snelheid;
      break;
           
    case 3:                                        // fout
      startMP3(true);                              // reset MP3 speler
      lopendeFunctie = 0;
      while (MP3status() != 1)  {                  // wacht op bericht dat initialisatie klaar is
      }
      break;

    default:                                       
      // MP3 speler speelt of er is geen info.
      // alleen een geluid starten bij:
      //    - starten van een speciale functie
      //    - snelheidswissel als er geen speciale functie loopt
      //    - en het geluid aan stat (kan bij geluidswagon worden uitgezet)
      functie = getFunctie();
      // speciale geluidsfunctie gevonden
      if (functie) {                               // functie toets ingedrukt
        // als speciale functie is gevonden, controleer de functie frequentie nogmaals.
        // Hiermee wordt onterecht starten van functie voorkomen (door bijvoorbeeld storing op de stroomopname).
        delay (5); 
        meetPuls();
        if (functie == getFunctie()) {

          // * Lichtfunctie
#if (!DigiSpark)                   // DigiSpark geen lichtfunctie
          if (functie == lichtfunctie) {
            if (licht == 0) {licht = lichtsterkte;} else { licht = 0;}  // wissel licht aan/uit op juiste sterkte
            analogWrite(lichtPin, licht); // zet licht aan (op dimwaarde) of uit
            EEPROM.write(licht1adr,licht);         // onthou licht aan of uit tot volgende opstart.
            delay (100);
          }
#endif
#if (uitgebreidLicht)               // 2e lichtfunctie
          if (functie == lichtfunctie2) {
            if (licht2 == 0) {licht2 = lichtsterkte2;} else { licht2 = 0;}  // wissel 2e licht aan/uit op juiste sterkte
            analogWrite(lichtPin2, licht2); // zet licht aan (op dimwaarde) of uit
            EEPROM.write(licht2adr,licht2);         // onthou licht aan of uit tot volgende opstart.
            delay (100);
          }
#endif
         // * Geluidsfuncties
#if !geluidswagon
          lopendeFunctie = startFunctie(functie);  // start het geluid
#else

          if (geluidAanUit(functie)){                  // geluidswagon kan geluid aan- en uitzetten
            lopendeFunctie = 0;
          }
          else {                                      // gewoon geluid alleen starten als geluid al aan was en blijft
            if (geluid){                             
              lopendeFunctie = startFunctie(functie);   // start het gewone geluid
            }
          }
#endif                                                 
        }
      }
      // rijgeluid (of stationair)
      pulsbreedte = 100 * pulsbreedteHoog / pulsPeriode;

#if geluidswagon
      if (geluid && pulsbreedte > pulsbreedtestil[geluid-1]) {   
        if (pulsbreedte > pulsbreedtemax[geluid-1]) {
          pulsbreedte = pulsbreedtemax[geluid-1];
        }
        // geluidsbestand berekenen: reken pulssbreedte % om naar geluidsbestand volgnummer
        snelheid = map(100 * sqrt (10+pulsbreedte-pulsbreedtestil[geluid-1]), sqrtpbstil, sqrtpbmax[geluid-1], 0, aantalSnelheden[geluid-1]); 
#else
      if (pulsbreedte > pulsbreedtestil) { 
        if (pulsbreedte > pulsbreedtemax) {
          pulsbreedte = pulsbreedtemax;
        }
        // geluidsbestand berekenen: reken pulssbreedte % om naar geluidsbestand volgnummer
       snelheid = map(100 * sqrt (10+pulsbreedte-pulsbreedtestil), sqrtpbstil, sqrtpbmax, 0, aantalSnelheden);  // reken pulssbreedte % om naar geluidsbestand
#endif
        if (vorigeSnelheid != snelheid && !lopendeFunctie) {      // snelheidswissel bij lopend geluid en geen speciale functie bezig
          speelGeluid(geluid, snelheid + stationair);             // rijgeluid: geluidsbestand vanaf stationair / stilstand
          vorigeSnelheid = snelheid;
        }
      }
  }                                                // einde case switch
}


De aansluitschema's voor geluid en licht met de Arduino.




Hier het schema met ATtiny, zonder licht. De Digispark wordt op eenzelfde manier aangelsoten.




En natuurlijk maakt deze module pas geluid met MP3 bestanden. Een zip bestand met geluiden voor de BR24 (of BR64), BR38, BR50, BR57, BR70, BR78, V60, V100, V160 en VT98. Het bestand kun je hier downloden
http://www.xs4all.nl/~robvd/Forum/DB_Geluidsets.zip

(lichtmodule in volgend bericht)
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #103 Gepost op: 22 oktober 2018, 22:16:12 »
De lichtmodule

De lichtmodule gebruikt 2 pinnen met PWM (pulsbreedte) om het licht te schakelen. Zo kan de lichtsterkte in de software worden gedimd als het te fel is. De sketch:

/*
 * MODELTREIN LICHTMODULE
 * Schakelbaar licht voor de modeltrein, voor binneverlichting, sluitverlichting en meer.
 *
 * Rijstroom met pulsbreedtebesturing is nodig: met veranderingen van de pulsfrequentie worden
 * de lichtfuncties bestuurd.
 *
 * versie 0.2 - 19 sep 2018
 *
 * Notities:
 * voor Digispark EEPROM gebruik moet de library worden gekopieerd van
 * C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\EEPROM\
 * naar
 * C:\Users\{user.name}\AppData\Local\Arduino15\packages\digistump\hardware\avr\1.6.5\libraries\EEPROM\
 *
 * Voor gebruik losse ATtiny: Bootloader branden met BOD op 4.3V en clock op 16 MHz 
 */


// --- DEFINITIES ----

// Pinnen
#define lichtPin      0                // pin1 voor aansturen van licht: PWM pin (dimbaar licht)
#define lichtPin2     1                // 2e lichtpin
#define rijPin1       3                // rijstroom meting
#define rijPin2       4                // rijstroom meting

// definities voor licht
#define lichtfunctie           5       // functie 5 is sluitlicht aan/uit
#define lichtsterkte          20       // lichtsterkte (0-255)
#define lichtfunctie2          6       // functie 6 is binnenverlichting aan/uit
#define lichtsterkte2         50       // lichtsterkte (0-255)

// EEPROM geheugenlocaties
#define licht1adr                0
#define licht2adr                1

// definities voor de meting van de rijstroom
#define pullup               false     // geeft aan of de interne pullup weerstand gebruikt moet worden
#define maxpulsperiode       5000      // hoe lang wachten (minimaal 2x periode rijstroom PWM)

// Frequenties (Periodes) op de rijstroom
#define rijPeriode            2020     // rijstroom puls in us
#define functie_01_Periode    1500     // Periode (freq.) functie 1 - niet gebruikt (geluid)
#define functie_02_Periode    1250     // Periode (freq.) functie 2 - niet gebruikt (geluid)
#define functie_03_Periode     990     // Periode (freq.) functie 3 - niet gebruikt (geluid)
#define functie_04_Periode     790     // Periode (freq.) functie 4 - niet gebruikt (geluid)
#define functie_05_Periode     590     // Periode (freq.) functie 5 - licht 1
#define functie_06_Periode     450     // Periode (freq.) functie 6 - licht 2
#define pulsruis                70     // maximaal verschil in gemeten Periodes (ruis)
#define minhoog                100     // minimaal "hoog" signaal


// ---- libraries en objecten ----
#include <EEPROM.h>                    // EEPROM om licht aan/uit en geluid aan/uit te onthouden

// --- CONSTANTES EN VARIABELEN---

// rijstroom variabelen
int rijpin[] {rijPin1, rijPin2};
int vooruit = 1;                          // richting: bepaalt welke pin wordt uitgelezen voor de rijstroom puls
double pulsbreedteHoog;
double pulsbreedteLaag;
double pulsPeriode;

// variabelen voor speciale functies op de rijstroom
int functie = 0;                          // speciale functie frequentie gemeten
int licht;                                // licht sterkte of uit (0);
int licht2;                               // licht sterkte of uit (0);


// --- FUNCTIES ---

// MEET DE PULS OP DE RiJSTROOM
void meetPuls() {
  // puls meting variabelen: lengte 'hoog', 'laag' en trillingstijd (periode). Alle tijden in us.
  pulsbreedteHoog = pulseIn(rijpin[vooruit], HIGH, maxpulsperiode);
  pulsbreedteLaag = pulseIn(rijpin[vooruit], LOW, maxpulsperiode );
  pulsPeriode = pulsbreedteHoog + pulsbreedteLaag;
}

// HERKEN FUNCTIE-FREQUENTIE
// functie voor het checken van functie-frequenties
// op de puls (functietoets).
int getFunctie () {
  int f = 0;
 
  if (abs (pulsPeriode - functie_01_Periode) < pulsruis) { f = 1;}
  if (abs (pulsPeriode - functie_02_Periode) < pulsruis) { f = 2;}
  if (abs (pulsPeriode - functie_03_Periode) < pulsruis) { f = 3;}
  if (abs (pulsPeriode - functie_04_Periode) < pulsruis) { f = 4;}
  if (abs (pulsPeriode - functie_05_Periode) < pulsruis) { f = 5;}
  if (abs (pulsPeriode - functie_06_Periode) < pulsruis) { f = 6;}

  return f;
}


// ----- HOOFDPROGRAMMA -----

// ----- initialisatie -----
void setup() {

  // intialiseren rij pinnen
  pinMode     (rijpin[0],INPUT);
  digitalWrite(rijpin[0],pullup);
  pinMode     (rijpin[1],INPUT);
  digitalWrite(rijpin[1],pullup);

  delay(100);                                // even wachten op opladen elco (stabiele voeding)

  // bij opstarten de opgeslagen licht status gebruiken
  licht  = EEPROM.read(licht1adr);           // laatste licht waarde uit EEPROM
  pinMode     (lichtPin,OUTPUT);
  analogWrite (lichtPin,licht);              // licht aan of uit: waarde uit EEPROM

  licht2 = EEPROM.read(licht2adr);           // laatste licht waarde uit EEPROM
  pinMode     (lichtPin2,OUTPUT);
  analogWrite (lichtPin2,licht2);            // licht aan of uit: waarde uit EEPROM
}

// ----- hoofdlus ------
void loop() {
  // Pulsbreedte bepalen
  do {
    vooruit = !vooruit;                     // wissel de pin waarop de rijstroom wordt gemeten
    meetPuls(); 
  } while (pulsbreedteHoog < minhoog || pulsbreedteLaag < pulsruis); // 'hoog' signaal alleen op actieve rijpin
 
  functie = getFunctie();
 
  // speciale geluidsfunctie gevonden
  if (functie) {
    // als speciale functie is gevonden, controleer de functie frequentie nogmaals.
    // Hiermee wordt onterecht meten voorkomen (door bijvoorbeeld storing op de stroomopname).
    delay (5);                                   // korte pauze tussen de metingen
    meetPuls();
    if (functie == getFunctie()) {               // nog steeds dezelfde funtie op de rijstroom
      switch (functie) {   

        case lichtfunctie:
          if (licht == 0) {licht = lichtsterkte;} else { licht = 0;}  // wissel licht aan/uit op juiste sterkte
          analogWrite(lichtPin, licht); // zet licht aan (op dimwaarde) of uit
          EEPROM.write(licht1adr,licht);         // onthou licht aan of uit tot volgende opstart.
          delay (500);
        break;
        case lichtfunctie2:
          if (licht2 == 0) {licht2 = lichtsterkte2;} else { licht2 = 0;}  // wissel 2e licht aan/uit op juiste sterkte
          analogWrite(lichtPin2, licht2);         // zet licht aan (op dimwaarde) of uit
          EEPROM.write(licht2adr,licht2);         // onthou licht aan of uit tot volgende opstart.
          delay (500);
        break;
      }
    }
  }
}

Tot zover het overzicht.

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline mark mms

  • Super Modelspoorder
  • ******
  • Berichten: 1.224
  • Thanked: 26 times
  • Geslacht: Man
Re: Analoog rijden met geluid - het project.
« Reactie #104 Gepost op: 23 oktober 2018, 18:53:21 »
Hallo Rob,

Ik heb nog eens even zitten terug kijken en vind die geluiden echt geweldig, zeker die met Arduino licht en mp3 geluid.
Zodra de kolenmijn klaar is ga ik eerst over op pulsbreedte besturing en dan in de grote locs geluid inbouwen.

Groeten mark

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #105 Gepost op: 28 oktober 2018, 00:26:21 »
OK Mark, Ik ben benieuwd.

Ondertussen was ik voor mijn werk een paar dagen in Rödermark (bij Frankfurt) deze week. In de avonduurtjes op de hotelkamer nog wat op youtube zitten kijken. Daar kwam ik een oud MIBA anlagenreport tegen van een spoor 0 baan met geluid van voordat er MP3 spelers waren. De diesels ratelden hun rondjes met een soort van takke-takke-takke geluiden.

Dat bracht mij op een idee. Zou dit kunnen?

Dieselgeluid zonder MP3 speler

Vanavond eens wat zitten prutten met een tot diesel aangepaste stoom ruisgenerator sketch.



Met name die hoge toon wil ik er nog uit halen, maar het geluid lijkt in de verte al wat op een verbrandingsmotor...

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Pierre

  • Super Modelspoorder
  • ******
  • Berichten: 7.918
  • Thanked: 334 times
  • Geslacht: Man
  • Woonplaats: Den Haag (Loosduinen)
    • Haagse Modelbouw Club
Re: Analoog rijden met geluid - het project.
« Reactie #106 Gepost op: 28 oktober 2018, 13:20:42 »
Wauw Rob ... ik schiet ineens ook weer wakker. :o Misschien is dat ook wel wat voor mij. Ik laat je eerst de moeilijkheden oplossen en dan maak ik daar misschien graag weer gebruik van. ;D
Groet Pierre.

Ik rommel wat met treintjes en bouwwerkjes in H0 (H0e) en ook een klein beetje in N  .... Scratchbuilding, kitbashing en weathering.  ;D Lid van de http://haagsemodelbouwclub.nl/

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #107 Gepost op: 28 oktober 2018, 17:08:13 »
Natuurlijk, Pierre

Wauw Rob ... ik schiet ineens ook weer wakker. :o Misschien is dat ook wel wat voor mij. Ik laat je eerst de moeilijkheden oplossen en dan maak ik daar misschien graag weer gebruik van. ;D
Je had inderdaad ook nog wat dieseltjes. Verstandig, hoor, om gewoon even af te wachten  :-X

Ondertussen zijn de eerste hobbels al genomen: Het geluid is wat doffer gemaakt met een extra Elco'tje tussen de basis van de transistor en de massa.  verder is de frequentie-verandering van elke slag omgedraaid: bij de stomers neemt die af, bij de diesel juist toe. Dat klinkt al weer wat beter.
En er is al een programma'tje dat de motor start als er stroom op de geluidsmodule komt en met de rijstroom het geluid van stationair naar rijden kan schakelen, en weer terug.
Met de functietoetsen (maar daar heb jij niets aan  :( ), is de motor ook weer af te schakelen.

Nu eerst maar eens serieus op zoek naar wat ruimte in die V60.

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #108 Gepost op: 28 oktober 2018, 22:02:03 »
Nou, de kogel is door de kerk: geluid in de V60, ik ga er voor.

Eerst de loc maar eens ontleden: onderstel met aandrijving, omloop, ballast, inrichting cabine en kap.




De loc is al flink dichtgebouwd door de Oostenrijkers. De kap klikt op het ballast blok en het geheel wordt vastgeschroefd met schroeven die in dat blok vast zitten. Dat wordt nog zoeken om, zonder de constructie geweld aan te doen, delen weg halen om ruimte te maken voor de geluidsmodule.




Dus maar stukje voor stukje: eerst de speaker. Aan de onderzijde is er geen plek voor. Ik heb overwogen het rooster vooraan de loc open te maken, maar die is erg fijn weergegeven en dat gaat niet meevallen om onopvallend spleetjes te maken voor het geluid. En het zit wel erg in het zicht... Hoe de loc er ut ziet vind ik toch ook wel belangrijk.
Dan maar ergens in de cabine. Als er een paar ramen open worden gezet moet het geluid weg kunnen. Ik maak een gat in het bedieningspaneel van de machinist, daar komt de speaker onder.






Nu nog even puzzelen welk ramen open gaan, en hoe dat netjes te doen.
En dan verder zoeken waar de rest van de geluidsmodule onderdelen kunnen worden ondergebracht. Eerst maar eens een nachtje over slapen.

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #109 Gepost op: 14 november 2018, 21:59:55 »
Het is druk met werk en andere zaken, maar tussendoor wat tijd gevonden om verder te werken aan een goed dieselgeluid.
Op enig moment had ik een V60 die stond te knetteren als een Dragracer aan de start...  :o
Dat moest dus anders. Flink zitten experimenteren met manieren om goed geluid uit de ATtiny te krijgen. Ondertussen kan ik in de software de vorm van de geluidsgolf definiëren: het is geen HiFi geluid, maar goed genoeg voor een soort van diesel en zelfs het geluid van een hoorn. En dat gaat zonder extra componenten. Er is wel een grotere speaker nodig om het geluid goed te kunnen horen.

Dus vandaag begonnen om de puzzel van de geluidsmodule in de V60 te maken.

De treeplanken er op, en de balast er af...




En dan kan langzamerhand de geluidsmodule om de aandrijving heen gesoldeerd worden....




Wordt vervolgd...

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Pierre

  • Super Modelspoorder
  • ******
  • Berichten: 7.918
  • Thanked: 334 times
  • Geslacht: Man
  • Woonplaats: Den Haag (Loosduinen)
    • Haagse Modelbouw Club
Re: Analoog rijden met geluid - het project.
« Reactie #110 Gepost op: 15 november 2018, 10:00:59 »
Lekker prutsen en puzzelen Rob. Grandioos! ;)
Groet Pierre.

Ik rommel wat met treintjes en bouwwerkjes in H0 (H0e) en ook een klein beetje in N  .... Scratchbuilding, kitbashing en weathering.  ;D Lid van de http://haagsemodelbouwclub.nl/

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #111 Gepost op: 19 november 2018, 21:55:02 »
Dank, Pierre.

Afgelopen dagen had ik wat tijd om de V60 af te maken. De geluidsmodule hardware is hetzelfde gebleven als die voor stoomlocs wordt gebruikt (met ruisgenerator). Alleen de software is dus anders geworden.

Het programma is klein genoeg, zodat deze ook op een DigiSpark kan draaien. Hier wordt echter een losse ATtiny gebruikt.

V60 dieselgeluid zonder MP3 speler: De Flim.



Zoals in de video al vermeld: het geluid is een compromis tussen diesel geluid, iets dat je kunt horen en acceptabel stroomverbruik. Daarmee is het geluid vrij 'scherp'. Maar al met al niet ontevreden... ik ben vooral ook blij met de hoorn. Lekker toeteruh.

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #112 Gepost op: 26 november 2018, 12:36:32 »
De V60 krijgt een 2e versnelling

Nou ja, het is een natuurlijk een diesel-hydraulische loc, maar ook die kan wat extra gas geven,
Ik was nog niet helemaal tevreden met het rij-geluid van de V60: de motor draaide bij het rijden voor mijn gevoel te traag. De sketch is nu nog wat aangepast, zodat de 'motor' een hoger toerental krijgt bij het verhogen van de rijstroom, en weer een lager toerental wanneer de rijstroom wat wordt teruggedraaid.

Dat levert dan versie 1.0 van de software voor de diesel zonder MP3 speler op.

/*
 * DIESEL GELUIDSMODULE
 * Werkt met eigen PWM (rond 10 kHz) voor 7 staps speaker volume.
 * Golfvorm wordt gedefinieeerd in array, met stappen van 4: waardes van 0 t/m 24
 *
 * Versie 1.0, 25 november 2018 - Rob van Deursen
 */
// --- DEFINITIES ----

// kies de loc om te compileren: zet precies één definitie op 'true'
 
#define V60  true                      // @ ATtiny (los). Bootloader branden met BOD op 2.7V en clock op 16 MHz                     

#if V60
  #define ATtiny          true         // V60 @ ATtiny
  #define ruisPin            0         // pin voor aansturen van speaker
  #define rijPin1            1         // rijstroom meting
  #define rijPin2            4         // rijstroom meting
  #define statGolf          83         // aantal stappen in stationaire golf (-1)
  #define statStap        5500         // us per golf stap (stationair)
  #define rijdGolf72        71         // aantal stappen bij rijden golf (-1)
  #define rijdGolf60        59         // aantal stappen bij rijden golf (-1)
  #define rijdGolf54        53         // aantal stappen bij rijden golf (-1)
  #define rijdGolf48        47         // aantal stappen bij rijden golf (-1)
  #define rijdStap        5500         // us per golf stap (rijden)
  // berekening snelheid
  #define pulsbreedtestil   30         // pulsbreedte in % waaronder loc stil staat / stationair geluid

#endif

// definities voor de meting van de rijstroom
#define pullup               false     // geeft aan of de interne pullup weerstand gebruikt moet worden
#define maxpulsperiode       2750      // hoe lang wachten (minimaal 2x periode rijstroom PWM)

// Frequenties (Periodes) op de rijstroom
#define rijPeriode            2020     // rijstroom puls in us
#if ATtiny
//  #define functie_01_Periode  1350     // Periode (freq.) functie 1
  #define functie_01_Periode  1400     // Periode (freq.) functie 1
  #define functie_02_Periode  1190     // Periode (freq.) functie 2
#else
  #define functie_01_Periode  1500     // Periode (freq.) functie 1
  #define functie_02_Periode  1250     // Periode (freq.) functie 2
#endif
#define functie_03_Periode     990     // Periode (freq.) functie 3
#define functie_04_Periode     790     // Periode (freq.) functie 4
#define functie_05_Periode     590     // Periode (freq.) functie 5 - niet gebruikt
#define functie_06_Periode     450     // Periode (freq.) functie 6 - niet gebruikt
#define pulsruis                80     // maximaal verschil in gemeten Periodes (ruis)
#define minhoog                100     // minimaal "hoog" signaal
#define pulsbreedteStap          3.0   // verschil in pulsbreedte om op- of terug te schakelen met rijgeluid

// --- VARIABELEN ---

// rijstroom variabelen
int rijpin[] {rijPin1, rijPin2};
int vooruit = 1;                       // richting: bepaalt welke pin wordt uitgelezen voor de rijstroom puls
double pulsbreedteHoog;
double pulsbreedteLaag;
double pulsPeriode;
float pulsbreedte = 0;                 // pulsbreedte in %
int functie = 0;                       // speciale functie frequentie gemeten
float vorigePulsbreedte = 30;          // laatste pulsbreedte - wordt gebruikt om motorgeluid te regelen.
int   pbv = 0;                         // pulsbreedteverschil       

// reeksen voor geluidsgolven
// Starten:
byte dieselStrt84 [] { 0,  0, 16, 24,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 20, 24,  0,  0,  0,  0,  0,  0, 12,  8,  4,  0,  0,  0,  8,  12, 16, 20,  0,  0,  0, 24, 12, 16,  4,  0,  4,  0,  0,  8, 24,  0,  0,  0,  8,  0,  24, 12,  4,  0,  0,  4,  8, 20, 24,  0,  0,  0,  0,  0, 20, 12,  4,  0,  0,  8,  0, 12, 20, 24, 12,  0,  0, 20, 12,  0,  0 };
//   golf#            1                          2                           3                           4                           5                           6                            7                           8                            9                           10                          11                          12                       
// Stationair:
byte dieselStat84 [] { 0,  0, 12, 24, 12, 24,  0,  0,  0, 24, 24,  8,  4,  0,  0,  4, 12,  0, 16, 24,  0,  0, 16, 24, 12,  8,  4,  0,  0,  0,  8,  4,  8, 12,  0,  0,  0,  16,  8, 12,  4,  0,  4,  0,  0,  8, 16,  0,  0,  0,  4,  0,  16, 12,  4,  0,  0,  4,  8,  4, 16,  0,  0,  0,  0,  0, 12,  8,  4,  0,  0,  4,  0,  8, 12, 16, 12,  0,  0, 16,  8,  0,  0 };
//   golf#            1                          2                           3                           4                           5                           6                            7                           8                            9                           10                          11                          12                       
// Rijden:
byte dieselRijd72 [] { 0,  4,  8, 12, 24,  0,  0, 24, 16,  8,  4,  0,  0,  4, 12, 16, 24,  0,  0, 24, 20, 12,  8,  0,  0,  8, 12, 20, 24,  0,  0,  24, 16, 12,  4,  0,  0,  8, 16, 20, 24,  0,  0, 24, 16, 12,  4,  0,  0,  8, 12, 16,  24,  0,  0, 24, 20, 12,  4,  0,  0,  4,  12, 20, 24,  0,  0,  24, 20,  12,  8,  0 };
byte dieselRijd54 [] {     0,  0, 12, 24,      0, 24, 16,  0,  0,          0,  0, 16, 24,      0, 24, 20,  0,  0,          0,  8, 20, 24,      0,  24, 16,  0,  0,          0,  4, 20, 24,      0, 24, 16,  0,  0,          0,  0, 16,  24,      0, 24, 20,  0,  0,          0,   4, 20, 24,      0,  24, 20,   0,  0     };
//   golf#            1                      2                       3                       4                       5                       6                        7                       8                        9                       10                      11                      12                       
// Niet gebruikte golfvormen voor rijden:
//byte dieselRijd60 [] { 0,  0,  0, 12, 24,      0, 24, 16,  0,  0,      0,  0,  0, 16, 24,      0, 24, 20,  0,  0,      0,  0,  8, 20, 24,      0,  24, 16,  0,  0,      0,  0,  4, 20, 24,      0, 24, 16,  0,  0,      0,  0,  0, 16,  24,      0, 24, 20,  0,  0,      0,  0,   4, 20, 24,      0,  24, 20,   0,  0     };
//byte dieselRijd48 [] {     0,  0, 12, 24,      0, 24, 16,  0,              0,  0, 16, 24,      0, 24, 20,  0,              0,  8, 20, 24,      0,  24, 16,  0,              0,  0, 16, 24,      0, 24, 16,  0,              0,  0, 12,  24,      0, 24, 20,  0,              0,   0, 16, 24,      0,  24, 12,   0         };

// Hoorn (vol volume, half volume):
byte hoorn [] { 12,  4, 12, 24, 16, 12, 24,  0};
byte hoorn2[] {  8,  0,  8, 16, 12,  8, 16,  0};

// overige variablen
int t = 0;                            // index geluidsreeks (array)
int gs;                               // waarde geluidsstap
int d = statStap;                     // vertraging afspelen geluidswaarden (us)
bool stationair = true;
bool gas        = false;
unsigned long u;                      // microseconden
unsigned long m;                      // milliseconden

// --- FUNCTIES ---

// PULSBREEDTE 0-24, ROND 10 kHz
// in stappen van 4. Voor afspelen van geluidsgolven.
// na het verloop van de gewensde tijdsfuur staat de PWM uit.
// input: pin waarop PWM wordt gezet
//        waarde van PWM , 7 stappen van 0-24 (0 = uit, 24 = maximaal)
//        tijdsduur van PWM waarde (in us)
void microPWM (int pin,int  pwm, int tim) {
  unsigned long mics = micros() + tim;
  do  {
    digitalWrite (pin,HIGH);
    delayMicroseconds (pwm);
    digitalWrite (pin,LOW);
    delayMicroseconds (24-pwm);
  } while (micros() <= mics);
}

// SPEEL GELUIDSGOLF AF
// input: reeks voor golfvorm
//        aantal stappen in de golfvorm reeks
//        tijdsduur van elke stap in us
//        aantal herhalingen
void speelGolf (byte golf[], int stappen, int usec, int herhaal){
  int           g;
  unsigned long w;
  //int           us = usec;
  for (int y = 0; y < herhaal ; y++){
    for (int x = 0; x < stappen ; x++) {
      g = golf[x];
      microPWM(ruisPin, g , usec);
    }
  }
}
// MEET DE PULS OP DE RIJSTROOM
void meetPuls() {
  // puls meting variabelen: lengte 'hoog', 'laag' en trillingstijd (periode). Alle tijden in us.
  pulsbreedteHoog = pulseIn(rijpin[vooruit], HIGH, maxpulsperiode);
  pulsbreedteLaag = pulseIn(rijpin[vooruit], LOW, maxpulsperiode );
  pulsPeriode = pulsbreedteHoog + pulsbreedteLaag;
}

// HERKEN FUNCTIE-FREQUENTIE OP DE RIJSTROOM
// functie voor het checken van functie-frequenties
// op de puls (functietoets).
int getFunctie () {
  int f = 0;
 
  if (abs (pulsPeriode - functie_01_Periode) < pulsruis) { f = 1;}
  if (abs (pulsPeriode - functie_02_Periode) < pulsruis) { f = 2;}
  if (abs (pulsPeriode - functie_03_Periode) < pulsruis) { f = 3;}
  if (abs (pulsPeriode - functie_04_Periode) < pulsruis) { f = 4;}

  return f;
}

// FUNCTIE: WACHTEN EN TERWIJL RIJSTROOM METEN
int wachtEnMeet() {
  int fu = 0;
  u = micros() + d;
  d = random (rijdStap, rijdStap+300);

  vooruit = !vooruit;                     // wissel de pin waarop de rijstroom wordt gemeten
  meetPuls(); 
  if (pulsbreedteHoog > minhoog && pulsbreedteLaag > pulsruis) {
    pulsbreedte = 100 * pulsbreedteHoog / pulsPeriode;
    stationair = (pulsbreedte <= pulsbreedtestil);         // stationair / rijden
    fu = getFunctie();
  }
  while (micros() < u) {
    ; 
  }
  return fu;
}

// SPEEL GELUIDSFUCTIE
// input: nummer van de geluidsfunctie
void speelFunctie(int gf) {
  switch (gf) {
    case 1:
      // lange hoorn
      speelGolf (hoorn2, 8, 300, 20 );
      speelGolf (hoorn , 8, 300, 540);
      speelGolf (hoorn2, 8, 308, 50 );
    break;

    case 2:
      // korte hoorn
      speelGolf (hoorn2, 8, 300, 20 );
      speelGolf (hoorn , 8, 300, 150);
      speelGolf (hoorn2, 8, 308, 50 );
    break;
   
    case 3:
      // remgeluid: 2,4 seconde
      m = millis() +2400;
      while (millis() < m) {
        microPWM (ruisPin, 12*random (0,2), random (4, 33));
        delayMicroseconds (190 + random (65));
      }
    break;

    case 4:
      // motor afzetten
      speelGolf (dieselStrt84, 83, 5200, 1);
      speelGolf (dieselStrt84, 83, 6900, 1);
      speelGolf (dieselStrt84, 27, 8300, 3);
      speelGolf (dieselStrt84, 27, 9500, 1);
      delay (5000);
    break;
  }
}

// --- INITIALISATIE ---
// Achtereenvolgens wordt het volgende uitgevoerd:
// Alle pinnen goed zetten (input, output)
// motor starten als de  loc nog niet rijdt.
void setup() {
  // Pinnen initialiseren
  pinMode (    ruisPin, OUTPUT);
  digitalWrite (ruisPin, LOW);
  pinMode      (rijpin[0],INPUT);
  digitalWrite (rijpin[0],pullup);
  pinMode      (rijpin[1],INPUT);
  digitalWrite (rijpin[1],pullup);
  delay(150);
   
  //meet de rijstroom op beide pinnen om te kijken of er gereden wordt
  for (t=0; t < 4; t++) {
    meetPuls(); 
    if (pulsbreedteHoog > minhoog && pulsbreedteLaag > pulsruis) {
      pulsbreedte = 100 * pulsbreedteHoog / pulsPeriode;
      stationair = (pulsbreedte <= pulsbreedtestil);         // stationair / rijden
    }
    vooruit = !vooruit;                     // wissel de pin waarop de rijstroom wordt gemeten
  }
  if (stationair) {
    //Loc staat stil: start de motor
    speelGolf (dieselStrt84, 27, 8300, 5);
    speelGolf (dieselStrt84, 83, 6700, 1);
    speelGolf (dieselStrt84, 83, 5200, 1);
  }
}

// --- HOOFPROGRAMMA ---
// Het hoofdprogramma speelt het motor geluid af, stationair of rijden.
// Tussendoor wordt de rijstroom gemeten voor snelheidswisseling en
// speciale geluidsfuncties.
// Het geluid wisselt tussen stationair en rijden, afhankelijk van de rijstroom
// als een geluidsfunctie wordt geregistreerd, wordt die ook afgespeeld.

void loop() {
  if (stationair) {
    // stationar geluid
    gas = false;
    vorigePulsbreedte = pulsbreedtestil;
    for (t = 0; t < statGolf ; t++) {
      gs = dieselStat84[t];
      if (gs) {
        microPWM(ruisPin, gs , d);
      }
      else {
        functie = wachtEnMeet(); 
        // bij stilstand 1x functie meten. Minder contact storingen
        if (functie) {
          speelFunctie(functie) ;
        }
      }
    }
  }
  if (!stationair) {
  // geluid bij rijden: in 2 trappen
    pbv = pulsbreedte - vorigePulsbreedte;
   if (pbv > pulsbreedteStap) {
      gas = true;
      vorigePulsbreedte = pulsbreedte;
    }
    if (pbv < -pulsbreedteStap) {
      gas = false;
      vorigePulsbreedte = pulsbreedte;
    }
    if (!gas) {
      for (t = 0; t < rijdGolf72 ; t++) {
        gs = dieselRijd72[t];
        if (gs) {
          microPWM(ruisPin, gs , d);
        }
        else {
          if (wachtEnMeet() ) {   
            // bij rijden 2x functie meten om contactstoringen te vermijden
            meetPuls(); 
            if (pulsbreedteHoog > minhoog && pulsbreedteLaag > pulsruis) {
              functie = getFunctie();
            }
            if (functie) {
              speelFunctie(functie) ;
            }
          }
        }
      }
    }
    else {
     for (t = 0; t < rijdGolf54 ; t++) {
        gs = dieselRijd54[t];
        if (gs) {
          microPWM(ruisPin, gs , d);
        }
        else {
          if (wachtEnMeet() ) {   
            // bij rijden 2x functie meten om contactstoringen te vermijden
            meetPuls(); 
            if (pulsbreedteHoog > minhoog && pulsbreedteLaag > pulsruis) {
              functie = getFunctie();
            }
            if (functie) {
              speelFunctie(functie) ;
            }
          }
        }
      }   
    }
  }             
}

Ik heb nog een filmpje gemaakt van de V60 op station "Klütz".



Deze loc werkt best fijn zo op dit eindstation. Ik denk dat ik tegenover de kolenbunker nog een klein dieseltankstation ga maken. Maar daarover volgt dan verder bericht in een ander draadje...

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Pierre

  • Super Modelspoorder
  • ******
  • Berichten: 7.918
  • Thanked: 334 times
  • Geslacht: Man
  • Woonplaats: Den Haag (Loosduinen)
    • Haagse Modelbouw Club
Re: Analoog rijden met geluid - het project.
« Reactie #113 Gepost op: 26 november 2018, 15:04:49 »
Weer een klus geklaard Rob. Prachtig werk. ;)  Is het schema hetzelfde als voor de stomers?
Groet Pierre.

Ik rommel wat met treintjes en bouwwerkjes in H0 (H0e) en ook een klein beetje in N  .... Scratchbuilding, kitbashing en weathering.  ;D Lid van de http://haagsemodelbouwclub.nl/

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #114 Gepost op: 26 november 2018, 15:28:42 »
Zo is het, Pierre. Bedankt.

Is het schema hetzelfde als voor de stomers?
Yep, dezelfde hardware als voor de stomers. Let alleen even op de gebruikte pinnen: ik wissel ze nog wel eens afhankelijk van wat het beste past. Maar die definieer je hier:
  #define ruisPin            0         // pin voor aansturen van speaker
  #define rijPin1            1         // rijstroom meting
  #define rijPin2            4         // rijstroom meting
Mocht je ooit een dieseltje doen, dan moeten nog wel de extra geluidsfuncties uit deze sketch worden weggehaald. Anders loop je de kans dat bij jouw rijstroomregeling het gewone rijden niet werkt. Maar dat is simpel te doen, hoor: heb ik bij de sketch voor je stomers ook gedaan ;D

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Wim Corduwener

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 10.844
  • Thanked: 300 times
  • Geslacht: Man
  • Enschede (import)
    • Portfolio
Re: Analoog rijden met geluid - het project.
« Reactie #115 Gepost op: 26 november 2018, 15:42:13 »
Naast het fraaie geluid van díe diesel vind ik het geluid van die ongeïsoleerde rails ook wel wat hebben. Bij elkaar klinkt het heel levensecht.
Trefwoorden:  Mac • Modulebouw • H0, H0e en 0e • Tijdperk III (1950-1960) • Nederlands (H0 en H0e) • Frans (1:45) • Gelijkstroom • Twee rails • Voorlopig nog even analoog • Scratchbuilding en Kitbutchering... en ik maak eigenlijk nooit wat af.

Meest recente projecten: Frans diorama 2.0 (Spoor 0e) en Verbouwing Magic Train (schaal 0e)

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #116 Gepost op: 26 november 2018, 16:12:07 »
Dank je, Wim.
Ik heb inderdaad geen geluidisolatie onder de rails liggen op deze module voor het eindstation. Er wordt hier altijd langzaam gereden.
En nu je me daar op wijst: de diesel klinkt hier ook wat luider dan op mijn andere station (op de vaste baan), waar de rails op piepschuim ligt...

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Wim Corduwener

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 10.844
  • Thanked: 300 times
  • Geslacht: Man
  • Enschede (import)
    • Portfolio
Re: Analoog rijden met geluid - het project.
« Reactie #117 Gepost op: 26 november 2018, 19:17:46 »
Is ook wel een beetje logisch: doordat je rails niet geïsoleerd is wordt via de rails het geluid overdragen naar je ondergrond en wordt je ondergrond een soort van geluidsdrager.
Daarbij vind ik dat het kedengedeng, kedengedeng-geluid ook bij een (model)spoorbaan hoort.
Trefwoorden:  Mac • Modulebouw • H0, H0e en 0e • Tijdperk III (1950-1960) • Nederlands (H0 en H0e) • Frans (1:45) • Gelijkstroom • Twee rails • Voorlopig nog even analoog • Scratchbuilding en Kitbutchering... en ik maak eigenlijk nooit wat af.

Meest recente projecten: Frans diorama 2.0 (Spoor 0e) en Verbouwing Magic Train (schaal 0e)

Offline mark mms

  • Super Modelspoorder
  • ******
  • Berichten: 1.224
  • Thanked: 26 times
  • Geslacht: Man
Re: Analoog rijden met geluid - het project.
« Reactie #118 Gepost op: 26 november 2018, 21:42:51 »
Ik vind het zeker niet storend, zelfs nog wat extra’s toevoegen aan de levendigheid van de baan.
Een heel geslaagd project naar mijn mening.

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #119 Gepost op: 26 november 2018, 23:55:32 »
Hoi Mark,
Bedankt.
Het project is nu, met deze V60 nabrander, inderdaad afgelopen.
Dat neemt niet weg dat er links of rechts nog wel eens een geluidsmodule ingebouwd gaat worden, hoor. Maar dat is dan 'regulier' modelbaanwerk....

Nog even een overzichtsplaat van dit compleet uit de klauwen gelopen projectje.




Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline mark mms

  • Super Modelspoorder
  • ******
  • Berichten: 1.224
  • Thanked: 26 times
  • Geslacht: Man
Re: Analoog rijden met geluid - het project.
« Reactie #120 Gepost op: 27 november 2018, 22:26:11 »
Rob ik heb toch nog eens zitten denken.
In de kleine locs zoals de Anna en glaskasten wordt dit een hele grote uitdaging.
Nou heb ik een stationair geluidsbron die rijspanning afhankelijk het stoomlokgeluid afspeelt.
Dit moet toch ook mogelijk zijn m.b.v. een Arduino met mp3?
En dan wellicht verschillende mp3 stoomlok geluiden zodat je het “juiste” geluid kunt afspelen bij de loc.

Hoor graag jouw mening.
En natuurlijk is het geluid in de loc het mooiste.

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #121 Gepost op: 27 november 2018, 23:53:46 »
Hoi Mark,

Heel kleine locs is inderdaad een uitdaging, dan is dit
Nou heb ik een stationair geluidsbron die rijspanning afhankelijk het stoomlokgeluid afspeelt.
Dit moet toch ook mogelijk zijn m.b.v. een Arduino met mp3?
En dan wellicht verschillende mp3 stoomlok geluiden zodat je het “juiste” geluid kunt afspelen bij de loc.
wel een idee.
Ik heb iets dergelijks al in de geluidswagon: die kan geluiden maken voor tot 6 verschillende locs. Die beperking van 6 is dat ik 6 functie knoppen heb, maar bij een stationaire opstelling kun je tot 255 verschillende locs gaan (het maximum aantal mapjes op de SD kaart van de MP3 speler.
Dus gewoon doen, zou ik zeggen.

Overigens zit bij de geluidssets ook een BR70. Misschien is dat geluid ook aardig bruikbaar voor de Anna.

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Michel Bikkel

  • Super Modelspoorder
  • ******
  • Berichten: 551
  • Thanked: 24 times
  • Geslacht: Man
Re: Analoog rijden met geluid - het project.
« Reactie #122 Gepost op: 12 december 2018, 15:50:46 »
Zou er ook iets van dit systeem werken voor DCC?
Gezien de prijs is dat namelijk wel intressant :-)

Groet Mies

Offline Rob

  • Forumbeheerder
  • Super Modelspoorder
  • *****
  • Berichten: 2.743
  • Thanked: 161 times
  • Geslacht: Man
  • Rob zegt: denk aan morgen, doe vandaag.
Re: Analoog rijden met geluid - het project.
« Reactie #123 Gepost op: 12 december 2018, 20:47:40 »
hoi Michel.

Goede vraag.
Zou er ook iets van dit systeem werken voor DCC?
Gezien de prijs is dat namelijk wel intressant :-)

Bij digitaal rijden heb je een constante spanning op de baan en daarop een of ander digitaal signaal. Met die constante rijspanning heb je in ieder geval voldoende vermogen beschikbaar om een Arduino en speaker (met of zonder MP3 speler) te voeden. Voor het aansturen van de Arduino (of een van de andere microcontrollers), kan ik me in grote lijnen 3 manieren voorstellen hoe dit zou kunnen werken bij digitaal rijden:
  • Als het alleen om rijgeluid (en stationair gaat), kun je de pulsbreedte van de motor meten. Deze pulsbreedte wordt geleverd door de digitale module.
    Voordeel van deze oplossing: je hoeft niets te weten van het DCC protocol. Nadeel: geen extra geluidsfuncties.
    Zelfs de sketches die hier zijn gebruikt kunnen dan een aardige basis geven, die meten ook de pulsbreedte voor de motor.
  • Met de Arduino (e.d.) is het vast mogelijk het digitale signaal op de rails op te pikken. Het lastigste is hier chocola te maken van dat signaal: ofwel wat voor signaal is het en volgens welk protocol gaan de gegevens er over?
    Als je dit kunt achterhalen, zou dit ook door de Arduino te lezen moeten zijn. Ik kan me echter voorstellen dat de informatie over dit protocol beperkt is, want anders kunnen hobbyisten zomaar zelf geluidsmodules in elkaar klussen  ;)
  • Ik weet niet of locdecoders en geluidsmodules apart zijn, dat je de geluidsmodule op een locdecoder aansluit? Als dat zo is, dan zou je de arduino aan de aansluiting van de geluidsmodule kunnen koppelen. Maar ook hier moet je dan weten hoe de communicatie verloopt.
Over digitale communicatie gesproken: daar zijn aardig wat mogelijkheden voor met de Arduino. Zo gebruik ik een software bibliotheek om de seriele communicatie met de MP3 speler te kunnen doen. Dit kon echter alleen omdat de structuur en inhoud van de seriële commando's van die MP3 speler duidelijk waren beschreven in de handleiding....

Maar lijkt me een mooi draadje: Digitaal rijden met geluid uit een Arduino.

Rob
Ergens in (West) Duitsland tussen 1960 en 1970 | gelijkstroom analoog, met geluid | kleine vaste baan en uitbreiding met modulebaan.
Nu vooral bezig met van alles en nog wat...

Offline Michel Bikkel

  • Super Modelspoorder
  • ******
  • Berichten: 551
  • Thanked: 24 times
  • Geslacht: Man
Re: Analoog rijden met geluid - het project.
« Reactie #124 Gepost op: 12 december 2018, 21:28:21 »
Hoi Rob,

mijn loc's gebruiken het DCC protocol.verder is het voor mij allemaal hocus pokus...
Misschien zijn er hier wel leden die daar wat meer van weten...

Groet Mies