Gå til innhold
  • Bli medlem
Støtt hjemmeautomasjon.no!
  • Fermate
    Fermate

    ESP32/MQTT Servostyring (5)

    Her er basis kode for å styre en Servo, med den innebyggede PWM funksjonaliteten:
     

    Sitat
    // Servo PWM
    const int pwmServoPin        = GPIO_NUM_25;  
    const int pwmServoFreq       = 50;
    const int pwmServoChannel    = 0;
    const int pwmServoResolution = 8;
     
    int iPos;
     
    void setup() {
      Serial.begin(115200);
     
      // configure Servo  PWM
      ledcSetup(pwmServoChannel, pwmServoFreq, pwmServoResolution);
      // attach the channel to the GPIO to be controlled
      ledcAttachPin(pwmServoPin, pwmServoChannel);
     
    }
     
    void loop() {
      iPos1=10; //servo posisjon, teoretisk 0-255
      ledcWrite(pwmServoChannel, iPos);
    }

     

    Det er gøy å få ting til å bevege seg og servoer er enkle å jobbe med.
     

    En servo er en motor med girkasse og en tilbakekobling for å kunne sjekke sin egen posisjon. Når den får beskjed om å flytte seg til en ny posisjon starter den motoren og stopper når sensoren sier den er kommet dit.

     

    Små billige servoer styres med pulser der bredden på pulsen styrer posisjonen. Den kobles til med 3 ledninger: Pluss, minus og Puls-Signal. Her er noen vanlige fargekodinger:

     

    Servo wires

     

    Det finnes noen Servo biblioteker en kan bruke men noen av den fungerer ikke med ESP32.
    Fordi ESP32 har innebygget funksjonalitet for å styre LED med pulsbredde bruker jeg like godt dette istedet.

    (Som dere ser ligner koden på viftestyringen i forrige guide)

     

    Forskjellige servoer har forskjellige reaksjoner på pulsbredden. Noen lar motoren gå kontinuerlig på bestemte verdier og mange har bare små puls områder der de reagerer. Kanskje fra 10 til 30.

    Jeg anbefaler å eksprimentere med den enkelte servo for å finne endeverdiene.

     

    Om du skal mappe disse til et smarthus system som går fra 0 til 100 % (Som en dimmer) kan du gjøre dette med denne kommandoen:

     

    iPos= map(iPos,0,100,MIN_SERVO_POS,MAX_SERVO_POS);

     

    Så kan du sette de endeverdiene du fant inn i konstanter slik:

     

    #define MIN_SERVO_POS 12
    #define MAX_SERVO_POS 30

     

    Jeg preier likegodt å eksponere både den mappede og den rå posisjonen over MQTT interfacet. (Det koster jo så lite) Så blir testingen (og evnt. rejustering) enklere.

     

    Her er kode for å styre 2 servoer over MQTT med både rå og mappede verdier:

     

    Sitat
    #define ONBOARD_LED 2 // Onboard LED
    #include <EspMQTTClient.h>
     
    // Servo PWM
    const int pwmServo1Pin        = GPIO_NUM_25;  
    const int pwmServo2Pin        = GPIO_NUM_26;  
    const int pwmServoFreq        = 50;
    const int pwmServo1Channel    = 0;
    const int pwmServo2Channel    = 1;
    const int pwmServoResolution  = 8;
     
    #define MIN_SERVO1_POS 12
    #define MAX_SERVO1_POS 30
    #define MIN_SERVO2_POS 9
    #define MAX_SERVO2_POS 33
     
    int iPos1=MAX_SERVO1_POS; // Start i max
    int iPos2=MAX_SERVO2_POS; // Start i max
     
    //MQTT
    EspMQTTClient MQTTclient(
      "ThePromisedLAN", // SSID
      "Hallelujah!", // WiFi Password
      "192.168.1.2",  // MQTT Broker server ip
      "",   // MQTTUsername Can be omitted if not needed
      "",   // MQTTPassword Can be omitted if not needed
      "servoClient",     // Client name that uniquely identify your device
      1883              // The MQTT port, default to 1883. this line can be omitted
    );
     
    void setup() {
      Serial.begin(115200);
     
      // Set pin mode for ONBOARD_LED
      pinMode(ONBOARD_LED,OUTPUT);
      digitalWrite(ONBOARD_LED,HIGH);
     
      // configure Servo 1 PWM
      ledcSetup(pwmServo1Channel, pwmServoFreq, pwmServoResolution);
      // attach the channel to the GPIO to be controlled
      ledcAttachPin(pwmServo1Pin, pwmServo1Channel);
     
      // configure Servo 2 PWM
      ledcSetup(pwmServo2Channel, pwmServoFreq, pwmServoResolution);
      // attach the channel to the GPIO to be controlled
      ledcAttachPin(pwmServo2Pin, pwmServo2Channel);
     
      // Init
      ledcWrite(pwmServo1Channel, iPos1);
      ledcWrite(pwmServo2Channel, iPos2);
     
     MQTTclient.setKeepAlive(60);
     
    }
     
    void loop() {
        MQTTclient.loop();
     
        if (MQTTclient.isMqttConnected()) {
          digitalWrite(ONBOARD_LED,LOW);
        } else {
         digitalWrite(ONBOARD_LED,HIGH);
        }
      }
     
    void onConnectionEstablished()
     {
     Serial.println("onConnectionEstablished");
     MQTTclient.publish("servoClient/status", "started");  
     
     // Servo 1
      MQTTclient.subscribe("servoClient/RawAngle1", [](const String & payload) {
      Serial.print("RawAngle1: ");
        Serial.println(payload);
        iPos1=payload.toInt();
        ledcWrite(pwmServo1Channel, iPos1);
      });
     
      MQTTclient.subscribe("servoClient/Angle1", [](const String & payload) {
      Serial.print("Angle1: ");
        Serial.println(payload);
        iPos1=payload.toInt();
        iPos1= map(iPos1,0,100,MIN_SERVO1_POS,MAX_SERVO1_POS);
        ledcWrite(pwmServo1Channel, iPos1);
      });
     
     // Servo 2
      MQTTclient.subscribe("servoClient/RawAngle2", [](const String & payload) {
      Serial.print("RawAngle2: ");
        Serial.println(payload);
        iPos2=payload.toInt();
        ledcWrite(pwmServo2Channel, iPos2);
      });
     
      MQTTclient.subscribe("servoClient/Angle2", [](const String & payload) {
      Serial.print("Angle2: ");
        Serial.println(payload);
        iPos2=payload.toInt();
        iPos2= map(iPos2,0,100,MIN_SERVO2_POS,MAX_SERVO2_POS);
        ledcWrite(pwmServo2Channel, iPos2);
      });
     
      }

     


     

     

    Brukertilbakemelding

    Anbefalte kommentarer

    Det er ingen kommentarer å vise.



    Bli med i samtalen

    Du kan publisere innhold nå og registrere deg senere. Hvis du har en konto, logg inn nå for å poste med kontoen din.

    Gjest
    Skriv en kommentar...

    ×   Du har limt inn tekst med formatering.   Lim inn uten formatering i stedet

      Du kan kun bruke opp til 75 smilefjes.

    ×   Lenken din har blitt bygget inn på siden automatisk.   Vis som en ordinær lenke i stedet

    ×   Tidligere tekst har blitt gjenopprettet.   Tøm tekstverktøy

    ×   Du kan ikke lime inn bilder direkte. Last opp eller legg inn bilder fra URL.




×
×
  • Opprett ny...

Viktig informasjon

Vi har plassert informasjonskapsler/cookies på din enhet for å gjøre denne siden bedre. Du kan justere dine innstillinger for informasjonskapsler, ellers vil vi anta at dette er ok for deg.