Pololu Smc

Hi Greetings, I am new to this forum. I recently purchased an SMC 24v12 motor controller, it works wonders once configured. But nothing is perfect and here I have the problem, I am building a robot that works with voice recognition, when acquiring the new controller (I have to purchase two more) I have modified my program and added the SMC class and it works fine, the question comes when I connect several SMCs the code gives an error,
that is, I cannot specify which engine is going to perform one action or another,
I’ll give it to you to see if you can guide me. Thanks.
By the way the code is written in C # for Windows forms application.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.IO;
using ROBOTIS;
using Pololu.UsbWrapper;
using Pololu.SimpleMotorController;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        SpeechRecognitionEngine reconocedor = new SpeechRecognitionEngine();
        SpeechSynthesizer EDU = new SpeechSynthesizer();
        bool habilitar_reconocimiento;
        string hablar;

        public Form1()
        {
            InitializeComponent();
            Inicio_Gramaticas();
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        void Inicio_Gramaticas()
        {
            reconocedor.LoadGrammarAsync(new Grammar(new GrammarBuilder(new Choices(File.ReadAllLines(@"Comandos\Comandos_Internos.txt")))));
            reconocedor.RequestRecognizerUpdate();
            reconocedor.SpeechRecognized += Reconocedor_SpeechRecognized;
            EDU.SpeakStarted += EDU_SpeakStarted;
            EDU.SpeakCompleted += EDU_SpeakCompleted;
            reconocedor.AudioLevelUpdated += Reconocedor_AudioLevelUpdated;
            reconocedor.SetInputToDefaultAudioDevice();
            reconocedor.RecognizeAsync(RecognizeMode.Multiple);
        }

        private void Reconocedor_AudioLevelUpdated(object sender, AudioLevelUpdatedEventArgs e)
        {
            int nivelaudio = e.AudioLevel;
            pb_Audio.Value = nivelaudio;
            
        }

        private void EDU_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
        {
            habilitar_reconocimiento = true;
        }

        private void EDU_SpeakStarted(object sender, SpeakStartedEventArgs e)
        {
            habilitar_reconocimiento = false;
        }

        private void Reconocedor_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            hablar = e.Result.Text;

            if (hablar == "Hola")
            {
                EDU.SpeakAsync("Hola");

            }

            if (hablar == "Adelante")
            {
                try
                {
                    using (Smc device = connectToDevice())  // Find a device and temporarily connect.
                    {
                        device.resume();         // Clear as many errors as possible.
                        device.setSpeed(3200);   // Set the speed to full forward (+100%).
                    }
                }
                catch (Exception exception)  // Handle exceptions by displaying them to the user.
                {
                    displayException(exception);
                }
            }

            if (hablar == "Stop")
            {
                try
                {
                    using (Smc device = connectToDevice())  // Find a device and temporarily connect.
                    {
                        device.stop();  // Activate the USB kill switch

                        // Alternatively you can set the speed to 0 to stop the motor,
                        // but that will only stop the motor if the input mode is Serial/USB:
                        //    device.setSpeed(0);
                    }
                }
                catch (Exception exception)  // Handle exceptions by displaying them to the user.
                {
                    displayException(exception);
                }
            }

            if (hablar == "Atras")
            {
                try
                {
                    using (Smc device = connectToDevice(39FF - 7406 - 3054 - 3036 - 4923 - 0743))  // Find a device and temporarily connect.
                    {
                        device.resume();          // Clear as many errors as possible.
                        device.setSpeed(-3200);   // Set the speed to full reverse (-100%).
                    }
                }
                catch (Exception exception)  // Handle exceptions by displaying them to the user.
                {
                    displayException(exception);
                }
            }
        }

        Smc connectToDevice()
        {
            // Get a list of all connected devices of this type.
            List<DeviceListItem> connectedDevices = Smc.getConnectedDevices();

            foreach (DeviceListItem dli in connectedDevices)
            {
                // If you have multiple devices connected and want to select a particular
                // device by serial number, you could simply add a line like this:
                if (dli.serialNumber != "39FF-7406-3054-3036-4923-0743")
                { 
                    continue; 
                }

                Smc device = new Smc(dli); // Connect to the device.
                return device;             // Return the device.
            }
            throw new Exception("Could not find device.  Make sure it is plugged in to USB " +
                "and check your Device Manager (Windows) or run lsusb (Linux).");
        }

        public void displayException(Exception exception)
        {
            StringBuilder stringBuilder = new StringBuilder();
            do
            {
                stringBuilder.Append(exception.Message + "  ");

                if (exception is Win32Exception)
                {
                    stringBuilder.Append("Error code 0x" + ((Win32Exception)exception).NativeErrorCode.ToString("x") + ".  ");
                }

                exception = exception.InnerException;
            }
            while (exception != null);
            MessageBox.Show(stringBuilder.ToString(), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

    }
}

Can anybody help me, please ?

Hello.

Welcome to the forum!

It looks like this line is part of the issue:

using (Smc device = connectToDevice(39FF - 7406 - 3054 - 3036 - 4923 - 0743))  // Find a device and temporarily connect.

I also noticed that serial number and the one in your connectToDevice() function are exactly the same as the one commented in Pololu USB Software Development Kit (SDK) Simple Motor Controller G2’s SmcG2Example1 code. I think for now we should focus on getting your code to just connect to one SMC unit (the one you want to control) using a hard-coded serial number in the connectToDevice() function. Afterward, we can try modifying the connectToDevice() function to accept a serial number argument.

First, can you remove the badly formatted serial number inside the parentheses in your Reconocedor_SpeechRecognized() function and replace the serial number in connectToDevice() so that it matches the SMC unit you want to control? You can find the serial numbers for each SMC G2 unit using the Simple Motor Control Center G2 or the command-line utility, smcg2cmd.

- Amanda

as soon as I get off work I get to it. Thank you.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.IO;
using ROBOTIS;
using Pololu.UsbWrapper;
using Pololu.SimpleMotorController;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        SpeechRecognitionEngine reconocedor = new SpeechRecognitionEngine();
        SpeechSynthesizer EDU = new SpeechSynthesizer();
        bool habilitar_reconocimiento;
        string hablar;


        public Form1()
        {
            InitializeComponent();
            Inicio_Gramaticas();
            
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        void Inicio_Gramaticas()
        {
            reconocedor.LoadGrammarAsync(new Grammar(new GrammarBuilder(new Choices(File.ReadAllLines(@"Comandos\Comandos_Internos.txt")))));
            reconocedor.RequestRecognizerUpdate();
            reconocedor.SpeechRecognized += Reconocedor_SpeechRecognized;
            EDU.SpeakStarted += EDU_SpeakStarted;
            EDU.SpeakCompleted += EDU_SpeakCompleted;
            reconocedor.AudioLevelUpdated += Reconocedor_AudioLevelUpdated;
            reconocedor.SetInputToDefaultAudioDevice();
            reconocedor.RecognizeAsync(RecognizeMode.Multiple);
        }

        private void Reconocedor_AudioLevelUpdated(object sender, AudioLevelUpdatedEventArgs e)
        {
            int nivelaudio = e.AudioLevel;
            pb_Audio.Value = nivelaudio;
            
        }

        private void EDU_SpeakCompleted(object sender, SpeakCompletedEventArgs e)
        {
            habilitar_reconocimiento = true;
        }

        private void EDU_SpeakStarted(object sender, SpeakStartedEventArgs e)
        {
            habilitar_reconocimiento = false;
        }

        private void Reconocedor_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
        {
            hablar = e.Result.Text;

            if (hablar == "Hola")
            {
                EDU.SpeakAsync("Hola");
                //lbl_Salida.Content = "Hola";
            }

            if (hablar == "Adelante")
            {
                try
                {
                    using (Smc device = connectToDevice(32FF - 6E06 - 5046 - 3630 - 1428 - 0443))  // Find a device and temporarily connect.
                    {
                        device.resume();         // Clear as many errors as possible.
                        device.setSpeed(3200);   // Set the speed to full forward (+100%).
                    }
                }
                catch (Exception exception)  // Handle exceptions by displaying them to the user.
                {
                    displayException(exception);
                }
            }

            if (hablar == "Stop")
            {
                try
                {
                    using (Smc device = connectToDevice(32FF - 6E06 - 5046 - 3630 - 1428 - 0443))  // Find a device and temporarily connect.
                    {
                        device.stop();  // Activate the USB kill switch

                        // Alternatively you can set the speed to 0 to stop the motor,
                        // but that will only stop the motor if the input mode is Serial/USB:
                        //    device.setSpeed(0);
                    }
                }
                catch (Exception exception)  // Handle exceptions by displaying them to the user.
                {
                    displayException(exception);
                }
            }

            if (hablar == "Atras")
            {
                try
                {
                    using (Smc device = connectToDevice(32FF - 6E06 - 5046 - 3630 - 1428 - 0443))  // Find a device and temporarily connect.
                    {
                        device.resume();          // Clear as many errors as possible.
                        device.setSpeed(-3200);   // Set the speed to full reverse (-100%).
                    }
                }
                catch (Exception exception)  // Handle exceptions by displaying them to the user.
                {
                    displayException(exception);
                }
            }
        }

        Smc connectToDevice()
        {
            // Get a list of all connected devices of this type.
            List<DeviceListItem> connectedDevices = Smc.getConnectedDevices();

            foreach (DeviceListItem dli in connectedDevices)
            {
                // If you have multiple devices connected and want to select a particular
                // device by serial number, you could simply add a line like this:
                if (dli.serialNumber != "32FF-6E06-5046-3630-1428-0443")
                { 
                    continue; 
                }

                Smc device = new Smc(dli); // Connect to the device.
                return device;             // Return the device.
            }
            throw new Exception("Could not find device.  Make sure it is plugged in to USB " +
                "and check your Device Manager (Windows) or run lsusb (Linux).");
        }

        public void displayException(Exception exception)
        {
            StringBuilder stringBuilder = new StringBuilder();
            do
            {
                stringBuilder.Append(exception.Message + "  ");

                if (exception is Win32Exception)
                {
                    stringBuilder.Append("Error code 0x" + ((Win32Exception)exception).NativeErrorCode.ToString("x") + ".  ");
                }

                exception = exception.InnerException;
            }
            while (exception != null);
            MessageBox.Show(stringBuilder.ToString(), this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

    }
}

done, I keep getting errors with the serial number

It looks like you added using (Smc device = connectToDevice(32FF - 6E06 - 5046 - 3630 - 1428 - 0443)) // Find a device and temporarily to several places in your Reconocedor_SpeechRecognized() function. The connectToDevice() function in your current code does not accept a serial number argument and the value you’re trying to pass to the function is not formatted properly, resulting in errors. Please replace all instances of connectToDevice(32FF - 6E06 - 5046 - 3630 - 1428 - 0443) to connectToDevice() in your Reconocedor_SpeechRecognized() function.

If you continue to have errors, please post the error messages you are seeing along with your current code.

- Amanda

Hello, I have already made the changes and it works ok, but now I have to install two more smcs apart from the one I have now in my possession (I don’t have them yet), how do I then to give orders to one and the other? I’ll have to specify it somehow, right?

Thank you

I am glad to hear your code is working now.

Yes, you would first need to connect to the SMC device you want to control by specifying the serial number to the connectToDevice() function before sending commands. You had the correct idea in your Reconocedor_SpeechRecognized() function, but the serial numbers are not formatted properly. You should fix those serial number values by removing the spaces between the hyphens and encapsulating the serial number in double-quotes:

connectToDevice("32FF-6E06-5046-3630-1428-0443"))

Next, you need to modify the connectToDevice() function so that it accepts the serial number argument:

Smc connectToDevice(String serialNumber)

Lastly, replace "32FF-6E06-5046-3630-1428-0443" with the string variable, containing the serial number (in the connectToDevice() function):

if (dli.serialNumber != serialNumber){ continue; }

Now the function will try to connect to the SMC unit that has a matching serial number in the list, connectedDevices.

- Amanda