From a810e7ed6db6ee025a0195c23f4e5f50af947b9f Mon Sep 17 00:00:00 2001 From: Dan Date: Sat, 12 Oct 2024 16:58:16 +0200 Subject: [PATCH] new PWM settings in GUI --- Assembly-manual.md | 6 +- IP-rotator.ino | 181 +++++++++++++++++++++++++++++++++++---------- index.h | 2 +- 3 files changed, 149 insertions(+), 40 deletions(-) diff --git a/Assembly-manual.md b/Assembly-manual.md index 43accfe..99cfa5a 100644 --- a/Assembly-manual.md +++ b/Assembly-manual.md @@ -568,7 +568,11 @@ How to works - **CW/CCW forbidden zone (software endstops),** are values of the range of forbidden zones in millivolts. the entire range of the rotator represents a voltage of 0 to 3.3V. The setting value will appear in the Calibration page as a yellow area at the edges of the range. If the rotator is set correctly, it only allows movement in the direction from the edge to the center. Keep the protection zone large enough to prevent damage to the rotator. - **Watchdog speed** is the minimum rotation speed in seconds per one turn, which if the rotator does not reach, it will be stopped by the watchdog. Use a value at least 50% higher than the real speed to avoid false stops. - **Motor supply,** is a choice between AC and DC rotator type. The DC type enables the activation of the PWM start-up and run-down ramps. -- **DC PWM control** activates the PWM ramp-up and ramp-down when using the DC rotator. If you use a rotator without hardware endstops, the destruction of one component (power mosfet) can cause the rotator to crash. Therefore, it is safe to connect one more active element in series (relay intended for the brake). **This setup is highly recomended, see [Connection section](#dc-motor-with-pwm-without-hardware-endstop-safe-mode).** +- **DC PWM control** activates the PWM ramp-up and ramp-down when using the DC rotator. If you use a rotator without hardware endstops, the destruction of one component (power mosfet) can cause the rotator to crash. Therefore, it is safe to connect one more active element in series (relay intended for the brake). **This setup is highly recomended, see [Connection section](#dc-motor-with-pwm-without-hardware-endstop-safe-mode).** Turning DC PWM on activates two other settings: + * **PWM ramp length in steps of 25ms** + displaying the length of the ramp in seconds, allows you to set how long the PWM control will regulate from 0 to 100% during acceleration, or vice versa during deceleration - **WARNING - a longer ramp may result in passing the end points, it is therefore necessary to set sufficiently large margins in CW /CCW forbidden zone (software endstops). In this way, imprecise stopping will occur more often due to the overlapping of the starting and stoping ramps when rotating through small angles.** + * **PWM ramp start distance** the distance from the target azimuth in degrees, from which the PWM ramp starts, the length of which is set by the previous value. + * By combining both values, it is possible to tune the PWM sequence so that the rotator stops as close as possible to the required azimuth. YouTube video show two parameter settings + * If there is a need to rotate to a closer azimuth than twice the "PWM ramp start distance" value, there will be a switch from the starting to the stopping ramp halfway through the journey, which affects the stopping accuracy (missing the entire stopping sequence in the combination of time and distance). Therefore, it is better to choose both values ​​as low as possible for your antenna assembly, so that it does not overlap the start and stop ramps. - **USB serial BAUDRATE,** is the setting of the communication speed of the serial console on the USB-C connector using the GS-232 protocol. Enabled commands * **?** display the IP address of the rotator * **R** clockwise rotation diff --git a/IP-rotator.ino b/IP-rotator.ino index 0353de0..08c9ddd 100644 --- a/IP-rotator.ino +++ b/IP-rotator.ino @@ -75,13 +75,15 @@ Changelog: + DC use brake relay + add AzimuthStop mqttpub + support HW rev 6 and 7 ++ add new settings to setup gui for PWM + - PWM ramp length + - PWM start distance ToDo - test - if stop, after run over target + 10 turn pot without preamp + test preamp linearity -- PWM up/dwn ramp long to setup page, and ° before target start PWM (measure and saved) - PwmDwnDelay/PwmUpDelay set from setup gui - save settings (dump eeprom?) - show target from az pot in map - disable target in map if status = 0 (not rotate) @@ -113,7 +115,7 @@ Použití knihovny Wire ve verzi 2.0.0 v adresáři: /home/dan/Arduino/hardware/ */ //------------------------------------------------------------------------------------------------------- -const char* REV = "20241009"; +const char* REV = "20241011"; // #define CN3A // fix ip float NoEndstopHighZone = 0; @@ -143,8 +145,10 @@ bool AZtwoWire = false; bool AZpreamp = false; bool PWMenable = true; -unsigned int PwmUpDelay = 3; // [ms]*255 -unsigned int PwmDwnDelay = 2; // [ms]*255 +unsigned int PwmDegree = 0; +unsigned int PwmRampSteps = 0; +unsigned int PwmUpDelay = 3; // [ms]*255steps +unsigned int PwmDwnDelay = 2; // [ms]*255steps byte dutyCycle = 0; long StatusWatchdogTimer = 0; long RotateWatchdogTimer = 0; @@ -281,7 +285,7 @@ int i = 0; #include #include #include "EEPROM.h" -#define EEPROM_SIZE 244 /* +#define EEPROM_SIZE 245 /* 0|Byte 1|128 1|Char 1|A @@ -325,13 +329,8 @@ int i = 0; 229 AZpreamp 230 - ReverseAZ 231 - PWMenable - -231-234 - Altitude 4 -// 232 - SpeedAlert 4 -235-238 - SpeedAlert 4 -// 233 - DS18B20 on/off 1 -239 - DS18B20 on/off 1 -240-243 - WindDirShift 4 +232 PwmDegree UShort +234 PwmRampSteps UShort !! Increment EEPROM_SIZE #define !! @@ -1020,7 +1019,26 @@ void setup() { } } + // 232 PwmDegree UShort + if(EEPROM.read(232)==0xff){ + PwmDegree=10; + PwmDegree=10; + }else{ + PwmDegree = EEPROM.readUShort(232); + if(PwmDegree<1 || PwmDegree>50){ + PwmDegree=10; + } + } + // 234 PwmRampSteps UShort + if(EEPROM.read(234)==0xff){ + PwmRampSteps=5; + }else{ + PwmRampSteps = EEPROM.readUShort(234); + if(PwmRampSteps<1 || PwmRampSteps>200){ + PwmRampSteps=5; + } + } @@ -1431,6 +1449,7 @@ void Watchdog(){ static int AZBuffer = 0; static int AZmasterBuffer = 0; static float VoltageBuffer = 0; + // Azimuth refresh 175 ms if(millis()-ADCTimer > 5){ AZBuffer = AZBuffer + readADC_Cal(analogRead(AzimuthPin)); AZmasterBuffer = AZmasterBuffer + readADC_Cal(analogRead(AZmasterPin)); @@ -1840,6 +1859,7 @@ void DetectEndstopZone(){ void RunByStatus(){ static long PwmTimer = 0; static bool OneTimeSend = false; + static int FromAzimuth = 0; DetectEndstopZone(); // }else if( (Azimuth>=0 && Azimuth<=450) ){ @@ -1848,13 +1868,13 @@ void RunByStatus(){ if(ACmotor==false){ //DC if(PWMenable==true){ - if(millis()-PwmTimer > PwmDwnDelay){ + if(millis()-PwmTimer > PwmRampSteps){ //PwmDwnDelay){ if(dutyCycle!=0){ - dutyCycle--; + dutyCycle-=10; //-10 } ledcWrite(mosfetPWMChannel, dutyCycle); PwmTimer=millis(); - if(dutyCycle<1){ + if(dutyCycle<10){ // || (abs(AzimuthTarget-Azimuth)<1) ){ // dutyCycle=0; ledcWrite(mosfetPWMChannel, 0); digitalWrite(BrakePin, LOW); @@ -1863,6 +1883,7 @@ void RunByStatus(){ digitalWrite(ReversePin, LOW); Status=0; AzimuthTarget=-1; + FromAzimuth=-1; } } }else{ @@ -1887,7 +1908,7 @@ void RunByStatus(){ ; break; } case -2: { if(PWMenable==true){ - if(abs(AzimuthTarget-Azimuth)<10){ + if(abs(AzimuthTarget-Azimuth) PwmUpDelay){ - dutyCycle+=2; + if(millis()-PwmTimer > PwmRampSteps){ + dutyCycle+=10; ledcWrite(mosfetPWMChannel, dutyCycle); PwmTimer=millis(); - if(dutyCycle>253){ + if(dutyCycle>244){ ledcWrite(mosfetPWMChannel, 255); Status=-2; } } + if(abs(AzimuthTarget-Azimuth) < abs(AzimuthTarget-FromAzimuth)/2 ){ // if target near than PwmDegree, switch in 1/2 path to PWMdwn + Status=-3; + } }else{ ledcWrite(mosfetPWMChannel, 255); // digitalWrite(ACcwPin, HIGH); @@ -1934,6 +1958,7 @@ void RunByStatus(){ RunTimer(); Status=-11; OneTimeSend = false; + FromAzimuth=Azimuth; ; break; } case 0: { LedStatusErr(); @@ -1948,6 +1973,7 @@ void RunByStatus(){ RunTimer(); Status=11; OneTimeSend = false; + FromAzimuth=Azimuth; ; break; } case 11: { ErrorDetect=0; @@ -1955,15 +1981,18 @@ void RunByStatus(){ if(ACmotor==false){ //DC if(PWMenable==true){ - if(millis()-PwmTimer > PwmUpDelay){ - dutyCycle+=2; + if(millis()-PwmTimer > PwmRampSteps){ + dutyCycle+=10; ledcWrite(mosfetPWMChannel, dutyCycle); PwmTimer=millis(); - if(dutyCycle>253){ + if(dutyCycle>244){ ledcWrite(mosfetPWMChannel, 255); Status=2; } } + if(abs(AzimuthTarget-Azimuth) < abs(AzimuthTarget-FromAzimuth)/2 ){ // if target near than PwmDegree, switch in 1/2 path to PWMdwn + Status=3; + } }else{ ledcWrite(mosfetPWMChannel, 255); // digitalWrite(ACcwPin, HIGH); @@ -1984,7 +2013,7 @@ void RunByStatus(){ ; break; } case 2: { if(PWMenable==true){ - if(abs(AzimuthTarget-Azimuth)<10){ + if(abs(AzimuthTarget-Azimuth) PwmDwnDelay){ + if(millis()-PwmTimer > PwmRampSteps){ //PwmDwnDelay){ if(dutyCycle!=0){ - dutyCycle--; + dutyCycle-=10; // -10 } ledcWrite(mosfetPWMChannel, dutyCycle); PwmTimer=millis(); - if(dutyCycle<1){ + if(dutyCycle<10){ // || (abs(AzimuthTarget-Azimuth)<1) ){ dutyCycle=0; ledcWrite(mosfetPWMChannel, 0); digitalWrite(BrakePin, LOW); @@ -2012,6 +2041,7 @@ void RunByStatus(){ digitalWrite(ReversePin, LOW); Status=0; AzimuthTarget=-1; + FromAzimuth=-1; } } }else{ @@ -4244,6 +4274,12 @@ void handleSet() { String twowireSELECT1= ""; String preampSELECT0= ""; String preampSELECT1= ""; + String pwmdegreeERR= ""; + String pwmdegreeSTYLE= ""; + String pwmdegreeDisable= ""; + String pwmrampstepsERR= ""; + String pwmrampstepsSTYLE= ""; + String pwmrampstepsDisable= ""; if ( ajaxserver.hasArg("yourcall") == false \ && ajaxserver.hasArg("rotid") == false \ @@ -4254,6 +4290,8 @@ void handleSet() { && ajaxserver.hasArg("antradiationangle") == false \ && ajaxserver.hasArg("edstoplowzone") == false \ && ajaxserver.hasArg("edstophighzone") == false \ + && ajaxserver.hasArg("pwmdegree") == false \ + && ajaxserver.hasArg("pwmrampsteps") == false \ ) { // MqttPubString("Debug", "Form not valid", false); }else{ @@ -4552,6 +4590,40 @@ void handleSet() { MqttPubString("PWMenable", "ON", true); } + // 232 PwmDegree + if (ACmotor==false && PWMenable==true){ + if (ajaxserver.arg("pwmdegree").length()<1 || ajaxserver.arg("pwmdegree").toInt()<1 || ajaxserver.arg("pwmdegree").toInt()>50){ + pwmdegreeERR= " Out of range number 1-30"; + }else{ + if(PwmDegree == ajaxserver.arg("pwmdegree").toInt()){ + pwmdegreeERR=""; + }else{ + pwmdegreeERR=""; + PwmDegree = ajaxserver.arg("pwmdegree").toInt(); + EEPROM.writeUShort(232, PwmDegree); + // EEPROM.commit(); + MqttPubString("PwmDegree", String(PwmDegree), true); + } + } + } + + // 233 PwmRampSteps UShort + if (ACmotor==false && PWMenable==true){ + if(ajaxserver.arg("pwmrampsteps").length()<1 || ajaxserver.arg("pwmrampsteps").toInt()<1 || ajaxserver.arg("pwmrampsteps").toInt()>200){ + pwmrampstepsERR= " Out of range number 1-200"; + }else{ + if(PwmRampSteps == ajaxserver.arg("pwmrampsteps").toInt()){ + pwmrampstepsERR=""; + }else{ + pwmrampstepsERR=""; + PwmRampSteps = ajaxserver.arg("pwmrampsteps").toInt(); + EEPROM.writeUShort(234, PwmRampSteps); + // EEPROM.commit(); + MqttPubString("PwmRampSteps", String(PwmRampSteps), true); + } + } + } + // 226-227 BaudRate static int BaudRateTmp=115200; switch (ajaxserver.arg("baud").toInt()) { @@ -4706,21 +4778,34 @@ if(ACmotor==true){ motorSELECT1= " selected"; pwmenableSTYLE=" style='text-decoration: line-through; color: #555;'"; pwmenableDisable=" disabled"; + pwmdegreeSTYLE=" style='text-decoration: line-through; color: #555;'"; + pwmdegreeDisable=" disabled"; + pwmrampstepsSTYLE=" style='text-decoration: line-through; color: #555;'"; + pwmrampstepsDisable=" disabled"; }else{ motorSELECT0= " selected"; motorSELECT1= ""; pwmenableSTYLE=""; pwmenableDisable=""; -} -if(PWMenable==true){ - pwmSELECT0= ""; - pwmSELECT1= " selected"; -}else{ - pwmSELECT0= " selected"; - pwmSELECT1= ""; + if(PWMenable==true){ + pwmSELECT0= ""; + pwmSELECT1= " selected"; + pwmdegreeSTYLE= ""; + pwmdegreeDisable= ""; + pwmrampstepsSTYLE= ""; + pwmrampstepsDisable= ""; + }else{ + pwmSELECT0= " selected"; + pwmSELECT1= ""; + pwmdegreeSTYLE=" style='text-decoration: line-through; color: #555;'"; + pwmdegreeDisable=" disabled"; + pwmrampstepsSTYLE=" style='text-decoration: line-through; color: #555;'"; + pwmrampstepsDisable=" disabled"; + } } + String HtmlSrc = "SETUP\n"; HtmlSrc +="\n"; // \n"; @@ -4772,7 +4857,7 @@ if(PWMenable==true){ HtmlSrc += sourceSELECT0; HtmlSrc +=">Potentiometer