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:
stefanbode 2019-12-12 16:14:06 +01:00 committed by GitHub
parent e53f637bb6
commit 29de8b9dce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 60 additions and 44 deletions

View File

@ -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;
}
}