Aansturing LGB Noordpool Express (PBM)

Toon hier Uw afgeronde projecten aan anderen.
Gebruikers-avatar
Berichten: 4
Geregistreerd: 25 Sep 2022, 16:39
Woonplaats: Geldrop

Aansturing LGB Noordpool Express (PBM)

Berichtdoor franspbm » 27 Sep 2022, 13:19

/* Aansturing LGB Noordpool Express
Eisen:
de trein moet zelfstandig kunnen rijden
de trein moet een willekeurige snelheid kunnen kiezen
bij een bepaalde snelheid moet een willekeurige rijtijd gekozen worden
de trein moet willekeurig voor en achteruit rijden in verhouding 9:1
versnellingen en vertragingen moeten geleidelijk gaan

Spanning LGB 18V
Omdat de locomotief bij lage spanning kracht verliest kies ik de snelheid te regelen met PBM

Materiaal
Arduino NANO
L298N motordriver
voeding 18V -> 5V
potmeter 2x 10K
schakelaar handbediening
schakelaar aan/uit
draadklemmetjes voor spoorspanning
plug 18V invoer

Standaardfrequentie Timer 2 is 490 Hz
Indien we een trein laten rijden met 490 Hz geeft dit een hinderlijk geluid.
Een frequentie boven de gehoorgrens werkt niet goed.
Een goede frequentie (voor mijn locomotief) ligt tussen de 30 en 130 Hz.
Arduino geeft de mogelijkheid de PBM frequentie aan te passen. Zie setup.

In handbediening kan een goede verhouding frequentie / snelheid gevonden worden

Handige links
https://www.arduino.cc/
https://docs.arduino.cc/tutorials/gener ... rduino-pwm
http://www.righto.com/2009/07/secrets-o ... o-pwm.html
https://www.sparkfun.com/datasheets/Com ... ega328.pdf
*/


int L298N_EN1 = 7; // output pin naar driver
int L298N_EN2 = 8; // output pin naar driver
int treinRichting = 0;
int x = 0; // teller
int y = 0; // teller
int z = 0; // teller

int rijrichtingOud = 0; // richting oud
int rijrichtingNeo = 0; // richting
int snelheidOud = 0; // snelheid oud
int snelheidNeo = 0; // snelheid
int snelheidMinimum = 15; // duty cycle 15%

int rijtijd = 0; // rijtijd trein
int vs = 50; // vertraging/versnelling in miliseconden
int PWMpin = 3; // timer 2 pin
int schakelaar = 2; // automatisch / handbediening

int maximunFrequentie = 60; //130 Hz PWM
int minimumFrequentie = 250; //31 Hz PWM

int snelheidPot = 0; // handbediening snelheid
int frequentiePot = 0; // instellen PWM frequentie
int frequentie = 0;

void setup()
{
Serial.begin(9600);
randomSeed(analogRead(7));
pinMode(L298N_EN1, OUTPUT);
pinMode(L298N_EN2, OUTPUT);
pinMode(PWMpin, OUTPUT);
pinMode(schakelaar, INPUT_PULLUP);

//Initialisatie Timer2
TCCR2A = 0;
TCCR2B = 0;
TCNT2 = 0;

bitSet(TCCR2A, COM2B1); //00100000 controle over output frequentie

// Set mode 5-- Fast PWM 8 bits (0-255)
bitSet(TCCR2A, WGM20); // 00000001
bitSet(TCCR2B, WGM22); // 00001000

// Setup /1024 prescale (16.000.000 / 1024 = 15.625 Hz)
bitSet(TCCR2B, CS20); // 000000001
bitSet(TCCR2B, CS21); // 000000010
bitSet(TCCR2B, CS22); // 000000100

// TCCR2A > 00100001
// TCCR2B > 00001111

// voorbeeld
OCR2A = 78; // zet freq 100Hz
// timer 2 telt 156 keer op en neer
// 15.625 / 156 = 100 Hz (bij benadering)

OCR2B = 38; // 50% duty cycle
// OCR2B bepaald de duty cycle
// feldige waardes bij OCR2A van 78 = 0-77
}

void loop()
{
rijrichtingOud = rijrichtingNeo;
snelheidOud = snelheidNeo;

frequentiePot = analogRead(A0);
frequentie = map(frequentiePot, 0, 1024, maximunFrequentie, minimumFrequentie);
OCR2A = frequentie;

if (digitalRead(schakelaar) == HIGH) // automatisch rijden
{
rijrichtingNeo = random(10);
if (rijrichtingNeo > 0) rijrichtingNeo = 1; // vooruit

snelheidNeo = random(snelheidMinimum, frequentie);
rijtijd = random(5, 20);
rijtijd = rijtijd * 1000; // seconden
}
else // handbediening
{
rijrichtingNeo = 1; // vooruit
rijtijd = 250;
snelheidPot = analogRead(A1);
snelheidNeo = map(snelheidPot, 0, 1024, snelheidMinimum, frequentie);
}

if (snelheidNeo < snelheidMinimum - 1) snelheidNeo = 0;
print1();
trein();
}

void trein()
{
if (rijrichtingOud != rijrichtingNeo) stopTrein();
if (snelheidOud < snelheidNeo) versnel();
if (snelheidOud > snelheidNeo) vertraag();
rijConstant();
}

void stopTrein()
{
Serial.println("trein stopt");
Serial.print("langzamer: ");
{
// rem snelheid af
for (x = snelheidOud; x > 0; x = x - 1)
{
OCR2B = x;
Serial.print(x); Serial.print(" ");
delay(vs);
}
}
OCR2B = 0;
Serial.println(); Serial.println("---X trein gestopt");
delay(2000);

if (rijrichtingNeo == 1)
{
Serial.println("---> trein vooruit");
digitalWrite(L298N_EN1, HIGH);
digitalWrite(L298N_EN2, LOW);
}
if (rijrichtingNeo == 0)
{
Serial.println("<--- trein achteruit");
digitalWrite(L298N_EN1, LOW);
digitalWrite(L298N_EN2, HIGH);
}
snelheidOud = snelheidMinimum;
}

void rijConstant()
{
// rijd "rijtijd" seconden met constante snelheid
OCR2B = snelheidNeo;
delay(rijtijd);
}

void versnel()
{
Serial.print("sneller: ");
// voer snelheid op
for (x = snelheidOud; x < snelheidNeo; x = x + 1)
{
OCR2B = x;
Serial.print(x); Serial.print(" ");
delay(vs);
}
Serial.println();
}

void vertraag()
{
Serial.print("langzamer: ");
// rem snelheid af
for (x = snelheidOud; x > snelheidNeo; x = x - 1)
{
OCR2B = x;
Serial.print(x); Serial.print(" ");
delay(vs);
}
Serial.println();
}

void print1()
{
Serial.println();
int temp = map(frequentie, maximunFrequentie, minimumFrequentie, 130, 31);
Serial.print("frequentie: ");
Serial.println(temp);

Serial.print("treinrichting: ");
if (rijrichtingNeo == 1) Serial.println("vooruit");
if (rijrichtingNeo == 0) Serial.println("achteruit");

Serial.print("treinsnelheid: ");
Serial.println(snelheidNeo);

Serial.print("rijtijd: ");
Serial.print(rijtijd / 1000);
Serial.println(" seconden");
}

Advertisement

Berichten: 3878
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Aansturing LGB Noordpool Express (PBM)

Berichtdoor shooter » 02 Okt 2022, 20:51

ik zie een paar delay dingen staan en dat is niet slim want dan stopt de invoer bijv maar ook allerlei tijd dingen ik zou dus als voeding een schakel IC gebruiken die netjes 5 Volt maakt voor je arduino die dus wel zker 20 Volt aankan en onstoort is voor pulsen
ook de motor zal een paar condensatoren en gelijkrichters nodig hebben. denk ook aan verlichting en bijvoorbeeld een waarschuwingslicht.
mooi projekt trouwens om met afstanbediening je trein te besturen.
paul deelen
shooter@home.nl

Gebruikers-avatar
Berichten: 4
Geregistreerd: 25 Sep 2022, 16:39
Woonplaats: Geldrop

Re: Aansturing LGB Noordpool Express (PBM)

Berichtdoor franspbm » 02 Okt 2022, 21:40

Dank voor je opmerkingen.
Als voeding voor de NANO gebruik ik een geschakelde DC naar DC module die kan worden gevoed met 5-38V en 5A kan leveren. Lichtelijk overdreven voor de NANO maar och...
Uitbreiding van dit project komt met een nieuw project om de trein met bluetooth aan te sturen en dan verdwijnen de delays zeker; de trein hoeft nu alleen maar zelfstandig rondjes onder de kerstboom te rijden zonder additionele invoer.
Ik moet zeggen dat de programmatuur veel eenvoudiger kan maar het manipuleren en daarmee het begrip van Timers in de ATMega328 is voor mij de hoofdzaak van dit project.

Gebruikers-avatar
Berichten: 4
Geregistreerd: 25 Sep 2022, 16:39
Woonplaats: Geldrop

Re: Aansturing LGB Noordpool Express (PBM)

Berichtdoor franspbm » 03 Okt 2022, 10:05

Manipulatie van Timer2

Normaal rijdt de trein omdat er een spanning van 0V tot (in mijn geval) 18V op de rails staat. Bij 0V staat de train stil. Bij 18V is de snelheid maximaal. Het nadeel is dat de train bij lage snelheid ook aan kracht verliest.
Wat ik doe is een continu spanning van 18V op de rails zetten, alleen niet constant. Door een blokspanning van 18V met een bepaalde duty cycle op de rails te zetten kan de snelheid van de train worden aangepast. Bij b.v. een duty cycle van 50% rijdt de train op halve snelheid.

Timer2 van de ATMega328 kan een blokspanning genereren . Dit doet hij standaard met een frequentie van 490Hz. Door mij onbekende oorzaak (resonantie of iets dergelijks) is die freq in de trein hoorbaar.
De freq en de duty cycle van de Timer is onafhankelijk van elkaar aan te passen. (Overigens functioneren Timers buiten de CPU om. Ze gebruiken dus geen CPU-tijd.) De freq van Timer2 wordt in eerder plaats bepaald door de prescaler (CS20, CS21 en CS22) in TCCR2B en in de tweede plaats met de waarde van OCR2A.

OCR2A:
In mode 5 telt de Timer van 0-255 en weer terug van 255-0.
De freq = 16.000.000 / (N x 510). N is de prescaler (in mijn gevanl 1024)
Bereikt de Timer de waarde van OCR2A dan telt hij van daar weer terug. Hoe lager de waarde in OCR2A hoe hoger de freq van de Timer. De waarde van OCR2A kan dus variëren van 0-255
De freq van de Timer2 kan zichtbaar worden gemaakt op OC2A (pin 11)

OCR2B:
De duty cycle wordt beïnvloed door OCR2B.
Bereikt de Timer tijdens het omhoog tellen de waarde van OCR2B dan wordt OC2B (pin 3) laag.
Bereikt de Timer tijdens het omlaag tellen de waarde van OCR2B dan wordt OC2B (pin 3) Hoog.
De waarde van OCR2B kan dus variëren van 0-OCR2A

Dit is in ieder geval wat ik snap van Timer2. Indien iemand aanvullingen heeft of vragen hoor ik het graag.

Gebruikers-avatar
Berichten: 4
Geregistreerd: 25 Sep 2022, 16:39
Woonplaats: Geldrop

Re: Aansturing LGB Noordpool Express (PBM)

Berichtdoor franspbm » 05 Okt 2022, 13:47

Manipulatie van Timer2
Normaal rijdt de trein omdat er een spanning van 0V tot (in mijn geval) 18V op de rails staat. Bij 0V staat de train stil. Bij 18V is de snelheid maximaal. Het nadeel is dat de train bij lage snelheid ook aan kracht verliest.
Wat ik doe is een continu spanning van 18V op de rails zetten, alleen niet constant. Door een blokspanning van 18V met een bepaalde duty cycle op de rails te zetten kan de snelheid van de train worden aangepast. Bij b.v. een duty cycle van 50% rijdt de train op halve snelheid.

Timer2 van de ATMega328 kan een blokspanning genereren . Dit doet hij standaard met een frequentie van 490Hz. Door mij onbekende oorzaak (resonantie of iets dergelijks) is die freq in de trein hoorbaar.
De freq en de duty cycle van de Timer is onafhankelijk van elkaar aan te passen. (Overigens functioneren Timers buiten de CPU om. Ze gebruiken dus geen CPU-tijd.) De freq van Timer2 wordt in eerder plaats bepaald door de prescaler (CS20, CS21 en CS22) in TCCR2B en in de tweede plaats met de waarde van OCR2A.

OCR2A:
In mode 5 telt de Timer van 0-255 en weer terug van 255-0.
De freq = 16.000.000 / (N x 510). N is de prescaler (in mijn gevanl 1024)
Bereikt de Timer de waarde van OCR2A dan telt hij van daar weer terug. Hoe lager de waarde in OCR2A hoe hoger de freq van de Timer. De waarde van OCR2A kan dus variëren van 0-255
De freq van de Timer2 kan zichtbaar worden gemaakt op OC2A (pin 11)

OCR2B:
De duty cycle wordt beïnvloed door OCR2B.
Bereikt de Timer tijdens het omhoog tellen de waarde van OCR2B dan wordt OC2B (pin 3) laag.
Bereikt de Timer tijdens het omlaag tellen de waarde van OCR2B dan wordt OC2B (pin 3) Hoog.
De waarde van OCR2B kan dus variëren van 0-OCR2A

Dit is in ieder geval wat ik snap van Timer2. Indien iemand aanvullingen heeft of vragen hoor ik het graag.

Terug naar Afgeronde projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 2 gasten