Go Down

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

Acki1985

Aber die Bühne hört ja auch permanent. Das hören wird doch nur unterbrochen, wenn die restlichen Schritte gesendet werden. Oder lieg ich da falsch?

postmaster-ino

Hi

Ein oder zwei Kleinigkeiten wird 'die Bühne' wohl drum herum noch machen müssen - gucken, ob der Endschalter betätigt wurde, um 1 runter zu zählen, den Motor anhalten, wenn wir auf Null sind und so Kram.
Du kannst, wie sonst auch immer, entweder bei jedem (möglichst schnellem) loop()-Durchlauf nachschauen, ob's was Neues gibt, oder, wenn der Funk-Empfänger Das bietet, einen Interrupt aktivieren, in Dem Du auf den eingehenden Datenstrom reagierst.
Normal wird dort aber auch nur 'gemerkt', daß was Neues gesendet wird - das Auslesen muß dann so schnell wie möglich in der loop() erledigt werden - und dann das darauf reagieren.

Wie bereits geschrieben: MALE Dir auf, was wann wie passieren soll.
Dort wirst Du schnell sehen, daß Du eine ganze Menge Kram zu erledigen hast und Du so auch eine ganze Zeit NICHT schaust, ob's was Neues gibt.
Damit Du trotzdem Nichts verpasst, muß loop() rasend schnell sein, um in jedem Durchlauf die 1/2 angefallenen Zeichen abzugrasen.

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

Whandall

#137
Feb 12, 2019, 09:33 pm Last Edit: Feb 12, 2019, 09:35 pm by Whandall
Der Kommunikationsablauf in der Bühne sollte so in Ordnung sein, du hast aber noch keinen Anhaltebefehl.

Der Ablauf im Sender ist dein Problem.
Wenn du den Sender änderst, bitte entferne alle Kommentare die Offensichtlichkeiten kommentieren.

Ich durchschaue deine verschachtelten Funktionen nicht,
die Positionserkennung kommt mir komisch an die Zeit gebunden vor,
teilweise gibt es komplizierte Bedingungen,
der halbe Kode ist auskommentiert.
Warum nutzt du einelementige Arrays?

Wie wäre es mit aktualisierten Versionen in einem neuen Post?
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Acki1985

Hier ist der Aktuelle Code vom Sender:

Code: [Select]

#include <SPI.h>
#include "RF24.h"

#define button 4
#define confirmLed 2
#define led 3

RF24 NRF24L01 (8, 9);//create object called NRF24L01. specifying the CE and CSN pins to be used on the Arduino

byte address[] [6] = {"pipe1", "pipe2"};//set addresses of the 2 pipes for read and write
boolean buttonState = false;//used for both transmission and receive
byte schritte[1];
void setup() {
  Serial.begin(9600);
  pinMode(button, INPUT_PULLUP);
  pinMode(confirmLed, OUTPUT);//yellow LED
  pinMode(led, OUTPUT);//red LED

  NRF24L01.begin();
  //open the pipes to read and write from board 1
  NRF24L01.openWritingPipe(address[0]);//open writing pipe to address pipe 1
  NRF24L01.openReadingPipe(1, address[1]);//open reading pipe from address pipe 2

  NRF24L01.setPALevel(RF24_PA_MAX);//set RF power output to minimum, RF24_PA_MIN (change to RF24_PA_MAX if required)
  NRF24L01.setDataRate(RF24_250KBPS);//set data rate to 250kbps
  NRF24L01.setChannel(110);//set frequency to channel 110
}

void loop() {
  schritte[0] = 120;

  buttonState = digitalRead(button);
  if (buttonState == LOW)
  {
    NRF24L01.stopListening();
    Serial.println("1");
    NRF24L01.write(&schritte, sizeof(schritte));
    Serial.println(schritte[0]);

    NRF24L01.startListening();
  }

  buttonState = HIGH;//reset the button state variable


  if (NRF24L01.available())
  {
    Serial.println("2");
    NRF24L01.read(&buttonState, sizeof(buttonState));
    Serial.println(buttonState);
  }
}


Und die Bühne:

Code: [Select]

#include <SPI.h>
#include "RF24.h"

unsigned long warteZeit;
int data[1];
boolean var = true;
//const byte addresses[][6] = {"00001", "00002"};
//const uint64_t pipe = 0xF0F0F0F0A1LL;
RF24 radio (8, 9);
byte address[] [6] = {"pipe1", "pipe2"}; // Adressen der beiden Pipes
byte rever_start = false;
const byte hal = 3;
byte schritte[1];                                 // Schritte die deer Motor (Hallsensor betätigt) zurücklegen muss
int sensor = LOW;
unsigned long startZeit;                          // Abfrage begin Sensor an Bühne
unsigned long interval = 2000;                    // Zeitabstand nachdem ein Zustand des Sensors erkannt wird
unsigned long vergangeneZeit = 0;                 // Speichervariable um die Vergangene Zeit zu speichern
/*int pin_motor_links = A1;                         // Richtungspin an H-Brücke für Links
int pin_motor_rechts = A2;                        // Richtungspin an H-Brücke für Rechts
*/
// Statusvariablen
bool nullStellung = false;                      // Speichervariable ob Referenzfahrt erfolgt ist
bool ergebnis = false;                          // Berechnung der Schritte und Richtung beendet/gestartet
bool start = false;                           // Schritte Zaehlen beendet/gestartet

void setup() {
  radio.begin();
  //radio.openReadingPipe(1, pipe);
  radio.openWritingPipe(address[1]); // 00001
  radio.openReadingPipe(1, address[0]); // 00002
  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate (RF24_250KBPS);
  radio.setChannel(110);
 
  radio.startListening();
  pinMode(hal, INPUT);
  Serial.begin(9600);
  //delay (2000);
  }

void loop() {
 
  referenzFahrt();
  encoder_lesen();
  schritteZaehlen();
  }

void referenzFahrt() {
  if (radio.available())
{
Serial.println("Data there");
radio.read(data, 1);
Serial.println(data[0]);
}

      // Reverenzfahrt

      if ((data[0] == 255) && (rever_start == false) && (nullStellung == false)) {
        rever_start = true;
        Serial.println("Reverenzfahrt gestartet");
    //    digitalWrite (pin_motor_rechts, HIGH);
      //  digitalWrite (pin_motor_links, LOW);
      }
      else if ((data[0] == 254) && (rever_start == true)) {
        nullStellung = true;
        rever_start = false;
        Serial.println("Reverenzfahrt beendet");
        Serial.println (" "); 
  //      digitalWrite (pin_motor_rechts, LOW);
//        digitalWrite (pin_motor_links, LOW);
      }
    }
 
  void encoder_lesen () {
   if ((data[0] <= 48) && (data[0] > 0) && (nullStellung == true) && (ergebnis == false)) {
    //rechtsrum data[0] Schritte
    schritte[0] = data[0];
    ergebnis = true;
    // Motor
    Serial.println (schritte[0]);
    Serial.print ("  Schritte nach Rechts");
    Serial.println (" ");   
   }
  else if ((data[0] >=100) && (data[0] <= 149) && (nullStellung == true) && (ergebnis == false)) {
    //linksrum data[0] - 100 Schritte
    schritte[0] = data[0] - 100;
    ergebnis = true;
    // Motor
    Serial.println (schritte[0]);
    Serial.print ("  Schritte nach links");
    Serial.println (" ");
   }
  }
 
void schritteZaehlen () {

  sensor = digitalRead (hal);
  startZeit = millis();
  if ((schritte[0] != 0) && (ergebnis == true)) {
    start = true;
    if ((startZeit - vergangeneZeit >= interval) && (sensor == LOW) && (start == true)) {
      vergangeneZeit = startZeit;
      schritte[0]--;
      Serial.println("Drehung start");
      Serial.println("Restl. Pos.");
      Serial.println(schritte[0]);
      radio.stopListening();
      radio.write (&schritte, sizeof (schritte));
      radio.startListening();
      }
  }
  else if ((schritte[0] == 0) && (start == true)) {
    start = false;
    ergebnis = false;
    data[0] = 0;
    Serial.println("Ziel");
    Serial.println("Drehung");
    Serial.println("beendet");
    Serial.print("daten");
    Serial.println(schritte[0]);
    radio.stopListening();
    radio.write (&schritte, sizeof (schritte));
    radio.startListening();
    //schritte[0]=0;
   
    Serial.println(ergebnis);
    }
}


- Stimmt der Stopbefehl ist noch nicht drin. Diesen würde ich wieder in eine Funktion packen, die dann augeführt wird, wenn eine 0 vom Sender kommt.

- Die Positionserkennung (Zeit) ist dazu da um ein Erneutes auslesen den Sensors zu vermeiden.

- Was meinst du mit den Verschachtelten Funktionen? Der Ablauf ist im Moment folgender:
   - die Bühne empfängt vom Sender eine 255 (die Reverenzfahrt wird gestartet) Bühne beginnt zu
     drehen
   - dann sendet der Sender eine 254 (wenn der Referenzpunkrt erreicht ist) Bühne stoppt
   - wenn jetzt vom Sender eine Zahl (Schritte) <48 kommt, dreht die Bühne rechtsrum
   - wenn eine Zahl > 100 kommt wird Zahl - 100 = Schritte linksrum
   - Jetzt wird bei jeder Sensor Betätigung die Variable schritte um 1 verringert bis sie 0 ist
   - dann hält die Bühne an und wartet auf neue Befehle
 
   - Während der Ganzen Zeit wo die Bühne dreht, lauscht sie ob eine 0 vom Sender kommt.
     Kommt diese soll die Bühne anhalten (Das ist Zukunft).

Ich hoffe ich konnte es etwas erklären.

Vielen Dank das ihr mir helft.

Whandall

#139
Feb 12, 2019, 10:32 pm Last Edit: Feb 12, 2019, 10:33 pm by Whandall
Dem Sender fehlt ein startListening in setup.

Der Receiver wird nicht so kurz wie möglich abgeschaltet.

Du sendest solange der Knopf gedrückt ist, nicht wenn er gedrückt wird.

Code: [Select]
 buttonState = HIGH;//reset the button state variable

Reines Wunschdenken.

Dein Ablauf ist IMHO unausgegoren und viel zu verschränkt.

Quote
- Die Positionserkennung (Zeit) ist dazu da um ein Erneutes auslesen den Sensors zu vermeiden.
Warum in Gottes Names würde man einen Sensor nicht lesen wollen?
Könnte aber das gleiche Problem wie mit deiner Taste sein, du hast keine State-Change-Detection.

Und weiterhin: Warum nutzt du einelementige Arrays?
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Acki1985

Was meinst du damit? Ich stoppe doch das Hören und starte es gleich nach dem Schreiben wieder?
Quote
Der Receiver wird nicht so kurz wie möglich abgeschaltet.
Die Array`s stammen auch aus dem Beispielcode. Ich dachte es funktioniert nur mit Array`s


Bei dem Sensor müsste ich vielleicht mit Flanke arbeiten?

Ich merke schon das ich den Beispielcode genommen und etwas umgeändert habe, war großer Mist.


Whandall

Was meinst du damit? Ich stoppe doch das Hören und starte es gleich nach dem Schreiben wieder?
Code: [Select]
  if (buttonState == LOW)
  {
    NRF24L01.stopListening();
    Serial.println("1");
    NRF24L01.write(&schritte, sizeof(schritte));
    Serial.println(schritte[0]);

    NRF24L01.startListening();
  }

Lüge.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Acki1985

Code: [Select]
  if (buttonState == LOW)
  {
    NRF24L01.stopListening();
    Serial.println("1");
    NRF24L01.write(&schritte, sizeof(schritte));
    Serial.println(schritte[0]);

    NRF24L01.startListening();
  }

Lüge.

Meinst du weil da da noch die Serial.print("1") und die Serial.println (schritte[0]) dazwischen sind?

Whandall

Was ist an 'so kurz wie möglich' so schwer zu verstehen?

Schieb die Druckerei hinter das startListening.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Acki1985

#144
Feb 12, 2019, 11:04 pm Last Edit: Feb 12, 2019, 11:07 pm by Acki1985
Nur mal zum Verständnis. Frisst das Serielle Drucken so viel Zeit?

Hab es geändert:

Code: [Select]

 if (buttonState == LOW)//button is pulled up so test for LOW
  {
    NRF24L01.stopListening();
    NRF24L01.write(&schritte, sizeof(schritte));//send LOW state to other Arduino board
    NRF24L01.startListening();
    Serial.println("1");
    Serial.println(schritte[0]);
  }

Whandall

#145
Feb 12, 2019, 11:07 pm Last Edit: Feb 12, 2019, 11:12 pm by Whandall
Normalerweise nicht, bei vollem Puffer und deiner Baudrate aber 1 ms pro Zeichen, also 8 ms.

Das ist ungefähr 128000 Instruktionen lang.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Acki1985

Ah ok. Der Code vom Sender sieht jetzt so aus:

Code: [Select]

#include <SPI.h>
#include "RF24.h"

#define button 4
#define confirmLed 2
#define led 3

RF24 NRF24L01 (8, 9);//create object called NRF24L01. specifying the CE and CSN pins to be used on the Arduino

byte address[] [6] = {"pipe1", "pipe2"};//set addresses of the 2 pipes for read and write
boolean buttonState = false;//used for both transmission and receive
byte schritte[1];
void setup() {
  Serial.begin(9600);
  pinMode(button, INPUT_PULLUP);
  pinMode(confirmLed, OUTPUT);//yellow LED
  pinMode(led, OUTPUT);//red LED

  NRF24L01.begin();
  //open the pipes to read and write from board 1
  NRF24L01.openWritingPipe(address[0]);//open writing pipe to address pipe 1
  NRF24L01.openReadingPipe(1, address[1]);//open reading pipe from address pipe 2

  NRF24L01.setPALevel(RF24_PA_MAX);//set RF power output to minimum, RF24_PA_MIN (change to RF24_PA_MAX if required)
  NRF24L01.setDataRate(RF24_250KBPS);//set data rate to 250kbps
  NRF24L01.setChannel(110);//set frequency to channel 110
  NRF24L01.startListening();
}

void loop() {
  schritte[0] = 120;

  buttonState = digitalRead(button);//test for button press on this board
  if (buttonState == LOW)//button is pulled up so test for LOW
  {
    NRF24L01.stopListening();
    NRF24L01.write(&schritte, sizeof(schritte));//send LOW state to other Arduino board
    NRF24L01.startListening();
    Serial.println("1");
    Serial.println(schritte[0]);
  }
 
  buttonState = HIGH;//reset the button state variable


  if (NRF24L01.available())//do we have transmission from other Arduino board
  {
    Serial.println("2");
    NRF24L01.read(&buttonState, sizeof(buttonState));//update the variable with new state
    Serial.println(buttonState);
  }
}

Whandall

#147
Feb 12, 2019, 11:18 pm Last Edit: Feb 12, 2019, 11:20 pm by Whandall
Code: [Select]
 {
    Serial.println("2");
    NRF24L01.read(&buttonState, sizeof(buttonState));//update the variable with new state
    Serial.println(buttonState);
  }

Erst von der Hardware lesen, dann Ausgeben.
Du willst den Puffer so schnell wie möglich leeren, er ist nur 3 Elemente tief.

Was ist das für ein komischer Kommentar?

Ich dachte die Bühne gäbe irgendwelche Schritte zurück, keinen Tastenzustand.
Zusätzlich schreibst du einen int, liest aber nur ein byte.
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Whandall

Code: [Select]
RF24 NRF24L01 (8, 9);//create object called NRF24L01. specifying the CE and CSN pins to be used on the Arduino

Hätten die Pins vernünftige const byte Definitionen wäre der Kommentar überflüssig.

Code: [Select]
byte address[] [6] = {"pipe1", "pipe2"};//set addresses of the 2 pipes for read and write

Offensichtlich.

Code: [Select]
boolean buttonState = false;//used for both transmission and receive

Falscher Kommentar.

Code: [Select]
  pinMode(confirmLed, OUTPUT);//yellow LED
  pinMode(led, OUTPUT);//red LED

Hätten die Pins vernünftige const byte Definitionen wäre der Kommentar überflüssig.

Code: [Select]
  //open the pipes to read and write from board 1
  NRF24L01.openWritingPipe(address[0]);//open writing pipe to address pipe 1
  NRF24L01.openReadingPipe(1, address[1]);//open reading pipe from address pipe 2

  NRF24L01.setPALevel(RF24_PA_MAX);//set RF power output to minimum, RF24_PA_MIN (change to RF24_PA_MAX if required)
  NRF24L01.setDataRate(RF24_250KBPS);//set data rate to 250kbps
  NRF24L01.setChannel(110);//set frequency to channel 110

Alles offensichtlich.

Code: [Select]
  if (NRF24L01.available())//do we have transmission from other Arduino board

Offensichtlichkeit und unter Umständen auch noch falsch (falls mein Raspi sendet z.B.)
Ah, this is obviously some strange usage of the word 'safe' that I wasn't previously aware of. (D.Adams)

Acki1985

Stimmt werde ich gleich alles ändern. Danke dir übrigens für deine Geduld.

Jetzt weis ich wieder warum ich mit Array`s gearbeitet habe. Wenn ich mit Int arbeite bekomme ich immer den Fehler beim Kompilieren : no matching function for call to 'RF24::read(int*)'

Kannst du mir sagen woran das liegt und wie ich das beheben kann?

Go Up