Instrument Neutral Distributed Interface INDI 2.2.5
STAR2000.cpp
Go to the documentation of this file.
1/*******************************************************************************
2 created 2014 G. Schmidt
3
4 derived from gpusb code from Jasem Mutlaq
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 2 of the License, or (at your option)
9 any later version.
10
11 This program is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 more details.
15
16 You should have received a copy of the GNU Library General Public License
17 along with this library; see the file COPYING.LIB. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
20
21 The full GNU General Public License is included in this distribution in the
22 file called LICENSE.
23*******************************************************************************/
24
25#include "STAR2000.h"
26
27#include "STAR2kdriver.h"
29
30#include <cstring>
31#include <memory>
32
33#include <unistd.h>
34
35// We declare an auto pointer to gpGuide.
36std::unique_ptr<STAR2000> s2kGuide(new STAR2000());
37
39{
40
41}
42
44{
45 return "STAR2000";
46}
47
49{
50 bool rc = false;
51
52 if (isConnected())
53 return true;
54
55 rc = Connect(PortT[0].text);
56
57 if (rc)
59
60 return rc;
61}
62
63bool STAR2000::Connect(char *port)
64{
65 if (isSimulation())
66 {
67 IDMessage(getDeviceName(), "Simulated STAR2000 box is online.");
68 return true;
69 }
70
71 if (ConnectSTAR2k(port) < 0)
72 {
74 "Error connecting to port %s. Make sure you have BOTH write and read permission to your port.", port);
75 return false;
76 }
77
78 IDMessage(getDeviceName(), "STAR2000 box is online.");
79
80 return true;
81}
82
84{
85 IDMessage(getDeviceName(), "STAR200 box is offline.");
86
87 if (!isSimulation())
89
90 return true;
91}
92
94{
96
97 IUFillText(&PortT[0], "PORT", "Port", "/dev/ttyUSB0");
99
102
104
106
107 return (rc);
108}
109
117
124
125bool STAR2000::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
126{
127 // Check guider interface
128 if (GI::processNumber(dev, name, values, names, n))
129 return true;
130
131 return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
132}
133
134bool STAR2000::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
135{
136 return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
137}
138
139bool STAR2000::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
140{
141 if (strcmp(name, PortTP.name) == 0)
142 {
143 PortTP.s = IPS_OK;
144 IUUpdateText(&PortTP, texts, names, n);
145 IDSetText(&PortTP, nullptr);
146
147 return true;
148 }
149
150 return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n);
151}
152
157
159{
161 return true;
162}
163
164float STAR2000::CalcWEPulseTimeLeft()
165{
166 double timesince;
167 double timeleft;
168 struct timeval now
169 {
170 0, 0
171 };
172
173 gettimeofday(&now, nullptr);
174 timesince = (double)(now.tv_sec * 1000.0 + now.tv_usec / 1000) -
175 (double)(WEPulseStart.tv_sec * 1000.0 + WEPulseStart.tv_usec / 1000);
176 timesince = timesince / 1000;
177
178 timeleft = WEPulseRequest - timesince;
179 return timeleft;
180}
181
182float STAR2000::CalcNSPulseTimeLeft()
183{
184 double timesince;
185 double timeleft;
186 struct timeval now
187 {
188 0, 0
189 };
190 gettimeofday(&now, nullptr);
191
192 timesince = (double)(now.tv_sec * 1000.0 + now.tv_usec / 1000) -
193 (double)(NSPulseStart.tv_sec * 1000.0 + NSPulseStart.tv_usec / 1000);
194 timesince = timesince / 1000;
195
196 timeleft = NSPulseRequest - timesince;
197 return timeleft;
198}
199
201{
202 float timeleft;
203
204 if (InWEPulse)
205 {
206 timeleft = CalcWEPulseTimeLeft();
207
208 if (timeleft < 1.0)
209 {
210 if (timeleft > 0.25)
211 {
212 // a quarter of a second or more
213 // just set a tighter timer
214 WEtimerID = SetTimer(250);
215 }
216 else
217 {
218 if (timeleft > 0.07)
219 {
220 // use an even tighter timer
221 WEtimerID = SetTimer(50);
222 }
223 else
224 {
225 // it's real close now, so spin on it
226 while (timeleft > 0)
227 {
228 int slv;
229 slv = 100000 * timeleft;
230 //IDLog("usleep %d\n",slv);
231 usleep(slv);
232 timeleft = CalcWEPulseTimeLeft();
233 }
234
235 StopPulse(WEDir);
236 InWEPulse = false;
237
238 // If we have another pulse, keep going
239 if (!InNSPulse)
240 SetTimer(250);
241 }
242 }
243 }
244 else if (!InNSPulse)
245 {
246 WEtimerID = SetTimer(250);
247 }
248 }
249
250 if (InNSPulse)
251 {
252 timeleft = CalcNSPulseTimeLeft();
253
254 if (timeleft < 1.0)
255 {
256 if (timeleft > 0.25)
257 {
258 // a quarter of a second or more
259 // just set a tighter timer
260 NStimerID = SetTimer(250);
261 }
262 else
263 {
264 if (timeleft > 0.07)
265 {
266 // use an even tighter timer
267 NStimerID = SetTimer(50);
268 }
269 else
270 {
271 // it's real close now, so spin on it
272 while (timeleft > 0)
273 {
274 int slv;
275 slv = 100000 * timeleft;
276 //IDLog("usleep %d\n",slv);
277 usleep(slv);
278 timeleft = CalcNSPulseTimeLeft();
279 }
280
281 StopPulse(NSDir);
282 InNSPulse = false;
283 }
284 }
285 }
286 else
287 {
288 NStimerID = SetTimer(250);
289 }
290 }
291}
292
294{
295 RemoveTimer(NStimerID);
296
298
299 NSDir = NORTH;
300
301 LOG_DEBUG("Starting NORTH guide");
302
303 if (ms <= getCurrentPollingPeriod())
304 {
305 usleep(ms * 1000);
306
308
309 return IPS_OK;
310 }
311
312 NSPulseRequest = ms / 1000.0;
313 gettimeofday(&NSPulseStart, nullptr);
314 InNSPulse = true;
315
316 NStimerID = SetTimer(ms - 50);
317
318 return IPS_BUSY;
319}
320
322{
323 RemoveTimer(NStimerID);
324
326
327 LOG_DEBUG("Starting SOUTH guide");
328
329 NSDir = SOUTH;
330
331 if (ms <= getCurrentPollingPeriod())
332 {
333 usleep(ms * 1000);
334
336
337 return IPS_OK;
338 }
339
340 NSPulseRequest = ms / 1000.0;
341 gettimeofday(&NSPulseStart, nullptr);
342 InNSPulse = true;
343
344 NStimerID = SetTimer(ms - 50);
345
346 return IPS_BUSY;
347}
348
350{
351 RemoveTimer(WEtimerID);
352
354
355 LOG_DEBUG("Starting EAST guide");
356
357 WEDir = EAST;
358
359 if (ms <= getCurrentPollingPeriod())
360 {
361 usleep(ms * 1000);
362
364
365 return IPS_OK;
366 }
367
368 WEPulseRequest = ms / 1000.0;
369 gettimeofday(&WEPulseStart, nullptr);
370 InWEPulse = true;
371
372 WEtimerID = SetTimer(ms - 50);
373
374 return IPS_BUSY;
375}
376
378{
379 RemoveTimer(WEtimerID);
380
382
383 LOG_DEBUG("Starting WEST guide");
384
385 WEDir = WEST;
386
387 if (ms <= getCurrentPollingPeriod())
388 {
389 usleep(ms * 1000);
390
392
393 return IPS_OK;
394 }
395
396 WEPulseRequest = ms / 1000.0;
397 gettimeofday(&WEPulseStart, nullptr);
398 InWEPulse = true;
399
400 WEtimerID = SetTimer(ms - 50);
401
402 return IPS_BUSY;
403}
std::unique_ptr< STAR2000 > s2kGuide(new STAR2000())
int ConnectSTAR2k(char *port)
void DisconnectSTAR2k(void)
void StopPulse(int direction)
void StartPulse(int direction)
#define EAST
#define NORTH
#define WEST
#define SOUTH
bool isConnected() const
const char * getDeviceName() const
virtual bool updateProperties()
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
Process the client newSwitch command.
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
virtual void ISGetProperties(const char *dev)
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
virtual bool ISSnoopDevice(XMLEle *root)
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
void setDriverInterface(uint32_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
virtual bool initProperties()
Initialize properties initial state and value. The child class must implement this function.
bool isSimulation() const
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
Process the client newNumber command.
void RemoveTimer(int id)
Remove timer added with SetTimer.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
Process the client newSwitch command.
bool updateProperties()
updateProperties Define or Delete Rotator properties based on the connection status of the base devic...
void initProperties(const char *groupName)
Initialize guider properties. It is recommended to call this function within initProperties() of your...
bool processNumber(const char *dev, const char *name, double values[], char *names[], int n)
Call this function whenever client updates GuideNSNP or GuideWSP properties in the primary device....
virtual IPState GuideEast(uint32_t ms) override
Guide east for ms milliseconds. East is defined as RA+.
Definition STAR2000.cpp:349
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
Definition STAR2000.cpp:139
virtual IPState GuideWest(uint32_t ms) override
Guide west for ms milliseconds. West is defined as RA-.
Definition STAR2000.cpp:377
void TimerHit() override
Callback function to be called once SetTimer duration elapses.
Definition STAR2000.cpp:200
const char * getDefaultName() override
Definition STAR2000.cpp:43
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
Definition STAR2000.cpp:158
virtual bool initProperties() override
Initialize properties initial state and value. The child class must implement this function.
Definition STAR2000.cpp:93
bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
Definition STAR2000.cpp:48
IText PortT[1]
Definition STAR2000.h:68
virtual void ISGetProperties(const char *dev) override
define the driver's properties to the client. Usually, only a minimum set of properties are defined t...
Definition STAR2000.cpp:118
virtual bool ISSnoopDevice(XMLEle *root) override
Process a snoop event from INDI server. This function is called when a snooped property is updated in...
Definition STAR2000.cpp:153
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition STAR2000.cpp:125
ITextVectorProperty PortTP
Definition STAR2000.h:67
virtual IPState GuideSouth(uint32_t ms) override
Guide south for ms milliseconds. South is defined as DEC-.
Definition STAR2000.cpp:321
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition STAR2000.cpp:110
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition STAR2000.cpp:134
bool Disconnect() override
Disconnect from device.
Definition STAR2000.cpp:83
virtual IPState GuideNorth(uint32_t ms) override
Guide north for ms milliseconds. North is defined as DEC+.
Definition STAR2000.cpp:293
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
ISState
Switch state.
Definition indiapi.h:148
@ IP_RW
Definition indiapi.h:184
IPState
Property state.
Definition indiapi.h:158
@ IPS_BUSY
Definition indiapi.h:161
@ IPS_IDLE
Definition indiapi.h:159
@ IPS_OK
Definition indiapi.h:160
void IUFillTextVector(ITextVectorProperty *tvp, IText *tp, int ntp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a text vector property. The vector's auxiliary elements will be set to NULL.
Definition indidevapi.c:509
void IUFillText(IText *tp, const char *name, const char *label, const char *initialText)
Assign attributes for a text property. The text's auxiliary elements will be set to NULL.
Definition indidevapi.c:416
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
Definition indidevapi.c:28
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
void IDMessage(const char *dev, const char *fmt,...)
Definition indidriver.c:983
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
#define LOG_DEBUG(txt)
Definition indilogger.h:75
const char * DEVICE_PORT
Device serial (or bluetooth) connection port. The default value on Linux is /dev/ttyUSB0 while on Mac...
char name[MAXINDINAME]
Definition indiapi.h:248