analogWrite mit float

Syntax
analogWrite(pin, pulsweite);

Kann man für "pulsweite" auch eine Variable im Dateityp float verwenden, deren Wert sich im Bereich von 0-255 bewegt?

Hintergrund. Ich will ein PWM Signal ansteigen/sinken lassen. Wie schnell es ansteigt/sinkt, ist abhängig von einem Poti. PWM Max und Min wird auch noch ermittelt. Ich möchte das ganze aber nicht Zeitabhängig machen sondern Schritt abhängig. Also z.B. ein PWMwert von 79 auf 255 ansteigen lassen in z.B. 1023 Schritten (einstellbarer Wert). Gedanke war die Differnz sozusagen in 1023 Teile zu teilen und das PWMSignal um diesen Wert Steigen zu lassen. Dieser Wert hat aber Dezimalstellen, und somit den Typ float.

Kann man den float Wert einfach in analogWrite einfügen und die Nachkommazahlen fallen einfach weg? Sprich wenn die nächste ganze Zahl erreicht ist, ändert sich erst der Analogwrite ausgabe wert am Pin?

Oder muss man den floatwert vorher noch in einen anderen Dateityp ändern?

Ich hoffe ich habe das relativ verständlich erklärt.

Nein, da geht nur ein Ganzzahlwert zwischen 0 und 255.

Gruß Tommy

Ok, also muss ich den Wert vorher ändern bzw. runden.

Danke

Kann man den float Wert einfach in analogWrite einfügen und die Nachkommazahlen fallen einfach weg? Sprich wenn die nächste ganze Zahl erreicht ist, ändert sich erst der Analogwrite ausgabe wert am Pin?

Ja, das geht!

analogWrite(5,44.1234);

Es wird automatisch konvertiert.

Merke: Impliziter Cast

Oder muss man den floatwert vorher noch in einen anderen Dateityp ändern?

Wäre schon ok, wenn man das tut.
Dann steht wenigstens im Quelltext, dass du das wirklich absichtlich machst und es nicht nur eine Dummheit ist.

float beispiel = 47.11;
analogWrite(5,byte(beispiel));

Merke: Expliziter Cast


Meine Glaskugel sagt:
In Wirklichkeit suchst du map() und constrain() !

Danke, ja map() ist mir bekannt.

Mit constrain() begrenzt man ja Werte, richtig?

Ich wurschtel mich noch durch die deutsche arduino refernce ^^

Im Grunde geht es um den Schaltplan im Anhang und ein Sketch dazu. Es gibt schon ein Sketch dazu vom Verfasser. Nur der Durchblick durch den Sketch ist mir noch nicht wirklich gelungen. Ist ziemlich verschachtelt. Da der Sketch Grundlegend Funktioniert, aber nicht das Ergebnis bringt was ich gern hätte, und ich mir denke, wenn ich ein Sketch von Grund auf neu schreibe, der Lerneffekt größer ist, habe ich mich dazu entschieden.

Orginal Sketch:

int GBM_analog = 3; // Eingang GBM-Sensordioden
int Vr_analog = 0; // Eingang heruntergeteilte (5:1)Istspannung im Bereich
int Vf_analog = 1; // Eingang heruntergeteilte (5:1)Fahrspannung
int Zeit_analog = 2; // Eingang Zeiteinstellung 0..1023 für max. 10,23 sec!
int Vmin_analog = 4; // Eingang Poti Sollwert der Mindestspannung (0..5V)

int PWM = 9; // PWM-Ausgang
int Block_Besetzt = 10; // Meldeausgang, 0 = BESETZT, 1 = FREI
int Stelleingang = 11; // Stelleingang für Signal, 0 = ROT, 1 = GRÜN
int Signal = 5; // Stellausgang für Relais, 0 = ROT, 1 = GRÜN

float GBM_Volt=0;
float GBM = 0;
float Zeit_sec = 0;
float Zeit =0;
float Vf_volt = 0;
float Vf =0;
float Vr =0;
float Vr_volt =0;
float Vmin =0;
float Vmin_volt =0;
float Inkrement =0;
float Inkrement_volt =0;
int Bremszeit = 0;
int M = 0;
int D =0;
int val =0;
int val1;
byte Merker = 0; // Hier werden Zustandsmerker gespeichert
/* Bit 0 = 1 Zug vor dem Signal (Schritt1)
 * Bit 1 = 1 Bremsparameter eingelesen (Schritt2)
 * Bit 2 = 1 Bremsablauf aktiv (Schritt3)
 * Bit 3 = 1 Vmin erreicht (Schritt4)
 * Bit 4 = 1 Beschleinigung auf Fahrgeschwindigkeit (Schritt5)
 * Bit 5 = 1 Umschalten während des Bremsens (Schritt6)
 * Bit 6 = 1 Ablauf zu Ende (Schritt7)
 * Bit 7 = 1 Durchfahrt ohne Aktion (Schritt8)
 */
byte Merker1 = 0; // Hilfsmerker
/* Bit 0 = 1 Geschwindigkeit vor Anfahren auf Null gesetzt
 * Bit 1 = 1 Geschwindigkeit = Minimalwert 
 */

void setup() {

 
  TCCR2B=TCCR2B&B11111000|B00000110; // Vorteiler auf 256 für ~123Hz PWM
 // Serial.begin(9600);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode( Signal, OUTPUT);
  pinMode (Block_Besetzt, OUTPUT );
  pinMode ( Stelleingang, INPUT_PULLUP );
  digitalWrite(LED_BUILTIN, LOW);
  digitalWrite (Signal, LOW );
  digitalWrite (Block_Besetzt, LOW);
  analogWrite(PWM, 0);
  Merker=0;
  Merker1=0;
  
  }



void loop() {
  
  // start
  GBM = analogRead (GBM_analog);
  val1=digitalRead(Stelleingang);
  // Schrittkette starten
  // Start entweder von 0  oder Schritt 7,8 aus
  if ((GBM > 100)&&(val1==0)&&((Merker == 0)||(bitRead(Merker,6)==1)||(bitRead(Merker, 7)==1))){
    bitSet(Merker,0); // Schritt1
    bitClear (Merker,6); // Schritt 7 löschen
    bitClear(Merker,7); // Schritt 8 löschen
    }
  if((GBM < 100)&&(val1==0)&&((Merker == 0)||(bitRead(Merker,6)==1)||(bitRead(Merker, 7)==1))){
    bitSet(Merker,1); // Schritt2
    bitClear (Merker,6); // Schritt 7 löschen
    bitClear(Merker,7); // Schritt 8 löschen
    }
  if((bitRead(Merker,1)==1)&&(GBM> 100)){
    bitSet(Merker,2); // Schritt 3
    bitClear(Merker,1); // Schritt 2 löschen
    }
 if ((bitRead(Merker,2)==1)&&(bitRead(Merker1,1)==1)){
    bitSet(Merker,3); // Schritt 4
    bitClear(Merker,2); // Schritt 3 löschen
    bitClear(Merker1,1);
    }
 if ((val1==1)&&(val > Vmin_volt)&&(bitRead(Merker, 2)==1)){
    bitSet(Merker,5); // Schritt6
    bitClear(Merker, 2); // Schritt 3 löschen
    }
 if ((val1==1)&&((bitRead(Merker,0)==1)||(bitRead(Merker,3)==1))){
    bitSet(Merker, 4); // Schritt 5
    bitClear(Merker,0); // Schritt 1 löschen
    bitClear(Merker, 3); // Schritt 4 löschen
    }
  if((val>=225)&&(GBM<100)&&((bitRead(Merker,4)==1)||(bitRead(Merker,5)==1))){
    bitSet(Merker,6); // Schritt 7
    bitClear(Merker,4); // Schritt 5 löschen
    bitClear(Merker,5); // Schritt 6 löschen
    bitClear(Merker1,0); //Hilfsmerker  in Schritt 5 löschen
    }
  if(((Merker==0)||(bitRead(Merker,6)==1))&&(val1==1)){
    bitSet(Merker,7); // Schritt 8
    bitClear(Merker,6); // Schritt 7 löschen
    }


  // ab hier die zugehörigen Aktionen

  if (bitRead(Merker,0)==1){ // Zug vor Signal bei Systemstart
    digitalWrite(Block_Besetzt, LOW);
    Vf=analogRead(Vf_analog);
    Zeit = analogRead(Zeit_analog);
    val =0;
    D=Vf*5;
    analogWrite(PWM, val);
    digitalWrite(Signal,LOW );
    if (Zeit !=0)M = D/Zeit;
    else M = 0;
    Inkrement=M*2.5; 
    D = 0;   
  }
  
  if (bitRead(Merker,1)==1){ // leerer Anhaltebereich und Stelleingang = LOW
    digitalWrite(Block_Besetzt, HIGH);
    digitalWrite(Signal, LOW);
    analogWrite( PWM, 225);
    delay(100);
    Vmin = analogRead(Vmin_analog);
    Vr = analogRead( Vr_analog);
    Vr=Vr*5;
    Zeit = analogRead(Zeit_analog);
    if (Zeit !=0)M = (Vr-Vmin)/Zeit;
    else M = 0;
    Inkrement = M*2.5;
    Vf=analogRead(Vf_analog);
    Vmin_volt = 75*Vmin/Vf;
    D =0;
    val = 225 ;
    }
     
  if (bitRead(Merker,2)==1){ // GBM spricht an und Signal = Rot
      digitalWrite(LED_BUILTIN, HIGH); // Anzeige Zeit läuft
      while(val > Vmin_volt){
        Vr=analogRead(Vr_analog);
        Vr=Vr*5;
        if((Vr-Vmin)<=Vmin/5) D=D+Inkrement/5;
        else D = D + Inkrement;
        val = 225-D;
        analogWrite( PWM, val);
        delay (100);
        }
      bitSet(Merker1,1);
      val =Vmin_volt;
      analogWrite(PWM, val);
      digitalWrite(LED_BUILTIN, LOW);
    }

    
     
  if( bitRead(Merker,4)==1){ // Stelleingang = HIGH und Zug vor Signal
      digitalWrite(Signal, HIGH);
      digitalWrite(LED_BUILTIN, HIGH); // Anzeige Zeit läuft
      if(bitRead(Merker1,0)==0){
        analogWrite(PWM,0 );
        val = val/2;
        bitSet(Merker1,0);
      }
          
      while(val < 225){
       Vf=analogRead(Vf_analog);
       Vr=analogRead(Vr_analog);
        if((Vf-Vr)<=Vf/5) D=D+Inkrement/5;
        else D = Inkrement;
        val = val+D;
        analogWrite( PWM, val);
        delay (100);
        }
    analogWrite(PWM, 225);
    digitalWrite(LED_BUILTIN, LOW);
    }

 if (bitRead(Merker,5)==1){
    digitalWrite(Signal, HIGH);
    while(val < 225){
        Vf=analogRead(Vf_analog);
        Vr=analogRead(Vr_analog);
        if((Vr-Vf)<=Vf/5) D=D+Inkrement/5;
        else D = Inkrement;
        val = val+D;
        analogWrite( PWM, val);
        delay (100); 
      }
     val =225;
     analogWrite(PWM, val);
   }
     
 if ((Merker,6)==1){
    digitalWrite(Block_Besetzt,HIGH);
    bitClear(Merker1,0);
 }
  
 if (bitRead(Merker,7)==1){ // Stelleingang= HIGH  
    digitalWrite(Signal, HIGH);
    analogWrite( PWM, 225);
    if (GBM>100) digitalWrite(Block_Besetzt,LOW);
    else digitalWrite(Block_Besetzt, HIGH);
    }
         
//endloop  
}

Da ich die 9k Zeichen überschritten habe, gehts hier weiter. Und 5 Minuten muss ich auch noch warten o.O

...

Und das was ich mir jetzt runtergeschrieben habe

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
  VBlock = map(analogRead(VBlockPin), 0, 1023, 0, 2500); // Blockspannung 0-2500 für 0,00-25,00V
  VMin = map(analogRead(VMinPin), 0, 1023, 0, 500); // Mindestspannung 0-500 für 0,00-5,00V
  if (VMin > VFahr) VMin = VFahr; // Wenn die Mindestspannung größer als die Fahrspannung ist, dann ist die Mindestspannung  gleich der Fahrspannung
  BremsZeit = analogRead(BremsZeitPin); // Bremszeit/Weg Einstellung, 0-1023, je größer der Wer, des so größer der Bremsweg bzw. die Bremszeit
  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
  inkr = (VFahr-VMin)/BremsZeit; // Schrittweite zur Verringerung/Erhöhung des PWM Signals
  
  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
    if (VMin>VBlock) VBlock = VMin; // Blockspannung auf mindestens Mindestspannung setzen
    VBlock = VBlock + inkr; // Blochspannung um die Schrittweite Erhöhen
    PWMcur = map(VBlock,0,VFahr,0,255); // Blockspannung in PWM umrechnen
    if (PWMcur > PWMmax) PWMcur = PWMmax; // PWMcur auf PWMmax begrenzen
    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
    if (VMin>VBlock) VBlock = VMin; // Blockspannung auf mindestens Mindestspannung setzen
    VBlock = VBlock - inkr; // Blochspannung um die Schrittweite Verringern
    PWMcur = map(VBlock,0,VFahr,0,255); // Blockspannung in PWM umrechnen
    if (PWMcur < PWMmin) PWMcur = PWMmin; // PWMcur auf PWMmin begrenzen
    digitalWrite(MelAusgPin, LOW); // Meldet vorherigem Block "BESETZT"
  }
  analogWrite(PWMPin, PWMcur); //schreibt den PWMWert an den Ausgangspin
  delay(100);
}

Zum testen komme ich jetzt gerade nicht, da ich im Moment kein Zugang zur MoBa habe. Also reine Theorie.

Wo ich mir nicht ganz sicher bin, ob man analogRead() direkt in der Map nutzen kann.

Entschuldigt die vielen Kommentare, aber die helfen mir persönlich sehr.

Die Überprüfung in der IDE (Rechts oben der Haken) zeigt kein Fehler, was aber nicht heist das es funktioniert. Wenn jemand was sieht, was man so nicht machen kann oder sollte, bin ich für Hinweise dankbar.

Aber ich Schweife sehr von der Eigentlich Frage ab ins sogenannte OffTopic.

Danke

Edit:
Und in der Wanne ist mir noch ein Fehler aufgefallen. Den VBlock Wert muss ich natürlich noch aufs PWM Signal "mapen" (sagt man das so?) Weis nur noch nicht wie ich das mache, da der VBlock wert in map() zu starkt "gerundet" wird. Wahrscheinlich wie weiter oben durch 100 bzw. jetzt mal 100. muss ich mir nochmal überlegen

Edit2: Hab den Code angepasst. Denke so sollte es funktionieren.

Ich möchte das ganze aber nicht Zeitabhängig machen sondern Schritt abhängig. Also z.B. ein PWMwert von 79 auf 255 ansteigen lassen in z.B. 1023 Schritten (einstellbarer Wert). Gedanke war die Differnz sozusagen in 1023 Teile zu teilen und das PWMSignal um diesen Wert Steigen zu lassen. Dieser Wert hat aber Dezimalstellen, und somit den Typ float.

Da die PWM Ausgänge des Arduino UNO / MEGA2560 eine 8 bit Auflösung haben, hat es keinen Sinn, kleinere Schritte als 1 ausgeben zu wollen.
Bei einem Bereich von 79 bis 255 machst Du am besten 176 Schritte zu 1.

Wenn Du mehr Auflösung willst, brauchst Du einen anderen PWM Controller mit mehr Auflösung wie zB den PCA9685 der 12 Bit hat (= 0 bis 4095) .
zB Adafruit 16-Channel 12-bit PWM/Servo Driver - I2C interface [PCA9685] : ID 815 : $14.95 : Adafruit Industries, Unique & fun DIY electronics and kits
Grüße Uwe

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.

uwefed:
Da die PWM Ausgänge des Arduino UNO / MEGA2560 eine 8 bit Auflösung haben

Das liegt aber nur an der Arduino IDE und daran dass man die Auflösung aller Ausgänge vereinheitlichen wollte.

Wenn man es per Hand macht sind da auch 9, 10 oder gar 16 Bit möglich

Kannst Du mal einen Tip geben, auf welchen Prozessoren und welchen Ausgängen?
Ich weiß: Datenblatt lesen. aber wenigsten ein Tipp - welches Datenblatt :wink:

Gruß Tommy

Tommy56:
Kannst Du mal einen Tip geben, auf welchen Prozessoren und welchen Ausgängen?

Die 16Bit Timer der AVR können das.

Danke.

Gruß Tommy

Tommy56:
Kannst Du mal einen Tip geben, auf welchen Prozessoren und welchen Ausgängen?

Alle 16 Bit Timer können logischerweise mehr als 8 Bit :slight_smile:
Davon gibt es auf dem Uno einen (mit 2 Ausgängen) und auf dem Mega 4 (mit je 3 Ausgängen)

Auch Dir vielen Dank.
Dann werde ich mal die Datenblätter flöhen, wenn ich Zeit habe - was bei (fast) Rentnern ein Problem ist.

Gruß Tommy

Ich möchte jetzt nicht extra ein neuen Thread aufmachen für eine neue Frage. Oder ist es eher gewünscht dazu einen neuen Thread zu eröffnen?

In dem Code lese ich ja aus, ob der Meldeeingang Low oder High ist.

...
const int MelEingPin = 11; // Pin SignalEingang vom folgenden Block 0 = BESETZT, 1 = FREI
...
...
void setup () {
...
pinMode(MelEingPin, INPUT_PULLUP);
...

Dies übergebe ich einer Variable

...
Void loop () {
...
Melder = digitalRead(MelEingPin); // 0 = Folgender Block besetzt, 1 = Folgender Block Frei
...

Dann setzte ich mit einer if Abfrage einen Ausgang auf High oder Low

...
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
...

Jetzt kam mir die Idee, warum erst einer Variable übergeben. Geht folgender Code?

digitalWrite(SignalPin,digitalread(MelEingPin);

Dann könnte ich mir die Variable "Melder" sparen.

  • Kompletter Code ein paar antworten weiter oben.

Geht folgender Code?

Natürlich!

Warum probierst du das nicht selber aus?

Der Arduinos und das Shield sind gut 10km entfernt. Ich versuche nur in der Zwischenzeit, bis ich wieder zugriff habe, etwas mein Wissensstand zu erweitern.

Danke.