Pages: 1 [2] 3 4   Go Down
Author Topic: 2 servos (or any functions) operating simultaneously?  (Read 12435 times)
0 Members and 1 Guest are viewing this topic.
denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

zoomkat:

I'm having some trouble understanding what/how I need to input parameter values into the code to produce a desired result.
For the 'expect single strings' example, I assume the lettered values represent microseconds and then degrees per each defined servo.

  Do these get input to 'if (c == ','), or after any of the comparison operators (>,<, etc.), or manually replace 'n' anywhere? and should they look the same, with a value (100a) followed by a letter?   Or, where do motor position parameters get input?
  How many changes of direction will this routine handle as is without repeating any of the 'if' statements?(maybe I shouldn't try to ask this last question yet, until I see a result)

Thank you for posting this example, at least I have a direction to work in.
Logged

0
Offline Offline
Tesla Member
***
Karma: 141
Posts: 9560
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I'm having some trouble understanding what/how I need to input parameter values into the code to produce a desired result. For the 'expect single strings' example, I assume the lettered values represent microseconds and then degrees per each defined servo.

You should be testing the code to see the results. Using the posted code, sending the first line below from the serial monitor to the arduino will position myservoc at 30 deg., myservob at 180 deg., myservoa at 70 deg., and myservod at 120 deg. The second line will send 700us to myservoa, 1500us to myservoc, and 2000us to myservod.

Code:
30c,180b,70a,120d,
700a,1500c,2000d,
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Sweet, I have some movement of the motors although I'm still not clear on how to input the values correctly.
I'll keep experimenting and see what happens.
Logged

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Cool, it works.  this is a whole new level of programming for me, it's hard to describe how I feel about it.   I had some problems with my com ports that I don't understand, I've never had a problem with them before but it seems to have sorted itself out. 

So now I need to figure out how to run a few short, looped series of strings (walking patterns for each leg ~they should all be the same, half with an opposite order of operation)  in a function similar to 'Serial.printIn(readString)' that will be stored on the arduino so that the 'string loops' can be incorporated into sensor iterations that will determine travel direction.  I think I have most of my sensor iteration figured out, except for the directional radio signal receiver, but that'll come later.

Thanks for the guidance everyone, I will gladly accept more help with my project.   
Logged

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I just started working on this and have a 'ways to go'  ~gotta sleep at some point, though.  I've decided to drop the idea of a smooth gait until more important things are taken care of first.  I haven't gone all the way through it or compiled it to see where the disjunctions are yet.  For the time being this will only be for one leg with 2 servos,  it will gradually expand from there.  I will edit this post as I work on it and ask for advice accordingly - unless anyone is able to see any obvious, needed restructuring.

Code:
/*
'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.
Moves one leg prototyped for a hexapod ~to be further expanded...
                              ********************************
         *Testing this gave me alphabet characters in the serial monitor instead
          of the indexed numbers I defined (degree values for servos), this tells me
          I must be close.  A simple change of datatypes only gives disassembler messages
          I don't understand(strcpy_P). Some help with this would be great.*  
                              ********************************
 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.
        -Setting up the strings is a two-step process.               */

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

  // 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,
//  string_5
//  string_6,
//  string_7,
//  string_8,
//  string_9,
};
char buffer[32];  //needs to be large enough for the largest string it must hold
                  //may eventually hold up to 240 characters for all servos  
String readString;
//int string[] = {1,2,3,4,5,6,7,8,9};

#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 pin
 const int bumperPinL = 4;   //
  int bumperStateR = 0;      // variable for reading the bumper status
  int bumperStateL = 0;      //

void setup()
{
  Serial.begin(9600);
          //wrong idea but want to save the values temporarily  
 //String('60a, 90b');  //positions leg at ready(may have no use)
 //String('25a, 170b');  //gait for one leg (2 motors(a,b))
 //String('160a');       //
 //String('5b');         //
 //String('25a');        //
 //String('125a, 140b');  //smoothed motion not in use
 //String('80a, 150b');   //
 //String('45a, 160b');   //
 //String('30a, 170b');   //

  //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
 pinMode(bumperPinL, INPUT);  //

 Wire.begin();      //initializes/activates voltage sensing for bumperpins?  
}

void loop()
{
  bumperStateR = digitalRead(bumperPinR);   //read state of bumper sensors
  //bumperStateL = digitalRead(bumperPinL);   //
 
 while (bumperStateR == LOW)      //begin a loop(one leg walking) with bumper sensor
 {
   for (unsigned int i = 1; i < 8; i++)   //prints successive strings in table?
   {                                                    //'strcpy_P' copies strings from program memory to buffer,
     strcpy_P(buffer, (PGM_P)pgm_read_word(&(string_table[i]))); //necessary casts and dereferencing
     Serial.println(buffer);                                           //required to gather data from table above.
     delay(500);                  //~line:'strcpy_P' seems to be the problem...~        
   }
   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)
         {
           Serial.print("writing Microseconds: ");
           Serial.println(n);
           if(readString.indexOf('a') >0) myservoa.writeMicroseconds(n);
           if(readString.indexOf('b') >0) myservob.writeMicroseconds(n);
         }
         else
         {  
           Serial.print("writing Angle: ");
           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
     }
   }
 }
}


« Last Edit: January 02, 2013, 05:35:57 am by evolion » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26249
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
String string1 =  String('25a, 170b');   
You haven't even tried to compile this, have you?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: January 02, 2013, 05:13:04 am by evolion » Logged

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26249
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I think the routine is really close to doing what I want
What routine would that be?
Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26249
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: January 02, 2013, 03:29:07 pm by AWOL » Logged

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.   smiley-neutral
I did rearrange a few things several times, notably: PROGMEM, so I'll try repositioning a few things, before continuing to research.

Code:
/*
'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!
« Last Edit: January 06, 2013, 12:09:22 am by evolion » Logged

0
Offline Offline
Tesla Member
***
Karma: 141
Posts: 9560
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Consider the daffodil. And while you're doing that, I'll be over here, looking through your stuff.   smiley-cool

denver
Offline Offline
Newbie
*
Karma: 0
Posts: 35
...no matter where you go, there you are
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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. 
Logged

Pages: 1 [2] 3 4   Go Up
Jump to: