Instrument Neutral Distributed Interface INDI  2.0.2
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"
28 #include "indistandardproperty.h"
29 
30 #include <cstring>
31 #include <memory>
32 
33 #include <unistd.h>
34 
35 // We declare an auto pointer to gpGuide.
36 std::unique_ptr<STAR2000> s2kGuide(new STAR2000());
37 
39 {
40  return (const char *)"STAR2000";
41 }
42 
44 {
45  bool rc = false;
46 
47  if (isConnected())
48  return true;
49 
50  rc = Connect(PortT[0].text);
51 
52  if (rc)
54 
55  return rc;
56 }
57 
58 bool STAR2000::Connect(char *port)
59 {
60  if (isSimulation())
61  {
62  IDMessage(getDeviceName(), "Simulated STAR2000 box is online.");
63  return true;
64  }
65 
66  if (ConnectSTAR2k(port) < 0)
67  {
69  "Error connecting to port %s. Make sure you have BOTH write and read permission to your port.", port);
70  return false;
71  }
72 
73  IDMessage(getDeviceName(), "STAR2000 box is online.");
74 
75  return true;
76 }
77 
79 {
80  IDMessage(getDeviceName(), "STAR200 box is offline.");
81 
82  if (!isSimulation())
84 
85  return true;
86 }
87 
89 {
91 
92  IUFillText(&PortT[0], "PORT", "Port", "/dev/ttyUSB0");
94 
97 
99 
101 
102  return (rc);
103 }
104 
106 {
108 
109  if (isConnected())
110  {
113  }
114  else
115  {
118  }
119 
120  return true;
121 }
122 
123 void STAR2000::ISGetProperties(const char *dev)
124 {
128 }
129 
130 bool STAR2000::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
131 {
132  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
133  {
134  if (strcmp(name, GuideNSNP.name) == 0 || strcmp(name, GuideWENP.name) == 0)
135  {
136  processGuiderProperties(name, values, names, n);
137  return true;
138  }
139  }
140 
141  return INDI::DefaultDevice::ISNewNumber(dev, name, values, names, n);
142 }
143 
144 bool STAR2000::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
145 {
146  return INDI::DefaultDevice::ISNewSwitch(dev, name, states, names, n);
147 }
148 
149 bool STAR2000::ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n)
150 {
151  if (strcmp(name, PortTP.name) == 0)
152  {
153  PortTP.s = IPS_OK;
154  IUUpdateText(&PortTP, texts, names, n);
155  IDSetText(&PortTP, nullptr);
156 
157  return true;
158  }
159 
160  return INDI::DefaultDevice::ISNewText(dev, name, texts, names, n);
161 }
162 
164 {
166 }
167 
169 {
170  IUSaveConfigText(fp, &PortTP);
171  return true;
172 }
173 
174 float STAR2000::CalcWEPulseTimeLeft()
175 {
176  double timesince;
177  double timeleft;
178  struct timeval now
179  {
180  0, 0
181  };
182 
183  gettimeofday(&now, nullptr);
184  timesince = (double)(now.tv_sec * 1000.0 + now.tv_usec / 1000) -
185  (double)(WEPulseStart.tv_sec * 1000.0 + WEPulseStart.tv_usec / 1000);
186  timesince = timesince / 1000;
187 
188  timeleft = WEPulseRequest - timesince;
189  return timeleft;
190 }
191 
192 float STAR2000::CalcNSPulseTimeLeft()
193 {
194  double timesince;
195  double timeleft;
196  struct timeval now
197  {
198  0, 0
199  };
200  gettimeofday(&now, nullptr);
201 
202  timesince = (double)(now.tv_sec * 1000.0 + now.tv_usec / 1000) -
203  (double)(NSPulseStart.tv_sec * 1000.0 + NSPulseStart.tv_usec / 1000);
204  timesince = timesince / 1000;
205 
206  timeleft = NSPulseRequest - timesince;
207  return timeleft;
208 }
209 
211 {
212  float timeleft;
213 
214  if (InWEPulse)
215  {
216  timeleft = CalcWEPulseTimeLeft();
217 
218  if (timeleft < 1.0)
219  {
220  if (timeleft > 0.25)
221  {
222  // a quarter of a second or more
223  // just set a tighter timer
224  WEtimerID = SetTimer(250);
225  }
226  else
227  {
228  if (timeleft > 0.07)
229  {
230  // use an even tighter timer
231  WEtimerID = SetTimer(50);
232  }
233  else
234  {
235  // it's real close now, so spin on it
236  while (timeleft > 0)
237  {
238  int slv;
239  slv = 100000 * timeleft;
240  //IDLog("usleep %d\n",slv);
241  usleep(slv);
242  timeleft = CalcWEPulseTimeLeft();
243  }
244 
245  StopPulse(WEDir);
246  InWEPulse = false;
247 
248  // If we have another pulse, keep going
249  if (!InNSPulse)
250  SetTimer(250);
251  }
252  }
253  }
254  else if (!InNSPulse)
255  {
256  WEtimerID = SetTimer(250);
257  }
258  }
259 
260  if (InNSPulse)
261  {
262  timeleft = CalcNSPulseTimeLeft();
263 
264  if (timeleft < 1.0)
265  {
266  if (timeleft > 0.25)
267  {
268  // a quarter of a second or more
269  // just set a tighter timer
270  NStimerID = SetTimer(250);
271  }
272  else
273  {
274  if (timeleft > 0.07)
275  {
276  // use an even tighter timer
277  NStimerID = SetTimer(50);
278  }
279  else
280  {
281  // it's real close now, so spin on it
282  while (timeleft > 0)
283  {
284  int slv;
285  slv = 100000 * timeleft;
286  //IDLog("usleep %d\n",slv);
287  usleep(slv);
288  timeleft = CalcNSPulseTimeLeft();
289  }
290 
291  StopPulse(NSDir);
292  InNSPulse = false;
293  }
294  }
295  }
296  else
297  {
298  NStimerID = SetTimer(250);
299  }
300  }
301 }
302 
304 {
305  RemoveTimer(NStimerID);
306 
307  StartPulse(NORTH);
308 
309  NSDir = NORTH;
310 
311  LOG_DEBUG("Starting NORTH guide");
312 
313  if (ms <= getCurrentPollingPeriod())
314  {
315  usleep(ms * 1000);
316 
317  StopPulse(NORTH);
318 
319  return IPS_OK;
320  }
321 
322  NSPulseRequest = ms / 1000.0;
323  gettimeofday(&NSPulseStart, nullptr);
324  InNSPulse = true;
325 
326  NStimerID = SetTimer(ms - 50);
327 
328  return IPS_BUSY;
329 }
330 
332 {
333  RemoveTimer(NStimerID);
334 
335  StartPulse(SOUTH);
336 
337  LOG_DEBUG("Starting SOUTH guide");
338 
339  NSDir = SOUTH;
340 
341  if (ms <= getCurrentPollingPeriod())
342  {
343  usleep(ms * 1000);
344 
345  StopPulse(SOUTH);
346 
347  return IPS_OK;
348  }
349 
350  NSPulseRequest = ms / 1000.0;
351  gettimeofday(&NSPulseStart, nullptr);
352  InNSPulse = true;
353 
354  NStimerID = SetTimer(ms - 50);
355 
356  return IPS_BUSY;
357 }
358 
360 {
361  RemoveTimer(WEtimerID);
362 
363  StartPulse(EAST);
364 
365  LOG_DEBUG("Starting EAST guide");
366 
367  WEDir = EAST;
368 
369  if (ms <= getCurrentPollingPeriod())
370  {
371  usleep(ms * 1000);
372 
373  StopPulse(EAST);
374 
375  return IPS_OK;
376  }
377 
378  WEPulseRequest = ms / 1000.0;
379  gettimeofday(&WEPulseStart, nullptr);
380  InWEPulse = true;
381 
382  WEtimerID = SetTimer(ms - 50);
383 
384  return IPS_BUSY;
385 }
386 
388 {
389  RemoveTimer(WEtimerID);
390 
391  StartPulse(WEST);
392 
393  LOG_DEBUG("Starting WEST guide");
394 
395  WEDir = WEST;
396 
397  if (ms <= getCurrentPollingPeriod())
398  {
399  usleep(ms * 1000);
400 
401  StopPulse(WEST);
402 
403  return IPS_OK;
404  }
405 
406  WEPulseRequest = ms / 1000.0;
407  gettimeofday(&WEPulseStart, nullptr);
408  InWEPulse = true;
409 
410  WEtimerID = SetTimer(ms - 50);
411 
412  return IPS_BUSY;
413 }
std::unique_ptr< STAR2000 > s2kGuide(new STAR2000())
int ConnectSTAR2k(char *port)
Definition: STAR2kdriver.c:59
void DisconnectSTAR2k(void)
Definition: STAR2kdriver.c:159
void StopPulse(int direction)
Definition: STAR2kdriver.c:133
void StartPulse(int direction)
Definition: STAR2kdriver.c:111
#define EAST
Definition: STAR2kdriver.h:39
#define NORTH
Definition: STAR2kdriver.h:37
#define WEST
Definition: STAR2kdriver.h:38
#define SOUTH
Definition: STAR2kdriver.h:40
bool isConnected() const
Definition: basedevice.cpp:520
const char * getDeviceName() const
Definition: basedevice.cpp:821
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...
virtual bool loadConfig(bool silent=false, const char *property=nullptr)
Load the last saved configuration file.
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
void defineProperty(INumberVectorProperty *property)
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
virtual bool initProperties()
Initilize 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 setDriverInterface(uint16_t value)
setInterface Set driver interface. By default the driver interface is set to GENERAL_DEVICE....
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.
INumberVectorProperty GuideNSNP
void initGuiderProperties(const char *deviceName, const char *groupName)
Initilize guider properties. It is recommended to call this function within initProperties() of your ...
INumberVectorProperty GuideWENP
void processGuiderProperties(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:359
virtual bool ISNewText(const char *dev, const char *name, char *texts[], char *names[], int n) override
Process the client newSwitch command.
Definition: STAR2000.cpp:149
virtual IPState GuideWest(uint32_t ms) override
Guide west for ms milliseconds. West is defined as RA-.
Definition: STAR2000.cpp:387
void TimerHit() override
Callback function to be called once SetTimer duration elapses.
Definition: STAR2000.cpp:210
const char * getDefaultName() override
Definition: STAR2000.cpp:38
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Save specific properties in the provide config file handler. Child class usually over...
Definition: STAR2000.cpp:168
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: STAR2000.cpp:88
bool Connect() override
Connect to the device. INDI::DefaultDevice implementation connects to appropriate connection interfac...
Definition: STAR2000.cpp:43
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:123
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:163
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: STAR2000.cpp:130
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:331
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: STAR2000.cpp:105
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: STAR2000.cpp:144
bool Disconnect() override
Disconnect from device.
Definition: STAR2000.cpp:78
virtual IPState GuideNorth(uint32_t ms) override
Guide north for ms milliseconds. North is defined as DEC+.
Definition: STAR2000.cpp:303
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:150
@ IP_RW
Definition: indiapi.h:186
IPState
Property state.
Definition: indiapi.h:160
@ IPS_BUSY
Definition: indiapi.h:163
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
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:291
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:198
void IUSaveConfigText(FILE *fp, const ITextVectorProperty *tvp)
Add a text vector property value to the configuration file.
Definition: indidevapi.c:20
int IUUpdateText(ITextVectorProperty *tvp, char *texts[], char *names[], int n)
Update all text members in a text vector property.
Definition: indidriver.c:1396
void IDMessage(const char *dev, const char *fmt,...)
Definition: indidriver.c:960
void IDSetText(const ITextVectorProperty *tvp, const char *fmt,...)
Definition: indidriver.c:1191
#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:323
char name[MAXINDINAME]
Definition: indiapi.h:250