/// <summary> /// Reads information from the Jrk and displays it in the textboxes. /// </summary> void DisplayStatus() { jrkVariables vars = jrk.getVariables(); TargetTextBox.Text = vars.target.ToString(); ScaledFeedbackTextBox.Text = vars.scaledFeedback.ToString(); }
static void Main() { List<DeviceListItem> list = Jrk.getConnectedDevices(); while(true) { string line; while((line=Console.ReadLine())!=null) { string[] p = line.Split(); if(p.Length==1) { ushort id = Convert.ToUInt16(p[0]); if(id>=list.Count){Console.WriteLine(-1);continue;}; jrk = new Jrk(list[id]); double current = 0.0; for(int i=0; i<100; i++) current += jrk.getVariables().current; Console.WriteLine(current); jrk.disconnect(); } if(p.Length==2) { ushort id = Convert.ToUInt16(p[0]); if(id>=list.Count)continue; ushort v = Convert.ToUInt16(Convert.ToDouble(p[1])*40.95); if(v>4095)v=4095; jrk = new Jrk(list[id]); jrk.setTarget(v); jrk.disconnect(); } } } }
// Starts the motor public static void startMotors() { if (NumOfConnectedJrks > 0) { UInt16 target = Jrk1.getVariables().target; Jrk1.setTarget(target); } if (NumOfConnectedJrks > 1) { UInt16 target = Jrk2.getVariables().target; Jrk2.setTarget(target); } if (NumOfConnectedJrks > 2) { UInt16 target = Jrk3.getVariables().target; Jrk3.setTarget(target); } if (NumOfConnectedJrks > 3) { UInt16 target = Jrk4.getVariables().target; Jrk4.setTarget(target); } }
// Pulls data from the devices and places it in the table created earlier. public static void updateTable(DataGridView dataTable) { DataTable flippedStatusValues = new DataTable(); string period; // // PULLING DATA FROM MAESTRO // statusValues.Clear(); if (NumOfConnectedMaestros > 0) { usc.getVariables(out maestroVars, out stack, out call_stack, out servos); errors = ""; foreach (var error in Enum.GetValues(typeof(uscError))) { if ((maestroVars.errors & (1 << (int)(uscError)error)) != 0) { errors += (error.ToString() + ", "); } } // // // Need to add data information for other values, if needed // // statusValues.Rows.Add("Maestro", usc.getSerialNumber(), errors, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); } // Case for when there are no connected Maestros else { statusValues.Rows.Add("Maestro", "No Maestros Found", "", -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); } // // PULLING DATA FROM JRK 1 // if (Program.NumOfConnectedJrks > 0 && usc.servoCount > 0) { // Preparing Jrk data input jrkVars = Jrk1.getVariables(); // Reading Jrk current // Easier to store in a variable before sending to the table. currentCalibrationForward = (Byte)Jrk1.getJrkParameter(jrkParameter.PARAMETER_MOTOR_CURRENT_CALIBRATION_FORWARD); currentCalibrationReverse = (Byte)Jrk1.getJrkParameter(jrkParameter.PARAMETER_MOTOR_CURRENT_CALIBRATION_REVERSE); current = currentToMilliamps(Jrk1, jrkVars.current, jrkVars.dutyCycle); // Reading Jrk errors // It's easier to store them all in one variable before sending to the table. errors = ""; if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_AWAITING_COMMAND)) { errors += "Awaiting command, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_NO_POWER)) { errors += "No power, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_MOTOR_DRIVER)) { errors += "Motor driver error, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_INPUT_INVALID)) { errors += "Input invalid, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_INPUT_DISCONNECT)) { errors += "Input disconnect"; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_FEEDBACK_DISCONNECT)) { errors += "Feedback disconnect, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_MAXIMUM_CURRENT_EXCEEDED)) { errors += "Max. current exceeded, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_SIGNAL)) { errors += "Serial signal error, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_OVERRUN)) { errors += "Serial overrun, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_BUFFER_FULL)) { errors += "Serial RX buffer full, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_CRC)) { errors += "Serial CRC error, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_PROTOCOL)) { errors += "Serial protocol error, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_TIMEOUT)) { errors += "Serial timeout error, "; } period = servos[0].position * 0.25 + " microseconds"; //Setting up the table with values statusValues.Rows.Add("Jrk", Jrk1.getSerialNumber(), errors, servos[0].position, period, jrkVars.target, jrkVars.scaledFeedback, jrkVars.feedback, jrkVars.errorSum, jrkVars.dutyCycleTarget, jrkVars.dutyCycle, servos[0].speed, servos[0].acceleration, current); } else { statusValues.Rows.Add("Jrk", "No Jrks Found"); } // // PULLING DATA FROM JRK 2 // if (Program.NumOfConnectedJrks > 1) { //Preparing Jrk data input jrkVars = Jrk2.getVariables(); //Reading Jrk current // Easier to store in a variable before sending to the table. currentCalibrationForward = (Byte)Jrk2.getJrkParameter(jrkParameter.PARAMETER_MOTOR_CURRENT_CALIBRATION_FORWARD); currentCalibrationReverse = (Byte)Jrk2.getJrkParameter(jrkParameter.PARAMETER_MOTOR_CURRENT_CALIBRATION_REVERSE); current = currentToMilliamps(Jrk2, jrkVars.current, jrkVars.dutyCycle); //Reading Jrk errors // It's easier to store them all in one variable before sending to the table. errors = ""; if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_AWAITING_COMMAND)) { errors += "Awaiting command, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_NO_POWER)) { errors += "No power, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_MOTOR_DRIVER)) { errors += "Motor driver error, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_INPUT_INVALID)) { errors += "Input invalid, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_INPUT_DISCONNECT)) { errors += "Input disconnect"; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_FEEDBACK_DISCONNECT)) { errors += "Feedback disconnect, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_MAXIMUM_CURRENT_EXCEEDED)) { errors += "Max. current exceeded, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_SIGNAL)) { errors += "Serial signal error, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_OVERRUN)) { errors += "Serial overrun, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_BUFFER_FULL)) { errors += "Serial RX buffer full, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_CRC)) { errors += "Serial CRC error, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_PROTOCOL)) { errors += "Serial protocol error, "; } if (1 == (1 & jrkVars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_TIMEOUT)) { errors += "Serial timeout error, "; } period = servos[1].position * 0.25 + " microseconds"; //Setting up the table with values statusValues.Rows.Add("Jrk", Jrk1.getSerialNumber(), errors, servos[1].position, period, jrkVars.target, jrkVars.scaledFeedback, jrkVars.feedback, jrkVars.errorSum, jrkVars.dutyCycleTarget, jrkVars.dutyCycle, servos[1].speed, servos[1].acceleration, current); } //Future extension to more devices /* * if (Program.NumOfConnectedJrks > 2) * { * } * if (Program.NumOfConnectedJrks > 3) * { * } */ flippedStatusValues.Columns.Add(""); string deviceTrack = ""; for (int i = 0; i < statusValues.Rows.Count; i++) { deviceTrack = "Device " + i; flippedStatusValues.Columns.Add(deviceTrack); } for (int i = 0; i < statusValues.Columns.Count; i++) { DataRow newRow = flippedStatusValues.NewRow(); newRow[0] = statusValues.Columns[i].Caption; for (int j = 0; j < statusValues.Rows.Count; j++) { newRow[j + 1] = statusValues.Rows[j][i]; } flippedStatusValues.Rows.Add(newRow); } // Configuring the table to show the data dataTable.DataSource = flippedStatusValues; }
static void MainWithExceptions(string[] args) { // If no arguments are given, just show the help message. if (args.Length == 0) { Console.Write(helpMessage()); Environment.Exit(2); } // Parse the arguments. Dictionary <String, String> opts = new Dictionary <string, string>(); string name = null; foreach (string rawArg in args) { string arg = rawArg; // Transform the short names in to the long names. switch (arg) { case "-l": arg = "--list"; break; case "-d": arg = "--device"; break; case "-s": arg = "--status"; break; } Match m = Regex.Match(arg, "^--(.*)"); if (m.Success) { name = m.Groups[1].ToString(); opts[name] = ""; // start it off with no string value } else if (name != null) { // This argument is right after a -- argument, so this argument // is its value. opts[name] = arg; name = null; } else { throw new ArgumentException("Unexpected argument \"" + arg + "\"."); } } if (opts.ContainsKey("list")) { if (args.Length > 1) { throw new ArgumentException("If --list is present, it must be the only option."); } listDevices(); return; } // Otherwise, we have to connect to a device. List <DeviceListItem> list = Jrk.getConnectedDevices(); // Make sure there is a device available.. if (list.Count == 0) { throw new Exception("No jrks found."); } DeviceListItem item = null; if (!opts.ContainsKey("device")) { // No serial number specified: connect to the first item in the list. item = list[0]; } else { // Serial number specified. // Remove the leading # sign. It is not standard to put it there, // but if someone writes it, this program should still work. string check_serial_number = opts["device"].TrimStart('#'); // Find the device with the specified serial number. foreach (DeviceListItem check_item in list) { if (check_item.serialNumber == check_serial_number) { item = check_item; break; } } if (item == null) { throw new Exception("Could not find a jrk with serial number " + opts["device"] + ".\n" + "To list devices, use the --list option."); } } // Connect to the device. jrk = new Jrk(item); if (opts.ContainsKey("bootloader")) { jrk.startBootloader(); return; } if (opts.ContainsKey("restoredefaults")) { jrk.setJrkParameter(jrkParameter.PARAMETER_INITIALIZED, 0xFF); jrk.reinitialize(); Thread.Sleep(1000); } if (opts.ContainsKey("configure")) { string filename = opts["configure"]; Stream stream = File.Open(filename, FileMode.Open); StreamReader sr = new StreamReader(stream); ConfigurationFile.load(sr, jrk); sr.Close(); stream.Close(); jrk.reinitialize(); } if (opts.ContainsKey("getconf")) { string filename = opts["getconf"]; Stream stream = File.Open(filename, FileMode.Create); StreamWriter sw = new StreamWriter(stream); ConfigurationFile.save(sw, jrk); sw.Close(); stream.Close(); } if (opts.ContainsKey("clearerrors")) { jrk.clearErrors(); } if (opts.ContainsKey("target")) { UInt16 target = stringToU12(opts["target"]); jrk.setTarget(target); } if (opts.ContainsKey("run")) { UInt16 target = jrk.getVariables().target; jrk.setTarget(target); } if (opts.ContainsKey("stop")) { jrk.motorOff(); } if (opts.ContainsKey("status")) { displayStatus(jrk); } if (opts.ContainsKey("stream")) { streamVariables(jrk, opts); } jrk.disconnect(); }
static void displayStatus(Jrk jrk) { Console.Write( "Serial number: " + jrk.getSerialNumber() + "\n" + "Firmware version: " + jrk.firmwareVersionString + "\n" ); storeCurrentCalibration(); jrkVariables vars = jrk.getVariables(); Console.Write( "Variables:\n" + " Input: " + vars.input + "\n" + " Target: " + vars.target + "\n" + " Feedback: " + vars.feedback + "\n" + " Scaled feedback: " + vars.scaledFeedback + "\n" + " Error: " + (vars.scaledFeedback - vars.target) + "\n" + " Integral: " + vars.errorSum + "\n" + " Duty cycle target: " + vars.dutyCycleTarget + "\n" + " Duty cycle: " + vars.dutyCycle + "\n" + " Current (mA): " + currentToMilliamps(vars.current, vars.dutyCycle) + "\n" ); if (vars.errorFlagBits == 0) { Console.WriteLine("No errors."); } else { Console.WriteLine("Errors:"); if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_AWAITING_COMMAND)) { Console.WriteLine(" Awaiting command"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_NO_POWER)) { Console.WriteLine(" No power"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_MOTOR_DRIVER)) { Console.WriteLine(" Motor driver error"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_INPUT_INVALID)) { Console.WriteLine(" Input invalid"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_INPUT_DISCONNECT)) { Console.WriteLine(" Input disconnect"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_FEEDBACK_DISCONNECT)) { Console.WriteLine(" Feedback disconnect"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_MAXIMUM_CURRENT_EXCEEDED)) { Console.WriteLine(" Max. current exceeded"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_SIGNAL)) { Console.WriteLine(" Serial signal error"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_OVERRUN)) { Console.WriteLine(" Serial overrun"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_BUFFER_FULL)) { Console.WriteLine(" Serial RX buffer full"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_CRC)) { Console.WriteLine(" Serial CRC error"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_PROTOCOL)) { Console.WriteLine(" Serial protocol error"); } if (1 == (1 & vars.errorFlagBits >> (byte)jrkError.ERROR_SERIAL_TIMEOUT)) { Console.WriteLine(" Serial timeout error"); } }; }
static void streamVariables(Jrk jrk, Dictionary <String, String> opts) { // Determine what interval to use (the time between each reading). int interval = 20; if (opts.ContainsKey("interval")) { try { interval = int.Parse(opts["interval"]); if (interval < 0) { throw new Exception("Value must be a non-negative whole number."); } } catch (Exception exception) { throw new Exception("Invalid interval parameter \"" + opts["interval"] + "\".", exception); } } // Determine the output format. if (opts.ContainsKey("format")) { // The user specified the format string completely. streamFormat = opts["format"].Replace("\\t", "\t"); } else { string separator = ","; if (opts.ContainsKey("separator")) { // The user just specified the separator separator = opts["separator"]; switch (separator) { case "space": separator = " "; break; case "\\t": case "tab": separator = "\t"; break; case "comma": separator = ","; break; } } if (separator == "\t") { // If the separator is a tab, then we don't need to have padding spaced. streamFormat = "{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}"; } else { // If the separator is something else, then we want padding to make each // field be a fixed width. streamFormat = "{0,6}" + separator + "{1,6}" + separator + "{2,4}" + separator + "{3,4}" + separator + "{4,4}" + separator + "{5,4}" + separator + "{6,6}" + separator + "{7,6}" + separator + "{8,4}" + separator + "{9,6}" + separator + "{10,4}"; } } // Determine the limit. if (opts.ContainsKey("limit")) { try { streamLineCountLimit = UInt32.Parse(opts["limit"]); } catch (Exception exception) { throw new Exception("Invalid limit parameter \"" + opts["limit"] + "\".", exception); } } // Print the header line if the user wanted it if (!opts.ContainsKey("noheader")) { Console.WriteLine(streamFormat, "Time (ms)", "PID Period Count", "Input", "Target", "Feedback", "Scaled feedback", "Integral", "Duty cycle target", "Duty cycle", "Current (mA)", "Error code", "PID period exceeded"); } // Prepare to process the current readings the Jrk will be sending us. storeCurrentCalibration(); if (interval == 0) { // Interval is zero so the user just wants the data as fast as possible. while (true) { streamPrintReading(DateTime.Now, jrk.getVariables()); } } else { // The three timer classes provided by the .NET framework do not // provide accurate timing so instead we poll DateTime.Now. // This takes more CPU power than the timer method, but we try // to minimize the CPU use by sleeping between readings. DateTime now = DateTime.Now; DateTime nextUpdateTime = now; while (true) { if (nextUpdateTime <= now) { // Get the reading from the Jrk over USB (should take about .2 ms). jrkVariables vars = jrk.getVariables(); streamPrintReading(now, vars); while (nextUpdateTime <= DateTime.Now) { nextUpdateTime = nextUpdateTime.AddMilliseconds(interval); } // Conserve CPU power by sleeping if (interval > 4 && !opts.ContainsKey("nosleep")) { Thread.Sleep(interval - 4); } } now = DateTime.Now; } } }