@will I know, I know, teacher teacher ask me!
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
Β
Β
Anything seems possible when you don't know what you're talking about.
So, they could be 'void'. I know it is good form to write return(0); for an int function that doesn't actually return a value. The Arduino IDE and the GCC don't seem to mind. I will try them as 'void', but I have to get to bed. The alarm goes off a 5:00 am. Thanks for all the advice.
ZoolanderMicro, where small ideas are a big deal
I know it is good form to write return(0); for an int function that doesn't actually return a value.
Actually, if an int function doesn't return an int, then it shouldn't be an int function. It's not wise to risk angering the compiler π
Anything seems possible when you don't know what you're talking about.
@will Back in the day, my rule was to set the compiler to show EVERY message including warnings. That meant no implicit casts, everything had to be specified. It teaches thoroughness and good form. I did get pushback until I showed that one level W or I not sure anymore, could result in a runtime crash under not farfetched circumstances. The benefit of being specific was a 50% speed gain for the operation. That makes it far more important than 'just' cosmetic.
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
Any way, I had a chance to clean up my code (as per suggestions). Looks nice, but the thirteenth servo still does not attach. The robot's head doesn't reallyy need to move, it would just look cool. On the head is a sonic distance sensor. I can still run the obsticle avoidence code. If the head could sweep, the code could make a choice of moving left or right. That would be a nice tric. For your viewing pleasure I present my test code:
/* Adeept Hexapod test code written to test each of thriteen servos. */ #include <Servo.h> //Servo control #define servoData 13 //Number of servos #define numSweeps 2 //Number of Hexapod head sweeps left and right #define debug //Comment out this line to disable serial output const int MIN_ANGLE = 10; //Minimum sweep angle of bot head const int MAX_ANGLE = 170; //Maximum sweep angle of bot head int angle[servoData] = {90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90}; Servo myServo[servoData];//Create servo object.Indecies 0 through 12 (13 servos) void setup() { #ifdef debug Serial.begin(9600); //For serial monitor output #endif for (int index = 0; index < servoData; index++) { //Attach servos to pins 2 through 14 myServo[index].attach(index + 2); } for (int index = 0; index < servoData; index++) { //Set all servos to 90 degree angle myServo[index].write(angle[index]); } delay(1000);//wait for a second } void loop() { for (int count = 0; count < servoData; count++) { //Counts from 0 - 12 if (count <= 5) { //Test range 0 - 5 moveServos_L(count); //Move servos on left side } else if (count > 5 && count < (servoData - 1)) { //Test range 6 - 11 moveServos_R(count); //Move servos on right side } else { //Value of 'count' is 12 botHead_Sweep(count); //Move head servo } } } //Functions void moveServos_L(int servo) { //Left side pivot and claw servos if (myServo[servo].attached()) { //If the servo is attached, proceed with the function myServo[servo].write(60); delay(500); myServo[servo].write(90); delay(500); myServo[servo].write(120); delay(500); myServo[servo].write(90); delay(500); } //End if } //End function void moveServos_R(int servo) { //Right side pivot and claw servos if (myServo[servo].attached()) { //If the servo is attached, proceed with the function myServo[servo].write(120); delay(500); myServo[servo].write(90); delay(500); myServo[servo].write(60); delay(500); myServo[servo].write(90); delay(500); } //End if } //End function void botHead_Sweep(int servo) { //Head servo pivots //if (myServo[servo].attached()) { //If the 13th servo is attached, proceed with the function #ifdef debug Serial.print("Servo "); Serial.print(servo); Serial.println(" is not attached"); #endif for (int count = 0; count < numSweeps; count++) { //The head sweeps left and right twice static int sweep = 10; //initialize sweep angle to 10 degrees while (sweep < MAX_ANGLE) { myServo[servo].write(sweep); sweep = sweep + 1; delay(10); //wait } while (sweep > MIN_ANGLE) { myServo[servo].write(sweep); sweep = sweep - 1; delay(10); //wait } } //End for loop //} //End if }//End function
ZoolanderMicro, where small ideas are a big deal
Here is a slightly modified version which creates the head as a separate entity from the array. It also includes a few mods to reduce the code and I've added some pre-processor Serial prints for debugging.
I am curious to see if part (or maybe all) of the problem is memory being overwritten.
Anything seems possible when you don't know what you're talking about.
I just read throught your code. Looks excellent. It tests, in the setup function, if the head servo is attached to pin 14. I had tried creating a separate servo object before without success. I will try your code when I get home from work tonight. Thanks @will .Β
ZoolanderMicro, where small ideas are a big deal
@will line 20, the comment should be 2 through 13 I think
First computer 1959. Retired from my own computer company 2004.
Hardware - Expert in 1401, and 360, fairly knowledge in PC plus numerous MPU's and MCU's
Major Languages - Machine language, 360 Macro Assembler, Intel Assembler, PL/I and PL1, Pascal, Basic, C plus numerous job control and scripting languages.
My personal scorecard is now 1 PC hardware fix (circa 1982), 1 open source fix (at age 82), and 2 zero day bugs in a major OS.
I just Googled the kit and it only seems to implement the legs, with the head being fixed in position. I had assumed (a nasty habit) that there was original working code that used 13 servos.
Google also seems to indicate that 12 is about the max number of servos that Servo.h can handle. There is supposedly another library that lets you use any pin as a servo driver but I haven't investigated it.
To move the head, you could just use a DC motor and controller or even stepper motor (which might allow more precise control over the direction).
Anything seems possible when you don't know what you're talking about.
HiΒ
Just read a quick summary of your posts re problem connecting a 13th servo.
I had a look at this library write up on the arduino site and it looks like 12 is the maximum unless your board is an arduino Due.
This is an extract:
Servo
Device Control
Allows Arduino boards to control a variety of servo motors.
This library can control a great number of servos. It makes careful use of timers: the library can control 12 servos using only 1 timer. On the Arduino Due you can control up to 60 servos.
Is this your issue?
Ron Bentley
Ron Bentley
Creativity is an input to innovation and change is the output from innovation. Braden Kelley
A computer is a machine for constructing mappings from input to output. Michael Kirby
Through great input you get great output. RZA
Gauss is great but Euler rocks!!
@will @zander @ronbentley1 I verified the code that Will provided. Avrdude reported:
Sketch uses 4020 bytes (12%) of program storage space. Maximum is 32256 bytes. Global variables use 379 bytes (18%) of dynamic memory, leaving 1669 bytes for local variables. Maximum is 2048 bytes.
The code useses very little program or dynamic memory. Uploaded the code and the Hexapod legs worked through their routene, but the head servo still didn't move. Output to the serial monitor:
myHead servo assigned pin is 14 which is attached In botHead_Sweep the head servo is attached
The serial output confirms that the servo controling the head is attached, and the action of the Hexabot indicates that the code in function botHead_Sweep() is running. There is a pause before the leg movement resumes. The first 12 servos are seized by timer 0. The next twelve servos would be seized by timer 1 (inference from the note in the servo.h file). Timer 1 may not be running at the correct frequency to produce the proper PWM output to run the servo. I will reference a book I have that explains how to set the timer frequeicies. Setting the proper frequency of timer 1 may resolve this issue (I can only hope). Thanks for the code example. I like the efficientcy of your code changes.
ZoolanderMicro, where small ideas are a big deal
Hi again,
Ive just looked at the servo library files and your use of 13 servos should be okay as the library object should claim 2 x 16 bit timers on instantiation. This would mean that with these two times 24 servos should be supportable.
It's a bit suspicious that 12 is working, these supported by the first 16 bit time but the 13th isn't, which should be on the second timer
In case there is a boundary value condition error in the library try increasing your number of servos to 14, to see if you get the 13th working.
If so, then there is likely to be a boundary condition error?
Ron Bentley
Β
Ron Bentley
Creativity is an input to innovation and change is the output from innovation. Braden Kelley
A computer is a machine for constructing mappings from input to output. Michael Kirby
Through great input you get great output. RZA
Gauss is great but Euler rocks!!
On the Arduino Due you can control up to 60 servos.
The Adeept Pixie board has a Mega328P chip like the Arduino Uno board. I think the Due uses a Mega2560 chip.
ZoolanderMicro, where small ideas are a big deal