SwitchBot mit FauxMo

Hallo Community,

ich baue grade einen "Finger" also Servo, welcher per Alexa auf einen Knopf drücken soll (SwitchBot).
Zum Start habe ich das FauxMo Beispiel-Skript versucht zu erweitern.

Dazu habe ich FauxMo auf meinem 8266 ESP WeMos Mini laufen. Alexa erkennt das Gerät auch prima.
Bei "Alexa schalte Finger ein" dreht er ein Stück, aber nicht mehr zurück. Er dreht auf die erste Postition, aber nicht mehr auf die zweite Position. Warum nur?

Im Skript seht ihr wie der Servo laufen muss. Er muss also um einen Knopf zu drücken einmal auf 10 Grad und dann 170 und dann wieder 10. Aktuell geht er nur auf die erste Position...

Was übersehe ich? (ganz unten im Skript - "myservo.write ...") - Delays habe ich mehrere probiert..
DANKE FÜR JEDEN TIPP! Bin noch recht neu im Thema...

#include <Arduino.h>
#ifdef ESP32
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
#endif
#include "fauxmoESP.h"
#include <Servo.h>

// Rename the credentials.sample.h file to credentials.h and 
// edit it according to your router configuration
#include "credentials.h"

fauxmoESP fauxmo;

// -----------------------------------------------------------------------------

#define SERIAL_BAUDRATE     115200

#define PIN_SERVO          D7

#define ID_SERVO           "finger"

// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// Wifi
// -----------------------------------------------------------------------------

Servo myservo;  // create servo object to control a servo
// twelve servo objects can be created on most boards

void wifiSetup() {

   // Set WIFI module to STA mode
   WiFi.mode(WIFI_STA);

   // Connect
   Serial.printf("[WIFI] Connecting to %s ", WIFI_SSID);
   WiFi.begin(WIFI_SSID, WIFI_PASS);

   // Wait
   while (WiFi.status() != WL_CONNECTED) {
       Serial.print(".");
       delay(100);
   }
   Serial.println();

   // Connected!
   Serial.printf("[WIFI] STATION Mode, SSID: %s, IP address: %s\n", WiFi.SSID().c_str(), WiFi.localIP().toString().c_str());

}

void setup() {

   // Init serial port and clean garbage
   Serial.begin(SERIAL_BAUDRATE);
   Serial.println();
   Serial.println();

   myservo.attach(PIN_SERVO);  // attaches the servo on GIOD7 to the servo object


   // LEDs
   pinMode(PIN_SERVO, OUTPUT);
   digitalWrite(PIN_SERVO, LOW);
   
   // Wifi
   wifiSetup();

   // By default, fauxmoESP creates it's own webserver on the defined port
   // The TCP port must be 80 for gen3 devices (default is 1901)
   // This has to be done before the call to enable()
   fauxmo.createServer(true); // not needed, this is the default value
   fauxmo.setPort(80); // This is required for gen3 devices

   // You have to call enable(true) once you have a WiFi connection
   // You can enable or disable the library at any moment
   // Disabling it will prevent the devices from being discovered and switched
   fauxmo.enable(true);

   // You can use different ways to invoke alexa to modify the devices state:
   // "Alexa, turn yellow lamp on"
   // "Alexa, turn on yellow lamp
   // "Alexa, set yellow lamp to fifty" (50 means 50% of brightness, note, this example does not use this functionality)

   // Add virtual devices
   fauxmo.addDevice(ID_SERVO);
   
   fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {
       
       // Callback when a command from Alexa is received. 
       // You can use device_id or device_name to choose the element to perform an action onto (relay, LED,...)
       // State is a boolean (ON/OFF) and value a number from 0 to 255 (if you say "set kitchen light to 50%" you will receive a 128 here).
       // Just remember not to delay too much here, this is a callback, exit as soon as possible.
       // If you have to do something more involved here set a flag and process it in your main loop.
       
       Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);

       // Checking for device_id is simpler if you are certain about the order they are loaded and it does not change.
       // Otherwise comparing the device_name is safer.

            if (strcmp(device_name, ID_SERVO)==0) {
            digitalWrite(PIN_SERVO, state ? HIGH : LOW);
            myservo.write(180);              // tell servo to go to position in variable 'pos'
            delay(50);
            myservo.write(10);
            delay(50);
            myservo.write(180);
            }
   });

}

void loop() {

   // fauxmoESP uses an async TCP server but a sync UDP server
   // Therefore, we have to manually poll for UDP packets
   fauxmo.handle();

   // This is a sample code to output free heap every 5 seconds
   // This is a cheap way to detect memory leaks
   static unsigned long last = millis();
   if (millis() - last > 5000) {
       last = millis();
       Serial.printf("[MAIN] Free heap: %d bytes\n", ESP.getFreeHeap());
   }

   // If your device state is changed by any other means (MQTT, physical button,...)
   // you can instruct the library to report the new state to Alexa on next request:
   // fauxmo.setState(ID_SERVO, true, 255);

}

Danke und LG
JB

Setze Deinen Code bitte direkt ins Forum. Benutze dazu Codetags (</>-Button oben links im Forumseditor oder [code] davor und [/code] dahinter oder gehe in der IDE auf Bearbeiten - Für Forum kopieren und füge es hier ein.
Dann ist er auch auf mobilen Geräten besser lesbar.
Das kannst Du auch noch nachträglich ändern.

Gruß Tommy

Mach doch mal ne serielle Ausgabe nach

digitalWrite(PIN_SERVO, state ? HIGH : LOW);

Wobei mir auch nicht klar ist, so state herkommt.

            myservo.write(180);              // tell servo to go to position in variable 'pos'
            delay(50);
            myservo.write(10);
            delay(50);
            myservo.write(180);

Kenne mich mit der Servobibliothek nicht aus und habe bisher auch noch nie eine Servo am Arduino betrieben, aber die Zeiten kommen mir ein wenig kurz vor.

Zwischen den Positionen lässt Du dem Servo 0,05 Sekunden Zeit die Position zu erreichen. Du schreibst zwar das Du verschiedene Delays versucht hast, aber nicht welche. Hast Du auch welche versucht die länger sind, so ab 500 aufwärts? Servos sind zwar schnell, aber 0,05 Sekunden sind sehr sportlich.

Gruß, Jürgen

@Katsumi: Eben nochmals mit 500 und 1000 (1 Sek) versucht. Auch hier macht er nur die erste Bewegung.

Vielleicht muss ich das ganz anders auslösen. Aber seltsam, dass nur der erste Schritt gemacht wird. Falls jemand Lust auf so ein Projekt hat, dann gerne melden :slight_smile: Parallel zeichne ich eben ein Gehäuse dafür, so dass man es mit PLA 3D ausdrucken kann... Wie soll sonst meine Senso angehen :wink:

@Klaus:
Wenn das Gerät an ist ON und wenn aus, dann OFF laut Protokoll:

13:21:55.194 -> [MAIN] Free heap: 50488 bytes
13:21:59.363 -> [MAIN] Device #0 (finger) state: ON value: 255
13:22:00.181 -> [MAIN] Free heap: 50488 bytes
13:22:05.174 -> [MAIN] Free heap: 50488 bytes
13:22:10.163 -> [MAIN] Device #0 (finger) state: OFF value: 255
13:22:10.197 -> [MAIN] Free heap: 49800 bytes

Gruß
JB

.. habe festgestellt, dass der DELAY nicht funktioniert. Egal welcher Wert. Selbst durch diese dicke Bremse rennt das Skript in 1 Sekunde... Doch warum?

if (strcmp(device_name, ID_SERVO)==0) {
            myservo.write(170);              // tell servo to go to position in variable 'pos'
            Serial.printf("STARTEin7Sekunden");
            delayMicroseconds(2500);
            delay(5000);
            Serial.printf("7SekundenVorbei");
            myservo.write(10);
            delayMicroseconds(2500);
            Serial.printf("2terSchrittErledigt");
           
            }

Was meinst Du mit "rennt das Skript in 1 Sekunde... " ?
Grüße Uwe

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.