Modyfikacja programu arduino

FilipXYZ
Posty: 10
Rejestracja: sob kwie 08, 2023 2:40 pm

Zlecę modyfikacje działającego programu arduino. Chciałbym żeby button obsługujący servo był dostępny z poziomu aplikacji Supla.

Kod: Zaznacz cały

#include <ESP8266WiFi.h>
#include <Servo.h>

Servo myservo;
int buttonPin = D1; // przycisk podłączony do pinu D1
int buttonState = 0;
int lastButtonState = 0;
int position = 0; // początkowa pozycja serwa
unsigned long lastButtonTime = 0; // czas ostatniego naciśnięcia przycisku
//unsigned long returnTime = 5000; // czas powrotu serwa do pozycji 0 (w milisekundach)
unsigned long debounceDelay = 500; // opóźnienie czasowe do przycisku (w milisekundach)

void setup() {
  myservo.attach(D5); // podłączenie serwomechanizmu do pinu D5
  pinMode(buttonPin, INPUT_PULLUP); // ustawienie pinu przycisku jako wejście i włączenie wewnętrznego pull-up resistora
  myservo.write(position); // ustawienie początkowej pozycji serwa na 0 stopni
}

void loop() {
  unsigned long currentTime = millis(); // aktualny czas w milisekundach
  buttonState = digitalRead(buttonPin); // odczytanie stanu przycisku
  if (buttonState != lastButtonState && (currentTime - lastButtonTime) > debounceDelay) {
    if (buttonState == LOW) { // jeśli przycisk został naciśnięty
      if (position == 0) { // jeśli serwo jest w pozycji 0 stopni
        position = 180; // ustawienie pozycji serwa na 90 stopni
        lastButtonTime = currentTime; // zapisanie czasu ostatniego naciśnięcia przycisku
      }
      else { // jeśli serwo jest w pozycji 90 stopni
        position = 0; // ustawienie pozycji serwa na 0 stopni
      }
      myservo.write(position); // ustawienie kąta obrotu serwomechanizmu na wartość pozycji
    }
    lastButtonState = buttonState; // zapisanie aktualnego stanu przycisku
  }
  if (position != 0 && (currentTime - lastButtonTime) >= returnTime) { // jeśli serwo nie jest w pozycji 0 i upłynął czas powrotu do pozycji 0
    position = 0; // ustawienie pozycji serwa na 0 stopni
    myservo.write(position); // ustawienie kąta obrotu serwomechanizmu na wartość pozycji
  }
}
Ostatnio zmieniony pt kwie 28, 2023 12:11 am przez FilipXYZ, łącznie zmieniany 1 raz.
Awatar użytkownika
lukfud
Posty: 2101
Rejestracja: czw lis 23, 2017 11:33 pm
Lokalizacja: Warszawa

Przetestowane, działające ;)

Kod: Zaznacz cały

#define STATUS_LED_GPIO 2
#define BUTTON_CFG_RELAY_GPIO 4
#define SERVO_PIN 12

#include <SuplaDevice.h>
#include <supla/network/client.h>
#include <supla/network/esp_wifi.h>
#include <supla/control/virtual_relay.h>
#include <supla/control/button.h>
#include <supla/device/status_led.h>
#include <supla/storage/littlefs_config.h>
#include <supla/network/esp_web_server.h>
#include <supla/device/supla_ca_cert.h>
#include <supla/network/html/device_info.h>
#include <supla/network/html/protocol_parameters.h>
#include <supla/network/html/status_led_parameters.h>
#include <supla/network/html/wifi_parameters.h>
#include <supla/network/html/custom_parameter.h>
#include <supla/network/html/custom_text_parameter.h>
#include <supla/storage/eeprom.h>
#include <Servo.h>
Servo myservo;

#include <supla/sensor/virtual_binary.h>
Supla::Sensor::VirtualBinary *v_sensor = nullptr;

Supla::Eeprom eeprom;
Supla::ESPWifi wifi;
Supla::EspWebServer suplaServer;
Supla::LittleFsConfig configSupla;
Supla::Device::StatusLed statusLed(STATUS_LED_GPIO, true); 

int servoPosition = 0;
enum default_actions {
  SET_SERVO_POSITION
};

class customIterate : public Supla::Element {
 public: customIterate() {}
 
  void iterateAlways() {
    if (Supla::Network::IsReady()) {
      if (myservo.read() == 0 && v_sensor->getValue() == HIGH) {
        v_sensor->handleAction(0, Supla::CLEAR);
      }
      if (myservo.read() == 180 && v_sensor->getValue() == LOW) {
        v_sensor->handleAction(0, Supla::SET);
      }
    }
  }
};
customIterate *custIterate = new customIterate;

class addedActionsClass : public Supla::ActionHandler, public Supla::Element {
 public: addedActionsClass() {}
  void handleAction(int event, int action) {
    if (action == SET_SERVO_POSITION) {
      if (myservo.read() == 0) {
        servoPosition = 180;
      } else if (myservo.read() == 180) {
        servoPosition = 0;
      }
      myservo.write(servoPosition);
      SUPLA_LOG_DEBUG("# setting up servo position - %d", servoPosition);
    }
  }
};
addedActionsClass *custAct = new addedActionsClass;

void setup() {

  Serial.begin(115200);

  myservo.attach(SERVO_PIN);
  myservo.write(servoPosition);
  
  auto v_relay = new Supla::Control::VirtualRelay();
  v_relay->addAction(SET_SERVO_POSITION, custAct, Supla::ON_TURN_ON);
  v_sensor = new Supla::Sensor::VirtualBinary();
  v_sensor->handleAction(0, Supla::CLEAR);
  auto buttonCfgRelay =
    new Supla::Control::Button(BUTTON_CFG_RELAY_GPIO, true, true);
  buttonCfgRelay->configureAsConfigButton(&SuplaDevice);
  buttonCfgRelay->addAction(SET_SERVO_POSITION, custAct, Supla::ON_CLICK_1);

  SuplaDevice.setSuplaCACert(suplaCACert);
  SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);
  
  new Supla::Html::DeviceInfo(&SuplaDevice);
  new Supla::Html::WifiParameters;
  new Supla::Html::ProtocolParameters;
  new Supla::Html::StatusLedParameters;
  
  SuplaDevice.setName("SERVO");
  SuplaDevice.begin();
  SuplaDevice.getSrpcLayer()->client->setDebugLogs(false);

};

void loop() {
  SuplaDevice.iterate();
};
https://www.facebook.com/groups/supladiy/
FilipXYZ
Posty: 10
Rejestracja: sob kwie 08, 2023 2:40 pm

Kod przetestowany i działa rewelacyjnie. Możliwość sterowania serwem za pomocą przycisku i aplikacji. W aplikacji widoczne stany otwarcia i zamknięcia. Jeśli ktoś chciałby wykorzystać serwo w roli np. zamka to dość fajne rozwiązanie sprzedają "My Frendy" : https://pl.aliexpress.com/item/40000795 ... pt=glo2pol .
W przypadku tego typu (dość mocnych) serw należy zasilać je z zewnętrznego zasilacza (5V) o odpowiednim amperżu. Co więcej należy spiąć piny GND wemosa i GND serwa. Serdeczne podziękowania dla kolegi @Lukfud :)
ODPOWIEDZ

Wróć do „Ogłoszenia / Giełda / Zlecenia”