Instrument Neutral Distributed Interface INDI  1.9.5
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  } else if (WriteCmd(CMD_TEMPCOMP_OFF))
365  return true;
366 
367  return false;
368 }
369 
370 bool Microtouch::ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n)
371 {
372  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
373  {
374  // Focus Motor Speed
375  if (strcmp(MotorSpeedSP.name, name) == 0)
376  {
377  bool rc = false;
378  int current_mode = IUFindOnSwitchIndex(&MotorSpeedSP);
379 
380  IUUpdateSwitch(&MotorSpeedSP, states, names, n);
381 
382  int target_mode = IUFindOnSwitchIndex(&MotorSpeedSP);
383 
384  if (current_mode == target_mode)
385  {
386  MotorSpeedSP.s = IPS_OK;
387  IDSetSwitch(&MotorSpeedSP, nullptr);
388  }
389 
390  if (target_mode == 0)
391  rc = setMotorSpeed(FOCUS_MOTORSPEED_NORMAL);
392  else
393  rc = setMotorSpeed(FOCUS_MOTORSPEED_FAST);
394 
395  if (!rc)
396  {
397  IUResetSwitch(&MotorSpeedSP);
398  MotorSpeedS[current_mode].s = ISS_ON;
399  MotorSpeedSP.s = IPS_ALERT;
400  IDSetSwitch(&MotorSpeedSP, nullptr);
401  return false;
402  }
403 
404  MotorSpeedSP.s = IPS_OK;
405  IDSetSwitch(&MotorSpeedSP, nullptr);
406  return true;
407  }
408 
409  if (strcmp(TemperatureCompensateSP.name, name) == 0)
410  {
411  int last_index = IUFindOnSwitchIndex(&TemperatureCompensateSP);
412  IUUpdateSwitch(&TemperatureCompensateSP, states, names, n);
413 
414  bool rc = setTemperatureCompensation((TemperatureCompensateS[0].s == ISS_ON));
415 
416  if (!rc)
417  {
418  TemperatureCompensateSP.s = IPS_ALERT;
419  IUResetSwitch(&TemperatureCompensateSP);
420  TemperatureCompensateS[last_index].s = ISS_ON;
421  IDSetSwitch(&TemperatureCompensateSP, nullptr);
422  return false;
423  }
424 
425  TemperatureCompensateSP.s = IPS_OK;
426  IDSetSwitch(&TemperatureCompensateSP, nullptr);
427  return true;
428  }
429 
430 // if (strcmp(ResetSP.name, name) == 0)
431 // {
432 // IUResetSwitch(&ResetSP);
433 
434 // if (reset())
435 // ResetSP.s = IPS_OK;
436 // else
437 // ResetSP.s = IPS_ALERT;
438 
439 // IDSetSwitch(&ResetSP, nullptr);
440 // return true;
441 // }
442  }
443 
444  return INDI::Focuser::ISNewSwitch(dev, name, states, names, n);
445 }
446 
447 bool Microtouch::ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n)
448 {
449  if (dev != nullptr && strcmp(dev, getDeviceName()) == 0)
450  {
451 // if (strcmp(name, MaxTravelNP.name) == 0)
452 // {
453 // IUUpdateNumber(&MaxTravelNP, values, names, n);
454 // MaxTravelNP.s = IPS_OK;
455 // IDSetNumber(&MaxTravelNP, nullptr);
456 // return true;
457 // }
458 
459  if (strcmp(name, TemperatureSettingNP.name) == 0)
460  {
461  IUUpdateNumber(&TemperatureSettingNP, values, names, n);
462  if (!setTemperatureCalibration(TemperatureSettingN[0].value) ||
463  !setTemperatureCoefficient(TemperatureSettingN[1].value))
464  {
465  TemperatureSettingNP.s = IPS_ALERT;
466  IDSetNumber(&TemperatureSettingNP, nullptr);
467  return false;
468  }
469 
470  TemperatureSettingNP.s = IPS_OK;
471  IDSetNumber(&TemperatureSettingNP, nullptr);
472  }
473 
474 // if (strcmp(name, ResetToPosNP.name) == 0)
475 // {
476 // IUUpdateNumber(&ResetToPosNP, values, names, n);
477 // if (!reset(ResetToPosN[0].value))
478 // {
479 // ResetToPosNP.s = IPS_ALERT;
480 // IDSetNumber(&ResetToPosNP, nullptr);
481 // return false;
482 // }
483 
484 // ResetToPosNP.s = IPS_OK;
485 // IDSetNumber(&ResetToPosNP, nullptr);
486 // }
487  }
488 
489  return INDI::Focuser::ISNewNumber(dev, name, values, names, n);
490 }
491 
492 void Microtouch::GetFocusParams()
493 {
494  if (updatePosition())
495  IDSetNumber(&FocusAbsPosNP, nullptr);
496 
497  if (updateTemperature())
498  {
499  IDSetNumber(&TemperatureNP, nullptr);
500  IDSetNumber(&TemperatureSettingNP, nullptr);
501  }
502 
503  /* if (updateSpeed())
504  IDSetNumber(&FocusSpeedNP, nullptr);
505  */
506  if (updateMotorSpeed())
507  IDSetSwitch(&MotorSpeedSP, nullptr);
508 }
509 
511 {
512  bool rc = false;
513 
514  rc = setSpeed(speed);
515 
516  if (!rc)
517  return false;
518 
519  currentSpeed = speed;
520 
522  IDSetNumber(&FocusSpeedNP, nullptr);
523 
524  return true;
525 }
526 
527 IPState Microtouch::MoveFocuser(FocusDirection dir, int speed, uint16_t duration)
528 {
529  if (speed != (int)currentSpeed)
530  {
531  bool rc = setSpeed(speed);
532 
533  if (!rc)
534  return IPS_ALERT;
535  }
536 
537  gettimeofday(&focusMoveStart, nullptr);
538  focusMoveRequest = duration / 1000.0;
539 
540  if (dir == FOCUS_INWARD)
541  MoveFocuser(0);
542  else
543  MoveFocuser(FocusAbsPosN[0].value + FocusMaxPosN[0].value - 1);
544 
545  if (duration <= getCurrentPollingPeriod())
546  {
547  usleep(duration * 1000);
548  AbortFocuser();
549  return IPS_OK;
550  }
551 
552  return IPS_BUSY;
553 }
554 
555 IPState Microtouch::MoveAbsFocuser(uint32_t targetTicks)
556 {
557  targetPos = targetTicks;
558 
559  bool rc = false;
560 
561  rc = MoveFocuser(targetPos);
562 
563  if (!rc)
564  return IPS_ALERT;
565 
567 
568  return IPS_BUSY;
569 }
570 
572 {
573  double newPosition = 0;
574  bool rc = false;
575 
576  if (dir == FOCUS_INWARD)
577  newPosition = FocusAbsPosN[0].value - ticks;
578  else
579  newPosition = FocusAbsPosN[0].value + ticks;
580 
581  rc = MoveFocuser(newPosition);
582 
583  if (!rc)
584  return IPS_ALERT;
585 
586  FocusRelPosN[0].value = ticks;
588 
589  return IPS_BUSY;
590 }
591 
593 {
594  if (!isConnected())
595  {
596  return;
597  }
598 
599  bool rc = updatePosition();
600 
601  if (rc)
602  {
603  if (fabs(lastPos - FocusAbsPosN[0].value) > 1)
604  {
605  IDSetNumber(&FocusAbsPosNP, nullptr);
606  lastPos = FocusAbsPosN[0].value;
607  }
608  }
609 
610  rc = updateTemperature();
611  if (rc)
612  {
613  if (fabs(lastTemperature - TemperatureN[0].value) >= 0.01)
614  {
615  IDSetNumber(&TemperatureNP, nullptr);
616  lastTemperature = TemperatureN[0].value;
617  }
618  }
619 
620  if (FocusTimerNP.s == IPS_BUSY)
621  {
622  float remaining = CalcTimeLeft(focusMoveStart, focusMoveRequest);
623  if (remaining <= 0)
624  {
626  FocusTimerN[0].value = 0;
627  AbortFocuser();
628  }
629  else
630  FocusTimerN[0].value = remaining * 1000.0;
631  IDSetNumber(&FocusTimerNP, nullptr);
632  }
633 
635  {
636  if (!isMoving())
637  {
640  IDSetNumber(&FocusAbsPosNP, nullptr);
641  IDSetNumber(&FocusRelPosNP, nullptr);
642  lastPos = FocusAbsPosN[0].value;
643  LOG_INFO("Focuser reached requested position.");
644  }
645  }
646 
648 }
649 
651 {
652  WriteCmd(CMD_HALT);
655  IDSetNumber(&FocusAbsPosNP, nullptr);
656  IDSetNumber(&FocusRelPosNP, nullptr);
657  return true;
658 }
659 
660 float Microtouch::CalcTimeLeft(timeval start, float req)
661 {
662  double timesince;
663  double timeleft;
664  struct timeval now { 0, 0 };
665  gettimeofday(&now, nullptr);
666 
667  timesince =
668  (double)(now.tv_sec * 1000.0 + now.tv_usec / 1000) - (double)(start.tv_sec * 1000.0 + start.tv_usec / 1000);
669  timesince = timesince / 1000;
670  timeleft = req - timesince;
671  return timeleft;
672 }
673 
674 bool Microtouch::WriteCmd(char cmd)
675 {
676  int nbytes_written = 0, rc = -1;
677  char errstr[MAXRBUF];
678 
679  tcflush(PortFD, TCIOFLUSH);
680 
681  LOGF_DEBUG("WriteCmd : %02x ", cmd);
682 
683  if ((rc = tty_write(PortFD, &cmd, 1, &nbytes_written)) != TTY_OK)
684  {
685  tty_error_msg(rc, errstr, MAXRBUF);
686  LOGF_ERROR("WriteCmd error: %s.", errstr);
687  return false;
688  }
689  return true;
690 }
691 
692 bool Microtouch::WriteCmdGetResponse(char cmd, char *readbuffer, char numbytes)
693 {
694  int nbytes_read = 0, rc = -1;
695  char errstr[MAXRBUF];
696 
697  if (WriteCmd(cmd))
698  {
699  if ((rc = tty_read(PortFD, readbuffer, numbytes, MICROTOUCH_TIMEOUT, &nbytes_read)) != TTY_OK)
700  {
701  tty_error_msg(rc, errstr, MAXRBUF);
702  LOGF_ERROR("WriteCmdGetResponse error: %s.", errstr);
703  return false;
704  }
705 
706  return true;
707  }
708  else
709  return false;
710 }
711 
712 char Microtouch::WriteCmdGetByte(char cmd)
713 {
714  char read[2];
715 
716  if (WriteCmdGetResponse(cmd, read, 2))
717  {
718  LOGF_DEBUG("WriteCmdGetByte : %02x %02x ", read[0], read[1]);
719  return read[1];
720  }
721  else
722  return -1;
723 }
724 
725 bool Microtouch::WriteCmdSetByte(char cmd, char val)
726 {
727  int nbytes_written = 0, rc = -1;
728  char errstr[MAXRBUF];
729  char write_buffer[2];
730 
731  write_buffer[0] = cmd;
732  write_buffer[1] = val;
733 
734  LOGF_DEBUG("WriteCmdSetByte : CMD %02x %02x ", write_buffer[0], write_buffer[1]);
735 
736  tcflush(PortFD, TCIOFLUSH);
737 
738  if ((rc = tty_write(PortFD, write_buffer, 2, &nbytes_written)) != TTY_OK)
739  {
740  tty_error_msg(rc, errstr, MAXRBUF);
741  LOGF_ERROR("WriteCmdSetByte error: %s.", errstr);
742  return false;
743  }
744  return true;
745 }
746 
747 bool Microtouch::WriteCmdSetShortInt(char cmd, short int val)
748 {
749  int nbytes_written = 0, rc = -1;
750  char errstr[MAXRBUF];
751  char write_buffer[3];
752 
753  write_buffer[0] = cmd;
754  write_buffer[1] = val & 0xFF;
755  write_buffer[2] = val >> 8;
756 
757  LOGF_DEBUG("WriteCmdSetShortInt : %02x %02x %02x ", write_buffer[0], write_buffer[1],
758  write_buffer[2]);
759 
760  tcflush(PortFD, TCIOFLUSH);
761 
762  if ((rc = tty_write(PortFD, write_buffer, 3, &nbytes_written)) != TTY_OK)
763  {
764  tty_error_msg(rc, errstr, MAXRBUF);
765  LOGF_ERROR("WriteCmdSetShortInt error: %s.", errstr);
766  return false;
767  }
768  return true;
769 }
770 
771 int Microtouch::WriteCmdGetInt(char cmd)
772 {
773  char read[5];
774 
775  if (WriteCmdGetResponse(cmd, read, 5))
776  return ((unsigned char)read[4] << 24 | (unsigned char)read[3] << 16 | (unsigned char)read[2] << 8 |
777  (unsigned char)read[1]);
778  else
779  return -100000;
780 }
781 
782 bool Microtouch::WriteCmdSetInt(char cmd, int val)
783 {
784  int nbytes_written = 0, rc = -1;
785  char errstr[MAXRBUF];
786  char write_buffer[5];
787 
788  write_buffer[0] = cmd;
789  write_buffer[1] = val & 0xFF;
790  write_buffer[2] = val >> 8;
791  write_buffer[3] = val >> 16;
792  write_buffer[4] = val >> 24;
793 
794  LOGF_DEBUG("WriteCmdSetInt : %02x %02x %02x %02x %02x ", write_buffer[0], write_buffer[1],
795  write_buffer[2], write_buffer[3], write_buffer[4]);
796 
797  tcflush(PortFD, TCIOFLUSH);
798 
799  if ((rc = tty_write(PortFD, write_buffer, 5, &nbytes_written)) != TTY_OK)
800  {
801  tty_error_msg(rc, errstr, MAXRBUF);
802  LOGF_ERROR("WriteCmdSetInt error: %s.", errstr);
803  return false;
804  }
805  return true;
806 }
807 
808 bool Microtouch::WriteCmdSetIntAsDigits(char cmd, int val)
809 {
810  int nbytes_written = 0, rc = -1;
811  char errstr[MAXRBUF];
812  char write_buffer[5];
813 
814  write_buffer[0] = cmd;
815  write_buffer[1] = val % 10;
816  write_buffer[2] = (val / 10) % 10;
817  write_buffer[3] = (val / 100) % 10;
818  write_buffer[4] = (val / 1000);
819 
820  LOGF_DEBUG("WriteCmdSetIntAsDigits : CMD (%02x %02x %02x %02x %02x) ", write_buffer[0],
821  write_buffer[1], write_buffer[2], write_buffer[3], write_buffer[4]);
822 
823  tcflush(PortFD, TCIOFLUSH);
824 
825  if ((rc = tty_write(PortFD, write_buffer, 5, &nbytes_written)) != TTY_OK)
826  {
827  tty_error_msg(rc, errstr, MAXRBUF);
828  LOGF_ERROR("WriteCmdSetIntAsDigits error: %s.", errstr);
829  return false;
830  }
831  return true;
832 }
INDI::FocuserInterface::FOCUSER_CAN_ABS_MOVE
@ FOCUSER_CAN_ABS_MOVE
Definition: indifocuserinterface.h:74
FOCUS_MOTORSPEED_NORMAL
#define FOCUS_MOTORSPEED_NORMAL
Definition: microtouch.h:41
Microtouch::SyncFocuser
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
Definition: microtouch.cpp:305
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
CMD_TEMPCOMP_ON
#define CMD_TEMPCOMP_ON
Definition: microtouch.h:33
INDI::FocuserInterface::FocusAbsPosNP
INumberVectorProperty FocusAbsPosNP
Definition: indifocuserinterface.h:282
CMD_GET_TEMPERATURE
#define CMD_GET_TEMPERATURE
Definition: microtouch.h:30
microtouch.h
cmd
__u8 cmd[4]
Definition: pwc-ioctl.h:4
CMD_GET_MOTOR_SPEED
#define CMD_GET_MOTOR_SPEED
Definition: microtouch.h:38
CMD_IS_MOVING
#define CMD_IS_MOVING
Definition: microtouch.h:28
IPState
IPState
Property state.
Definition: indiapi.h:158
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
min
double min(void)
ISS_OFF
@ ISS_OFF
Definition: indiapi.h:150
indicom.h
Implementations for common driver routines.
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
OPTIONS_TAB
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
Definition: defaultdevice.cpp:39
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
INDI::FocuserInterface::FocusTimerN
INumber FocusTimerN[1]
Definition: indifocuserinterface.h:279
INDI_UNUSED
#define INDI_UNUSED(x)
Definition: indidevapi.h:799
MICROTOUCH_TIMEOUT
#define MICROTOUCH_TIMEOUT
Definition: microtouch.cpp:33
INDI::BaseDevice::getDeviceName
const char * getDeviceName() const
Definition: basedevice.cpp:799
INDI::Focuser::serialConnection
Connection::Serial * serialConnection
Definition: indifocuser.h:113
Microtouch::AbortFocuser
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
Definition: microtouch.cpp:650
INDI::FocuserInterface::FOCUSER_CAN_ABORT
@ FOCUSER_CAN_ABORT
Definition: indifocuserinterface.h:76
Connection::Serial::B_19200
@ B_19200
Definition: connectionserial.h:82
LOG_INFO
#define LOG_INFO(txt)
Definition: indilogger.h:74
MAXRBUF
#define MAXRBUF
Definition: indidriver.c:52
Microtouch::ISNewNumber
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Process the client newNumber command.
Definition: microtouch.cpp:447
max
double max(void)
CMD_GET_POSITION
#define CMD_GET_POSITION
Definition: microtouch.h:36
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
INDI::DefaultDevice::getCurrentPollingPeriod
uint32_t getCurrentPollingPeriod() const
getCurrentPollingPeriod Return the current polling period.
Definition: defaultdevice.cpp:1139
Microtouch
Definition: microtouch.h:44
tty_read
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
Definition: indicom.c:473
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
CMD_GET_COEFF
#define CMD_GET_COEFF
Definition: microtouch.h:32
Microtouch::SetFocuserSpeed
virtual bool SetFocuserSpeed(int speed) override
SetFocuserSpeed Set Focuser speed.
Definition: microtouch.cpp:510
INDI::FocuserInterface::FocusTimerNP
INumberVectorProperty FocusTimerNP
Definition: indifocuserinterface.h:278
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
CMD_UPDATE_POSITION
#define CMD_UPDATE_POSITION
Definition: microtouch.h:35
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
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::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
Microtouch::initProperties
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: microtouch.cpp:44
INDI::BaseDevice::isConnected
bool isConnected() const
Definition: basedevice.cpp:518
Microtouch::MoveFocuser
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:527
Microtouch::Handshake
virtual bool Handshake() override
perform handshake with device to check communication
Definition: microtouch.cpp:138
Microtouch::Microtouch
Microtouch()
Definition: microtouch.cpp:37
Microtouch::MoveAbsFocuser
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
Definition: microtouch.cpp:555
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
name
const char * name
Definition: indiserver.c:116
_ISwitchVectorProperty::s
IPState s
Definition: indiapi.h:382
INDI::FocuserInterface::FocusMaxPosN
INumber FocusMaxPosN[1]
Definition: indifocuserinterface.h:291
CMD_HALT
#define CMD_HALT
Definition: microtouch.h:29
IUUpdateNumber
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
Definition: indidriver.c:225
Microtouch::TimerHit
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
Definition: microtouch.cpp:592
INDI::FocuserInterface::FocusDirection
FocusDirection
Definition: indifocuserinterface.h:66
IP_RW
@ IP_RW
Definition: indiapi.h:185
INDI::FocuserInterface::FocusSpeedNP
INumberVectorProperty FocusSpeedNP
Definition: indifocuserinterface.h:268
ISState
ISState
Switch state.
Definition: indiapi.h:148
Microtouch::MoveRelFocuser
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
Definition: microtouch.cpp:571
CMD_SET_MOTOR_SPEED
#define CMD_SET_MOTOR_SPEED
Definition: microtouch.h:37
IUFindOnSwitchIndex
int IUFindOnSwitchIndex(const ISwitchVectorProperty *sp)
Returns the index of first ON switch it finds in the vector switch property.
Definition: indicom.c:1424
Microtouch::getDefaultName
const char * getDefaultName() override
Definition: microtouch.cpp:153
CMD_SET_TEMP_OFFSET
#define CMD_SET_TEMP_OFFSET
Definition: microtouch.h:39
INDI::DefaultDevice::addDebugControl
void addDebugControl()
Add Debug control to the driver.
Definition: defaultdevice.cpp:639
INDI::Focuser::initProperties
virtual bool initProperties() override
Initilize properties initial state and value. The child class must implement this function.
Definition: indifocuser.cpp:58
CMD_TEMPCOMP_OFF
#define CMD_TEMPCOMP_OFF
Definition: microtouch.h:34
Microtouch::updateProperties
virtual bool updateProperties() override
updateProperties is called whenever there is a change in the CONNECTION status of the driver....
Definition: microtouch.cpp:106
TTY_OK
@ TTY_OK
Definition: indicom.h:94
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
CMD_SET_COEFF
#define CMD_SET_COEFF
Definition: microtouch.h:31
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.
CMD_RESET_POSITION
#define CMD_RESET_POSITION
Definition: microtouch.h:27
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
FOCUS_MOTORSPEED_FAST
#define FOCUS_MOTORSPEED_FAST
Definition: microtouch.h:42
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
Microtouch::ISNewSwitch
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Process the client newSwitch command.
Definition: microtouch.cpp:370
INDI::FocuserInterface::FocusSpeedN
INumber FocusSpeedN[1]
Definition: indifocuserinterface.h:269
_ISwitchVectorProperty::name
char name[MAXINDINAME]
Definition: indiapi.h:370
ISS_ON
@ ISS_ON
Definition: indiapi.h:151