Instrument Neutral Distributed Interface INDI 2.2.5
microtouch.cpp
Go to the documentation of this file.
1/*
2 Microtouch Focuser
3 Copyright (C) 2016 Marco Peters ([email protected])
4 Copyright (C) 2013 Jasem Mutlaq ([email protected])
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
35static 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 FocusSpeedNP[0].setMin(1);
49 FocusSpeedNP[0].setMax(5);
50 FocusSpeedNP[0].setValue(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,
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 FocusRelPosNP[0].setMin(0.);
91 FocusRelPosNP[0].setMax(30000.);
92 FocusRelPosNP[0].setValue(0);
93 FocusRelPosNP[0].setStep(1000.);
94
95 FocusAbsPosNP[0].setMin(0.);
96 FocusAbsPosNP[0].setMax(60000.);
97 FocusAbsPosNP[0].setValue(0);
98 FocusAbsPosNP[0].setStep(1000.);
99
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
158bool Microtouch::Ack()
159{
160 return updatePosition();
161}
162
163bool 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
190bool Microtouch::updatePosition()
191{
192 char read[3] = {0};
193
194 if (WriteCmdGetResponse(CMD_GET_POSITION, read, 3))
195 {
196 FocusAbsPosNP[0].setValue(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
203bool 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 FocusSpeedNP[0].setValue(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
250bool 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
269bool Microtouch::isMoving()
270{
271 return (WriteCmdGetByte(CMD_IS_MOVING) > 0);
272}
273
274bool Microtouch::setTemperatureCalibration(double calibration)
275{
276 return WriteCmdSetShortInt(CMD_SET_TEMP_OFFSET, (short int)(calibration * 16));
277}
278
279bool 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
305bool Microtouch::SyncFocuser(uint32_t ticks)
306{
307 WriteCmdSetIntAsDigits(CMD_RESET_POSITION, ticks);
308 return true;
309}
310
311bool Microtouch::MoveFocuser(unsigned int position)
312{
313 LOGF_DEBUG("MoveFocuser to Position: %d", position);
314
315 if (position < FocusAbsPosNP[0].getMin() || position > FocusAbsPosNP[0].getMax())
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
323bool 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
333bool 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
356bool 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
371bool 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
448bool 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
493void Microtouch::GetFocusParams()
494{
495 if (updatePosition())
497
498 if (updateTemperature())
499 {
500 IDSetNumber(&TemperatureNP, nullptr);
501 IDSetNumber(&TemperatureSettingNP, nullptr);
502 }
503
504 /* if (updateSpeed())
505 FocusSpeedNP.apply();
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
524
525 return true;
526}
527
528IPState 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(FocusAbsPosNP[0].getValue() + FocusMaxPosNP[0].getValue() - 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
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 = FocusAbsPosNP[0].getValue() - ticks;
579 else
580 newPosition = FocusAbsPosNP[0].getValue() + ticks;
581
582 rc = MoveFocuser(newPosition);
583
584 if (!rc)
585 return IPS_ALERT;
586
587 FocusRelPosNP[0].setValue(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 - FocusAbsPosNP[0].getValue()) > 1)
605 {
607 lastPos = FocusAbsPosNP[0].getValue();
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
622 {
623 float remaining = CalcTimeLeft(focusMoveStart, focusMoveRequest);
624 if (remaining <= 0)
625 {
627 FocusTimerNP[0].setValue(0);
628 AbortFocuser();
629 }
630 else
631 FocusTimerNP[0].setValue(remaining * 1000.0);
633 }
634
636 {
637 if (!isMoving())
638 {
643 lastPos = FocusAbsPosNP[0].getValue();
644 LOG_INFO("Focuser reached requested position.");
645 }
646 }
647
649}
650
652{
653 WriteCmd(CMD_HALT);
658 return true;
659}
660
661float 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
678bool 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
696bool 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
716char 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
729bool 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
751bool 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
775int 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
786bool 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
812bool 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
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.
INDI::PropertyNumber FocusRelPosNP
void SetCapability(uint32_t cap)
FI::SetCapability sets the focuser capabilities. All capabilities must be initialized.
INDI::PropertyNumber FocusSpeedNP
INDI::PropertyNumber FocusTimerNP
INDI::PropertyNumber FocusMaxPosNP
INDI::PropertyNumber FocusAbsPosNP
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Processes incoming new number values from the client for this device. Handles updates to FocuserInter...
Connection::Serial * serialConnection
void setState(IPState state)
void apply(const char *format,...) const ATTRIBUTE_FORMAT_PRINTF(2
virtual IPState MoveAbsFocuser(uint32_t targetTicks) override
MoveFocuser the focuser to an absolute position.
virtual bool Handshake() override
Performs a device-specific handshake after a connection is established. This method should be overrid...
virtual bool AbortFocuser() override
AbortFocuser all focus motion.
virtual bool ISNewNumber(const char *dev, const char *name, double values[], char *names[], int n) override
Processes incoming new number values from the client for this device. Handles updates to FocuserInter...
const char * getDefaultName() override
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.
virtual bool ISNewSwitch(const char *dev, const char *name, ISState *states, char *names[], int n) override
Processes incoming new switch states from the client for this device. Handles updates to FocuserInter...
virtual bool SetFocuserSpeed(int speed) override
SetFocuserSpeed Set Focuser speed.
virtual IPState MoveRelFocuser(FocusDirection dir, uint32_t ticks) override
MoveFocuser the focuser to an relative position.
virtual bool updateProperties() override
Updates the state and definition of properties based on the current connection status....
virtual bool initProperties() override
Initializes the default properties for the focuser device. Sets up standard INDI properties,...
virtual bool SyncFocuser(uint32_t ticks) override
SyncFocuser Set current position to ticks without moving the focuser.
virtual void TimerHit() override
Callback function to be called once SetTimer duration elapses.
const char * MAIN_CONTROL_TAB
MAIN_CONTROL_TAB Where all the primary controls for the device are located.
const char * OPTIONS_TAB
OPTIONS_TAB Where all the driver's options are located. Those may include auxiliary controls,...
ISState
Switch state.
Definition indiapi.h:148
@ ISS_OFF
Definition indiapi.h:149
@ ISS_ON
Definition indiapi.h:150
@ IP_RW
Definition indiapi.h:184
@ IP_RO
Definition indiapi.h:182
IPState
Property state.
Definition indiapi.h:158
@ IPS_BUSY
Definition indiapi.h:161
@ IPS_ALERT
Definition indiapi.h:162
@ IPS_IDLE
Definition indiapi.h:159
@ IPS_OK
Definition indiapi.h:160
@ ISR_1OFMANY
Definition indiapi.h:171
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
Definition indicom.c:418
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
Definition indicom.c:548
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Definition indicom.c:1243
Implementations for common driver routines.
@ TTY_OK
Definition indicom.h:54
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:490
int IUFindOnSwitchIndex(const ISwitchVectorProperty *svp)
Returns the index of first ON switch it finds in the vector switch property.
Definition indidevapi.c:337
void IUResetSwitch(ISwitchVectorProperty *svp)
Reset all switches in a switch vector property to OFF.
Definition indidevapi.c:366
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:376
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:398
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:453
#define INDI_UNUSED(x)
Definition indidevapi.h:132
int IUUpdateSwitch(ISwitchVectorProperty *svp, ISState *states, char *names[], int n)
Update all switches in a switch vector property.
void IDSetNumber(const INumberVectorProperty *nvp, const char *fmt,...)
void IDSetSwitch(const ISwitchVectorProperty *svp, const char *fmt,...)
#define MAXRBUF
Definition indidriver.c:52
int IUUpdateNumber(INumberVectorProperty *nvp, double values[], char *names[], int n)
Update all numbers in a number vector property.
#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 getDeviceName
#define MICROTOUCH_TIMEOUT
#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
uint8_t cmd[4]
Definition pwc-ioctl.h:2
char name[MAXINDINAME]
Definition indiapi.h:321
char name[MAXINDINAME]
Definition indiapi.h:369