Help with programming Pololu Maestro 12

Hi all, I’m new to this site and a first time user of a servo controller. I had experience with servos, but that was in RC car applications with a radio and a receiver, but never an automated controller such as pololu so this is very new to me and pretty exciting to see something you programmed come to life. My problem, however, is not to do with servos, but and LED aquarium light I am trying to control.

A member on my local forum posted a write up on how he used the same controller to control his aquarium light. I liked the idea and made a light similar to his original design. He posted his script as well which I adapted and modified it to suit my application. I understand what the script does and how it flows, but to get it to do exactly what i have imagine is what I’m having a little problem with. Here is the script

begin
closeAllCh
ON_Royal_Blue
on_blue
on_white
6 delay_hours
OFF_white
off_blue
off_royal_blue
10 delay_minutes
repeat


############
sub ON_Royal_Blue
############
0
begin
dup 10816 less_than while
1 plus
180 delay
dup 2 servo 
dup 3 servo 
repeat
drop
return

############
sub ON_Blue
############
0
begin
dup 9500 less_than while
1 plus
180 delay
dup 4 servo 
dup 5 servo 
repeat
drop
return

############
sub ON_White
############
0
begin
dup 7552 less_than while
1 plus
360 delay
dup 0 servo 
dup 1 servo 
repeat
drop
return

############
sub OFF_white
############
7552
begin
dup -1 greater_than while 
dup 0 servo 
dup 1 servo
1 minus
360 delay
repeat

0 0 servo
0 1 servo
drop return

############
sub OFF_Blue
############
9500
begin
dup -1 greater_than while 
dup 4 servo 
dup 5 servo
1 minus
180 delay
repeat

0 4 servo
0 5 servo
drop return

############
sub OFF_Royal_Blue
############
10816
begin
dup -1 greater_than while 
dup 2 servo 
dup 3 servo
1 minus
180 delay
repeat

0 2 servo
0 3 servo
drop return

####################

####################
sub closeAllCh
######################
0 0 0 0
0 0 0 0
7 servo 6 servo 5 servo 4 servo
3 servo 2 servo 1 servo 0 servo
1000 delay
return

#####################
sub delay_seconds
#####################
begin
dup while
1 minus 1000 delay
repeat
drop return

#######################
sub delay_minutes
#####################
begin
dup while
1 minus 60 delay_seconds
repeat
drop return

#####################
sub delay_hours
#####################
begin
dup while
1 minus 60 delay_minutes
repeat
drop return
####################

return

What I have is an LED light with 6 channels. 2 white (servo 0 and 1), 2 royal blue (servo 2 and 3) and 2 blue (servo 4 and 5) channels. I have a timer that turns on the whole system at a certain time and the controller will control when and which led to turn on or off. here is my thought process:

  • Once the system is turned off, I want all channels to be off
  • The royal blue LED will turn on first, starting off at its minimum value and slowly ramping up to its maximum value in 30 mins
  • The blue LED will turn on after the royal blue is at maximum power, slowly ramping up from its minimum value to a certain point (~85% of maximum) in 30 mins.
  • The white LED will turn on after the blue LED is finish, slowly ramping from its minimum value to a certain point (~70% of maximum) in 1 hour.
  • All LEDs will stay at their current position for 6 hours
  • The White LED will slowly dim from its current value to minimum and turn off in 1 hour
  • The blue LED will slowly dim from its current value to minimum and turn off in 30 mins
  • The royal blue LED will slowly dim from its maximum value to minimum and off in 30 mins.
  • The controller will not move for another 10 mins, just incase the timer doesnt match up completely with the controller and stays on when the script is finished.

I have ran the script for 2 days now and so far I noticed the time commands I have set in the program doesnt match up with what I had in mind. The first day it was an hour off so I messed with the script (just trial and error) the second day it was 15 mins off. Which im beginning to wonder if there are something wrong with my script. So my question is, are my time commands inline to what i want to do? how do i fix this?

sorry for the long post.

Hello.

I don’t see anything wrong with your script, but please keep in mind that the Maestro’s internal clock is not as accurate as a watch. The crystal itself has a 0.1% tolerance, so it could lose or gain as much as 86 seconds every day. Also, the Maestro has many tasks to take care of concurrently, so the execution of time of the script can sometimes be hard to predict.

I see you have a lot of arbitrary numbers in your code that affect how long it will take. Have you calculated how long each part of the code should take and made sure that it adds up to 24 hours?

In order to prevent noticeable drift over the months, I would power the Maestro from a wall power adapter that is in turn powered by some sort of standard AC outlet timer. I would expect these timers to be much more accurate than the Maestro. The timer should turn the Maestro off for some time every night in order to reset the Maestro’s clock and the state of your script. Then you don’t actually have to worry about doing the calculations to make sure that your loop takes exactly 24 hours to execute.

–David

Thanks david,

Right now i have the controller on a timer. Im not using its internal clock to control when my lights turn on or off. I just learned to deal with the inconsistent times and adjust my code with trial and error

since my last post, I have added 2 more channels of light and beginning to notice the red LED turning on. I didnt think much of it since my light was still working. But the problem seem to be getting worse and worse. I will have some channels turn off all of a sudden or my light would turn off completely.

I didnt change my script much, just added 2 more channels

begin
closeAllCh
ON_Royal_Blue
on_blue
on_white
6 delay_hours
OFF_white
off_blue
off_royal_blue
10 delay_minutes
repeat


############
sub ON_Royal_Blue
############
0
begin
dup 10200 less_than while
1 plus
220 delay
dup 2 servo 
dup 3 servo 
repeat
drop
return

############
sub ON_Blue
############
0
begin
dup 9500 less_than while
1 plus
200 delay
dup 4 servo 
dup 5 servo 
dup 6 servo
dup 7 servo 
repeat
drop
return

############
sub ON_White
############
16
begin
dup 7552 less_than while
1 plus
360 delay
dup 0 servo 
dup 1 servo 
repeat
drop
return

############
sub OFF_white
############
7552
begin
dup -1 greater_than while 
dup 0 servo 
dup 1 servo
1 minus
360 delay
repeat

0 0 servo
0 1 servo
drop return

############
sub OFF_Blue
############
9500
begin
dup -1 greater_than while 
dup 4 servo 
dup 5 servo
dup 6 servo
dup 7 servo
1 minus
200 delay
repeat

0 4 servo
0 5 servo
0 6 servo
0 7 servo
drop return

############
sub OFF_Royal_Blue
############
10200
begin
dup -1 greater_than while 
dup 2 servo 
dup 3 servo
1 minus
220 delay
repeat

0 2 servo
0 3 servo
drop return

####################

####################
sub closeAllCh
######################
0 0 0 0
0 0 0 0
7 servo 6 servo 5 servo 4 servo
3 servo 2 servo 1 servo 0 servo
1000 delay
return

#####################
sub delay_seconds
#####################
begin
dup while
1 minus 1000 delay
repeat
drop return

#######################
sub delay_minutes
#####################
begin
dup while
1 minus 60 delay_seconds
repeat
drop return

#####################
sub delay_hours
#####################
begin
dup while
1 minus 60 delay_minutes
repeat
drop return
####################

return

the error i would constantly get “servo period exceeded”, then eventually ill get 0x0010, Serial protocol error.

I did a search for both of these errors. I’m not really sure what the 0x0010 error code means, exp if you say you cant seem to find anything wrong with my code.

The other one, “servo period exceeded”. I tried trouble shooting the problem and it seems like if i dial back the 2 channels from its maximum set point to around 95% the errors stops.

any help would be appreciated.

thanks

Hello.

Regarding the “Servo Period Exceeded” error, I suspect you are exceeding one of the limitations documented in the “Maestro Settings Limitations” section of the user’s guide. Could you use the Maestro Control Center to save your settings file and post it here as an attachment?

I am not sure why you would get a serial protocol error; the Maestro is just being controlled by its internal script and you are not using any kind of serial communication, right?

–David

David,

Heres the saved settings from the program

<!--Pololu Maestro servo controller settings file, https://www.pololu.com/catalog/product/1350-->
<UscSettings version="1">
  <NeverSuspend>false</NeverSuspend>
  <SerialMode>UART_FIXED_BAUD_RATE</SerialMode>
  <FixedBaudRate>9600</FixedBaudRate>
  <SerialTimeout>0</SerialTimeout>
  <EnableCrc>false</EnableCrc>
  <SerialDeviceNumber>12</SerialDeviceNumber>
  <SerialMiniSscOffset>0</SerialMiniSscOffset>
  <Channels MiniMaestroServoPeriod="12000" ServoMultiplier="1">
    <!--Period = 3 ms-->
    <!--Channel 0-->
    <Channel name="White L" mode="Servo" min="256" max="10816" homemode="Ignore" home="256" speed="0" acceleration="0" neutral="6000" range="1905" />
    <!--Channel 1-->
    <Channel name="White R" mode="Servo" min="256" max="10816" homemode="Ignore" home="256" speed="0" acceleration="0" neutral="6000" range="1905" />
    <!--Channel 2-->
    <Channel name="Royal Blue L" mode="Servo" min="256" max="10240" homemode="Ignore" home="256" speed="0" acceleration="0" neutral="6000" range="1905" />
    <!--Channel 3-->
    <Channel name="Royal Blue R" mode="Servo" min="256" max="10240" homemode="Ignore" home="256" speed="0" acceleration="0" neutral="6000" range="1905" />
    <!--Channel 4-->
    <Channel name="Blue L" mode="Servo" min="256" max="10816" homemode="Ignore" home="256" speed="0" acceleration="0" neutral="6000" range="1905" />
    <!--Channel 5-->
    <Channel name="Blue R" mode="Servo" min="256" max="10816" homemode="Ignore" home="256" speed="0" acceleration="0" neutral="6000" range="1905" />
    <!--Channel 6-->
    <Channel name="R.G.UV 1" mode="Servo" min="256" max="7232" homemode="Ignore" home="256" speed="0" acceleration="0" neutral="5440" range="1905" />
    <!--Channel 7-->
    <Channel name="R.G.UV 2" mode="Servo" min="256" max="7232" homemode="Ignore" home="256" speed="0" acceleration="0" neutral="5440" range="1905" />
    <!--Channel 8-->
    <Channel name="" mode="Output" min="3968" max="8000" homemode="Ignore" home="3968" speed="0" acceleration="0" neutral="6000" range="1905" />
    <!--Channel 9-->
    <Channel name="" mode="Output" min="3968" max="8000" homemode="Ignore" home="3968" speed="0" acceleration="0" neutral="6000" range="1905" />
    <!--Channel 10-->
    <Channel name="" mode="Output" min="3968" max="8000" homemode="Ignore" home="3968" speed="0" acceleration="0" neutral="6000" range="1905" />
    <!--Channel 11-->
    <Channel name="" mode="Output" min="3968" max="8000" homemode="Ignore" home="3968" speed="0" acceleration="0" neutral="6000" range="1905" />
  </Channels>
  <Sequences />
  <Script ScriptDone="false">begin
closeAllCh
ON_Royal_Blue
on_blue
on_white
6 delay_hours
OFF_white
off_blue
off_royal_blue
10 delay_minutes
repeat


############
sub ON_Royal_Blue
############
0
begin
dup 10200 less_than while
1 plus
220 delay
dup 2 servo 
dup 3 servo 
repeat
drop
return

############
sub ON_Blue
############
0
begin
dup 9500 less_than while
1 plus
200 delay
dup 4 servo 
dup 5 servo 
dup 6 servo
dup 7 servo 
repeat
drop
return

############
sub ON_White
############
16
begin
dup 7552 less_than while
1 plus
360 delay
dup 0 servo 
dup 1 servo 
repeat
drop
return

############
sub OFF_white
############
7552
begin
dup -1 greater_than while 
dup 0 servo 
dup 1 servo
1 minus
360 delay
repeat

0 0 servo
0 1 servo
drop return

############
sub OFF_Blue
############
9500
begin
dup -1 greater_than while 
dup 4 servo 
dup 5 servo
dup 6 servo
dup 7 servo
1 minus
200 delay
repeat

0 4 servo
0 5 servo
0 6 servo
0 7 servo
drop return

############
sub OFF_Royal_Blue
############
10200
begin
dup -1 greater_than while 
dup 2 servo 
dup 3 servo
1 minus
220 delay
repeat

0 2 servo
0 3 servo
drop return

####################

####################
sub closeAllCh
######################
0 0 0 0
0 0 0 0
7 servo 6 servo 5 servo 4 servo
3 servo 2 servo 1 servo 0 servo
1000 delay
return

#####################
sub delay_seconds
#####################
begin
dup while
1 minus 1000 delay
repeat
drop return

#######################
sub delay_minutes
#####################
begin
dup while
1 minus 60 delay_seconds
repeat
drop return

#####################
sub delay_hours
#####################
begin
dup while
1 minus 60 delay_minutes
repeat
drop return
####################

return </Script>
</UscSettings>

Im not using any serial communication with the Maestro. Its being controlled by its internal script

I loaded your settings file and took a look at the channel settings. I see that you have set the servo period to 3 ms, and you are generating pulses on several channels that can be as high as 2704 microseconds. If you have several channels at 2704 microseconds, it will be hard for the Maestro to schedule starting times for all the pulses without overrunning the 3ms period.

Based on the information in the the section of the user’s guide that I linked to above, you should probably be able to fix the “Servo period exceeded” problem by changing the Min to 384 and Max to 2456 for all the servo channels. However, that probably means that your lights would be a little bit dimmer.

If you continue to have trouble after making that change, please try to simplify your script to the simplest thing that causes the problem, and try to make the problem occur within the first minute of operation. That will allow me to reproduce the problem here.

–David

Thanks david for all your help. ill try and reconfigure my settings and see if the error still exists.

I have a question tho, right now I have set each channel to ignore any errors that occur and continue running and that seem to stop the controller from turning off any of my lights. But what will happen in the long run? Would that damage the controller or I’ll just have the red light constantly staying on?

The red LED is turning on because you are getting the serial protocol error. I don’t know what is causing that. Since there is something about your system that I don’t understand, it is hard for me to say for sure if the controller is being damaged, but I think it is probably not being damaged.

–David