/*
* RUISGENERATOR STOOMTREIN
* Stoomtrein geluiden: "puffen" van ruis in verschillend tempo
*/
// --- DEFINITIES ----
// pin definities
#define Ruispin 13 // pin voor aansturen van speaker: pin 1 of 0 (0 = 5 sec. vertraging)
//geluidsdefinities
//lok 1
// definities voor slagen BR91: 1e wat hoger, laatste wat lager dan de 2 middelste slagen (tsjie, tsja, tsja, tsjoe)
#define Startfreq1 1950 // laagste frequentie ruis slag 1
#define Eindfreq1 4350 // 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 26 // pulsbreedte in % waaronder loc stil staat
#define pulsbreedtemax 84 // pulsbreedte waar de maximum snelheid (pufritme) wordt bereikt
#define langstePuf 800 // langste puf (in ms) - langzaam rijden
#define kortstePuf 71 // kortste puf (in ms) - topsnelheid (minimum ligt rond 50ms)
// algemene geluidsdefinities
#define pauze 0.25 // factor puf/pauze (elke slag heeft voor een deel stilte)
#define SisLaag 4000 // frequentiebereik voor sisgeluid
#define SisHoog 5500
// --- CONSTANTES ---
const float sqrtpbstil = 100*sqrt(pulsbreedtestil);
const float sqrtpbmax = 100*sqrt(pulsbreedtemax);
// ---- 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;
float pulsbreedte = pulsbreedtestil; // pulsbreedte in %
float pbtoename = 2;
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);
}
// --- HOOFDPROGRAMMA ---
// functies bij starten
void setup() {
Serial.begin(9600);
Serial.println("Ruisgenerator start.");
pinMode (Ruispin,OUTPUT);
speelRuis (3150, SisLaag,SisHoog); // sissen bij opstarten
}
// --- hoofdlus (loopt eindeloos door) ---
void loop() {
if (millis() > pze) { // lok rijdt en er is nu geen puf-pauze of vrijloop
// Pulsbreedte bepalen
pulsbreedte = pulsbreedte + pbtoename;
Serial.print("pulsbreedte: ");
Serial.println(pulsbreedte);
// rijgeluid
// tweecylinder = 4 puf slagen met verschil in de slagen (volgens definities van de loc)
// puf slag berekenen
if (pulsbreedte > pulsbreedtemax) {
pulsbreedte = pulsbreedtemax;
pbtoename = -2;
}
if (pulsbreedte < pulsbreedtestil) {
pulsbreedte = pulsbreedtestil;
pbtoename = 2;
}
puf = map(100 * sqrt (pulsbreedte), 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 hoofd-lus
Eerst maar straatje schilderen....
Dus eigenlijk is pulsbreedte besturing ook een soort van digitale voeding?
Nou Pierre dat is een grote stap voor een analoge spoorder.
Ik ben woest aan het schilderen en popel om de soldeerbout te pakken. Ik moet me beheersen. ;DDat vind ik nou weer knap van je @Pierre: dat je jezelf kunt beheersen en eerst het ene project afmaakt voordat je met het volgende begint. IJzeren discipline! :D
Tja ... dat doe jij toch ook altijd. ::)Nee, ik ben bezig met het één en in m'n hoofd alweer bezig met het volgende project. ::)
/* GELUIDSMODULE TESTER
* Testprogramma voor geluidsmodules voor analoge h0 trein
* Geeft aan welke signalen door de module worden herkend.
* Meet de puls op 2 pinnen verbonden met de rijstroom.
* Programma wacht op herkenbaar signaal op een van de pinnen.
* Bij herkenbaar signaal wordt de rijpin, pulsbreedte in % en
* frequentie weergegeven.
* Output op de seriële (USB) poort. Waarden zijn uit te lezen met
* de serial monitor op de computer.
*
* Alleen als de pulsbreedte-waarde verandert wordt een nieuwe regel
* met informatie 'geprint'.
*/
// ==> Geef hier de 2 pinnen op waarmee de rijstroom wordt gemeten <==
#define rijpin1 11
#define rijpin2 12
// --- DEFINITIES ----
#define pullup false // geeft aan of de interne pullup weerstand gebruikt moet worden
#define maxpulsperiode 5000 // hoe lang wachten (minimaal 2x periode)
#define pulsruis 40 // maximaal verschil in gemeten Periodes (ruis)
#define minhoog 200 // minimaal "hoog" signaal
#define elcoLaadtijd 1000 // oplaadtijd van de Elcos (ms) = tijd tot stabiele pulsmeting
// ---- VARIABLEN ----
int rijpin[] {rijpin1, rijpin2};
// pulse meting variabelen: lengte 'hoog', 'laag' en trillingstijd (periode). Alle tijden in us.
double pulsbreedteHoog;
double pulsbreedteLaag;
double pulsPeriode;
double pulsbreedteHoog2;
double pulsbreedteLaag2;
double pulsPeriode2;
int vooruit = 1; // richting: bepaalt welke pin wordt uitgelezen voor de rijstroom puls
int pulsbreedte = 0; // pulsbreedte in %
int vorigePulsbreedte = 0; // vorige pulsbreedte om verandering vast te stellen
unsigned int pulsfrequentie = 0; // speciale functie frequentie gemeten
unsigned int vorigeFrequentie = 0;
void setup() {
pinMode (rijpin[0],INPUT);
digitalWrite(rijpin[0],pullup);
pinMode (rijpin[1],INPUT);
digitalWrite(rijpin[1],pullup);
Serial.begin(9600);
Serial.println("Geluidsmodule gestart.");
delay(elcoLaadtijd); // wacht op stabiele puls (na opladen Elco)
getSignaal(); // zoek naar signaal op de pinnen
}
void loop() {
// lees de huidige rijpin uit
pulsbreedteHoog = pulseIn(rijpin[vooruit], HIGH, maxpulsperiode);
pulsbreedteLaag = pulseIn(rijpin[vooruit], LOW, maxpulsperiode );
pulsbreedteHoog2 = pulseIn(rijpin[vooruit], HIGH, maxpulsperiode);
pulsbreedteLaag2 = pulseIn(rijpin[vooruit], LOW, maxpulsperiode );
pulsPeriode = pulsbreedteHoog + pulsbreedteLaag;
pulsPeriode2 = pulsbreedteHoog2 + pulsbreedteLaag2;
// beoordeel het signaal
if (pulsPeriode < pulsruis ) {
// geen herkenbaar signaal meer
getSignaal(); // zoek naar signaal op een van de rijpinnen
vorigePulsbreedte = 0; // forceer weergave zodra signaal gevonden
} else
// herkenbaar signaal
{
// bepaal welk signaal (frequentie) is ontvangen en voer resultaten uit
// normale rijstroom: bereken pulsbreedte (in %)
pulsbreedte = 100 * pulsbreedteHoog / pulsPeriode;
pulsfrequentie = 1000000 / pulsPeriode;
// resultaten weegeven als er iets is veranderd.
if (abs(vorigePulsbreedte - pulsbreedte) > 0) {
// meer dan 1% pulsbreedte verschil of functietoets ingedrukt
Serial.print ("Rijpin: ");
Serial.print (vooruit + 1);
Serial.print (" || Pulsbreedte: ");
Serial.print (pulsbreedte);
Serial.print("% ");
Serial.print (" || Frequentie: ");
Serial.print(pulsfrequentie);
Serial.println(" Hz");
delay(10);
vorigePulsbreedte = pulsbreedte;
vorigeFrequentie = pulsfrequentie;
}
}
}
// SIGNAAL ZOEKEN
// functie om te wachten op een herkenbaar signaal op een van de rijpinnen.
void getSignaal() {
Serial.println ("Module wacht op herkenbaar signaal.");
// zolang geen rijstroom periode en geen "hoog" signaal is gevonden
// blijft deze lus om-en-om op elk van de rijpinnen meten.
do {
vooruit = (!vooruit); // wissel van rijpin
pulsbreedteHoog = pulseIn(rijpin[vooruit], HIGH, maxpulsperiode);
pulsbreedteLaag = pulseIn(rijpin[vooruit], LOW , maxpulsperiode);
pulsPeriode = pulsbreedteHoog + pulsbreedteLaag;
delay(50);
Serial.print("."); // elke poging: "."
delay(200);
} while ( pulsbreedteHoog < minhoog);
// Signaal gevonden. Geef dit aan op de seriële bus
Serial.println("!");
Serial.print("Herkenbaar signaal gevonden op rijpin ");
Serial.print(vooruit+1);
Serial.println(".");
}
// --- einde ---
@Pierre, ga je ook zelf met de software 'oan de geng' na verloop van tijd of laat je dat over aan de programmeurs?
Ondanks dat deze materie ver buiten mijn bevattingsvermogen gaat lees ik toch mee en heb ik een vraagje zodat ik ook meteen weet of ik er ook maar iets van begrijp: een MSF-trafo van bijvoorbeeld Fleischmann, is dat een transformator met pulsbreedtemodulatie waar jullie het hier over hebben?
een MSF-trafo van bijvoorbeeld Fleischmann, is dat een transformator met pulsbreedtemodulatie waar jullie het hier over hebben?
Pulsbreedte besturing werkt niet met 'ronde' golven, maar met 'hoekige'. Voor het rijden maakt dat niet zo heel veel uit, maar voor de geluidsmodules wel.
Ik heb de twee weerstanden vergroot naar 1K. De voeding heb ik teruggebracht naar 13V maar het werkt nog steeds niet lekker.Dat is in ieder geval een verandering ten opzichte van gisteren....
Als ik (hulpmiddelen - Seriële monitor) start dat geeft hij inderdaad aan Geluidsmodule gestart en dat er gewacht wordt op een herkenbaar signaal. Als ik nu aan de draaiknop een klein stukje draai geeft hij geeft hij aan pin1 of pin2 en een regeltje met Pulsbreedte: 100% Frequentie: 1602 en Module wacht op herkenbaar signaal. Dit regeltje blijft hij herhalen. Als ik dan aan de knop draai (maakt niet uit hoe hoog en welke kant op ) dan zegt hij: Herkenbaar signaal gevonden op rijpin 1 of 2. Module wacht op herkenbaar signaal. Gevolgd door een hele zwik lopende puntjes met een ! er achter. Ook deze regel blijft hij maar herhalen. Als ik de knop hoger draai krijg ik steeds meer puntjes.
Bij metingen aan mijn eigen MSF trafo heb ik overigens nooit iets van deelgolven kunnen zien.Ah, ik probeerde de term "Mischwellen" te interpreteren. Blijkbaar is dat iets anders...
/* PULS METEN
* Hulpprogramma bij geluidsmodules voor analoge h0 trein.
* Meet de puls op 2 pinnen waarmee de rijstroom wordt gemeten
* en print deze op de seriële poort, en daarme op de USB poort.
* Waarden zijn uit te lezen met de serial monitor op de computer.
*/
// Geef de 2 pinnen op waar de rijstroom wordt gemeten
#define rijpin1 11
#define rijpin2 12
#define pullup false
// --- variabelen ---
double channel1;
double channel2;
double channel3;
double channel4;
double frequentie1;
double frequentie2;
void setup() {
// rijpinnen initialiseren: input en interne pullup weerstand gebruiken
pinMode(rijpin1,INPUT);
pinMode(rijpin2,INPUT);
digitalWrite(rijpin1,pullup);
digitalWrite(rijpin2,pullup);
// start de seriele communicatie (USB)
Serial.begin(9600);
Serial.println("Pulsmeting gestart. Alle waarden in micro seconden (us)");
}
void loop() {
// meet de tijdspanne voor "hoog" en "laag" op beide pinnen
channel1 = pulseIn(rijpin1,HIGH);
channel2 = pulseIn(rijpin1,LOW);
channel3 = pulseIn(rijpin2,HIGH);
channel4 = pulseIn(rijpin2,LOW);
// geef de meetwaarden weer
Serial.print("Pin 1 periode: ");
Serial.print(channel1 + channel2);
Serial.print(" - hoog/laag: ");
Serial.print(channel1);
Serial.print(" / ");
Serial.print(channel2);
Serial.print(" || Pin 2 periode: ");
Serial.print(channel3 + channel4);
Serial.print(" - hoog/laag: ");
Serial.print(channel3);
Serial.print(" / ");
Serial.println(channel4);
delay (200); // even wachten...
}
// --- einde ---
eerde de term "Mischwellen" te interpreteren. Blijkbaar is dat iets anders...
deze nieuwe pulsbreedtebesturing ziet er wel solide uit en met 5A output heb je ruim voldoende vermogen. De uitgangsspanning zal wel ergens rond de 12V liggen (ik neem aan dat deze bedoeld was voor 12V halogeenlampen).
Ben wel benieuwd of/hoe de richting geregeld wordt.
Op de Arduino kun je gewoon nieuwe software laden: de oude hoeft er niet eerst af.
Is de draairichting niet te regelen door gewoon de draden om te wisselen met b.v. een schakelaar? Het blijft toch gelijkstroom?Dat werkt ook. Voor het geluid in beide richtingen is een rijrichting wissel wel nodig om te testen.
/*
* 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)
* 2: sissen
* 3: remmen
* 4: stilte (vrijloop)
* Functies werken redelijk bij langzaam rijden en goed bij stilstand en snel rijden
*
* versie 1.1 - 29 jul 2018
*/
// --- DEFINITIES ----
// kies de loc om te compileren: zet precies één definitie op 'true'
#define LocPierre true
#define BR64 false
#define BR70 false
#define BR91 false
#define Ruispin 13 // pin voor aansturen van speaker: pin 1 of 0 (0 = 5 sec. vertraging)
#define rijpin1 12 // rijstroom meting
#define rijpin2 11 // rijstroom meting
//geluidsdefinities per type loc
#if LocPierre
// 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 42 // pulsbreedte in % waaronder loc stil staat
#define pulsbreedtemax 90 // 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 930 // 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 BR91
// definities voor slagen BR91: 1e wat hoger, laatste wat lager dan de 2 middelste slagen ("tsjie, tsja, tsja, tsjoe")
#define Startfreq1 1950 // laagste frequentie ruis slag 1
#define Eindfreq1 4350 // 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 26 // pulsbreedte in % waaronder loc stil staat
#define pulsbreedtemax 84 // pulsbreedte waar de maximum snelheid (pufritme) wordt bereikt
#define langstePuf 800 // langste puf (in ms) - langzaam rijden
#define kortstePuf 71 // 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 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 490 // Periode (freq.) functie 6 - niet gebruikt
#define pulsruis 100 // maximaal verschil in gemeten Periodes (ruis)
#define minhoog 200 // 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);
}
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);
speelRuis (BeginSis, SisLaag,SisHoog); // sissen bij opstarten
}
void loop() {
// Pulsbreedte bepalen
vooruit = !vooruit; // wissel de pin waarop de rijstroom wordt gemeten
meetPuls();
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).
meetPuls();
if (functie == getFunctie()) { // nog steeds dezelfde funtie op de rijstrrom
switch (functie) { // speel functie 1, 2, 3 of 4.
case 1:
speelFluitje(1800); // fluitje afspelen, 1,8 sec.
break;
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
#define Ruispin 13 // pin voor aansturen van speaker: pin 1 of 0 (0 = 5 sec. vertraging)
#define rijpin1 12 // rijstroom meting
#define rijpin2 11 // rijstroom meting
#define Ruispin 0 // pin voor aansturen van speaker: pin 1 of 0 (0 = 5 sec. vertraging)
#define rijpin1 1 // rijstroom meting
#define rijpin2 2 // rijstroom meting
// berekening snelheid
#define pulsbreedtestil 42 // pulsbreedte in % waaronder loc stil staat
#define pulsbreedtemax 90 // 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)
pulsbreedtestil definieert waar de loc gaat rijden. Deze staat nu op 42% pulsbreedte. Blijkbaar moet die waarde wat hoger.Met zo'n grote speaker en klankkast past het geluid goed bij zo'n grote loc.
Zo te zien heb je op rechts nog ruimte voor een extra Elco. Hoe groter (de gezamenlijke) capaciteit is, hoe minder gevoelig de loc straks is voor onderbrekingen in de stroomopname.
Misschien alleen nog die 5 seconden opstart-tijd er af halen?
Ik zet binnenkort even de procedure en bijbehorende bestanden hier.
Domme vraag: zitten er in afgedankte smartphones ook geen hele kleine luidsprekertjes? Meestal zijn die ook nog van heel behoorlijke kwaliteit.
#define Ruispin 0 // pin voor aansturen van speaker: pin 1 of 0 (0 = 5 sec. vertraging)
#define rijpin1 1 // rijstroom meting
#define rijpin2 2 // rijstroom meting
vervangen door#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
Domme vraag: zitten er in afgedankte smartphones ook geen hele kleine luidsprekertjes? Meestal zijn die ook nog van heel behoorlijke kwaliteit.
Ik denk dat ik die 5 sec. maar voor lief neem :-\ :( Ik vind het al knap van mij zelf dat ik tot hier gekomen ben.Mee eens, Pierre. Dan alleen nog een grotere Elco er op, zou ik zeggen....
Zo te zien zetten die pulsbreedte regelaars alles om naar (ik denk) 12V, ook als de ingangsspanning 15V is. Als dat zo is, dan hoef je verder niets te veranderen. Dan kun je de 15V trafo's gewoon gebruiken, want de uitgang blijft 12V met pulsbreedte.
Tenminste, als het werkt zoals ik verwacht...
Even afwachten....
Als de ingangsspanning 9 Volt is komt er 13 Volt uit. Stop ik er 12 Volt in dan komt er 16 Volt uit. Ik heb nu twee regelaars gebouwd en op een gezamenlijke voeding van 9 Volt gezet. Dit werkt en de DigiSpark's werken hier ook prima op. Ik denk dat ik het zo maar in mijn bedieningspaneel bouw. Op de ene regelaar moeten dan twee locs komen te lopen en de andere komt dan een pendelbaantje op voor een trammetje.In ieder geval doet-ie consequent 4V meer er uit dan er in gaat :o
Ik heb nog wel een ander klein probleempje en dat is dat het eerste gedeelte van de potmeter (10K) bijna niets doorlaat en op een kwart ineens naar 7 Volt springt. De rest gaat wel heel geleidelijk. Kan ik een andere waarde voor de potmeter nemen of is dat niet aan te raden?Deze is wat lastiger... Regelt de potmeter zelf (potmeter uitgang) wel regelmatig tussen 0 en een maximale spanning?
Ik ga hier eerst maar eens mee rijden en dan zien we verder.Dat is in ieder geval een goed idee, Pierre.
Hoe dicht zijn we bij een filmpje van een tsjoekende loc op de brug en door het station?
Als de ingangsspanning 9 Volt is komt er 13 Volt uit. Stop ik er 12 Volt in dan komt er 16 Volt uit.
Ik heb nog wel een ander klein probleempje en dat is dat het eerste gedeelte van de potmeter (10K) bijna niets doorlaat en op een kwart ineens naar 9 Volt springt. De rest gaat wel heel geleidelijk.
Op papier ziet het schema er goed uit. Kun je het volgende controleren, just to be sure: de loper van de potmeter zit aan R6 (10k) en niet per ongeluk aan R4 of R5 (4k7)?
Als dat het geval is, wat doet dan de schakeling wanneer je D1 (1N4148) verwijdert? Daardoor ontkoppel je de stroombegrenzing en kunnen we ons concentreren op de PWM schakeling.
Het ding wordt wel knap warm.Maar dan kun je die weerstand met warmte-geleidende gell op een plaatje metaal plakken.
Oplossen op de print betekent dat de eindtrap opnieuw ontworpen moet worden, en dan ben je bij deze schakeling niet ver meer van een heel nieuwe PWM regelaar.In dat geval kan ik een Arduino-gedreven motorcontroller aanbevelen - en nee, ik heb geen Arduino aandelen :D
Het ding wordt wel knap warm.Maar dan kun je die weerstand met warmte-geleidende gell op een plaatje metaal plakken.
Toch nog een vraagje Dirk. Moet ik diode D1 weer vast solderen of is dat niet nodig?