mirror of https://github.com/arendst/Tasmota.git
Update several functions
- finally, secure pressing DOWN/UP button when shutter already in end-position will not turn ON the relay - remove shutter commands to main to allow other modules to interact - fix some overrun and underrun issues to end-positions
This commit is contained in:
parent
e53f637bb6
commit
29de8b9dce
|
@ -24,27 +24,10 @@
|
|||
|
||||
#define XDRV_27 27
|
||||
|
||||
#define D_PRFX_SHUTTER "Shutter"
|
||||
#define D_CMND_SHUTTER_OPEN "Open"
|
||||
#define D_CMND_SHUTTER_CLOSE "Close"
|
||||
#define D_CMND_SHUTTER_STOP "Stop"
|
||||
#define D_CMND_SHUTTER_POSITION "Position"
|
||||
#define D_CMND_SHUTTER_OPENTIME "OpenDuration"
|
||||
#define D_CMND_SHUTTER_CLOSETIME "CloseDuration"
|
||||
#define D_CMND_SHUTTER_RELAY "Relay"
|
||||
#define D_CMND_SHUTTER_SETHALFWAY "SetHalfway"
|
||||
#define D_CMND_SHUTTER_SETCLOSE "SetClose"
|
||||
#define D_CMND_SHUTTER_INVERT "Invert"
|
||||
#define D_CMND_SHUTTER_CLIBRATION "Calibration"
|
||||
#define D_CMND_SHUTTER_MOTORDELAY "MotorDelay"
|
||||
#define D_CMND_SHUTTER_FREQUENCY "Frequency"
|
||||
|
||||
#define D_SHUTTER "SHUTTER"
|
||||
|
||||
const uint16_t MOTOR_STOP_TIME = 500; // in mS
|
||||
|
||||
|
||||
|
||||
uint8_t calibrate_pos[6] = {0,30,50,70,90,100};
|
||||
uint16_t messwerte[5] = {30,50,70,90,100};
|
||||
|
||||
|
@ -82,9 +65,10 @@ struct SHUTTER {
|
|||
uint16_t close_velocity[MAX_SHUTTERS]; // in relation to open velocity. higher value = faster
|
||||
int8_t direction[MAX_SHUTTERS]; // 1 == UP , 0 == stop; -1 == down
|
||||
uint8_t mode = 0; // operation mode definition. see enum type above SHT_OFF_OPEN__OFF_CLOSE, SHT_OFF_ON__OPEN_CLOSE, SHT_PULSE_OPEN__PULSE_CLOSE
|
||||
uint8_t motordelay[MAX_SHUTTERS]; // initial motorstarttime in 0.05sec.
|
||||
int16_t motordelay[MAX_SHUTTERS]; // initial motorstarttime in 0.05sec.
|
||||
uint16_t pwm_frequency; // frequency of PWN for stepper motors
|
||||
uint16_t max_pwm_frequency = 1000;
|
||||
uint16_t max_pwm_frequency = 1000; // maximum of PWM frequency that can be used. depend on the motor and drivers
|
||||
uint8_t skip_relay_change; // avoid overrun at endstops
|
||||
} Shutter;
|
||||
|
||||
void ShutterRtc50mS(void)
|
||||
|
@ -99,7 +83,7 @@ int32_t ShutterPercentToRealPosition(uint8_t percent,uint8_t index)
|
|||
if (Settings.shutter_set50percent[index] != 50) {
|
||||
return percent <= 5 ? Settings.shuttercoeff[2][index] * percent : Settings.shuttercoeff[1][index] * percent + Settings.shuttercoeff[0][index];
|
||||
} else {
|
||||
uint32_t realpos;
|
||||
int32_t realpos;
|
||||
// check against DIV 0
|
||||
for (uint8_t j=0 ; j < 5 ; j++) {
|
||||
if (Settings.shuttercoeff[j][index] == 0) {
|
||||
|
@ -133,7 +117,7 @@ uint8_t ShutterRealToPercentPosition(int32_t realpos, uint8_t index)
|
|||
if (Settings.shutter_set50percent[index] != 50) {
|
||||
return Settings.shuttercoeff[2][index] * 5 > realpos ? realpos / Settings.shuttercoeff[2][index] : (realpos-Settings.shuttercoeff[0][index]) / Settings.shuttercoeff[1][index];
|
||||
} else {
|
||||
uint16_t realpercent;
|
||||
int16_t realpercent;
|
||||
|
||||
for (uint8_t i=0 ; i < 5 ; i++) {
|
||||
if (realpos > Shutter.open_max[index] * calibrate_pos[i+1] / 100) {
|
||||
|
@ -151,7 +135,7 @@ uint8_t ShutterRealToPercentPosition(int32_t realpos, uint8_t index)
|
|||
break;
|
||||
}
|
||||
}
|
||||
return realpercent;
|
||||
return (realpercent < 0 ? 0 : (realpercent > 100 ? 0 : realpercent));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +214,7 @@ void ShutterInit(void)
|
|||
dtostrfd((float)Shutter.open_time[i] / 10 , 1, shutter_open_chr);
|
||||
char shutter_close_chr[10];
|
||||
dtostrfd((float)Shutter.close_time[i] / 10, 1, shutter_close_chr);
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter %d (Relay:%d): Init. Pos: %d [%d %%], Open Vel.: 100 Close Vel.: %d , Max Way: %d, Opentime %s [s], Closetime %s [s], CoeffCalc: c0: %d, c1 %d, c2: %d, c3: %d, c4: %d, binmask %d, is inverted %d, shuttermode %d,motordelay %d"),
|
||||
AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Shutter %d (Relay:%d): Init. Pos: %d [%d %%], Open Vel.: 100 Close Vel.: %d , Max Way: %d, Opentime %s [s], Closetime %s [s], CoedffCalc: c0: %d, c1 %d, c2: %d, c3: %d, c4: %d, binmask %d, is inverted %d, shuttermode %d,motordelay %d"),
|
||||
i+1, Settings.shutter_startrelay[i], Shutter.real_position[i], Settings.shutter_position[i], Shutter.close_velocity[i], Shutter.open_max[i], shutter_open_chr, shutter_close_chr,
|
||||
Settings.shuttercoeff[0][i], Settings.shuttercoeff[1][i], Settings.shuttercoeff[2][i], Settings.shuttercoeff[3][i], Settings.shuttercoeff[4][i],
|
||||
Shutter.mask, Settings.shutter_invert[i], Shutter.mode, Shutter.motordelay[i]);
|
||||
|
@ -257,7 +241,7 @@ void ShutterUpdatePosition(void)
|
|||
// Counter should be initiated to 0 to count movement.
|
||||
// 0..1000 in step 100 = 10 steps with 0.05 sec = 0.5sec total ramp time from start to
|
||||
// full speed.
|
||||
if (pin[GPIO_PWM1+i] < 99 && Shutter.pwm_frequency != Shutter.max_pwm_frequency) {
|
||||
if (Shutter.mode == SHT_OFF_ON__OPEN_CLOSE && pin[GPIO_PWM1+i] < 99 && Shutter.pwm_frequency != Shutter.max_pwm_frequency) {
|
||||
Shutter.pwm_frequency += Shutter.max_pwm_frequency/20;
|
||||
Shutter.pwm_frequency = (Shutter.pwm_frequency > Shutter.max_pwm_frequency ? Shutter.max_pwm_frequency : Shutter.pwm_frequency);
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
|
@ -266,7 +250,7 @@ void ShutterUpdatePosition(void)
|
|||
|
||||
Shutter.real_position[i] = Shutter.start_position[i] + ( (Shutter.time[i] - Shutter.motordelay[i]) * (Shutter.direction[i] > 0 ? 100 : -Shutter.close_velocity[i]));
|
||||
// avoid real position leaving the boundaries.
|
||||
Shutter.real_position[i] = Shutter.real_position[i] < 0 ? 0 : (Shutter.real_position[i] > Shutter.open_max[i] ? Shutter.open_max[i] : Shutter.real_position[i]) ;
|
||||
// Shutter.real_position[i] = Shutter.real_position[i] < 0 ? 0 : (Shutter.real_position[i] > Shutter.open_max[i] ? Shutter.open_max[i] : Shutter.real_position[i]) ;
|
||||
|
||||
|
||||
if (Shutter.real_position[i] * Shutter.direction[i] >= Shutter.target_position[i] * Shutter.direction[i] ) {
|
||||
|
@ -295,8 +279,9 @@ void ShutterUpdatePosition(void)
|
|||
analogWrite(pin[GPIO_PWM1+i], 50);
|
||||
//prepare for stop PWM
|
||||
Shutter.motordelay[i] = -2 + Shutter.motordelay[i] + missing_steps/(Shutter.max_pwm_frequency/20);
|
||||
Shutter.motordelay[i] = Shutter.motordelay[i] > 0 ? Shutter.motordelay[i] : 0;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: Missing steps %d, adjust motordelay %d, counter %d, temp realpos %d"), missing_steps, Shutter.motordelay[i],RtcSettings.pulse_counter[i] ,Shutter.real_position[i]);
|
||||
Settings.shutter_motordelay[i]=(missing_steps > 0 ? Shutter.motordelay[i] : 0);
|
||||
Settings.shutter_motordelay[i]=Shutter.motordelay[i];
|
||||
analogWriteFreq(0);
|
||||
while (RtcSettings.pulse_counter[i] < (uint32_t)(Shutter.target_position[i]-Shutter.start_position[i])*Shutter.direction[i]*Shutter.max_pwm_frequency/2000) {
|
||||
delay(1);
|
||||
|
@ -351,19 +336,35 @@ bool ShutterState(uint8_t device)
|
|||
(Shutter.mask & (1 << (Settings.shutter_startrelay[device]-1))) );
|
||||
}
|
||||
|
||||
void ShutterStartInit(uint8_t index, uint8_t direction, int32_t target_pos)
|
||||
void ShutterStartInit(uint8_t index, int8_t direction, int32_t target_pos)
|
||||
{
|
||||
Shutter.direction[index] = direction;
|
||||
Shutter.target_position[index] = target_pos;
|
||||
Shutter.start_position[index] = Shutter.real_position[index];
|
||||
Shutter.time[index] = 0;
|
||||
if (pin[GPIO_PWM1+index] < 99) {
|
||||
Shutter.pwm_frequency = 0;
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
analogWrite(pin[GPIO_PWM1+index], 0);
|
||||
// can be operated without counter, but then not that acurate.
|
||||
if (pin[GPIO_CNTR1+index] < 99) {
|
||||
RtcSettings.pulse_counter[index] = 0;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: dir %d, delta1 %d, delta2 %d, grant %d"),direction, (Shutter.open_max[index] - Shutter.real_position[index]) / Shutter.close_velocity[index], Shutter.real_position[index] / Shutter.close_velocity[index], 2+Shutter.motordelay[index]);
|
||||
if (direction == 1 && (Shutter.open_max[index] - Shutter.real_position[index]) / Shutter.close_velocity[index] <= 2+Shutter.motordelay[index]) {
|
||||
// shutter alread 100% cannot move further
|
||||
// store relay number variable
|
||||
Shutter.skip_relay_change = 1 ;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: 100%% endstop already reached: Relay %d"),Shutter.skip_relay_change);
|
||||
|
||||
} else if (direction == -1 && Shutter.real_position[index] / Shutter.close_velocity[index] <= 2+Shutter.motordelay[index]) {
|
||||
// shutter already at 0% connot move into minus
|
||||
// store relay number variable
|
||||
Shutter.skip_relay_change = 1;
|
||||
//AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: 0%% endstop already reached: Relay %d"),Shutter.skip_relay_change);
|
||||
|
||||
} else {
|
||||
Shutter.direction[index] = direction;
|
||||
Shutter.target_position[index] = target_pos;
|
||||
Shutter.start_position[index] = Shutter.real_position[index];
|
||||
Shutter.time[index] = 0;
|
||||
Shutter.skip_relay_change = 0;
|
||||
if (pin[GPIO_PWM1+index] < 99) {
|
||||
Shutter.pwm_frequency = 0;
|
||||
analogWriteFreq(Shutter.pwm_frequency);
|
||||
analogWrite(pin[GPIO_PWM1+index], 0);
|
||||
// can be operated without counter, but then not that acurate.
|
||||
if (pin[GPIO_CNTR1+index] < 99) {
|
||||
RtcSettings.pulse_counter[index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
//AddLog_P2(LOG_LEVEL_INFO, PSTR("SHT: Start shutter: %d from %d to %d in directin %d"), index, Shutter.start_position[index], Shutter.target_position[index], Shutter.direction[index]);
|
||||
|
@ -378,7 +379,7 @@ void ShutterDelayForMotorStop(void)
|
|||
void ShutterReportPosition(void)
|
||||
{
|
||||
uint16_t shutter_moving = 0;
|
||||
for (uint32_t i = 0; i < shutters_present; i++) {
|
||||
for (uint8_t i = 0; i < shutters_present; i++) {
|
||||
if (Shutter.direction[i] != 0) {
|
||||
char stemp1[20];
|
||||
char stemp2[10];
|
||||
|
@ -414,7 +415,7 @@ void ShutterRelayChanged(void)
|
|||
switch (powerstate_local) {
|
||||
case 1:
|
||||
ShutterDelayForMotorStop();
|
||||
ShutterStartInit(i, 1, Shutter.open_max[i]);
|
||||
ShutterStartInit(i, 1, Shutter.open_max[i]);
|
||||
break;
|
||||
case 3:
|
||||
ShutterDelayForMotorStop();
|
||||
|
@ -652,7 +653,7 @@ void CmndShutterSetClose(void)
|
|||
Shutter.real_position[XdrvMailbox.index -1] = 0;
|
||||
ShutterStartInit(XdrvMailbox.index -1, 0, 0);
|
||||
Settings.shutter_position[XdrvMailbox.index -1] = 0;
|
||||
ResponseCmndChar(D_CONFIGURATION_RESET);
|
||||
ResponseCmndIdxChar(D_CONFIGURATION_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -717,7 +718,7 @@ bool Xdrv27(uint8_t function)
|
|||
result = DecodeCommand(kShutterCommands, ShutterCommand);
|
||||
break;
|
||||
case FUNC_JSON_APPEND:
|
||||
for (uint32_t i = 0; i < shutters_present; i++) {
|
||||
for (uint8_t i = 0; i < shutters_present; i++) {
|
||||
uint8_t position = Settings.shutter_invert[i] ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i];
|
||||
ResponseAppend_P(",");
|
||||
ResponseAppend_P(JSON_SHUTTER_POS, i+1, position, Shutter.direction[i]);
|
||||
|
@ -731,10 +732,25 @@ bool Xdrv27(uint8_t function)
|
|||
case FUNC_SET_POWER:
|
||||
char stemp1[10];
|
||||
// extract the number of the relay that was switched and save for later in Update Position.
|
||||
Shutter.switched_relay = power ^ Shutter.old_power;
|
||||
Shutter.old_power = power;
|
||||
Shutter.switched_relay = XdrvMailbox.index ^ Shutter.old_power;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Switched relay: %d by %s"), Shutter.switched_relay,GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource));
|
||||
ShutterRelayChanged();
|
||||
Shutter.old_power = XdrvMailbox.index;
|
||||
break;
|
||||
case FUNC_SET_DEVICE_POWER:
|
||||
if (Shutter.skip_relay_change ) {
|
||||
uint8_t i;
|
||||
for (i = 0; i < devices_present; i++) {
|
||||
if (Shutter.switched_relay &1) {
|
||||
break;
|
||||
}
|
||||
Shutter.switched_relay >>= 1;
|
||||
}
|
||||
//AddLog_P2(LOG_LEVEL_ERROR, PSTR("SHT: skip relay change: %d"),i+1);
|
||||
result = true;
|
||||
Shutter.skip_relay_change = 0;
|
||||
ExecuteCommandPower(i+1, 0, SRC_SHUTTER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue