示例#1
0
        // Function for Sequence Control
        public void sequenceControl(List <Int32> ticks, List <Double> times)
        {
            // Wrtie the first 16 targets
            // Save values from the log registers
            for (ushort i = 0; i < 16; i++)
            {
                // Variables for increasing the register numbers
                ushort ch1 = (ushort)(Register.SeqTarget + i);
                ushort ch2 = (ushort)(Register.SeqTime + i);

                // Write values
                ModCom.RunModbus(ch1, ticks[i]);
                ModCom.RunModbus(ch2, (ushort)(times[i + 1] - times[i] * 1000));
            }

            // Set mode to sequence control
            ModCom.RunModbus(Register.Mode, 51); // Set the mode to positonramp

            bool done = false;

            // Start to continously update the sequence registers
            while (!done)
            {
            }
        }
示例#2
0
        //EventLogic,
        // The operands are used according to: "Trigger value = <Register> OPERATOR DataValue"
        // see p.20 in manual for more information about thie

        /* Note that only bits 0-3 of Register.EventControl is considered here.
         * 0           Always true
         * 1   =       Equal
         * 2   !=      Not equal
         * 3   <       Less than
         * 4   >       Greater than
         * 5   or      Bitwise or
         * 6   nor     Bitwise not or
         * 7   and     Bitwise and
         * 8   nand    Bitwise not and
         * 9   xor     Bitwise exclusive or
         * 10  nxor    Bitwise not exclusive or
         * 11  +       Add
         * 12  -       Subtract
         * 13  *       Multiply
         * 14  /       Divide
         * 15  Value   Takes data value directly
         */
        //

        // Function to create events. See p.19-21 in manual for more information about events
        public void CreateEvent(ushort EventNr,
                                Int16 TrgData,
                                Int16 TrgReg,
                                ushort EventLogic,
                                Int16 DstRegister,
                                ushort SrcData,
                                Int16 SrcRegister)
        {
            /* (ushort) EventNr,        Number between 0-19
             * (Int16)  TrgData,        Value that is used for event triggers
             * (Int16)  TrgReg,         Register that is read and used to trigger event
             * (ushort) EventLogic,     0XA--B where A is how the event should behave
             *                          and B is how the event should be triggered
             * (Int16)  DstRegister,    Destination register
             * (ushort) SrcData,        What should be written to the destination register
             * (Int16)  SrcRegister,    Combined with SrcData
             */

            // Write to the registers to "implement/create" the events
            ModCom.RunModbus((ushort)(Register.EventTrgData + EventNr), TrgData);
            ModCom.RunModbus((ushort)(Register.EventTrgReg + EventNr), TrgReg);
            ModCom.RunModbus((ushort)(Register.EventControl + EventNr), EventLogic);
            ModCom.RunModbus((ushort)(Register.EventDstReg + EventNr), DstRegister);
            ModCom.RunModbus((ushort)(Register.EventSrcData + EventNr), SrcData);
            ModCom.RunModbus((ushort)(Register.EventSrcReg + EventNr), SrcRegister);
        }
示例#3
0
        // Function to allow the user to manually control the motor, i.e the syring, from the console.
        public void ManualControl()
        {
            // Write to the console
            Console.WriteLine("Manual control active");
            Console.WriteLine("Press enter to exit, + to increase and - to decrease position");
            // Read current position from motor
            int CurrentPosition = ModCom.ReadModbus(Register.Position, 2, true);
            // Update last position to current position
            int LastPosition = CurrentPosition;
            // Define variable to save keyboard input from the user
            ConsoleKeyInfo input = new ConsoleKeyInfo();

            // As long as "Enter" is not pressed, continue
            while (Console.ReadKey().Key != ConsoleKey.Enter)
            {
                // Read the keyboard input
                input = Console.ReadKey(true);

                // In input is "+", increase currenposition with 50
                if (input.KeyChar == '+')
                {
                    CurrentPosition = CurrentPosition + 50;
                    Console.WriteLine("position increased");
                }

                // In input is "-", decrease currenposition with 50
                if (input.KeyChar == '-')
                {
                    CurrentPosition = CurrentPosition - 50;
                    Console.WriteLine("position decreased");
                }

                // If currenposition was updated, update position of motor
                if (CurrentPosition != LastPosition)
                {
                    ModCom.RunModbus(Register.TargetInput, CurrentPosition);
                    LastPosition = CurrentPosition;
                }
            }
            Console.WriteLine("Exiting manual control");
        }
示例#4
0
 // Function for setting upp the logging of values from motor
 // Position = 1     Logging for position control
 // Position = 0     Logging for velocity control
 public void setupLogging(int RegLogFactor, int Position)
 {
     // If position control
     if (Position == 1)
     {
         // Define registers to log
         ModCom.RunModbus(Register.LogRegister1, (ushort)(Register.Position + 1));     // Position
         ModCom.RunModbus(Register.LogRegister2, (ushort)(Register.TargetInput + 1));  // Regulator target
         ModCom.RunModbus(Register.LogRegister3, Register.Pressure);                   // Pressure
         ModCom.RunModbus(Register.LogRegister4, Register.LinearPosition);             // Linear position
     }
     else
     {
         // Define registers to log
         ModCom.RunModbus(Register.LogRegister1, Register.Speed);                      // Speed
         ModCom.RunModbus(Register.LogRegister2, (ushort)(Register.TargetInput + 1));  // Regulator target
         ModCom.RunModbus(Register.LogRegister3, Register.Pressure);                   // Pressure
         ModCom.RunModbus(Register.LogRegister4, Register.LinearPosition);             // Linear position
     }
     // Settings for the logging
     ModCom.RunModbus(Register.LogPeriod, (short)RegLogFactor);
     // Start logging
     ModCom.RunModbus(Register.LogState, (short)2);
 }
示例#5
0
        public void volumeTest()
        {
            // Define variable to save keyboard input from the user
            ConsoleKeyInfo input = new ConsoleKeyInfo();

            Console.WriteLine("Press Enter to start the volume test");

            // Start the volume test when enter is pressed
            while (Console.ReadKey().Key != ConsoleKey.Enter)
            {
            }



            // Initialize the motor
            ModCom.RunModbus(Register.Mode, Mode.MotorOff);     // Turn off the motor
            ModCom.RunModbus(Register.Speed, (Int32)0);         // Set the speed to 0
            ModCom.RunModbus(Register.Position, (Int32)0);      // Set the position to 0
            ModCom.RunModbus(Register.TargetInput, (Int32)0);   // Set the target to 0
            ModCom.RunModbus(Register.Mode, Mode.PositionRamp); // Set the mode to positonramp

            // Get the current linear position
            double currentPosition = sensorToLinPos(ModCom.ReadModbus(Register.LinearPosition, 1, false));
            double homePos         = currentPosition;
            double dist            = 3.304 + homePos;
            int    newPosition     = 0;
            bool   done            = false;

            Console.Write("Start Position in MM: ");
            Console.WriteLine(currentPosition);
            Console.Write("Start Position: ");
            Console.WriteLine(ModCom.ReadModbus(Register.LinearPosition, 1, false));

            while (!done)
            {
                // Read the current position
                currentPosition = sensorToLinPos(ModCom.ReadModbus(Register.LinearPosition, 1, false));

                // Define variable for how much to inrease
                int increase = 0;
                // Decide how much to increase with depending on how far away from home
                if (Math.Abs(currentPosition - dist) > 0.5)
                {
                    increase = 20;
                }
                else
                {
                    increase = 1;
                }

                // If the piston is to far into the syringe, turn the motor counterclockwise (piston is moved 0.mm)
                if (currentPosition < dist - Hardware.HomePosTolerance)
                {
                    // Increase the position
                    newPosition = newPosition - increase;
                }
                // Check if we are done
                else if (currentPosition > dist - Hardware.HomePosTolerance)
                {
                    // Decrease the position
                    done = true;
                }

                // Write the new position to the motor
                ModCom.RunModbus(Register.TargetInput, newPosition);
            }


            // Turn off the motor
            ModCom.RunModbus(Register.Mode, Mode.MotorOff);
            // Set the position to 0
            ModCom.RunModbus(Register.Position, (Int32)0);
            // Set the target to 0
            ModCom.RunModbus(Register.TargetInput, (Int32)0);


            Console.Write("End Position in MM: ");
            Console.WriteLine(currentPosition);
            Console.Write("End Position: ");
            Console.WriteLine(ModCom.ReadModbus(Register.LinearPosition, 1, false));
        }
示例#6
0
        // Function to initialize the motor and set the system in its home position
        public void goToHome()
        {
            // Tune the regulator
            ModCom.RunModbus(300, (Int16)1000); //P
            ModCom.RunModbus(301, (Int16)1000); //I
            ModCom.RunModbus(302, (Int16)0);    //D

            // Get the current linear position
            double currentPosition = sensorToLinPos(ModCom.ReadModbus(Register.LinearPosition, 1, false));

            // Chech if the current linear position is valid, if not throw an error
            if (currentPosition > Hardware.MaxPosition | currentPosition < Hardware.MinPosition)
            {
                throw new Exception("Measurement from linear sensor is out of physical range!");
            }

            // Boolean operator to keep track if home position found
            bool done = false;

            // Define value for the updated position for the motor
            int newPosition = 0;

            // Initialize the motor
            ModCom.RunModbus(Register.Mode, Mode.MotorOff);     // Turn off the motor
            ModCom.RunModbus(Register.Speed, (Int32)0);         // Set the speed to 0
            ModCom.RunModbus(Register.Position, (Int32)0);      // Set the position to 0
            ModCom.RunModbus(Register.TargetInput, (Int32)0);   // Set the target to 0
            ModCom.RunModbus(Register.Mode, Mode.PositionRamp); // Set the mode to positonramp

            // Run the motor until the system is in its homeposition
            while (!done)
            {
                // Read the current position
                currentPosition = (Double)sensorToLinPos(ModCom.ReadModbus(Register.LinearPosition, 1, false));

                // Define variable for how much to inrease
                int increase = 0;
                // Decide how much to increase with depending on how far away from home
                if (Math.Abs(currentPosition - Hardware.HomePosition) > 0.5)
                {
                    increase = 20;
                }
                else
                {
                    increase = 1;
                }

                // If the piston is to far into the syringe, turn the motor counterclockwise (piston is moved 0.mm)
                if (currentPosition > Hardware.HomePosition + Hardware.HomePosTolerance)
                {
                    // Increase the position
                    newPosition = newPosition + increase;
                }
                // If the piston is to far out of the syringe, turn the motor clockwise
                else if (currentPosition < Hardware.HomePosition - Hardware.HomePosTolerance)
                {
                    // Decrease the position
                    newPosition = newPosition - increase;
                }

                // Check if we are done
                if (currentPosition <Hardware.HomePosition + Hardware.HomePosTolerance&
                                     currentPosition> Hardware.HomePosition - Hardware.HomePosTolerance)
                {
                    done = true;
                }
                Console.Write("Current Position: ");
                Console.WriteLine(currentPosition);

                // Write the new position to the motor
                ModCom.RunModbus(Register.TargetInput, newPosition);
            }
            Console.Write("Current Position: ");
            Console.WriteLine(currentPosition);
            // Turn off the motor
            ModCom.RunModbus(Register.Mode, Mode.MotorOff); // Set the mode to positonramp
            // Set the position to 0
            ModCom.RunModbus(Register.Position, (Int32)0);
            // Set the target to 0
            ModCom.RunModbus(Register.TargetInput, (Int32)0);
        }
示例#7
0
        // Function to actually run the motor based on a list of ticks, i.e a list with angular positions
        // for the motor, a list of times and a given mode.
        public void RunTickSequence(List <Int32> ticks, List <Double> times, Int16 mode)
        {
            // If the number of ticks and number of times are not equal, throw an error
            if (ticks.Count() != times.Count())
            {
                throw new Exception("Input lists not of equal length");
            }
            // Create event reading the maximum torque status register
            CreateEvent((ushort)0,
                        (Int16)(0B000000000100000),                         // Bitmask to get torque from status register
                        (Int16)(MotorControl.Register.Status),
                        (ushort)0XF007,                                     // Logical 'and' between bitmask and status register
                        (Int16)(MotorControl.Register.Mode),
                        (ushort)0,
                        (Int16)0);                                          // No source register

            // Set a maximum allowed torque
            ModCom.RunModbus(MotorControl.Register.MotorTorqueMax, Hardware.MaxTorque);
            // Define the sequence length
            int sequenceLength = ticks.Count();
            // Create an instance of Stopwatch used to measure the time
            Stopwatch stopWatch = new Stopwatch();

            // Define lists to save logged motor values
            Int32[] LogRecordedVelocities      = new Int32[500];
            Int32[] LogRecordedTargets         = new Int32[500];
            Int32[] LogRecordedPressures       = new Int32[500];
            Int32[] LogRecordedLinearPositions = new Int32[500];

            // Define list for the actual time
            Double[] StopwatchRecordedTimes = new Double[sequenceLength];

            // Add time values to LoggedTime and compute the LogFactor for logging
            int RegLogFactor = createTimeVector(times, sequenceLength);

            // Run the system to its home position
            goToHome();

            // SET the PID-parameters
            ModCom.RunModbus(300, (Int16)10000); //P
            ModCom.RunModbus(301, (Int16)1000);  //I
            ModCom.RunModbus(302, (Int16)0);     //D


            // Initializing the motor
            ModCom.RunModbus(Register.Mode, Mode.MotorOff);     // Turn off the motor
            ModCom.RunModbus(Register.Speed, (Int32)0);         // Set the speed to 0
            ModCom.RunModbus(Register.Position, (Int32)0);      // Set the position to 0
            ModCom.RunModbus(Register.TargetInput, (Int32)0);   // Set the motor to be continously controlled via communication bus
            // Set the mode of the motor to the given mode
            ModCom.RunModbus(Register.Mode, mode);
            // Set time = 0 in the motor time register
            ModCom.RunModbus(Register.Time, (Int32)0);

            // Setup and start the logging
            setupLogging(RegLogFactor, 0);

            // Start to run the actual sequence and send regulator targets to the motor
            int i = 0;

            // Start to measure time at computer
            stopWatch.Start();
            while (i < sequenceLength)
            {
                // If more time have elapsed than times[i], send a new regulator target to the motor
                if (times[i] <= stopWatch.Elapsed.TotalSeconds)
                {
                    // Write a new target value to the motor
                    ModCom.RunModbus(Register.TargetInput, (Int32)ticks[i]);
                    // Read time
                    StopwatchRecordedTimes[i] = stopWatch.Elapsed.TotalSeconds;
                    i++;
                }
            }

            // Set target to zero
            ModCom.RunModbus(Register.TargetInput, (Int32)0);
            // Turn off the motor
            ModCom.RunModbus(Register.Mode, Mode.MotorOff);
            // Stop counting the time
            stopWatch.Stop();

            // Read and save logged values from motor
            saveLoggedValues(LogRecordedVelocities, LogRecordedTargets,
                             LogRecordedPressures, LogRecordedLinearPositions, 1);

            // Convert Ticks to positions
            LoggedVelocities = MotorSpeedToVelocity(LogRecordedVelocities);
            // Convert Ticks to velocity
            LoggedTargets = TicksPerSecondToVelocity(LogRecordedTargets);
            // Convert sensorreading to linear position
            LoggedLinearPositions = sensorToLinPosList(LogRecordedLinearPositions);
            //LoggedPressures = uns16ToVDc(LogRecordedPressures);
        }