Pololu maestro and arduino again

Hi, i had help on my arduino code before, thanks for that.
I thought i had i sorted but i didn’t.
I’ll post the relevant parts.
I decided to try out the newsoftserial library as you suggested:
When i set target as 8000, it goes to the extreme end – i was told it would take values from 4000 - 8000.
But any 4000 and 2000 just give the same position - Centre.
Just really desperate to get this solved.

#include <NewSoftSerial.h>
#define txPin 4 
#define rxPin 3

NewSoftSerial mySerial(rxPin, txPin);
void setup()// run once, when the sketch starts
{
  mySerial.begin(9600);
  delay(1000);  
}
void putf(unsigned char servo, unsigned int target)
{
  target = 2000;  // The value i'm using for testing and will changed by another function later
  unsigned int temp;
  byte pos_hi,pos_low;
  temp = target & 0x1f80;
  pos_hi = temp >> 7;
  pos_low = target & 0x7f;
   //Send a Pololu Protocol command
   mySerial.print(0xAA,BYTE); //start byte
   mySerial.print(0x0C,BYTE); //device id
   mySerial.print(0x04,BYTE); //command number
   mySerial.print(servo,BYTE); //servo number
   //Convert the angle data into two 7-bit bytes
   mySerial.print(pos_low, BYTE);
   mySerial.print(pos_hi,BYTE);
}

What am i doing wrong?
Thanks in advance.

Hello.

Your putf function is more complicated than it needs to be. Please try replacing it with this:

//Send a Set Target command to the Maestro.
//Target is in units of quarter microseconds, so the normal range is 4000 to 8000.
void set_target(unsigned char servo, unsigned int target)
{
    mySerial.print(0xAA,BYTE); //start byte
    mySerial.print(0x0C,BYTE); //device id
    mySerial.print(0x04,BYTE); //command number
    mySerial.print(servo,BYTE); //servo number
    mySerial.print(target & 0x7F, BYTE);
    mySerial.print((target >> 7) & 0x7F,BYTE);
}

Also, you should write a loop() function to test it in the simplest possible way. Something like this would be fine:

void loop()
{
   delay(1000);
   set_target(0, 8000);
   delay(1000);
   set_target(0, 4000);
}

When you put this code together in a sketch and run it, you should be able to see the servo on channel 0 moving back and forth between its two extremes. If its movement is not what you would expect, then please connect to the Maestro via USB, open the Maestro Control Center, and look at the Position of channel 0. It should be changing between 1000 microseconds and 2000 microseconds every second.

Also, make sure that your Maestro’s serial mode is “UART, fixed baud rate” with a baud rate that matches the one you have in your Arduino code. You should also make sure that you don’t have an internal script running on the Maestro that might override the commands from the Arduino.

If you can’t get this to work, please simplify your code as much as possible, post your entire program here, let us know what is going wrong when you run it, and tell us how you have wired everything together.

–David

Thank you david,
looks like my data types might have been the problem, anyway your code was perfect and i only had to change the lower and upper limits and the target values to get a full 1 - 179 degrees turn.

Thanks a lot again, great product but my weak C got the upper hand.

Hello, posting here because it is one of the higher google hits for maestro + arduino
and perhaps someone out there will also be as clueless as me.

[edit jun 27 fixed multiple errors as suggested in following post]

  1. newsoftserial should be downloaded from the internet and the folder inside the zip put in (path to where you unzipped arduino)/arduino/libraries/

  2. what the code from https://www.pololu.com/docs/0J40/5.e or from above means:
    a. BYTE is a parameter that specifies the base (format) to use http://www.arduino.cc/en/Serial/Print
    b. target is a non-negative integer less than 8192 (it can be written in binary notation with 14 or fewer digits)
    c. 0x7F is 01111111 in binary, which infinity zeros to the left, so "&"ing (bitwise AND) it masks out all the digits in target (when target is written in binary) except the last 7 digits (only 1 AND 1 == 1. all other combinations == 0)
    e.g., from pololu docs, 6000 = 01011101110000

  01011101110000
& 00000001111111
= 00000001110000

d. >> right shift operator, shifts last seven digits (numbers 7 through 13) in target off into empty space and so now the “new” last seven digits were originally bits #0 to 6 (see color-coded pololu doc). Mask with 0x7F again.

  01011101110000, >>7 to:
  00000001011100, then
& 00000001111111
= 00000001011100
    mySerial.print(0xAA,BYTE); //start byte a.
    mySerial.print(0x0C,BYTE); //device id
    mySerial.print(0x04,BYTE); //command number
    mySerial.print(servo,BYTE); //servo number
    mySerial.print(target & 0x7F, BYTE); //b. c.
    mySerial.print((target >> 7) & 0x7F,BYTE); //d.

[size=50]also, tangentially, setting the VSRV=VIN jumper seems to current limit the power to the servos or something [/size]
(please remove post if it violates some sensibility somewhere)

Hello orangenarwhals.

Your description of the code is partly correct. I will quote and comment on the parts that aren’t correct:

Yes, target is an integer, but it doesn’t make much sense to say that it is a “binary number”. You are confusing the value of the integer itself with the notations used for representing the integer. In C/C++ code (e.g. Arduino code), integer variables have values but they don’t store any information about notation. For example, “int x = 8;” and “int x = 0b1000;” are totally equivalent.

A more correct statement about the target would be: “b. target is a non-negative integer less than 8192 (it can be written in binary notation with 14 digits or fewer).”

This is correct except that 0x7F is 01111111 in binary (you only wrote six 1s).

Actually “>>” is called a right shift operator. It sounds like you understand what the operator does, but I’d like to warn you that your 1-14 numbering system for the digits is not standard. Most people call the least-significant (right-most) bit “bit 0” and the bit number increases as the bits get more significant. So a better statement would be:

“d. >> is the right shift operator. It is used to shift the target to the right by 7 bits. Bits 0-6 get thrown off in to empty space. After shifting, the “new” bits 0-6 are equal to the original bits 7-13.”

I am glad that you are trying to understand what is going on at a fundamental level and I hope these corrections help you understand it better. Let me know if something I said didn’t make sense. If you haven’t yet, please be sure to read the documentation of the Set Target command for more information:
pololu.com/docs/0J40/5.e

Adding the VSRV=VIN jumper should just increase the load on your servo’s power supply slightly because it makes the Maestro’s processor get powered from servo power. If your power supply is adequate and correctly connected, it shouldn’t have a big impact on performance. What power supply are you using and how is everything connected?

–David

Oh, thanks! I see I had both multiple typos and multiple misunderstandings.

Hmm,

8.4V supply (two of these batteries in series) run through an arduino nano carrier board with switching 5V/3A regulator
18x hs-311 servos (on pololu mini maestro 24ch, pins 1 through 18)

Setup A: VSRV=VIN jumper, power to VSRV via two wires from carrier board (5V leeched from pin 9 on the carrier board).

Setup B: no jumper, power to VSRV as before, power to VIN via fem-fem servo cable from carrier board. Aka only difference is VIN 5V and GND are now leeched from carrier board pin 2 and VSRV 5V is leeched from carrier board pin 9.

Both appear to behave fine in-air, but on the ground, hexapod A isn’t able to walk, while hexapod B is able to. Multimeter shows hexapod A with voltage dropping to zero under load; probably hexapod B has voltage hovering around 4 or 5 V.

As far as I can tell electrically the only difference between the two is the jumper.

Are A and B actually different hexapods that you built or are they the same hexapod and you just change the wiring slightly to switch between setup A and setup B?

I looked at the Pin Diagram page for your Arduino Nano carrier board, and pins 2 and 9 are not power pins. What pins are you referring to when you say “pin 2” and “pin 9”?

We usually recommend that you should have at least 1 A per servo, so powering 18 servos from a 3 A regulator will probably not work. I’m not sure how you got one of your hexapods to work!

–David