Ich hatte es mir so gedacht, das der PWM Wert erst nach ein paar Durchläufen der Schleife steigt. Halt immer wenn erst wenn die nächste ganze Zahl erreicht ist. Die Auflösung der PWM spielt da eigentlich nicht so eine große Rolle bzw. mit einer Auflösung von 255 ausreichend.
Es ging halt darum das sich der Bremsweg nicht ändert, wenn man die Fahrspannung oder die Mindestspannung ändert. Der Bremsweg würde bei gleichem Zug immer relativ gleich bleiben.
Aber ich habe mir das mal beispielhaft durchgerechnet. Und 1023 Schritte für den Bremsweg(Zeit) sind zu Fein. Man müsste den Poti schon sehr weit runter drehen um sichtbare Ergebnisse zu erziehlen. Wenn ich die Schritte auf ein 10tel reduziere, komme ich bei 16V Fahrspannung und 5V Mindestspannung, auf eine Bremszeit von ~8,8s, und das ist schon eine Ordentliche Strecke die der Zug in der Zeit zurücklegt. Beim reduzieren des Wertes erreicht man dann ordentliche Bremsstrecken.
Hier der Code mit Anpassung und der Beispielrechnung:
const int GBMPin = 3; //Pin Eingang GleisBesetztMelder Sensordioden
const int VFahrPin = 1; // Pin Eingang heruntergeteilte ~(5:1)Fahrspannung
const int VBlockPin = 0; // Pin Eingang heruntergeteilte ~(5:1)Blockspannung
const int VMinPin = 4; // Pin Eingang PotiWert für Mindestspannung 0-5V
const int BremsZeitPin = 2; // Pin Eingang PotiWert für Bremsweg/Bremszeit
const int MelEingPin = 11; // Pin SignalEingang vom folgenden Block 0 = BESETZT, 1 = FREI
const int MelAusgPin = 10; // Pin SignalAusgang zum vorherigen Block 0 = BESETZT, 1 = FREI
const int PWMPin = 9; // Pin Ausgang für das PWM-Signal
const int SignalPin = 5; // Pin Ausgang zum Steuern des Relais für Signal und Halteabschnitt, 0 = ROT, 1 = GRÜN
float VFahr = 0; // Variable für eingelesene Fahrspannung
float VMin = 0; // Variable für eingelesene Mindestspannung
float VBlock = 0; // Variable für eingelesene Blockspannung
int PWMmin = 0; // Variable für den Mindest PWM-Wert
int PWMmax = 255; // Variable für den Maximalen PWM-Wert
int PWMcur = 0; // Variable für aktuellen PWM-Wert als ganze Zahl
int GBM = 0; // Variable für GBM
int BremsZeit = 0; // Variable für Bremsweg/Zeit
int Melder = 0; // Variable für den Meldeeingang vom folgenden Block
float inkr = 0; // Variable für die Schrittweite der Erhöhung/Verringerung der PWM
void setup() {
TCCR2B=TCCR2B&B11111000|B00000110; // Vorteiler auf 256 für ~123Hz PWM
//Serial.begin(9600);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(SignalPin, OUTPUT);
pinMode(MelAusgPin, OUTPUT);
pinMode(MelEingPin, INPUT_PULLUP);
digitalWrite(LED_BUILTIN, LOW);
digitalWrite(SignalPin, LOW);
digitalWrite(MelAusgPin, LOW);
analogWrite(PWMPin, 0);
}
void loop () {
GBM = analogRead(GBMPin); // Wert über 100, Gleis Besetzt, unter 101, Gleis Frei
VFahr = map(analogRead(VFahrPin), 0, 1023, 0, 2500); // Fahrspannung 0-2500 für 0,00-25,00V // BSP: 1600
VBlock = map(analogRead(VBlockPin), 0, 1023, 0, 2500); // Blockspannung 0-2500 für 0,00-25,00V // BSP: 1600
VMin = map(analogRead(VMinPin), 0, 1023, 0, 500); // Mindestspannung 0-500 für 0,00-5,00V // BSP: 500
if (VMin > VFahr) VMin = VFahr; // Wenn die Mindestspannung größer als die Fahrspannung ist, dann ist die Mindestspannung gleich der Fahrspannung // pasiert wenn man den Fahrregler unter die Mindestspannung regelt
BremsZeit = analogRead(BremsZeitPin)/10; // Bremszeit/Weg Einstellung, 0-102, je größer der Wert, des so größer der Bremsweg bzw. die ralative Bremszeit // BSP: 102
Melder = digitalRead(MelEingPin); // 0 = Folgender Block besetzt, 1 = Folgender Block Frei
PWMmin = map(VMin,0, VFahr, 0, 255); // Mindest PWM-Signal analog zur Eingestellten Mindestspannung in Abhängigkeit zur Fahrspannung // BSP: 500, 0, 1600, 0, 255 -> 79.68... -> 79
inkr = (VFahr-VMin)/BremsZeit; // Schrittweite zur Verringerung/Erhöhung des PWM Signals // BSP: 1600-500 -> 1100/25 -> 44
VBlock = constrain(VBlock,VMin,VFahr); // Blockspannung auf den Bereich zwischen Mindestspannung und Fahrspannung begrenzen //BSP: 1600
if (Melder == 1) digitalWrite(SignalPin, HIGH); // Wenn folgender Block Frei meldet, setze Halteabschnitt und Signal auf Fahrt
else digitalWrite(SignalPin, LOW); // ansonsten setze Halteabschnitt und Signal auf Halt
if (GBM <= 100) { // Wenn sich kein Zug im Block befindet,
PWMcur = PWMmax; // ist die Blockspannung gleich Maximale Spannung im Block
digitalWrite(MelAusgPin, HIGH); // Meldet vorherigem Block "FREI"
}
if ((GBM > 100) && (Melder == 1)) { // Wenn sich ein Zug im Block befindet und der Folgende Block "FREI" ist
VBlock = VBlock + inkr; // Blockspannung um die Schrittweite Erhöhen // BSP: 1600+44 -> 1644
VBlock = constrain(VBlock,VMin,VFahr); // Blockspannung auf den Bereich zwischen Mindestspannung und Fahrspannung begrenzen // BSP: -> 1600
PWMcur = map(VBlock,0,VFahr,0,255); // Blockspannung in PWM umrechnen // BSP: 1600, 0, 1600, 0, 255 -> 255
if (PWMcur > PWMmax) PWMcur = PWMmax; // PWMcur auf PWMmax begrenzen // BSP: 255
digitalWrite(MelAusgPin, LOW); // Meldet vorherigem Block "BESETZT"
}
if ((GBM > 100) && (Melder == 0)) { // Wenn sich ein Zug im Block befindet und der Folgende Block "BESETZT" ist
VBlock = VBlock - inkr; // Blochspannung um die Schrittweite Verringern // BSP: 1600-44 -> 1556
VBlock = constrain(VBlock,VMin,VFahr); // Blockspannung auf den Bereich zwischen Mindestspannung und Fahrspannung begrenzen // BSP: 1556
PWMcur = map(VBlock,0,VFahr,0,255); // Blockspannung in PWM umrechnen // BSP: 1578, 0, 1600, 0, 255 -> 247.9875 -> 247
if (PWMcur < PWMmin) PWMcur = PWMmin; // PWMcur auf PWMmin begrenzen // BSP: 247 // würde bei einem delay(100) ungefähr 2.2s dauern bei der eingestellten Fahrspannung und Mindestspannung
digitalWrite(MelAusgPin, LOW); // Meldet vorherigem Block "BESETZT"
}
analogWrite(PWMPin, PWMcur); //schreibt den PWMWert an den Ausgangspin
delay(100);
}
Wie schon gesagt, theoretisch, kein Zugang zur MoBa.
Habe ich das richtig heraus gelesen das constrain nicht in integer wandelt? Wäre für mich super.