2 servos (or any functions) operating simultaneously?

String string1 =  String('25a, 170b');

You haven't even tried to compile this, have you?

AWOL:

No, I didn't try to compile it, I just threw it together after some research and wanted to see what initial responses it would conjure.

I just replaced/modified it (above) with a version that survived the compiler but hasn't yet been tested. I'm gonna do that now and see what happens.

HMMM.... I'm having 'com port' problems again, not sure what's happening with my ports, so the code (above) remains untested until I figure this out.

1-2-13. Upon testing, alphabet characters printed to the serial monitor instead of the indexed number values. I changed datatypes to 'unsigned int' and 'uint16_t', used '#define' for the first line, and tried quite a few combinations of changes with no results. There must be more to it than simply changing datatypes, I don't know. I could use some help with it if anyone has any ideas.

I need help setting up strings in PROGMEM as 'int' or 'unsigned int' instead of 'char' datatypes. I think the routine is really close to doing what I want except it prints alphabet characters only instead of the indexed numbers I have defined in the first few lines of code (refer to my last couple of posts and the code above)

Any suggestions or info about this would be greatly appreciated. Thanx

I think the routine is really close to doing what I want

What routine would that be?

Maybe I'm not using the word 'routine' correctly, but the code I'm referring to is in reply #19 (above). I refined and replaced what I had first posted there but the new code gives me the wrong results. There are a few comments in the code and in subsequent posts.

The code in reply #19 needs to have the single quotes replaced with double quotes where necessary, otherwise chances of success are slim. When you've done that and compiled it, repost your code, and tell us how it behaves.

Sweet, I'll try that. I thought that might possibly be part of the problem ~hopefully it's the whole problem. It will probably be several hours before I can get back online with results. Thanx

AWOL: The use of double quotes for defining the strings was definitely part of, if not the entire, problem.

RESULTS: The code below prints the defined strings {","}; line by line in sequence to the serial monitor and timed according to the delay. This is only partially what I wanted because Serial.read either is not reading them as they are being printed or they are not being converted to integers and/or not being written to the servos. The ‘Serial.read/write’ section [from zoomkat] of the loop (everything at the bottom after ‘if(Serial.available())’ ) works fine on its own with manual input into the serial monitor but apparently doesn’t do anything in combination with the PROGMEM section/s. I’m not sure what needs to happen now for the strings to get written to the servos, I don’t know what the disconnect is. It may only be one or two lines away from working, or may need an entirely new approach. :expressionless:
I did rearrange a few things several times, notably: PROGMEM, so I’ll try repositioning a few things, before continuing to research.

/*
'zoomkat 11-22-12 simple delimited ',' string parse' is combined with 'PROGMEM string demo' 
inside of a while loop that gets started with a bumper sensor used as a manual switch.
Intended to control one leg prototyped for a hexapod ~will be further expanded as the bugs
get worked out...

 zoomkat 11-22-12 simple delimited ',' string parse
         from serial port input (via serial monitor)
         and print result out serial port
         multi servos added
         
 PROGMEM string demo
        -How to store a table of strings in program memory (flash), and retrieve them.
           Information summarized from:
        http://www.nongnu.org/avr-libc/user-manual/pgmspace.html
               -Here is a good template to follow for setting up a 
                table (array) of strings in program memory.               */

#include <avr/pgmspace.h>
PROGMEM prog_char string_0[] = {"60a, 90b"};   //positions leg at ready (may have no use)
PROGMEM prog_char string_1[] = {"25a, 170b"};  //gait for one leg (2 motors(a,b))
PROGMEM prog_char string_2[] = {"160a"};       //
PROGMEM prog_char string_3[] = {"5b"};         //
PROGMEM prog_char string_4[] = {"25a"};        // 

  // Then set up a table to refer to strings.
PROGMEM const char *string_table[] =   //change "string_table" name to suit
{   
  string_0,
  string_1,
  string_2,
  string_3,
  string_4,
};
char buffer[4];  //needs to be large enough for the largest string it must hold
                      //may eventually hold up to 30 indexed variables for all servo/sensor functions  
String readString;

#include <Servo.h> 
 Servo myservoa, myservob;   //create servo object to control a servo 

#include <Wire.h>
 const int bumperPinR = 2;    // the number of the bumper (whisker) pin
  int bumperStateR = 0;       // variable for reading the bumper status

void setup() 
{
  Serial.begin(9600);

  //myservoa.writeMicroseconds(1500);   //set initial servo position if desired?
  //myservob.writeMicroseconds(1500);   //
 myservob.attach(8);     //the pin for the servob control
 myservoa.attach(9);     // 
  //Serial.println("");     //keep track of what is loaded

 pinMode(bumperPinR, INPUT);     //sets the bumper pins as an inputs

 Wire.begin();      //initializes/activates voltage sensing for bumperpins?  
}
void loop() 
{
  bumperStateR = digitalRead(bumperPinR);    //read state of bumper sensors
 
 while (bumperStateR == LOW)      //begin a loop(one leg walking) with bumper sensor
 {
   for (int i = 1; i < 4; i++)    //prints successive strings in table?
   {
         //'strcpy_P' copies strings from program memory to buffer,
         //necessary casts and dereferencing required to gather data from table.
     strcpy_P(buffer, (char*) pgm_read_word(&(string_table[i])));
     Serial.println(buffer);                                          
     //delay(500);                 //delay will certainly need adjustment     

 //everything beyond this point does not seem to correlate with that above, although
 //it does control the servos when values are manually entered into the serial monitor
    if (Serial.available())  
    {
      char c = Serial.read();   //gets one byte from serial buffer
      if (c == ',')              //where/what is 'char c'??  
      {
        if (readString.length() >1)   //greater than 1 char??
        {
          Serial.println(readString);  //prints string to serial port out
          int n = readString.toInt();   //convert readString into a number
             // auto select appropriate value ~my servos use 0-180, so 181 should work
          if(n >= 500)                  //don't know if I'm interpreting this correctly
          {
            Serial.print("writing Microseconds: ");       //header for input 'n >= 500' in monitor
            Serial.println(n);
            if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
            if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
          }
          else
          {   
            Serial.print("writing Angle: ");                 //header for input 'n < 500'
            Serial.println(n);
            if(readString.indexOf('a') >0) myservoa.write(n);
            if(readString.indexOf('b') >0) myservob.write(n);
          }
          readString="";    //clears variable for new input
        }
      }  
      else 
      {     
        readString += c;    //makes the string readString
      }
     }
   }
 } 
}

1/5/13
I need help!
Here’s what I’m trying to do:

  1. Store strings to PROGMEM
  2. Retrieve strings from PROGMEM using Serial()
  3. Write strings to multiple servos in sequence/s
    Purpose:
    Mainly to have simultaneous operation of multiple servos and sensors, the other would be to conserve memory for functions.

The ‘disjunction’ appears to be between ‘strcpy_P’ and ‘if (Serial.available())’.
I’ve made too many changes, additions, omissions to the code to remember everything I’ve tried. I can’t really go much further with my project without solving this problem.

Any suggestions or additional info will be greatly appreciated!

You may need to look at just what PROGMEM does and how it works, and see if it supports the way you are trying to use it.

zoomkat:

Yes, I have been trying to find as much info on it as possible. I think I'm heading in the right direction and what I now understand or at least think I understand is that there is a conversion problem. It is between the 'serial buffer' and the 'readString' variable which is then indexed to 'n' in 'servo.write()'. Maybe, if possible, I should not do a conversion and try to work with only the buffer up to '.indexOf()'. I'm still looking for applicable information on this subject.

I think I'm heading in the right direction and what I now understand or at least think I understand is that there is a conversion problem.

But, I'm not going to show you my code.

It is between the 'serial buffer' and the 'readString' variable which is then indexed to 'n' in 'servo.write()'.

Well, certainly. Fix it. Or not. Only you can see what you are talking about.

I'm still looking for applicable information on this subject.

What subject would that be?

PaulS:

So are your comments serious? ...joking? or seriously joking?

the code I've been working on is on post #27 are you saying you aren't going to post yours?

Well, if you look at post #27, you can see it too if you were to run it, you can certainly see what it do Unfixed. And so.

the subject is apparently in the form of a question as the title of the thread (see title) any more explanation of my problem would be ad nauseam

If you have any info that could possibly help me solve it, I'd love to know about it.

the code I've been working on is on post #27 are you saying you aren't going to post yours?

If you've been working on the code in post #27, presumably it now doesn't look like the code in post #27, so you need to post it again. Now.

the subject is apparently in the form of a question as the title of the thread (see title) any more explanation of my problem would be ad nauseam

Well, "2 servos (or any functions) operating simultaneously?" seems to have you stummped. The code only does one thing at a time, but the code itself performs actions so fast you will not be able to detect the individual actions (unless you add delays and such).

If you have any info that could possibly help me solve it, I'd love to know about it.

Well, if the "it" problem is a knowledge deficit on your part, it is up to you to get up to speed.

AWOL:
I have probably made 100’s of changes to the code in #27 by now, except none of them have have brought me any closer to my goal. Each change has had either no effect, produces undesirable effects, nullifies the code altogether, or doesn’t compile.
I believe each half of the code (PROGMEM with table to Serial buffer) and (Serial.read to index. to .write) are doing things I want to see happen, I just can’t seem to integrate them to work together. Nothing I have done has furthered what is already there.
So, effectively, the code remains unchanged.

zoomkat:
I understand that it does one thing at a time and gives the impression of simultaneity, the code you presented to me (2nd half of the code in #27) definitely produces this effect. I’m still trying to figure out what function/s will replace manually inputting parameters to serial.

The “it” certainly results from my surplus of ignorance but I’m not sitting idle waiting for someone to bestow their esoteric knowledge unto me, although it would be sweet to be blessed with such an occurrence, not unlike you supplying much the code I’m working with now. I’m doing my due diligence and have gone through the entire reference especially focused on ‘string theory’, investigated many of the links provided and their links also, as well as other forums and books. I’m learning as much as I can as quickly as I can - I may have totally overlooked the exact solution because I didn’t know what I was looking at, I don’t know.
I’m not going to give up on the issue, I want to understand how it is done, but I’m reaching a threshold of having to re-prioritize in order to meet the deadline for the robotics challenge. I’ve figured out a way for a hexapod to use 2 servos to do the work of the 12 originally planned and as long as I am able to get the parts printed it shouldn’t be too difficult to make happen. I won’t need to have the servos operate simultaneously.

I will continue to work on this simultaneous servo problem in my spare time. In the meantime I built a different style of ‘walking’ robot prototype using 2 servos out of battery compartments and paperclips. I’ve got a couple of other projects that I want to finish/get started after the challenge. I’ll go nuts if I only focus on this problem.

There are lots of three servo hexipods, and other simple walking bots. Below are some ideas.

http://www.google.com/search?num=100&hl=en&lr=&tbo=d&as_qdr=all&spell=1&q=three+servo+hexapod&sa=X&ei=DVYDUdKGAcbo0gGWlYFQ&ved=0CC8QBSgA&biw=1173&bih=642

http://davidbuckley.net/DB/Inspire.htm

Ha Ha, she’s one hot bot.

I thought I’d post my first project.
I don’t have much to offer the forum yet, but maybe someone can benefit from this.
I built this robot out of roof flashing, designed to stay on top of fine loose sand, spike-paddles were cut into each wheel and a ‘ski’ was on a pivot in the rear
I wish I had a pic of it finished

here’s the code I used with it:
~this has nothing to do with my hexapod idea

/* 10-5-10
  Pete Dokter
  SparkFun Electronics
 
This is an example sketch for Arduino that shows very basically how to control an Ardumoto
 motor driver shield with a 5V Arduino controller board.

~~~ The variable values in this code have changed significantly from the (above) author's draft,
    I also incorporated bumper sensors (whiskers) with iterations and fixed the northward navigation
   */
#include <Wire.h>   
#include <LSM303.h>  //compass/accelerometer
LSM303 compass;

int pwm_a = 3;   //PWM control for motor outputs 1 and 2 is pin 3
int pwm_b = 11;  //                               outputs 3 and 4 is pin 11
int dir_a = 12;  //direction control for motor outputs 1 and 2 is pin 12
int dir_b = 13;  //                                      outputs 3 and 4 is pin 13

const int bumperPinR = 2;   //bumper pins
const int bumperPinL = 4;  

int bumperStateR = 0;      //variable for reading the bumper status
int bumperStateL = 0;     

int IRsensorPin = A0;     //input pin for IR sensor
int IRsensorValue = 0;    //variable to store value of IR sensor
 
int LEDPin = 13;          //On when backing up

void setup()
{
   Serial.begin(9600);
  pinMode(pwm_a, OUTPUT);   //Set control pins to be outputs (motors)
  pinMode(pwm_b, OUTPUT);
  pinMode(dir_a, OUTPUT);
  pinMode(dir_b, OUTPUT);

  //initialize bumper and IR pins
  pinMode(bumperPinR, INPUT);
  pinMode(bumperPinL, INPUT);
  pinMode(IRsensorPin, INPUT);

  pinMode(LEDPin, OUTPUT);

  digitalWrite(dir_a, LOW);    //Set motor direction, 1 low, 2 high 
  digitalWrite(dir_b, LOW);    //Set motor direction, 3 high, 4 low
  analogWrite(pwm_a, 255);     //set both motors to 100% duty cycle
  analogWrite(pwm_b, 255);

  Wire.begin();             
  compass.init();
  compass.enableDefault(); 
  //Use Calibrate example program for compass values
             //(environment specific ~magnetics differ from place to place, recalibrate)  
     //M min X: -405 Y: -108 Z: -9 M max X: -382 Y: -86 Z:8
                   //values are copied from serial monitor, pause calibration to copy  
   compass.m_min.x = -405; 
   compass.m_min.y = -108; 
   compass.m_min.z = -9;
   compass.m_max.x = -382; 
   compass.m_max.y = -86; 
   compass.m_max.z = +8;
}
void loop()
{
    digitalWrite(LEDPin, LOW);
  digitalWrite(dir_a, LOW);   //motor direction, 1 low, 2 high (forward)
  digitalWrite(dir_b, LOW);   //                      3 high, 4 low

  analogWrite(pwm_a, 200);    //motors run at 80% duty cycle (slower)
  analogWrite(pwm_b, 200);
    
 compass.read();
 int heading = compass.heading((LSM303::vector) {1,0,0} );   //1,0,0 aligns North
    Serial.println("");
    Serial.print("Compass: ");
    Serial.print(heading);
    Serial.print("\t");

 //IR reading
  IRsensorValue = analogRead(IRsensorPin);    
    Serial.print("IR Reading: ");
    Serial.print(IRsensorValue);
    Serial.print("\t");
 
 //read state of bumper value
  bumperStateR = digitalRead(bumperPinR);
  bumperStateL = digitalRead(bumperPinL);

 //Check IR Sensor
   if(IRsensorValue > 455)
    {
        Serial.println("");
        Serial.println("IR rev ");
  //reverse
     digitalWrite(dir_a, HIGH);  //motor direction, 1 low, 2 high 
     digitalWrite(dir_b, HIGH);  //                     3 high, 4 low

     analogWrite(pwm_a, 225);    //motors run slower than 100% duty cycle =(255)
     analogWrite(pwm_b, 225);
      delay(450);

  //turn right
     digitalWrite(dir_a, HIGH);  //motor direction, 1 low, 2 high
     digitalWrite(dir_b, HIGH);  //                      3 high, 4 low

     analogWrite(pwm_a, 15);     //turns left in reverse
     analogWrite(pwm_b, 245);    //points further right in forward direction
      delay(520);
      
  //forward
     digitalWrite(dir_a, LOW);   //motor dir, 1 low, 2 high
     digitalWrite(dir_b, LOW);   //            3 high, 4 low

     analogWrite(pwm_a, 230);    //motors run at ()% duty cycle
     analogWrite(pwm_b, 230);
      delay(850);
    }
 else
  {   
 //check if bumper triggered
  if (bumperStateR == LOW) 
   {     
      //back and turn L    
         Serial.println("");
         Serial.println("bumperR rev ");
   //reverse
     digitalWrite(dir_a, HIGH);  //motor dir, 1 low, 2 high
     digitalWrite(dir_b, HIGH);  //            3 high, 4 low

     analogWrite(pwm_a, 225);    //motors run slower than 100% duty cycle
     analogWrite(pwm_b, 225);
      delay(450);

   //turn left
     digitalWrite(dir_a, HIGH);  //motor dir, 1 low, 2 high
     digitalWrite(dir_b, HIGH);  //             3 high, 4 low

     analogWrite(pwm_a, 15);     //turns left in reverse
     analogWrite(pwm_b, 245);    //points further right in forward direction)
      delay(525);
      
   //forward
     digitalWrite(dir_a, LOW);   // 1 low, 2 high
     digitalWrite(dir_b, LOW);   // 3 high, 4 low

     analogWrite(pwm_a, 230);    //motors run at ()% duty cycle
     analogWrite(pwm_b, 230);
      delay(880);
    }
  if (bumperStateL == LOW) 
   {     
      //back and turn R    
         Serial.println("");
         Serial.println("bumper L rev ");
   //reverse
     digitalWrite(dir_a, HIGH);   //1 low, 2 high
     digitalWrite(dir_b, HIGH);   //3 high, 4 low

     analogWrite(pwm_a, 225);     //motors slower than 100% duty cycle
     analogWrite(pwm_b, 225);
      delay(450);

   //turn right
     digitalWrite(dir_a, HIGH);   //1 low, 2 high
     digitalWrite(dir_b, HIGH);   //3 high, 4 low

     analogWrite(pwm_a, 245);     //turns left in reverse
     analogWrite(pwm_b, 15);      //points further right in forward direction)
      delay(525);
      
   //forward
     digitalWrite(dir_a, LOW);    //1 low, 2 high
     digitalWrite(dir_b, LOW);    //3 high, 4 low

     analogWrite(pwm_a, 230);     //motors at ()% duty cycle
     analogWrite(pwm_b, 230);
      delay(880);
    }  
 //break out of iteration, start navigation
   else
    {
     if(heading < 255)     // (270) = north
      {
       //turn left
         Serial.print("left");
       digitalWrite(dir_a, LOW);   //1 low, 2 high
       digitalWrite(dir_b, LOW);   //3 high, 4 low

       analogWrite(pwm_a, 135);    //motor A (left) slower, B (right) faster
       analogWrite(pwm_b, 225);
        delay(40);
      }

     if(heading > 285)
      {
       //turn right
         Serial.print("right");
       digitalWrite(dir_a, LOW);   //1 l, 2 h
       digitalWrite(dir_b, LOW);   //3 h, 4 l

       analogWrite(pwm_a, 225);    //motor A faster, B slower
       analogWrite(pwm_b, 135);
        delay(40);
      }
    }
  }  
}

How do I attach a normal size photo?

Ok, so I found a new approach to my problem. I’m a bit more hopeful but I can’t get it to compile.

Here is what I found (the list of compiler errors is huge):

//(this sketch is straight from the playground)
// test sketch for MegaServo library
// this will sweep all servos back and forth once, then position according to voltage on potPin

#include <MegaServo.h>

#define FIRST_SERVO_PIN  22  

MegaServo Servos[MAX_SERVOS] ; // max servos is 32 for mega, 8 for other boards

int pos = 0;      // variable to store the servo position 
int potPin = 0;   // connect a pot to this pin.

void setup()
{
  for( int i =0; i < MAX_SERVOS; i++)
    Servos[i].attach( FIRST_SERVO_PIN +i, 800, 2200);

  sweep(0,180,2); // sweep once    
}

void sweep(int min, int max, int step)
{
  for(pos = min; pos < max; pos += step)  // goes from 0 degrees to 180 degrees    
  {                                  // in steps of 1 degree 
    for( int i =0; i < MAX_SERVOS; i++){ 
      Servos[i].write( pos);     // tell servo to go to position  
    }
    delay(15);                  // waits 15ms for the servo to move 
  } 
  for(pos = max; pos>=min; pos-=step)     // goes from 180 degrees to 0 degrees 
  {                                
    for( int i =0; i < MAX_SERVOS; i++){ 
      Servos[i].write( pos);     // tell servo to go to position  
    }
    delay(15);                  // waits 15ms for the servo to move 
  }   
}

void loop()
{ 
  pos = analogRead(potPin);   // read a value from 0 to 1023
  for( int i =0; i < MAX_SERVOS; i++) 
    Servos[i].write( map(pos, 0,1023,0,180));   
  delay(15);   
}

I compared the above sketch to others I found (sorry they aren’t cited, I didn’t record where the other similar examples were from) and here are the changes I made:

#include <MegaServo.h>
#include <Wire.h>
#include <arduino.h>

#define NBR_SERVOS 12
#define FIRST_SERVO_PIN  2  
  MegaServo Servos[NBR_SERVOS] ; // max servos is 12
   MegaServo MegaServo;
int pos = 0;      // variable to store the servo position 
int potPin = 0;   // connect a pot to this pin.
  
void setup()
{
   Serial.begin(9600);
  MegaServo.writeMicroseconds(1500);
  int i = 0;
  pinMode(i,OUTPUT);
} 

void Servos digitalWrite.MegaServo( )
{
  for( int i =0; i < NBR_SERVOS; i++)
    Servos[i].attach( FIRST_SERVO_PIN +i, 800, 2200);

  sweep(0,180,2); // sweep once    
}

void sweep(int min, int max, int step)
{
  for(pos = min; pos < max; pos += step)  // goes from 0 degrees to 180 degrees    
  {                                  // in steps of 1 degree 
    for( int i =0; i < NBR_SERVOS; i++){ 
      Servos[i].write( pos);     // tell servo to go to position  
    }
    delay(15);                  // waits 15ms for the servo to move 
  } 
  for(pos = max; pos>=min; pos-=step)     // goes from 180 degrees to 0 degrees 
  {                                
    for( int i =0; i < NBR_SERVOS; i++){ 
      Servos[i].write( pos);     // tell servo to go to position  
    }
    delay(15);                  // waits 15ms for the servo to move 
  }   
}

void loop()
{ 
  pos = analogRead(potPin);   // read a value from 0 to 1023
  for( int i =0; i < NBR_SERVOS; i++) 
    Servos[i].write( map(pos, 0,1023,0,180));   
  delay(15);   
}

compiler error: MegaServo:23: error: expected initializer before ‘digitalWrite’

This is the only error that this version produces. I don’t know that it’s necessarily a good thing or not. I guess I don’t understand what an ‘expected initializer’ is, even after some research on it. If this does end up compiling, I don’t know that it will work correctly as I don’t understand most of what is going on in it. Please don’t ask me WHY I made some of the changes were made in it as I don’t really remember and probably couldn’t tell you in the first place. All I know is that this is the closest it has come to compiling.

Thanx for any input on this

void Servos digitalWrite.MegaServo( ) what's that?

   MegaServo MegaServo;

Having an instance name the same as the class name is not the brightest idea I've seen today.