logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Sterownik automatycznych rolet Arduino nano

hetm4n 23 Gru 2024 12:31 2058 12

TL;DR LABEL_AI_GENERATED

  • Sterownik na Arduino Nano obsługuje niezależnie 2 automatyczne rolety z ręcznym sterowaniem i harmonogramem otwierania oraz zamykania.
  • Menu na OLED SSD1306 128x32 z RTC DS3231 pozwala ustawiać godziny, a kontaktrony NC i limit czasu pracy zatrzymują silniki na krańcach.
  • Kierunek obrotów realizują 4 przekaźniki, układ zasilają 12V 1A, a całość powstała z elementów z „przydasiów” i frezarki CNC3018.
  • Projekt ma kosztować poniżej 100 zł za komplet, choć autor zauważa różnice w obrotach dwóch silników 77Rpm 12V.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA
Słuchaj:
  • Sterownik rolet automatycznych z ekranem OLED i przyciskami.
    Witam! Szybki tani projekt rolet automatycznych na arduino nano. Układ obsługuje 2 rolety niezależnie. Posiada podstawowe funkcje takie jak :
    - automatyczne odsuwanie i zasuwanie o żądanej godzinie, ustawiane poprzez menu na wyświetlaczu oled ssd1306 128x32
    - ręczne odsuwanie i zasuwanie.
    - pozycje krańcowe wykorzystują czujniki kontaktronowe NC,
    - dodatkowe zabezpieczenie czasu pracy silnika
    - układ RTC DS3231 do odmierzania czasu.
    Program napisany "kompilatorem" Chat GTP 4.0 :D
    Z lewej strony na sterowniku, w menu ustawiamy za pomocą przycisków czasy zasuwania /odsuwania, natomiast z prawej mamy ręczne sterowanie. Gdy naciśniemy dany kierunek roleta zaczyna swój cykl odmierzając jednocześnie ustawiony programowo czas cyklu. Ponowne naciśnięcie przycisku powoduje jej zatrzymanie. Gdy roleta dojedzie na swoją pozycję krańcową czujnik zasygnalizuje rozwarcie i zatrzyma się roleta.
    Zmiana kierunków obrotów jest wykonana na 2 przekaźnikach dla każdej rolety (łącznie 4szt). Układ zasilany z zasilacza 12V 1A. Zastosowane silniki z przekładnia 77Rpm 12V (nie wiem dlaczego ale ich obroty się różnią )które zostana zabudowane. Silniki sprzężone z roletami są za pomocą koralików, które skróciłem na malutkie odcinki. PCB, obudowa, laminat grawerski wykonane frezarką CNC3018 Wszystkie części wykorzystane z tak zwanych przydasiów, ale jak ktoś zakupi u pana chińczyka to zmieści się w 100zł za cały komplet.
    Automatyczna roleta z silnikiem zamocowana na oknie. Okno z białymi firanami i roletami. Panel sterowania do rolet automatycznych z wyświetlaczem OLED i przyciskami. Płyta PCB z wzorem ścieżek zamocowana w plastikowej obudowie. Płytka PCB z elementami elektronicznymi dla projektu rolet automatycznych.

    Film z pracy :







    Program:
    
    #include <Wire.h>
    #include <RTClib.h>
    #include <Adafruit_GFX.h>
    #include <Adafruit_SSD1306.h>
    
    #define SCREEN_WIDTH 128
    #define SCREEN_HEIGHT 32
    #define OLED_RESET    -1
    Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
    
    RTC_DS3231 rtc;
    
    // Pin assignments
    const int leftUpPin = 2;
    const int leftDownPin = 3;
    const int rightUpPin = 4;
    const int rightDownPin = 5;
    
    const int leftTopSensor = 6;
    const int leftBottomSensor = 7;
    const int rightTopSensor = 8;
    const int rightBottomSensor = 9;
    
    // Rolety button pins
    const int leftUpButton = 10;
    const int leftDownButton = 11;
    const int rightUpButton = 12;
    const int rightDownButton = 13;
    
    // Menu button pins
    const int enterButton = A0;
    const int backButton = A1;
    const int upButton = A2;
    const int downButton = A3;
    
    // Variables for settings
    int leftUpHour = 9, leftUpMinute = 30, leftUpSecond = 0;
    int leftDownHour = 17, leftDownMinute = 0, leftDownSecond = 0;
    int rightUpHour = 9, rightUpMinute = 30, rightUpSecond = 0;
    int rightDownHour = 17, rightDownMinute = 0, rightDownSecond = 0;
    
    unsigned long leftMotorTimeout = 36000; // Max run time for left motor (ms)
    unsigned long rightMotorTimeout = 36000; // Max run time for right motor (ms)
    
    // Debounce settings
    unsigned long debounceDelay = 50;
    unsigned long lastDebounceTime[8] = {0};
    
    // Button states
    bool buttonState[8] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};
    bool lastButtonState[8] = {HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH, HIGH};
    
    // State variables
    bool leftMotorActive = false, rightMotorActive = false;
    unsigned long leftMotorStartTime = 0;
    unsigned long rightMotorStartTime = 0;
    
    bool leftMovingUp = false, leftMovingDown = false;
    bool rightMovingUp = false, rightMovingDown = false;
    
    // Pause state variables
    bool leftMotorPaused = false;
    bool rightMotorPaused = false;
    
    // Menu variables
    enum MenuState { MAIN_MENU, EDIT_LEFT_UP, EDIT_LEFT_DOWN, EDIT_RIGHT_UP, EDIT_RIGHT_DOWN };
    MenuState currentMenu = MAIN_MENU;
    int editCursorPosition = 0; // 0: Hour, 1: Minute
    bool editing = false;
    unsigned long lastInteractionTime = 0;
    const unsigned long screenTimeout = 120000; // 30 seconds
    
    void setup() {
      Serial.begin(9600);
      pinMode(leftUpPin, OUTPUT);
      pinMode(leftDownPin, OUTPUT);
      pinMode(rightUpPin, OUTPUT);
      pinMode(rightDownPin, OUTPUT);
    
      pinMode(leftTopSensor, INPUT_PULLUP);
      pinMode(leftBottomSensor, INPUT_PULLUP);
      pinMode(rightTopSensor, INPUT_PULLUP);
      pinMode(rightBottomSensor, INPUT_PULLUP);
    
      pinMode(leftUpButton, INPUT_PULLUP);
      pinMode(leftDownButton, INPUT_PULLUP);
      pinMode(rightUpButton, INPUT_PULLUP);
      pinMode(rightDownButton, INPUT_PULLUP);
    
      pinMode(enterButton, INPUT_PULLUP);
      pinMode(backButton, INPUT_PULLUP);
      pinMode(upButton, INPUT_PULLUP);
      pinMode(downButton, INPUT_PULLUP);
    
      if (!rtc.begin()) {
        Serial.println("Couldn't find RTC");
        while (1);
      }
    
      if (rtc.lostPower()) {
        Serial.println("RTC lost power, setting time to compile time.");
        rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
      }
    
      if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
        Serial.println(F("SSD1306 allocation failed"));
        for (;;);
      }
    
      display.clearDisplay();
      display.display();
    }
    
    void loop() {
      DateTime now = rtc.now();
      unsigned long currentMillis = millis();
    
      // Automatic control
      handleAutomaticControl(now, currentMillis);
    
      // Manual control
      handleRoletyButtonControl(currentMillis);
    
      // Menu control
      handleMenuControl(currentMillis);
    
      // Stop motors if timeout or sensor triggered
      checkMotorStopConditions(currentMillis);
    
      // Update display
      if ((currentMillis - lastInteractionTime) < screenTimeout) {
        updateDisplay(now);
      } else {
        display.clearDisplay();
        display.display();
      }
    
      // Serial commands for setting time
      if (Serial.available()) {
        String command = Serial.readStringUntil('\n');
        handleSerialCommand(command);
      }
    }
    
    void handleAutomaticControl(DateTime now, unsigned long currentMillis) {
      if (now.hour() == leftUpHour && now.minute() == leftUpMinute && now.second() == leftUpSecond && !leftMotorActive) {
        moveLeftUp(currentMillis);
      }
      if (now.hour() == leftDownHour && now.minute() == leftDownMinute && now.second() == leftDownSecond && !leftMotorActive) {
        moveLeftDown(currentMillis);
      }
      if (now.hour() == rightUpHour && now.minute() == rightUpMinute && now.second() == rightUpSecond && !rightMotorActive) {
        moveRightUp(currentMillis);
      }
      if (now.hour() == rightDownHour && now.minute() == rightDownMinute && now.second() == rightDownSecond && !rightMotorActive) {
        moveRightDown(currentMillis);
      }
    }
    
    void handleRoletyButtonControl(unsigned long currentMillis) {
      int buttons[4] = {leftUpButton, leftDownButton, rightUpButton, rightDownButton};
      void (*actions[4])(unsigned long) = {moveLeftUp, moveLeftDown, moveRightUp, moveRightDown};
      bool *motorActive[4] = {&leftMotorActive, &leftMotorActive, &rightMotorActive, &rightMotorActive};
      bool *motorPaused[4] = {&leftMotorPaused, &leftMotorPaused, &rightMotorPaused, &rightMotorPaused};
      void (*stopActions[4])() = {stopLeftMotor, stopLeftMotor, stopRightMotor, stopRightMotor};
    
      for (int i = 0; i < 4; i++) {
        int reading = digitalRead(buttons[i]);
    
        if (reading != lastButtonState[i]) {
          lastDebounceTime[i] = currentMillis;
        }
    
        if ((currentMillis - lastDebounceTime[i]) > debounceDelay) {
          if (reading != buttonState[i]) {
            buttonState[i] = reading;
    
            if (buttonState[i] == LOW) { // Button pressed
              if (*motorActive[i]) {
                if (*motorPaused[i]) {
                  // Jeśli silnik jest wstrzymany, uruchom go ponownie
                  actions[i](currentMillis);
                  *motorPaused[i] = false;
                } else {
                  // Jeśli silnik działa, zatrzymaj go
                  stopActions[i]();
                  *motorPaused[i] = true;
                }
              } else {
                // Jeśli silnik nie działa, uruchom go
                actions[i](currentMillis);
              }
            }
          }
        }
        lastButtonState[i] = reading;
      }
    }
    
    void handleMenuControl(unsigned long currentMillis) {
      // Update last interaction time
      if (digitalRead(enterButton) == LOW || digitalRead(backButton) == LOW ||
          digitalRead(upButton) == LOW || digitalRead(downButton) == LOW) {
        lastInteractionTime = currentMillis;
      }
    
      if (digitalRead(enterButton) == LOW) {
        delay(200); // Debounce
        if (currentMenu == MAIN_MENU) {
          switch (editCursorPosition) {
            case 0: currentMenu = EDIT_LEFT_UP; break;
            case 1: currentMenu = EDIT_LEFT_DOWN; break;
            case 2: currentMenu = EDIT_RIGHT_UP; break;
            case 3: currentMenu = EDIT_RIGHT_DOWN; break;
          }
          editing = true;
        } else {
          editing = !editing;
        }
      }
    
      if (digitalRead(backButton) == LOW) {
        delay(200); // Debounce
        if (editing) {
          editing = false;
        } else {
          currentMenu = MAIN_MENU;
        }
      }
    
      if (digitalRead(upButton) == LOW) {
        delay(200); // Debounce
        if (currentMenu == MAIN_MENU) {
          editCursorPosition = (editCursorPosition + 3) % 4; // Wrap around
        } else if (editing) {
          adjustTime(true);
        }
      }
    
      if (digitalRead(downButton) == LOW) {
        delay(200); // Debounce
        if (currentMenu == MAIN_MENU) {
          editCursorPosition = (editCursorPosition + 1) % 4; // Wrap around
        } else if (editing) {
          adjustTime(false);
        }
      }
    }
    
    void adjustTime(bool increase) {
      int *hour, *minute;
      switch (currentMenu) {
        case EDIT_LEFT_UP: hour = &leftUpHour; minute = &leftUpMinute; break;
        case EDIT_LEFT_DOWN: hour = &leftDownHour; minute = &leftDownMinute; break;
        case EDIT_RIGHT_UP: hour = &rightUpHour; minute = &rightUpMinute; break;
        case EDIT_RIGHT_DOWN: hour = &rightDownHour; minute = &rightDownMinute; break;
      }
    
      if (increase) {
        *minute += 1;
        if (*minute >= 60) {
          *minute = 0;
          *hour = (*hour + 1) % 24;
        }
      } else {
        *minute -= 1;
        if (*minute < 0) {
          *minute = 59;
          *hour = (*hour - 1 + 24) % 24;
        }
      }
    }
    
    void updateDisplay(DateTime now) {
      display.clearDisplay();
    
      // Display current time
      display.setTextSize(1);
      display.setTextColor(SSD1306_WHITE);
      display.setCursor(30, 0);
      display.print("Time: ");
      display.print(now.hour());
      display.print(":");
      if (now.minute() < 10) display.print("0");
      display.print(now.minute());
    
      // Display menu
      display.setCursor(3, 12);
      display.print("LU: ");
      display.print(leftUpHour);
      display.print(":");
      if (leftUpMinute < 10) display.print("0");
      display.print(leftUpMinute);
    
      display.setCursor(64, 12);
      display.print("RU: ");
      display.print(rightUpHour);
      display.print(":");
      if (rightUpMinute < 10) display.print("0");
      display.print(rightUpMinute);
    
      display.setCursor(3, 22);
      display.print("LD: ");
      display.print(leftDownHour);
      display.print(":");
      if (leftDownMinute < 10) display.print("0");
      display.print(leftDownMinute);
    
      display.setCursor(64, 22);
      display.print("RD: ");
      display.print(rightDownHour);
      display.print(":");
      if (rightDownMinute < 10) display.print("0");
      display.print(rightDownMinute);
    
      // Highlight the selected menu item
      if (currentMenu == MAIN_MENU) {
        int yPos[] = {11, 21, 11, 21};
        int xPos[] = {2, 2, 63, 63};
        display.drawRect(xPos[editCursorPosition] - 2, yPos[editCursorPosition] - 1, 60, 11, SSD1306_WHITE);
      }
    
      // Flash the editable field if in edit mode
      if (editing && (millis() / 500) % 2) {
        int yPos = (editCursorPosition % 2 == 0) ? 11 : 21;
        int xPos = (editCursorPosition < 2) ? 2 : 63;
        display.fillRect(xPos, yPos, 60, 11, SSD1306_BLACK);
      }
    
      display.display();
    }
    
    void checkMotorStopConditions(unsigned long currentMillis) {
      if (leftMotorActive) {
        if ((currentMillis - leftMotorStartTime > leftMotorTimeout) ||
            (leftMovingUp && digitalRead(leftTopSensor) == HIGH) ||  // Sensor triggered
            (leftMovingDown && digitalRead(leftBottomSensor) == HIGH)) {
          stopLeftMotor();
        }
      }
      if (rightMotorActive) {
        if ((currentMillis - rightMotorStartTime > rightMotorTimeout) ||
            (rightMovingUp && digitalRead(rightTopSensor) == HIGH) ||  // Sensor triggered
            (rightMovingDown && digitalRead(rightBottomSensor) == HIGH)) {
          stopRightMotor();
        }
      }
    }
    
    void moveLeftUp(unsigned long currentMillis) {
      if (digitalRead(leftTopSensor) == LOW) { // Not at the top
        digitalWrite(leftUpPin, HIGH);
        digitalWrite(leftDownPin, LOW);
        leftMotorActive = true;
        leftMotorStartTime = currentMillis;
        leftMovingUp = true;
        leftMovingDown = false;
        Serial.println("Left motor moving up");
      }
    }
    
    void moveLeftDown(unsigned long currentMillis) {
      if (digitalRead(leftBottomSensor) == LOW) { // Not at the bottom
        digitalWrite(leftDownPin, HIGH);
        digitalWrite(leftUpPin, LOW);
        leftMotorActive = true;
        leftMotorStartTime = currentMillis;
        leftMovingDown = true;
        leftMovingUp = false;
        Serial.println("Left motor moving down");
      }
    }
    
    void moveRightUp(unsigned long currentMillis) {
      if (digitalRead(rightTopSensor) == LOW) { // Not at the top
        digitalWrite(rightUpPin, HIGH);
        digitalWrite(rightDownPin, LOW);
        rightMotorActive = true;
        rightMotorStartTime = currentMillis;
        rightMovingUp = true;
        rightMovingDown = false;
        Serial.println("Right motor moving up");
      }
    }
    
    void moveRightDown(unsigned long currentMillis) {
      if (digitalRead(rightBottomSensor) == LOW) { // Not at the bottom
        digitalWrite(rightDownPin, HIGH);
        digitalWrite(rightUpPin, LOW);
        rightMotorActive = true;
        rightMotorStartTime = currentMillis;
        rightMovingDown = true;
        rightMovingUp = false;
        Serial.println("Right motor moving down");
      }
    }
    
    void stopLeftMotor() {
      digitalWrite(leftUpPin, LOW);
      digitalWrite(leftDownPin, LOW);
      leftMotorActive = false;
      leftMotorStartTime = 0;
      leftMovingUp = false;
      leftMovingDown = false;
      Serial.println("Left motor stopped");
    }
    
    void stopRightMotor() {
      digitalWrite(rightUpPin, LOW);
      digitalWrite(rightDownPin, LOW);
      rightMotorActive = false;
      rightMotorStartTime = 0;
      rightMovingUp = false;
      rightMovingDown = false;
      Serial.println("Right motor stopped");
    }
    
    void handleSerialCommand(String command) {
      if (command.startsWith("SET ")) {
        int index = command.indexOf(' ');
        String data = command.substring(index + 1);
        int value = data.toInt();
    
        if (data.startsWith("LU ")) {
          leftUpHour = value / 100;
          leftUpMinute = value % 100;
          Serial.println("Left up time updated");
        } else if (data.startsWith("LD ")) {
          leftDownHour = value / 100;
          leftDownMinute = value % 100;
          Serial.println("Left down time updated");
        } else if (data.startsWith("RU ")) {
          rightUpHour = value / 100;
          rightUpMinute = value % 100;
          Serial.println("Right up time updated");
        } else if (data.startsWith("RD ")) {
          rightDownHour = value / 100;
          rightDownMinute = value % 100;
          Serial.println("Right down time updated");
        }
      }
    }
    

    Pliki wraz z pcb (sprintLayout 6.0)
    Załączniki:
    • Rolety ardu oled.rar (24.91 KB) Musisz być zalogowany, aby pobrać ten załącznik.

    Fajne? Ranking DIY
    O autorze
    hetm4n
    Poziom 20  
    Offline 
    hetm4n napisał 813 postów o ocenie 525, pomógł 5 razy. Mieszka w mieście Ruda Śląska. Jest z nami od 2007 roku.
  • REKLAMA
  • #2 21359942
    androot
    VIP Zasłużony dla elektroda
    Posty: 1801
    Pomógł: 54
    Ocena: 635
    Dlaczego nie użyłeś ESP? Miałbyś możliwość sterowania z telefonu czy przez przeglądarkę
  • #3 21359947
    TechEkspert
    Redaktor
    Posty: 7329
    Pomógł: 17
    Ocena: 5704
    Ładna obudowa, co to za materiał maskujący przyciski?
    Czy na CNC3018 dałoby radę zrobić PCB pod SMD np. SO8?
  • REKLAMA
  • #4 21359962
    ArturAVS
    Moderator
    Posty: 26433
    Pomógł: 2303
    Ocena: 7850
    androot napisał:
    Dlaczego nie użyłeś ESP?

    To samo miałem napisać :D Jednym kliknięciem można podnieść w całym domu :D. Stoję u siebie z podobnym dylematem, ale chyba się oprze o silniki krokowe, lub DC sterowane PWM.
  • #6 21360048
    sq3evp
    Poziom 39  
    Posty: 6742
    Pomógł: 226
    Ocena: 902
    androot napisał:
    Dlaczego nie użyłeś ESP? Miałbyś możliwość sterowania z telefonu czy przez przeglądarkę

    No tak to by było możliwe, ale czasem wystarczy sterowanie klawiszami, bez zdalnego sterowania.
    Projekt ciekawy - jak dla mnie zadanie swoje spełnia.
  • #7 21360062
    slaw0
    Poziom 16  
    Posty: 189
    Pomógł: 8
    Ocena: 112
    ArturAVS napisał:
    Stoję u siebie z podobnym dylematem, ale chyba się oprze o silniki krokowe, lub DC sterowane PWM.

    Krokowe lepiej. U siebie mam na takich małych 5v z przekładnią. Wystarczy jeden czujnik. Tzw referencyjny (ja mam u góry). Po włączeniu zasilania robi najazd, a później już tylko liczy kroki.
  • REKLAMA
  • #8 21360140
    efi222
    Poziom 22  
    Posty: 779
    Pomógł: 12
    Ocena: 1220
    PCB domowej roboty. Mam zawsze obawy co do tak małego odstępu ścieżek do poligonu masy. To niskie napięcia, jednak coś się może niedotrawić i zawsze staram się robić szerszy odstęp. To nie krytyka, tylko takie tam moje spostrzeżenia..
  • REKLAMA
  • #9 21360326
    hetm4n
    Poziom 20  
    Posty: 813
    Pomógł: 5
    Ocena: 525
    TechEkspert napisał:
    Ładna obudowa, co to za materiał maskujący przyciski?
    Czy na CNC3018 dałoby radę zrobić PCB pod SMD np. SO8?

    Bezproblemu, Robiłem płytki pod atmege128.

    slaw0 napisał:
    ArturAVS napisał:
    Stoję u siebie z podobnym dylematem, ale chyba się oprze o silniki krokowe, lub DC sterowane PWM.

    Krokowe lepiej. U siebie mam na takich małych 5v z przekładnią. Wystarczy jeden czujnik. Tzw referencyjny (ja mam u góry). Po włączeniu zasilania robi najazd, a później już tylko liczy kroki.


    był kiedyś taki pomysł, ale zostałem przy tym co miałem w szufladzie. ogólnie mam 2 okna tak samo sterowane lecz poprzez PLC oraz HMI które 6 lat temu zrobiłem. 3 okno zrobiłem na arduino, bo do plc bym musiał kolejny moduł rozszerzeń dodać a to nietanie rzeczy :D i ciągnąć kable przez pół mieszkania.

    efi222 napisał:
    PCB domowej roboty. Mam zawsze obawy co do tak małego odstępu ścieżek do poligonu masy. To niskie napięcia, jednak coś się może nie dotrawić i zawsze staram się robić szerszy odstęp. To nie krytyka, tylko takie tam moje spostrzeżenia..

    tu u mnie niema co sie nie dotrawić bo pcb jest frezowane na głębokość 0.1mm, ewentualnie mogło by coś wpaść i zwierać, zawsze można psiknąć warstwę zabezpieczającą :)
  • #10 21360671
    krzbor
    Poziom 29  
    Posty: 1785
    Pomógł: 42
    Ocena: 1072
    ArturAVS napisał:
    androot napisał:
    Dlaczego nie użyłeś ESP?

    To samo miałem napisać :D Jednym kliknięciem można podnieść w całym domu :D. Stoję u siebie z podobnym dylematem, ale chyba się oprze o silniki krokowe, lub DC sterowane PWM.

    To już lepiej ZigBee. Powstanie nam od razu ładna sieć mesh. Teraz dodajemy przyciski, wyłączniki, żarówki, czujnik CO2, czujnik zalania, kontaktrony - tu lista 4000 urządzeń, które możemy podłączyć Link. Do tego jeden HA.
  • #11 21360746
    george2002

    Poziom 21  
    Posty: 526
    Ocena: 158
    hetm4n napisał:
    Program napisany "kompilatorem" Chat GTP 4.0

    Zainspirował kolega - coś więcej co jak gdzie dla czego w tym temacie ;) ?
    Konto firmowe:
    GS electronic Grzegorz Stoliński
    2 Pułku Lotniczego 18, Kraków, 31-857 | Strona WWW: www.gselectronic.pl
  • #12 21360776
    lopr_pol
    Poziom 32  
    Posty: 1727
    Pomógł: 164
    Ocena: 491
    androot napisał:
    Dlaczego nie użyłeś ESP? Miałbyś możliwość sterowania z telefonu czy przez przeglądarkę

    Właśnie, podchodzenie do rolet żeby nacisnąć przycisk trochę bez celu, no niby jest tam jakiś timer.
    Ja zrobiłem na początku na pilota ir, później już na esp32 z prostymi krokowcami z przekładnią, mam sterowanie po ir i przez sieć plus odliczanie kroków czyli zasłanianie okna w procentach jakich chce.
    Panel sterowania roletami z procentowym wskaźnikiem.
  • #13 21361609
    hetm4n
    Poziom 20  
    Posty: 813
    Pomógł: 5
    Ocena: 525
    >>21360776 ja nie chcę w ogóle podchodzić. Mnie tylko interesuje samoczynne rozwijanie i zasuwanie o wybranych godzinach. Sterowanie ręczne to przy okazji bo czasami chcę sobie do filmu przysłonić, lub zajrzeć wieczorem co się za oknem wyprawia :) wszelkie bajery tupu kontrola przez smartfon , wi fi mi niepotrzebna :) miało być prosto i tanio.

    George2002 wejdź sobie na chatgtp w przegladarce i zobacz jak dobrze sobie radzi z programowaniem. Ewentualnie zapytaj elektrodabota :)
Słuchaj:

Podsumowanie tematu

LABEL_AI_GENERATED
W dyskusji poruszono projekt automatycznych rolet oparty na Arduino Nano, który obsługuje dwie rolety niezależnie. Użytkownik zaprezentował funkcje takie jak automatyczne otwieranie i zamykanie o określonej godzinie, ręczne sterowanie oraz wykorzystanie czujników kontaktronowych do detekcji pozycji krańcowych. W odpowiedziach zasugerowano alternatywy, takie jak użycie ESP dla zdalnego sterowania, a także omówiono różne metody napędu, w tym silniki krokowe i DC. Uczestnicy dyskusji dzielili się doświadczeniami związanymi z projektowaniem PCB oraz zastosowaniem różnych komponentów, takich jak RTC DS3231 i wyświetlacz OLED SSD1306.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA