/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Handles inbound data events. /// /// NOTE: You are not on the Main Form Thread here. /// </summary> /// <history> /// 19 Nov 18 Cynic - Started /// </history> private void ServerClientDataEventHandler(object sender, ServerClientData scData) { if (scData == null) { LogMessage("ServerClientDataEventHandler scData==null"); return; } // Ok, you probably already know this but I'll note it here because this is so important // You do NOT want to update any form controls from a thread that is not the forms main // thread. Very odd, intermittent and hard to debug problems will result. Even if your // handler does not actually update any form controls do not do it! Sooner or later you // or someone else will make changes that calls something that eventually updates a // form or control and then you will have introduced a really hard to find bug. // So, we always use the InvokeRequired...Invoke sequence to get us back on the form thread if (InvokeRequired == true) { // call ourselves again but this time be on the form thread. Invoke(new TCPDataTransporter.ServerClientDataEvent_Delegate(ServerClientDataEventHandler), new object[] { sender, scData }); return; } // Now we KNOW we are on the main form thread. // what type of data is it if (scData.DataContent == ServerClientDataContentEnum.USER_DATA) { // it is user defined data, log it LogMessage("ServerClientDataEventHandler dataStr=" + scData.DataStr); // display it AppendDataToTrace("IN: dataInt= dataStr=" + scData.DataStr); } else if (scData.DataContent == ServerClientDataContentEnum.REMOTE_CONNECT) { // the remote side has connected LogMessage("ServerClientDataEventHandler REMOTE_CONNECT"); // display it AppendDataToTrace("IN: REMOTE_CONNECT"); // set the screen SetScreenVisualsBasedOnConnectionState(true); } else if (scData.DataContent == ServerClientDataContentEnum.REMOTE_DISCONNECT) { // the remote side has connected LogMessage("ServerClientDataEventHandler REMOTE_DISCONNECT"); // display it AppendDataToTrace("IN: REMOTE_DISCONNECT"); // set the screen SetScreenVisualsBasedOnConnectionState(false); // shut things down on our end ShutdownDataTransporter(); } }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Sends the data from the screen to the client /// </summary> /// <history> /// 19 Nov 18 Cynic - Started /// </history> private void SendDataFromScreenToClient() { if (dataTransporter == null) { LogMessage("SendDataFromScreenToClient, dataTransporter == null"); return; } if (IsConnected() == false) { LogMessage("SendDataFromScreenToClient, Not connected"); return; } // some sanity checks if (stepperControlSTEP0.StepSpeed == 0) { OISMessageBox("STEPPER 0, zero is not a valid speed"); return; } if (stepperControlSTEP1.StepSpeed == 0) { OISMessageBox("STEPPER 1, zero is not a valid speed"); return; } if (stepperControlSTEP2.StepSpeed == 0) { OISMessageBox("STEPPER 2, zero is not a valid speed"); return; } if (stepperControlSTEP3.StepSpeed == 0) { OISMessageBox("STEPPER 3, zero is not a valid speed"); return; } if (stepperControlSTEP4.StepSpeed == 0) { OISMessageBox("STEPPER 4, zero is not a valid speed"); return; } if (stepperControlSTEP5.StepSpeed == 0) { OISMessageBox("STEPPER 5, zero is not a valid speed"); return; } // get the server client data from the screen ServerClientData scData = GetSCDataFromScreen("Data from server to client"); // display it AppendDataToTrace("OUT: dataStr=" + scData.DataStr); // send it dataTransporter.SendData(scData); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Handles presses on the buttonSendMessage button /// </summary> /// <history> /// 10 Nov 18 Cynic - Started /// </history> private void buttonSendMessage_Click(object sender, EventArgs e) { LogMessage("buttonSendMessage_Click"); if (dataTransporter == null) { OISMessageBox("No data transporter"); return; } ServerClientData scData = new ServerClientData(111, "test from server to client"); // display it AppendDataToTrace("OUT: dataInt=" + scData.DataInt.ToString() + " dataStr=" + scData.DataStr); // send it dataTransporter.SendData(scData); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Handles inbound data events /// </summary> /// <param name="scData">the server client data object</param> /// <history> /// 19 Nov 18 Cynic - Started /// </history> private void ServerClientDataEventHandler(object sender, ServerClientData scData) { if (scData == null) { LogMessage("ServerClientDataEventHandler scData==null"); Console.WriteLine("ServerClientDataEventHandler scData==null"); return; } // what type of data is it if (scData.DataContent == ServerClientDataContentEnum.USER_DATA) { // user content LogMessage("ServerClientDataEventHandler dataStr=" + scData.DataStr + ", Data=" + scData.ToString()); Console.WriteLine("inbound data received: dataStr=" + scData.DataStr + ", Data=" + scData.ToString()); // send the data to the PRU SetPRUSteppersFromServerClientData(scData); // for the purposes of demonstration, send an ack now if (dataTransporter == null) { LogMessage("ServerClientDataEventHandler dataTransporter==null"); Console.WriteLine("ServerClientDataEventHandler dataTransporter==null"); return; } // send it ServerClientData ackData = new ServerClientData("ACK from client to server"); dataTransporter.SendData(ackData); } else if (scData.DataContent == ServerClientDataContentEnum.REMOTE_CONNECT) { // the remote side has connected LogMessage("ServerClientDataEventHandler REMOTE_CONNECT"); Console.WriteLine("ServerClientDataEventHandler REMOTE_CONNECT"); } else if (scData.DataContent == ServerClientDataContentEnum.REMOTE_DISCONNECT) { // the remote side has connected LogMessage("ServerClientDataEventHandler REMOTE_DISCONNECT"); Console.WriteLine("ServerClientDataEventHandler REMOTE_DISCONNECT"); } }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Shutsdown the data transporter safely /// </summary> /// <history> /// 19 Nov 18 Cynic - Started /// </history> private void ShutdownDataTransporter() { // shutdown the data transporter if (dataTransporter != null) { // are we connected? we want to tell the client to exit if (IsConnected() == true) { // get the server client data from the screen ServerClientData scData = GetSCDataFromScreen("Client close down message"); // set a special flag in here scData.AllStep_Enable = 2; // display it AppendDataToTrace("OUT: dataStr=" + scData.DataStr); // send it dataTransporter.SendData(scData); } dataTransporter.Shutdown(); dataTransporter = null; } }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// Gets the server client data from the screen and returns the populated /// container /// </summary> /// <returns>a populated ServerClientData container</returns> /// <history> /// 19 Nov 18 Cynic - Started /// </history> private ServerClientData GetSCDataFromScreen(string scDataText) { if (scDataText == null) { scDataText = "Data from Server to Client"; } ServerClientData scData = new ServerClientData(scDataText); // now get the data off the screen scData.Step0_Enable = stepperControlSTEP0.StepEnabled; scData.Step0_DirState = stepperControlSTEP0.StepDir; if (radioButtonHz.Checked == true) { scData.Step0_StepSpeed = ConvertHzToCycles(stepperControlSTEP0.StepSpeed); } else { scData.Step0_StepSpeed = stepperControlSTEP0.StepSpeed; } scData.Step1_Enable = stepperControlSTEP1.StepEnabled; scData.Step1_DirState = stepperControlSTEP1.StepDir; if (radioButtonHz.Checked == true) { scData.Step1_StepSpeed = ConvertHzToCycles(stepperControlSTEP1.StepSpeed); } else { scData.Step1_StepSpeed = stepperControlSTEP1.StepSpeed; } scData.Step2_Enable = stepperControlSTEP2.StepEnabled; scData.Step2_DirState = stepperControlSTEP2.StepDir; if (radioButtonHz.Checked == true) { scData.Step2_StepSpeed = ConvertHzToCycles(stepperControlSTEP2.StepSpeed); } else { scData.Step2_StepSpeed = stepperControlSTEP2.StepSpeed; } scData.Step3_Enable = stepperControlSTEP3.StepEnabled; scData.Step3_DirState = stepperControlSTEP3.StepDir; if (radioButtonHz.Checked == true) { scData.Step3_StepSpeed = ConvertHzToCycles(stepperControlSTEP3.StepSpeed); } else { scData.Step3_StepSpeed = stepperControlSTEP3.StepSpeed; } scData.Step4_Enable = stepperControlSTEP4.StepEnabled; scData.Step4_DirState = stepperControlSTEP4.StepDir; if (radioButtonHz.Checked == true) { scData.Step4_StepSpeed = ConvertHzToCycles(stepperControlSTEP4.StepSpeed); } else { scData.Step4_StepSpeed = stepperControlSTEP4.StepSpeed; } scData.Step5_Enable = stepperControlSTEP5.StepEnabled; scData.Step5_DirState = stepperControlSTEP5.StepDir; if (radioButtonHz.Checked == true) { scData.Step5_StepSpeed = ConvertHzToCycles(stepperControlSTEP5.StepSpeed); } else { scData.Step5_StepSpeed = stepperControlSTEP5.StepSpeed; } // get the global enable if (checkBoxEnabledSTEPALL.Checked == true) { scData.AllStep_Enable = 1; } else { scData.AllStep_Enable = 0; } return(scData); }
/// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+= /// <summary> /// A function to send data received from the server over to the /// code running in the PRU /// /// </summary> /// <param name="scData">the server client data object</param> /// <history> /// 19 Nov 18 Cynic - Originally written /// </history> public void SetPRUSteppersFromServerClientData(ServerClientData scData) { // sanity check if (scData == null) { LogMessage("SetPRUSteppersFromServerClientData, scData==null"); return; } // write the allstep_enable flag pruDriver.WritePRUDataUInt32(scData.AllStep_Enable, ALLSTEP_ENABLE_OFFSET); // write the STEP0 enable/disable flag pruDriver.WritePRUDataUInt32(scData.Step0_Enable, STEP0_ENABLED_OFFSET); // write the STEP0 fullcount value pruDriver.WritePRUDataUInt32(scData.Step0_StepSpeed, STEP0_FULLCOUNT); // write the STEP0 direction flag pruDriver.WritePRUDataUInt32(scData.Step0_DirState, STEP0_DIRSTATE); // write the STEP1 enable/disable flag pruDriver.WritePRUDataUInt32(scData.Step1_Enable, STEP1_ENABLED_OFFSET); // write the STEP1 fullcount value pruDriver.WritePRUDataUInt32(scData.Step1_StepSpeed, STEP1_FULLCOUNT); // write the STEP1 direction flag pruDriver.WritePRUDataUInt32(scData.Step1_DirState, STEP1_DIRSTATE); // write the STEP2 enable/disable flag pruDriver.WritePRUDataUInt32(scData.Step2_Enable, STEP2_ENABLED_OFFSET); // write the STEP2 fullcount value pruDriver.WritePRUDataUInt32(scData.Step2_StepSpeed, STEP2_FULLCOUNT); // write the STEP2 direction flag pruDriver.WritePRUDataUInt32(scData.Step2_DirState, STEP2_DIRSTATE); // write the STEP3 enable/disable flag pruDriver.WritePRUDataUInt32(scData.Step3_Enable, STEP3_ENABLED_OFFSET); // write the STEP3 fullcount value pruDriver.WritePRUDataUInt32(scData.Step3_StepSpeed, STEP3_FULLCOUNT); // write the STEP3 direction flag pruDriver.WritePRUDataUInt32(scData.Step3_DirState, STEP3_DIRSTATE); // write the STEP4 enable/disable flag pruDriver.WritePRUDataUInt32(scData.Step4_Enable, STEP4_ENABLED_OFFSET); // write the STEP4 fullcount value pruDriver.WritePRUDataUInt32(scData.Step4_StepSpeed, STEP4_FULLCOUNT); // write the STEP4 direction flag pruDriver.WritePRUDataUInt32(scData.Step4_DirState, STEP4_DIRSTATE); // write the STEP5 enable/disable flag pruDriver.WritePRUDataUInt32(scData.Step5_Enable, STEP5_ENABLED_OFFSET); // write the STEP5 fullcount value pruDriver.WritePRUDataUInt32(scData.Step5_StepSpeed, STEP5_FULLCOUNT); // write the STEP5 direction flag pruDriver.WritePRUDataUInt32(scData.Step5_DirState, STEP5_DIRSTATE); // pump the current state out to the console Console.WriteLine(scData.GetState()); LogMessage("scData=" + scData.GetState()); // write the semaphore. This must come last, the code running in the // PRU will see this change and set things up according to the // other configuration items above pruDriver.WritePRUDataUInt32(1, SEMAPHORE_OFFSET); }