C# help please

Hello,
I have essentially no C# experience but I am learning. I would like to send a serial command to my Meastro 12 to “Restart script at subroutine with parameter”. I have successfully written a program to do this if I enter the 2 “parameter” hex codes individually…but, am struggling with how to convert from a single decimal less that 16383 to the parameter low and high bits. (hopefully I said that right). Any chance someone could help me with this or, better yet provide the code?
Thanks in advance,
Kevin

The code you would use to create two serial bytes from a single value is very similar to the example code in the user’s guide for the Maestro’s Set Target command. Something like this should work for you:

serialBytes[2] = value & 0x7F; // Second byte holds the lower 7 bits.  
serialBytes[3] = (value >> 7) & 0x7F;   // Third data byte holds the bits 7-13.

You should also be aware that we have several C# examples in the Pololu USB SDK which use the native USB interface to control the Maestro.

–David

Thank you for the prompt reply. I’m clearly clueless…not sure how I can put that into this, where the “127’s” represent arbitrary values that look like should be replaced by your “value”???

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;


namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //configuring the serial port
                serialPort1.PortName="COM5";
                serialPort1.BaudRate=9600;
                serialPort1.DataBits=8;
                serialPort1.Parity = Parity.None;
                serialPort1.StopBits = StopBits.One;
                int para1 = 127;
                int para2 = 127;
                string para1Hex = para1.ToString("X");
                byte para1Byte = byte.Parse(para1Hex, System.Globalization.NumberStyles.HexNumber);
                string para2Hex = para2.ToString("X");
                byte para2Byte = byte.Parse(para2Hex, System.Globalization.NumberStyles.HexNumber);



                //opening the serial port
                serialPort1.Open();

                //write data to serial port
                serialPort1.Write(new byte[] {0xA8,0x00,(byte)para1,(byte)para2},0,4);

                //close the port
                serialPort1.Close();

You were almost there. Try this instead:

        private void button1_Click(object sender, EventArgs e)
        {
            //configuring the serial port
                serialPort1.PortName="COM5";
                serialPort1.BaudRate=9600;
                serialPort1.DataBits=8;
                serialPort1.Parity = Parity.None;
                serialPort1.StopBits = StopBits.One;
                uint value = 6000;   // put whatever you want here
                byte para1 = value & 0x7F;
                byte para2 = (value >> 7) & 0x7F;

                serialPort1.Open();
                serialPort1.Write(new byte[] {0xA8,0x00,para1,para2},0,4);
                serialPort1.Close();
        }

Also remember that you will need to put your Maestro in to USB Dual Port mode, you will need to select the correct COM port (specifically, the Command Port), and all serial settings besides PortName are irrelevant so you can remove the lines of code that set those.

–David

Thank you David. For some reason that didn’t work(namespace, assembly, enum…ya de ya) I’ll skip the details because I’m looking into the native USB suggestion and it’s looking very promising…I’m sure I’ll have questions.
Thanks again,
Kevin

well I got things working using the native USB…much better, thanks for your help. I do have one more question.
Is it possible to compare the top number on the stack to the one right below it(Meastro 6 or 12)? My application uses characteristics from a digital picture, that are conveyed as numbers within its file name. I am able to put that number on the stack with a mod to the SDK Easy example using restartScriptAtSubroutineWithParameter, but I need to be able to compare the next number to the previous number to determine direction of movement. I tried just subtracting which works once, then the numbers are lost. Unfortunately the numbers are not always the same so I cannot just compare to a constant…I need to compare one to the next. I was hoping to do this with a Meastro script as oppsed to writing code.
Is it possible? (hope that made sense…)
Thank you,
Kevin

Hello,

Whenever you restart the script, the contents of the stack are erased. So you cannot do what I think you want to do.

What does not make sense to me is that you think it will be easier to write code on the Maestro rather than in C#. In general, if you have a computer powerful enough to run C# programs, you should take full advantage of it and not bother with Maestro scripts at all. A C# program will be literally thousands of times faster, and the language is about a thousand times better, so it should be far easier for you to do anything in C# than in the Maestro language.

Still, is it possible that you can do sometime like what you want using the GET_POSITION function in the Maestro language?

-Paul

Thanks Paul, I’ve been trying to figure out if the GET_POSITION will work. Problem is I’m not using servos. I know…WHAT…I started this project w/ a cont. rotation servo but changed to a stepper(via L293). I’m trying to see if I can just use a channel (or 2) to ‘hold’ a variable W/out actually being connected to a servo, but it seems like the get_position really needs input from a servo.

The reason for Maestro script over C# is simply my lack of C# knowledge vs the simplicity of Maestro script…I am however conceding to the fact that I’ll likely have to learn more C# and do ‘everything’ from there.

Thanks,
Kevin

Hello,

GET_POSITION does not need “input from a servo” - there is no such thing, anyway. Set an unused channel to some position, and you can read it back.

-Paul

ok this is working great…thanks for all the help. I’m in the process of trying to write code to eliminate all of the script. Is there a simple way in C# to GET_POSITION ? I see ways to get “variables”…but not simply position. I think I’m missing something.

Thanks again,
Kevin

Hello,

The getVariables(out ServoStatus[] servos) method defined in Usc.cs should return all available information about all of the channels. You can also use the version of that function with four arguments; one of them contains the servo status.

-Paul

That works great, thanks.
A couple more questions…I’m almost there.

I’m wondering if there is a way to load a script (settings.txt file) via code. My application (remote telescope focus control) has essentially 2 modes of operation.

  1. manual remote focus: 6 ch Maestro, 4 channels to control stepper motor the other 2 for a rotary encoder via 50 foot connection. The script allows for movement of stepper/focus knob to mimic rotation of the encoder and turn the focus knob. Ideally this is stand- alone and needs no PC connection and thus would represent my default Maestro startup settings.

  2. Autofocus: same 4 channels for stepper, of the other 2, 1 for ‘storing value on the stack’ another for thermistor and temperature compensations. The stored stack value simply allows for comparison to the next value to determine which way to focus. Here the code watches a folder where a CCD(camera) stores focus star ‘sharpness’ data. The code essentailly strives to minimize the diameter of the star via adjusting the focus. Once focus is achieved, it compensates for temperature changes.

SO…I would like to be able to ‘load’ the auto focus ‘settings’ upon start of the program THEN RESET to the stand alone settings prior to closing. Is this possible??

Thanks for all your help and patience with this beginner

Hello,

You can do that, but why not just have all of the code loaded on the Maestro and either:

  1. Stop the script and use C# to control the Maestro directly for autofocus[
  2. Restart the script in an autofocus subroutine

Also, what are your four stepper motor channels connected to?

-Paul

stepper is via L293.

So…have the stand alone mode as the only script on the Maestro, stop it for autofocus and have complete control via C#?

If that makes the most sense, I’ll work on eleminating the script for autofocus mode and move toward complete control via c#. (I guess I’ve learned enough at this point that it may be doable…initially it was easy for me to learn maestro script. I stayed away from code due to no previous exposure to c# or any other language)

So I would use ‘setScriptDone’? to stop script, then change the setting of a channel from input to servo
Would I have to change it back upon closing the autofocus program?

… Looking at the code it seems complicated, any chance you could provide a sample of how to change form input to servo?

Thanks,
Kevin

Hello,

Why do you need to change a channel from input to servo?

-Paul

ok my bad…I was using it to ‘store’ the stack value for comparison…guess that could just be in the code as well…

could you tell me what the byte value represents in the setScriptDone? should it justs be zero?

Thanks

Okay. For scriptDone, a value of 1 means that the script is done and a value of 0 means that it is running. If you set it to a 2, the script will run a single step and then stop. This is described in a comment in protocol.h.

-Paul