32#define SCOPEDOME_TIMEOUT 2
34static const uint8_t header = 0xaa;
36const char* ScopeDomeUSB21::cmdToString(Command
cmd)
const
38 static const CmdStr cmdStrMap[] =
41 { FunctionNotSupported,
"FunctionNotSupported" },
42 { MotionConflict,
"MotionConflict" },
43 { ParamError,
"ParamError" },
44 { FuncBufferError,
"FuncBufferError" },
45 { ConnectionTest,
"ConnectionTest" },
46 { SetAllDigital,
"SetAllDigital" },
47 { ClearDigitalChannel,
"ClearDigitalChannel" },
48 { ClearAllDigital,
"ClearAllDigital" },
49 { SetDigitalChannel,
"SetDigitalChannel" },
50 { GetDigitalChannel,
"GetDigitalChannel" },
51 { GetAllDigital,
"GetAllDigital" },
53 { GetCounter,
"GetCounter" },
54 { ResetCounter,
"ResetCounter" },
55 { SetCounterDebounceTime,
"SetCounterDebounceTime" },
56 { SetCounterMax,
"SetCounterMax" },
57 { GetCounterMax,
"GetCounterMax" },
58 { SetCounterMin,
"SetCounterMin" },
59 { GetCounterMin,
"GetCounterMin" },
60 { CCWRotation,
"CCWRotation" },
61 { CWRotation,
"CWRotation" },
63 { GetAnalogChannel,
"GetAnalogChannel" },
64 { OutputAnalogChannel1,
"OutputAnalogChannel1" },
65 { OutputAnalogChannel2,
"OutputAnalogChannel2" },
66 { OutputAllAnalog,
"OutputAllAnalog" },
67 { ClearAnalogChannel,
"ClearAnalogChannel" },
68 { SetAllAnalog,
"SetAllAnalog" },
69 { ClearAllAnalog,
"ClearAllAnalog" },
70 { SetAnalogChannel,
"SetAnalogChannel" },
71 { GetVersionFirmware,
"GetVersionFirmware" },
73 { SetAllRelays,
"SetAllRelays" },
74 { ClearRelay,
"ClearRelay" },
75 { SetRelay,
"SetRelay" },
77 { GetStatus,
"GetStatus" },
78 { GetTemp1,
"GetTemp1" },
79 { GetTemp2,
"GetTemp2" },
80 { GetTemp3,
"GetTemp3" },
81 { GetTemp4,
"GetTemp4" },
82 { GetTemp5,
"GetTemp5" },
83 { GetDscnt,
"GetDscnt" },
85 { GetTempHum,
"GetTempHum" },
86 { GetAnalog1,
"GetAnalog1" },
87 { GetAnalog2,
"GetAnalog2" },
89 { EnableAutoClose,
"EnableAutoClose" },
90 { DisableAutoClose,
"DisableAutoClose" },
91 { GetAutoClose,
"GetAutoClose" },
93 { EnablePosSave,
"EnablePosSave" },
94 { DisablePosSave,
"DisablePosSave" },
95 { GetPosSave,
"GetPosSave" },
97 { GetCounterExt,
"GetCounterExt" },
98 { ResetCounterExt,
"ResetCounterExt" },
99 { SetCounterDebounceTimeExt,
"SetCounterDebounceTimeExt" },
100 { SetCounterMaxExt,
"SetCounterMaxExt" },
101 { GetCounterMaxExt,
"GetCounterMaxExt" },
103 { SetCounterMinExt,
"SetCounterMinExt" },
104 { GetCounterMinExt,
"GetCounterMinExt" },
106 { GetAllDigitalExt,
"GetAllDigitalExt" },
107 { StandbyOff,
"StandbyOff" },
108 { StandbyOn,
"StandbyOn" },
109 { GetPowerState,
"GetPowerState" },
110 { SetImpPerTurn,
"SetImpPerTurn" },
112 { UpdateFirmware,
"UpdateFirmware" },
113 { UpdateRotaryFirmwareSerial,
"UpdateRotaryFirmwareSerial" },
114 { UpdateRotaryFirmwareRf,
"UpdateRotaryFirmwareRf" },
116 { GoHome,
"GoHome" },
118 { GetMainAnalog1,
"GetMainAnalog1" },
119 { GetMainAnalog2,
"GetMainAnalog2" },
121 { GetPressure,
"GetPressure" },
122 { GetTempIn,
"GetTempIn" },
123 { GetTempOut,
"GetTempOut" },
125 { GetRotaryCounter1,
"GetRotaryCounter1" },
126 { GetRotaryCounter2,
"GetRotaryCounter2" },
127 { ResetRotaryCounter1,
"ResetRotaryCounter1" },
128 { ResetRotaryCounter2,
"ResetRotaryCounter2" },
130 { RotaryAutoOpen1,
"RotaryAutoOpen1" },
131 { RotaryAutoOpen2,
"RotaryAutoOpen2" },
133 { RotaryAutoClose1,
"RotaryAutoClose1" },
134 { RotaryAutoClose2,
"RotaryAutoClose2" },
136 { GetLinkStrength,
"GetLinkStrength" },
138 { GetLowVoltageMain,
"GetLowVoltageMain" },
139 { SetLowVoltageMain,
"SetLowVoltageMain" },
140 { GetLowVoltageRotary,
"GetLowVoltageRotary" },
141 { SetLowVoltageRotary,
"SetLowVoltageRotary" },
143 { GetHomeSensorPosition,
"GetHomeSensorPosition" },
144 { SetHomeSensorPosition,
"SetHomeSensorPosition" },
146 { GetImpPerTurn,
"GetImpPerTurn" },
149 { GetStartCnt,
"GetStartCnt" },
152 { SetStopTime,
"SetStopTime" },
153 { GetStopTime,
"GetStopTime" },
155 { GetCounterDebounceTimeExt,
"GetCounterDebounceTimeExt" },
157 { SetDebounceTimeInputs,
"SetDebounceTimeInputs" },
158 { GetDebounceTimeInputs,
"GetDebounceTimeInputs" },
160 { FindHome,
"FindHome" },
161 { NegHomeSensorActiveState,
"NegHomeSensorActiveState" },
165 { SetAutoCloseEvents,
"SetAutoCloseEvents" },
166 { GetAutoCloseEvents,
"GetAutoCloseEvents" },
167 { SetAutoCloseTime,
"SetAutoCloseTime" },
168 { GetAutoCloseTime,
"GetAutoCloseTime" },
170 { SetShutterConfig,
"SetShutterConfig" },
171 { GetShutterConfig,
"GetShutterConfig" },
173 { GetVersionFirmwareRotary,
"GetVersionFirmwareRotary" },
174 { GetCommunicationMode,
"GetCommunicationMode" },
175 { SetCommunicationMode,
"SetCommunicationMode" },
177 { SetTherm1Mode,
"SetTherm1Mode" },
178 { SetTherm1Out1,
"SetTherm1Out1" },
179 { SetTherm1Out2,
"SetTherm1Out2" },
180 { SetTherm1Hist,
"SetTherm1Hist" },
181 { SetTherm1VAL,
"SetTherm1VAL" },
183 { GetTherm1Mode,
"GetTherm1Mode" },
184 { GetTherm1Out1,
"GetTherm1Out1" },
185 { GetTherm1Out2,
"GetTherm1Out2" },
186 { GetTherm1Hist,
"GetTherm1Hist" },
187 { GetTherm1VAL,
"GetTherm1VAL" },
189 { SetTherm2Mode,
"SetTherm2Mode" },
190 { SetTherm2Out1,
"SetTherm2Out1" },
191 { SetTherm2Out2,
"SetTherm2Out2" },
192 { SetTherm2Hist,
"SetTherm2Hist" },
193 { SetTherm2VAL,
"SetTherm2VAL" },
195 { GetTherm2Mode,
"GetTherm2Mode" },
196 { GetTherm2Out1,
"GetTherm2Out1" },
197 { GetTherm2Out2,
"GetTherm2Out2" },
198 { GetTherm2Hist,
"GetTherm2Hist" },
199 { GetTherm2VAL,
"GetTherm2VAL" },
201 { SetTherm3Mode,
"SetTherm3Mode" },
202 { SetTherm3Out1,
"SetTherm3Out1" },
203 { SetTherm3Out2,
"SetTherm3Out2" },
204 { SetTherm3Hist,
"SetTherm3Hist" },
205 { SetTherm3VAL,
"SetTherm3VAL" },
207 { GetTherm3Mode,
"GetTherm3Mode" },
208 { GetTherm3Out1,
"GetTherm3Out1" },
209 { GetTherm3Out2,
"GetTherm3Out2" },
210 { GetTherm3Hist,
"GetTherm3Hist" },
211 { GetTherm3VAL,
"GetTherm3VAL" },
212 { StartSafeCommunication,
"StartSafeCommunication" },
213 { StopSafeCommunication,
"StopSafeCommunication" },
214 { SetAutoCloseOrder,
"SetAutoCloseOrder" },
215 { GetAutoCloseOrder,
"GetAutoCloseOrder" },
217 { FullSystemCal,
"FullSystemCal" },
218 { IsFullSystemCalReq,
"IsFullSystemCalReq" }
221 for (
auto i = 0u; i <
sizeof(cmdStrMap) /
sizeof(CmdStr); ++i)
223 if (cmdStrMap[i].
cmd ==
cmd)
225 return cmdStrMap[i].str;
228 return "Unknown command";
236 rc = write(ConnectionTest);
241 if (
cmd != ConnectionTest)
246 rc = write(StopSafeCommunication);
248 return (
cmd == StopSafeCommunication);
251uint8_t ScopeDomeUSB21::CRC(uint8_t crc, uint8_t data)
255 for (
int i = 0; i < 8; i++)
258 crc = ((crc >> 1) ^ 0x8C);
265int ScopeDomeUSB21::writeBuf(Command
cmd, uint8_t len, uint8_t *buff)
267 int BytesToWrite = len + 4;
268 int nbytes_written = 0, rc = -1;
271 std::vector<uint8_t> cbuf(BytesToWrite, 0);
273 cbuf[3] = CRC(0, cbuf[0]);
275 cbuf[3] = CRC(cbuf[3], cbuf[1]);
277 cbuf[3] = CRC(cbuf[3], cbuf[2]);
279 for (
int i = 0; i < len; i++)
281 cbuf[i + 4] = buff[i];
282 cbuf[3] = CRC(cbuf[3], buff[i]);
285 tcflush(PortFD, TCIOFLUSH);
290 LOGF_DEBUG(
"write buf: %x %x %x %x %x", cbuf[0], cbuf[1], cbuf[2], cbuf[3], cbuf[4]);
291 if ((rc =
tty_write(PortFD, (
const char *)cbuf.data(), cbuf.size() *
sizeof(cbuf[0]), &nbytes_written)) !=
TTY_OK)
294 LOGF_ERROR(
"Error writing command: %s. Cmd %s (%d)", errstr, cmdToString(
cmd),
cmd);
299int ScopeDomeUSB21::write(Command
cmd)
301 int nbytes_written = 0, rc = -1;
305 tcflush(PortFD, TCIOFLUSH);
308 cbuf[3] = CRC(0, cbuf[0]);
310 cbuf[3] = CRC(cbuf[3], cbuf[1]);
312 cbuf[3] = CRC(cbuf[3], cbuf[2]);
317 LOGF_DEBUG(
"write cmd: %x %x %x %x", cbuf[0], cbuf[1], cbuf[2], cbuf[3]);
318 if ((rc =
tty_write(PortFD, (
const char *)cbuf,
sizeof(cbuf), &nbytes_written)) !=
TTY_OK)
321 LOGF_ERROR(
"Error writing command: %s. Cmd: %s (%d)", errstr, cmdToString(
cmd),
cmd);
326int ScopeDomeUSB21::readBuf(Command &
cmd, uint8_t len, uint8_t *buff)
328 int nbytes_read = 0, rc = -1;
329 int BytesToRead = len + 4;
330 std::vector<uint8_t> cbuf(BytesToRead, 0);
337 LOGF_ERROR(
"Error reading: %s. Cmd: %s (%d)", errstr, cmdToString(prevcmd), prevcmd);
341 LOGF_DEBUG(
"readbuf cmd: %x %x %x %x", cbuf[0], cbuf[1], cbuf[2], cbuf[3]);
342 uint8_t Checksum = CRC(0, cbuf[0]);
343 Checksum = CRC(Checksum, cbuf[1]);
344 cmd = (Command)cbuf[2];
345 Checksum = CRC(Checksum, cbuf[2]);
347 for (
int i = 0; i < len; i++)
349 buff[i] = cbuf[i + 4];
350 Checksum = CRC(Checksum, cbuf[i + 4]);
353 if (cbuf[3] != Checksum)
355 LOGF_ERROR(
"readbuf checksum error, cmd: %s (%d)", cmdToString(prevcmd), prevcmd);
356 return CHECKSUM_ERROR;
358 if (
cmd == FunctionNotSupported)
360 LOGF_ERROR(
"readbuf not supported error, cmd: %s (%d)", cmdToString(prevcmd), prevcmd);
361 return FUNCTION_NOT_SUPPORTED_BY_FIRMWARE;
366 LOGF_ERROR(
"readbuf packet length error, cmd: %s (%d)", cmdToString(prevcmd), prevcmd);
367 return PACKET_LENGTH_ERROR;
372int ScopeDomeUSB21::read(Command &
cmd)
374 int nbytes_read = 0, rc = -1;
376 uint8_t cbuf[4] = { 0 };
383 LOGF_ERROR(
"Error reading: %s. Cmd %s (%d)", errstr, cmdToString(prevcmd), prevcmd);
387 LOGF_DEBUG(
"read cmd: %x %x %x %x", cbuf[0], cbuf[1], cbuf[2], cbuf[3]);
388 uint8_t Checksum = CRC(0, cbuf[0]);
389 Checksum = CRC(Checksum, cbuf[1]);
390 cmd = (Command)cbuf[2];
391 Checksum = CRC(Checksum, cbuf[2]);
393 if (cbuf[3] != Checksum || cbuf[1] != 0)
395 LOGF_ERROR(
"read checksum error, cmd: %s (%d)", cmdToString(prevcmd), prevcmd);
396 return CHECKSUM_ERROR;
401 LOGF_ERROR(
"read motion conflict, cmd: %s (%d)", cmdToString(prevcmd), prevcmd);
402 err = MOTION_CONFLICT;
405 case FunctionNotSupported:
406 LOGF_ERROR(
"read function not supported, cmd: %s (%d)", cmdToString(prevcmd), prevcmd);
407 err = FUNCTION_NOT_SUPPORTED;
411 LOGF_ERROR(
"read param error, cmd: %s (%d)", cmdToString(prevcmd), prevcmd);
423bool ScopeDomeUSB21::readFloat(Command
cmd,
float &dst)
433 rc = readBuf(c, 4, (uint8_t *)&value);
437 while (rc != 0 && --retryCount);
447bool ScopeDomeUSB21::readU8(Command
cmd, uint8_t &dst)
457 rc = readBuf(c, 1, &value);
461 while (rc != 0 && --retryCount);
471bool ScopeDomeUSB21::readS8(Command
cmd, int8_t &dst)
481 rc = readBuf(c, 1, (uint8_t *)&value);
485 while (rc != 0 && --retryCount);
495bool ScopeDomeUSB21::readU16(Command
cmd, uint16_t &dst)
505 rc = readBuf(c, 2, (uint8_t *)&value);
509 while (rc != 0 && --retryCount);
519bool ScopeDomeUSB21::readS16(Command
cmd, int16_t &dst)
529 rc = readBuf(c, 2, (uint8_t *)&value);
533 while (rc != 0 && --retryCount);
543bool ScopeDomeUSB21::readU32(Command
cmd, uint32_t &dst)
553 rc = readBuf(c, 4, (uint8_t *)&value);
557 while (rc != 0 && --retryCount);
567bool ScopeDomeUSB21::readS32(Command
cmd, int32_t &dst)
577 rc = readBuf(c, 4, (uint8_t *)&value);
581 while (rc != 0 && --retryCount);
591int ScopeDomeUSB21::readBuffer(Command
cmd,
int len, uint8_t *cbuf)
600 rc = readBuf(c, len, cbuf);
604 while (rc != 0 && --retryCount);
608int ScopeDomeUSB21::writeCmd(Command
cmd)
619int ScopeDomeUSB21::writeU8(Command
cmd, uint8_t value)
621 int rc = writeBuf(
cmd, 1, &value);
630int ScopeDomeUSB21::writeU16(Command
cmd, uint16_t value)
632 int rc = writeBuf(
cmd, 2, (uint8_t *)&value);
641int ScopeDomeUSB21::writeU32(Command
cmd, uint32_t value)
643 int rc = writeBuf(
cmd, 4, (uint8_t *)&value);
652int ScopeDomeUSB21::writeBuffer(Command
cmd,
int len, uint8_t *cbuf)
654 int rc = writeBuf(
cmd, len, cbuf);
663void ScopeDomeUSB21::reconnect()
670 int rc = readU16(GetStatus, status);
671 rc |= readS16(GetCounter, counter);
672 rc |= readBuffer(GetAllDigitalExt, 5, digitalSensorState);
683 uint16_t fwVersion = 0;
684 readU16(GetVersionFirmware, fwVersion);
685 main = fwVersion / 100.0;
687 uint8_t fwVersionRotary = 0;
688 readU8(GetVersionFirmwareRotary, fwVersionRotary);
689 rotary = (fwVersionRotary + 9) / 10.0;
694 uint32_t stepsPerRevolution = 0;
695 readU32(GetImpPerTurn, stepsPerRevolution);
696 return stepsPerRevolution;
712 channel = IN_CLOSED1;
718 channel = IN_CLOSED1;
721 channel = IN_ROT_LINK;
736 channel = OUT_RELAY1;
754 int ch = (int)channel;
756 uint8_t bit = 1 << (ch & 7);
762 return writeU8(onOff ==
ISS_ON ? SetDigitalChannel : ClearDigitalChannel, (uint8_t)channel);
772 readS32(GetCounterExt, counterExt);
778 uint8_t calibrationNeeded =
false;
779 readU8(IsFullSystemCalReq, calibrationNeeded);
780 return calibrationNeeded != 0;
790 writeCmd(FullSystemCal);
819 writeCmd(ResetCounter);
820 writeCmd(ResetCounterExt);
827 writeU16(CCWRotation, -steps);
831 writeU16(CWRotation, steps);
847 info.
label =
"Shutter link strength";
854 info.
label =
"Shutter internal power";
861 info.
label =
"Shutter battery power";
868 info.
label =
"Card internal power";
875 info.
label =
"Card battery power";
882 info.
label =
"Temperature in dome";
889 info.
label =
"Temperature outside dome";
895 info.
propName =
"TEMP_DOME_HUMIDITY";
896 info.
label =
"Temperature humidity sensor";
903 info.
label =
"Humidity";
910 info.
label =
"Pressure";
917 info.
label =
"Dew point";
937 readU8(GetLinkStrength, linkStrength);
938 value = linkStrength;
943 static int count = 0;
944 if (linkStrength == 0)
960 readFloat(GetAnalog1, sensors[0]);
964 readFloat(GetAnalog2, sensors[1]);
968 readFloat(GetMainAnalog1, sensors[2]);
972 readFloat(GetMainAnalog2, sensors[3]);
976 readFloat(GetTempIn, sensors[4]);
980 readFloat(GetTempOut, sensors[5]);
984 readFloat(GetTempHum, sensors[6]);
988 readFloat(GetHum, sensors[7]);
992 readFloat(GetPressure, sensors[8]);
996 value = parent->getDewPoint(sensors[7], sensors[6]);
1021 info.
label =
"Telescope";
1025 info.
label =
"Light";
1033 info.
label =
"Relay 1 (reset)";
1037 info.
label =
"Relay 2 (heater)";
1041 info.
label =
"Relay 3";
1045 info.
label =
"Relay 4";
1128 info.
label =
"Az counter";
1132 info.
label =
"Dome at home";
1136 info.
label =
"Shutter 1 open";
1140 info.
label =
"Shutter 1 closed";
1144 info.
label =
"Shutter 2 open";
1148 info.
label =
"Shutter 2 closed";
1152 info.
label =
"Scope at home";
1156 info.
label =
"Rain sensor";
1160 info.
label =
"Cloud sensor";
1164 info.
label =
"Observatory safe";
1168 info.
label =
"Rotary link";
1172 info.
label =
"Free input";
1229 writeU8(NegHomeSensorActiveState, negate);
virtual void calibrate() override
virtual void abort() override
virtual void getFirmwareVersions(double &main, double &rotary) override
virtual double getSensorValue(size_t index) override
virtual ISState getInputValue(size_t index) override
virtual int updateState() override
virtual int getRotationCounterExt() override
virtual uint32_t getStepsPerRevolution() override
virtual size_t getNumberOfRelays() override
virtual size_t getNumberOfInputs() override
virtual ISState getRelayState(size_t index) override
virtual int setOutputState(AbstractOutput output, ISState state) override
virtual void resetCounter() override
virtual uint32_t getStatus() override
virtual ISState getInputState(AbstractInput input) override
virtual void findHome() override
virtual bool detect() override
virtual size_t getNumberOfSensors() override
virtual int getRotationCounter() override
virtual RelayInfo getRelayInfo(size_t index) override
virtual bool isCalibrationNeeded() override
virtual SensorInfo getSensorInfo(size_t index) override
virtual void setRelayState(size_t index, ISState state) override
virtual void controlShutter(ShutterOperation operation) override
virtual void setHomeSensorPolarity(HomeSensorPolarity polarity) override
virtual InputInfo getInputInfo(size_t index) override
virtual void move(int steps) override
int tty_write(int fd, const char *buf, int nbytes, int *nbytes_written)
Writes a buffer to fd.
int tty_read(int fd, char *buf, int nbytes, int timeout, int *nbytes_read)
read buffer from terminal
void tty_error_msg(int err_code, char *err_msg, int err_msg_len)
Retrieve the tty error message.
Implementations for common driver routines.
#define LOGF_DEBUG(fmt,...)
#define LOG_ERROR(txt)
Shorter logging macros. In order to use these macros, the function (or method) "getDeviceName()" must...
#define LOGF_ERROR(fmt,...)
#define SCOPEDOME_TIMEOUT