Instrument Neutral Distributed Interface INDI  1.9.5
pegasus_focuscube.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  Copyright(c) 2021 Chrysikos Efstathios. All rights reserved.
3 
4  Pegasus FocusCube
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 #include "pegasus_focuscube.h"
25 
26 #include "indicom.h"
28 
29 #include <cmath>
30 #include <cstring>
31 #include <memory>
32 
33 #include <termios.h>
34 #include <unistd.h>
35 
36 #define DMFC_TIMEOUT 3
37 #define FOCUS_SETTINGS_TAB "Settings"
38 #define TEMPERATURE_THRESHOLD 0.1
39 
40 static std::unique_ptr<PegasusFocusCube> focusCube(new PegasusFocusCube());
41 
43 {
44  // Can move in Absolute & Relative motions, can AbortFocuser motion.
51 }
52 
54 {
56 
57  // Focuser temperature
58  IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Celsius", "%6.2f", -50, 70., 0., 0.);
59  IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "FOCUS_TEMPERATURE", "Temperature",
61 
62  // Max Speed
63  IUFillNumber(&MaxSpeedN[0], "Value", "", "%6.2f", 100, 1000., 100., 400.);
64  IUFillNumberVector(&MaxSpeedNP, MaxSpeedN, 1, getDeviceName(), "MaxSpeed", "", FOCUS_SETTINGS_TAB, IP_RW, 0, IPS_IDLE);
65 
66  // Encoders
67  IUFillSwitch(&EncoderS[ENCODERS_ON], "On", "", ISS_ON);
68  IUFillSwitch(&EncoderS[ENCODERS_OFF], "Off", "", ISS_OFF);
69  IUFillSwitchVector(&EncoderSP, EncoderS, 2, getDeviceName(), "Encoders", "", FOCUS_SETTINGS_TAB, IP_RW, ISR_1OFMANY, 0,
70  IPS_IDLE);
71 
72  // LED
73  IUFillSwitch(&LEDS[LED_OFF], "Off", "", ISS_ON);
74  IUFillSwitch(&LEDS[LED_ON], "On", "", ISS_OFF);
75  IUFillSwitchVector(&LEDSP, LEDS, 2, getDeviceName(), "LED", "", FOCUS_SETTINGS_TAB, IP_RW, ISR_1OFMANY, 0, IPS_IDLE);
76 
77  // Firmware Version
78  IUFillText(&FirmwareVersionT[0], "Version", "Version", "");
79  IUFillTextVector(&FirmwareVersionTP, FirmwareVersionT, 1, getDeviceName(), "Firmware", "Firmware", MAIN_CONTROL_TAB, IP_RO,
80  0, IPS_IDLE);
81 
82  // Relative and absolute movement
83  FocusRelPosN[0].min = 0.;
84  FocusRelPosN[0].max = 50000.;
85  FocusRelPosN[0].value = 0;
86  FocusRelPosN[0].step = 1000;
87 
88  FocusAbsPosN[0].min = 0.;
89  FocusAbsPosN[0].value = 0;
90  FocusAbsPosN[0].step = 1000;
91 
92  // Backlash compensation
93  FocusBacklashN[0].min = 1; // 0 is off.
94  FocusBacklashN[0].max = 1000;
95  FocusBacklashN[0].value = 1;
96  FocusBacklashN[0].step = 1;
97 
98  FocusMaxPosN[0].max = 1317500;
99  FocusMaxPosN[0].value = 1317500;
100  FocusAbsPosN[0].max = 1317500;
101 
102  //LED Default ON
103  LEDS[LED_ON].s = ISS_ON;
104  LEDS[LED_OFF].s = ISS_OFF;
105 
106  addDebugControl();
109 
110  return true;
111 }
112 
114 {
116 
117  if (isConnected())
118  {
119  defineProperty(&MaxSpeedNP);
120  defineProperty(&TemperatureNP);
121  defineProperty(&EncoderSP);
122  defineProperty(&LEDSP);
123  defineProperty(&FirmwareVersionTP);
124  }
125  else
126  {
127  deleteProperty(MaxSpeedNP.name);
128  deleteProperty(TemperatureNP.name);
129  deleteProperty(EncoderSP.name);
130  deleteProperty(LEDSP.name);
131  deleteProperty(FirmwareVersionTP.name);
132  }
133 
134  return true;
135 }
136 
138 {
139  if (ack())
140  {
141  LOGF_INFO("%s is online. Getting focus parameters...", this->getDeviceName());
142  return true;
143  }
144 
145  LOGF_INFO(
146  "Error retrieving data from %s, please ensure device is powered and the port is correct.", this->getDeviceName());
147  return false;
148 }
149 
151 {
152  return "Pegasus FocusCube";
153 }
154 
155 bool PegasusFocusCube::ack()
156 {
157  int nbytes_written = 0, nbytes_read = 0, rc = -1;
158  char errstr[MAXRBUF];
159  char cmd[2] = {0};
160  char res[16] = {0};
161 
162  cmd[0] = '#';
163  cmd[1] = 0xA;
164 
165  LOGF_DEBUG("CMD <%#02X>", cmd[0]);
166 
167  tcflush(PortFD, TCIOFLUSH);
168 
169  if ((rc = tty_write(PortFD, cmd, 2, &nbytes_written)) != TTY_OK)
170  {
171  tty_error_msg(rc, errstr, MAXRBUF);
172  LOGF_ERROR("Ack error: %s.", errstr);
173  return false;
174  }
175 
176  if ((rc = tty_read_section(PortFD, res, 0xA, DMFC_TIMEOUT, &nbytes_read)) != TTY_OK)
177  {
178  tty_error_msg(rc, errstr, MAXRBUF);
179  LOGF_ERROR("Ack error: %s.", errstr);
180  return false;
181  }
182 
183  // Get rid of 0xA
184  res[nbytes_read - 1] = 0;
185 
186 
187  if( res[nbytes_read - 2] == '\r') res[nbytes_read - 2] = 0;
188 
189  LOGF_DEBUG("RES <%s>", res);
190 
191  tcflush(PortFD, TCIOFLUSH);
192 
193  if(strstr(res, "OK_FC") != nullptr)
194  return true;
195 
196  return false;
197 }
198 
199 
200 bool PegasusFocusCube::SyncFocuser(uint32_t ticks)
201 {
202  int nbytes_written = 0, rc = -1;
203  char cmd[16] = {0};
204 
205  snprintf(cmd, 16, "W:%ud", ticks);
206  cmd[strlen(cmd)] = 0xA;
207 
208  LOGF_DEBUG("CMD <%s>", cmd);
209 
210  // Set Position
211  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
212  {
213  char errstr[MAXRBUF];
214  tty_error_msg(rc, errstr, MAXRBUF);
215  LOGF_ERROR("sync error: %s.", errstr);
216  return false;
217  }
218 
219  this->ignoreResponse();
220 
221  return true;
222 }
223 
224 bool PegasusFocusCube::move(uint32_t newPosition)
225 {
226  int nbytes_written = 0, rc = -1;
227  char cmd[16] = {0};
228 
229  snprintf(cmd, 16, "M:%ud", newPosition);
230  cmd[strlen(cmd)] = 0xA;
231 
232  LOGF_DEBUG("CMD <%s>", cmd);
233 
234  // Set Position
235  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
236  {
237  char errstr[MAXRBUF];
238  tty_error_msg(rc, errstr, MAXRBUF);
239  LOGF_ERROR("move error: %s.", errstr);
240  return false;
241  }
242 
243  this->ignoreResponse();
244 
245  return true;
246 }
247 
248 bool PegasusFocusCube::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
249 {
250  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
251  {
252 
253  // Encoders
254  if (!strcmp(name, EncoderSP.name))
255  {
256  IUUpdateSwitch(&EncoderSP, states, names, n);
257  bool rc = setEncodersEnabled(EncoderS[ENCODERS_ON].s == ISS_ON);
258  EncoderSP.s = rc ? IPS_OK : IPS_ALERT;
259  IDSetSwitch(&EncoderSP, nullptr);
260  return true;
261  }
262 
263  // LED
264  if (!strcmp(name, LEDSP.name))
265  {
266  IUUpdateSwitch(&LEDSP, states, names, n);
267  bool rc = setLedEnabled(LEDS[LED_ON].s == ISS_ON);
268  LEDSP.s = rc ? IPS_OK : IPS_ALERT;
269  IDSetSwitch(&LEDSP, nullptr);
270  return true;
271  }
272  }
273  return INDI::Focuser::ISNewSwitch(dev, name, states, names, n);
274 }
275 
276 bool PegasusFocusCube::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
277 {
278  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
279  {
280  // MaxSpeed
281  if (strcmp(name, MaxSpeedNP.name) == 0)
282  {
283  IUUpdateNumber(&MaxSpeedNP, values, names, n);
284  bool rc = setMaxSpeed(MaxSpeedN[0].value);
285  MaxSpeedNP.s = rc ? IPS_OK : IPS_ALERT;
286  IDSetNumber(&MaxSpeedNP, nullptr);
287  return true;
288  }
289 
290  }
291 
292  return INDI::Focuser::ISNewNumber(dev, name, values, names, n);
293 }
294 
295 void PegasusFocusCube::ignoreResponse()
296 {
297  int nbytes_read = 0;
298  char res[64];
299  tty_read_section(PortFD, res, 0xA, DMFC_TIMEOUT, &nbytes_read);
300 }
301 
302 bool PegasusFocusCube::updateFocusParams()
303 {
304  int nbytes_written = 0, nbytes_read = 0, rc = -1;
305  char errstr[MAXRBUF];
306  char cmd[3] = {0};
307  char res[64];
308  cmd[0] = 'A';
309  cmd[1] = 0xA;
310 
311  LOGF_DEBUG("CMD <%#02X>", cmd[0]);
312 
313  tcflush(PortFD, TCIOFLUSH);
314 
315  if ((rc = tty_write(PortFD, cmd, 2, &nbytes_written)) != TTY_OK)
316  {
317  tty_error_msg(rc, errstr, MAXRBUF);
318  LOGF_ERROR("GetFocusParams error: %s.", errstr);
319  return false;
320  }
321 
322 
323  if ((rc = tty_read_section(PortFD, res, 0xA, DMFC_TIMEOUT, &nbytes_read)) != TTY_OK)
324  {
325  tty_error_msg(rc, errstr, MAXRBUF);
326  LOGF_ERROR("GetFocusParams error: %s.", errstr);
327  return false;
328  }
329 
330  res[nbytes_read - 1] = 0;
331 
332  // Check for '\r' at end of string and replace with nullptr (DMFC firmware version 2.8)
333  if( res[nbytes_read - 2] == '\r') res[nbytes_read - 2] = 0;
334 
335  LOGF_DEBUG("RES <%s>", res);
336 
337  tcflush(PortFD, TCIOFLUSH);
338 
339  char *token = std::strtok(res, ":");
340 
341  // #1 Status
342  if (token == nullptr || (strstr(token, "OK_FC") == nullptr))
343  {
344  LOGF_ERROR("Invalid status response. %s", res);
345  return false;
346  }
347 
348  // #2 Version
349  token = std::strtok(nullptr, ":");
350 
351  if (token == nullptr)
352  {
353  LOG_ERROR("Invalid version response.");
354  return false;
355  }
356 
357  if (FirmwareVersionT[0].text == nullptr || strcmp(FirmwareVersionT[0].text, token))
358  {
359  IUSaveText(&FirmwareVersionT[0], token);
360  FirmwareVersionTP.s = IPS_OK;
361  IDSetText(&FirmwareVersionTP, nullptr);
362  }
363 
364  // #3 Motor Type
365  token = std::strtok(nullptr, ":");
366 
367  // #4 Temperature
368  token = std::strtok(nullptr, ":");
369 
370  if (token == nullptr)
371  {
372  LOG_ERROR("Invalid temperature response.");
373  return false;
374  }
375 
376  double temperature = atof(token);
377  if (temperature == -127)
378  {
379  TemperatureNP.s = IPS_ALERT;
380  IDSetNumber(&TemperatureNP, nullptr);
381  }
382  else
383  {
384  if (fabs(temperature - TemperatureN[0].value) > TEMPERATURE_THRESHOLD)
385  {
386  TemperatureN[0].value = temperature;
387  TemperatureNP.s = IPS_OK;
388  IDSetNumber(&TemperatureNP, nullptr);
389  }
390  }
391 
392  // #5 Position
393  token = std::strtok(nullptr, ":");
394 
395  if (token == nullptr)
396  {
397  LOG_ERROR("Invalid position response.");
398  return false;
399  }
400 
401  currentPosition = atoi(token);
402  if (currentPosition != FocusAbsPosN[0].value)
403  {
404  FocusAbsPosN[0].value = currentPosition;
405  IDSetNumber(&FocusAbsPosNP, nullptr);
406  }
407 
408  // #6 Moving Status
409  token = std::strtok(nullptr, ":");
410 
411  if (token == nullptr)
412  {
413  LOG_ERROR("Invalid moving status response.");
414  return false;
415  }
416 
417  isMoving = (token[0] == '1');
418 
419  // #7 LED Status
420  token = std::strtok(nullptr, ":");
421 
422  if (token == nullptr)
423  {
424  LOG_ERROR("Invalid LED response.");
425  return false;
426  }
427 
428  int ledStatus = atoi(token);
429  if (ledStatus >= 0 && ledStatus <= 1)
430  {
431  IUResetSwitch(&LEDSP);
432  LEDS[ledStatus].s = ISS_ON;
433  LEDSP.s = IPS_OK;
434  IDSetSwitch(&LEDSP, nullptr);
435  }
436 
437  // #8 Reverse Status
438  token = std::strtok(nullptr, ":");
439 
440  if (token == nullptr)
441  {
442  LOG_ERROR("Invalid reverse response.");
443  return false;
444  }
445 
446  int reverseStatus = atoi(token);
447  if (reverseStatus >= 0 && reverseStatus <= 1)
448  {
450  FocusReverseS[INDI_ENABLED].s = (reverseStatus == 1) ? ISS_ON : ISS_OFF;
451  FocusReverseS[INDI_DISABLED].s = (reverseStatus == 0) ? ISS_ON : ISS_OFF;
453  IDSetSwitch(&FocusReverseSP, nullptr);
454  }
455 
456  // #9 Encoder status
457  token = std::strtok(nullptr, ":");
458 
459  if (token == nullptr)
460  {
461  LOG_ERROR("Invalid encoder response.");
462  return false;
463  }
464 
465  int encoderStatus = atoi(token);
466  if (encoderStatus >= 0 && encoderStatus <= 1)
467  {
468  IUResetSwitch(&EncoderSP);
469  EncoderS[encoderStatus].s = ISS_ON;
470  EncoderSP.s = IPS_OK;
471  IDSetSwitch(&EncoderSP, nullptr);
472  }
473 
474  // #10 Backlash
475  token = std::strtok(nullptr, ":");
476 
477  if (token == nullptr)
478  {
479  LOG_ERROR("Invalid encoder response.");
480  return false;
481  }
482 
483  int backlash = atoi(token);
484  // If backlash is zero then compensation is disabled
485  if (backlash == 0 && FocusBacklashS[INDI_ENABLED].s == ISS_ON)
486  {
487  LOG_WARN("Backlash value is zero, disabling backlash switch...");
488 
492  IDSetSwitch(&FocusBacklashSP, nullptr);
493  }
494  else if (backlash > 0 && (FocusBacklashS[INDI_DISABLED].s == ISS_ON || backlash != FocusBacklashN[0].value))
495  {
496  if (backlash != FocusBacklashN[0].value)
497  {
498  FocusBacklashN[0].value = backlash;
500  IDSetNumber(&FocusBacklashNP, nullptr);
501  }
502 
504  {
508  IDSetSwitch(&FocusBacklashSP, nullptr);
509  }
510  }
511 
512  return true;
513 }
514 
515 bool PegasusFocusCube::setMaxSpeed(uint16_t speed)
516 {
517  int nbytes_written = 0, rc = -1;
518  char cmd[16] = {0};
519 
520  snprintf(cmd, 16, "S:%d", speed);
521  cmd[strlen(cmd)] = 0xA;
522 
523  LOGF_DEBUG("CMD <%s>", cmd);
524 
525  tcflush(PortFD, TCIOFLUSH);
526 
527  // Set Speed
528  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
529  {
530  char errstr[MAXRBUF];
531  tty_error_msg(rc, errstr, MAXRBUF);
532  LOGF_ERROR("setMaxSpeed error: %s.", errstr);
533  return false;
534  }
535 
536  this->ignoreResponse();
537  return true;
538 }
539 
541 {
542  int nbytes_written = 0, rc = -1;
543  char cmd[16] = {0};
544 
545  snprintf(cmd, 16, "N:%d", enabled ? 1 : 0);
546  cmd[strlen(cmd)] = 0xA;
547 
548  LOGF_DEBUG("CMD <%s>", cmd);
549 
550  tcflush(PortFD, TCIOFLUSH);
551 
552  // Reverse
553  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
554  {
555  char errstr[MAXRBUF];
556  tty_error_msg(rc, errstr, MAXRBUF);
557  LOGF_ERROR("Reverse error: %s.", errstr);
558  return false;
559  }
560 
561  this->ignoreResponse();
562 
563  return true;
564 }
565 
566 bool PegasusFocusCube::setLedEnabled(bool enable)
567 {
568  int nbytes_written = 0, rc = -1;
569  char cmd[16] = {0};
570 
571  snprintf(cmd, 16, "L:%d", enable ? 2 : 1);
572  cmd[strlen(cmd)] = 0xA;
573 
574  LOGF_DEBUG("CMD <%s>", cmd);
575 
576  tcflush(PortFD, TCIOFLUSH);
577 
578  // Led
579  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
580  {
581  char errstr[MAXRBUF];
582  tty_error_msg(rc, errstr, MAXRBUF);
583  LOGF_ERROR("Led error: %s.", errstr);
584  return false;
585  }
586 
587  this->ignoreResponse();
588  return true;
589 }
590 
591 bool PegasusFocusCube::setEncodersEnabled(bool enable)
592 {
593  int nbytes_written = 0, rc = -1;
594  char cmd[16] = {0};
595 
596  snprintf(cmd, 16, "E:%d", enable ? 0 : 1);
597  cmd[strlen(cmd)] = 0xA;
598 
599  LOGF_DEBUG("CMD <%s>", cmd);
600 
601  tcflush(PortFD, TCIOFLUSH);
602 
603  // Encoders
604  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
605  {
606  char errstr[MAXRBUF];
607  tty_error_msg(rc, errstr, MAXRBUF);
608  LOGF_ERROR("Encoder error: %s.", errstr);
609  return false;
610  }
611 
612  this->ignoreResponse();
613  return true;
614 }
615 
617 {
618  int nbytes_written = 0, rc = -1;
619  char cmd[16] = {0};
620 
621  snprintf(cmd, 16, "C:%d", steps);
622  cmd[strlen(cmd)] = 0xA;
623 
624  LOGF_DEBUG("CMD <%s>", cmd);
625 
626  tcflush(PortFD, TCIOFLUSH);
627 
628  // Backlash
629  if ((rc = tty_write(PortFD, cmd, strlen(cmd), &nbytes_written)) != TTY_OK)
630  {
631  char errstr[MAXRBUF];
632  tty_error_msg(rc, errstr, MAXRBUF);
633  LOGF_ERROR("Backlash error: %s.", errstr);
634  return false;
635  }
636 
637  this->ignoreResponse();
638  return true;
639 }
640 
642 {
643  if (!enabled)
644  return SetFocuserBacklash(0);
645 
646  return SetFocuserBacklash(FocusBacklashN[0].value > 0 ? FocusBacklashN[0].value : 1);
647 }
648 
649 
651 {
652  targetPosition = targetTicks;
653 
654  bool rc = move(targetPosition);
655 
656  if (!rc)
657  return IPS_ALERT;
658 
660 
661  return IPS_BUSY;
662 }
663 
665 {
666  double newPosition = 0;
667  bool rc = false;
668 
669  if (dir == FOCUS_INWARD)
670  newPosition = FocusAbsPosN[0].value - ticks;
671  else
672  newPosition = FocusAbsPosN[0].value + ticks;
673 
674  rc = move(newPosition);
675 
676  if (!rc)
677  return IPS_ALERT;
678 
679  FocusRelPosN[0].value = ticks;
681 
682  return IPS_BUSY;
683 }
684 
686 {
687  if (!isConnected())
688  {
690  return;
691  }
692 
693  bool rc = updateFocusParams();
694 
695  if (rc)
696  {
698  {
699  if (isMoving == false)
700  {
703  IDSetNumber(&FocusAbsPosNP, nullptr);
704  IDSetNumber(&FocusRelPosNP, nullptr);
705  LOG_INFO("Focuser reached requested position.");
706  }
707  }
708  }
709 
711 }
712 
714 {
715  int nbytes_written;
716  char cmd[2] = { 'H', 0xA };
717 
718  if (tty_write(PortFD, cmd, 2, &nbytes_written) == TTY_OK)
719  {
722  IDSetNumber(&FocusAbsPosNP, nullptr);
723  IDSetNumber(&FocusRelPosNP, nullptr);
724  this->ignoreResponse();
725  return true;
726  }
727  else
728  return false;
729 }
730 
732 {
734  IUSaveConfigSwitch(fp, &EncoderSP);
735  IUSaveConfigNumber(fp, &MaxSpeedNP);
736  IUSaveConfigSwitch(fp, &LEDSP);
737 
738  return true;
739 }
INDI::FocuserInterface::FOCUSER_CAN_ABS_MOVE
@ FOCUSER_CAN_ABS_MOVE
Definition: indifocuserinterface.h:74
IP_RO
@ IP_RO
Definition: indiapi.h:183
INDI::FocuserInterface::FOCUSER_CAN_SYNC
@ FOCUSER_CAN_SYNC
Definition: indifocuserinterface.h:78
INDI::FocuserInterface::FOCUSER_CAN_REL_MOVE
@ FOCUSER_CAN_REL_MOVE
Definition: indifocuserinterface.h:75
INDI::FocuserInterface::FocusAbsPosNP
INumberVectorProperty FocusAbsPosNP
Definition: indifocuserinterface.h:282
cmd
__u8 cmd[4]
Definition: pwc-ioctl.h:4
PegasusFocusCube::updateProperties
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: pegasus_focuscube.cpp:113
IPState
IPState
Property state.
Definition: indiapi.h:158
PegasusFocusCube
Definition: pegasus_focuscube.h:28
INDI::FocuserInterface::FocusBacklashN
INumber FocusBacklashN[1]
Definition: indifocuserinterface.h:311
LOGF_ERROR
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
IPS_OK
@ IPS_OK
Definition: indiapi.h:161
_INumberVectorProperty::s
IPState s
Definition: indiapi.h:332
PegasusFocusCube::SetFocuserBacklashEnabled
virtual bool SetFocuserBacklashEnabled(bool enabled) override
SetFocuserBacklashEnabled Enables or disables the focuser backlash compensation.
Definition: pegasus_focuscube.cpp:641
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
indicom.h
Implementations for common driver routines.
IDSetText
void IDSetText(const ITextVectorProperty *t, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing text vector property.
IPS_ALERT
@ IPS_ALERT
Definition: indiapi.h:163
IUFillNumber
void IUFillNumber(INumber *np, const char *name, const char *label, const char *format, double min, double max, double step, double value)
Assign attributes for a number property. The number's auxiliary elements will be set to NULL.
Definition: indidriver.c:348
INDI::DefaultDevice::defineProperty
void defineProperty(INumberVectorProperty *property)
Definition: defaultdevice.cpp:997
MAIN_CONTROL_TAB
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
Definition: defaultdevice.cpp:34
IUFillTextVector
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: indidriver.c:477
INDI::DefaultDevice::setDefaultPollingPeriod
void setDefaultPollingPeriod(uint32_t msec)
setDefaultPollingPeriod Change the default polling period to call TimerHit() function in the driver.
Definition: defaultdevice.cpp:1157
INDI::Focuser::saveConfigItems
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Focuser Presets in the configuration file
Definition: indifocuser.cpp:241
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
PegasusFocusCube::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: pegasus_focuscube.cpp:248
INDI::Focuser::serialConnection
Connection::Serial * serialConnection
Definition: indifocuser.h:113
tty_read_section
int tty_read_section(int fd, char *buf, char stop_char, int timeout, int *nbytes_read)
read buffer from terminal with a delimiter
Definition: indicom.c:557
INDI::FocuserInterface::FOCUSER_CAN_ABORT
@ FOCUSER_CAN_ABORT
Definition: indifocuserinterface.h:76
Connection::Serial::B_19200
@ B_19200
Definition: connectionserial.h:82
IUSaveConfigNumber
void IUSaveConfigNumber(FILE *fp, const INumberVectorProperty *nvp)
Add a number vector property value to the configuration file.
Definition: indicom.c:1455
IUFillText
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: indidriver.c:369
PegasusFocusCube::PegasusFocusCube
PegasusFocusCube()
Definition: pegasus_focuscube.cpp:42
INDI::FocuserInterface::FocusReverseSP
ISwitchVectorProperty FocusReverseSP
Definition: indifocuserinterface.h:302
PegasusFocusCube::Handshake
virtual bool Handshake() override
perform handshake with device to check communication
Definition: pegasus_focuscube.cpp:137
PegasusFocusCube::getDefaultName
const char * getDefaultName() override
Definition: pegasus_focuscube.cpp:150
LOG_INFO
#define LOG_INFO(txt)
Definition: indilogger.h:74
MAXRBUF
#define MAXRBUF
Definition: indidriver.c:52
IUResetSwitch
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indicom.c:1442
tty_error_msg
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1156
DMFC_TIMEOUT
#define DMFC_TIMEOUT
Definition: pegasus_focuscube.cpp:36
INDI::DefaultDevice::getCurrentPollingPeriod
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
Definition: defaultdevice.cpp:1139
INDI::FocuserInterface::FocusBacklashSP
ISwitchVectorProperty FocusBacklashSP
Definition: indifocuserinterface.h:306
LOGF_DEBUG
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
Connection::Serial::setDefaultBaudRate
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
Definition: connectionserial.cpp:381
INDI::DefaultDevice::SetTimer
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
Definition: defaultdevice.cpp:865
INDI::Focuser::PortFD
int PortFD
Definition: indifocuser.h:116
PegasusFocusCube::SyncFocuser
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
Definition: pegasus_focuscube.cpp:200
tty_write
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:415
INDI::FocuserInterface::FOCUS_INWARD
@ FOCUS_INWARD
Definition: indifocuserinterface.h:68
IUFillSwitchVector
void IUFillSwitchVector(ISwitchVectorProperty *svp, ISwitch *sp, int nsp, const char *dev, const char *name, const char *label, const char *group, IPerm p, ISRule r, double timeout, IPState s)
Assign attributes for a switch vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:412
INDI::BaseDevice::INDI_ENABLED
@ INDI_ENABLED
Definition: basedevice.h:64
pegasus_focuscube.h
IUFillNumberVector
void IUFillNumberVector(INumberVectorProperty *nvp, INumber *np, int nnp, const char *dev, const char *name, const char *label, const char *group, IPerm p, double timeout, IPState s)
Assign attributes for a number vector property. The vector's auxiliary elements will be set to NULL.
Definition: indidriver.c:455
IPS_BUSY
@ IPS_BUSY
Definition: indiapi.h:162
ISR_1OFMANY
@ ISR_1OFMANY
Definition: indiapi.h:172
connectionserial.h
IPS_IDLE
@ IPS_IDLE
Definition: indiapi.h:160
INDI::FocuserInterface::FocusRelPosN
INumber FocusRelPosN[1]
Definition: indifocuserinterface.h:287
INDI::FocuserInterface::FOCUSER_CAN_REVERSE
@ FOCUSER_CAN_REVERSE
Definition: indifocuserinterface.h:77
INDI::Focuser::updateProperties
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: indifocuser.cpp:120
_INumberVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:322
IUUpdateSwitch
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:171
INDI::FocuserInterface::FocusRelPosNP
INumberVectorProperty FocusRelPosNP
Definition: indifocuserinterface.h:286
_ITextVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:249
INDI::BaseDevice::isConnected
bool isConnected() const
Definition: basedevice.cpp:518
LOGF_INFO
#define LOGF_INFO(fmt,...)
Definition: indilogger.h:82
INDI::FocuserInterface::FocusBacklashS
ISwitch FocusBacklashS[2]
Definition: indifocuserinterface.h:307
FOCUS_SETTINGS_TAB
#define FOCUS_SETTINGS_TAB
Definition: pegasus_focuscube.cpp:37
LOG_ERROR
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
Definition: indilogger.h:72
INDI::FocuserInterface::SetCapability
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
Definition: indifocuserinterface.h:95
PegasusFocusCube::SetFocuserBacklash
virtual bool SetFocuserBacklash(int32_t steps) override
SetFocuserBacklash Set the focuser backlash compensation value.
Definition: pegasus_focuscube.cpp:616
IUSaveText
void IUSaveText(IText *tp, const char *newtext)
Function to reliably save new text in a IText.
Definition: indicom.c:1449
name
const char * name
Definition: indiserver.c:116
TEMPERATURE_THRESHOLD
#define TEMPERATURE_THRESHOLD
Definition: pegasus_focuscube.cpp:38
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
INDI::FocuserInterface::FocusReverseS
ISwitch FocusReverseS[2]
Definition: indifocuserinterface.h:303
INDI::FocuserInterface::FocusMaxPosN
INumber FocusMaxPosN[1]
Definition: indifocuserinterface.h:291
_ITextVectorProperty::s
IPState s
Definition: indiapi.h:259
IUUpdateNumber
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:225
PegasusFocusCube::AbortFocuser
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
Definition: pegasus_focuscube.cpp:713
INDI::FocuserInterface::FocusDirection
FocusDirection
Definition: indifocuserinterface.h:66
IP_RW
@ IP_RW
Definition: indiapi.h:185
LOG_WARN
#define LOG_WARN(txt)
Definition: indilogger.h:73
PegasusFocusCube::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: pegasus_focuscube.cpp:276
INDI::FocuserInterface::FOCUSER_HAS_BACKLASH
@ FOCUSER_HAS_BACKLASH
Definition: indifocuserinterface.h:80
ISState
ISState
Switch state.
Definition: indiapi.h:148
PegasusFocusCube::MoveRelFocuser
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
Definition: pegasus_focuscube.cpp:664
PegasusFocusCube::ReverseFocuser
virtual bool ReverseFocuser(bool enabled) override
ReverseFocuser Reverse focuser motion direction.
Definition: pegasus_focuscube.cpp:540
INDI::DefaultDevice::addDebugControl
void addDebugControl()
Add Debug control to the driver.
Definition: defaultdevice.cpp:639
IUSaveConfigSwitch
void IUSaveConfigSwitch(FILE *fp, const ISwitchVectorProperty *svp)
Add a switch vector property value to the configuration file.
Definition: indicom.c:1465
INDI::Focuser::initProperties
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: indifocuser.cpp:58
PegasusFocusCube::TimerHit
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
Definition: pegasus_focuscube.cpp:685
TTY_OK
@ TTY_OK
Definition: indicom.h:94
INDI::FocuserInterface::FocusBacklashNP
INumberVectorProperty FocusBacklashNP
Definition: indifocuserinterface.h:310
INDI::DefaultDevice::deleteProperty
virtual bool deleteProperty(const char *propertyName)
Delete a property and unregister it. It will also be deleted from all clients.
Definition: defaultdevice.cpp:965
INDI::Focuser::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: indifocuser.cpp:168
PegasusFocusCube::MoveAbsFocuser
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
Definition: pegasus_focuscube.cpp:650
INDI::FocuserInterface::FocusAbsPosN
INumber FocusAbsPosN[1]
Definition: indifocuserinterface.h:283
IDSetNumber
void void void IDSetNumber(const INumberVectorProperty *n, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing number vector property.
IDSetSwitch
void void void void void IDSetSwitch(const ISwitchVectorProperty *s, const char *msg,...) ATTRIBUTE_FORMAT_PRINTF(2
Tell client to update an existing switch vector property.
IUFillSwitch
void IUFillSwitch(ISwitch *sp, const char *name, const char *label, ISState s)
Assign attributes for a switch property. The switch's auxiliary elements will be set to NULL.
Definition: indidriver.c:320
PegasusFocusCube::initProperties
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: pegasus_focuscube.cpp:53
INDI::Focuser::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: indifocuser.cpp:145
INDI::BaseDevice::INDI_DISABLED
@ INDI_DISABLED
Definition: basedevice.h:65
_ISwitchVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:370
PegasusFocusCube::saveConfigItems
virtual bool saveConfigItems(FILE *fp) override
saveConfigItems Saves the Device Port and Focuser Presets in the configuration file
Definition: pegasus_focuscube.cpp:731
ISS_ON
@ ISS_ON
Definition: indiapi.h:151