Merge pull request #7195 from stefanbode/patch-4

prepare for other modules to use shutter. endstop fixes
This commit is contained in:
Theo Arends 2019-12-12 17:58:33 +01:00 committed by GitHub
commit f5c173cb1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 77 additions and 43 deletions

View File

@ -494,6 +494,24 @@
#define D_JSON_MOTOR_MIS "setMIS" #define D_JSON_MOTOR_MIS "setMIS"
#endif #endif
// Commands xdrv_27_Shutter.ino
#ifdef USE_SHUTTER
#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"
#endif
/********************************************************************************************/ /********************************************************************************************/
// Log message prefix // Log message prefix

View File

@ -24,27 +24,10 @@
#define XDRV_27 27 #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" #define D_SHUTTER "SHUTTER"
const uint16_t MOTOR_STOP_TIME = 500; // in mS const uint16_t MOTOR_STOP_TIME = 500; // in mS
uint8_t calibrate_pos[6] = {0,30,50,70,90,100}; uint8_t calibrate_pos[6] = {0,30,50,70,90,100};
uint16_t messwerte[5] = {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 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 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 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 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; } Shutter;
void ShutterRtc50mS(void) void ShutterRtc50mS(void)
@ -99,7 +83,7 @@ int32_t ShutterPercentToRealPosition(uint8_t percent,uint8_t index)
if (Settings.shutter_set50percent[index] != 50) { if (Settings.shutter_set50percent[index] != 50) {
return percent <= 5 ? Settings.shuttercoeff[2][index] * percent : Settings.shuttercoeff[1][index] * percent + Settings.shuttercoeff[0][index]; return percent <= 5 ? Settings.shuttercoeff[2][index] * percent : Settings.shuttercoeff[1][index] * percent + Settings.shuttercoeff[0][index];
} else { } else {
uint32_t realpos; int32_t realpos;
// check against DIV 0 // check against DIV 0
for (uint8_t j=0 ; j < 5 ; j++) { for (uint8_t j=0 ; j < 5 ; j++) {
if (Settings.shuttercoeff[j][index] == 0) { 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) { 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]; return Settings.shuttercoeff[2][index] * 5 > realpos ? realpos / Settings.shuttercoeff[2][index] : (realpos-Settings.shuttercoeff[0][index]) / Settings.shuttercoeff[1][index];
} else { } else {
uint16_t realpercent; int16_t realpercent;
for (uint8_t i=0 ; i < 5 ; i++) { for (uint8_t i=0 ; i < 5 ; i++) {
if (realpos > Shutter.open_max[index] * calibrate_pos[i+1] / 100) { 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; break;
} }
} }
return realpercent; return (realpercent < 0 ? 0 : (realpercent > 100 ? 0 : realpercent));
} }
} }
@ -257,7 +241,7 @@ void ShutterUpdatePosition(void)
// Counter should be initiated to 0 to count movement. // 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 // 0..1000 in step 100 = 10 steps with 0.05 sec = 0.5sec total ramp time from start to
// full speed. // 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.max_pwm_frequency/20;
Shutter.pwm_frequency = (Shutter.pwm_frequency > Shutter.max_pwm_frequency ? Shutter.max_pwm_frequency : Shutter.pwm_frequency); Shutter.pwm_frequency = (Shutter.pwm_frequency > Shutter.max_pwm_frequency ? Shutter.max_pwm_frequency : Shutter.pwm_frequency);
analogWriteFreq(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])); 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. // 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] ) { 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); analogWrite(pin[GPIO_PWM1+i], 50);
//prepare for stop PWM //prepare for stop PWM
Shutter.motordelay[i] = -2 + Shutter.motordelay[i] + missing_steps/(Shutter.max_pwm_frequency/20); 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]); 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); 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) { 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); delay(1);
@ -351,19 +336,35 @@ bool ShutterState(uint8_t device)
(Shutter.mask & (1 << (Settings.shutter_startrelay[device]-1))) ); (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; //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]);
Shutter.target_position[index] = target_pos; if (direction == 1 && (Shutter.open_max[index] - Shutter.real_position[index]) / Shutter.close_velocity[index] <= 2+Shutter.motordelay[index]) {
Shutter.start_position[index] = Shutter.real_position[index]; // shutter alread 100% cannot move further
Shutter.time[index] = 0; // store relay number variable
if (pin[GPIO_PWM1+index] < 99) { Shutter.skip_relay_change = 1 ;
Shutter.pwm_frequency = 0; //AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SHT: 100%% endstop already reached: Relay %d"),Shutter.skip_relay_change);
analogWriteFreq(Shutter.pwm_frequency);
analogWrite(pin[GPIO_PWM1+index], 0); } else if (direction == -1 && Shutter.real_position[index] / Shutter.close_velocity[index] <= 2+Shutter.motordelay[index]) {
// can be operated without counter, but then not that acurate. // shutter already at 0% connot move into minus
if (pin[GPIO_CNTR1+index] < 99) { // store relay number variable
RtcSettings.pulse_counter[index] = 0; 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]); //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) void ShutterReportPosition(void)
{ {
uint16_t shutter_moving = 0; 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) { if (Shutter.direction[i] != 0) {
char stemp1[20]; char stemp1[20];
char stemp2[10]; char stemp2[10];
@ -414,7 +415,7 @@ void ShutterRelayChanged(void)
switch (powerstate_local) { switch (powerstate_local) {
case 1: case 1:
ShutterDelayForMotorStop(); ShutterDelayForMotorStop();
ShutterStartInit(i, 1, Shutter.open_max[i]); ShutterStartInit(i, 1, Shutter.open_max[i]);
break; break;
case 3: case 3:
ShutterDelayForMotorStop(); ShutterDelayForMotorStop();
@ -652,7 +653,7 @@ void CmndShutterSetClose(void)
Shutter.real_position[XdrvMailbox.index -1] = 0; Shutter.real_position[XdrvMailbox.index -1] = 0;
ShutterStartInit(XdrvMailbox.index -1, 0, 0); ShutterStartInit(XdrvMailbox.index -1, 0, 0);
Settings.shutter_position[XdrvMailbox.index -1] = 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); result = DecodeCommand(kShutterCommands, ShutterCommand);
break; break;
case FUNC_JSON_APPEND: 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]; uint8_t position = Settings.shutter_invert[i] ? 100 - Settings.shutter_position[i]: Settings.shutter_position[i];
ResponseAppend_P(","); ResponseAppend_P(",");
ResponseAppend_P(JSON_SHUTTER_POS, i+1, position, Shutter.direction[i]); ResponseAppend_P(JSON_SHUTTER_POS, i+1, position, Shutter.direction[i]);
@ -731,10 +732,25 @@ bool Xdrv27(uint8_t function)
case FUNC_SET_POWER: case FUNC_SET_POWER:
char stemp1[10]; char stemp1[10];
// extract the number of the relay that was switched and save for later in Update Position. // extract the number of the relay that was switched and save for later in Update Position.
Shutter.switched_relay = power ^ Shutter.old_power; Shutter.switched_relay = XdrvMailbox.index ^ Shutter.old_power;
Shutter.old_power = power;
AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Switched relay: %d by %s"), Shutter.switched_relay,GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource)); AddLog_P2(LOG_LEVEL_DEBUG_MORE, PSTR("SHT: Switched relay: %d by %s"), Shutter.switched_relay,GetTextIndexed(stemp1, sizeof(stemp1), last_source, kCommandSource));
ShutterRelayChanged(); 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; break;
} }
} }