Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Sterowanie roletami przewodowymi co wpisać w programie

klakier_2006 16 Jan 2018 13:44 3459 13
Ochrona Domu
  • #1
    klakier_2006
    Level 9  
    Witam. Mam zainstalowanego domoticza na raspberry pi 3 i chcę go używać do prostej automatyki domowej. Do maliny mam podpięte arduino uno przez usb i korzystam z biblioteki mysensors. Problem dotyczy sterowania roletami okiennymi. Chce sterować tadycyjnymi przewodowymi roletami za pomocą przekaźników sterowanych przez arduino i dodatkowo z zachowaniem możliwości otwierania i zamykania rolet za pomocą przycisków. Dla każdej rolety przeznaczam w arduino po dwa releye - jeden roleta w górę, drugi - roleta w dół. Każdy z przekaźnik ma przypisany swój przycisk w domoticzu typu on/off. To rozwiązanie jest jednak wadliwe poniewąż istnieje możliwość jednoczesnego załączenia przekaźnika odpowiadającego za podnoszenie jak i za opuszczania rolety. Pytanie brzmi jak zrobić żeby załącznie jednego przekaźnika dawało automatycznie informację do arduino o konieczności wyłączenia dugiego przekaźnika.
    Do you have a problem with Arduino? Ask question. Visit our forum Arduino.
  • Ochrona Domu
  • #2
    czareqpl
    Level 31  
    klakier_2006 wrote:
    Pytanie brzmi jak zrobić żeby załącznie jednego przekaźnika dawało automatycznie informację do arduino o konieczności wyłączenia dugiego przekaźnika.


    Wystarczy dopisać w kodzie polecenie wyłączenia obu przekaźników zanim zostanie wykonana procedura włączenia jednego z nich...
  • Ochrona Domu
  • #3
    k9mil
    Level 16  
    klakier_2006 wrote:
    To rozwiązanie jest jednak wadliwe poniewąż istnieje możliwość jednoczesnego załączenia przekaźnika odpowiadającego za podnoszenie jak i za opuszczania rolety

    Połącz przekaźniki według tego schematu i będziesz fizycznie zabezpieczony przed podaniem zasilania na zamykanie i otwieranie naraz.
    Sterowanie roletami przewodowymi co wpisać w programie
  • #4
    Darek0026
    Level 26  
    k9mil wrote:
    klakier_2006 wrote:
    To rozwiązanie jest jednak wadliwe poniewąż istnieje możliwość jednoczesnego załączenia przekaźnika odpowiadającego za podnoszenie jak i za opuszczania rolety

    Połącz przekaźniki według tego schematu i będziesz fizycznie zabezpieczony przed podaniem zasilania na zamykanie i otwieranie naraz.
    Sterowanie roletami przewodowymi co wpisać w programie


    Ten schemat jest prawidłowy lecz w praktyce stosuje sie trzy przekaźniki do sterowania silnika. Trzeci odłącza "N" od silniki dla bezpieczeństwa.
  • #5
    klakier_2006
    Level 9  
    Dzięki za zainteresowanie moim problemem, ale czy możecie mi podpowiedzieć jak ma brzmieć to polecenie wyłączające przekaźniki i w którym miejscu je wpisać. Nie ukrywam że jestem totalnym nowicjuszem jak chodzi o arduino. Jako załącznik dorzucam plik z moim sketch-em. Jest on napisany pod kontem sterowania dwoma roletami.



    Code: csharp
    Log in, to see the code
  • #6
    k9mil
    Level 16  
    Jeśli połączysz przekaźniki taj jak jest narysowane w poprzednim schemacie to fizycznie niemożliwe będzie podanie zasilania na otwieranie i zmaykanie.

    klakier_2006 wrote:
    Dzięki za zainteresowanie moim problemem, ale czy możecie mi podpowiedzieć jak ma brzmieć to polecenie wyłączające przekaźniki i w którym miejscu je wpisać. Nie ukrywam że jestem totalnym nowicjuszem jak chodzi o arduino. Jako załącznik dorzucam plik z moim sketch-em. Jest on napisany pod kontem sterowania dwoma roletami.

    Np. tak jeśli za sterowanie rolet odpowiadają odpowiedni RELAY1 i RELAY2 oraz RELAY3 i RELAY4.
    Code: c
    Log in, to see the code
  • #7
    klakier_2006
    Level 9  
    Schemat zabezpiecza mnie przed podaniem jednoczesnego napięcia na dwa kierunki, jednak wolałbym rozwiązać tę kwestię softwerowo ponieważ wszystkim ma sterować domoticz na rastberry pi i jeżeli podpinam to według schematu, to efekt jest taki gdy załączone są dwa przekaźniki to roleta jedzie w jednym kierunku, gdy wyłączone obydwa to w drugim kierunku, jeśli jeden włączony a drugi załączony to stoi. Jest to połowiczny sukces bo na panelu domoticza nie da się wtedy opisać który włącznik odpowiada za podnoszenie, a który za opuszczenie rolety, co powoduje haos, tym bardziej, że prawdę mówiąc, jest to dopiero model. Docelowo rolet ma być 12 szt. Chciałbym jescze żeby jeden z przycisków "A" na arduino przypisać w ten sposób że opuszcza wszystkie rolety i wszystkie podnosi. Czy wedłóg Was takie coś takiego da się wykonać?
  • Helpful post
    #8
    es2
    Level 16  
    klakier_2006 wrote:
    Schemat zabezpiecza mnie przed podaniem jednoczesnego napięcia na dwa kierunki, jednak wolałbym rozwiązać tę kwestię softwerowo

    Stwórz funkcję np
    Code: c
    Log in, to see the code

    Wywołuj ją gdzie trzeba z odpowiednim parametrem i masz zabezpieczenie programowo. naturalnie, zamiast dir==1 zdefiniuj stale z kiernunkiem np
    Code: c
    Log in, to see the code


    klakier_2006 wrote:

    ponieważ wszystkim ma sterować domoticz na rastberry pi i jeżeli podpinam to według schematu, to efekt jest taki gdy załączone są dwa przekaźniki to roleta jedzie w jednym kierunku, gdy wyłączone obydwa to w drugim kierunku, jeśli jeden włączony a drugi załączony to stoi.

    To masz coś źle podłączone bo ze schematu wynika cos innego.
  • #9
    klakier_2006
    Level 9  
    Sprawdziłem wszystko jeszcze raz i faktycznie źle podłączyłem. Wszystko zadziałało. Dzięki.
  • #10
    mchrzan
    Level 5  
    Witam
    I jak działa ci to rozwiązanie ?
    Też chciałem ogarnać całość przewodowo żeby nie mieć 12 wifi nad głową
    możesz napisać jak to masz ogarnięte ?
    ile kabli idzie z rolet od rolet do centrali itp ?
    u mnie wygląda to tak
    z rolety idzie kabel 4 żyłowy do puszki, a z puszki 5 żyłowy do jednej skrzynki
    jak to dalej ogarnąć możesz pomóc ?
  • #11
    boe6666
    Level 7  
    Jeśli mogę coś dorzucić. Mam identyczną instalację w domu. Rolety klasyczne, sterowane ręcznym wyłącznikiem rolet (mechaniczne zabezpieczenie przed zwarcie obu na raz). Do sterowania roletami użyłem 2 przekaźników, jednakże podłączenia styków roboczych wykonałem w taki sposób iż jeśli którykolwiek przekaźnik jest załączony, odcina jednocześnie fazę idącą na wyłącznik rolet. Efekt jest taki że jak roleta działa z domoticza to fizycznie nie działają wyłączniki ścienne. (schemat jest prosty - przeanalizuj dokładnie - da się to tak podłączyć). Co się tyczy samego sterowania - wystarczy funkcję załączającą dany stycznik poprzedzić - tak jak już zostało to napisane - wyłączeniem drugiego stycznika (stan LO) sparowanego z pierwszym. Ja tą opercję dopisałem w arduino (kiedyś atmega teraz stm32) i niezależnie jak będę tym sterował z poziomu domoticza - nigdy nie nastąpi zwarcie obu styczników.
    Mam nadzieję że coś pomogłem pozdrawiam.
  • #12
    omnixcrs
    Level 11  
    Ja uważam, że nie ma co kombinować programowo, program zawsze może zgłupieć lub się zawiesić i wtedy leżysz. Zabezpieczenie przed podaniem dwóch faz na raz realizuje się na stykach przekaźników. Do sterowania roletą używa się dwóch przekaźników o stykach SPDT czyli jeden zwierny i jeden rozwierny. Spójrz na kawałek mojego schematu jak to podłączyć:
    Sterowanie roletami przewodowymi co wpisać w programie

    oczywiście RG i RD na rysunko to faza na roletę w górę i w dół
  • #13
    boe6666
    Level 7  
    Masz rację, teraz sobie przypominałem że podłączenie o którym pisałem wcześniej, również wyklucza podanie obu faz na raz z obu styczników :) Jest to poniekąd logiczne, ale nie wspomniałem o tym. Co do zmian w arduino - owszem masz rację że program może się zawiesić, ale lepiej dopisać to wyłączenie. Z praktyki - od 2 lat używam różnych kombinacji sprzętowych i jeszcze się nie zdarzyło żeby się program zawiesił - no ale zawsze może się zdarzyć.

    Jeszcze jedno jeśli można - nie rozwiązałem jeszcze problemu ze stanem otwarcia rolet i ew. zabezpieczeniem przed zablokowaniem pancerza - silniki mam zwykłe bez enkoderów i bez przeciążeniówek. Rozważałem potencjometr wieloobrotowy + mechanizm linkowy ze sprężyną, ale to dość skomplikowane.

    Chyba najlepszy byłby impulsator obrotowy + jakiś kółeczko na samej górze pancerza. Chodzi o to że przy rozwijaniu rolety - w przypadku zablokowania pancerza - może dojść do kompletnego zniszczenia pancerza i kasety... Ktoś to może rozwiązał. ???
  • #14
    marpac09
    Level 1  
    witam czy jest mi w stanie ktos pomoc w powieleniu tego skechu na dwie rolety. juz nic mi do głowy nie przychodzi.// Enable debug prints to serial monitor

    Dodano po 41 [sekundy]:

    // Enable debug prints to serial monitor
    #define MY_DEBUG

    #define MY_GATEWAY_SERIAL

    // Enable and select radio type attached
    //#define MY_RADIO_NRF24

    //#define MY_RF24_PA_LEVEL RF24_PA_LOW

    //#define MY_REPEATER_FEATURE

    // uncomment if we want to manually assign an ID/////////////////////////////////////////////////////////////
    //#define MY_NODE_ID 1
    // Define a lower baud rate for Arduino's running on 8 MHz (Arduino Pro Mini 3.3V & SenseBender)
    //#if F_CPU == 8000000L
    //#define MY_BAUD_RATE 38400
    //#endif

    // Flash leds on rx/tx/err
    // #define MY_LEDS_BLINKING_FEATURE
    // Set blinking period
    // #define MY_DEFAULT_LED_BLINK_PERIOD 300

    // Inverses the behavior of leds
    // #define MY_WITH_LEDS_BLINKING_INVERSE

    // Enable inclusion mode
    #define MY_INCLUSION_MODE_FEATURE
    // Enable Inclusion mode button on gateway
    #define MY_INCLUSION_BUTTON_FEATURE

    // Inverses behavior of inclusion button (if using external pullup)
    //#define MY_INCLUSION_BUTTON_EXTERNAL_PULLUP

    // Set inclusion mode duration (in seconds)
    #define MY_INCLUSION_MODE_DURATION 60
    // Digital pin used for inclusion mode button
    #define MY_INCLUSION_MODE_BUTTON_PIN 3

    // Uncomment to override default HW configurations
    //#define MY_DEFAULT_ERR_LED_PIN 4 // Error led pin
    //#define MY_DEFAULT_RX_LED_PIN 6 // Receive led pin
    //#define MY_DEFAULT_TX_LED_PIN 5 // the PCB, on board LED

    #include <Bounce2.h>
    #include <MySensors.h>
    #include <SPI.h>

    #define BUTTON_UP 54// Arduino Digital I/O pin number for up button
    #define BUTTON_DOWN 55 // Arduino Digital I/O pin number for down button
    //#define BUTTON_STOP_PIN 5 // Arduino Digital I/O pin number for stop button
    //#define RELAY_DIR_PIN 6 // Arduino Digital I/O pin number for direction relay
    //#define RELAY_POWER_PIN 7 // Arduino Digital I/O pin number for power relay
    #define RELAY_UP 22
    #define RELAY_DOWN 23
    #define NUMBER_OF_RELAYS 2
    #define RELAY_ON 1
    #define RELAY_OFF 0
    //#define RELAY_DOWN 1
    //#define RELAY_UP 0
    #define DIRECTION_DOWN 0
    #define DIRECTION_UP 1
    #define SKETCH_NAME "Cover by Marek"
    #define SKETCH_VER "1.0"
    #define CHILD_ID_COVER 0 // sensor Id of the sensor child
    #define STATE_UP 100 // 100 is open - up
    #define STATE_DOWN 0 // 0 is closed - down
    //#define CHILD_ID_CALIBRATE 1 // sensor Id of the sensor child to calibrate
    #define CHILD_ID_SET 1 // sensor Id of the sensor child to init the roll time
    #define PRESENT_MESSAGE "Cover sensor for hass"
    const int LEVELS = 100; //the number of levels
    float rollTime = 10.0; //the overall rolling time of the shutter
    const bool IS_ACK = false; //is to acknowlage
    static bool initial_state_sent = false;//for hass we need at list one state send at begining

    // debouncing parameters
    int value = 0;
    int oldValueUp = 0;
    int oldValueDown = 0;
    int oldValueStop = 0;
    //static unsigned long last_interrupt_time_up = 0;
    //static unsigned long last_interrupt_time_down = 0;
    //static unsigned long debounce_time = 200;

    Bounce debouncerUp = Bounce();
    Bounce debouncerDown = Bounce();
    Bounce debouncerStop = Bounce();

    // shutter position parameters
    float timeOneLevel = rollTime / LEVELS;
    int requestedShutterLevel = 0;
    int currentShutterLevel = 0;
    unsigned long lastLevelTime = 0;
    bool isMoving = false;
    int directionUpDown;

    enum CoverState {
    STOP,
    UP, // Window covering. Up.
    DOWN, // Window covering. Down.
    };

    static int coverState = STOP;

    MyMessage msgUp(CHILD_ID_COVER, V_UP);
    MyMessage msgDown(CHILD_ID_COVER, V_DOWN);
    MyMessage msgStop(CHILD_ID_COVER, V_STOP);
    MyMessage msgPercentage(CHILD_ID_COVER, V_PERCENTAGE);
    //MyMessage msgCode(CHILD_ID_SET, V_IR_SEND);

    void sendState() {
    // Send current state and status to gateway.
    send(msgUp.set(coverState == UP));
    send(msgDown.set(coverState == DOWN));
    send(msgStop.set(coverState == STOP));
    send(msgPercentage.set(currentShutterLevel));
    }

    void shuttersUp(void) {
    #ifdef MY_DEBUG
    Serial.println("Shutters going up");
    #endif
    if (digitalRead(RELAY_DOWN) == RELAY_ON) {
    digitalWrite(RELAY_DOWN, RELAY_OFF);
    wait(50);
    }
    digitalWrite(RELAY_UP, RELAY_ON);

    directionUpDown = DIRECTION_UP;
    isMoving = true;
    coverState = UP;
    sendState();
    }

    void shuttersDown(void) {
    #ifdef MY_DEBUG
    Serial.println("Shutters going down");
    #endif
    if (digitalRead(RELAY_UP) == RELAY_ON) {
    digitalWrite(RELAY_UP, RELAY_OFF);
    wait(50);
    }
    digitalWrite(RELAY_DOWN, RELAY_ON);

    directionUpDown = DIRECTION_DOWN;
    isMoving = true;
    coverState = DOWN;
    sendState();
    }

    void shuttersHalt(void) {
    #ifdef MY_DEBUG
    Serial.println("Shutters halted");
    #endif
    digitalWrite(RELAY_UP, RELAY_OFF);
    digitalWrite(RELAY_DOWN, RELAY_OFF);

    isMoving = false;
    requestedShutterLevel = currentShutterLevel;
    #ifdef MY_DEBUG
    Serial.println("saving state to: ");
    Serial.println(String(currentShutterLevel));
    #endif
    saveState(CHILD_ID_COVER, currentShutterLevel);
    coverState = STOP;
    sendState();
    }

    void changeShuttersLevel(int level) {
    int dir = (level > currentShutterLevel) ? DIRECTION_UP : DIRECTION_DOWN;
    if (isMoving && dir != directionUpDown) {
    shuttersHalt();
    }
    requestedShutterLevel = level;
    }

    void initShutters() {
    #ifdef MY_DEBUG
    Serial.println("Init Cover");
    #endif
    shuttersUp();
    wait((rollTime + timeOneLevel * LEVELS) * 1000);
    currentShutterLevel = STATE_UP;
    requestedShutterLevel = currentShutterLevel;
    }

    void receive(const MyMessage &message) {
    #ifdef MY_DEBUG
    Serial.println("recieved incomming message");
    Serial.println("Recieved message for sensor: ");
    Serial.println(String(message.sensor));
    Serial.println("Recieved message with type: ");
    Serial.println(String(message.type));
    #endif
    if (message.sensor == CHILD_ID_COVER) {
    switch (message.type) {
    case V_UP:
    //Serial.println(", New status: V_UP");
    changeShuttersLevel(STATE_UP);
    //state = UP;
    //sendState();
    break;

    case V_DOWN:
    //Serial.println(", New status: V_DOWN");
    changeShuttersLevel(STATE_DOWN);
    //state = DOWN;
    //sendState();
    break;

    case V_STOP:
    //Serial.println(", New status: V_STOP");
    shuttersHalt();
    //state = IDLE;
    //sendState();
    break;

    case V_PERCENTAGE:
    //Serial.println(", New status: V_PERCENTAGE");
    // if (!initial_state_sent) {
    // #ifdef MY_DEBUG
    // Serial.println("Receiving initial value from controller");
    // #endif
    // initial_state_sent = true;
    // }
    int per = message.getInt();
    if (per > STATE_UP) {
    per = STATE_UP;
    }
    changeShuttersLevel(per);
    //InitShutters(message.getInt());//send value < 0 or > 100 to calibrate
    //sendState();
    break;
    }
    }
    else if (message.sensor == CHILD_ID_SET) {

    if (message.type == V_VAR1) {
    #ifdef MY_DEBUG
    Serial.println(", New status: V_VAR1, with payload: ");
    #endif
    String strRollTime = message.getString();
    rollTime = strRollTime.toFloat();
    #ifdef MY_DEBUG
    Serial.println("rolltime value: ");
    Serial.println(String(rollTime));
    #endif
    saveState(CHILD_ID_SET, rollTime);
    }
    }
    #ifdef MY_DEBUG
    Serial.println("exiting incoming message");
    #endif
    return;
    }

    void before() {

    // Setup the button
    pinMode(BUTTON_UP, INPUT_PULLUP);
    // Activate internal pull-up
    // digitalWrite(BUTTON_UP_PIN, HIGH);
    // attachInterrupt(digitalPinToInterrupt(BUTTON_UP_PIN), upButtonPress, FALLING);

    pinMode(BUTTON_DOWN, INPUT_PULLUP);
    // Activate internal pull-up
    // digitalWrite(BUTTON_DOWN_PIN, HIGH);
    // attachInterrupt(digitalPinToInterrupt(BUTTON_DOWN_PIN), downButtonPress, FALLING);

    // pinMode(BUTTON_STOP_PIN, INPUT_PULLUP);
    // Activate internal pull-up
    // digitalWrite(BUTTON_STOP_PIN, HIGH);

    // After setting up the button, setup debouncer
    debouncerUp.attach(BUTTON_UP);
    debouncerUp.interval(5);
    // After setting up the button, setup debouncer
    debouncerDown.attach(BUTTON_DOWN);
    debouncerDown.interval(5);
    // After setting up the button, setup debouncer
    // debouncerStop.attach(BUTTON_STOP_PIN);
    // debouncerStop.interval(5);

    // Make sure relays are off when starting up
    digitalWrite(RELAY_UP, RELAY_OFF);
    // Then set relay pins in output mode
    pinMode(RELAY_UP, OUTPUT);

    // Make sure relays are off when starting up
    digitalWrite(RELAY_DOWN, RELAY_OFF);
    // Then set relay pins in output mode
    pinMode(RELAY_DOWN, OUTPUT);
    }

    void presentation() {
    // Send the sketch version information to the gateway and Controller
    sendSketchInfo(SKETCH_NAME, SKETCH_VER);
    // Register all sensors to gw (they will be created as child devices)
    present(CHILD_ID_COVER, S_COVER, PRESENT_MESSAGE, IS_ACK);
    // present(CHILD_ID_SET, S_CUSTOM);
    }

    void setup(void) {
    //set up roll time if the saved value is not 255
    #ifdef MY_DEBUG
    Serial.println("getting rolltime from eeprom: ");
    #endif
    float tmpRollTime = loadState(CHILD_ID_SET);
    if (tmpRollTime != 0xff) {
    rollTime = tmpRollTime;
    }
    #ifdef MY_DEBUG
    Serial.println(String(rollTime));
    #endif

    int state = loadState(CHILD_ID_COVER);

    #ifdef MY_DEBUG
    Serial.println("getting state from eeprom: ");
    Serial.println(String(state));
    #endif

    if (state == 0xff) {
    initShutters();
    } else {
    changeShuttersLevel(state);
    }
    }

    void loop(void) {
    if (!initial_state_sent) {
    #ifdef MY_DEBUG
    Serial.println("Sending initial value");
    #endif
    sendState();

    // send(msgCode.set('20.0'));
    // #ifdef MY_DEBUG
    // Serial.println("Requesting initial value from controller");
    // #endif
    // request(CHILD_ID_COVER, V_PERCENTAGE);
    // wait(2000, C_SET, V_PERCENTAGE);
    initial_state_sent = true;
    }

    debouncerUp.update();
    value = debouncerUp.read();
    if (value == 0 && value != oldValueUp) {
    if(isMoving){
    shuttersHalt();
    }
    else{
    changeShuttersLevel(STATE_UP);
    }
    //state = UP;
    //sendState();
    }
    oldValueUp = value;

    debouncerDown.update();
    value = debouncerDown.read();
    if (value == 0 && value != oldValueDown) {
    if(isMoving){
    shuttersHalt();
    }
    else{
    changeShuttersLevel(STATE_DOWN);
    }
    //state = DOWN;
    //sendState();
    }
    oldValueDown = value;

    /* debouncerStop.update();
    value = debouncerStop.read();
    if (value == 0 && value != oldValueStop) {
    shuttersHalt();
    //state = IDLE;
    //sendState();
    }
    oldValueStop = value;
    */

    if (isMoving) {
    unsigned long _now = millis();
    if (_now - lastLevelTime >= timeOneLevel * 1000) {
    if (directionUpDown == DIRECTION_UP) {
    currentShutterLevel += 1;
    } else {
    currentShutterLevel -= 1;
    }
    #ifdef MY_DEBUG
    Serial.println(String(requestedShutterLevel));
    Serial.println(String(currentShutterLevel));
    #endif
    lastLevelTime = millis();
    send(msgPercentage.set(currentShutterLevel));
    }
    if (currentShutterLevel == requestedShutterLevel) {
    shuttersHalt();
    }
    }
    else if (requestedShutterLevel != currentShutterLevel) {
    if (requestedShutterLevel > currentShutterLevel) {
    shuttersUp();
    }
    else {
    shuttersDown();
    }
    lastLevelTime = millis();
    }
    }