Maestro Mini and MOVI Shield (Arduino)

Hello,

I want use my Mini Maestro board to create several pre-made sequences and execute them with my Arduino. I have an Arduino shield called a MOVI Shield. The MOVI Shield is a speech synthesizer and it allows me to execute voice commands (For example: I say “Turn on light” and the robot will turn on the light and respond with “Ok”). I was wondering if it was possible to have the servos connected to the Maestro and when I say “Activate sequence 1” the Arduino will tell the Maestro to play Sequence 1 and if I say “Play sequence 2” it will play sequence 2 (I hope to have more than 1 pre-programmed sequence, if that’s possible).

I used the MOVI Shield because it is simple to understand and program. You can get a better understanding of it by taking a look at the code down below or by checking out the website.

This is what my code looks like right now (See code below). I have programmed servo positions and values into it to make my robot move but it doesn’t work as well, compared to when I create a sequence on the Maestro. Plus, the Maestro lets me control the speed of the servos a lot easier which is very important for this project. (I hope to replace all my current servo positions and values with ones from the Maestro. Since the Maestro seems to work a lot better).

(You should know that I am a beginner at programming so it would be greatly appreciated if you could show me with lots of detail how this can be done).

Thanks in advance.

#include <MOVIShield.h>
#include <Servo.h>
//Pins where positive wire of LED connects. (4=Chest Armour Led 7=Eye LED 8=Shield LED)
int led1=4;
int led2=7;
int led3=8;

Servo myservo;
//Define Servo
Servo servo1; //Torso
Servo servo2; //R-Shoulder
Servo servo3; //R-Bicep
Servo servo4; //L-Shoulder
//Servo position in degrees
int servoPos = 0;  
int servo1Pos=90;
int servo2Pos=0;
int servo3Pos=0;
int servo4Pos=180;
MOVI recognizer (true);  //Get a MOVI object, true enables serial monitor interface, rx and tx for alternate communication pins on AVR architecture boards

void setup() 
{
  //Define LED pins as outputs
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  //Define servo pins
  servo1.attach(3); //attach servo 1 to pin 3
  servo2.attach(5);//attach servo 2 to pin 5
  servo3.attach(6);//attach servo 3 to pin 6
  servo4.attach(9);//attach servo 4 to pin 9

  recognizer.init();
  recognizer.callSign(F("Sergey")); //Train callsign (may take 20 seconds)
  recognizer.addSentence(F("Activate display mode")); //1 (Turns on lights)
  recognizer.addSentence(F("Activate stealth mode")); //2 (Turns off lights)
  recognizer.addSentence(F("Shutdown")); //3 (Turn off all LEDs and puts servos to rest position) 
  recognizer.addSentence(F("At ease")); //4 (Servos go to home postion but LEDs stay on)
  recognizer.addSentence(F("Activate Shield")); //5 (Turns on LED for Riot Shield)
  recognizer.addSentence(F("Pose")); //6 (SERGEY strikes a pose)
  recognizer.addSentence(F("Defensive Mode")); //7 (Shield Strobes)  
  recognizer.train(); 

}

void loop() {
  int res = recognizer.poll();

  if (res == 1) {
    recognizer.say("Display mode activated");
    digitalWrite(led1, HIGH); //Turns on LED connected to pin 4
    digitalWrite(led2, HIGH); //Turns on LED connected to pin 7
        recognizer.ask();
  }
  if (res == 2) {
    recognizer.say("Stealth mode activatedn");
    //Turns off all LEDs
    digitalWrite(led1, LOW); //Turns off LED connected to pin 4
    digitalWrite(led2, LOW); //Turns off LED connected to pin 7
    digitalWrite(led3, LOW); //Turns off LED connected to pin 8 
  }
  if (res == 3) {
    recognizer.say("Deactivating");
    //Turns off all LEDs
    digitalWrite(led1, LOW); //Turns off LED connected to pin 4
    digitalWrite(led2, LOW); //Turns off LED connected to pin 7
    digitalWrite(led3, LOW); //Turns off LED connected to pin 8
    servo1.write(90);// set torso to home/rest position
    servo2.write(0);// set R-Shoulder to home/rest position
    servo3.write(0);// set R-Bicep to home/rest position
    servo4.write(180);//set L-Shoulder to home/rest position 
  }
  if (res ==4) {
    recognizer.say("Yes, commander");
     //Turns off all LEDs
    digitalWrite(led1,HIGH); //Turns on LED connected to pin 4
    digitalWrite(led2, HIGH); //Turns on LED connected to pin 7
    digitalWrite(led3, HIGH); //Turns on LED connected to pin 8
     servo1.write(90);// set torso to home/rest position
     servo2.write(0);// set R-Shoulder to home/rest position
     servo3.write(0);// set R-Bicep to home/rest position
     servo4.write(180);//set L-Shoulder to home/rest position 
  }
  if (res ==5) {
    recognizer.say("Sheild activated");
     digitalWrite(led3, HIGH); //Turns on Shield LED
  }
  if (res ==6) {
    recognizer.say("Pose initiated");
     //Test code
     //Defensive Pose
     servo1.write(90);//We are controlling the Torso
     for (servoPos = 0; servoPos <= 135; servoPos += 1) //Goes from 0 degrees to 135 degrees
    servo2.write(servoPos); //We are controlling R-Shoulder            
    delay(8000);// waits 8sec for the servo to reach the position
    for (servoPos = 0; servoPos <= 90; servoPos += 1) //Goes from 0 degrees to 90 degrees
    servo3.write(servoPos); //We are controlling R-Bicep            
    delay(10000);// waits 10sec for the servo to reach the position
    for (servoPos = 180; servoPos <= 90; servoPos += 1) //Goes from 180 degrees to 90 degrees
    servo4.write(servoPos); //We are controlling L-Shoulder            
    delay(8000);// waits 8sec for the servo to reach the position
    //End of test code
  }
  if (res ==7) {
    recognizer.say("Get Back! Get Back!");
     digitalWrite(led3, HIGH); //Turns on Shield LED
     delay(5000);
     digitalWrite(led3, LOW);
  }
}`

Hello.

I moved your post to the “Servo controllers and servos” section of our support forum since it seemed more appropriate.

It sounds like you already have the voice recognition part working and just need to integrate it with the Maestro now. There are several ways you could go about doing this. If you want to have the sequences pre-programmed on the Maestro, you could use the “Restart script at subroutine” serial command to trigger the different sequences. For this to work, your sequences would have to be separated into their own subroutines in a Maestro script. If you made these sequences using the “Sequence” tab of the Maestro Control Center, you can transfer them to a Maestro script by using the “Copy all Sequences to Script” button. After this, you can refer to the comments in the “Script” tab of the Maestro Control Center to see the subroutine number of each sequence. Then, you can specify that number in the “Restart script at subroutine” serial command to run that sequence. You can use our Maestro library for Arduino to make the communication easier. The “Script” example shows how to use the “Restart script at subroutine” command (which is restartScript in the Arduino library).

Brandon

Hello,

Thanks for your reply, it is very helpful. I have a few questions though. As I am a beginner I am having a little trouble combining all the codes for the sequence and the "Script example together. Could you point me in the right direction?

I also have another question. Is sub frame_0…5 and/or sub frame_0…3 the subroutine number? If it is, where would I insert it into the Arduino “Script” example code. If not, where can I find it, and where do I insert it into the code?

Thanks. I really appreciate your help.

(Here are all my codes):

As a test, I created this short routine below (un-complied):

# Sequence 0
begin
  500 8000 0 0 0 0 0 frame_0..5 # home
  500 6000 3968 3968 8000 frame_0..3 # Frame 1
  500 6982 5984 4966 frame_1..3 # Frame 2
repeat

sub frame_0..5
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  0 servo
  delay
  return

sub frame_0..3
  3 servo
  2 servo
  1 servo
  0 servo
  delay
  return

sub frame_1..3
  3 servo
  2 servo
  1 servo
  delay
  return


Here is the compiled version:

0000:                      -- # Sequence 0
0000:                      -- begin
0000: 030EF40100000000000000000000601780 --   500 0 0 0 0 0 5984 frame_0..5 # Frame 0
0011: 0304F401800F81       --   500 3968 frame_5 # Frame 1
0018: 0304F401401F81       --   500 8000 frame_5 # Frame 2
001F: 0304F401C31681       --   500 5827 frame_5 # Frame 3
0026: 0304F401901181       --   500 4496 frame_5 # Frame 4
002D: 0304F401461B81       --   500 6982 frame_5 # Frame 5
0034: 0304F401381781       --   500 5944 frame_5 # Frame 6
003B: 0304F4019A1781       --   500 6042 frame_5 # Frame 7
0042: 060000               -- repeat
0045:                      -- 
0045:                      -- sub frame_0..5
0045: 02052A               --   5 servo
0048: 02042A               --   4 servo
004B: 02032A               --   3 servo
004E: 02022A               --   2 servo
0051: 02012A               --   1 servo
0054: 02002A               --   0 servo
0057: 08                   --   delay
0058: 05                   --   return
0059:                      -- 
0059:                      -- sub frame_5
0059: 02052A               --   5 servo
005C: 08                   --   delay
005D: 05                   --   return
005E:                      -- 
005E:                      -- 

Subroutines:
Hex Decimal Address Name
00  000     0045    FRAME_0..5
01  001     0059    FRAME_5

And here is the “Script” example in Arduino:

/* This example shows how to control Maestro scripts with an
Arduino. It assumes you have an RC hobby servo connected on
channel 0 of your Maestro, and that you have already used the
Maestro Control Center software to verify that the servo is
powered correctly and moves when you command it to from the
Maestro Control Center software.

Before using this example, you should go to the Serial Settings
tab in the Maestro Control Center and apply these settings:

* Serial mode: UART, fixed baud rate
* Baud rate: 9600
* CRC disabled

Be sure to click "Apply Settings" after making any changes.

It also assumes you have connected your Arduino to your Maestro
appropriately. If you have not done so, please see
https://github.com/pololu/maestro-arduino for more details on how
to make the connection between your Arduino and your Maestro.

Also, the Maestro needs to have the script in the comment
below installed on it. */

/*
# Maestro script for Script.ino Arduino library example.
# Copy into the Script tab of the Maestro Control Center and
# click Apply Settings.

# Don't do anything by default.
begin
repeat

# Subroutine 0
sub alternate_mid_to_high
  begin
    6000 0 servo
    1000 delay
    7000 0 servo
    1000 delay
  repeat

# Subroutine 1
# Expects the delay time to be on the top of the stack
sub alternate_mid_to_low
  begin
    6000 0 servo
    dup delay
    5000 0 servo
    dup delay
  repeat
*/

#include <PololuMaestro.h>

/* On boards with a hardware serial port available for use, use
that port to communicate with the Maestro. For other boards,
create a SoftwareSerial object using pin 10 to receive (RX) and
pin 11 to transmit (TX). */
#ifdef SERIAL_PORT_HARDWARE_OPEN
  #define maestroSerial SERIAL_PORT_HARDWARE_OPEN
#else
  #include <SoftwareSerial.h>
  SoftwareSerial maestroSerial(10, 11);
#endif

/* Next, create a Maestro object using the serial port.

Uncomment one of MicroMaestro or MiniMaestro below depending
on which one you have. */
MicroMaestro maestro(maestroSerial);
//MiniMaestro maestro(maestroSerial);

void setup()
{
  maestroSerial.begin(9600);
}

void loop()
{
  /* Subroutine numbers can be found by clicking "View Compiled
  Code..." on the Maestro Control Center script tab.

  Restart script at subroutine 0. Subroutine 0 constantly
  alternates the servo position from the neutral position to the
  high end of the range. */
  maestro.restartScript(0);
  delay(4000);

  // Stop the running script.
  maestro.stopScript();

  /* Restart subroutine 1 with the value 2000 on the stack.

  Subroutine 1 constantly alternates the servo position from the
  neutral position to the low end of the range. In this case, The
  parameter put on to the stack represents how long the delay is
  between servo movements.*/
  maestro.restartScriptWithParameter(1, 2000);
  delay(4000);
}

Hello.

frame_0...5 and frame_0...3 are the generated names of the subroutines, but not the subroutine number. The subroutine number you want to use is determined by the order they are declared in the script (starting at 0). For example, in the first (non-complied) script you posted, subroutine 0 would refer to frame_0..5 since that is the first to be declared, followed by frame_0..3 as subroutine 1, and frame_1..3 as subroutine 2. The problem with your current script is that you want to tell the script to start at your begin statement, which isn’t in a subroutine. It looks like you used the “Copy Sequence to Script” button instead of the “Copy all Sequences to Script” button (the latter will put the main code for each sequence into its own subroutine).

By the way, it does not look like your complied script matches the non-complied script you posted. You might not have pressed the “Apply settings” button before clicking on the “View Complied Code…” button. The complied code is another way to check the subroutine numbers associated with each subroutine, as they are listed in the “Subroutines” section at the bottom.

The Script example in our Maestro library for Arduino will not work with just any Maestro script, as the second part of it shows how to use the “Restart Script at Subroutine with parameter” command and you will get an error if your subroutine is not set up for that. However, you can see how it uses maestro.restartScript(0) to specify that it wants the script to start at subroutine 0 (the first one). You can change the value used with this command to start at other subroutines in your Maestro script.

Brandon

Hello,

Thank you for your response, it is greatly appreciated.

I have clicked “copy all sequences to script” and “apply settings” and viewed the newly complied code. According to the newly complied code (shown below) subroutine 0 should be frame 0…5, sub routine 1 should be frame 0…3, and so on. Correct?

Also, To get this to work with the Arduino, do I copy and paste the whole Script example into the Script Tab of the Maestro, or do I have to do something else?

I also noticed that there are 2 restart scripts in the Script example (Shown below). Do I have to get rid of one or do I keep both? I get the part that if I want it to start a subroutine 1 I would replace maestro.restartScript(0) with maestro.restartScript(1) or is it maestro.restartScript(01) , but I don’t get why there are 2 resets scripts.

Sorry for all the questions, but I am fairly new to all this and i’m trying to gain a better understanding of how this should all work.

Thanks, once again.

(Here is the complied code):

0000:                      -- # Sequence 0
0000:                      -- begin
0000: 030EF401401F0000000000000000000080 --   500 8000 0 0 0 0 0 frame_0..5 # home
0011: 030AF4017017800F800F401F81 --   500 6000 3968 3968 8000 frame_0..3 # Frame 1
001E: 0308F401461B6017661382 --   500 6982 5984 4966 frame_1..3 # Frame 2
0029: 060000               -- repeat
002C:                      -- 
002C:                      -- sub frame_0..5
002C: 02052A               --   5 servo
002F: 02042A               --   4 servo
0032: 02032A               --   3 servo
0035: 02022A               --   2 servo
0038: 02012A               --   1 servo
003B: 02002A               --   0 servo
003E: 08                   --   delay
003F: 05                   --   return
0040:                      -- 
0040:                      -- sub frame_0..3
0040: 02032A               --   3 servo
0043: 02022A               --   2 servo
0046: 02012A               --   1 servo
0049: 02002A               --   0 servo
004C: 08                   --   delay
004D: 05                   --   return
004E:                      -- 
004E:                      -- sub frame_1..3
004E: 02032A               --   3 servo
0051: 02022A               --   2 servo
0054: 02012A               --   1 servo
0057: 08                   --   delay
0058: 05                   --   return
0059:                      -- 

Subroutines:
Hex Decimal Address Name
00  000     002C    FRAME_0..5
01  001     0040    FRAME_0..3
02  002     004E    FRAME_1..3

(A chunk of the Arduino code):

void loop()
{
  /* Subroutine numbers can be found by clicking "View Compiled
  Code..." on the Maestro Control Center script tab.

  Restart script at subroutine 0. Subroutine 0 constantly
  alternates the servo position from the neutral position to the
  high end of the range. */
  maestro.restartScript(0);
  delay(4000);

  // Stop the running script.
  maestro.stopScript();

  /* Restart subroutine 1 with the value 2000 on the stack.

  Subroutine 1 constantly alternates the servo position from the
  neutral position to the low end of the range. In this case, The
  parameter put on to the stack represents how long the delay is
  between servo movements.*/
  maestro.restartScriptWithParameter(1, 2000);
  delay(4000);
}

The Maestro script you are posting is still what is generated from the “Copy Sequence to Script” button instead of the “Copy all Sequences to Script.” Can you try deleting your current script in the Script tab, clicking the “Apply settings” button, then going to the Sequence tab and clicking “Copy all Sequences to Script”? If you do that, the script in the Script tab should start with ### Sequence subroutines: ###.

As far as the maestro.restartScript() command, 1 or 01 are both functionally identical.

To run the Script.ino example from the Arduino library as intended, you would need to replace your Maestro script with the one in the comments of that code. As I mentioned before, that example is showing how to use the “Restart Script at Subroutine” command as well as the “Restart Script at Subroutine with parameter” command (the latter is not directly relevant for what you are trying to do with your sequences right now). You could remove or comment out the maestro.restartScriptWithParameter(1, 2000); line of code to use that sketch with your Maestro script.

Brandon

Hello,

I decided to start from scratch and I have created a brand new test code. I clicked the “Apply Settings” button and “Copy all Sequences to Script” button. I have included the un-complied and complied code below.

I then deleted the script in the Maestro and replaced it with the comments of the Script Example code in Arduino (Also shown below).

Is that all I have to do or is there more?
Once I replace the Maestro Script with the Comments from the Script Example, I click apply settings, and do I have to do anything else? And for the Arduino part, I wire it up and do I upload the Script Example to it in order for everything to work?

Thanks in advance.

Un-compiled code:

### Sequence subroutines: ###

# Test
sub Test
  500 0 8000 6000 3968 0 0 frame_0..5 # Home
  500 5984 3968 5984 frame_1..3 # Frame 1
  500 5964 frame_2 # Frame 2
  return

sub frame_0..5
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  0 servo
  delay
  return

sub frame_1..3
  3 servo
  2 servo
  1 servo
  delay
  return

sub frame_2
  2 servo
  delay
  return

Complied Code:

0000:                      -- 
0000:                      -- ### Sequence subroutines: ###
0000:                      -- 
0000:                      -- # Test
0000:                      -- sub Test
0000: 030EF4010000401F7017800F0000000081 --   500 0 8000 6000 3968 0 0 frame_0..5 # Home
0011: 0308F4016017800F601782 --   500 5984 3968 5984 frame_1..3 # Frame 1
001C: 0304F4014C1783       --   500 5964 frame_2 # Frame 2
0023: 05                   --   return
0024:                      -- 
0024:                      -- sub frame_0..5
0024: 02052A               --   5 servo
0027: 02042A               --   4 servo
002A: 02032A               --   3 servo
002D: 02022A               --   2 servo
0030: 02012A               --   1 servo
0033: 02002A               --   0 servo
0036: 08                   --   delay
0037: 05                   --   return
0038:                      -- 
0038:                      -- sub frame_1..3
0038: 02032A               --   3 servo
003B: 02022A               --   2 servo
003E: 02012A               --   1 servo
0041: 08                   --   delay
0042: 05                   --   return
0043:                      -- 
0043:                      -- sub frame_2
0043: 02022A               --   2 servo
0046: 08                   --   delay
0047: 05                   --   return
0048:                      -- 

Subroutines:
Hex Decimal Address Name
00  000     0000    TEST
01  001     0024    FRAME_0..5
02  002     0038    FRAME_1..3
03  003     0043    FRAME_2

Un-Complied code of the replaced Maestro Script:

# Maestro script for Script.ino Arduino library example.
# Copy into the Script tab of the Maestro Control Center and
# click Apply Settings.

# Don't do anything by default.
begin
repeat

# Subroutine 0
sub alternate_mid_to_high
  begin
    6000 0 servo
    1000 delay
    7000 0 servo
    1000 delay
  repeat

# Subroutine 1
# Expects the delay time to be on the top of the stack
sub alternate_mid_to_low
  begin
    6000 0 servo
    dup delay
    5000 0 servo
    dup delay
  repeat


Complied code of the replaced Maestro Script:

0000:                      -- # Maestro script for Script.ino Arduino library example.
0000:                      -- # Copy into the Script tab of the Maestro Control Center and
0000:                      -- # click Apply Settings.
0000:                      -- 
0000:                      -- # Don't do anything by default.
0000:                      -- begin
0000: 060000               -- repeat
0003:                      -- 
0003:                      -- # Subroutine 0
0003:                      -- sub alternate_mid_to_high
0003:                      --   begin
0003: 0304701700002A       --     6000 0 servo
000A: 01E80308             --     1000 delay
000E: 0304581B00002A       --     7000 0 servo
0015: 01E80308             --     1000 delay
0019: 060300               --   repeat
001C:                      -- 
001C:                      -- # Subroutine 1
001C:                      -- # Expects the delay time to be on the top of the stack
001C:                      -- sub alternate_mid_to_low
001C:                      --   begin
001C: 0304701700002A       --     6000 0 servo
0023: 0C08                 --     dup delay
0025: 0304881300002A       --     5000 0 servo
002C: 0C08                 --     dup delay
002E: 061C00               --   repeat
0031:                      -- 
0031:                      -- 

Subroutines:
Hex Decimal Address Name
00  000     0003    ALTERNATE_MID_TO_HIGH
01  001     001C    ALTERNATE_MID_TO_LOW

It is not clear to me what you are trying to do, but it sounds like you are confusing the two different things I was suggesting. Are you trying to run your own custom sequence right now or just use the unmodified example from the Arduino library? If you are trying to run your own sequence, you shouldn’t be deleting the sequence you just generated in the Maestro script.

To be clear, there are steps for those two options:

Running the Script.ino example from the Maestro Arduino library to check that communication between the two devices is working:

  1. Copy and paste the script from the Script.ino comments into the “Script” tab of the Maestro Control Center and apply settings.
  2. Upload and run the unmodified Script.ino example to the Arduino.

Running your custom sequence created in the Maestro Control Center “Sequence” tab using the restartScript() command from the Maestro Arduino library:

  1. Create your sequence in the “Sequence” tab of the Maestro Control Center.
  2. Click “Copy all Sequences to Script” and apply settings.
  3. Send the restartScript() command from the Arduino with an argument specifying which subroutine to start at.

If you are not comfortable writing your own Arduino sketch from scratch, you can use the example and delete the maestro.restartScriptWithParameter(1, 2000); line of code like I mentioned in my previous post.

Brandon

Hello,

Thank you for your response. I think I finally get how this works. The maestro will run the sequence and the Arduino will tell it to restart where specified in the script example. Correct?

If it does restart the sequence, is there a way for the Arduino to tell the Maestro that once the sequence is done, instead of restarting, just stop. Since I want to use it with my voice recognition shield I will need the Sequence to stop once it is finished instead of running in a loop. Is that possible? If so how would I do that?

Thanks for your help. It is greatly appreciated.

Hello.

Yes, you are correct. The sequence will be stored in the Maestro script and the command from the Arduino is telling the Maestro where to start its script.

To have it stop after it finishes the sequence, you should change the return at the end of the sequence to a quit command, in the Script tab of the Maestro Control Center. For example, the last script you posted looked like this:

### Sequence subroutines: ###

# Test
sub Test
  500 0 8000 6000 3968 0 0 frame_0..5 # Home
  500 5984 3968 5984 frame_1..3 # Frame 1
  500 5964 frame_2 # Frame 2
  return

#the rest of your subroutines

You should replace the return command at the end of the “Test” sequence to quit, like this:

### Sequence subroutines: ###

# Test
sub Test
  500 0 8000 6000 3968 0 0 frame_0..5 # Home
  500 5984 3968 5984 frame_1..3 # Frame 1
  500 5964 frame_2 # Frame 2
  quit

#the rest of your subroutines

This will cause the Maestro to stop the script when it finishes the sequence.

Brandon

Hello,

This helps out a lot. Thanks!

Alright, I have one final question. Can the Maestro run multiple sequences. For example I would like to create 3 completely different sequences. So when I say one command it would execute sequence 1 and when I say another command it will execute sequence 2 and so on. Is this possible?

Thanks.

Yes, you can use the “New Sequence” button in the “Sequence” tab of the Maestro Control Center to create additional sequences. You can then use the “Sequence” drop-down menu to switch between which one you are editing. When you are happy with your sequences, you can follow the same process of using the “Copy all Sequences to Script” button, then looking at the script to find the corresponding number to use from your Arduino code to tell the Maestro which sequence to run. Also, you can replace the return command for each main sequence subroutine to quit as described in my previous post so the Maestro script stops when it finishes the sequence. Note that you do not want to replace all of the return commands, just the ones at the end of each main sequence subroutine (these will be named according to the names of the sequences created in the “Sequence” tab).

Brandon

Awesome! Thank you so much for your continued support. This is really going to help me with the robot.
Once again, Thanks!
:+1:

1 Like

Hello again,

I have another problem. I created a test routine and it worked fine. The Arduino called it and it executed the sequence properly. But now I went to make a new sequence and I followed all the steps to put it into the script, but when I tell the Arduino to call the new script, it runs the old script. I clicked the Run Script button on the Maestro Script tab and it didn’t work, but when I deleted this:

# Maestro script for Script.ino Arduino library example.
# Copy into the Script tab of the Maestro Control Center and
# click Apply Settings.

# Don't do anything by default.
begin
repeat

# Subroutine 0
sub alternate_mid_to_high
  begin
    6000 0 servo
    1000 delay
    7000 0 servo
    1000 delay
  repeat

# Subroutine 1
# Expects the delay time to be on the top of the stack
sub alternate_mid_to_low
  begin
    6000 0 servo
    dup delay
    5000 0 servo
    dup delay
  repeat

and clicked Run Script it ran the code.

What am I missing and how do I fix this issue?

Thanks in advance.

This is my Maestro Script:

# Maestro script for Script.ino Arduino library example.
# Copy into the Script tab of the Maestro Control Center and
# click Apply Settings.

# Don't do anything by default.
begin
repeat

# Subroutine 0
sub alternate_mid_to_high
  begin
    6000 0 servo
    1000 delay
    7000 0 servo
    1000 delay
  repeat

# Subroutine 1
# Expects the delay time to be on the top of the stack
sub alternate_mid_to_low
  begin
    6000 0 servo
    dup delay
    5000 0 servo
    dup delay
  repeat

### Sequence subroutines: ###

# SERGEY Pose
sub SERGEY_Pose
  5000 7099 8000 3968 3968 0 0 frame_0..5 # Home
  8000 0 4887 frame_0_1 # Point gun
  8000 8000 frame_1 # Rest
  2000 7119 6200 frame_0_2 # Frame 8
  8000 4927 8000 frame_1_3 # Frame 9
  4000 8000 3968 frame_1_3 # Frame 10
  4000 3968 frame_2 # Rest
  quit

sub frame_0..5
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  0 servo
  delay
  return

sub frame_0_1
  1 servo
  0 servo
  delay
  return

sub frame_1
  1 servo
  delay
  return

sub frame_0_2
  2 servo
  0 servo
  delay
  return

sub frame_1_3
  3 servo
  1 servo
  delay
  return

sub frame_2
  2 servo
  delay
  return


This is my Ardunio Code:


// S.E.R.G.E.Y A.I MK 5 Program
//By Paglia Industries
//7/20/20

#include <MOVIShield.h>
#include <PololuMaestro.h>
//Pins where positive wire of LED connects. (4=Chest Armour Led 7=Eye LED 8=Shield LED)
int led1=4;
int led2=7;
int led3=8;

//Connect Maestro pin RX to Pin 11 of Ardunio 
//Conect Maestro pin TX to Pin 10 of Arduino
//Conect Maestro GND pin to GND of Arduino 
#ifdef SERIAL_PORT_HARDWARE_OPEN
  #define maestroSerial SERIAL_PORT_HARDWARE_OPEN
#else
  #include <SoftwareSerial.h>
  SoftwareSerial maestroSerial(10, 11);
#endif

MicroMaestro maestro(maestroSerial);

MOVI recognizer (true);  //Get a MOVI object, true enables serial monitor interface, rx and tx for alternate communication pins on AVR architecture boards

void setup() 
{

  maestroSerial.begin(9600);
  
  //Define LED pins as outputs
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  recognizer.init();
  recognizer.callSign(F("Sergey")); //Train callsign (may take 20 seconds)
  recognizer.addSentence(F("Activate display mode")); //1 (Turns on lights)
  recognizer.addSentence(F("Activate stealth mode")); //2 (Turns off lights)
  recognizer.addSentence(F("Shutdown")); //3 (Turn off all LEDs and puts servos to rest position) 
  recognizer.addSentence(F("At ease")); //4 (Servos go to home postion but LEDs stay on)
  recognizer.addSentence(F("Activate Shield")); //5 (Turns on LED for Riot Shield)
  recognizer.addSentence(F("Pose")); //6 (SERGEY strikes a pose)
  recognizer.addSentence(F("Defensive Mode")); //7 (Shield Strobes)  
  recognizer.train(); 

}

void loop() {
  int res = recognizer.poll();

  if (res == 1) {
    recognizer.say("Display mode activated");
    digitalWrite(led1, HIGH); //Turns on LED connected to pin 4
    digitalWrite(led2, HIGH); //Turns on LED connected to pin 7
        recognizer.ask();
  }
  if (res == 2) {
    recognizer.say("Stealth mode activated");
    //Turns off all LEDs
    digitalWrite(led1, LOW); //Turns off LED connected to pin 4
    digitalWrite(led2, LOW); //Turns off LED connected to pin 7
    digitalWrite(led3, LOW); //Turns off LED connected to pin 8 
  }
  if (res == 3) {
    recognizer.say("Deactivating");
    //Turns off all LEDs
    digitalWrite(led1, LOW); //Turns off LED connected to pin 4
    digitalWrite(led2, LOW); //Turns off LED connected to pin 7
    digitalWrite(led3, LOW); //Turns off LED connected to pin 8
  }
  if (res ==4) {
    recognizer.say("Yes, commander");
     //Turns off all LEDs
    digitalWrite(led1,HIGH); //Turns on LED connected to pin 4
    digitalWrite(led2, HIGH); //Turns on LED connected to pin 7
    digitalWrite(led3, HIGH); //Turns on LED connected to pin 8
  }
  if (res ==5) {
    recognizer.say("Sheild activated");
     digitalWrite(led3, HIGH); //Turns on Shield LED
  }
  if (res ==6) {
    recognizer.say("Pose initiated");
      
      maestro.restartScript(0);
  delay(4000);

  // Stop the running script.
  maestro.stopScript();
  }
  if (res ==7) {
    recognizer.say("Get Back! Get Back!");
     digitalWrite(led3, HIGH); //Turns on Shield LED
  }
}

The longer routine with the shield and gun pose is what its supposed to do but the video where just the torso rotates is what it’s doing (that was the test code).

Hello. Your Arduino code says maestro.restartScript(0);. Since you specified 0 as the argument, that command will restart the script at subroutine 0, which means the first subroutine in your script. The first subroutine in your script is alternate_mid_to_high. If you are trying to run SERGEY_pose instead, you need to specify 2 as the argument. The subroutines are numbered from top to bottom, starting at 0.

–David

Hello,

I changed the argument to 2

 maestro.restartScript(02);

and when I click run script in the script tab of the Maestro it will run the SERGEY Pose sequence, but when I call upon it with the Arduino it won’t work. What could be the problem?

Thanks.

Arduino Code:


// S.E.R.G.E.Y A.I MK 5 Program
//By Paglia Industries
//7/20/20

#include <MOVIShield.h>
#include <PololuMaestro.h>
//Pins where positive wire of LED connects. (4=Chest Armour Led 7=Eye LED 8=Shield LED)
int led1=4;
int led2=7;
int led3=8;

//Connect Maestro pin RX to Pin 11 of Ardunio 
//Conect Maestro pin TX to Pin 10 of Arduino
//Conect Maestro GND pin to GND of Arduino 
#ifdef SERIAL_PORT_HARDWARE_OPEN
  #define maestroSerial SERIAL_PORT_HARDWARE_OPEN
#else
  #include <SoftwareSerial.h>
  SoftwareSerial maestroSerial(10, 11);
#endif

MicroMaestro maestro(maestroSerial);

MOVI recognizer (true);  //Get a MOVI object, true enables serial monitor interface, rx and tx for alternate communication pins on AVR architecture boards

void setup() 
{

  maestroSerial.begin(9600);
  
  //Define LED pins as outputs
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  recognizer.init();
  recognizer.callSign(F("Sergey")); //Train callsign (may take 20 seconds)
  recognizer.addSentence(F("Activate display mode")); //1 (Turns on lights)
  recognizer.addSentence(F("Activate stealth mode")); //2 (Turns off lights)
  recognizer.addSentence(F("Shutdown")); //3 (Turn off all LEDs and puts servos to rest position) 
  recognizer.addSentence(F("At ease")); //4 (Servos go to home postion but LEDs stay on)
  recognizer.addSentence(F("Activate Shield")); //5 (Turns on LED for Riot Shield)
  recognizer.addSentence(F("Pose")); //6 (SERGEY strikes a pose)
  recognizer.addSentence(F("Defensive Mode")); //7 (Shield Strobes)  
  recognizer.train(); 

}

void loop() {
  int res = recognizer.poll();

  if (res == 1) {
    recognizer.say("Display mode activated");
    digitalWrite(led1, HIGH); //Turns on LED connected to pin 4
    digitalWrite(led2, HIGH); //Turns on LED connected to pin 7
        recognizer.ask();
  }
  if (res == 2) {
    recognizer.say("Stealth mode activated");
    //Turns off all LEDs
    digitalWrite(led1, LOW); //Turns off LED connected to pin 4
    digitalWrite(led2, LOW); //Turns off LED connected to pin 7
    digitalWrite(led3, LOW); //Turns off LED connected to pin 8 
  }
  if (res == 3) {
    recognizer.say("Deactivating");
    //Turns off all LEDs
    digitalWrite(led1, LOW); //Turns off LED connected to pin 4
    digitalWrite(led2, LOW); //Turns off LED connected to pin 7
    digitalWrite(led3, LOW); //Turns off LED connected to pin 8
  }
  if (res ==4) {
    recognizer.say("Yes, commander");
     //Turns off all LEDs
    digitalWrite(led1,HIGH); //Turns on LED connected to pin 4
    digitalWrite(led2, HIGH); //Turns on LED connected to pin 7
    digitalWrite(led3, HIGH); //Turns on LED connected to pin 8
  }
  if (res ==5) {
    recognizer.say("Sheild activated");
     digitalWrite(led3, HIGH); //Turns on Shield LED
  }
  if (res ==6) {
    recognizer.say("Pose initiated");
      
      maestro.restartScript(02);
  delay(4000);

  // Stop the running script.
  maestro.stopScript();
  }
  if (res ==7) {
    recognizer.say("Get Back! Get Back!");
     digitalWrite(led3, HIGH); //Turns on Shield LED
  }
}

Maestro Script:

# Maestro script for Script.ino Arduino library example.
# Copy into the Script tab of the Maestro Control Center and
# click Apply Settings.

# Don't do anything by default.
begin
repeat

# Subroutine 0
sub alternate_mid_to_high
  begin
    6000 0 servo
    1000 delay
    7000 0 servo
    1000 delay
  repeat

# Subroutine 1
# Expects the delay time to be on the top of the stack
sub alternate_mid_to_low
  begin
    6000 0 servo
    dup delay
    5000 0 servo
    dup delay
  repeat

### Sequence subroutines: ###

# SERGEY Pose
sub SERGEY_Pose
  5000 7099 8000 3968 3968 0 0 frame_0..5 # Home
  8000 0 4887 frame_0_1 # Point gun
  8000 8000 frame_1 # Rest
  2000 7119 6200 frame_0_2 # Frame 8
  8000 4927 8000 frame_1_3 # Frame 9
  4000 8000 3968 frame_1_3 # Frame 10
  4000 3968 frame_2 # Rest
  quit

sub frame_0..5
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  0 servo
  delay
  return

sub frame_0_1
  1 servo
  0 servo
  delay
  return

sub frame_1
  1 servo
  delay
  return

sub frame_0_2
  2 servo
  0 servo
  delay
  return

sub frame_1_3
  3 servo
  1 servo
  delay
  return

sub frame_2
  2 servo
  delay
  return

The first frame of SERGEY_Pose lasts 5000 ms but your Arduino program is stopping the script just 4000 ms after starting it.

–David

So in order to run the complete routine I must change delay(4000); to delay (39000); because it will take 39000 ms to run the entire routine. Correct?

Thanks once again.

If you do that, your robot would not respond to any commands for a whole 39 seconds because it would be busy delaying. Instead you could simply remove the line that calls stopScript. Then the delay does not matter, and it could be removed too.

–David

Ok, Thanks. I’ll take out this section:

  maestro.restartScript(02);
  delay(4000);

  // Stop the running script.
  maestro.stopScript();

and hopefully it works.