#ifndef __ESPEC_IF__ #define __ESPEC_IF__ /** * @file * * 恒温槽をリモート制御するためのヘッダ * * 標準モードの運用を前提にしたソース * 通信は * 19200bps * stop: 1bit * data: 8bits * parity: none * delimiter CR + LF */ #include #include #include #include #include #ifdef _WIN32 #include #define sleep(seconds) (Sleep(seconds*1000)) #else #include #endif #include "util/comstream.h" class EspecIF { private: ComportStream comport; #ifdef _WIN32 static void reconfig_dcb(DCB &dcb) { dcb.BaudRate = CBR_19200; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.fParity = FALSE; dcb.StopBits = ONESTOPBIT; dcb.fBinary = TRUE; // バイナリモード dcb.fNull = FALSE; // NULLバイトは破棄しない dcb.fOutX = FALSE; // XONなし dcb.fInX = FALSE; // XOFFなし //dcb.fOutxCtsFlow = FALSE; // CTSフロー制御なし //dcb.fOutxDsrFlow = FALSE; // DSRフロー制御なし //dcb.fDsrSensitivity = FALSE; // DSR制御なし } #else #error Assume non-Windows? Unsupported!! #endif static const char CRLF[]; static std::ostream &crlf(std::ostream &out){ return out << CRLF; } public: std::string tx_rx(const std::string &command){ std::string res; comport << command; #if DEBUG std::cerr << "TX: " << command; #endif sleep(1); // 1秒待つ char c[32] = {0}; comport.readsome(c, sizeof(c) - 1); res.append(c); //std::getline(comport, res); #if DEBUG std::cerr << "RX: " << res << std::endl; #endif return res; } EspecIF(const char *port_spec) throw(std::ios_base::failure) : comport(port_spec){ comport.buffer().config_dcb(reconfig_dcb); // 冷凍機については自動設定にしておく std::stringstream command; command << "SET, REF9" << crlf; std::string res(tx_rx(command.str())); } ~EspecIF(){} bool set_temperature(const double °reeC){ // 温度をセット { std::stringstream command; command << "TEMP, S" << std::setprecision(1) << std::fixed << degreeC << crlf; std::string res(tx_rx(command.str())); if(!res.size() || (res.find("OK") != 0)){return false;} } // 定値運転にする { std::stringstream command; command << "MODE, CONSTANT" << crlf; std::string res(tx_rx(command.str())); if(!res.size() || (res.find("OK") != 0)){return false;} } // 設定温度になるまで待つ while(true){ std::stringstream command; sleep(10); // 10秒待つ double current; command << "TEMP?" << crlf; std::string res(tx_rx(command.str())); if(!res.size()){return false;} // 4つの値がカンマ区切りで得られる // 測定温度、温度設定値、温度警報(上限)、温度警報(下限) std::stringstream(res) >> current; if(std::abs(degreeC - current) <= 0.15){break;} } return true; } ///< スタンバイ状態にする bool standby(){ { std::stringstream command; command << "MODE, STANDBY" << crlf; std::string res(tx_rx(command.str())); if(!res.size() || (res.find("OK") != 0)){return false;} } return true; } }; const char EspecIF::CRLF[] = "\r\n"; #endif /* __ESPEC_IF__ */