Instrument Neutral Distributed Interface INDI  2.0.2
microtouch.cpp
Go to the documentation of this file.
1 /*
2  Microtouch Focuser
3  Copyright (C) 2016 Marco Peters (mpeters@rzpeters.de)
4  Copyright (C) 2013 Jasem Mutlaq (mutlaqja@ikarustech.com)
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Lesser General Public
8  License as published by the Free Software Foundation; either
9  version 2.1 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public
17  License along with this library; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 
20 */
21 
22 #include "microtouch.h"
23 
24 #include "indicom.h"
26 
27 #include <cmath>
28 #include <memory>
29 #include <cstring>
30 #include <termios.h>
31 #include <unistd.h>
32 
33 #define MICROTOUCH_TIMEOUT 3
34 
35 static std::unique_ptr<Microtouch> microTouch(new Microtouch());
36 
38 {
39  // Can move in Absolute & Relative motions, can AbortFocuser motion, and has variable speed.
42 }
43 
45 {
47 
48  FocusSpeedN[0].min = 1;
49  FocusSpeedN[0].max = 5;
50  FocusSpeedN[0].value = 1;
51 
52  /* Step Mode */
53  IUFillSwitch(&MotorSpeedS[0], "Normal", "", ISS_ON);
54  IUFillSwitch(&MotorSpeedS[1], "Fast", "", ISS_OFF);
55  IUFillSwitchVector(&MotorSpeedSP, MotorSpeedS, 2, getDeviceName(), "Motor Speed", "", OPTIONS_TAB, IP_RW,
56  ISR_1OFMANY, 0, IPS_IDLE);
57 
58  /* Focuser temperature */
59  IUFillNumber(&TemperatureN[0], "TEMPERATURE", "Celsius", "%6.2f", -50, 70., 0., 0.);
60  IUFillNumberVector(&TemperatureNP, TemperatureN, 1, getDeviceName(), "FOCUS_TEMPERATURE", "Temperature",
62 
63  // Maximum Travel
64  // IUFillNumber(&MaxTravelN[0], "MAXTRAVEL", "Maximum travel", "%6.0f", 1., 60000., 0., 10000.);
65  // IUFillNumberVector(&MaxTravelNP, MaxTravelN, 1, getDeviceName(), "FOCUS_MAXTRAVEL", "Max. travel", OPTIONS_TAB,
66  // IP_RW, 0, IPS_IDLE);
67 
68  // Temperature Settings
69  IUFillNumber(&TemperatureSettingN[0], "Calibration", "", "%6.2f", -20, 20, 0.01, 0);
70  IUFillNumber(&TemperatureSettingN[1], "Coefficient", "", "%6.2f", -20, 20, 0.01, 0);
71  IUFillNumberVector(&TemperatureSettingNP, TemperatureSettingN, 2, getDeviceName(), "Temperature Settings", "",
73 
74  // Compensate for temperature
75  IUFillSwitch(&TemperatureCompensateS[0], "Enable", "", ISS_OFF);
76  IUFillSwitch(&TemperatureCompensateS[1], "Disable", "", ISS_ON);
77  IUFillSwitchVector(&TemperatureCompensateSP, TemperatureCompensateS, 2, getDeviceName(), "Temperature Compensate",
79 
80  // Reset
81  // IUFillSwitch(&ResetS[0], "Zero", "", ISS_OFF);
82  // IUFillSwitchVector(&ResetSP, ResetS, 1, getDeviceName(), "Reset", "", MAIN_CONTROL_TAB, IP_RW, ISR_1OFMANY, 0,
83  // IPS_IDLE);
84 
85  // IUFillNumber(&ResetToPosN[0], "Position", "", "%6.0f", 0, 60000, 1, 0);
86  // IUFillNumberVector(&ResetToPosNP, ResetToPosN, 1, getDeviceName(), "Reset to Position", "", MAIN_CONTROL_TAB, IP_RW,
87  // 0, IPS_IDLE);
88 
89  /* Relative and absolute movement */
90  FocusRelPosN[0].min = 0.;
91  FocusRelPosN[0].max = 30000.;
92  FocusRelPosN[0].value = 0;
93  FocusRelPosN[0].step = 1000.;
94 
95  FocusAbsPosN[0].min = 0.;
96  FocusAbsPosN[0].max = 60000.;
97  FocusAbsPosN[0].value = 0;
98  FocusAbsPosN[0].step = 1000.;
99 
100  addDebugControl();
102 
103  return true;
104 }
105 
107 {
109 
110  if (isConnected())
111  {
112  defineProperty(&TemperatureNP);
113  //defineProperty(&MaxTravelNP);
114  defineProperty(&MotorSpeedSP);
115  defineProperty(&TemperatureSettingNP);
116  defineProperty(&TemperatureCompensateSP);
117  // defineProperty(&ResetSP);
118  // defineProperty(&ResetToPosNP);
119 
120  GetFocusParams();
121 
122  LOG_INFO("Microtouch parameters updated, focuser ready for use.");
123  }
124  else
125  {
126  deleteProperty(TemperatureNP.name);
127  // deleteProperty(MaxTravelNP.name);
128  deleteProperty(MotorSpeedSP.name);
129  deleteProperty(TemperatureSettingNP.name);
130  deleteProperty(TemperatureCompensateSP.name);
131  // deleteProperty(ResetSP.name);
132  // deleteProperty(ResetToPosNP.name);
133  }
134 
135  return true;
136 }
137 
139 {
140  tcflush(PortFD, TCIOFLUSH);
141 
142  if (Ack())
143  {
144  LOG_INFO("Microtouch is online. Getting focus parameters...");
145  return true;
146  }
147 
148  LOG_INFO("Error retrieving data from Microtouch, please ensure Microtouch controller is "
149  "powered and the port is correct.");
150  return false;
151 }
152 
154 {
155  return "Microtouch";
156 }
157 
158 bool Microtouch::Ack()
159 {
160  return updatePosition();
161 }
162 
163 bool Microtouch::updateTemperature()
164 {
165  char resp[7];
166 
167  short int ttemp = 0, tcoeff = 0;
168  double raw_temp = 0, raw_coeff = 0, tcomp_coeff = 0;
169 
170  if (!(WriteCmdGetResponse(CMD_GET_TEMPERATURE, resp, 6)))
171  return false;
172  ttemp = ((short int)resp[1] << 8 | ((short int)resp[2] & 0xff));
173  raw_temp = ((double)ttemp) / 16;
174 
175  tcoeff = ((short int)resp[5] << 8 | ((short int)resp[4] & 0xff));
176  raw_coeff = ((double)tcoeff) / 16;
177 
178  tcomp_coeff = (double)(((double)WriteCmdGetInt(CMD_GET_COEFF)) / 128);
179 
180  LOGF_DEBUG("updateTemperature : RESP (%02X %02X %02X %02X %02X %02X)", resp[0], resp[1],
181  resp[2], resp[3], resp[4], resp[5]);
182 
183  TemperatureN[0].value = raw_temp + raw_coeff;
184  TemperatureSettingN[0].value = raw_coeff;
185  TemperatureSettingN[1].value = tcomp_coeff;
186 
187  return true;
188 }
189 
190 bool Microtouch::updatePosition()
191 {
192  char read[3] = {0};
193 
194  if (WriteCmdGetResponse(CMD_GET_POSITION, read, 3))
195  {
196  FocusAbsPosN[0].value = static_cast<double>(static_cast<uint8_t>(read[2]) << 8 | static_cast<uint8_t>(read[1]));
197  return true;
198  }
199 
200  return false;
201 }
202 
203 bool Microtouch::updateSpeed()
204 {
205  // TODO
206  /* int nbytes_written=0, nbytes_read=0, rc=-1;
207  char errstr[MAXRBUF];
208  char resp[3];
209  short speed;
210 
211  tcflush(PortFD, TCIOFLUSH);
212 
213  if ( (rc = tty_write(PortFD, ":GD#", 4, &nbytes_written)) != TTY_OK)
214  {
215  tty_error_msg(rc, errstr, MAXRBUF);
216  LOGF_ERROR("updateSpeed error: %s.", errstr);
217  return false;
218  }
219 
220  if ( (rc = tty_read(PortFD, resp, 3, MICROTOUCH_TIMEOUT, &nbytes_read)) != TTY_OK)
221  {
222  tty_error_msg(rc, errstr, MAXRBUF);
223  LOGF_ERROR("updateSpeed error: %s.", errstr);
224  return false;
225  }
226 
227  rc = sscanf(resp, "%hX#", &speed);
228 
229  if (rc > 0)
230  {
231  int focus_speed=-1;
232  while (speed > 0)
233  {
234  speed >>= 1;
235  focus_speed++;
236  }
237 
238  currentSpeed = focus_speed;
239  FocusSpeedN[0].value = focus_speed;
240  }
241  else
242  {
243  LOGF_ERROR("Unknown error: focuser speed value (%s)", resp);
244  return false;
245  }
246  */
247  return true;
248 }
249 
250 bool Microtouch::updateMotorSpeed()
251 {
252  IUResetSwitch(&MotorSpeedSP);
253 
254  LOGF_DEBUG("MotorSpeed: %d.", WriteCmdGetByte(CMD_GET_MOTOR_SPEED));
255 
256  if (WriteCmdGetByte(CMD_GET_MOTOR_SPEED) == 8)
257  MotorSpeedS[0].s = ISS_ON;
258  else if (WriteCmdGetByte(CMD_GET_MOTOR_SPEED) == 4)
259  MotorSpeedS[1].s = ISS_ON;
260  else
261  {
262  LOGF_ERROR("Unknown error: updateMotorSpeed (%s)", WriteCmdGetByte(CMD_GET_MOTOR_SPEED));
263  return false;
264  }
265 
266  return true;
267 }
268 
269 bool Microtouch::isMoving()
270 {
271  return (WriteCmdGetByte(CMD_IS_MOVING) > 0);
272 }
273 
274 bool Microtouch::setTemperatureCalibration(double calibration)
275 {
276  return WriteCmdSetShortInt(CMD_SET_TEMP_OFFSET, (short int)(calibration * 16));
277 }
278 
279 bool Microtouch::setTemperatureCoefficient(double coefficient)
280 {
281  int tcoeff = (int)(coefficient * 128);
282 
283  LOGF_DEBUG("Setting new temperaturecoefficient : %d.", tcoeff);
284 
285  if (!(WriteCmdSetInt(CMD_SET_COEFF, tcoeff)))
286  {
287  LOG_ERROR("setTemperatureCoefficient error: Setting temperaturecoefficient failed.");
288  return false;
289  }
290  return true;
291 }
292 
293 //bool Microtouch::reset()
294 //{
295 // WriteCmdSetIntAsDigits(CMD_RESET_POSITION, 0x00);
296 // return true;
297 //}
298 
299 //bool Microtouch::reset(double pos)
300 //{
301 // WriteCmdSetIntAsDigits(CMD_RESET_POSITION, (int)pos);
302 // return true;
303 //}
304 
305 bool Microtouch::SyncFocuser(uint32_t ticks)
306 {
307  WriteCmdSetIntAsDigits(CMD_RESET_POSITION, ticks);
308  return true;
309 }
310 
311 bool Microtouch::MoveFocuser(unsigned int position)
312 {
313  LOGF_DEBUG("MoveFocuser to Position: %d", position);
314 
315  if (position < FocusAbsPosN[0].min || position > FocusAbsPosN[0].max)
316  {
317  LOGF_ERROR("Requested position value out of bound: %d", position);
318  return false;
319  }
320  return WriteCmdSetIntAsDigits(CMD_UPDATE_POSITION, position);
321 }
322 
323 bool Microtouch::setMotorSpeed(char speed)
324 {
325  if (speed == FOCUS_MOTORSPEED_NORMAL)
326  WriteCmdSetByte(CMD_SET_MOTOR_SPEED, 8);
327  else
328  WriteCmdSetByte(CMD_SET_MOTOR_SPEED, 4);
329 
330  return true;
331 }
332 
333 bool Microtouch::setSpeed(unsigned short speed)
334 {
335  INDI_UNUSED(speed);
336  /* int nbytes_written=0, rc=-1;
337  char errstr[MAXRBUF];
338  char cmd[7];
339 
340  int hex_value=1;
341 
342  hex_value <<= speed;
343 
344  snprintf(cmd, 7, ":SD%02X#", hex_value);
345 
346  if ( (rc = tty_write(PortFD, cmd, 6, &nbytes_written)) != TTY_OK)
347  {
348  tty_error_msg(rc, errstr, MAXRBUF);
349  LOGF_ERROR("setSpeed error: %s.", errstr);
350  return false;
351  }
352  */
353  return true;
354 }
355 
356 bool Microtouch::setTemperatureCompensation(bool enable)
357 {
358  if (enable)
359  {
360  if (WriteCmd(CMD_TEMPCOMP_ON))
361  return true;
362  else
363  return false;
364  }
365  else if (WriteCmd(CMD_TEMPCOMP_OFF))
366  return true;
367 
368  return false;
369 }
370 
371 bool Microtouch::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
372 {
373  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
374  {
375  // Focus Motor Speed
376  if (strcmp(MotorSpeedSP.name, name) == 0)
377  {
378  bool rc = false;
379  int current_mode = IUFindOnSwitchIndex(&MotorSpeedSP);
380 
381  IUUpdateSwitch(&MotorSpeedSP, states, names, n);
382 
383  int target_mode = IUFindOnSwitchIndex(&MotorSpeedSP);
384 
385  if (current_mode == target_mode)
386  {
387  MotorSpeedSP.s = IPS_OK;
388  IDSetSwitch(&MotorSpeedSP, nullptr);
389  }
390 
391  if (target_mode == 0)
392  rc = setMotorSpeed(FOCUS_MOTORSPEED_NORMAL);
393  else
394  rc = setMotorSpeed(FOCUS_MOTORSPEED_FAST);
395 
396  if (!rc)
397  {
398  IUResetSwitch(&MotorSpeedSP);
399  MotorSpeedS[current_mode].s = ISS_ON;
400  MotorSpeedSP.s = IPS_ALERT;
401  IDSetSwitch(&MotorSpeedSP, nullptr);
402  return false;
403  }
404 
405  MotorSpeedSP.s = IPS_OK;
406  IDSetSwitch(&MotorSpeedSP, nullptr);
407  return true;
408  }
409 
410  if (strcmp(TemperatureCompensateSP.name, name) == 0)
411  {
412  int last_index = IUFindOnSwitchIndex(&TemperatureCompensateSP);
413  IUUpdateSwitch(&TemperatureCompensateSP, states, names, n);
414 
415  bool rc = setTemperatureCompensation((TemperatureCompensateS[0].s == ISS_ON));
416 
417  if (!rc)
418  {
419  TemperatureCompensateSP.s = IPS_ALERT;
420  IUResetSwitch(&TemperatureCompensateSP);
421  TemperatureCompensateS[last_index].s = ISS_ON;
422  IDSetSwitch(&TemperatureCompensateSP, nullptr);
423  return false;
424  }
425 
426  TemperatureCompensateSP.s = IPS_OK;
427  IDSetSwitch(&TemperatureCompensateSP, nullptr);
428  return true;
429  }
430 
431  // if (strcmp(ResetSP.name, name) == 0)
432  // {
433  // IUResetSwitch(&ResetSP);
434 
435  // if (reset())
436  // ResetSP.s = IPS_OK;
437  // else
438  // ResetSP.s = IPS_ALERT;
439 
440  // IDSetSwitch(&ResetSP, nullptr);
441  // return true;
442  // }
443  }
444 
445  return INDI::Focuser::ISNewSwitch(dev, name, states, names, n);
446 }
447 
448 bool Microtouch::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
449 {
450  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
451  {
452  // if (strcmp(name, MaxTravelNP.name) == 0)
453  // {
454  // IUUpdateNumber(&MaxTravelNP, values, names, n);
455  // MaxTravelNP.s = IPS_OK;
456  // IDSetNumber(&MaxTravelNP, nullptr);
457  // return true;
458  // }
459 
460  if (strcmp(name, TemperatureSettingNP.name) == 0)
461  {
462  IUUpdateNumber(&TemperatureSettingNP, values, names, n);
463  if (!setTemperatureCalibration(TemperatureSettingN[0].value) ||
464  !setTemperatureCoefficient(TemperatureSettingN[1].value))
465  {
466  TemperatureSettingNP.s = IPS_ALERT;
467  IDSetNumber(&TemperatureSettingNP, nullptr);
468  return false;
469  }
470 
471  TemperatureSettingNP.s = IPS_OK;
472  IDSetNumber(&TemperatureSettingNP, nullptr);
473  }
474 
475  // if (strcmp(name, ResetToPosNP.name) == 0)
476  // {
477  // IUUpdateNumber(&ResetToPosNP, values, names, n);
478  // if (!reset(ResetToPosN[0].value))
479  // {
480  // ResetToPosNP.s = IPS_ALERT;
481  // IDSetNumber(&ResetToPosNP, nullptr);
482  // return false;
483  // }
484 
485  // ResetToPosNP.s = IPS_OK;
486  // IDSetNumber(&ResetToPosNP, nullptr);
487  // }
488  }
489 
490  return INDI::Focuser::ISNewNumber(dev, name, values, names, n);
491 }
492 
493 void Microtouch::GetFocusParams()
494 {
495  if (updatePosition())
496  IDSetNumber(&FocusAbsPosNP, nullptr);
497 
498  if (updateTemperature())
499  {
500  IDSetNumber(&TemperatureNP, nullptr);
501  IDSetNumber(&TemperatureSettingNP, nullptr);
502  }
503 
504  /* if (updateSpeed())
505  IDSetNumber(&FocusSpeedNP, nullptr);
506  */
507  if (updateMotorSpeed())
508  IDSetSwitch(&MotorSpeedSP, nullptr);
509 }
510 
512 {
513  bool rc = false;
514 
515  rc = setSpeed(speed);
516 
517  if (!rc)
518  return false;
519 
520  currentSpeed = speed;
521 
523  IDSetNumber(&FocusSpeedNP, nullptr);
524 
525  return true;
526 }
527 
528 IPState Microtouch::MoveFocuser(FocusDirection dir, int speed, uint16_t duration)
529 {
530  if (speed != (int)currentSpeed)
531  {
532  bool rc = setSpeed(speed);
533 
534  if (!rc)
535  return IPS_ALERT;
536  }
537 
538  gettimeofday(&focusMoveStart, nullptr);
539  focusMoveRequest = duration / 1000.0;
540 
541  if (dir == FOCUS_INWARD)
542  MoveFocuser(0);
543  else
544  MoveFocuser(FocusAbsPosN[0].value + FocusMaxPosN[0].value - 1);
545 
546  if (duration <= getCurrentPollingPeriod())
547  {
548  usleep(duration * 1000);
549  AbortFocuser();
550  return IPS_OK;
551  }
552 
553  return IPS_BUSY;
554 }
555 
556 IPState Microtouch::MoveAbsFocuser(uint32_t targetTicks)
557 {
558  targetPos = targetTicks;
559 
560  bool rc = false;
561 
562  rc = MoveFocuser(targetPos);
563 
564  if (!rc)
565  return IPS_ALERT;
566 
568 
569  return IPS_BUSY;
570 }
571 
573 {
574  double newPosition = 0;
575  bool rc = false;
576 
577  if (dir == FOCUS_INWARD)
578  newPosition = FocusAbsPosN[0].value - ticks;
579  else
580  newPosition = FocusAbsPosN[0].value + ticks;
581 
582  rc = MoveFocuser(newPosition);
583 
584  if (!rc)
585  return IPS_ALERT;
586 
587  FocusRelPosN[0].value = ticks;
589 
590  return IPS_BUSY;
591 }
592 
594 {
595  if (!isConnected())
596  {
597  return;
598  }
599 
600  bool rc = updatePosition();
601 
602  if (rc)
603  {
604  if (fabs(lastPos - FocusAbsPosN[0].value) > 1)
605  {
606  IDSetNumber(&FocusAbsPosNP, nullptr);
607  lastPos = FocusAbsPosN[0].value;
608  }
609  }
610 
611  rc = updateTemperature();
612  if (rc)
613  {
614  if (fabs(lastTemperature - TemperatureN[0].value) >= 0.01)
615  {
616  IDSetNumber(&TemperatureNP, nullptr);
617  lastTemperature = TemperatureN[0].value;
618  }
619  }
620 
621  if (FocusTimerNP.s == IPS_BUSY)
622  {
623  float remaining = CalcTimeLeft(focusMoveStart, focusMoveRequest);
624  if (remaining <= 0)
625  {
627  FocusTimerN[0].value = 0;
628  AbortFocuser();
629  }
630  else
631  FocusTimerN[0].value = remaining * 1000.0;
632  IDSetNumber(&FocusTimerNP, nullptr);
633  }
634 
636  {
637  if (!isMoving())
638  {
641  IDSetNumber(&FocusAbsPosNP, nullptr);
642  IDSetNumber(&FocusRelPosNP, nullptr);
643  lastPos = FocusAbsPosN[0].value;
644  LOG_INFO("Focuser reached requested position.");
645  }
646  }
647 
649 }
650 
652 {
653  WriteCmd(CMD_HALT);
656  IDSetNumber(&FocusAbsPosNP, nullptr);
657  IDSetNumber(&FocusRelPosNP, nullptr);
658  return true;
659 }
660 
661 float Microtouch::CalcTimeLeft(timeval start, float req)
662 {
663  double timesince;
664  double timeleft;
665  struct timeval now
666  {
667  0, 0
668  };
669  gettimeofday(&now, nullptr);
670 
671  timesince =
672  (double)(now.tv_sec * 1000.0 + now.tv_usec / 1000) - (double)(start.tv_sec * 1000.0 + start.tv_usec / 1000);
673  timesince = timesince / 1000;
674  timeleft = req - timesince;
675  return timeleft;
676 }
677 
678 bool Microtouch::WriteCmd(char cmd)
679 {
680  int nbytes_written = 0, rc = -1;
681  char errstr[MAXRBUF];
682 
683  tcflush(PortFD, TCIOFLUSH);
684 
685  LOGF_DEBUG("WriteCmd : %02x ", cmd);
686 
687  if ((rc = tty_write(PortFD, &cmd, 1, &nbytes_written)) != TTY_OK)
688  {
689  tty_error_msg(rc, errstr, MAXRBUF);
690  LOGF_ERROR("WriteCmd error: %s.", errstr);
691  return false;
692  }
693  return true;
694 }
695 
696 bool Microtouch::WriteCmdGetResponse(char cmd, char *readbuffer, char numbytes)
697 {
698  int nbytes_read = 0, rc = -1;
699  char errstr[MAXRBUF];
700 
701  if (WriteCmd(cmd))
702  {
703  if ((rc = tty_read(PortFD, readbuffer, numbytes, MICROTOUCH_TIMEOUT, &nbytes_read)) != TTY_OK)
704  {
705  tty_error_msg(rc, errstr, MAXRBUF);
706  LOGF_ERROR("WriteCmdGetResponse error: %s.", errstr);
707  return false;
708  }
709 
710  return true;
711  }
712  else
713  return false;
714 }
715 
716 char Microtouch::WriteCmdGetByte(char cmd)
717 {
718  char read[2];
719 
720  if (WriteCmdGetResponse(cmd, read, 2))
721  {
722  LOGF_DEBUG("WriteCmdGetByte : %02x %02x ", read[0], read[1]);
723  return read[1];
724  }
725  else
726  return -1;
727 }
728 
729 bool Microtouch::WriteCmdSetByte(char cmd, char val)
730 {
731  int nbytes_written = 0, rc = -1;
732  char errstr[MAXRBUF];
733  char write_buffer[2];
734 
735  write_buffer[0] = cmd;
736  write_buffer[1] = val;
737 
738  LOGF_DEBUG("WriteCmdSetByte : CMD %02x %02x ", write_buffer[0], write_buffer[1]);
739 
740  tcflush(PortFD, TCIOFLUSH);
741 
742  if ((rc = tty_write(PortFD, write_buffer, 2, &nbytes_written)) != TTY_OK)
743  {
744  tty_error_msg(rc, errstr, MAXRBUF);
745  LOGF_ERROR("WriteCmdSetByte error: %s.", errstr);
746  return false;
747  }
748  return true;
749 }
750 
751 bool Microtouch::WriteCmdSetShortInt(char cmd, short int val)
752 {
753  int nbytes_written = 0, rc = -1;
754  char errstr[MAXRBUF];
755  char write_buffer[3];
756 
757  write_buffer[0] = cmd;
758  write_buffer[1] = val & 0xFF;
759  write_buffer[2] = val >> 8;
760 
761  LOGF_DEBUG("WriteCmdSetShortInt : %02x %02x %02x ", write_buffer[0], write_buffer[1],
762  write_buffer[2]);
763 
764  tcflush(PortFD, TCIOFLUSH);
765 
766  if ((rc = tty_write(PortFD, write_buffer, 3, &nbytes_written)) != TTY_OK)
767  {
768  tty_error_msg(rc, errstr, MAXRBUF);
769  LOGF_ERROR("WriteCmdSetShortInt error: %s.", errstr);
770  return false;
771  }
772  return true;
773 }
774 
775 int Microtouch::WriteCmdGetInt(char cmd)
776 {
777  char read[5];
778 
779  if (WriteCmdGetResponse(cmd, read, 5))
780  return ((unsigned char)read[4] << 24 | (unsigned char)read[3] << 16 | (unsigned char)read[2] << 8 |
781  (unsigned char)read[1]);
782  else
783  return -100000;
784 }
785 
786 bool Microtouch::WriteCmdSetInt(char cmd, int val)
787 {
788  int nbytes_written = 0, rc = -1;
789  char errstr[MAXRBUF];
790  char write_buffer[5];
791 
792  write_buffer[0] = cmd;
793  write_buffer[1] = val & 0xFF;
794  write_buffer[2] = val >> 8;
795  write_buffer[3] = val >> 16;
796  write_buffer[4] = val >> 24;
797 
798  LOGF_DEBUG("WriteCmdSetInt : %02x %02x %02x %02x %02x ", write_buffer[0], write_buffer[1],
799  write_buffer[2], write_buffer[3], write_buffer[4]);
800 
801  tcflush(PortFD, TCIOFLUSH);
802 
803  if ((rc = tty_write(PortFD, write_buffer, 5, &nbytes_written)) != TTY_OK)
804  {
805  tty_error_msg(rc, errstr, MAXRBUF);
806  LOGF_ERROR("WriteCmdSetInt error: %s.", errstr);
807  return false;
808  }
809  return true;
810 }
811 
812 bool Microtouch::WriteCmdSetIntAsDigits(char cmd, int val)
813 {
814  int nbytes_written = 0, rc = -1;
815  char errstr[MAXRBUF];
816  char write_buffer[5];
817 
818  write_buffer[0] = cmd;
819  write_buffer[1] = val % 10;
820  write_buffer[2] = (val / 10) % 10;
821  write_buffer[3] = (val / 100) % 10;
822  write_buffer[4] = (val / 1000);
823 
824  LOGF_DEBUG("WriteCmdSetIntAsDigits : CMD (%02x %02x %02x %02x %02x) ", write_buffer[0],
825  write_buffer[1], write_buffer[2], write_buffer[3], write_buffer[4]);
826 
827  tcflush(PortFD, TCIOFLUSH);
828 
829  if ((rc = tty_write(PortFD, write_buffer, 5, &nbytes_written)) != TTY_OK)
830  {
831  tty_error_msg(rc, errstr, MAXRBUF);
832  LOGF_ERROR("WriteCmdSetIntAsDigits error: %s.", errstr);
833  return false;
834  }
835  return true;
836 }
void setDefaultBaudRate(BaudRate newRate)
setDefaultBaudRate Set default baud rate. The default baud rate is 9600 unless otherwise changed by t...
bool isConnected() const
Definition: basedevice.cpp:520
const char * getDeviceName() const
Definition: basedevice.cpp:821
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.
int SetTimer(uint32_t ms)
Set a timer to call the function TimerHit after ms milliseconds.
void addDebugControl()
Add Debug control to the driver.
INumberVectorProperty FocusSpeedNP
INumberVectorProperty FocusAbsPosNP
INumberVectorProperty FocusRelPosNP
INumberVectorProperty FocusTimerNP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: indifocuser.cpp:42
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Connection::Serial * serialConnection
Definition: indifocuser.h:116
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
Definition: microtouch.cpp:556
virtual bool Handshake() override
perform handshake with device to check communication
Definition: microtouch.cpp:138
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
Definition: microtouch.cpp:651
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: microtouch.cpp:448
const char * getDefaultName() override
Definition: microtouch.cpp:153
virtual IPState MoveFocuser(FocusDirection dir, int speed, uint16_t duration) override
MoveFocuser the focuser in a particular direction with a specific speed for a finite duration.
Definition: microtouch.cpp:528
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: microtouch.cpp:371
virtual bool SetFocuserSpeed(int speed) override
SetFocuserSpeed Set Focuser speed.
Definition: microtouch.cpp:511
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
Definition: microtouch.cpp:572
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: microtouch.cpp:106
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: microtouch.cpp:44
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
Definition: microtouch.cpp:305
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
Definition: microtouch.cpp:593
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,...
double max(void)
double min(void)
ISState
Switch state.
Definition: indiapi.h:150
@ ISS_OFF
Definition: indiapi.h:151
@ ISS_ON
Definition: indiapi.h:152
@ IP_RW
Definition: indiapi.h:186
@ IP_RO
Definition: indiapi.h:184
IPState
Property state.
Definition: indiapi.h:160
@ IPS_BUSY
Definition: indiapi.h:163
@ IPS_ALERT
Definition: indiapi.h:164
@ IPS_IDLE
Definition: indiapi.h:161
@ IPS_OK
Definition: indiapi.h:162
@ ISR_1OFMANY
Definition: indiapi.h:173
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition: indicom.c:424
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
Definition: indicom.c:482
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition: indicom.c:1167
Implementations for common driver routines.
@ TTY_OK
Definition: indicom.h:150
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: indidevapi.c:272
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indidevapi.c:128
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition: indidevapi.c:148
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: indidevapi.c:158
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: indidevapi.c:180
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: indidevapi.c:235
#define INDI_UNUSED(x)
Definition: indidevapi.h:131
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
Definition: indidriver.c:1308
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
Definition: indidriver.c:1211
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
Definition: indidriver.c:1231
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:1362
#define LOGF_DEBUG(fmt,...)
Definition: indilogger.h:83
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
Definition: indilogger.h:72
#define LOGF_ERROR(fmt,...)
Definition: indilogger.h:80
#define LOG_INFO(txt)
Definition: indilogger.h:74
#define MAXRBUF
Definition: indiserver.cpp:102
#define MICROTOUCH_TIMEOUT
Definition: microtouch.cpp:33
#define CMD_SET_TEMP_OFFSET
Definition: microtouch.h:39
#define CMD_TEMPCOMP_ON
Definition: microtouch.h:33
#define CMD_GET_TEMPERATURE
Definition: microtouch.h:30
#define CMD_RESET_POSITION
Definition: microtouch.h:27
#define CMD_HALT
Definition: microtouch.h:29
#define CMD_TEMPCOMP_OFF
Definition: microtouch.h:34
#define CMD_SET_MOTOR_SPEED
Definition: microtouch.h:37
#define CMD_GET_MOTOR_SPEED
Definition: microtouch.h:38
#define CMD_GET_COEFF
Definition: microtouch.h:32
#define CMD_GET_POSITION
Definition: microtouch.h:36
#define CMD_UPDATE_POSITION
Definition: microtouch.h:35
#define CMD_SET_COEFF
Definition: microtouch.h:31
#define FOCUS_MOTORSPEED_NORMAL
Definition: microtouch.h:41
#define CMD_IS_MOVING
Definition: microtouch.h:28
#define FOCUS_MOTORSPEED_FAST
Definition: microtouch.h:42
__u8 cmd[4]
Definition: pwc-ioctl.h:2
char name[MAXINDINAME]
Definition: indiapi.h:323
char name[MAXINDINAME]
Definition: indiapi.h:371