├── ASCOMDriver ├── ArduinoST4Driver │ ├── .gitignore │ ├── ArduinoST4Driver.sln │ ├── ArduinoST4Driver.v12.suo │ ├── ArduinoST4Driver │ │ ├── .gitignore │ │ ├── ASCOM.ico │ │ ├── ASCOM.png │ │ ├── ASCOMDriverTemplate.snk │ │ ├── ArduinoST4Driver.csproj │ │ ├── Axis.cs │ │ ├── AxisController.cs │ │ ├── AxisMovementTracker.cs │ │ ├── Constants.cs │ │ ├── DeviceController.cs │ │ ├── Driver.cs │ │ ├── Orientation.cs │ │ ├── Properties │ │ │ ├── AssemblyInfo.cs │ │ │ ├── Resources.Designer.cs │ │ │ ├── Resources.resx │ │ │ ├── Settings.Designer.cs │ │ │ └── Settings.settings │ │ ├── Rates.cs │ │ ├── Resources │ │ │ └── ASCOM.bmp │ │ ├── SetupDialogForm.cs │ │ ├── SetupDialogForm.designer.cs │ │ ├── SetupDialogForm.resx │ │ └── app.config │ └── ArduinoST4TestForms │ │ ├── .gitignore │ │ ├── ArduinoST4TestForms.csproj │ │ ├── Form1.Designer.cs │ │ ├── Form1.cs │ │ ├── Form1.resx │ │ ├── Program.cs │ │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ │ └── app.config └── Installer │ └── ArduinoST4 Setup.iss ├── ArduinoCode └── ArduinoCode.ino ├── Hardware ├── diagram.png ├── final_back.jpg ├── final_case.png ├── final_front.jpg ├── plugged_into_scope.jpg ├── plugged_into_scope_small.jpg ├── prototype.png └── prototype_small.png ├── README.md └── Wiki ├── DriverConfiguration.png └── DriverSelection.png /ASCOMDriver/ArduinoST4Driver/.gitignore: -------------------------------------------------------------------------------- 1 | .vs 2 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArduinoST4Driver", "ArduinoST4Driver\ArduinoST4Driver.csproj", "{64308775-BD4A-469C-BCAB-3ED830B811AF}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArduinoST4TestForms", "ArduinoST4TestForms\ArduinoST4TestForms.csproj", "{8E8D406C-1838-4914-867D-AB602D0EAF3E}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Debug|Mixed Platforms = Debug|Mixed Platforms 14 | Debug|x86 = Debug|x86 15 | Release|Any CPU = Release|Any CPU 16 | Release|Mixed Platforms = Release|Mixed Platforms 17 | Release|x86 = Release|x86 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 23 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 24 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|x86.ActiveCfg = Debug|x86 25 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Debug|x86.Build.0 = Debug|x86 26 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 29 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|Mixed Platforms.Build.0 = Release|Any CPU 30 | {64308775-BD4A-469C-BCAB-3ED830B811AF}.Release|x86.ActiveCfg = Release|Any CPU 31 | {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|Any CPU.ActiveCfg = Debug|x86 32 | {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 33 | {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|Mixed Platforms.Build.0 = Debug|x86 34 | {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|x86.ActiveCfg = Debug|x86 35 | {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Debug|x86.Build.0 = Debug|x86 36 | {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|Any CPU.ActiveCfg = Release|x86 37 | {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|Mixed Platforms.ActiveCfg = Release|x86 38 | {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|Mixed Platforms.Build.0 = Release|x86 39 | {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|x86.ActiveCfg = Release|x86 40 | {8E8D406C-1838-4914-867D-AB602D0EAF3E}.Release|x86.Build.0 = Release|x86 41 | EndGlobalSection 42 | GlobalSection(SolutionProperties) = preSolution 43 | HideSolutionNode = FALSE 44 | EndGlobalSection 45 | EndGlobal 46 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver.v12.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver.v12.suo -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/ASCOM.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/ASCOM.ico -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/ASCOM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/ASCOM.png -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/ASCOMDriverTemplate.snk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/ASCOMDriverTemplate.snk -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/ArduinoST4Driver.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {64308775-BD4A-469C-BCAB-3ED830B811AF} 9 | Library 10 | Properties 11 | ASCOM.ArduinoST4 12 | ASCOM.ArduinoST4.Telescope 13 | 14 | 15 | 16 | 17 | 3.5 18 | v4.0 19 | ASCOM.ico 20 | true 21 | ASCOMDriverTemplate.snk 22 | publish\ 23 | true 24 | Disk 25 | false 26 | Foreground 27 | 7 28 | Days 29 | false 30 | false 31 | true 32 | 0 33 | 1.0.0.%2a 34 | false 35 | false 36 | true 37 | Client 38 | 39 | 40 | true 41 | full 42 | false 43 | bin\Debug\ 44 | DEBUG;TRACE 45 | prompt 46 | 4 47 | true 48 | AnyCPU 49 | true 50 | true 51 | 52 | 53 | pdbonly 54 | true 55 | bin\Release\ 56 | TRACE 57 | prompt 58 | 4 59 | AnyCPU 60 | false 61 | 62 | 63 | true 64 | bin\x86\Debug\ 65 | CODE_ANALYSIS;DEBUG;TRACE 66 | true 67 | true 68 | full 69 | x86 70 | true 71 | prompt 72 | MinimumRecommendedRules.ruleset 73 | 74 | 75 | bin\x86\Release\ 76 | TRACE 77 | true 78 | pdbonly 79 | x86 80 | prompt 81 | MinimumRecommendedRules.ruleset 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 3.5 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | True 114 | True 115 | Resources.resx 116 | 117 | 118 | True 119 | True 120 | Settings.settings 121 | 122 | 123 | 124 | Form 125 | 126 | 127 | SetupDialogForm.cs 128 | 129 | 130 | 131 | 132 | Designer 133 | ResXFileCodeGenerator 134 | Resources.Designer.cs 135 | 136 | 137 | SetupDialogForm.cs 138 | Designer 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | SettingsSingleFileGenerator 147 | Settings.Designer.cs 148 | 149 | 150 | 151 | 152 | 153 | 154 | False 155 | .NET Framework 3.5 SP1 Client Profile 156 | false 157 | 158 | 159 | False 160 | .NET Framework 3.5 SP1 161 | true 162 | 163 | 164 | False 165 | Windows Installer 3.1 166 | true 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 181 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Axis.cs: -------------------------------------------------------------------------------- 1 | // This file is part of Arduino ST4. 2 | // 3 | // Arduino ST4 is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU Lesser General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // Arduino ST4 is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License 14 | // along with Arduino ST4. If not, see . 15 | 16 | namespace ASCOM.ArduinoST4 17 | { 18 | enum Axis 19 | { 20 | RA = 0, 21 | DEC = 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/AxisController.cs: -------------------------------------------------------------------------------- 1 | // This file is part of Arduino ST4. 2 | // 3 | // Arduino ST4 is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU Lesser General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // Arduino ST4 is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License 14 | // along with Arduino ST4. If not, see . 15 | 16 | using ASCOM.Utilities; 17 | using System; 18 | using System.Threading; 19 | 20 | namespace ASCOM.ArduinoST4 21 | { 22 | /// 23 | /// Controls an axis. 24 | /// 25 | /// Responsible for telling the hardware to start and stop slewing. 26 | /// Keeps trace of the position while doing so. 27 | /// 28 | /// Can move the axis for a given amount of time or until a position is reached. 29 | /// 30 | /// Author: Kevin Ferrare 31 | class AxisController : IDisposable 32 | { 33 | private TraceLogger traceLogger; 34 | 35 | /// 36 | /// Axis controlled by this object 37 | /// 38 | private Axis axis; 39 | 40 | /// 41 | /// Helper to keep track of the position along the axis depending on the slew time 42 | /// 43 | private AxisMovementTracker axisMovementTracker; 44 | 45 | /// 46 | /// Actual hardware controller 47 | /// 48 | private DeviceController deviceController; 49 | 50 | /// 51 | /// Thread that will wait for axis to finish slewing asynchronously 52 | /// 53 | private Thread waitAndStopAsyncThread; 54 | 55 | /// 56 | /// Slew rate to use when moving in the MINUS orientation 57 | /// 58 | private double minusSlewRate; 59 | 60 | /// 61 | /// Slew rate to use when moving in the PLUS orientation 62 | /// 63 | private double plusSlewRate; 64 | 65 | /// 66 | /// Build an AxisPositionController object. 67 | /// 68 | /// 69 | /// Axis controlled by this object 70 | /// Actual hardware controller 71 | /// Slew rate to use when moving in the MINUS orientation 72 | /// Slew rate to use when moving in the PLUS orientation 73 | public AxisController(Axis axis, DeviceController deviceController, double minusSlewRate, double plusSlewRate) 74 | { 75 | this.traceLogger = new TraceLogger("", "ArduinoST4 AxisPositionController " + axis.ToString()); 76 | this.traceLogger.Enabled = true; 77 | this.axis = axis; 78 | this.deviceController = deviceController; 79 | this.minusSlewRate = minusSlewRate; 80 | this.plusSlewRate = plusSlewRate; 81 | this.axisMovementTracker = new AxisMovementTracker(); 82 | } 83 | 84 | /// 85 | /// Return the slew rate corresponding to the given orientation 86 | /// 87 | /// Orientation for which the slew rate is requested 88 | /// 89 | private double CalculateSlewRate(Orientation slewOrientation) 90 | { 91 | return slewOrientation == Orientation.PLUS ? this.plusSlewRate : this.minusSlewRate; 92 | } 93 | 94 | /// 95 | /// Return an orientation from the given positive or negative slew rate. 96 | /// 97 | /// Slew rate, eithe positive or negative 98 | /// 99 | private Orientation CalculateOrientation(double slewRate) 100 | { 101 | return slewRate > 0 ? Orientation.PLUS : Orientation.MINUS; 102 | } 103 | 104 | /// 105 | /// Whether the axis is currently moving or not 106 | /// 107 | public Boolean Moving 108 | { 109 | get 110 | { 111 | return SlewRate != 0; 112 | } 113 | } 114 | 115 | /// 116 | /// Current position of the axis 117 | /// 118 | public double Position 119 | { 120 | get 121 | { 122 | return this.axisMovementTracker.Position; 123 | } 124 | set 125 | { 126 | this.axisMovementTracker.Position = value; 127 | this.Log("Position Set", "New position is " + value); 128 | } 129 | } 130 | 131 | /// 132 | /// Current rate at which the axis is slewing, can be 0 if not moving 133 | /// 134 | public double SlewRate 135 | { 136 | get 137 | { 138 | return this.axisMovementTracker.SlewRate; 139 | } 140 | } 141 | 142 | /// 143 | /// Move the axis for the given time with the given orientation. 144 | /// If provided time is null or async is true, will not wait for the move to complete. 145 | /// 146 | /// Duration of the move, moves indefinitely if null 147 | /// Orientation to move the axis (+ or -) 148 | /// If true, will return without waiting for the move to complete 149 | /// 150 | protected void Move(TimeSpan? moveDuration, Orientation orientation, Boolean async) 151 | { 152 | this.Log("Move", "duration=" + (moveDuration == null ? "null" : moveDuration.ToString()) + ", orientation=" + orientation + ", async=" + async); 153 | //Stop any async move 154 | this.Log("Move", "Stopping any move"); 155 | this.Stop(); 156 | if (moveDuration != null && ((TimeSpan)moveDuration).TotalMilliseconds == 0) 157 | { 158 | this.Log("Move", "Nothing to do :)"); 159 | //Nothing to do :) 160 | return; 161 | } 162 | //Tell the device to move 163 | this.deviceController.Move(this.axis, orientation); 164 | //Start tracking move position 165 | this.axisMovementTracker.Start(this.CalculateSlewRate(orientation)); 166 | //Respect the duration if it has been specified 167 | if (moveDuration != null) 168 | { 169 | if (async) 170 | { 171 | this.WaitAndStopAsync((TimeSpan)moveDuration); 172 | } 173 | else 174 | { 175 | this.WaitAndStop((TimeSpan)moveDuration); 176 | } 177 | } 178 | } 179 | 180 | /// 181 | /// Move the axis with the given orientation. 182 | /// Return immediatly leaving the axis moving for as long as Stop or another move is not called. 183 | /// Orientation of the move 184 | /// 185 | public void Move(Orientation orientation) 186 | { 187 | this.Move(null, orientation); 188 | } 189 | 190 | /// 191 | /// Move the axis for the given duration with the given orientation. 192 | /// Return immediatly without waiting for the move to complete. 193 | /// Duration of the move 194 | /// Orientation of the move 195 | /// 196 | public void Move(TimeSpan? moveDuration, Orientation orientation) 197 | { 198 | this.Log("Move", "orientation=" + orientation); 199 | this.Move(moveDuration, orientation, true); 200 | } 201 | 202 | /// 203 | /// Move the axis until the position changes by the given positionDifference. 204 | /// Return immediatly without waiting for the move to complete. 205 | /// Value to add or remove to the current position 206 | /// 207 | public void Move(double positionDifference) 208 | { 209 | this.Log("Move", "positionDifference=" + positionDifference + ", currentPosition=" + this.Position); 210 | Orientation orientation = this.CalculateOrientation(positionDifference); 211 | double remainingTimeInSeconds = positionDifference / this.CalculateSlewRate(orientation); 212 | //Calculates the time difference to reach the given position 213 | TimeSpan time = TimeSpan.FromSeconds(remainingTimeInSeconds); 214 | this.Move(time, orientation, true); 215 | } 216 | 217 | /// 218 | /// Stop the hardware slew and aborts the waiting thread 219 | /// 220 | public void Stop() 221 | { 222 | if (this.waitAndStopAsyncThread != null && this.waitAndStopAsyncThread.IsAlive) 223 | { 224 | //Stops the waiting thread 225 | this.waitAndStopAsyncThread.Abort(); 226 | this.waitAndStopAsyncThread = null; 227 | } 228 | this.StopMovement(); 229 | } 230 | 231 | /// 232 | /// Wait for the axis to stop moving. 233 | /// Will return immediately if no asynchronous move is currently taking place. 234 | /// 235 | public void WaitAsyncMoveEnd() 236 | { 237 | if (this.waitAndStopAsyncThread != null && this.waitAndStopAsyncThread.IsAlive) 238 | { 239 | this.waitAndStopAsyncThread.Join(); 240 | } 241 | } 242 | /// 243 | /// Wait the given amount of time, then stop the movement 244 | /// 245 | private void WaitAndStop(TimeSpan moveDuration) 246 | { 247 | Thread.Sleep(moveDuration); 248 | this.StopMovement(); 249 | this.Log("WaitAndStop", "Waited for move to complete for " + moveDuration.ToString() + " sec, stopped. Current position is " + this.Position); 250 | } 251 | 252 | /// 253 | /// Stop the movement and the position tracking 254 | /// 255 | private void StopMovement() 256 | { 257 | //Stop the position tracking 258 | this.axisMovementTracker.Stop(); 259 | 260 | //Stop the hardware movement 261 | this.deviceController.Move(this.axis, null); 262 | } 263 | 264 | /// 265 | /// Start a thread that will execute WaitAndStop so that the waiting can be done in background. 266 | /// Ensure that no other waiting thread for the axis is active before calling. 267 | /// 268 | private void WaitAndStopAsync(TimeSpan moveDuration) 269 | { 270 | this.Log("StartAsyncMove", "Starting async thread"); 271 | this.waitAndStopAsyncThread = new Thread( 272 | delegate(object data) 273 | { 274 | WaitAndStop(moveDuration); 275 | } 276 | ); 277 | this.waitAndStopAsyncThread.Start(); 278 | } 279 | 280 | public void Dispose() 281 | { 282 | Stop(); 283 | // Clean up the tracelogger and util objects 284 | traceLogger.Enabled = false; 285 | traceLogger.Dispose(); 286 | traceLogger = null; 287 | } 288 | 289 | private void Log(String id, String message) 290 | { 291 | this.traceLogger.LogMessage(id + " " + this.axis.ToString(), message); 292 | } 293 | } 294 | } 295 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/AxisMovementTracker.cs: -------------------------------------------------------------------------------- 1 | // This file is part of Arduino ST4. 2 | // 3 | // Arduino ST4 is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU Lesser General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // Arduino ST4 is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License 14 | // along with Arduino ST4. If not, see . 15 | 16 | using System; 17 | 18 | namespace ASCOM.ArduinoST4 19 | { 20 | /// 21 | /// Keeps track of the position of an axis. 22 | /// 23 | /// Updates the position from the slew rate and the movement start / stop time 24 | /// 25 | /// Author: Kevin Ferrare 26 | class AxisMovementTracker 27 | { 28 | 29 | /// 30 | /// Start position before slewing started. Is updated when calling Stop(). 31 | /// 32 | private double position = 0; 33 | 34 | /// 35 | /// Slew rate for the axis 36 | /// 37 | private double slewRate; 38 | 39 | /// 40 | /// Time at which the slewing started, used to calculate the current position 41 | /// 42 | private DateTime slewStartTime; 43 | 44 | public AxisMovementTracker() 45 | { 46 | } 47 | 48 | /// 49 | /// Calculate the position delta from time represented by the slewStartTime property until now. 50 | /// 51 | /// 52 | private double CalculateCurrentPositionDelta() 53 | { 54 | TimeSpan slewTime = DateTime.Now - this.slewStartTime; 55 | return slewRate * slewTime.TotalSeconds; 56 | } 57 | 58 | /// 59 | /// Position of the axis. The value returned is calculated when the axis is moving. 60 | /// 61 | public double Position 62 | { 63 | get 64 | { 65 | //If moving, returns calculated position 66 | if (this.SlewRate != 0) 67 | { 68 | return this.position + this.CalculateCurrentPositionDelta(); 69 | } 70 | else 71 | { 72 | return this.position; 73 | } 74 | 75 | } 76 | set 77 | { 78 | this.position = value; 79 | } 80 | } 81 | 82 | /// 83 | /// Rate at which the axis is moving 84 | /// 85 | public double SlewRate 86 | { 87 | get 88 | { 89 | return this.slewRate; 90 | } 91 | } 92 | 93 | /// 94 | /// Start keeping track of the movement with the given slew rate 95 | /// 96 | /// Rate at which the axis is moving 97 | public void Start(double slewRate) 98 | { 99 | this.slewRate = slewRate; 100 | this.slewStartTime = DateTime.Now; 101 | } 102 | 103 | /// 104 | /// Stop keeping track of the movement 105 | /// 106 | public void Stop() 107 | { 108 | this.position += CalculateCurrentPositionDelta(); 109 | this.slewRate = 0; 110 | } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Constants.cs: -------------------------------------------------------------------------------- 1 | // This file is part of Arduino ST4. 2 | // 3 | // Arduino ST4 is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU Lesser General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // Arduino ST4 is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License 14 | // along with Arduino ST4. If not, see . 15 | 16 | namespace ASCOM.ArduinoST4 17 | { 18 | /// 19 | /// Constants used by the driver 20 | /// 21 | /// Author: Kevin Ferrare 22 | class Constants 23 | { 24 | public const double DEGREES_PER_SECOND = 360d / (24d * 3600d); 25 | public const double RA_PER_SECOND = 1d / 3600d; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/DeviceController.cs: -------------------------------------------------------------------------------- 1 | // This file is part of Arduino ST4. 2 | // 3 | // Arduino ST4 is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU Lesser General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // Arduino ST4 is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License 14 | // along with Arduino ST4. If not, see . 15 | 16 | using ASCOM.Utilities; 17 | using System; 18 | 19 | namespace ASCOM.ArduinoST4 20 | { 21 | /// 22 | /// Hardware communication is implemented here. 23 | /// 24 | /// Author: Kevin Ferrare 25 | class DeviceController : IDisposable 26 | { 27 | private TraceLogger traceLogger; 28 | 29 | /// 30 | /// Serial connection to the device 31 | /// 32 | private Serial serialConnection = new Serial(); 33 | 34 | /// 35 | /// Whether the device is connected or not 36 | /// 37 | private Boolean connected; 38 | 39 | public DeviceController() 40 | { 41 | traceLogger = new TraceLogger("", "ArduinoST4 DeviceController"); 42 | traceLogger.Enabled = true; 43 | connected = false; 44 | } 45 | 46 | /// 47 | /// Connect to the arduino with the given com port. 48 | /// 49 | /// 50 | public void Connect(String comPort) 51 | { 52 | traceLogger.LogMessage("Connected Set", "Connecting to port " + comPort); 53 | serialConnection.PortName = comPort; 54 | //57.6k 55 | serialConnection.Speed = SerialSpeed.ps57600; 56 | //No parity 57 | serialConnection.Parity = SerialParity.None; 58 | //Stop bit one 59 | serialConnection.StopBits = SerialStopBits.One; 60 | serialConnection.DataBits = 8; 61 | //Timeout, initial message can take up to 5 seconds while the arduino initializes 62 | serialConnection.ReceiveTimeout = 5; 63 | serialConnection.Connected = true; 64 | 65 | //The arduino will send "INITIALIZED" by itself once it is ready (can take several seconds) 66 | String initialMessage = ReadResponse(); 67 | //Reset device and light up the LED 68 | this.connected = CommandBool("CONNECT"); 69 | if (!this.connected) 70 | { 71 | //close serial connection when it failed 72 | serialConnection.Connected = false; 73 | } 74 | } 75 | 76 | /// 77 | /// Disconnect from the arduino 78 | /// 79 | public void Disconnect() 80 | { 81 | //Tell bye-bye to the device 82 | CommandBool("DISCONNECT"); 83 | this.connected = false; 84 | traceLogger.LogMessage("Connected Set", "Disconnecting"); 85 | serialConnection.Connected = false; 86 | } 87 | 88 | /// 89 | /// Return true when connected 90 | /// 91 | public bool Connected 92 | { 93 | get 94 | { 95 | traceLogger.LogMessage("Connected Get", connected.ToString()); 96 | return this.connected; 97 | } 98 | } 99 | 100 | /// 101 | /// Send the given command to the device. 102 | /// 103 | /// Command to send 104 | /// true if it has been understood correctly 105 | public bool CommandBool(string command) 106 | { 107 | string ret = CommandString(command); 108 | //Successful commands should return OK 109 | return ret.Equals("OK"); 110 | } 111 | 112 | /// 113 | /// Send the given command to the device. 114 | /// 115 | /// Command to send 116 | /// Response returned by the device 117 | public string CommandString(string command) 118 | { 119 | traceLogger.LogMessage("CommandString", "Sending command " + command); 120 | //All commands from and to the arduino ends with # 121 | serialConnection.Transmit(command + "#"); 122 | return ReadResponse(); 123 | } 124 | 125 | /// 126 | /// Read a response from the arduino and returns it 127 | /// 128 | private String ReadResponse() 129 | { 130 | traceLogger.LogMessage("ReadResponse", "Reading response"); 131 | String response = serialConnection.ReceiveTerminated("#"); 132 | response = response.Replace("#", "").Replace("\r", "").Replace("\n", ""); 133 | traceLogger.LogMessage("ReadResponse", "Received response " + response); 134 | return response; 135 | } 136 | 137 | /// 138 | /// Tell the hardware to start / stop moving on the given axis. 139 | /// If the given orientation is null, the movement will stop. 140 | /// 141 | /// Axis to move 142 | /// Orientation along the axis 143 | public void Move(Axis axis, Orientation? orientation) 144 | { 145 | //Do nothing if not connected 146 | if (!this.Connected) 147 | { 148 | return; 149 | } 150 | String axisName = axis.ToString(); 151 | if (orientation == null) 152 | { 153 | //Stops the movement for the axis 154 | this.CommandBool(axisName + "0"); 155 | } 156 | else 157 | { 158 | String sign = (Orientation)orientation == Orientation.PLUS ? "+" : "-"; 159 | this.CommandBool(axisName + sign); 160 | } 161 | } 162 | 163 | public void Dispose() 164 | { 165 | traceLogger.Enabled = false; 166 | traceLogger.Dispose(); 167 | traceLogger = null; 168 | serialConnection.Dispose(); 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Driver.cs: -------------------------------------------------------------------------------- 1 | // This file is part of Arduino ST4. 2 | // 3 | // Arduino ST4 is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU Lesser General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // Arduino ST4 is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License 14 | // along with Arduino ST4. If not, see . 15 | 16 | // ASCOM Telescope driver for ArduinoST4 17 | // 18 | // Description: Driver for an USB-ST4 interface implemented with an arduino. 19 | // Pulse guiding and slew is supported, allowing for very slow goto :) 20 | // 21 | // Implements: ASCOM Telescope interface version: 22 | // Author: (Kevin FERRARE) kevinferrare@gmail.com 23 | 24 | using ASCOM.DeviceInterface; 25 | using ASCOM.Utilities; 26 | using System; 27 | using System.Collections; 28 | using System.Globalization; 29 | using System.Runtime.InteropServices; 30 | 31 | namespace ASCOM.ArduinoST4 32 | { 33 | /// 34 | /// ASCOM Telescope Driver for ArduinoST4. 35 | /// A big part of the code in this class is autogenerated boilerplate for ASCOM API. 36 | /// Real logic is under AxisPositionController. 37 | /// 38 | /// GUID is for COM identification of the component. 39 | /// ClassInterface is to make it invisible to other COM clients. 40 | /// 41 | /// Author: Kevin Ferrare 42 | [Guid("045b2ced-6f70-4a3a-8483-1891f235deb1")] 43 | [ClassInterface(ClassInterfaceType.None)] 44 | public class Telescope : ITelescopeV3, IDisposable 45 | { 46 | /// 47 | /// ASCOM DeviceID (COM ProgID) for this driver. 48 | /// The DeviceID is used by ASCOM applications to load the driver at runtime. 49 | /// 50 | internal static string driverID = "ASCOM.ArduinoST4.Telescope"; 51 | 52 | /// 53 | /// Driver description that displays in the ASCOM Chooser. 54 | /// 55 | private static string driverDescription = "ArduinoST4 telescope driver"; 56 | 57 | /// 58 | /// Right ascension and declination speed of the device in sideral multiple (earth rotation multiple) 59 | /// 60 | internal static double rightAscensionSideralRatePlus = 9;//8X Sideral Rate + 1 for earth rotation 61 | internal static double rightAscensionSideralRateMinus = 7;//8X Sideral Rate - 1 for earth rotation 62 | internal static double declinationSideralRatePlus = 8; 63 | internal static double declinationSideralRateMinus = 8; 64 | 65 | /// 66 | /// COM port for arduino access 67 | /// 68 | internal static string comPort = ""; 69 | 70 | /// 71 | /// Enable logging 72 | /// 73 | internal static bool traceState = false; 74 | 75 | /// 76 | /// ASCOM Utilities object, used only to calculate dates 77 | /// 78 | private Util utilities = new Util(); 79 | 80 | /// 81 | /// Logger 82 | /// 83 | private TraceLogger traceLogger; 84 | 85 | /// 86 | /// Handles the communication with the arduino 87 | /// 88 | private DeviceController deviceController; 89 | 90 | /// 91 | /// Target position 92 | /// 93 | private double? targetRightAscension; 94 | private double? targetDeclination; 95 | 96 | /// 97 | /// Controller for each axis, talks with the device controller to start / stop movement, keeps track of the position while doing so 98 | /// 99 | private AxisController[] axisControllers; 100 | 101 | public Telescope() 102 | { 103 | // Read device configuration from the ASCOM Profile store 104 | ReadProfile(); 105 | 106 | traceLogger = new TraceLogger("", "ArduinoST4"); 107 | traceLogger.Enabled = traceState; 108 | traceLogger.LogMessage("Telescope", "Starting initialisation"); 109 | 110 | deviceController = new DeviceController(); 111 | 112 | //Setup the axes 113 | axisControllers = new AxisController[2]; 114 | axisControllers[(int)Axis.RA] = new AxisController(Axis.RA, this.deviceController, -Constants.RA_PER_SECOND * rightAscensionSideralRateMinus, Constants.RA_PER_SECOND * rightAscensionSideralRatePlus); 115 | axisControllers[(int)Axis.DEC] = new AxisController(Axis.DEC, this.deviceController, -Constants.DEGREES_PER_SECOND * declinationSideralRateMinus, Constants.DEGREES_PER_SECOND * declinationSideralRatePlus); 116 | traceLogger.LogMessage("Telescope", "Completed initialisation"); 117 | } 118 | 119 | 120 | #region Common properties and methods. 121 | 122 | /// 123 | /// Displays the Setup Dialog form. 124 | /// If the user clicks the OK button to dismiss the form, then 125 | /// the new settings are saved, otherwise the old values are reloaded. 126 | /// THIS IS THE ONLY PLACE WHERE SHOWING USER INTERFACE IS ALLOWED! 127 | /// 128 | public void SetupDialog() 129 | { 130 | // Only show the setup dialog if not connected 131 | if (this.deviceController.Connected) 132 | { 133 | System.Windows.Forms.MessageBox.Show("Already connected, just press OK"); 134 | return; 135 | } 136 | 137 | using (SetupDialogForm setupDialogForm = new SetupDialogForm()) 138 | { 139 | var result = setupDialogForm.ShowDialog(); 140 | if (result == System.Windows.Forms.DialogResult.OK) 141 | { 142 | WriteProfile(); // Persist device configuration values to the ASCOM Profile store 143 | } 144 | } 145 | } 146 | 147 | public void CommandBlind(string command, bool raw) 148 | { 149 | CheckConnected("CommandBlind"); 150 | // Call CommandString and return as soon as it finishes 151 | this.CommandString(command, raw); 152 | } 153 | 154 | public bool CommandBool(string command, bool raw) 155 | { 156 | CheckConnected("CommandBool"); 157 | return deviceController.CommandBool(command); 158 | } 159 | 160 | public string CommandString(string command, bool raw) 161 | { 162 | CheckConnected("CommandString"); 163 | return deviceController.CommandString(command); 164 | } 165 | 166 | public bool Connected 167 | { 168 | get 169 | { 170 | traceLogger.LogMessage("Connected Get", this.deviceController.Connected.ToString()); 171 | return this.deviceController.Connected; 172 | } 173 | set 174 | { 175 | traceLogger.LogMessage("Connected Set", value.ToString()); 176 | if (value == this.deviceController.Connected) 177 | { 178 | return; 179 | } 180 | if (value) 181 | { 182 | this.deviceController.Connect(comPort); 183 | } 184 | else 185 | { 186 | this.deviceController.Disconnect(); 187 | } 188 | } 189 | } 190 | 191 | public string Description 192 | { 193 | get 194 | { 195 | traceLogger.LogMessage("Description Get", driverDescription); 196 | return driverDescription; 197 | } 198 | } 199 | 200 | public string DriverInfo 201 | { 202 | get 203 | { 204 | Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; 205 | string driverInfo = "Information about the driver itself. Version: " + DriverVersion; 206 | traceLogger.LogMessage("DriverInfo Get", driverInfo); 207 | return driverInfo; 208 | } 209 | } 210 | 211 | public string DriverVersion 212 | { 213 | get 214 | { 215 | Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; 216 | string driverVersion = String.Format(CultureInfo.InvariantCulture, "{0}.{1}", version.Major, version.Minor); 217 | traceLogger.LogMessage("DriverVersion Get", driverVersion); 218 | return driverVersion; 219 | } 220 | } 221 | 222 | public short InterfaceVersion 223 | { 224 | // set by the driver wizard 225 | get 226 | { 227 | traceLogger.LogMessage("InterfaceVersion Get", "3"); 228 | return 3; 229 | } 230 | } 231 | 232 | public string Name 233 | { 234 | get 235 | { 236 | string name = "ArduinoST4"; 237 | traceLogger.LogMessage("Name Get", name); 238 | return name; 239 | } 240 | } 241 | 242 | #endregion 243 | 244 | #region ITelescope Implementation 245 | public void AbortSlew() 246 | { 247 | axisControllers[(int)Axis.RA].Stop(); 248 | axisControllers[(int)Axis.DEC].Stop(); 249 | } 250 | 251 | public AlignmentModes AlignmentMode 252 | { 253 | get 254 | { 255 | return AlignmentModes.algGermanPolar; 256 | } 257 | } 258 | 259 | public IAxisRates AxisRates(TelescopeAxes axis) 260 | { 261 | traceLogger.LogMessage("AxisRates", "Get - " + axis.ToString()); 262 | return new AxisRates(axis); 263 | } 264 | 265 | #region Capabilities 266 | public bool CanMoveAxis(TelescopeAxes axis) 267 | { 268 | traceLogger.LogMessage("CanMoveAxis", "Get - " + axis.ToString()); 269 | switch (axis) 270 | { 271 | case TelescopeAxes.axisPrimary: return true; 272 | case TelescopeAxes.axisSecondary: return true; 273 | case TelescopeAxes.axisTertiary: return false; 274 | default: throw new InvalidValueException("CanMoveAxis", axis.ToString(), "0 to 2"); 275 | } 276 | } 277 | 278 | public bool CanPulseGuide 279 | { 280 | get 281 | { 282 | traceLogger.LogMessage("CanPulseGuide", "Get - " + true.ToString()); 283 | return true; 284 | } 285 | } 286 | 287 | public bool CanSetGuideRates 288 | { 289 | get 290 | { 291 | traceLogger.LogMessage("CanSetGuideRates", "Get - " + false.ToString()); 292 | return false; 293 | } 294 | } 295 | 296 | public bool CanSlew 297 | { 298 | get 299 | { 300 | traceLogger.LogMessage("CanSlew", "Get - " + true.ToString()); 301 | return true; 302 | } 303 | } 304 | 305 | public bool CanSlewAsync 306 | { 307 | get 308 | { 309 | traceLogger.LogMessage("CanSlewAsync", "Get - " + true.ToString()); 310 | return true; 311 | } 312 | } 313 | 314 | public bool CanSync 315 | { 316 | get 317 | { 318 | traceLogger.LogMessage("CanSync", "Get - " + true.ToString()); 319 | return true; 320 | } 321 | } 322 | 323 | public bool CanFindHome 324 | { 325 | get 326 | { 327 | //No feedback on position=> cannot find home 328 | traceLogger.LogMessage("CanFindHome", "Get - " + false.ToString()); 329 | return false; 330 | } 331 | } 332 | 333 | public bool CanPark 334 | { 335 | get 336 | { 337 | //No feedback on position=> cannot park 338 | traceLogger.LogMessage("CanPark", "Get - " + false.ToString()); 339 | return false; 340 | } 341 | } 342 | 343 | public bool CanSetDeclinationRate 344 | { 345 | get 346 | { 347 | traceLogger.LogMessage("CanSetDeclinationRate", "Get - " + false.ToString()); 348 | return false; 349 | } 350 | } 351 | 352 | public bool CanSetPark 353 | { 354 | get 355 | { 356 | traceLogger.LogMessage("CanSetPark", "Get - " + false.ToString()); 357 | return false; 358 | } 359 | } 360 | 361 | public bool CanSetPierSide 362 | { 363 | get 364 | { 365 | traceLogger.LogMessage("CanSetPierSide", "Get - " + false.ToString()); 366 | return false; 367 | } 368 | } 369 | 370 | public bool CanSetRightAscensionRate 371 | { 372 | get 373 | { 374 | traceLogger.LogMessage("CanSetRightAscensionRate", "Get - " + false.ToString()); 375 | return false; 376 | } 377 | } 378 | 379 | public bool CanSetTracking 380 | { 381 | get 382 | { 383 | traceLogger.LogMessage("CanSetTracking", "Get - " + false.ToString()); 384 | return false; 385 | } 386 | } 387 | 388 | 389 | public bool CanSlewAltAz 390 | { 391 | get 392 | { 393 | traceLogger.LogMessage("CanSlewAltAz", "Get - " + false.ToString()); 394 | return false; 395 | } 396 | } 397 | 398 | public bool CanSlewAltAzAsync 399 | { 400 | get 401 | { 402 | traceLogger.LogMessage("CanSlewAltAzAsync", "Get - " + false.ToString()); 403 | return false; 404 | } 405 | } 406 | 407 | public bool CanSyncAltAz 408 | { 409 | get 410 | { 411 | traceLogger.LogMessage("CanSyncAltAz", "Get - " + false.ToString()); 412 | return false; 413 | } 414 | } 415 | 416 | public bool CanUnpark 417 | { 418 | get 419 | { 420 | traceLogger.LogMessage("CanUnpark", "Get - " + false.ToString()); 421 | return false; 422 | } 423 | } 424 | 425 | #endregion 426 | 427 | 428 | public double Declination 429 | { 430 | get 431 | { 432 | return axisControllers[(int)Axis.DEC].Position; 433 | } 434 | } 435 | 436 | public EquatorialCoordinateType EquatorialSystem 437 | { 438 | get 439 | { 440 | EquatorialCoordinateType equatorialSystem = EquatorialCoordinateType.equLocalTopocentric; 441 | traceLogger.LogMessage("DeclinationRate", "Get - " + equatorialSystem.ToString()); 442 | return equatorialSystem; 443 | } 444 | } 445 | 446 | public double GuideRateDeclination 447 | { 448 | get 449 | { 450 | return axisControllers[(int)Axis.DEC].SlewRate; 451 | } 452 | set 453 | { 454 | traceLogger.LogMessage("GuideRateDeclination Set", "Not implemented"); 455 | throw new ASCOM.PropertyNotImplementedException("GuideRateDeclination", true); 456 | } 457 | } 458 | 459 | public double GuideRateRightAscension 460 | { 461 | get 462 | { 463 | return axisControllers[(int)Axis.RA].SlewRate; 464 | } 465 | set 466 | { 467 | traceLogger.LogMessage("GuideRateRightAscension Set", "Not implemented"); 468 | throw new ASCOM.PropertyNotImplementedException("GuideRateRightAscension", true); 469 | } 470 | } 471 | 472 | public bool IsPulseGuiding 473 | { 474 | get 475 | { 476 | return this.Moving; 477 | } 478 | } 479 | 480 | public void MoveAxis(TelescopeAxes telescopeAxis, double rate) 481 | { 482 | traceLogger.LogMessage("MoveAxis", "TelescopeAxis - " + telescopeAxis.ToString() + "Rate - " + rate.ToString()); 483 | //Some checks on given values for API conformity 484 | if (telescopeAxis == TelescopeAxes.axisTertiary) 485 | { 486 | throw new ASCOM.InvalidValueException("TelescopeAxes", telescopeAxis.ToString(), "No ternary axis on ST-4"); 487 | } 488 | IRate axisRate = this.AxisRates(telescopeAxis)[1]; 489 | if (Math.Abs(rate) > axisRate.Maximum || Math.Abs(rate) < axisRate.Minimum) 490 | { 491 | throw new ASCOM.InvalidValueException("AxisRate", rate.ToString(), axisRate.Minimum + ".." + axisRate.Maximum); 492 | } 493 | 494 | Orientation orientation = rate > 0 ? Orientation.PLUS : Orientation.MINUS; 495 | Axis axis = telescopeAxis == TelescopeAxes.axisPrimary ? Axis.RA : Axis.DEC; 496 | AxisController axisPositionController = axisControllers[(int)axis]; 497 | if (rate == 0) 498 | { 499 | axisPositionController.Stop(); 500 | } 501 | else 502 | { 503 | axisPositionController.Move(orientation); 504 | } 505 | } 506 | 507 | 508 | public void PulseGuide(GuideDirections direction, int duration) 509 | { 510 | traceLogger.LogMessage("PulseGuide", "Direction - " + direction.ToString() + "Duration - " + duration.ToString()); 511 | //Duration in milliseconds 512 | TimeSpan moveDuration = TimeSpan.FromMilliseconds(duration); 513 | switch (direction) 514 | { 515 | case GuideDirections.guideEast: 516 | axisControllers[(int)Axis.RA].Move(moveDuration, Orientation.PLUS); 517 | break; 518 | case GuideDirections.guideWest: 519 | axisControllers[(int)Axis.RA].Move(moveDuration, Orientation.MINUS); 520 | break; 521 | case GuideDirections.guideNorth: 522 | axisControllers[(int)Axis.DEC].Move(moveDuration, Orientation.PLUS); 523 | break; 524 | case GuideDirections.guideSouth: 525 | axisControllers[(int)Axis.DEC].Move(moveDuration, Orientation.MINUS); 526 | break; 527 | } 528 | } 529 | 530 | public double RightAscension 531 | { 532 | get 533 | { 534 | double rightAscension = axisControllers[(int)Axis.RA].Position; 535 | rightAscension = (rightAscension % 24 + 24) % 24;//Ensure that RA is always positive and between 0 and 24 536 | return rightAscension; 537 | } 538 | } 539 | 540 | public double SiderealTime 541 | { 542 | get 543 | { 544 | double siderealTime = (18.697374558 + 24.065709824419081 * (utilities.DateLocalToJulian(DateTime.Now) - 2451545.0)) % 24.0; 545 | traceLogger.LogMessage("SiderealTime", "Get - " + siderealTime.ToString()); 546 | return siderealTime; 547 | } 548 | } 549 | 550 | public void SlewToCoordinates(double rightAscension, double declination) 551 | { 552 | traceLogger.LogMessage("SlewToCoordinatesAsync", "RightAscension=" + rightAscension.ToString() + ", Declination=" + declination.ToString()); 553 | SlewToCoordinatesAsync(rightAscension, declination); 554 | //Wait for both axes to finish 555 | this.axisControllers[(int)Axis.RA].WaitAsyncMoveEnd(); 556 | this.axisControllers[(int)Axis.DEC].WaitAsyncMoveEnd(); 557 | } 558 | 559 | public void SlewToCoordinatesAsync(double rightAscension, double declination) 560 | { 561 | traceLogger.LogMessage("SlewToCoordinatesAsync", "RightAscension=" + rightAscension.ToString() + ", Declination=" + declination.ToString() + " (current position ra=" + this.RightAscension + ", dec=" + this.Declination); 562 | double rightAscensionDelta = rightAscension - this.RightAscension; 563 | if (rightAscensionDelta < -12) 564 | { 565 | //Shortest path from 24 to 0 566 | rightAscensionDelta += 24; 567 | } 568 | else if (rightAscensionDelta > 12) 569 | { 570 | //Shortest path from 0 to 24 571 | rightAscensionDelta -= 24; 572 | } 573 | traceLogger.LogMessage("SlewToCoordinatesAsync", "RightAscension delta =" + rightAscensionDelta.ToString()); 574 | double declinationDelta = declination - this.Declination; 575 | this.axisControllers[(int)Axis.RA].Move(rightAscensionDelta); 576 | this.axisControllers[(int)Axis.DEC].Move(declinationDelta); 577 | } 578 | 579 | public void SlewToTarget() 580 | { 581 | SlewToCoordinates(TargetRightAscension, TargetDeclination); 582 | } 583 | 584 | public void SlewToTargetAsync() 585 | { 586 | SlewToCoordinatesAsync(TargetRightAscension, TargetDeclination); 587 | } 588 | 589 | public bool Slewing 590 | { 591 | get 592 | { 593 | // Slewing and pulse guiding are the same for the hardware 594 | return IsPulseGuiding; 595 | } 596 | } 597 | 598 | public void SyncToCoordinates(double rightAscension, double declination) 599 | { 600 | axisControllers[(int)Axis.RA].Position = rightAscension; 601 | axisControllers[(int)Axis.DEC].Position = declination; 602 | } 603 | 604 | public void SyncToTarget() 605 | { 606 | SyncToCoordinates(TargetRightAscension, TargetDeclination); 607 | } 608 | 609 | public double TargetDeclination 610 | { 611 | get 612 | { 613 | if (this.targetDeclination == null) 614 | { 615 | throw new ASCOM.ValueNotSetException("TargetDeclination"); 616 | } 617 | return (double)this.targetDeclination; 618 | } 619 | set 620 | { 621 | if (value < -90 || value > 90) 622 | { 623 | throw new ASCOM.InvalidValueException("TargetDeclination", value.ToString(), "-90..90"); 624 | } 625 | this.targetDeclination = value; 626 | } 627 | } 628 | 629 | public double TargetRightAscension 630 | { 631 | get 632 | { 633 | if (this.targetRightAscension == null) 634 | { 635 | throw new ASCOM.ValueNotSetException("TargetRightAscension"); 636 | } 637 | return (double)this.targetRightAscension; 638 | } 639 | set 640 | { 641 | if (value < 0 || value > 24) 642 | { 643 | throw new InvalidValueException("TargetRightAscension", value.ToString(), "0..24"); 644 | } 645 | this.targetRightAscension = value; 646 | } 647 | } 648 | 649 | public bool Tracking 650 | { 651 | get 652 | { 653 | //EQ5 is always tracking when motors are on 654 | bool tracking = !this.Moving; 655 | traceLogger.LogMessage("Tracking Get", tracking.ToString()); 656 | return tracking; 657 | } 658 | set 659 | { 660 | traceLogger.LogMessage("Tracking Set", "Not implemented"); 661 | throw new ASCOM.PropertyNotImplementedException("Tracking", false); 662 | } 663 | } 664 | 665 | public DriveRates TrackingRate 666 | { 667 | get 668 | { 669 | return DriveRates.driveSidereal; 670 | } 671 | set 672 | { 673 | } 674 | } 675 | 676 | public ITrackingRates TrackingRates 677 | { 678 | get 679 | { 680 | traceLogger.LogMessage("TrackingRates", "Get - "); 681 | return new TrackingRates(); 682 | } 683 | } 684 | 685 | public DateTime UTCDate 686 | { 687 | get 688 | { 689 | return DateTime.UtcNow; 690 | } 691 | set 692 | { 693 | } 694 | } 695 | 696 | #endregion 697 | 698 | #region Helpers 699 | 700 | #region ASCOM Registration 701 | 702 | // Register or unregister driver for ASCOM. This is harmless if already 703 | // registered or unregistered. 704 | // 705 | /// 706 | /// Register or unregister the driver with the ASCOM Platform. 707 | /// This is harmless if the driver is already registered/unregistered. 708 | /// 709 | /// If true, registers the driver, otherwise unregisters it. 710 | private static void RegUnregASCOM(bool register) 711 | { 712 | using (var profile = new ASCOM.Utilities.Profile()) 713 | { 714 | profile.DeviceType = "Telescope"; 715 | if (register) 716 | { 717 | profile.Register(driverID, driverDescription); 718 | } 719 | else 720 | { 721 | profile.Unregister(driverID); 722 | } 723 | } 724 | } 725 | 726 | /// 727 | /// This function registers the driver with the ASCOM Chooser and 728 | /// is called automatically whenever this class is registered for COM Interop. 729 | /// 730 | /// Type of the class being registered, not used. 731 | /// 732 | /// This method typically runs in two distinct situations: 733 | /// 734 | /// 735 | /// In Visual Studio, when the project is successfully built. 736 | /// For this to work correctly, the option Register for COM Interop 737 | /// must be enabled in the project settings. 738 | /// 739 | /// During setup, when the installer registers the assembly for COM Interop. 740 | /// 741 | /// This technique should mean that it is never necessary to manually register a driver with ASCOM. 742 | /// 743 | [ComRegisterFunction] 744 | public static void RegisterASCOM(Type t) 745 | { 746 | RegUnregASCOM(true); 747 | } 748 | 749 | /// 750 | /// This function unregisters the driver from the ASCOM Chooser and 751 | /// is called automatically whenever this class is unregistered from COM Interop. 752 | /// 753 | /// Type of the class being registered, not used. 754 | /// 755 | /// This method typically runs in two distinct situations: 756 | /// 757 | /// 758 | /// In Visual Studio, when the project is cleaned or prior to rebuilding. 759 | /// For this to work correctly, the option Register for COM Interop 760 | /// must be enabled in the project settings. 761 | /// 762 | /// During uninstall, when the installer unregisters the assembly from COM Interop. 763 | /// 764 | /// This technique should mean that it is never necessary to manually unregister a driver from ASCOM. 765 | /// 766 | [ComUnregisterFunction] 767 | public static void UnregisterASCOM(Type t) 768 | { 769 | RegUnregASCOM(false); 770 | } 771 | 772 | #endregion 773 | 774 | /// 775 | /// Throws an exception if not connected to the hardware 776 | /// 777 | /// 778 | private void CheckConnected(string message) 779 | { 780 | if (!this.deviceController.Connected) 781 | { 782 | throw new ASCOM.NotConnectedException(message); 783 | } 784 | } 785 | 786 | /// 787 | /// Read the device configuration from the ASCOM Profile store 788 | /// 789 | internal void ReadProfile() 790 | { 791 | using (Profile driverProfile = new Profile()) 792 | { 793 | driverProfile.DeviceType = "Telescope"; 794 | traceState = ReadBoolFromProfile(driverProfile, "traceState", traceState); 795 | comPort = ReadStringFromProfile(driverProfile, "comPort", comPort); 796 | rightAscensionSideralRatePlus = ReadDoubleFromProfile(driverProfile, "rightAscensionSideralRatePlus", rightAscensionSideralRatePlus); 797 | rightAscensionSideralRateMinus = ReadDoubleFromProfile(driverProfile, "rightAscensionSideralRateMinus", rightAscensionSideralRateMinus); 798 | declinationSideralRatePlus = ReadDoubleFromProfile(driverProfile, "declinationSideralRatePlus", declinationSideralRatePlus); 799 | declinationSideralRateMinus = ReadDoubleFromProfile(driverProfile, "declinationSideralRateMinus", declinationSideralRateMinus); 800 | } 801 | } 802 | 803 | internal bool ReadBoolFromProfile(Profile driverProfile, String profileName, bool defaultValue) 804 | { 805 | return Convert.ToBoolean(ReadStringFromProfile(driverProfile, profileName, Convert.ToString(defaultValue))); 806 | } 807 | 808 | internal double ReadDoubleFromProfile(Profile driverProfile, String profileName, double defaultValue) 809 | { 810 | return Convert.ToDouble(ReadStringFromProfile(driverProfile, profileName, Convert.ToString(defaultValue))); 811 | } 812 | 813 | internal String ReadStringFromProfile(Profile driverProfile, String profileName, String defaultValue) 814 | { 815 | return driverProfile.GetValue(driverID, profileName, string.Empty, defaultValue); 816 | } 817 | 818 | /// 819 | /// Write the device configuration to the ASCOM Profile store 820 | /// 821 | internal void WriteProfile() 822 | { 823 | using (Profile driverProfile = new Profile()) 824 | { 825 | driverProfile.DeviceType = "Telescope"; 826 | driverProfile.WriteValue(driverID, "traceState", traceState.ToString()); 827 | driverProfile.WriteValue(driverID, "comPort", comPort.ToString()); 828 | driverProfile.WriteValue(driverID, "rightAscensionSideralRatePlus", rightAscensionSideralRatePlus.ToString()); 829 | driverProfile.WriteValue(driverID, "rightAscensionSideralRateMinus", rightAscensionSideralRateMinus.ToString()); 830 | driverProfile.WriteValue(driverID, "declinationSideralRatePlus", declinationSideralRatePlus.ToString()); 831 | driverProfile.WriteValue(driverID, "declinationSideralRateMinus", declinationSideralRateMinus.ToString()); 832 | } 833 | } 834 | 835 | internal Boolean Moving 836 | { 837 | get 838 | { 839 | return axisControllers[(int)Axis.RA].Moving || axisControllers[(int)Axis.DEC].Moving; 840 | } 841 | } 842 | #endregion 843 | 844 | #region unimplementable 845 | public ArrayList SupportedActions 846 | { 847 | get 848 | { 849 | traceLogger.LogMessage("SupportedActions Get", "Returning empty arraylist"); 850 | return new ArrayList(); 851 | } 852 | } 853 | 854 | public string Action(string actionName, string actionParameters) 855 | { 856 | throw new ASCOM.ActionNotImplementedException("Action " + actionName + " is not implemented by this driver"); 857 | } 858 | 859 | public double Altitude 860 | { 861 | get 862 | { 863 | traceLogger.LogMessage("Altitude", "Not implemented"); 864 | throw new ASCOM.PropertyNotImplementedException("Altitude", false); 865 | } 866 | } 867 | 868 | public double ApertureArea 869 | { 870 | get 871 | { 872 | traceLogger.LogMessage("ApertureArea Get", "Not implemented"); 873 | throw new ASCOM.PropertyNotImplementedException("ApertureArea", false); 874 | } 875 | } 876 | 877 | public double ApertureDiameter 878 | { 879 | get 880 | { 881 | traceLogger.LogMessage("ApertureDiameter Get", "Not implemented"); 882 | throw new ASCOM.PropertyNotImplementedException("ApertureDiameter", false); 883 | } 884 | } 885 | 886 | public bool AtHome 887 | { 888 | get 889 | { 890 | //No feedback on position=> never at home 891 | traceLogger.LogMessage("AtHome", "Get - " + false.ToString()); 892 | return false; 893 | } 894 | } 895 | 896 | public bool AtPark 897 | { 898 | get 899 | { 900 | //No feedback on position=> never parked 901 | traceLogger.LogMessage("AtPark", "Get - " + false.ToString()); 902 | return false; 903 | } 904 | } 905 | 906 | public double Azimuth 907 | { 908 | get 909 | { 910 | traceLogger.LogMessage("Azimuth Get", "Not implemented"); 911 | throw new ASCOM.PropertyNotImplementedException("Azimuth", false); 912 | } 913 | } 914 | 915 | public double DeclinationRate 916 | { 917 | get 918 | { 919 | double declination = 0.0; 920 | traceLogger.LogMessage("DeclinationRate", "Get - " + declination.ToString()); 921 | return declination; 922 | } 923 | set 924 | { 925 | traceLogger.LogMessage("DeclinationRate Set", "Not implemented"); 926 | throw new ASCOM.PropertyNotImplementedException("DeclinationRate", true); 927 | } 928 | } 929 | 930 | public PierSide DestinationSideOfPier(double RightAscension, double Declination) 931 | { 932 | traceLogger.LogMessage("DestinationSideOfPier Get", "Not implemented"); 933 | throw new ASCOM.PropertyNotImplementedException("DestinationSideOfPier", false); 934 | } 935 | 936 | public bool DoesRefraction 937 | { 938 | get 939 | { 940 | traceLogger.LogMessage("DoesRefraction Get", "Not implemented"); 941 | throw new ASCOM.PropertyNotImplementedException("DoesRefraction", false); 942 | } 943 | set 944 | { 945 | traceLogger.LogMessage("DoesRefraction Set", "Not implemented"); 946 | throw new ASCOM.PropertyNotImplementedException("DoesRefraction", true); 947 | } 948 | } 949 | 950 | public void FindHome() 951 | { 952 | traceLogger.LogMessage("FindHome", "Not implemented"); 953 | throw new ASCOM.MethodNotImplementedException("FindHome"); 954 | } 955 | 956 | public double FocalLength 957 | { 958 | get 959 | { 960 | traceLogger.LogMessage("FocalLength Get", "Not implemented"); 961 | throw new ASCOM.PropertyNotImplementedException("FocalLength", false); 962 | } 963 | } 964 | 965 | 966 | public void Park() 967 | { 968 | traceLogger.LogMessage("Park", "Not implemented"); 969 | throw new ASCOM.MethodNotImplementedException("Park"); 970 | } 971 | 972 | public double RightAscensionRate 973 | { 974 | get 975 | { 976 | double rightAscensionRate = 0.0; 977 | traceLogger.LogMessage("RightAscensionRate", "Get - " + rightAscensionRate.ToString()); 978 | return rightAscensionRate; 979 | } 980 | set 981 | { 982 | traceLogger.LogMessage("RightAscensionRate Set", "Not implemented"); 983 | throw new ASCOM.PropertyNotImplementedException("RightAscensionRate", true); 984 | } 985 | } 986 | 987 | public void SetPark() 988 | { 989 | traceLogger.LogMessage("SetPark", "Not implemented"); 990 | throw new ASCOM.MethodNotImplementedException("SetPark"); 991 | } 992 | 993 | public PierSide SideOfPier 994 | { 995 | get 996 | { 997 | traceLogger.LogMessage("SideOfPier Get", "Not implemented"); 998 | throw new ASCOM.PropertyNotImplementedException("SideOfPier", false); 999 | } 1000 | set 1001 | { 1002 | traceLogger.LogMessage("SideOfPier Set", "Not implemented"); 1003 | throw new ASCOM.PropertyNotImplementedException("SideOfPier", true); 1004 | } 1005 | } 1006 | 1007 | public double SiteElevation 1008 | { 1009 | get 1010 | { 1011 | traceLogger.LogMessage("SiteElevation Get", "Not implemented"); 1012 | throw new ASCOM.PropertyNotImplementedException("SiteElevation", false); 1013 | } 1014 | set 1015 | { 1016 | traceLogger.LogMessage("SiteElevation Set", "Not implemented"); 1017 | throw new ASCOM.PropertyNotImplementedException("SiteElevation", true); 1018 | } 1019 | } 1020 | 1021 | public double SiteLatitude 1022 | { 1023 | get 1024 | { 1025 | traceLogger.LogMessage("SiteLatitude Get", "Not implemented"); 1026 | throw new ASCOM.PropertyNotImplementedException("SiteLatitude", false); 1027 | } 1028 | set 1029 | { 1030 | traceLogger.LogMessage("SiteLatitude Set", "Not implemented"); 1031 | throw new ASCOM.PropertyNotImplementedException("SiteLatitude", true); 1032 | } 1033 | } 1034 | 1035 | public double SiteLongitude 1036 | { 1037 | get 1038 | { 1039 | traceLogger.LogMessage("SiteLongitude Get", "Not implemented"); 1040 | throw new ASCOM.PropertyNotImplementedException("SiteLongitude", false); 1041 | } 1042 | set 1043 | { 1044 | traceLogger.LogMessage("SiteLongitude Set", "Not implemented"); 1045 | throw new ASCOM.PropertyNotImplementedException("SiteLongitude", true); 1046 | } 1047 | } 1048 | 1049 | public short SlewSettleTime 1050 | { 1051 | get 1052 | { 1053 | traceLogger.LogMessage("SlewSettleTime Get", "Not implemented"); 1054 | throw new ASCOM.PropertyNotImplementedException("SlewSettleTime", false); 1055 | } 1056 | set 1057 | { 1058 | traceLogger.LogMessage("SlewSettleTime Set", "Not implemented"); 1059 | throw new ASCOM.PropertyNotImplementedException("SlewSettleTime", true); 1060 | } 1061 | } 1062 | 1063 | public void SlewToAltAz(double Azimuth, double Altitude) 1064 | { 1065 | traceLogger.LogMessage("SlewToAltAz", "Not implemented"); 1066 | throw new ASCOM.MethodNotImplementedException("SlewToAltAz"); 1067 | } 1068 | 1069 | public void SlewToAltAzAsync(double Azimuth, double Altitude) 1070 | { 1071 | traceLogger.LogMessage("SlewToAltAzAsync", "Not implemented"); 1072 | throw new ASCOM.MethodNotImplementedException("SlewToAltAzAsync"); 1073 | } 1074 | 1075 | public void SyncToAltAz(double Azimuth, double Altitude) 1076 | { 1077 | traceLogger.LogMessage("SyncToAltAz", "Not implemented"); 1078 | throw new ASCOM.MethodNotImplementedException("SyncToAltAz"); 1079 | } 1080 | 1081 | public void Unpark() 1082 | { 1083 | traceLogger.LogMessage("Unpark", "Not implemented"); 1084 | throw new ASCOM.MethodNotImplementedException("Unpark"); 1085 | } 1086 | #endregion 1087 | 1088 | protected virtual void Dispose(bool disposing) 1089 | { 1090 | this.Connected = false; 1091 | foreach (AxisController axisController in this.axisControllers) 1092 | { 1093 | axisController.Dispose(); 1094 | } 1095 | this.deviceController.Dispose(); 1096 | // Clean up the tracelogger and util objects 1097 | this.traceLogger.Enabled = false; 1098 | this.traceLogger.Dispose(); 1099 | this.traceLogger = null; 1100 | this.utilities.Dispose(); 1101 | this.utilities = null; 1102 | } 1103 | 1104 | public void Dispose() 1105 | { 1106 | Dispose(true); 1107 | GC.SuppressFinalize(this); 1108 | } 1109 | } 1110 | } 1111 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Orientation.cs: -------------------------------------------------------------------------------- 1 | // This file is part of Arduino ST4. 2 | // 3 | // Arduino ST4 is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU Lesser General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // Arduino ST4 is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License 14 | // along with Arduino ST4. If not, see . 15 | 16 | namespace ASCOM.ArduinoST4 17 | { 18 | /// 19 | /// Orientation of the movement along an axis. Can be forward (PLUS) or backward (MINUS) 20 | /// 21 | enum Orientation 22 | { 23 | PLUS, MINUS 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | // 9 | // TODO - Add your authorship information here 10 | [assembly: AssemblyTitle("ASCOM.ArduinoST4.Telescope")] 11 | [assembly: AssemblyDescription("ASCOM Telescope driver for ArduinoST4")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("The ASCOM Initiative")] 14 | [assembly: AssemblyProduct("ASCOM Telescope driver for ArduinoST4")] 15 | [assembly: AssemblyCopyright("Copyright © 2014 The ASCOM Initiative")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(true)] 23 | 24 | // The following GUID is for the ID of the typelib if this project is exposed to COM 25 | [assembly: Guid("275d986f-45db-4fb0-8289-ff95c4d63c63")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Revision and Build Numbers 35 | // by using the '*' as shown below: 36 | // 37 | [assembly: AssemblyVersion("6.0.*")] 38 | [assembly: AssemblyFileVersion("6.0.0.0")] 39 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18052 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ASCOM.ArduinoST4.Properties 12 | { 13 | using System; 14 | 15 | 16 | /// 17 | /// A strongly-typed resource class, for looking up localized strings, etc. 18 | /// 19 | // This class was auto-generated by the StronglyTypedResourceBuilder 20 | // class via a tool like ResGen or Visual Studio. 21 | // To add or remove a member, edit your .ResX file then rerun ResGen 22 | // with the /str option, or rebuild your VS project. 23 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 24 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 25 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 26 | internal class Resources 27 | { 28 | 29 | private static global::System.Resources.ResourceManager resourceMan; 30 | 31 | private static global::System.Globalization.CultureInfo resourceCulture; 32 | 33 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 34 | internal Resources() 35 | { 36 | } 37 | 38 | /// 39 | /// Returns the cached ResourceManager instance used by this class. 40 | /// 41 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 42 | internal static global::System.Resources.ResourceManager ResourceManager 43 | { 44 | get 45 | { 46 | if (object.ReferenceEquals(resourceMan, null)) 47 | { 48 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASCOM.ArduinoST4.Properties.Resources", typeof(Resources).Assembly); 49 | resourceMan = temp; 50 | } 51 | return resourceMan; 52 | } 53 | } 54 | 55 | /// 56 | /// Overrides the current thread's CurrentUICulture property for all 57 | /// resource lookups using this strongly typed resource class. 58 | /// 59 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 60 | internal static global::System.Globalization.CultureInfo Culture 61 | { 62 | get 63 | { 64 | return resourceCulture; 65 | } 66 | set 67 | { 68 | resourceCulture = value; 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized resource of type System.Drawing.Bitmap. 74 | /// 75 | internal static System.Drawing.Bitmap ASCOM 76 | { 77 | get 78 | { 79 | object obj = ResourceManager.GetObject("ASCOM", resourceCulture); 80 | return ((System.Drawing.Bitmap)(obj)); 81 | } 82 | } 83 | 84 | /// 85 | /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). 86 | /// 87 | internal static System.Drawing.Icon DefaultIcon 88 | { 89 | get 90 | { 91 | object obj = ResourceManager.GetObject("DefaultIcon", resourceCulture); 92 | return ((System.Drawing.Icon)(obj)); 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\ASCOM.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\ASCOM.ico;System.Drawing.Icon, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18052 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ASCOM.ArduinoST4.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Rates.cs: -------------------------------------------------------------------------------- 1 | // This file is part of Arduino ST4. 2 | // 3 | // Arduino ST4 is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU Lesser General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // Arduino ST4 is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License 14 | // along with Arduino ST4. If not, see . 15 | 16 | using ASCOM.DeviceInterface; 17 | using System; 18 | using System.Collections; 19 | using System.Runtime.InteropServices; 20 | 21 | namespace ASCOM.ArduinoST4 22 | { 23 | #region Rate class 24 | // 25 | // The Rate class implements IRate, and is used to hold values 26 | // for AxisRates. You do not need to change this class. 27 | // 28 | // The Guid attribute sets the CLSID for ASCOM.ArduinoST4.Rate 29 | // The ClassInterface/None addribute prevents an empty interface called 30 | // _Rate from being created and used as the [default] interface 31 | // 32 | [Guid("a60ffd60-3725-4457-812e-49ace8613a81")] 33 | [ClassInterface(ClassInterfaceType.None)] 34 | [ComVisible(true)] 35 | public class Rate : ASCOM.DeviceInterface.IRate 36 | { 37 | private double maximum = 0; 38 | private double minimum = 0; 39 | 40 | internal Rate(double minimum, double maximum) 41 | { 42 | this.maximum = maximum; 43 | this.minimum = minimum; 44 | } 45 | 46 | #region Implementation of IRate 47 | 48 | public void Dispose() 49 | { 50 | throw new System.NotImplementedException(); 51 | } 52 | 53 | public double Maximum 54 | { 55 | get { return this.maximum; } 56 | set { this.maximum = value; } 57 | } 58 | 59 | public double Minimum 60 | { 61 | get { return this.minimum; } 62 | set { this.minimum = value; } 63 | } 64 | 65 | #endregion 66 | } 67 | #endregion 68 | 69 | #region AxisRates 70 | // 71 | // AxisRates is a strongly-typed collection that must be enumerable by 72 | // both COM and .NET. The IAxisRates and IEnumerable interfaces provide 73 | // this polymorphism. 74 | // 75 | // The Guid attribute sets the CLSID for ASCOM.ArduinoST4.AxisRates 76 | // The ClassInterface/None addribute prevents an empty interface called 77 | // _AxisRates from being created and used as the [default] interface 78 | // 79 | [Guid("1f302d16-dd2d-49a4-af1a-992cf9599bc4")] 80 | [ClassInterface(ClassInterfaceType.None)] 81 | [ComVisible(true)] 82 | public class AxisRates : IAxisRates, IEnumerable 83 | { 84 | private readonly Rate[] rates; 85 | 86 | // 87 | // Constructor - Internal prevents public creation 88 | // of instances. Returned by Telescope.AxisRates. 89 | // 90 | internal AxisRates(TelescopeAxes axis) 91 | { 92 | switch (axis) 93 | { 94 | case TelescopeAxes.axisPrimary: 95 | this.rates = new Rate[] { new Rate(0, Constants.DEGREES_PER_SECOND * 8) };//8X Sideral Rate 96 | break; 97 | case TelescopeAxes.axisSecondary: 98 | this.rates = new Rate[] { new Rate(0, Constants.DEGREES_PER_SECOND * 8) };//8X Sideral Rate 99 | break; 100 | case TelescopeAxes.axisTertiary: 101 | this.rates = new Rate[] { new Rate(0, Constants.DEGREES_PER_SECOND * 8) };//8X Sideral Rate 102 | break; 103 | } 104 | } 105 | 106 | #region IAxisRates Members 107 | 108 | public int Count 109 | { 110 | get { return this.rates.Length; } 111 | } 112 | 113 | public void Dispose() 114 | { 115 | throw new System.NotImplementedException(); 116 | } 117 | 118 | public IEnumerator GetEnumerator() 119 | { 120 | return rates.GetEnumerator(); 121 | } 122 | 123 | public IRate this[int index] 124 | { 125 | get { return this.rates[index - 1]; } // 1-based 126 | } 127 | 128 | #endregion 129 | } 130 | #endregion 131 | 132 | #region TrackingRates 133 | // 134 | // TrackingRates is a strongly-typed collection that must be enumerable by 135 | // both COM and .NET. The ITrackingRates and IEnumerable interfaces provide 136 | // this polymorphism. 137 | // 138 | // The Guid attribute sets the CLSID for ASCOM.ArduinoST4.TrackingRates 139 | // The ClassInterface/None addribute prevents an empty interface called 140 | // _TrackingRates from being created and used as the [default] interface 141 | // 142 | [Guid("a544289a-d48d-44fc-8492-d911fcd6d3ef")] 143 | [ClassInterface(ClassInterfaceType.None)] 144 | [ComVisible(true)] 145 | public class TrackingRates : ITrackingRates, IEnumerable, IEnumerator 146 | { 147 | private readonly DriveRates[] trackingRates; 148 | private static int pos = -1; 149 | 150 | // 151 | // Default constructor - Internal prevents public creation 152 | // of instances. Returned by Telescope.AxisRates. 153 | // 154 | internal TrackingRates() 155 | { 156 | // 157 | // This array must hold ONE or more DriveRates values, indicating 158 | // the tracking rates supported by your telescope. The one value 159 | // (tracking rate) that MUST be supported is driveSidereal! 160 | // 161 | this.trackingRates = new[] { DriveRates.driveSidereal }; 162 | // TODO Initialize this array with any additional tracking rates that your driver may provide 163 | } 164 | 165 | #region ITrackingRates Members 166 | 167 | public int Count 168 | { 169 | get { return this.trackingRates.Length; } 170 | } 171 | 172 | public IEnumerator GetEnumerator() 173 | { 174 | pos = -1; 175 | return this as IEnumerator; 176 | } 177 | 178 | public void Dispose() 179 | { 180 | throw new System.NotImplementedException(); 181 | } 182 | 183 | public DriveRates this[int index] 184 | { 185 | get { return this.trackingRates[index - 1]; } // 1-based 186 | } 187 | 188 | #endregion 189 | 190 | #region IEnumerable members 191 | 192 | public object Current 193 | { 194 | get 195 | { 196 | if (pos < 0 || pos >= trackingRates.Length) 197 | { 198 | throw new System.InvalidOperationException(); 199 | } 200 | return trackingRates[pos]; 201 | } 202 | } 203 | 204 | public bool MoveNext() 205 | { 206 | if (++pos >= trackingRates.Length) 207 | { 208 | return false; 209 | } 210 | return true; 211 | } 212 | 213 | public void Reset() 214 | { 215 | pos = -1; 216 | } 217 | #endregion 218 | } 219 | #endregion 220 | } 221 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Resources/ASCOM.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/Resources/ASCOM.bmp -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/SetupDialogForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | using System.Windows.Forms; 4 | 5 | namespace ASCOM.ArduinoST4 6 | { 7 | [ComVisible(false)] // Form not registered for COM! 8 | public partial class SetupDialogForm : Form 9 | { 10 | public SetupDialogForm() 11 | { 12 | InitializeComponent(); 13 | populateSerialComboBox(); 14 | // Initialise current values of user settings from the ASCOM Profile 15 | this.comPortComboBox.Text = Telescope.comPort; 16 | this.traceStateCheckBox.Checked = Telescope.traceState; 17 | this.rightAscensionPlusSideralRateTextBox.Text = Telescope.rightAscensionSideralRatePlus.ToString(); 18 | this.rightAscensionMinusSideralRateTextBox.Text = Telescope.rightAscensionSideralRateMinus.ToString(); 19 | this.declinationPlusSideralRateTextBox.Text = Telescope.declinationSideralRatePlus.ToString(); 20 | this.declinationMinusSideralRateTextBox.Text = Telescope.declinationSideralRateMinus.ToString(); 21 | } 22 | 23 | /// 24 | /// Reads the available COM ports on the computer and adds them to the COM Port combobox 25 | /// 26 | private void populateSerialComboBox() 27 | { 28 | string[] serialPorts = System.IO.Ports.SerialPort.GetPortNames(); 29 | foreach (string serialPort in serialPorts) 30 | { 31 | this.comPortComboBox.Items.Add(serialPort); 32 | } 33 | } 34 | 35 | private void cmdOK_Click(object sender, EventArgs e) // OK button event handler 36 | { 37 | // Update the state variables with results from the dialogue 38 | Telescope.comPort = comPortComboBox.Text; 39 | Telescope.traceState = traceStateCheckBox.Checked; 40 | Telescope.rightAscensionSideralRatePlus = Convert.ToDouble(this.rightAscensionPlusSideralRateTextBox.Text); 41 | Telescope.rightAscensionSideralRateMinus = Convert.ToDouble(this.rightAscensionMinusSideralRateTextBox.Text); 42 | Telescope.declinationSideralRatePlus = Convert.ToDouble(this.declinationPlusSideralRateTextBox.Text); 43 | Telescope.declinationSideralRateMinus = Convert.ToDouble(this.declinationMinusSideralRateTextBox.Text); 44 | } 45 | 46 | private void cmdCancel_Click(object sender, EventArgs e) // Cancel button event handler 47 | { 48 | Close(); 49 | } 50 | 51 | private void BrowseToAscom(object sender, EventArgs e) // Click on ASCOM logo event handler 52 | { 53 | try 54 | { 55 | System.Diagnostics.Process.Start("http://ascom-standards.org/"); 56 | } 57 | catch (System.ComponentModel.Win32Exception noBrowser) 58 | { 59 | if (noBrowser.ErrorCode == -2147467259) 60 | MessageBox.Show(noBrowser.Message); 61 | } 62 | catch (System.Exception other) 63 | { 64 | MessageBox.Show(other.Message); 65 | } 66 | } 67 | 68 | private void SetupDialogForm_Load(object sender, EventArgs e) 69 | { 70 | 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/SetupDialogForm.designer.cs: -------------------------------------------------------------------------------- 1 | namespace ASCOM.ArduinoST4 2 | { 3 | partial class SetupDialogForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.cmdOK = new System.Windows.Forms.Button(); 32 | this.cmdCancel = new System.Windows.Forms.Button(); 33 | this.commentLabel = new System.Windows.Forms.Label(); 34 | this.picASCOM = new System.Windows.Forms.PictureBox(); 35 | this.comPortComboBox = new System.Windows.Forms.ComboBox(); 36 | this.comPortLabel = new System.Windows.Forms.Label(); 37 | this.traceStateCheckBox = new System.Windows.Forms.CheckBox(); 38 | this.rightAscensionPlusSideralRateLabel = new System.Windows.Forms.Label(); 39 | this.rightAscensionMinusSideralRateLabel = new System.Windows.Forms.Label(); 40 | this.declinationPlusSideralRateLabel = new System.Windows.Forms.Label(); 41 | this.declinationMinusSideralRateLabel = new System.Windows.Forms.Label(); 42 | this.rightAscensionPlusSideralRateTextBox = new System.Windows.Forms.TextBox(); 43 | this.rightAscensionMinusSideralRateTextBox = new System.Windows.Forms.TextBox(); 44 | this.declinationPlusSideralRateTextBox = new System.Windows.Forms.TextBox(); 45 | this.declinationMinusSideralRateTextBox = new System.Windows.Forms.TextBox(); 46 | this.axisSideralRatesGroupBox = new System.Windows.Forms.GroupBox(); 47 | this.axisSideralRatesPanel = new System.Windows.Forms.Panel(); 48 | this.connectionGroupBox = new System.Windows.Forms.GroupBox(); 49 | ((System.ComponentModel.ISupportInitialize)(this.picASCOM)).BeginInit(); 50 | this.axisSideralRatesGroupBox.SuspendLayout(); 51 | this.axisSideralRatesPanel.SuspendLayout(); 52 | this.connectionGroupBox.SuspendLayout(); 53 | this.SuspendLayout(); 54 | // 55 | // cmdOK 56 | // 57 | this.cmdOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 58 | this.cmdOK.DialogResult = System.Windows.Forms.DialogResult.OK; 59 | this.cmdOK.Location = new System.Drawing.Point(281, 164); 60 | this.cmdOK.Name = "cmdOK"; 61 | this.cmdOK.Size = new System.Drawing.Size(59, 24); 62 | this.cmdOK.TabIndex = 0; 63 | this.cmdOK.Text = "OK"; 64 | this.cmdOK.UseVisualStyleBackColor = true; 65 | this.cmdOK.Click += new System.EventHandler(this.cmdOK_Click); 66 | // 67 | // cmdCancel 68 | // 69 | this.cmdCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); 70 | this.cmdCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; 71 | this.cmdCancel.Location = new System.Drawing.Point(281, 194); 72 | this.cmdCancel.Name = "cmdCancel"; 73 | this.cmdCancel.Size = new System.Drawing.Size(59, 25); 74 | this.cmdCancel.TabIndex = 1; 75 | this.cmdCancel.Text = "Cancel"; 76 | this.cmdCancel.UseVisualStyleBackColor = true; 77 | this.cmdCancel.Click += new System.EventHandler(this.cmdCancel_Click); 78 | // 79 | // commentLabel 80 | // 81 | this.commentLabel.Location = new System.Drawing.Point(12, 9); 82 | this.commentLabel.Name = "commentLabel"; 83 | this.commentLabel.Size = new System.Drawing.Size(86, 17); 84 | this.commentLabel.TabIndex = 2; 85 | this.commentLabel.Text = "Driver setup"; 86 | // 87 | // picASCOM 88 | // 89 | this.picASCOM.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); 90 | this.picASCOM.Cursor = System.Windows.Forms.Cursors.Hand; 91 | this.picASCOM.Image = global::ASCOM.ArduinoST4.Properties.Resources.ASCOM; 92 | this.picASCOM.Location = new System.Drawing.Point(292, 9); 93 | this.picASCOM.Name = "picASCOM"; 94 | this.picASCOM.Size = new System.Drawing.Size(48, 56); 95 | this.picASCOM.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; 96 | this.picASCOM.TabIndex = 3; 97 | this.picASCOM.TabStop = false; 98 | this.picASCOM.Click += new System.EventHandler(this.BrowseToAscom); 99 | this.picASCOM.DoubleClick += new System.EventHandler(this.BrowseToAscom); 100 | // 101 | // comPortTextBox 102 | // 103 | this.comPortComboBox.Location = new System.Drawing.Point(109, 10); 104 | this.comPortComboBox.Name = "comPortComboBox"; 105 | this.comPortComboBox.Size = new System.Drawing.Size(82, 20); 106 | this.comPortComboBox.TabIndex = 4; 107 | // 108 | // comPortLabel 109 | // 110 | this.comPortLabel.AutoSize = true; 111 | this.comPortLabel.Location = new System.Drawing.Point(12, 16); 112 | this.comPortLabel.Name = "comPortLabel"; 113 | this.comPortLabel.Size = new System.Drawing.Size(50, 13); 114 | this.comPortLabel.TabIndex = 5; 115 | this.comPortLabel.Text = "Com Port"; 116 | // 117 | // traceStateCheckBox 118 | // 119 | this.traceStateCheckBox.AutoSize = true; 120 | this.traceStateCheckBox.Location = new System.Drawing.Point(12, 202); 121 | this.traceStateCheckBox.Name = "traceStateCheckBox"; 122 | this.traceStateCheckBox.Size = new System.Drawing.Size(79, 17); 123 | this.traceStateCheckBox.TabIndex = 6; 124 | this.traceStateCheckBox.Text = "Debug Log"; 125 | this.traceStateCheckBox.UseVisualStyleBackColor = true; 126 | // 127 | // rightAscensionPlusSideralRateLabel 128 | // 129 | this.rightAscensionPlusSideralRateLabel.AutoSize = true; 130 | this.rightAscensionPlusSideralRateLabel.Location = new System.Drawing.Point(6, 10); 131 | this.rightAscensionPlusSideralRateLabel.Name = "rightAscensionPlusSideralRateLabel"; 132 | this.rightAscensionPlusSideralRateLabel.Size = new System.Drawing.Size(89, 13); 133 | this.rightAscensionPlusSideralRateLabel.TabIndex = 7; 134 | this.rightAscensionPlusSideralRateLabel.Text = "RA+ Sideral Rate"; 135 | // 136 | // rightAscensionMinusSideralRateLabel 137 | // 138 | this.rightAscensionMinusSideralRateLabel.AutoSize = true; 139 | this.rightAscensionMinusSideralRateLabel.Location = new System.Drawing.Point(6, 35); 140 | this.rightAscensionMinusSideralRateLabel.Name = "rightAscensionMinusSideralRateLabel"; 141 | this.rightAscensionMinusSideralRateLabel.Size = new System.Drawing.Size(86, 13); 142 | this.rightAscensionMinusSideralRateLabel.TabIndex = 8; 143 | this.rightAscensionMinusSideralRateLabel.Text = "RA- Sideral Rate"; 144 | // 145 | // declinationPlusSideralRateLabel 146 | // 147 | this.declinationPlusSideralRateLabel.AutoSize = true; 148 | this.declinationPlusSideralRateLabel.Location = new System.Drawing.Point(6, 60); 149 | this.declinationPlusSideralRateLabel.Name = "declinationPlusSideralRateLabel"; 150 | this.declinationPlusSideralRateLabel.Size = new System.Drawing.Size(96, 13); 151 | this.declinationPlusSideralRateLabel.TabIndex = 9; 152 | this.declinationPlusSideralRateLabel.Text = "DEC+ Sideral Rate"; 153 | // 154 | // declinationMinusSideralRateLabel 155 | // 156 | this.declinationMinusSideralRateLabel.AutoSize = true; 157 | this.declinationMinusSideralRateLabel.Location = new System.Drawing.Point(6, 85); 158 | this.declinationMinusSideralRateLabel.Name = "declinationMinusSideralRateLabel"; 159 | this.declinationMinusSideralRateLabel.Size = new System.Drawing.Size(93, 13); 160 | this.declinationMinusSideralRateLabel.TabIndex = 10; 161 | this.declinationMinusSideralRateLabel.Text = "DEC- Sideral Rate"; 162 | // 163 | // rightAscensionPlusSideralRateTextBox 164 | // 165 | this.rightAscensionPlusSideralRateTextBox.Location = new System.Drawing.Point(103, 5); 166 | this.rightAscensionPlusSideralRateTextBox.Name = "rightAscensionPlusSideralRateTextBox"; 167 | this.rightAscensionPlusSideralRateTextBox.Size = new System.Drawing.Size(82, 20); 168 | this.rightAscensionPlusSideralRateTextBox.TabIndex = 11; 169 | // 170 | // rightAscensionMinusSideralRateTextBox 171 | // 172 | this.rightAscensionMinusSideralRateTextBox.Location = new System.Drawing.Point(103, 30); 173 | this.rightAscensionMinusSideralRateTextBox.Name = "rightAscensionMinusSideralRateTextBox"; 174 | this.rightAscensionMinusSideralRateTextBox.Size = new System.Drawing.Size(82, 20); 175 | this.rightAscensionMinusSideralRateTextBox.TabIndex = 12; 176 | // 177 | // declinationPlusSideralRateTextBox 178 | // 179 | this.declinationPlusSideralRateTextBox.Location = new System.Drawing.Point(103, 55); 180 | this.declinationPlusSideralRateTextBox.Name = "declinationPlusSideralRateTextBox"; 181 | this.declinationPlusSideralRateTextBox.Size = new System.Drawing.Size(82, 20); 182 | this.declinationPlusSideralRateTextBox.TabIndex = 13; 183 | // 184 | // declinationMinusSideralRateTextBox 185 | // 186 | this.declinationMinusSideralRateTextBox.Location = new System.Drawing.Point(103, 80); 187 | this.declinationMinusSideralRateTextBox.Name = "declinationMinusSideralRateTextBox"; 188 | this.declinationMinusSideralRateTextBox.Size = new System.Drawing.Size(82, 20); 189 | this.declinationMinusSideralRateTextBox.TabIndex = 14; 190 | // 191 | // axisSideralRatesGroupBox 192 | // 193 | this.axisSideralRatesGroupBox.Controls.Add(this.axisSideralRatesPanel); 194 | this.axisSideralRatesGroupBox.Location = new System.Drawing.Point(12, 71); 195 | this.axisSideralRatesGroupBox.Name = "axisSideralRatesGroupBox"; 196 | this.axisSideralRatesGroupBox.Size = new System.Drawing.Size(203, 123); 197 | this.axisSideralRatesGroupBox.TabIndex = 15; 198 | this.axisSideralRatesGroupBox.TabStop = false; 199 | this.axisSideralRatesGroupBox.Text = "Axis Sideral Rates"; 200 | // 201 | // axisSideralRatesPanel 202 | // 203 | this.axisSideralRatesPanel.Controls.Add(this.rightAscensionPlusSideralRateLabel); 204 | this.axisSideralRatesPanel.Controls.Add(this.declinationMinusSideralRateTextBox); 205 | this.axisSideralRatesPanel.Controls.Add(this.rightAscensionPlusSideralRateTextBox); 206 | this.axisSideralRatesPanel.Controls.Add(this.declinationMinusSideralRateLabel); 207 | this.axisSideralRatesPanel.Controls.Add(this.declinationPlusSideralRateTextBox); 208 | this.axisSideralRatesPanel.Controls.Add(this.rightAscensionMinusSideralRateLabel); 209 | this.axisSideralRatesPanel.Controls.Add(this.rightAscensionMinusSideralRateTextBox); 210 | this.axisSideralRatesPanel.Controls.Add(this.declinationPlusSideralRateLabel); 211 | this.axisSideralRatesPanel.Location = new System.Drawing.Point(6, 13); 212 | this.axisSideralRatesPanel.Name = "axisSideralRatesPanel"; 213 | this.axisSideralRatesPanel.Size = new System.Drawing.Size(188, 105); 214 | this.axisSideralRatesPanel.TabIndex = 16; 215 | // 216 | // connectionGroupBox 217 | // 218 | this.connectionGroupBox.Controls.Add(this.comPortLabel); 219 | this.connectionGroupBox.Controls.Add(this.comPortComboBox); 220 | this.connectionGroupBox.Location = new System.Drawing.Point(15, 29); 221 | this.connectionGroupBox.Name = "connectionGroupBox"; 222 | this.connectionGroupBox.Size = new System.Drawing.Size(200, 36); 223 | this.connectionGroupBox.TabIndex = 16; 224 | this.connectionGroupBox.TabStop = false; 225 | this.connectionGroupBox.Text = "Connection"; 226 | // 227 | // SetupDialogForm 228 | // 229 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 230 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 231 | this.ClientSize = new System.Drawing.Size(350, 227); 232 | this.Controls.Add(this.connectionGroupBox); 233 | this.Controls.Add(this.axisSideralRatesGroupBox); 234 | this.Controls.Add(this.traceStateCheckBox); 235 | this.Controls.Add(this.picASCOM); 236 | this.Controls.Add(this.commentLabel); 237 | this.Controls.Add(this.cmdCancel); 238 | this.Controls.Add(this.cmdOK); 239 | this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; 240 | this.MaximizeBox = false; 241 | this.MinimizeBox = false; 242 | this.Name = "SetupDialogForm"; 243 | this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; 244 | this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; 245 | this.Text = "ArduinoST4 Setup"; 246 | this.Load += new System.EventHandler(this.SetupDialogForm_Load); 247 | ((System.ComponentModel.ISupportInitialize)(this.picASCOM)).EndInit(); 248 | this.axisSideralRatesGroupBox.ResumeLayout(false); 249 | this.axisSideralRatesPanel.ResumeLayout(false); 250 | this.axisSideralRatesPanel.PerformLayout(); 251 | this.connectionGroupBox.ResumeLayout(false); 252 | this.connectionGroupBox.PerformLayout(); 253 | this.ResumeLayout(false); 254 | this.PerformLayout(); 255 | 256 | } 257 | 258 | #endregion 259 | 260 | private System.Windows.Forms.Button cmdOK; 261 | private System.Windows.Forms.Button cmdCancel; 262 | private System.Windows.Forms.Label commentLabel; 263 | private System.Windows.Forms.PictureBox picASCOM; 264 | private System.Windows.Forms.ComboBox comPortComboBox; 265 | private System.Windows.Forms.Label comPortLabel; 266 | private System.Windows.Forms.CheckBox traceStateCheckBox; 267 | private System.Windows.Forms.Label rightAscensionPlusSideralRateLabel; 268 | private System.Windows.Forms.Label rightAscensionMinusSideralRateLabel; 269 | private System.Windows.Forms.Label declinationPlusSideralRateLabel; 270 | private System.Windows.Forms.Label declinationMinusSideralRateLabel; 271 | private System.Windows.Forms.TextBox rightAscensionPlusSideralRateTextBox; 272 | private System.Windows.Forms.TextBox rightAscensionMinusSideralRateTextBox; 273 | private System.Windows.Forms.TextBox declinationPlusSideralRateTextBox; 274 | private System.Windows.Forms.TextBox declinationMinusSideralRateTextBox; 275 | private System.Windows.Forms.GroupBox axisSideralRatesGroupBox; 276 | private System.Windows.Forms.Panel axisSideralRatesPanel; 277 | private System.Windows.Forms.GroupBox connectionGroupBox; 278 | } 279 | } -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/SetupDialogForm.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4Driver/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | obj -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/ArduinoST4TestForms.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {8E8D406C-1838-4914-867D-AB602D0EAF3E} 9 | WinExe 10 | Properties 11 | ASCOM.ArduinoST4 12 | ASCOM.ArduinoST4.Test 13 | v4.0 14 | 512 15 | 16 | 17 | 18 | x86 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | x86 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Form 52 | 53 | 54 | Form1.cs 55 | 56 | 57 | 58 | 59 | Form1.cs 60 | 61 | 62 | ResXFileCodeGenerator 63 | Resources.Designer.cs 64 | Designer 65 | 66 | 67 | True 68 | Resources.resx 69 | True 70 | 71 | 72 | 73 | SettingsSingleFileGenerator 74 | Settings.Designer.cs 75 | 76 | 77 | True 78 | Settings.settings 79 | True 80 | 81 | 82 | 83 | 90 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace ASCOM.ArduinoST4 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.buttonChoose = new System.Windows.Forms.Button(); 32 | this.buttonConnect = new System.Windows.Forms.Button(); 33 | this.labelDriverId = new System.Windows.Forms.Label(); 34 | this.SuspendLayout(); 35 | // 36 | // buttonChoose 37 | // 38 | this.buttonChoose.Location = new System.Drawing.Point(309, 10); 39 | this.buttonChoose.Name = "buttonChoose"; 40 | this.buttonChoose.Size = new System.Drawing.Size(72, 23); 41 | this.buttonChoose.TabIndex = 0; 42 | this.buttonChoose.Text = "Choose"; 43 | this.buttonChoose.UseVisualStyleBackColor = true; 44 | this.buttonChoose.Click += new System.EventHandler(this.buttonChoose_Click); 45 | // 46 | // buttonConnect 47 | // 48 | this.buttonConnect.Location = new System.Drawing.Point(309, 39); 49 | this.buttonConnect.Name = "buttonConnect"; 50 | this.buttonConnect.Size = new System.Drawing.Size(72, 23); 51 | this.buttonConnect.TabIndex = 1; 52 | this.buttonConnect.Text = "Connect"; 53 | this.buttonConnect.UseVisualStyleBackColor = true; 54 | this.buttonConnect.Click += new System.EventHandler(this.buttonConnect_Click); 55 | // 56 | // labelDriverId 57 | // 58 | this.labelDriverId.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; 59 | this.labelDriverId.DataBindings.Add(new System.Windows.Forms.Binding("Text", global::ASCOM.ArduinoST4.Properties.Settings.Default, "DriverId", true, System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged)); 60 | this.labelDriverId.Location = new System.Drawing.Point(12, 40); 61 | this.labelDriverId.Name = "labelDriverId"; 62 | this.labelDriverId.Size = new System.Drawing.Size(291, 21); 63 | this.labelDriverId.TabIndex = 2; 64 | this.labelDriverId.Text = global::ASCOM.ArduinoST4.Properties.Settings.Default.DriverId; 65 | this.labelDriverId.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; 66 | // 67 | // Form1 68 | // 69 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 70 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 71 | this.ClientSize = new System.Drawing.Size(409, 262); 72 | this.Controls.Add(this.labelDriverId); 73 | this.Controls.Add(this.buttonConnect); 74 | this.Controls.Add(this.buttonChoose); 75 | this.Name = "Form1"; 76 | this.Text = "TEMPLATEDEVICETYPE Test"; 77 | this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing); 78 | this.ResumeLayout(false); 79 | 80 | } 81 | 82 | #endregion 83 | 84 | private System.Windows.Forms.Button buttonChoose; 85 | private System.Windows.Forms.Button buttonConnect; 86 | private System.Windows.Forms.Label labelDriverId; 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | 4 | namespace ASCOM.ArduinoST4 5 | { 6 | public partial class Form1 : Form 7 | { 8 | 9 | private ASCOM.DriverAccess.Telescope driver; 10 | 11 | public Form1() 12 | { 13 | InitializeComponent(); 14 | SetUIState(); 15 | } 16 | 17 | private void Form1_FormClosing(object sender, FormClosingEventArgs e) 18 | { 19 | if (IsConnected) 20 | driver.Connected = false; 21 | 22 | Properties.Settings.Default.Save(); 23 | } 24 | 25 | private void buttonChoose_Click(object sender, EventArgs e) 26 | { 27 | Properties.Settings.Default.DriverId = ASCOM.DriverAccess.Telescope.Choose(Properties.Settings.Default.DriverId); 28 | SetUIState(); 29 | } 30 | 31 | private void buttonConnect_Click(object sender, EventArgs e) 32 | { 33 | if (IsConnected) 34 | { 35 | driver.Connected = false; 36 | } 37 | else 38 | { 39 | driver = new ASCOM.DriverAccess.Telescope(Properties.Settings.Default.DriverId); 40 | driver.Connected = true; 41 | } 42 | SetUIState(); 43 | } 44 | 45 | private void SetUIState() 46 | { 47 | buttonConnect.Enabled = !string.IsNullOrEmpty(Properties.Settings.Default.DriverId); 48 | buttonChoose.Enabled = !IsConnected; 49 | buttonConnect.Text = IsConnected ? "Disconnect" : "Connect"; 50 | } 51 | 52 | private bool IsConnected 53 | { 54 | get 55 | { 56 | return ((this.driver != null) && (driver.Connected == true)); 57 | } 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/Form1.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | 6 | namespace ASCOM.ArduinoST4 7 | { 8 | static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | Application.EnableVisualStyles(); 17 | Application.SetCompatibleTextRenderingDefault(false); 18 | Application.Run(new Form1()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("ASCOM Driver Test Forms Application")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("ASCOM Initiative")] 12 | [assembly: AssemblyProduct("Driver Test Forms Application Template CSharp")] 13 | [assembly: AssemblyCopyright("Copyright © ASCOM Initiative 2014")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("e6c7b090-1f16-486f-bdba-d45785e9f6f1")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("6.0.0.0")] 36 | [assembly: AssemblyFileVersion("6.0.0.0")] 37 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ASCOM.ArduinoST4.Properties 12 | { 13 | using System; 14 | 15 | 16 | /// 17 | /// A strongly-typed resource class, for looking up localized strings, etc. 18 | /// 19 | // This class was auto-generated by the StronglyTypedResourceBuilder 20 | // class via a tool like ResGen or Visual Studio. 21 | // To add or remove a member, edit your .ResX file then rerun ResGen 22 | // with the /str option, or rebuild your VS project. 23 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 24 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 25 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 26 | internal class Resources 27 | { 28 | 29 | private static global::System.Resources.ResourceManager resourceMan; 30 | 31 | private static global::System.Globalization.CultureInfo resourceCulture; 32 | 33 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 34 | internal Resources() 35 | { 36 | } 37 | 38 | /// 39 | /// Returns the cached ResourceManager instance used by this class. 40 | /// 41 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 42 | internal static global::System.Resources.ResourceManager ResourceManager 43 | { 44 | get 45 | { 46 | if (object.ReferenceEquals(resourceMan, null)) 47 | { 48 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ASCOM.ArduinoST4.Properties.Resources", typeof(Resources).Assembly); 49 | resourceMan = temp; 50 | } 51 | return resourceMan; 52 | } 53 | } 54 | 55 | /// 56 | /// Overrides the current thread's CurrentUICulture property for all 57 | /// resource lookups using this strongly typed resource class. 58 | /// 59 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 60 | internal static global::System.Globalization.CultureInfo Culture 61 | { 62 | get 63 | { 64 | return resourceCulture; 65 | } 66 | set 67 | { 68 | resourceCulture = value; 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18444 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ASCOM.ArduinoST4.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | 30 | [global::System.Configuration.UserScopedSettingAttribute()] 31 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 32 | [global::System.Configuration.DefaultSettingValueAttribute("")] 33 | public string DriverId 34 | { 35 | get 36 | { 37 | return ((string)(this["DriverId"])); 38 | } 39 | set 40 | { 41 | this["DriverId"] = value; 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ASCOMDriver/ArduinoST4Driver/ArduinoST4TestForms/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ASCOMDriver/Installer/ArduinoST4 Setup.iss: -------------------------------------------------------------------------------- 1 | ; 2 | ; Script generated by the ASCOM Driver Installer Script Generator 6.0.0.0 3 | ; Generated by Kevin Ferrare on 2015-01-17 (UTC) 4 | ; 5 | [Setup] 6 | AppID={{d4b5de5b-9b10-47eb-8d49-f91ee606f7f1} 7 | AppName=ASCOM ArduinoST4 Telescope Driver 8 | AppVerName=ASCOM ArduinoST4 Telescope Driver 1.0 9 | AppVersion=1.0 10 | AppPublisher=Kevin Ferrare 11 | AppPublisherURL=mailto:kevinferrare@gmail.com 12 | AppSupportURL=https://code.google.com/p/arduino-st4/ 13 | AppUpdatesURL=https://code.google.com/p/arduino-st4/ 14 | VersionInfoVersion=1.0.0 15 | MinVersion=0,5.0.2195sp4 16 | DefaultDirName="{cf}\ASCOM\Telescope" 17 | DisableDirPage=yes 18 | DisableProgramGroupPage=yes 19 | OutputDir="." 20 | OutputBaseFilename="ArduinoST4 Setup" 21 | Compression=lzma 22 | SolidCompression=yes 23 | ; Put there by Platform if Driver Installer Support selected 24 | WizardImageFile="C:\Program Files (x86)\ASCOM\Platform 6 Developer Components\Installer Generator\Resources\WizardImage.bmp" 25 | ; {cf}\ASCOM\Uninstall\Telescope folder created by Platform, always 26 | UninstallFilesDir="{cf}\ASCOM\Uninstall\Telescope\ArduinoST4" 27 | 28 | [Languages] 29 | Name: "english"; MessagesFile: "compiler:Default.isl" 30 | 31 | [Dirs] 32 | Name: "{cf}\ASCOM\Uninstall\Telescope\ArduinoST4" 33 | ; TODO: Add subfolders below {app} as needed (e.g. Name: "{app}\MyFolder") 34 | 35 | [Files] 36 | Source: "..\ArduinoST4Driver\ArduinoST4Driver\bin\Release\ASCOM.ArduinoST4.Telescope.dll"; DestDir: "{app}" 37 | ; Optional source files (COM and .NET aware) 38 | 39 | ; Only if driver is .NET 40 | [Run] 41 | ; Only for .NET assembly/in-proc drivers 42 | Filename: "{dotnet4032}\regasm.exe"; Parameters: "/codebase ""{app}\ASCOM.ArduinoST4.Telescope.dll"""; Flags: runhidden 32bit 43 | Filename: "{dotnet4064}\regasm.exe"; Parameters: "/codebase ""{app}\ASCOM.ArduinoST4.Telescope.dll"""; Flags: runhidden 64bit; Check: IsWin64 44 | 45 | 46 | 47 | 48 | ; Only if driver is .NET 49 | [UninstallRun] 50 | ; Only for .NET assembly/in-proc drivers 51 | Filename: "{dotnet4032}\regasm.exe"; Parameters: "-u ""{app}\ASCOM.ArduinoST4.Telescope.dll"""; Flags: runhidden 32bit 52 | Filename: "{dotnet4064}\regasm.exe"; Parameters: "-u ""{app}\ASCOM.ArduinoST4.Telescope.dll"""; Flags: runhidden 64bit; Check: IsWin64 53 | 54 | 55 | 56 | 57 | [CODE] 58 | // 59 | // Before the installer UI appears, verify that the (prerequisite) 60 | // ASCOM Platform 6.0 or greater is installed, including both Helper 61 | // components. Utility is required for all types (COM and .NET)! 62 | // 63 | function InitializeSetup(): Boolean; 64 | var 65 | U : Variant; 66 | H : Variant; 67 | begin 68 | Result := FALSE; // Assume failure 69 | // check that the DriverHelper and Utilities objects exist, report errors if they don't 70 | try 71 | H := CreateOLEObject('DriverHelper.Util'); 72 | except 73 | MsgBox('The ASCOM DriverHelper object has failed to load, this indicates a serious problem with the ASCOM installation', mbInformation, MB_OK); 74 | end; 75 | try 76 | U := CreateOLEObject('ASCOM.Utilities.Util'); 77 | except 78 | MsgBox('The ASCOM Utilities object has failed to load, this indicates that the ASCOM Platform has not been installed correctly', mbInformation, MB_OK); 79 | end; 80 | try 81 | if (U.IsMinimumRequiredVersion(6,0)) then // this will work in all locales 82 | Result := TRUE; 83 | except 84 | end; 85 | if(not Result) then 86 | MsgBox('The ASCOM Platform 6.0 or greater is required for this driver.', mbInformation, MB_OK); 87 | end; 88 | 89 | // Code to enable the installer to uninstall previous versions of itself when a new version is installed 90 | procedure CurStepChanged(CurStep: TSetupStep); 91 | var 92 | ResultCode: Integer; 93 | UninstallExe: String; 94 | UninstallRegistry: String; 95 | begin 96 | if (CurStep = ssInstall) then // Install step has started 97 | begin 98 | // Create the correct registry location name, which is based on the AppId 99 | UninstallRegistry := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\{#SetupSetting("AppId")}' + '_is1'); 100 | // Check whether an extry exists 101 | if RegQueryStringValue(HKLM, UninstallRegistry, 'UninstallString', UninstallExe) then 102 | begin // Entry exists and previous version is installed so run its uninstaller quietly after informing the user 103 | MsgBox('Setup will now remove the previous version.', mbInformation, MB_OK); 104 | Exec(RemoveQuotes(UninstallExe), ' /SILENT', '', SW_SHOWNORMAL, ewWaitUntilTerminated, ResultCode); 105 | sleep(1000); //Give enough time for the install screen to be repainted before continuing 106 | end 107 | end; 108 | end; 109 | 110 | -------------------------------------------------------------------------------- /ArduinoCode/ArduinoCode.ino: -------------------------------------------------------------------------------- 1 | // This file is part of Arduino ST4. 2 | // 3 | // Arduino ST4 is free software: you can redistribute it and/or modify 4 | // it under the terms of the GNU Lesser General Public License as published by 5 | // the Free Software Foundation, either version 3 of the License, or 6 | // (at your option) any later version. 7 | // 8 | // Arduino ST4 is distributed in the hope that it will be useful, 9 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | // GNU Lesser General Public License for more details. 12 | // 13 | // You should have received a copy of the GNU Lesser General Public License 14 | // along with Arduino ST4. If not, see . 15 | // 16 | // Copyright Kevin Ferrare 2014 17 | 18 | /* 19 | * Led indicates whether the software requested connection, it is shut off when the software disconnects 20 | */ 21 | const int pinLED = 13; 22 | 23 | /** 24 | * An axis has a pin per direction. 25 | * Both pins cannot be up at the same time. 26 | */ 27 | class Axis { 28 | private: 29 | int plusPin; 30 | int minusPin; 31 | public: 32 | Axis(int plusPin, int minusPin) : 33 | plusPin(plusPin), minusPin(minusPin) { 34 | } 35 | void setupPins(){ 36 | pinMode(this->plusPin, OUTPUT); 37 | pinMode(this->minusPin, OUTPUT); 38 | } 39 | void plus(){ 40 | digitalWrite(this->minusPin, LOW); 41 | digitalWrite(this->plusPin, HIGH); 42 | } 43 | void minus(){ 44 | digitalWrite(this->plusPin, LOW); 45 | digitalWrite(this->minusPin, HIGH); 46 | } 47 | void reset(){ 48 | digitalWrite(this->minusPin, LOW); 49 | digitalWrite(this->plusPin, LOW); 50 | } 51 | }; 52 | 53 | class Axis rightAscension( 54 | 2,//RA+ pin 55 | 5);//RA- pin 56 | class Axis declination( 57 | 3,//DEC+ pin 58 | 4);//DEC- pin 59 | 60 | void setup() 61 | { 62 | rightAscension.setupPins(); 63 | declination.setupPins(); 64 | pinMode(pinLED, OUTPUT); 65 | //57.6k, 8 data bits, no parity, one stop bit. 66 | Serial.begin(57600, SERIAL_8N1); 67 | //Wait for serial port to connect. Needed for Leonardo only 68 | while (!Serial); 69 | Serial.println("INITIALIZED#"); 70 | } 71 | 72 | void resetPins(){ 73 | rightAscension.reset(); 74 | declination.reset(); 75 | } 76 | 77 | void loop() 78 | { 79 | if (Serial.available() > 0) { 80 | //Received something 81 | String opcode = Serial.readStringUntil('#'); 82 | boolean validOpcode=true; 83 | //Parse opcode 84 | if(opcode=="CONNECT"){ 85 | digitalWrite(pinLED, HIGH); 86 | resetPins(); 87 | } 88 | else if (opcode=="DISCONNECT"){ 89 | digitalWrite(pinLED, LOW); 90 | resetPins(); 91 | } 92 | else if(opcode=="RA0"){ 93 | rightAscension.reset(); 94 | } 95 | else if(opcode=="RA+"){ 96 | rightAscension.plus(); 97 | } 98 | else if(opcode=="RA-"){ 99 | rightAscension.minus(); 100 | } 101 | else if(opcode=="DEC0"){ 102 | declination.reset(); 103 | } 104 | else if(opcode=="DEC+"){ 105 | declination.plus(); 106 | } 107 | else if(opcode=="DEC-"){ 108 | declination.minus(); 109 | } 110 | else{ 111 | validOpcode=false; 112 | } 113 | if(validOpcode){ 114 | //Acknowledge valid command 115 | Serial.println("OK#"); 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /Hardware/diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/Hardware/diagram.png -------------------------------------------------------------------------------- /Hardware/final_back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/Hardware/final_back.jpg -------------------------------------------------------------------------------- /Hardware/final_case.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/Hardware/final_case.png -------------------------------------------------------------------------------- /Hardware/final_front.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/Hardware/final_front.jpg -------------------------------------------------------------------------------- /Hardware/plugged_into_scope.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/Hardware/plugged_into_scope.jpg -------------------------------------------------------------------------------- /Hardware/plugged_into_scope_small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/Hardware/plugged_into_scope_small.jpg -------------------------------------------------------------------------------- /Hardware/prototype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/Hardware/prototype.png -------------------------------------------------------------------------------- /Hardware/prototype_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/Hardware/prototype_small.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Purpose 2 | The purpose of this project is to connect a telescope to a computer through the mount guide port (ST-4 port) using an arduino. This is similar to [GPUSB](http://www.store.shoestringastronomy.com/gpusb.htm). 3 | 4 | The ST-4 Port is present on some computerized mounts and it is easy to [add one](http://thx8411.over-blog.com/pages/Add_an_ST4_port_on_the_EQ4EQ5_motor_drives-3258969.html) to motorized mounts like the EQ3 / EQ4 / EQ5. Refer to [this](http://www.store.shoestringastronomy.com/downloads/HCModGuidance.pdf) for other mounts modifications. 5 | 6 | Building your own ST-4 adapter costs less than available commercial solutions (~6 USD) and on the top of providing autoguiding, the custom driver also has a working GOTO functionality. 7 | 8 | ## Functionalities 9 | Autoguiding and GOTO are supported, this allows the telescope to be used for astrophotography using PHD or for finding objects in the sky with a software like stellarium or cartes du ciel. 10 | 11 | GOTO will require a good polar alignment in order to have acceptable accuracy. 12 | 13 | The slewing speed will be limited by the mount maximal speed. 14 | 15 | ## Implementation 16 | The project has 3 main components: 17 | * The hardware 18 | * The arduino software 19 | * The ASCOM driver 20 | 21 | # Getting started 22 | ## Building the hardware 23 | The hardware is built from off the shelf cheap components, you can buy them from ebay: 24 | * An arduino with an USB port (I used the Nano v3 clone since it is cheap and small). 25 | * An optocoupler (I used the TLP521-4). 26 | * A RJ12 socket. 27 | * A RJ12 straight cable (6P6C). 28 | * A bunch of 100 Ohm resistors to protect the optocoupler leds (it works without those as well) 29 | 30 | The connection between the components is as below: 31 | 32 | ![Wiring](https://raw.githubusercontent.com/kevinferrare/arduino-st4/master/Hardware/diagram.png) 33 | 34 | Be careful not to invert GND with some other pins. 35 | 36 | Please note that some mounts may have a different pinout for ST-4. 37 | 38 | My first version looked like this (quick and dirty solders, very fragile!): 39 | 40 | ![First prototype](https://raw.githubusercontent.com/kevinferrare/arduino-st4/master/Hardware/prototype_small.png) 41 | 42 | It is also possible to avoid buying the RJ12 cable and the connector by soldering the optocoupler directly to the mount controler. 43 | 44 | ## Flashing the arduino 45 | Once the hardware is built, you have to upload the code to the arduino. 46 | * Download the [arduino IDE](http://arduino.cc/en/main/software#toc1) 47 | * Download the [firmware](https://github.com/kevinferrare/arduino-st4/releases/download/1.0/ArduinoCode.ino) 48 | * Connect your arduino to your PC, open the downloaded .ino file with the IDE and click on the upload button (there are plenty of tutorials on the internet describing how to upload code to an arduino if you need more details) 49 | 50 | At this point, you should be able to send commands to the arduino through the serial monitor of the IDE and to test if you can control you telescope axes (bitrate is 57.6k, if you see garbled output, you might want to check this). 51 | 52 | Accepted commands are: 53 | 54 | Command | Action 55 | --------|------- 56 | CONNECT# | Stop all the moves and light up the arduino LED 57 | RA+# | Start moving right ascension axis towards upper position 58 | RA-# | Start moving right ascension axis towards lower position 59 | RA0# | Stop moving right ascension axis 60 | DEC+# | Start moving declination axis towards upper position 61 | DEC-# | Start moving declination axis towards lower position 62 | DEC0# | Stop moving declination axis 63 | DISCONNECT# | Stop all the moves and shut down the arduino LED 64 | 65 | The arduino should respond "OK#" to all the commands above. The commands should all end with #. 66 | 67 | If the telescope is not behaving as expected, check your connections, you may have inverted some cables. 68 | 69 | ## Installing the ASCOM driver 70 | First, please check that the [ASCOM platform](http://ascom-standards.org/) v6.0 (or higher) is installed on your computer. 71 | 72 | Then download and run the installer: 73 | https://github.com/kevinferrare/arduino-st4/releases/download/1.0/ArduinoST4.Setup.exe 74 | 75 | ## Configuring the driver 76 | * Open any software you would like to use with your telescope (for example [cartes du ciel](http://www.ap-i.net/skychart/en/start) or [PHD](http://www.stark-labs.com/phdguiding.html)) 77 | * Open the connection dialog 78 | * Select the "ArduinoST4 telescope driver" 79 | 80 | ![Driver Selection](https://raw.githubusercontent.com/kevinferrare/arduino-st4/master/Wiki/DriverSelection.png) 81 | 82 | If you couldn't find it, there was a problem with the driver installation. 83 | * Click on "Properties" to configure it 84 | * Put in com port the name of the port on which the arduino is connected 85 | * Modify if needed the different slewing rates in order to match the axis rates of the mount (multiple of sideral rate, 1X = earth rotation rate). 86 | 87 | ![Driver Configuration](https://raw.githubusercontent.com/kevinferrare/arduino-st4/master/Wiki/DriverConfiguration.png) 88 | 89 | The default settings work fine for my EQ5 mount with the speed switch on the 8X position. 90 | 91 | Please note that RA+ and RA- value is not 8, this is because of the earth rotation. Your mount may compensate for this or not. 92 | 93 | Everything plugged in: 94 | 95 | ![Telescope setup picture](https://raw.githubusercontent.com/kevinferrare/arduino-st4/master/Hardware/plugged_into_scope_small.jpg) 96 | 97 | Video of the telescope slewing: 98 | 99 | [![Video of the telescope slewing](http://img.youtube.com/vi/MwBNUDN8piQ/0.jpg)](http://www.youtube.com/watch?v=MwBNUDN8piQ) 100 | 101 | 102 | # Usage notes 103 | Autoguiding should work just fine. 104 | 105 | GOTO will be slow, going from andromeda to the pleiades takes 20 minutes with 8X speed. When searching for an object, it is faster to point the telescope to a known position that is close and to slew from there. 106 | 107 | If the polar alignment is good, GOTO will be precise enough. Most of the times, the object is right in the center of the eyepiece :) 108 | 109 | Stellarium does not support ASCOM out of the box, it is thus necessary to install an ASCOM<->Stellarium bridge like [Stellariumscope](http://welshdragoncomputing.ca/x/index.php/home/stellariumscope/download-stellariumscope). 110 | # Indi driver 111 | Thanks to Stephan for implementing a basic [indi driver](https://github.com/tliff/indi_ardust4) that can do autoguiding. 112 | 113 | # Todo 114 | * Write a complete [indi](http://www.indilib.org/) driver. 115 | * Cleanup ASCOM boilerplate (API had to be implemented through trial and error due to lack of details in documentation). 116 | * Test the driver on more configurations, especially windows 32 bits. 117 | * Implement a way to do a meridian flip (Easiest way would be to do it in the ASCOM driver) 118 | 119 | # License 120 | This project is licensed under the GNU LGPL v3 121 | -------------------------------------------------------------------------------- /Wiki/DriverConfiguration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/Wiki/DriverConfiguration.png -------------------------------------------------------------------------------- /Wiki/DriverSelection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinferrare/arduino-st4/7f75176505f52057f3570f15d4e8c8b9e0f17fea/Wiki/DriverSelection.png --------------------------------------------------------------------------------