3 Taster - 3 schaltstellungen funkübetragung

Hallo zusammen,

Ich möchte mit einem servomotor drei verschiedene stellungen anfahren.

Drücke ich auf taster 1fährt er auf position 1
Drücke ich auf taster 2, position 2.....

Das alles soll über funk passieren. Welche art ist egal (wlan Bluetooth). Reichweite unter 2 m.

Wie ich das für eine stellung realisieren kann weis ich (433 MHz transmitter)

Zusätzlich soll nicht nur ein motor angesteuert werden sondern auch ein zweiter der an einem eigenen arduino hãngt.

Kann mir da jemand behilflich sein?

Danke

Natürlich gibt es verschiedene Lösungen, spontan fällt mir ESP-NOW ein.

Getting Started with ESP-NOW (ESP32 with Arduino IDE)

ESP-NOW with ESP32: Send Data to Multiple Boards (one-to-many)

Was hast/verwendest Du?
Oder fängst Du ohne Hardware an und bist nur in der Findungsphase?

Egal welche Frequenz oder Funkart du einsetzen möchtest, das geht auch für drei Servo-Stellungen.
Du solltest dich nur entscheiden was du zur Übertragung einsetzen möchtest.

Beschreibe doch auch mal, was es genau werden soll.

Wo ist dein Problem denn dann?

Hallo,

Status eher findungsphase.

Aber bestellt hab ich das:

DEBO 433 RX/TX Entwicklerboards - 433 MHz RX/TX Modul

Am Liebsten würde ich das per Funk lösen. Grund ist der, dass ich dafür schon eine Anleitung habe und weis wie ich mit einem Sender und einem Empfänger arbeiten kann.

„Nur“ die Kombination 3 Taster und zwei verschieden Empfänger kenn ich nicht

Zeig mal Anleitung... (link)
Dann kann darauf aufgebaut werden.
Vom Prinzip her braucht es ein Telegram, welches den Empfänger benennt und den Schaltzustand.
Ist der Empfänger nicht angesprochen, verwirft er den Rest.

Der Link zur Hardware funktioniert leider nicht.

Wenn Du ein 433 MHz Modul bestellt hast, fällt ESP-NOW raus.

War kein Link, aber das hier: https://www.reichelt.de/de/de/entwicklerboards-433-mhz-rx-tx-modul-debo-433-rx-tx-p224219.html?r=1

Erstmal vielen Dank für deine schnelle Antwort.

Ich hab ein YT Video dazu
https://youtu.be/MbTIvael6yI

geht auch ohne. www.simsso.de

Das ist wohl wahr :grin:

Aber das hilft mir ja nicht bei meinem, „ 3 Sender, 2 Empfänger Problem“ oder übersehen ich was :sweat_smile:

JA.
Kein Sch... schaut sich (Hier Zeit eintragen) Minuten lang ein Video an, wenn der Code nur 10 Zeilen hat.

Dein Stichwort ist schon im Code versteckt und nennt sich message.
Du schickst eine message und in der versteckst Du wem Du die Nachricht schicken willst und was da passieren soll...
Am Empfänger wird aufgeteilt und gut ist.

Hallo Thomas,

ist das ein Geheimprojekt oder wäre es OK wenn du die Details des Projektes beschreibst? [quote="thomasbart, post:1, topic:1045560"]
Ich möchte mit einem servomotor drei verschiedene stellungen anfahren.
[/quote]

Ist mit Servomotor ein klassisches RC-Modellbauservo gemeint?

oder meint Servomotor so etwas hier?
image

Da ich mich ja gerade selber in die Funktionsweise von ESPUI einarbeite habe ich dazu ein Webinterface programmiert bei dem man ein RC Modellbauservo auf 3 Positionen fahren kann.
Die Positionen lassen sich in einem Tab "Settings" einstellen und dann im Flash des ESP speichern.
Das kann man von jedem WLAN/browserfähigen Gerät Handy Tablet PC aus steuern.

Hier die Screenshots

Also wenn du die libraries installiert bekommst dann kannste das auf einen ESP8266 oder einen ESP32 aufspielen.

Eine Variante mit richtigen Tasten wäre das gleiche Grundgerüst zum einstellen der Positionen zu benutzen aber entweder per ESP-NOW oder per UDP die Steuerbefehle von einem ESP32 zu einem zweiten zu senden

vgs

Der Punkt geht an dich! :smile:

Vielleicht muss ich an der Stelle auch nochmal sagen, wenn’s nicht eh schon klar war, das ich ein ziemlicher Anfänger bin

Hast du dafür einen Code für mich, damit ich verstehe was du damit meinst? :sweat_smile:

Oder alternativ auch gerne eine Anleitung mithilfe der ich mir das selbst erarbeiten kann?

Wenn ich dir mein Lieblingsprojekt, welches ich begleitet habe, unterjubel, dann gehst Du auf Tauchstation.
Wenn Du willst, kannst ja lesen... Ganz am Anfang ist eine Auswertung - später wird es anstrengend, weil mehrfach aufgeteilt.

Ich überleg mal, was Du brauchst. Wenn ich was habe, kommt es...

Hier ist der Code zum ESPUI-projekt

  #define dbg(myFixedText, variableName) \
  Serial.print( F(#myFixedText " "  #variableName"=") ); \
  Serial.println(variableName);

#define dbgi(myFixedText, variableName,timeInterval) \
  do { \
    static unsigned long intervalStartTime; \
    if ( millis() - intervalStartTime >= timeInterval ){ \
      intervalStartTime = millis(); \
      Serial.print( F(#myFixedText " "  #variableName"=") ); \
      Serial.println(variableName); \
    } \
  } while (false);

#include <Preferences.h>     // add sourcecode file
Preferences myPrefInstance;  // create an instance of the object

#include <DNSServer.h>
#include <ESPUI.h>

const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 4, 1);
DNSServer dnsServer;

#if defined(ESP32)
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
#endif

#include <MobaTools.h>

const byte servoPin = 14; // GPIO 14 is labeled D5
const byte Speed = 230;

MoToServo myServo;

unsigned long MyTestTimer = 0;                   // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 2;
unsigned long SwitchStateTimer = 0;


const char *home_ssid     = "FRITZ!Box 7490";
const char *home_password = "";

char ap_ssid[25];
const char* AP_password = "espui";
const char* AP_hostname = "espui";

uint16_t myTab1_ID;
uint16_t myTab2_ID;

uint16_t statusLabel_ID;

uint16_t button1_ID;
uint16_t button2_ID;
uint16_t button3_ID;

uint16_t ServoPos1_ID;
uint16_t ServoPos2_ID;
uint16_t ServoPos3_ID;
uint16_t buttonSave_ID;
uint16_t buttonSetDefault_ID;

#define myNameSpace "ServoPos"
const boolean ReadOnly  = true;
const boolean ReadWrite = !ReadOnly; // not-operator inverts the value

int servoPos1microS;
int servoPos2microS;
int servoPos3microS;


void PrintFileNameDateTime() {
  Serial.println( F("Code running comes from file ") );
  Serial.println( F(__FILE__) );
  Serial.print( F("  compiled ") );
  Serial.print( F(__DATE__) );
  Serial.print( F(" ") );
  Serial.println( F(__TIME__) );
}


// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - startOfPeriod >= TimePeriod ) {
    // more time than TimePeriod has elapsed since last time if-condition was true
    startOfPeriod = currentMillis; // a new period starts right here so set new starttime
    return true;
  }
  else return false;            // actual TimePeriod is NOT yet over
}


void BlinkHeartBeatLED(int IO_Pin, int BlinkPeriod) {
  static unsigned long MyBlinkTimer;
  pinMode(IO_Pin, OUTPUT);

  if ( TimePeriodIsOver(MyBlinkTimer, BlinkPeriod) ) {
    digitalWrite(IO_Pin, !digitalRead(IO_Pin) );
  }
}


void number1Callback(Control* sender, int eventType) {
  Serial.print(" ");
  Serial.print(sender->label);

  Serial.println(sender->value);
  servoPos1microS = atoi(sender->value.c_str());
  dbg("Pos1", servoPos1microS);
}

void number2Callback(Control* sender, int eventType) {
  Serial.print(" ");
  Serial.print(sender->label);

  Serial.println(sender->value);
  servoPos2microS = atoi(sender->value.c_str());
  dbg("Pos2", servoPos2microS);
}


void number3Callback(Control* sender, int eventType) {
  Serial.print(" ");
  Serial.print(sender->label);

  Serial.println(sender->value);
  servoPos3microS = atoi(sender->value.c_str());
  dbg("Pos3", servoPos3microS);
}


void buttonSetDefaultCallback(Control* sender, int eventType) {
  Serial.print("ID: ");
  Serial.print(sender->id);
  Serial.print(" ");
  Serial.println(sender->label);

  if (eventType == B_UP) {
    servoPos1microS = 1100;
    servoPos2microS = 1500;
    servoPos3microS = 1900;
    ESPUI.updateControlValue(ServoPos1_ID, String(servoPos1microS) );
    ESPUI.updateControlValue(ServoPos2_ID, String(servoPos2microS) );
    ESPUI.updateControlValue(ServoPos3_ID, String(servoPos3microS) );

    dbg("Default", servoPos1microS);
    dbg("Default", servoPos2microS);
    dbg("Default", servoPos3microS);
    ESPUI.updateControlValue(statusLabel_ID, "Set positions to default");
  }
}


void  buttonSaveCallback(Control* sender, int eventType) {
  Serial.print("ID: ");
  Serial.print(sender->id);
  Serial.print(" ");
  Serial.println(sender->label);
  if (eventType == B_UP) {
    SafePreferences();
    ESPUI.updateControlValue(statusLabel_ID, "positions saved to flash");
  }
}


void button123Callback(Control* sender, int eventType) {

  uint16_t UI_ID = sender->id;

  switch (eventType) {

    case B_DOWN:
      //Serial.println("Button DOWN");
      break;

    case B_UP:
      Serial.print("Button UP ");
      Serial.print("label ");
      Serial.print(sender->label);
      dbg(" Btn123", UI_ID);

      if (UI_ID == button1_ID) {
        myServo.write(servoPos1microS);
        ESPUI.updateControlValue(statusLabel_ID, "Position 1 clicked");
      }
      
      if (UI_ID == button2_ID) {
        myServo.write(servoPos2microS);
        ESPUI.updateControlValue(statusLabel_ID, "Position 2 clicked");
      }

      if (UI_ID == button3_ID) {
        myServo.write(servoPos3microS);
        ESPUI.updateControlValue(statusLabel_ID, "Position 3 clicked");
      }
      break;
  }
}


void ConnectToWiFi() {
  int myCount = 0;
#if defined(ESP32)
  WiFi.setHostname(AP_hostname); // xxy
#else
  WiFi.hostname(AP_hostname);
#endif

  // try to connect to existing network
  WiFi.begin(home_ssid, home_password);
  Serial.print("\n\nTry to connect to existing network");
  Serial.print(" named #");
  Serial.print(home_ssid);
  Serial.println("#");

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED && myCount < 31) {
    yield(); // very important to execute yield to make it work
    BlinkHeartBeatLED(OnBoard_LED, 50); // blink LED fast during attempt to connect

    if ( TimePeriodIsOver(MyTestTimer, 500) ) { // once every 500 miliseconds
      Serial.print(".");                        // print a dot
      myCount++;

      if (myCount > 30) { // after 30 dots = 15 seconds restart
        Serial.println();
        Serial.print("not connected ");
      }
    }
  }

  if (WiFi.status() == WL_CONNECTED ) {
    Serial.println("");
    Serial.print("Connected to #");
    Serial.print(home_ssid);
    Serial.print("# IP address: ");
    Serial.println(WiFi.localIP());
  }
}

void createOwnAP() {
  // not connected -> create hotspot
  if (WiFi.status() != WL_CONNECTED) {
    Serial.print("\n\n no connection to SSID #");
    Serial.print(home_ssid);
    Serial.println("#\n Creating hotspot");

    WiFi.mode(WIFI_AP);
    delay(100);
    WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));

#if defined(ESP32)
    uint32_t chipid = 0;
    for (int i = 0; i < 17; i = i + 8) {
      chipid |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
    }
#else
    uint32_t chipid = ESP.getChipId();
#endif
    snprintf(ap_ssid, 26, "ESPUI-%08X", chipid);
    WiFi.softAP(ap_ssid);
    Serial.print("SSID #");
    Serial.print(ap_ssid);
    Serial.println("#");

    //dnsServer.start(DNS_PORT, "*", apIP);
  }
}

void printWiFiModeAndIP() {
  if (WiFi.getMode() == WIFI_AP) {
    Serial.print("ESP is its OWN accesspoint with SSID ");
    Serial.println(ap_ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.softAPIP() );
  }
  else {
    Serial.print("ESP connected to existing WLAN named ");
    Serial.println(home_ssid);
    Serial.print("IPAdress: ");
    Serial.println(WiFi.localIP() );
  }
}


void setup() {
  delay(1000);
  Serial.begin(115200);
  delay(1000);
  PrintFileNameDateTime();

#if defined(ESP32)
  WiFi.setHostname(AP_hostname);
#else
  WiFi.hostname(AP_hostname);
#endif

  ConnectToWiFi();
  if (WiFi.status() != WL_CONNECTED) {
    createOwnAP();
  }
  dnsServer.start(DNS_PORT, "*", apIP);
  printWiFiModeAndIP();

  defineUI();
  ESPUI.begin("I am the website created by the ESPUI-Demo");
  LoadPreferences();
  setupServo();
}


void loop() {
  BlinkHeartBeatLED(OnBoard_LED, 500);
  dnsServer.processNextRequest();

  if ( TimePeriodIsOver(MyTestTimer, 1000) ) {
  }

  if ( TimePeriodIsOver(SwitchStateTimer, 5000) ) {
  }
}


void defineUI() {
  // defining the website-tabs
  myTab1_ID = ESPUI.addControl(ControlType::Tab, "Operation", "Operation");
  myTab2_ID = ESPUI.addControl(ControlType::Tab, "Settings",  "Settings");

  // shown above all tabs
  statusLabel_ID = ESPUI.addControl(ControlType::Label, "last action:", "Last Action: none", ControlColor::Turquoise);

  // elements on myTab1_ID
  button1_ID = ESPUI.addControl(ControlType::Button, "Position 1", "Pos 1", ControlColor::Peterriver, myTab1_ID, &button123Callback);
  button2_ID = ESPUI.addControl(ControlType::Button, "Position 2", "Pos 2", ControlColor::Wetasphalt, myTab1_ID, &button123Callback);
  button3_ID = ESPUI.addControl(ControlType::Button, "Position 3", "Pos 3", ControlColor::Wetasphalt, myTab1_ID, &button123Callback);


  // elements on myTab2_ID
  ServoPos1_ID = ESPUI.addControl(ControlType::Number, "Servo position 1 (µseconds):", "1100",  ControlColor::Alizarin, myTab2_ID, &number1Callback);
  ESPUI.addControl(ControlType::Min, "Min-value", "1000", ControlColor::None, ServoPos1_ID);
  ESPUI.addControl(ControlType::Max, "Max-value", "2000", ControlColor::None, ServoPos1_ID);

  ServoPos2_ID = ESPUI.addControl(ControlType::Number, "Servo position 2 (µseconds):", "1500",  ControlColor::Alizarin, myTab2_ID, &number2Callback);
  ESPUI.addControl(ControlType::Min, "Min-value", "1000", ControlColor::None, ServoPos2_ID);
  ESPUI.addControl(ControlType::Max, "Max-value", "2000", ControlColor::None, ServoPos2_ID);

  ServoPos3_ID = ESPUI.addControl(ControlType::Number, "Servo position 3 (µseconds):", "1900",  ControlColor::Alizarin, myTab2_ID, &number3Callback);
  ESPUI.addControl(ControlType::Min, "Min-value", "1000", ControlColor::None, ServoPos3_ID);
  ESPUI.addControl(ControlType::Max, "Max-value", "2000", ControlColor::None, ServoPos3_ID);

  buttonSave_ID       = ESPUI.addControl(ControlType::Button, "Save to Flash ", "Save ",    ControlColor::Peterriver, myTab2_ID, &buttonSaveCallback);
  buttonSetDefault_ID = ESPUI.addControl(ControlType::Button, "Set Default ",   "Default ", ControlColor::Peterriver, myTab2_ID, &buttonSetDefaultCallback);
}


void LoadPreferences() {
  Serial.println("LoadPreferences");
  myPrefInstance.begin(myNameSpace, ReadOnly);

  servoPos1microS = myPrefInstance.getInt    ("ServoPos1"      , 1101);
  servoPos2microS = myPrefInstance.getInt    ("ServoPos2"      , 1501);
  servoPos3microS = myPrefInstance.getInt    ("ServoPos3"      , 1901);

  ESPUI.updateControlValue(ServoPos1_ID, String(servoPos1microS) );
  ESPUI.updateControlValue(ServoPos2_ID, String(servoPos2microS) );
  ESPUI.updateControlValue(ServoPos3_ID, String(servoPos3microS) );

  dbg("LP", servoPos1microS);
  dbg("LP", servoPos2microS);
  dbg("LP", servoPos3microS);
  myPrefInstance.end();
}

void SafePreferences() {
  Serial.println("SafePreferences");

  myPrefInstance.begin(myNameSpace, ReadWrite);
  //myPrefInstance.clear();

  myPrefInstance.putInt    ("ServoPos1"      , servoPos1microS);
  myPrefInstance.putInt    ("ServoPos2"      , servoPos2microS);
  myPrefInstance.putInt    ("ServoPos3"      , servoPos3microS);
  myPrefInstance.end();
  dbg("SP", servoPos1microS);
  dbg("SP", servoPos2microS);
  dbg("SP", servoPos3microS);
  LoadPreferences();
}

void setupServo() {
  myServo.attach(servoPin);
  myServo.setMinimumPulse(1000);
  myServo.setMaximumPulse(2000);
  myServo.setSpeed(Speed);
  myServo.write(servoPos2microS);
}

mit Hardware ESP8266 und einem RC-Servo getestet.
vgs

Ja, du übersiehst, das du dafür nur einen Sender und einen Empfänger benötigst.

Du kannst aber gern dein Projekt näher beschreiben, dann sehen wir ob du tatsächlich mehr von den "billigen" Dingern brauchst. Billig, da die nix taugen.
OK, für den Anfang wird es reichen, aber du wirst nicht zufrieden damit sein.

Und solltest du dich trotz der vielen anderen Vorschläge dennoch für die Version mit 433MHz und deinen Modulen entscheiden, dann verwende für dein Projekt die Library RCSwitch. Damit wird es für dich am einfachsten lösbar.

weiß ich nicht ob du da was übersiehst.
Ich selbst habe jedenfalls keinen wirklichen Durchblick was du da machen willst.
Am Anfang war von drei Tastern die Rede.

Befinden sich diese drei Taster ein einem Gehäuse?
oder
sind die drei Taster räumlich verteilt ?
Wozu bräuchte man sonst 3 Sender?

Gibt es den zweiten Arduino schon?

Was genau heißt Servomotor?
RC-Servo oder step/dir closed-loop-DC-Motor?

Abhängig davon was für ein Motor das ist kann man das für beide Motoren auch mit einem einzigen Microcontroller lösen.
Aber du beschreibst ja das Gesamtprojekt trotz mehrfacher Aufforderung nicht.

Da habe ich jetzt bald keinen Bock mehr noch irgendwie Unterstützung zu geben.
vgs