Mini Maestro used to open servo control panales for R2D2

Hi,
I have a full scale R2D2 Robot that I want to open the panels around his head. I am using a Mini Maestro 12 with 10 micro servos connected to servo pins 0 - 9. I have an Arduino Micro connected to the Mini Maestro 12 via hardware serial ports 0 & 1 and this board is also powering the Maestros logic via 5V. The Maestros servo power is on a separate 6V power source from within R2’s Dome. The Arduino Micro is been sent I2C commands from another Arduino in the body of R2 and this is all sent from R2’s Transmitter.

I have made a number of sequences using the Maestro Control Center and have copied all these to a script using the Copy All Sequences to Script button within to Control Center Software.

I have some code written on the Arduino Micro in R2’s head that receives the I2C commands and I am processing this by using a Switch/Case Statement. The aim is that this will trigger a restartScript() command in the Mini Maestro 12 and play one of the subs in the script. All very good!

However the problem is playing the script. The Dome controller (Arduino Micro) receives the correct I2C command but the panels on r2’s head start but then stop after about a second. For example, the Sequence named ‘Cantina’ has many panels opening and closing and runs for about 16 seconds. When this is triggered only the first panel will open and then nothing. So frustratingggggggggg!!! Any ideas here would be great!

I have included the Code on the Arduino Micro (that is receiving I2C Commands) and the script on the Maestro.

#include <PololuMaestro.h>
#include <SoftwareSerial.h>
#include <Wire.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 8 to receive (RX) and
pin 7 to transmit (TX).*/

#ifdef SERIAL_PORT_HARDWARE_OPEN
  #define maestroSerial SERIAL_PORT_HARDWARE_OPEN
#else
  #include <SoftwareSerial.h>
  SoftwareSerial maestroSerial(10, 11);
#endif

byte eventNumber = 0;

/* 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);

// The following are the I2C Commands used to open and close pannels on the dome.

// 0 = All Panels Closed               
// 1 = All Panels Open
// 2 = Cantina Panels Effects
// 3 = Darth Vader Panels Effects
// 4 = Panel Open Sequence Effect 1
// 5 = Panel Open Sequence Effect 2
// 6 = Panel Wave 1
// 7 = Panel Wave 2
// 8 = Panel Wave 3

void setup()
{
  Wire.begin(11); //I2C Address of the Dome Controller
  Wire.onReceive(receiveEvent);
  
  maestroSerial.begin(9600);
}

void loop()
{
  switch (eventNumber)
  {
    case 1:
      maestro.restartScript(1);
      break;
    case 2:
      maestro.restartScript(2);
      break;
    case 3:
      maestro.restartScript(3);
      break;
    default:
      maestro.restartScript(0);
    break;
  }
}  
  
// function that executes whenever data is received from master
// this function is registered as an event, see setup()

void receiveEvent(int numBytes) 
{
  if (Wire.available())
  {
    eventNumber = Wire.read();
  }
}

Below is the script I have on the Mini Maestro.

### Sequence subroutines: ###

# AllClosed
sub Sequence_0
	  begin
  500 6976 6976 6848 7552 2560 3200 
  2944 8768 3200 3648 0 0 frame_0..11 # Frame 0
  repeat
# AllOpen
sub Sequence_1
  begin
  500 4288 4288 4288 4288 5504 6400 
  6400 4608 6400 7296 0 0 frame_0..11 # Frame 1
  repeat
# Cantina
sub Sequence_2
  begin
  400 6976 4288 6720 7360 2560 3200 
  2944 8768 3200 3648 0 0 frame_0..11 # Frame 1
  400 4288 frame_0 # Frame 2
  400 4288 frame_3 # Frame 3
  400 4288 frame_2 # Frame 4
  400 6720 frame_2 # Frame 5
  400 7360 frame_3 # Frame 6
  400 6976 frame_0 # Frame 7
  400 6976 frame_1 # Frame 8
  400 5504 frame_4 # Frame 9
  400 6400 frame_5 # Frame 10
  400 6400 frame_6 # Frame 11
  400 4608 frame_7 # Frame 12
  400 8768 frame_7 # Frame 13
  400 2944 frame_6 # Frame 14
  400 3200 frame_5 # Frame 15
  400 2560 frame_4 # Frame 16
  400 4288 4288 frame_0_2 # Frame 17
  400 6976 4288 6720 4288 frame_0..3 # Frame 18
  400 6976 7360 frame_1_3 # Frame 19
  400 4288 4288 4288 4288 frame_0..3 # Frame 20
  400 6976 6720 4317 frame_0_2_3 # Frame 21
  400 4288 6976 4288 7360 frame_0..3 # Frame 22
  400 6976 6720 frame_0_2 # Frame 23
  400 5504 6400 6400 frame_4_6_8 # Frame 24
  400 2560 6400 2944 4608 3200 7296 frame_4..9 # Frame 25
  400 3200 8768 3648 frame_5_7_9 # Frame 26
  400 4608 6400 7296 frame_7..9 # Frame 27
  400 5504 6400 6400 8768 3200 3648 frame_4..9 # Frame 28
  400 2560 frame_4 # Frame 29
  400 3200 frame_5 # Frame 30
  400 2944 frame_6 # Frame 31
  400 7296 frame_9 # Frame 32
  400 5504 6400 6400 frame_4..6 # Frame 33
  400 2560 3200 2944 frame_4..6 # Frame 34
  400 4608 6400 frame_7_8 # Frame 35
  400 3200 3648 frame_8_9 # Frame 36
  400 8768 frame_7 # Frame 37
  400 4288 4288 4288 4288 5504 6400 
  6400 4608 6400 7296 frame_0..9 # Frame 38
  400 6976 6976 6720 7360 2560 3200 
  2944 8768 3200 3648 frame_0..9 # Frame 39
  repeat
# DarthVader
sub Sequence_3
  begin
  500 6284 6271 6094 6584 3274 3976 
  3782 7697 3961 4533 0 0 frame_0..11 # Frame 0
  100 6976 6976 6720 7360 2560 3200 
  2944 8768 3200 3648 frame_0..9 # Frame 1
  100 6271 6271 6094 6554 3260 3976 
  3766 7717 3976 4533 frame_0..9 # Frame 2
  100 6976 6976 6720 7360 2560 3200 
  2944 8768 3200 3648 frame_0..9 # Frame 3
  600 4288 4288 5504 6400 6400 frame_1_3_4_6_8 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  600 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 6
  600 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 5
  500 6976 7360 2560 2944 3200 frame_1_3_4_6_8 # Frame 31
  repeat
# Open 1 - OneByOne
sub Sequence_4
  begin
  500 6976 4288 6720 7360 2560 3200 
  2944 8768 3200 3648 0 0 frame_0..11 # Frame 1
  500 6976 frame_1 # Frame 2
  500 4288 frame_0 # Frame 3
  500 6976 frame_0 # Frame 4
  500 4288 frame_3 # Frame 5
  500 7360 frame_3 # Frame 6
  500 4288 frame_2 # Frame 7
  500 6720 frame_2 # Frame 8
  500 5504 frame_4 # Frame 9
  500 2560 frame_4 # Frame 10
  500 6400 frame_5 # Frame 11
  500 3200 frame_5 # Frame 12
  500 6400 frame_6 # Frame 13
  500 2944 frame_6 # Frame 14
  500 4608 frame_7 # Frame 15
  500 8768 frame_7 # Frame 16
  500 6400 frame_8 # Frame 17
  500 3200 frame_8 # Frame 18
  500 7296 frame_9 # Frame 19
  500 3648 frame_9 # Frame 20
  repeat
# Open 2 - OneByOne
sub Sequence_5
  begin
  500 6976 4288 6720 7360 2560 3200 
  2944 8768 3200 3648 0 0 frame_0..11 # Frame 1
  500 4288 frame_0 # Frame 2
  500 4288 frame_3 # Frame 3
  500 4288 frame_2 # Frame 4
  500 5504 frame_4 # Frame 5
  500 6400 frame_5 # Frame 6
  500 6400 frame_6 # Frame 7
  500 4608 frame_7 # Frame 8
  500 6400 frame_8 # Frame 9
  500 7296 frame_9 # Frame 10
  500 6976 6976 6720 7360 2560 3200 
  2944 8768 3200 3648 frame_0..9 # Frame 11
  repeat
# Wave 1
sub Sequence_6
  begin
  500 6976 6976 6720 7360 2560 3200 
  2944 8768 3200 3648 0 0 frame_0..11 # Frame 0
  100 6284 6284 6094 6569 frame_0..3 # Frame 1
  100 6976 6976 6720 7360 frame_0..3 # Frame 2
  100 6297 6297 6106 6569 frame_0..3 # Frame 3
  500 6976 6976 6720 7360 frame_0..3 # Frame 4
  repeat
# Wave 2
sub Sequence_7
  begin
  500 6976 6976 6720 7360 2560 3200 
  2944 8768 3200 3648 0 0 frame_0..11 # Frame 0
  100 3274 3976 3782 frame_4..6 # Frame 1
  100 2560 3200 2944 frame_4..6 # Frame 2
  100 3288 3992 3782 frame_4..6 # Frame 3
  500 2560 3200 2944 frame_4..6 # Frame 4
  repeat
# Wave 3
sub Sequence_8
  begin
  500 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 0 0 frame_0..11 # Frame 1
  500 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 2
  500 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 1
  500 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 2
  500 6976 4288 6720 4288 5504 3200 
  6400 8768 6400 3648 frame_0..9 # Frame 1
  500 4288 6976 4288 7360 2560 6400 
  2944 4608 3200 7296 frame_0..9 # Frame 2
  repeat

sub frame_0..11
  11 servo
  10 servo
  9 servo
  8 servo
  7 servo
  6 servo
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  0 servo
  return

sub frame_0
  0 servo
  delay
  return

sub frame_3
  3 servo
  delay
  return

sub frame_2
  2 servo
  delay
  return

sub frame_1
  1 servo
  delay
  return

sub frame_4
  4 servo
  delay
  return

sub frame_5
  5 servo
  delay
  return

sub frame_6
  6 servo
  delay
  return

sub frame_7
  7 servo
  delay
  return

sub frame_0_2
  2 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
  1 servo
  delay
  return

sub frame_0_2_3
  3 servo
  2 servo
  0 servo
  delay
  return

sub frame_4_6_8
  8 servo
  6 servo
  4 servo
  delay
  return

sub frame_4..9
  9 servo
  8 servo
  7 servo
  6 servo
  5 servo
  4 servo
  delay
  return

sub frame_5_7_9
  9 servo
  7 servo
  5 servo
  delay
  return

sub frame_7..9
  9 servo
  8 servo
  7 servo
  delay
  return

sub frame_9
  9 servo
  delay
  return

sub frame_4..6
  6 servo
  5 servo
  4 servo
  delay
  return

sub frame_7_8
  8 servo
  7 servo
  delay
  return

sub frame_8_9
  9 servo
  8 servo
  delay
  return

sub frame_0..9
  9 servo
  8 servo
  7 servo
  6 servo
  5 servo
  4 servo
  3 servo
  2 servo
  1 servo
  0 servo
  delay
  return

sub frame_1_3_4_6_8
  8 servo
  6 servo
  4 servo
  3 servo
  1 servo
  delay
  return

sub frame_8
  8 servo
  delay
  return

Hello.

I didn’t see any obvious issues with your Maestro script, although it sounds like you probably want each subroutine to run through once and then stop instead of repeating endlessly, so I recommend adding QUIT commands before the REPEAT at the end of each of the subroutines.

When it stops, does the Maestro indicate an error with its red LED? If so, could you connect it to the Maestro Control Center and see which error it is?

Also, when it stops are the servos getting stuck in the same location every time? I noticed that your case/switch statements defaults to restarting at the subroutine that closes all of the panels, so it might be possible that the Maestro is receiving some data from your controller and interrupting the current subroutine to close them all.

Could you post a copy of your Maestro settings file? You can save a copy of your settings file form the “File” drop-down menu of the Maestro Control Center while the controller is connected.

Brandon

Hi Brandon,

Thanks for your reply!

Yes, I did read about placing the QUIT before the REPEAT for the subroutines stuff and thought I might to do that but want to get this I2C sorted first.

When it stops, does the Maestro indicate an error with its red LED? If so, could you connect it to the Maestro Control Center and see which error it is?

When it stops there is no error led. Just the yellow flashing as expected.

Also, when it stops are the servos getting stuck in the same location every time? I noticed that your case/switch statements defaults to restarting at the subroutine that closes all of the panels, so it might be possible that the Maestro is receiving some data from your controller and interrupting the current subroutine to close them all.

Yes the same servo, The first one that is meant to move first in the sequence. I have removed the default part from the case/switch statements to see if there is a difference and there is a change. Now when I send it a command it does the same thing as before, stops on the same panel. But now if I send it another It start the correct subroutine. Very strange!! Any ideas?

Please find new code & file as requested.

#include <PololuMaestro.h>
#include <SoftwareSerial.h>
#include <Wire.h>

SoftwareSerial maestroSerial(5, 4);

int eventNumber = 0;

/* 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);

// The following are the I2C Commands used to open and close pannels on the dome.

// 0 = All Panels Closed               
// 1 = All Panels Open
// 2 = Cantina Panels Effects
// 3 = Darth Vader Panels Effects
// 4 = Panel Open Sequence Effect 1
// 5 = Panel Open Sequence Effect 2
// 6 = Panel Wave 1
// 7 = Panel Wave 2
// 8 = Panel Wave 3

void setup()
{
  Wire.begin(11);   
[maestro_settings.txt|attachment](upload://mMMzCUd6sGsARQ5ZDuGqCf7BzI2.txt) (23.8 KB)
//I2C Address of the Dome Controller
  Wire.onReceive(receiveEvent);
  
  maestroSerial.begin(9600);
  
}

void loop()
{
  switch (eventNumber)
  {
    case 2:
      maestro.restartScript(2);
      break;
    case 3:
      maestro.restartScript(3);
      break;
    case 4:
      maestro.restartScript(4);
      break;
    default:
      //maestro.restartScript(0);
      break;
   }
}  

// function that executes whenever data is received from master
// this function is registered as an event, see setup()

void receiveEvent(int bytes) 
{
  if (Wire.available())
  {
    eventNumber = Wire.read();
  }
}

maestro_settings.txt (23.8 KB)

Hi again,

Just a post to say that I got this working. That said I am still puzzled as to why it didn’t work before? Any way what I did was change the following:

void loop()
{
  switch (eventNumber)

To the following:

void loop()
{
  if (Wire.available())
   {
     switch (Wire.read())
      {
        case 0:
          maestro.restartScript(0); //0 = All Panels Closed 
          break;

and it works! The sequences play as expected when it receives the correct command from the other controller in R2’s body.

Below is the full code for you to see.

#include <PololuMaestro.h>
#include <SoftwareSerial.h>
#include <Wire.h>

SoftwareSerial maestroSerial(5, 4);

//give a name to the group of data
//RECEIVE_DATA_STRUCTURE domeData;

/* 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);

// The following are the I2C Commands used to open and close pannels on the dome.

// 0 = All Panels Closed               
// 1 = All Panels Open
// 2 = Cantina Panels Effects
// 3 = Darth Vader Panels Effects
// 4 = Panel Open Sequence Effect 1
// 5 = Panel Open Sequence Effect 2
// 6 = Panel Wave 1
// 7 = Panel Wave 2
// 8 = Panel Wave 3

void setup()
{
  Wire.begin(11); //I2C Address of the Dome Controller
  
  Wire.onReceive(receiveEvent);
  
  maestroSerial.begin(9600);
  
}

void loop()
{
  if (Wire.available())
   {
     switch (Wire.read())
      {
        case 0:
          maestro.restartScript(0); //0 = All Panels Closed 
          break;
        case 1:
          maestro.restartScript(1); //1 = All Panels Open
          break;
        case 2:
          maestro.restartScript(2); //2 = Cantina Panels Effects
          break;
        case 3:
          maestro.restartScript(3); //3 = Darth Vader Panels Effects
          break;
        case 4:
          maestro.restartScript(4); //4 = Panel Open Sequence Effect 1
          break;
        case 5:
          maestro.restartScript(5); // 5 = Panel Open Sequence Effect 2
          break;
        case 6:
          maestro.restartScript(6); // 6 = Panel Wave 1
          break;
        case 7:
          maestro.restartScript(7); // 7 = Panel Wave 2
          break;
        case 8:
          maestro.restartScript(8); // 8 = Panel Wave 3
          break;
        default:
          maestro.stopScript();
        break;
      }
    }  
}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()

void receiveEvent(int bytes) {}
    

Anyhow, thanks for your response in the first place. Hopefully this may help others that come across the same thing.

Greg

I am glad you were able to get it working; thank you for posting your solution.

By the way, we took another look at the code in your previous post and noticed that eventNumber is set by receiveEvent(), but it never gets cleared. So, every time through loop() it will resend a restartScript() command. To fix that, you could probably just set it to something like -1 or 255 at the end of loop().

Brandon