Go Down

Topic: Drehscheibe Modellbahn mit RF24 (Read 3118 times) previous topic - next topic

Acki1985

Hallo alle zusammen,

das mit dem richtig habe ich manuell dazu geschrieben. Überall wo richtig dahinter steht, stimmen die Schritte und die Richtung und bei denen wo falsch dahinter steht stimmen Ricchtung und Schritte nicht.

Hat noch wer ne Idee, wie man es lösen könnte?

Acki1985

Keiner ne Idee? Es muss doch irgendwie möglich sein. Ich denke das das Problem daran liegt, dass man über Null dreht.

Acki1985

Man könnte doch auch die Richtung über die drhrichtung des encoders wählen. Dazu müsste man aber den Encoder über 0 zählen lassen können. Geht sowas und wenn ja wie könnte man das machen?

postmaster-ino

Hi

Über Null zählen ist nicht so schwer:
- wenn über 47 (Maximal-Wert -1), einfach 48 (Maximal-Wert) abziehen
- wenn unter 0 (dafür signed Typ notwendig) 48 (Maximal-Wert) addieren

Oder, ohne signed-Typ, beim Hochzählen prüfen, ob wir damit auf 48 (Maximal-Wert) kämen, ja->0, nein ->+1, beim Runterzählen, ob wir jetzt noch auf NULL sind, ja ->Maximal-Wert-1, nein -> -1.

Trotzdem muß Es gehen, daß der Arduino die richtige Richtung errechnet.
Wenn mir akut aber auch eine direkte Idee fehlt und die Zeit - da bekommen dann doch eher eigene Projekte den Vorrang.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Acki1985

#109
Jan 20, 2019, 08:32 pm Last Edit: Jan 20, 2019, 08:33 pm by Acki1985
* gelöscht mein Fehler*

Acki1985

Habe einen Weg gefunden. :-)


Code: [Select]


const byte schritte_max = 48;   //Anzahl an möglichen Anschlußpunkten

byte von;                       //Ausgangsgleis
byte nach;                      //Zielgleis

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  von = random(schritte_max) + 1;   //von und bis 'auswürfeln'
  nach = random(schritte_max) + 1;
  //  von = 19;
    //nach = 38;
  Serial.print("Von ");       // Von 1
  Serial.print(von);
  Serial.print(" nach ");     // nach 12
  Serial.println(nach);
if (von > nach){
  int schritte_links = (von - nach);
  Serial.println("Entfernung in Drehrichtung links");
  Serial.println(schritte_links);
  Serial.println(" ");
 
  int schritte_rechts = nach - von;
  Serial.println("Entfernung in Drehrichtung rechts");
  Serial.println(schritte_rechts);
  int schritte_rechts_erg = schritte_rechts + 48;
  Serial.println(schritte_rechts_erg);
  Serial.println(" ");
  if (schritte_links > schritte_rechts_erg) {
    Serial.println("Drehrichtung rechts");
   
  }
  else if (schritte_links < schritte_rechts_erg) {
    Serial.println("Drehrichtung links");
  }
}
if (von < nach) {
    int schritte_links = abs ((nach - von) -48);
    Serial.println("Entfernung in Drehrichtung links");
    Serial.println(schritte_links);
    Serial.println(" ");
    int schritte_rechts = (nach - von);
    Serial.println("Entfernung in Drehrichtung rechts");
    Serial.println(schritte_rechts);
    Serial.println(" ");
    if (schritte_links > schritte_rechts) {
      Serial.println("Drehrichtung rechts");
    }
    else if (schritte_links < schritte_rechts) {
      Serial.println("Drehrichtung links");
    }
  }

 
 
  Serial.println("-------------------------------------------------------------------------");

  delay(1000);
}




Acki1985

geht auch nicht. Schade

das kommt bei:

Von 42 nach 18
Entfernung in Drehrichtung links
24
 
Entfernung in Drehrichtung rechts
-24
24

raus.  ::)

Acki1985

Hab es rausbekommen. Er wusste nicht in welche Richtung er fahren soll, da bei Richtungen die gleiche Anzahl an Schritten hatte.

Jetzt funktioniert es.  :)

Code: [Select]



const byte schritte_max = 48;   //Anzahl an möglichen Anschlußpunkten

byte von;                       //Ausgangsgleis
byte nach;                      //Zielgleis

void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
 von = random(schritte_max) + 1;   //von und bis 'auswürfeln'
 nach = random(schritte_max) + 1;
  //von = 25;
  //nach = 1;
  Serial.print("Von ");       // Von 1
  Serial.print(von);
  Serial.print(" nach ");     // nach 12
  Serial.println(nach);
if (von > nach){
  int schritte_links = (von - nach);
  Serial.println("Entfernung in Drehrichtung links");
  Serial.println(schritte_links);
  Serial.println(" ");
 
  int schritte_rechts = nach - von;
  Serial.println("Entfernung in Drehrichtung rechts");
  Serial.println(schritte_rechts);
  int schritte_rechts_erg = schritte_rechts + 48;
  Serial.println(schritte_rechts_erg);
  Serial.println(" ");
  if (schritte_links >= schritte_rechts_erg) {
    Serial.println("Drehrichtung rechts");
   
  }
  else if (schritte_links < schritte_rechts_erg) {
    Serial.println("Drehrichtung links");
  }
}
if (von < nach) {
    int schritte_links = abs ((nach - von) -48);
    Serial.println("Entfernung in Drehrichtung links");
    Serial.println(schritte_links);
    Serial.println(" ");
    int schritte_rechts = (nach - von);
    Serial.println("Entfernung in Drehrichtung rechts");
    Serial.println(schritte_rechts);
    Serial.println(" ");
    if (schritte_links >= schritte_rechts) {
      Serial.println("Drehrichtung rechts");
    }
    else if (schritte_links < schritte_rechts) {
      Serial.println("Drehrichtung links");
    }
  }

 
 
  Serial.println("-------------------------------------------------------------------------");
 
 
  delay(1000);
}




Acki1985

Guten Abend,

Wie bekomme ich hin, dass man den Encoderwert überdrehen kann. Ich meine, das ich wenn ich den Encoder bei 48 weiter drehe dann als nächstes der Wert 1 kommt und wenn ich ihn zurück drehe der Wert 48?

Code: [Select]

void encoder_lesen () {
  messungPin1 = digitalRead(encoderPinA);
  if ((messungPin1 == LOW) && (messungPin1Alt == HIGH) && (nullStellung == true)) {
    if (digitalRead(encoderPinB) == HIGH) {
      if (encoderWert < 48) encoderWert++ ;
    } else {
      if (encoderWert > 1) encoderWert-- ;


postmaster-ino

Hi
Code: [Select]
if (encoderWert < 48) encoderWert++ ;
Hier bist Du im Bereich 'Aufwärts' - Du hast also wohl rechts herum gedreht.
Deine jetzige Abfrage fragt, ob der Wert kleiner 48 ist, wenn Das gegeben ist, zählst Du 1 hinzu.
Da Das bei 48 nicht mehr gegeben ist, kannst Du entweder einen else-Zweig machen, um dort encoderWert auf 1 zu setzen, oder Du rechnest 'mit Überlauf'.

48+1->49
49%48->1 (Modulo, Rest der Division, 49:48=1, Rest 1)

Damit Das auch 'rückwärts' klappt, musst Du '-1' addieren - dabei kannst Du aber einen Unterlauf erzeugen - dann wird Dir Modulo 48 wohl keine 47 zurück geben.
Deshalb addierst Du '48-1'.

Beim 'Hochdrehen' stur +1
Beim Runterdrehen stur +47 (=48-1)
Ein +48 wäre das Gleiche, wie ein +0, somit bekommst Du durch +47 Dein '-1', aber in die Richtung 'nach Oben'.
Nach der Addition (also +1 oder +47) erzeugst Du das Modulo:
Code: [Select]
encoderWert=encoderWert%48+1;
Hier fällt Dir wohl die +1 auf - Die brauchen wir hier, weil Dein Sketch von 1-48 'zählt', Modulo aber Ergebnisse von 0-47 liefert (eben der Rest, wenn wir keine 48 mehr abziehen können).
Richtung, von, über (Addition), nach (Modulo)
+> 1 -> 2 -> 2
+> 2 -> 3 -> 3
-> 3 -> 49 -> 2
-> 2 -> 48 -> 1
-> 1 -> 47 -> 48
-> 48 -> 95 -> 47

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Acki1985

Ich danke dir. Oh kannst mir das genauer erklären wie ich das machen muss. Versteh das leider nicht.

postmaster-ino

Da, wo Du um 1 erhöhst, erhöhst Du auch weiterhin um 1.
Da, Wo Du um 1 verminderst, erhöhst Du um 47 (einen weniger als MAX-Positionen).
BEIDE, ohne die IF-Abfrage davor, wir wollen ja bei 1 auch runter und bei 48 auch hoch zählen.
Hinter der Zählerei kommt dann die Korrektur des gezählten Wert, die Modulo-Berechnung.

Etwas Spieltrieb darfst Du gerne auch zeigen - wenn's wider Erwarten doch nicht klappt, hast Du die Vorversion (Die Du Dir UNBEDINGT Exportieren/Archivieren solltest).

Zur größten Not schreibe Dir einen Testsketch und lasse eine Variable von 0 bis 32000 hoch zählen (int geht dafür).
Diese Variable verrechnest Du mit %48 (Modulo 48) und lässt Dir dieses Ergebnis anzeigen.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Acki1985

Aber wen ich die If Abfragen für den Encoderwert wegnehme, mach das doch keinen Sinn mehr oder?


if (encoderWert < 48) encoderWert++ ;
    } else {
      if (encoderWert > 1) encoderWert-- ;

Ich begreif das einfach nicht. Gibt es da eventuell irgendwo ein Beispiel?

postmaster-ino

Hi

Code: [Select]
if ((messungPin1 == LOW) && (messungPin1Alt == HIGH) && (nullStellung == true)) {
    if (digitalRead(encoderPinB) == HIGH) {
      if (encoderWert < 48) encoderWert++ ;
    } else {
      if (encoderWert > 1) encoderWert-- ;

1. Zeile: Abfrage, ob der Encoder gedreht wurde, wenn JA, geht's weiter
2. Zeile, Abfrage, ob der Encoder HOCH gedreht wurde, wenn JA, geht's direkt weiter, sonst beim ELSE
3. Zeile - HIER begrenzt Du den Wert auf 48 - DIESE IF raus und NUR encoderwert++; dahin
4. Zeile ... ein ELSE, ab hier, wenn 'RUNTER' gedreht wurde
5. Zeile - HIER begrenzt Du auf den Wert 1 - DIESES IF raus und statt -- machst Du hier encoderwert+=47; (oder +(maxiwert-1) )
DAHINTER - quasi Zeile 5 1/2
encoderwert=encoderwert%48; (oder maxwert)

... fertig ...

Die 3.te und die 5.te Zeile haben NICHTS mit der Abfrage des Encoder zu tun - DIE verhindern nur, daß der Wert <1 oder >48 werden kann.

Wenn man mit der IF-Verschachtelung nicht klar kommt, sollte man STUR ALLE Klammern setzen.
Das hier:
if (encoderWert < 48) encoderWert++ ;
ist eine komplette und gültige IF-Abfrage mit einer Anweisung, wenn Diese erfüllt ist.
if (encoderWert < 48) {
   //hier, wenn Bedingung erfüllt
  encoderWert++ ;
}else{
  //hier, wenn Bedingung NICHT erfüllt
}
Ohne die Klammern (Block-Bildung), kannst Du auch nur EINEN Befehl bedingt ausführen lassen.
Im Block beliebig Viele.

MfG
anscheinend ist Es nicht erwünscht, einen Foren-internen Link als 'Homepage' einzubinden, damit JEDER nur einen Klick von combie's Liste zum Thema State-Maschine entfernt ist.
... dann eben nicht ...

Acki1985

#119
Jan 26, 2019, 03:33 pm Last Edit: Jan 26, 2019, 03:36 pm by Acki1985
Hallo alle zusammen. So hab es jetzt mit eurer Hilfe bis hier her Geschafft. Das Programm läuft so wie es soll. Ok hab den Motor noch nicht angeschlossen.

Jetzt müsste ich aber zwei Arduinos verwenden, welche über eine Funkverbindung miteinander reden und die Befehle ausführen. Habt ihr da einen link, wo die Datenübertragung mittels NRF24 beschrieben ist?
Oder wie man das hinbekommt, das wenn am sender ein Pin high ist am Empfänger eine LED angeht und wenn am Sender der Pin wieder LOW ist am Empfänger die LED wieder aus geht?

Hier ist übrigens das Programm was mit eurer Hilfe entstanden ist:

https://pastebin.com/WM9ZZTdt

Go Up