Recently bought teensy 3.0 how many servo's can she drive?

Status
Not open for further replies.
Great news.
The teensy is driving the servo with no issue's.
No TTL tricks required.

"Excited"
 
Last edited:
Img_0105.jpgImg_0114.jpg

OK.. Now.

Somehow heavily lighten the Rpi Board weight

OR

http://dx.com/p/jesurun-cx-919-quad...r-w-1gb-ram-8gb-rom-xbmc-netflix-black-221308
I have the option of having to buy and wait for a android TV stick. "this may take long" TOO LONG

OR

Somehow making a teensy work as a IOIO board for android phones and using my x10 mini pro phone as the brains.
Saving the effort and cost of adding A Magnometer, Accelerometer, GPS and GSM to a R-pi when I already have a phone that I am willing to sacrifice.
http://www.gsmarena.com/sony_ericsson_xperia_x10_mini_pro-3147.php

OR someone suggest me something truly powerful to control this teensy.

:)

:edit Too bad i cannot find one of these in south africa
http://www.hardkernel.com/renewal_2011/products/prdt_info.php?g_code=G135341370451

Would solder off the bulky ports "usb,ether,audio"
And apply a smaller sink with a small fan.

I'm open for suggestions.
Perhaps solder off the ports from the R-pi to lighten her.
Then I need to look into interfacing the following
X2 Teensy 3.0 boards "to operate sensors and servos"
And 2 to 3 USB cams for 3D Depth tracking. "To help the little bot see "
 
Last edited:
Nested interrupt priority.
I have no idea.
I looked at servo lib... but not sure.
I haven't programmed a micro controller since the pic16F84 as well but, I learn languages fast.

Just not sure what to be looking for or to modify to drive more servo's.

I have 4 months to finish this project.
I will be graded on it and it will suggest if i shall pass or fail my practical school exam.
So far the competition is far asleep compared to what I am bringing to the party.

There's a job up for grabs and I want to make sure I cement my chances.
Please guys wont you help a dude out.
 
Last edited:
> 2 to 3 USB cams for 3D Depth tracking.
As far as I know, there are no small-light-cheap computers that can handle 2 or 3 USB cameras at once. The R-Pi struggles with one USB camera (it does fine with its dedicated R-Pi camera, but you can have only one per R-Pi). Even the quad-core ODROID/U2 can do only very low resolution with 2 USB webcams, from what I have read.
 
Just not sure what to be looking for or to modify to drive more servo's.

Look for this in Servo.h

Code:
#define SERVOS_PER_TIMER       12     // the maximum number of servos controlled by one timer 
#define MAX_SERVOS   (_Nbr_16timers  * SERVOS_PER_TIMER)

Prehaps review the prior messages I wrote too?
 
The R-Pi struggles with one USB camera (it does fine with its dedicated R-Pi camera, but you can have only one per R-Pi).

Earlier this year I tried to use a RPi with a Logitech 9000 USB webcam. It wasn't using much CPU time, but most of the frames were being dropped. I was using the v4l2 library, so it wasn't matter of heavyweight software needing too much CPU time. It seems like the video data was being dropped before it ever got to userspace, perhaps in the kernel or drivers or hardware? I never did find out why the RPi can't handle the incoming video stream, but I did find lots of comments on forums and mail lists were other people had similar unresolved webcam issues. Now with a dedicated camera product, it seems unlikely the RPi will ever work well for USB webcams.

I was able to get my webcam and code working great on a BeagleBone Black. It used about 30% CPU time to deal with 320x240 video, but much of that was probably my code doing inefficient scaling and conversion, and transmitting to a couple Teensy3s. Someone I met at Maker Faire who was from Texas Instruments mentioned the early BeagleBone Black was using non-optimized USB drivers and better ones were in beta testing. Still, the BeagleBone Black was able to pretty easily handle webcam video that the Raspberry Pi could not. It's likely future software releases on Beaglebone will probably improve.

The BeagleBone Black did have trouble recognizing USB device attach and detach events. A workaround was to use a hub and leave a USB memory stick plugged in at all times. It seems if the hub has at least 1 device always present, it works much better. It also works fine if you have everything plugged in before power is applied, but I wrote my code around libudev and I wanted to be able to hot plug. Someone recently sent me a link to this youtube video about a workaround for the BeagleBone's hotplug issues.

So far, I've had nothing but trouble the 3 times I've tried to use Raspberry Pi. Admittedly, 2 of those were with very early versions. My 1 and only project using Beaglebone Black went very well. A sample of one isn't very conclusive, but I'm going to try another project soon. I'll run it on both boards, but given how poorly it's performed before, I don't have high hopes for Raspberry Pi.
 
> 2 to 3 USB cams for 3D Depth tracking.
As far as I know, there are no small-light-cheap computers that can handle 2 or 3 USB cameras at once. The R-Pi struggles with one USB camera (it does fine with its dedicated R-Pi camera, but you can have only one per R-Pi). Even the quad-core ODROID/U2 can do only very low resolution with 2 USB webcams, from what I have read.

Not 100% true buddy.
The R-pi has hardware encoders for it's own camera.
Android rules apply on Rpi to some extent.
Considering the arm chip set was used in phones originally.
So the requirement for a hardware codec to handle video was there something to offload work from the poor arm cpu "many times even embedded on core"
 
Last edited:
Look for this in Servo.h

Code:
#define SERVOS_PER_TIMER       12     // the maximum number of servos controlled by one timer 
#define MAX_SERVOS   (_Nbr_16timers  * SERVOS_PER_TIMER)

Prehaps review the prior messages I wrote too?

Ahh.. sorry I kept opening servo.ccp
My bad, thanks.
Will remember to read more carefully.
I'm only human we are all prone to mistakes.. this is why machines would wreck us at war.
 
#define SERVOS_PER_TIMER 24 // the maximum number of servos controlled by one timer changed to 24 ... idk if thats right..

#define MAX_SERVOS (_Nbr_16timers * SERVOS_PER_TIMER)
//i have no idea what this line does but it seems that it multiplies the amount of servo's per timer by the amount of available timers.... i think..

I also noticed these.
#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
#define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds
handy...
 
Well I can't be 100% sure.
but looks like 24 servo's are sweeping backward and forward.

:edit
Nope only 16 of e'm.

So max = 16 servo's per timer.

How would i fix this...

"how i tested"
Created 24 servo objects

Used 1 servo to test each pin assigned 0 to 23.
servo sweeps on pin 0 to 15 = 16 pins
17 to 23 were not outputting.
 
Last edited:
Used 1 servo to test each pin assigned 0 to 23.
servo sweeps on pin 0 to 15 = 16 pins
17 to 23 were not outputting.

Post the exact and complete code you used for testing. Nobody can help if you don't show exactly what you did.
 
Code:
// Sweep
// by BARRAGAN <http://barraganstudio.com> 
// This example code is in the public domain.
// modified by luenardi De Polo


#include <Servo.h> 
 
Servo myservo1;  // create servo object to control a servo 
Servo myservo2;  // create servo object to control a servo 
Servo myservo3;  // create servo object to control a servo 
Servo myservo4;  // create servo object to control a servo 
Servo myservo5;  // create servo object to control a servo 
Servo myservo6;  // create servo object to control a servo 
Servo myservo7;  // create servo object to control a servo 
Servo myservo8;  // create servo object to control a servo 
Servo myservo9;  // create servo object to control a servo 
Servo myservo10;  // create servo object to control a servo 
Servo myservo11;  // create servo object to control a servo 
Servo myservo12;  // create servo object to control a servo 
Servo myservo13;  // create servo object to control a servo 
Servo myservo14;  // create servo object to control a servo 
Servo myservo15;  // create servo object to control a servo 
Servo myservo16;  // create servo object to control a servo 
Servo myservo17;  // create servo object to control a servo 
Servo myservo18;  // create servo object to control a servo 
Servo myservo19;  // create servo object to control a servo 
Servo myservo20;  // create servo object to control a servo 
Servo myservo21;  // create servo object to control a servo 
Servo myservo22;  // create servo object to control a servo 
Servo myservo23;  // create servo object to control a servo 
Servo myservo24;  // create servo object to control a servo 
                // a maximum of eight servo objects can be created 
 
int pos = 0;    // variable to store the servo position 
 
void setup() 
{ 
  myservo1.attach(0);  // attaches the servo on pin 9 to the servo object 
  myservo2.attach(1);  // attaches the servo on pin 9 to the servo object 
  myservo3.attach(2);  // attaches the servo on pin 9 to the servo object 
  myservo4.attach(3);  // attaches the servo on pin 9 to the servo object 
  myservo5.attach(4);  // attaches the servo on pin 9 to the servo object 
  myservo6.attach(5);  // attaches the servo on pin 9 to the servo object 
  myservo7.attach(6);  // attaches the servo on pin 9 to the servo object 
  myservo8.attach(7);  // attaches the servo on pin 9 to the servo object 
  myservo9.attach(8);  // attaches the servo on pin 9 to the servo object 
  myservo10.attach(9);  // attaches the servo on pin 9 to the servo object 
  myservo11.attach(10);  // attaches the servo on pin 9 to the servo object 
  myservo12.attach(11);  // attaches the servo on pin 9 to the servo object 
  myservo13.attach(12);  // attaches the servo on pin 9 to the servo object 
  myservo14.attach(13);  // attaches the servo on pin 9 to the servo object 
  myservo15.attach(14);  // attaches the servo on pin 9 to the servo object 
  myservo16.attach(15);  // attaches the servo on pin 9 to the servo object 
  myservo17.attach(16);  // attaches the servo on pin 9 to the servo object 
  myservo18.attach(17);  // attaches the servo on pin 9 to the servo object 
  myservo19.attach(18);  // attaches the servo on pin 9 to the servo object 
  myservo20.attach(19);  // attaches the servo on pin 9 to the servo object 
  myservo21.attach(20);  // attaches the servo on pin 9 to the servo object 
  myservo22.attach(21);  // attaches the servo on pin 9 to the servo object 
  myservo23.attach(22);  // attaches the servo on pin 9 to the servo object 
  myservo24.attach(23);  // attaches the servo on pin 9 to the servo object 
} 
 
 
void loop() 
{ 
  for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
  {                                  // in steps of 1 degree 
    myservo1.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo2.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo4.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo5.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo6.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo7.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo8.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo9.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo10.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo11.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo12.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo13.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo14.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo15.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo16.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo17.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo18.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo19.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo20.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo21.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo22.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo23.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo24.write(pos);              // tell servo to go to position in variable 'pos' 

    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
  for(pos = 180; pos>=1; pos-=1)     // goes from 180 degrees to 0 degrees 
  {                                
    myservo1.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo2.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo3.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo4.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo5.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo6.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo7.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo8.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo9.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo10.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo11.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo12.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo13.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo14.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo15.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo16.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo17.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo18.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo19.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo20.write(pos);
    myservo21.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo22.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo23.write(pos);              // tell servo to go to position in variable 'pos' 
    myservo24.write(pos);              // tell servo to go to position in variable 'pos' 
    delay(15);                       // waits 15ms for the servo to reach the position 
  } 
}

Code:
/*
  Servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
  Copyright (c) 2009 Michael Margolis.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/* 
  
  A servo is activated by creating an instance of the Servo class passing the desired pin to the attach() method.
  The servos are pulsed in the background using the value most recently written using the write() method

  Note that analogWrite of PWM on pins associated with the timer are disabled when the first servo is attached.
  Timers are seized as needed in groups of 12 servos - 24 servos use two timers, 48 servos will use four.
  The sequence used to sieze timers is defined in timers.h

  The methods are:

   Servo - Class for manipulating servo motors connected to Arduino pins.

   attach(pin )  - Attaches a servo motor to an i/o pin.
   attach(pin, min, max  ) - Attaches to a pin setting min and max values in microseconds
   default min is 544, max is 2400  
 
   write()     - Sets the servo angle in degrees.  (invalid angle that is valid as pulse in microseconds is treated as microseconds)
   writeMicroseconds() - Sets the servo pulse width in microseconds 
   read()      - Gets the last written servo pulse width as an angle between 0 and 180. 
   readMicroseconds()   - Gets the last written servo pulse width in microseconds. (was read_us() in first release)
   attached()  - Returns true if there is a servo attached. 
   detach()    - Stops an attached servos from pulsing its i/o pin. 
 */

#ifndef Servo_h
#define Servo_h

#include <inttypes.h>

/* 
 * Defines for 16 bit timers used with  Servo library 
 *
 * If _useTimerX is defined then TimerX is a 16 bit timer on the curent board
 * timer16_Sequence_t enumerates the sequence that the timers should be allocated
 * _Nbr_16timers indicates how many 16 bit timers are available.
 *
 */

// Say which 16 bit timers can be used and in what order
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define _useTimer5
#define _useTimer1 
#define _useTimer3
#define _useTimer4 
typedef enum { _timer5, _timer1, _timer3, _timer4, _Nbr_16timers } timer16_Sequence_t ;

#elif defined(__AVR_ATmega32U4__)  
#define _useTimer1 
typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t ;

#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define _useTimer3
#define _useTimer1
typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ;

#elif defined(__AVR_ATmega128__) ||defined(__AVR_ATmega1281__)||defined(__AVR_ATmega2561__)
#define _useTimer3
#define _useTimer1
typedef enum { _timer3, _timer1, _Nbr_16timers } timer16_Sequence_t ;

#else  // everything else
#define _useTimer1
typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t ;                  
#endif

#define Servo_VERSION           2      // software version of this library

#define MIN_PULSE_WIDTH       544     // the shortest pulse sent to a servo  
#define MAX_PULSE_WIDTH      2400     // the longest pulse sent to a servo 
#define DEFAULT_PULSE_WIDTH  1500     // default pulse width when servo is attached
#define REFRESH_INTERVAL    20000     // minumim time to refresh servos in microseconds 

#define SERVOS_PER_TIMER       24     // the maximum number of servos controlled by one timer !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! changed this to 24
#define MAX_SERVOS   (_Nbr_16timers  * SERVOS_PER_TIMER)

#define INVALID_SERVO         255     // flag indicating an invalid servo index

typedef struct  {
  uint8_t nbr        :6 ;             // a pin number from 0 to 63
  uint8_t isActive   :1 ;             // true if this channel is enabled, pin not pulsed if false 
} ServoPin_t   ;  

typedef struct {
  ServoPin_t Pin;
  unsigned int ticks;
} servo_t;

class Servo
{
public:
  Servo();
  uint8_t attach(int pin);           // attach the given pin to the next free channel, sets pinMode, returns channel number or 0 if failure
  uint8_t attach(int pin, int min, int max); // as above but also sets min and max values for writes. 
  void detach();
  void write(int value);             // if value is < 200 its treated as an angle, otherwise as pulse width in microseconds 
  void writeMicroseconds(int value); // Write pulse width in microseconds 
  int read();                        // returns current pulse width as an angle between 0 and 180 degrees
  int readMicroseconds();            // returns current pulse width in microseconds for this servo (was read_us() in first release)
  bool attached();                   // return true if this servo is attached, otherwise false 
private:
#if defined(__arm__)
   uint16_t min_ticks;
   uint16_t max_ticks;
#else
   int8_t min;                       // minimum is this value times 4 added to MIN_PULSE_WIDTH    
   int8_t max;                       // maximum is this value times 4 added to MAX_PULSE_WIDTH   
#endif
   uint8_t servoIndex;               // index into the channel data for this servo
};

#endif
 

Attachments

  • Servo_sweep_test.ino
    8.1 KB · Views: 165
Last edited:
Oh, I think I see what might be the trouble...

In Servo.cpp, find these 2 lines:

Code:
static uint16_t servo_active_mask = 0;
static uint16_t servo_allocated_mask = 0;

Try changing them to this:

Code:
static uint32_t servo_active_mask = 0;
static uint32_t servo_allocated_mask = 0;


Edit: you'll also need the change "mask" to uint32_t in Servo::Servo(), on line 364.
 
Last edited:
Oh, I think I see what might be the trouble...

In Servo.cpp, find these 2 lines:

Code:
static uint16_t servo_active_mask = 0;
static uint16_t servo_allocated_mask = 0;

Try changing them to this:

Code:
static uint32_t servo_active_mask = 0;
static uint32_t servo_allocated_mask = 0;


Edit: you'll also need the change "mask" to uint32_t in Servo::Servo(), on line 364.

Ok i tried that pins 0 to 15 work
17 to 23 are not sweeping.
Servo's are now painfully slow and so is teensy.
 
Further update.
Using this tutorial http://publiclab.org/notes/warren/10-17-2012/prototype-raspberry-pi-based-dual-ir-cam


So I figured.
Slim down the Pi and remove junk x10 mini pro parts.
Send data from X10 phone to pi and have pi command via 2x teensy 3 boards.
Use pc to control PI and u20i phone.

Right now the teensy can only drive 16 servo's.
So i figure i am better off driving 16 per teensy.

So 12 servo's on one teensy.
Then 12 to 14 on the other.
This also saves speed and effort and making wring less of a task. :)


BUT!!
Can I control both teensy's independently each with it's own serial port on the PI?
 
Last edited:
Can I control both teensy's independently each with it's own serial port on the PI?

Yes. You can plug several into the same Raspberry Pi. They will appear as /dev/ttyACM0, /dev/ttyACM1, /dev/ttyACM2, and so on. Linux assigns the numbers as it detects each board, so you'll need to implement some way to detect which board has each set of motors.

I tried these mods to the Servo library. I'm only testing with LEDs connected. I initially got 12 blinking, then 16, and then all 24. Here are the modified files:

View attachment Servo.cpp

View attachment Servo.h
 
Thanks much appreciated will remember to also look what you did.
Will remember you in the dev credits.
 
Last edited:
After looking deeper into the PI Cam conumdrum.
I saw the kinect uses A onboard image processing dsp.

Then I noticed someone found a smaller depth cam with the same dsp from asus.
Already ordered one.
So far this build is looking good.
Been fiddling in 3d max and matlab to make a simulated model that will be the basis for animating this beast.

Also got some some nice idea's the other day when watching the movie "Virus"
It was awesome and gave me some incentive to make CorA "robot name" intelligent and interactive.

Putting like my savings into her.
Really want to show the school full of numbskulls what I can pull out.
I was even blessed when my supplier sent me a extra set of 5 servo's and a 5V Regulator, specked to the batteries i'm using.

So thanks for the effort dude will keep you up to date.
The final model may drop the Rpi for a powerful 8 Core android stick running linux. "ordered but may have a month delivery time"
so i need to use the PI for now and hope shipping doesn't screw up.
 
Ok.. so how do I ID 2 teensy devices both over serial?

Well here's the answer..

Simply have teensy ping it over serial.
"hello world serial example"
The host checks what the teensy is ping-ing.

in this case my teensy pings "Servo1"
When the host looks for "Servo1" it will connect to each teensy till one matches "Servo1"
Then the host and teensy does handshake.
and the PI begins the serial stream.
 
Did you try the modified Servo files?

It's not urgent, but if you get a chance, please confirm it they truly work for all 24 motors?

If they do, in a future release I'll add some #ifdef stuff into Servo.cpp so tweaking Servo.h will work beyond the limit of 16 motors.
 
Yes sorry I tested it and it's working 100%
it's a teeny tiny bit slower but not a issue as the teensy has loads of space and processing power left.
So i have opted for the teensy to also handle some tricks to make servo control more powerful and by adding lerping, limits ect.
So the teensy is becoming a amazing servo driver.

Thank you very much.
I am in your debt.
 
Status
Not open for further replies.
Back
Top