/// <summary> /// Tries to connect to the psu. /// </summary> /// <param name="portname">Name of the com port that has the psu attached</param> /// <returns>true if connected</returns> public bool Connect(string portname) { serport1.Open(portname, 9600); //send one cmd to check if the psu is there SerialPortHandler.SerialTask task = null; for (int retries = 0; retries < 2; retries++) { serport1.Send(new SerialPortHandler.SerialTask(SerialMsgType.INITOUTENA, "STATUS?", SERIAL_RECV_TIMEOUT_KEEP)); //send a status request to see if the psu is present and set the outputenabled state while (!serport1.TryRecv(out task)) { ; } if (task.Recv.Length == 1) { break; } } if (task.Recv.Length != 1) { //we didnt get the expected single byte back serport1.Close(); return(false); } SetStatusIndicators((byte)task.Recv[0]); Resync(); //enable comms processing: consecutiveEmptyReplies = 0; StartOtherThread(); return(true); }
private void OtherThread() { SerialPortHandler.SerialTask task = null; while (serport1.IsOpen && !stopOtherThread_CancelToken.Token.IsCancellationRequested) { //send new commands if the transmit queue is empty: (avoids creating a large backlog because of differing transfer rates) if (serport1.SendCount == 0) { if (!retreivingSetpoints) { if (setpointOutputEnable != prevSetOutputEnable) { prevSetOutputEnable = setpointOutputEnable; serport1.Send(new SerialPortHandler.SerialTask(SerialMsgType.DONTCARE, "OUT" + (setpointOutputEnable ? "1" : "0"), SERIAL_RECV_TIMEOUT_TOSS)); } if (setpointVoltage != prevSetVoltage) { prevSetVoltage = setpointVoltage; serport1.Send(new SerialPortHandler.SerialTask(SerialMsgType.VSET, "VSET1:" + ((double)setpointVoltage / 100).ToString("00.00", new CultureInfo("en-US")), SERIAL_RECV_TIMEOUT_TOSS)); } if (setpointCurrent != prevSetCurrent) { prevSetCurrent = setpointCurrent; serport1.Send(new SerialPortHandler.SerialTask(SerialMsgType.ISET, "ISET1:" + ((double)setpointCurrent / 1000).ToString("0.000", new CultureInfo("en-US")), SERIAL_RECV_TIMEOUT_TOSS)); } } serport1.Send(new SerialPortHandler.SerialTask(SerialMsgType.STATUS, "STATUS?", SERIAL_RECV_TIMEOUT_KEEP)); serport1.Send(new SerialPortHandler.SerialTask(SerialMsgType.VOUT, "VOUT1?", SERIAL_RECV_TIMEOUT_KEEP)); serport1.Send(new SerialPortHandler.SerialTask(SerialMsgType.IOUT, "IOUT1?", SERIAL_RECV_TIMEOUT_KEEP)); } bool msgReceived = false; try { msgReceived = serport1.TryRecv(out task, 100, stopOtherThread_CancelToken.Token); } catch { // OperationCanceledException } if (msgReceived) { //handle all command replies: //Console.WriteLine("{0}: {1} -> {2} {3} : {4}", task.Tag, ToLiteral(task.Send), ToLiteral(task.Recv), serport1.SendCount, serport1.RecvCount); if (task.Recv.Length == 0) { if (task.WaitTime != SERIAL_RECV_TIMEOUT_TOSS) { //we expected a reply but didn't get one consecutiveEmptyReplies++; if (consecutiveEmptyReplies >= SERIAL_MAXEMPTYREPLIES) { //psu is considered not connected anymore break; } } continue; } else if (task.WaitTime != SERIAL_RECV_TIMEOUT_TOSS) { consecutiveEmptyReplies = 0; } if (((SerialMsgType)task.Tag != SerialMsgType.STATUS) && (!char.IsDigit(task.Recv[0]))) { continue; //filter misformed replies } double tempvalue; switch (task.Tag) { //received cc/cv and output enabled state from psu (happens frequent) case SerialMsgType.STATUS: SetStatusIndicators((byte)task.Recv[0]); break; //received actual v/i output from psu (happens frequent) case SerialMsgType.VOUT: if (double.TryParse(task.Recv, NumberStyles.Any, new CultureInfo("en-US"), out currentVoltage)) { // nothing... } break; case SerialMsgType.IOUT: if (double.TryParse(task.Recv, NumberStyles.Any, new CultureInfo("en-US"), out currentCurrent)) { //status, v and i received, so notify eventhandlers: (when we send requests the status and the V are asked first so here we should have received status and V already) OnOutputUpdate?.Invoke(this, EventArgs.Empty); } break; //received setpoint v/i output from psu (happens only at connect and resync) case SerialMsgType.VGET: if (double.TryParse(task.Recv, NumberStyles.Any, new CultureInfo("en-US"), out tempvalue)) { this.SetpointV = tempvalue; prevSetVoltage = setpointVoltage; } break; case SerialMsgType.IGET: if (double.TryParse(task.Recv, NumberStyles.Any, new CultureInfo("en-US"), out tempvalue)) { this.SetpointI = tempvalue; prevSetCurrent = setpointCurrent; retreivingSetpoints = false; //v and i received, so notify eventhandlers: OnSetpointUpdate?.Invoke(this, EventArgs.Empty); } break; default: break; } } } if (!stopOtherThread_CancelToken.Token.IsCancellationRequested) { //if we're not volantarily stopping, notify the error Console.WriteLine("[OtherThread] error"); if (serport1.IsOpen) { serport1.Close(); } NotifyOnSurpriseDisconnect(); } Console.WriteLine("[OtherThread] exit"); }