diff --git a/Client/source/MainFrm.dfm b/Client/source/MainFrm.dfm index 5689c93..e1906b1 100644 --- a/Client/source/MainFrm.dfm +++ b/Client/source/MainFrm.dfm @@ -108,8 +108,6 @@ object MainForm: TMainForm Align = alClient BevelOuter = bvNone TabOrder = 0 - ExplicitTop = 56 - ExplicitHeight = 121 end object SimulatorSelectionPanel: TPanel Left = 2 @@ -119,9 +117,6 @@ object MainForm: TMainForm Align = alTop BevelOuter = bvNone TabOrder = 1 - ExplicitLeft = 192 - ExplicitTop = 72 - ExplicitWidth = 185 DesignSize = ( 560 41) diff --git a/Client/source/MainFrm.pas b/Client/source/MainFrm.pas index 740bc18..60fbf06 100644 --- a/Client/source/MainFrm.pas +++ b/Client/source/MainFrm.pas @@ -111,12 +111,14 @@ procedure TMainForm.FormClose(Sender: TObject; var Action: TCloseAction); begin if Ready then begin + FReady := False; + SendCommand('>SetFans:0', procedure(Response: string) begin - FReady := False; Close; end); + Action := caNone; end; end; @@ -225,7 +227,13 @@ begin StartCommand; FOnResponse := AOnResponse; FOnTimeout := AOnTimeout; - ComPort.WriteStr(ACommand + #10); + + try + ComPort.WriteStr(ACommand + #10); + except + on E:Exception do + PortStatusLabel.Caption := 'Failed to send command'; + end; end; @@ -275,6 +283,9 @@ var value: Byte; begin + if not Ready then + exit; + if ValidFanIndex(AFan) and (FFanValues[AFan] <> AValue) then begin FFanValues[AFan] := AValue; @@ -300,12 +311,25 @@ end; procedure TMainForm.SetAll(const AValue: Byte); var fanIndex: Integer; + changed: Boolean; begin - for fanIndex := 0 to High(FFanValues) do - FFanValues[fanIndex] := AValue; + if not Ready then + exit; - SendCommand('>SetFans:A,' + IntToStr(AValue), nil); + changed := False; + + for fanIndex := 0 to High(FFanValues) do + begin + if FFanValues[fanIndex] <> AValue then + begin + FFanValues[fanIndex] := AValue; + changed := True; + end; + end; + + if changed then + SendCommand('>SetFans:A,' + IntToStr(AValue), nil); end; @@ -314,6 +338,9 @@ var fanIndex: Integer; begin + if not Ready then + exit; + for fanIndex := 0 to High(FFanValues) do FFanValues[fanIndex] := 255; diff --git a/SimulatorFans.ino b/SimulatorFans.ino index e327da0..974d035 100644 --- a/SimulatorFans.ino +++ b/SimulatorFans.ino @@ -72,28 +72,28 @@ const byte FanPin[FanCount] = }; -/* - * PWM mode configuration - */ // When a fan goes from completely off to a value below full, this -// determines how long the fan will run on full power before changing +// determines how long the fan will run on a higher value before changing // to the actual value, to give it a chance to start up. -#define PWMStartingFansTime 200 +#define StartingFansTime 200 + +// The value used when the fan is starting up (range 0 - 255) +#define StartingValue 128 // The minimum value at which the fan still spins reliably. Anything below // will be considered as 0. -#define PWMMinimumValue 32 +#define MinimumValue 70 /* * Servo mode configuration */ // The minimum pulse width. Servo library uses a default of 544. -#define ServoMinPulseWidth 544 +#define ServoMinPulseWidth 1000 // The maximum pulse width. Servo library uses a default of 2400. -#define ServoMaxPulseWidth 2400 +#define ServoMaxPulseWidth 2000 #define ServoPulseRange (ServoMaxPulseWidth - ServoMinPulseWidth) @@ -114,6 +114,7 @@ const byte FanPin[FanCount] = #define IsPWM (FanMode == ModePWM) #define IsServo (FanMode == ModeServo) + #if IsServo #include #endif @@ -121,10 +122,7 @@ const byte FanPin[FanCount] = typedef struct { byte value; - - #if IsPWM unsigned long startTime; - #endif #if IsServo Servo servo; @@ -132,10 +130,7 @@ typedef struct } FanStatus; -#if IsPWM unsigned long currentTime = 0; -#endif - FanStatus fanStatus[FanCount]; @@ -145,9 +140,7 @@ void handleGetFansCommand(); void handleSetFansCommand(); void handleUnknownCommand(char* command); -#if IsPWM void checkStartingFans(); -#endif void setFan(byte fan, byte value); @@ -181,6 +174,12 @@ void setup() #define correctedMillis() (millis() * (1024 / 64)) #endif + + #if IsServo + #define correctedMillis() millis() + #endif + + // Set up serial communication (through USB or the default pins) // 19.2k is fast enough for our purpose, and according to the ATMega's datasheet // has a low error percentage across the common oscillator frequencies. @@ -196,10 +195,8 @@ char* token; void loop() { - #if IsPWM currentTime = correctedMillis(); checkStartingFans(); - #endif if (Serial.available() > 0) { @@ -327,15 +324,13 @@ void handleUnknownCommand(char* command) } -#if IsPWM void checkStartingFans() { - // Check if any of the fans are currently starting up and - // have been for at least PWMStartingFansTime + // Check if any of the fans are currently starting up for (byte fan = 0; fan < FanCount; fan++) { if ((fanStatus[fan].startTime > 0) && - (currentTime - fanStatus[fan].startTime >= PWMStartingFansTime)) + (currentTime - fanStatus[fan].startTime >= StartingFansTime)) { fanStatus[fan].startTime = 0; setFan(fan, fanStatus[fan].value); @@ -343,16 +338,23 @@ void checkStartingFans() } } +#if IsPWM +#define writeFanValue(fan, value) analogWrite(FanPin[fan], value) +#endif +#if IsServo +#define writeFanValue(fan, value) fanStatus[fan].servo.writeMicroseconds(map(value, 0, 255, ServoMinValue, ServoMaxValue)) +#endif + void setFan(byte fan, byte value) { byte correctedValue = value; - if (correctedValue < PWMMinimumValue) + if (correctedValue < MinimumValue) correctedValue = 0; if ((fanStatus[fan].value == 0 || fanStatus[fan].startTime > 0) && correctedValue > 0) { - // Fan was off or still starting up, start with full power to kick it off - analogWrite(FanPin[fan], 255); + // Fan was off or still starting up, start with full power to kick it off + writeFanValue(fan, StartingValue); if (fanStatus[fan].startTime == 0) { @@ -363,17 +365,8 @@ void setFan(byte fan, byte value) { // Already running, simply change the speed and reset the start time if necessary fanStatus[fan].startTime = 0; - analogWrite(FanPin[fan], correctedValue); + writeFanValue(fan, correctedValue); } fanStatus[fan].value = correctedValue; } -#endif - -#if IsServo -void setFan(byte fan, byte value) -{ - fanStatus[fan].servo.writeMicroseconds(map(value, 0, 255, ServoMinValue, ServoMaxValue)); - fanStatus[fan].value = value; -} -#endif