stefanbode / Sonoff-Tasmota

Provide ESP8266 based itead Sonoff with Web, MQTT and OTA firmware using Arduino IDE, enhanced with I2C options
GNU General Public License v3.0
126 stars 40 forks source link

Positions are volatile #67

Closed FauthD closed 6 years ago

FauthD commented 6 years ago

Hi, after a few days, the shutter won't close completely anymore. Then I have to reset the positions as described in the wiki. My guess is that the time to open or close are not accurate enough (should be 1/10 of a second). My times used to be 16 for down and 17 for up. As a test I now use 1 second more, and that improves at least (I have a bash script that does that automatically, will place it as example into wiki). Analyzing the firmware source shows that open/close just pass the % value (100 or 0) to the position function. So all errors in position will collect up. My first idea to fix that would be to turn on the relay for the direction as long as the up/down time is configured. Then set the internal position accordingly to full open/close. This would remove the error if the shutters get closed every night (as I do it). The motor does stop internally if it recognizes the end of a direction.

I will try to provide a patch, but will take a few weeks. There is some code that handles the first 5% in special way, that part I do not understand why it is there yet. I assume it is for another kind of blinds. Found this picture in wikipedia: https://de.wikipedia.org/wiki/Datei:L-Jalousie.png Mine are looking like this wikipedia picture: https://de.wikipedia.org/wiki/Datei:L-Rollladen.png These are very common in Germany. (time to position is not a linear math function with them, that could also influence the error)

Dieter :-)

stefanbode commented 6 years ago

Great input. My close duration is a bit longer than required. This ensure with every open blinds I reset it automatically other software like homematic solve this issue by doing a calibration after some time of operation when not reaching an endstop

abaszczok commented 6 years ago

I think all the time there is request to 100% or 0% - we should use this opportunity to keep the relay longer active to "re-calibrate" zero position. I don't think that any 1/10 sec will solve issue of position drift this is just time controlled motor! I agree that zero calibration should be possible to execute over the night i.e. once per week. Simply run to 100% or 0% then back to its previous state. I think the best way would be to implement it and call it by certain "pay_load".... BTW ... Stefan I was struggling five days with Platfomio , Vsd, Arduino..etc still no progress ( user_config_override.h - no such file or directory..) I tried several installations, three different computers (including fresh WIN7 installation) ..Once I press build I got error..

stefanbode commented 6 years ago

Hi @abaszczok . As written in a post before just add an empty user_config_override.h and it should work. This file is for you personal settings and compiler options if you have one. My shutter have an electrical/mechanical end stop. Therfore operating longer is not an issue to destroy something. Therefore my closeduration is 1s longer than required. This ensures that after every close I'm back at the calibrated end stop. Just easy. Doing movements at night is definitely not a good idea. My wife will go crazy. The only thing that might be an idea is to sum the seconds you operate and hit not the 0 position. If you exceed the limit the next shutterposition or shutterclose will add 10% driving time to ensure you're at 0 and then drive to the position. As mentioned, this is the way how homatic is doing it because you will never get the drift completely removed. Anyhow short-term solution is to increase the closeduration (100 -> 0, non inverted). Regarding the 5% stuff. The idea is to have 50% open when you send it to shutterposition 50. German shutters like you showed needs to operate after full close until the bottom one segment start moving. Without compensation worst case you set position 20 and at the end the button most segment still hits the ground. When the last segment starts moving, the movement is quite linear. not exact, but nearly. I know about the diameter change. With the compensation, you can use 50 or 80 to get it to the right position (50% open, 80% open) and 5 or 10 just to open the small light holes between the segments.

stefanbode commented 6 years ago

Hi Dieter,

if you increase the closeduration 1 more second you should be done. Because then the electrical endstop executes before TASMOTA. This initiate an auto-calibration. There is no code change required.

en set the internal position accordingly to full o

abaszczok commented 6 years ago

@Stefan - I tried to create empty file it is not woking.. It seems that I'm to stupid to do it or I'm missing some important steps.. Maybe one of you could prepare virtual machine (i.e. VmarePlayer) with properly working ArduinoIDE or PlaformIO..ON the other hand if you could prepare *.bin file with MQTT timeout 10seconds I will stop spamming you :) Thx guys.

stefanbode commented 6 years ago

No Problem. Every start is maybe a bit hard. Alternative2: Delete line: 399 in user_config.h

#include <user_config_override.h>

stefanbode commented 6 years ago

hi @FauthD , did it worked for you now with the slightly higher durations?

abaszczok commented 6 years ago

@stefan - Many thx to you for your help. Finally a colleague has showed me how to add properly user_config_overide.h file. Now it works perfectly. I also changed MQTT Timeout from 1 to 10 seconds - and indeed this was my issue with hbmqtt (homeassistant standard MQTT brooker). thx. sorry for off-topic.

FauthD commented 6 years ago

@Stefan the increased time did not solve it. Still looses exact positions. I need to run my calibration script every 3..4 days. The bash script sends MQTT commands and first turns off the shutter mode, then closes shutter with with a long time (+20 seconds). Then turn it back on, reboot the T1, sets times and 50% value, reboot, sets shutter to 50% as a test. I have 3 shutters right now and they differ about 10cm at 50%. I assume the speed of the motors is different (same brand/model). Tough 10cm tolerance is acceptable. After 2 days it is much more, one shutter does not close anymore, it stops at ~25cm from bottom. In case it is important, I use Home Assistant.

I hoped to find time today change the code, so it runs with max time instead 100/0 position, but that did not work out - too many other stuff ongoing in life :-)

abaszczok commented 6 years ago

@FauthD. I got an idea.. Could you please record with camera how one of your roller shutter operates...put it to youtube.. Than based on your video we will try to estimate times which supoose to be programmed in sonoff. This way we will have great example how to setup all options and evantualy what to change in cimmands.. I think most of the problems are due to wrong time setup. Regards

FauthD commented 6 years ago

Very good idea. Will do. I just observed a big non linearity. (My automation sets the shuttter on west side to 20% if it is warn enough outside. As I entered the room it was at ~75% from viewing it. Let me add this table:

pos set; real pos (with eye)
60         100 
at 55 it moves slightly, so between 55 and 60 should be full open)
50           80
40           70
30           60
20           50
10           45
05           40
04           35
02           20
01          15
00          12

Looks like it is shifted to above. Non-linearity might come from the coiling (diameter of coil is smaller if shutter is more down) I will run my calibration script and see how it behaves then.

FauthD commented 6 years ago

After calibration:

pos set; real pos (with eye)
90          almost 100 (shutter is not 100 coiled up, but cannot be seen from inside anymore)
80          90
70          80
60          70
50          60
40          50
30          40
20          30
10          20
05          15
02          04
01          04
00          0x  /not closed, the wholes between the boards are still open)

Perhaps my 50% calibration is not good enough. I had evaluated the value with the 1s short run times.

FauthD commented 6 years ago

The out put of the script:

ConfigureSonoff.sh shutter/buero/west
Shutters to setup:
  shutter/buero/west
First part, standard setup and close
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/FriendlyName1 -m shutter-buero-west
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/FriendlyName2 -m shutter-buero-west2
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/PulseTime1 -m 0
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/PulseTime2 -m 0
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/SetOption80 -m 0
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/Backlog -m power1 0;delay 10;power2 1
now wait for devices to reboot .................... PROCEED (edit: each dot is one second)
Part 2, make it a cover
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/Backlog -m power2 0
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/SetOption14 -m 1
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/SetOption81 -m 1
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/SetOption80 -m 1
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/Restart -m 1
now wait for devices to reboot ............... PROCEED
Part 3, cover setup (now cover commands are known
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/shutterinvert -m 0
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/shutteropenduration -m 18
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/shuttercloseduration -m 17
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/shutter50percent -m 60
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/SHUTTERSETCLOSE -m 0
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/Restart -m 1
now wait for devices to reboot ............... PROCEED
Part 4, cover set to position 50%
mosquitto_pub -h pvr -t cmnd/shutter/buero/west/shutterposition -m 50

After that, the shutter is pretty much at 50%. Script will be in separate post.

FauthD commented 6 years ago

Bash script to calibrate the shutters. I plan to rewrite in Python with more features.

#!/bin/bash

SHUTTERS+="shutter/buero/west "
SHUTTERS+="shutter/buero/sued "
SHUTTERS+="shutter/hwr "
#SHUTTERS+="shutter/exp "

BROKER="pvr"
PUB="mosquitto_pub -h $BROKER"
SLASH="/"

RESETTIME="15"
DOWNTIME="20"

Publish()
{
    local device=$1
    local cmd=$2
    local parm=$3
    echo $PUB -t "cmnd/$device/$cmd" -m "$parm"
    $PUB -t "cmnd/$device/$cmd" -m "$parm"
}

ShutterClose()
{
    local shutter=$1
    Publish $shutter "Backlog" "power1 0;delay 10;power2 1"
}

ConfigShutterPart1()
{
    local shutter=$1
    echo "First part, standard setup and close"
    Publish $shutter "FriendlyName1" ${shutter//$SLASH/-}
    Publish $shutter "FriendlyName2" ${shutter//$SLASH/-}2
    Publish $shutter "PulseTime1" "0"
    Publish $shutter "PulseTime2" "0"
    Publish $shutter "SetOption80" "0"
    Publish $shutter "Backlog" "power1 0;delay 10;power2 1"
    # this can take some time until shutter is down
}

ConfigShutterPart2()
{
    local shutter=$1
    echo "Part 2, make it a cover"
    Publish $shutter "Backlog" "power2 0"
    Publish $shutter "SetOption14" "1"
    Publish $shutter "SetOption81" "1"
    Publish $shutter "SetOption80" "1"
    Publish $shutter "Restart" "1"
    # this can take some time until device is back
}

# Note: I measured 17s for up and 16s for down.
# That seems a bit short, so I try +1 for both.
ConfigShutterPart3()
{
    local shutter=$1
    echo "Part 3, cover setup (now cover commands are known"
    Publish $shutter "shutterinvert" "0"
    Publish $shutter "shutteropenduration" "18"
    Publish $shutter "shuttercloseduration" "17"
    Publish $shutter "shutter50percent" "60"
    Publish $shutter "SHUTTERSETCLOSE" "0"
    Publish $shutter "Restart" "1"
    # this can take some time until device is back
}

# drive it to 50% to proof it did work
ConfigShutterPart4()
{
    local shutter=$1
    echo "Part 4, cover set to position 50%"
    Publish $shutter "shutterposition" "50"
}

WaitForDeviceReboot()
{
    echo -n "now wait for devices to reboot "
    local counter=$1
    while [ $counter -gt 0 ]; do
        echo -n '.'
        let counter=counter-1
        sleep 1
    done
    echo " PROCEED"
}

ConfigAllShutters()
{
    local shutters="$@"
    echo "Shutters to setup:"
    for s in $shutters; do
        echo "  $s"
    done

    for s in $shutters; do
        ConfigShutterPart1 $s
    done
    WaitForDeviceReboot $DOWNTIME

    for s in $shutters; do
        ConfigShutterPart2 $s
    done
    WaitForDeviceReboot $RESETTIME

    for s in $shutters; do
        ConfigShutterPart3 $s
    done
    WaitForDeviceReboot $RESETTIME

    for s in $shutters; do
        ConfigShutterPart4 $s
    done
}

if [ "x$1" == "x" ]; then
    ConfigAllShutters $SHUTTERS
else
    ConfigAllShutters $1
fi
stefanbode commented 6 years ago

Hi gents. I will not implement some nonlinear movements because this is too muchh effort and over complicate things enormous. Additionally there will be always shutters behave differently. From the values provided at least the 50% should be exact. One issue could be that you have some latency on the motor start. I have seen a compensation for this at Homematic. If you like we can try this one. Anyhow if you go up and down alternating the position should not shift. If it also shift here we have a different problem. To calculate the latency go down in 4 steps and up in one step. Then do the same with 1 step down and 1 step up. From the difference in cm we can calculate the latency and see if this is an issue.

FauthD commented 6 years ago

Good idea. Unfortunately I have to leave now, so it will need some days.

FauthD commented 6 years ago

Hi, trying to understand the code... This is what I assume is close to ensure it closes/opens completely. Delay needs to to fixed Forgot to call SetfullyClosed (or so, running out of time)

  else if ( (CMND_OPEN == command_code) && (index > 0) && (index <= shutters_present)) {
    Shutter_Direction[index-1] = 1
    ExecuteCommandPower(Settings.shutter_startrelay[index-1] + (Shutter_Direction[index-1] == 1 ? 0 : 1), 1, SRC_SHUTTER);
    SOMEDELAYFUNCKTION(Shutter_Open_Time[index-1])  // perhaps need to adjust scaling (secs, 1/s sec etc)
    ExecuteCommandPower(Settings.shutter_startrelay[index-1] + (Shutter_Direction[index-1] == 1 ? 0 : 1), 0, SRC_SHUTTER);
    Shutter_Direction[index-1] = 0
  }
  else if ( (CMND_CLOSE == command_code) && (index > 0) && (index <= shutters_present)) {
    Shutter_Direction[index-1] = -1
    ExecuteCommandPower(Settings.shutter_startrelay[index-1] + (Shutter_Direction[index-1] == 1 ? 0 : 1), 1, SRC_SHUTTER);
    SOMEDELAYFUNCKTION(Shutter_Close_Time[index-1])  // perhaps need to adjust scaling (secs, 1/s sec etc)
    ExecuteCommandPower(Settings.shutter_startrelay[index-1] + (Shutter_Direction[index-1] == 1 ? 0 : 1), 0, SRC_SHUTTER);
    Shutter_Direction[index-1] = 0
  }
stefanbode commented 6 years ago

Hi Dieter, I got an accident earlier this day. Therefore a bit OFF for the next days. The proposed solution is at the end not more than just increase the closeduration. The motor is longer ON to ensure a full close and to make usage of the end stops. I have seen the measurements you provided but did not have the time to take a closer look at it.

stefanbode commented 6 years ago

Hi Dieter, back from the hospital. As mentioned above your problem should be easy to fix by increasing the closeduration and/or openduration to run into the endpoints without code change