Hey there,
i`m working on the code for my 3d-printed eye-mechanism with an arduino uno and the adafruit servo-shield and i want to randomize everything as far as possible.
Right now, i have three servos in my code (see the attachment). Servo 1 and servo 2 for Looking Up/Down and Looking Left/Right and Servo 3 for the Blinking of the Eyelid.
Right now the LOOP is like this:
Servo 1 - moves in one direction
Servo 1 - moves in the other direction
Servo 2 - moves in one direction
Servo 2 - moves in the other direction
Servo 3 - moves in one direction
Servo 3 - moves in the other direction
My question is: How can i customize the code, so that the actions 1-6 will work randomly, so the eye movement looks more realistic?
Thanks for any help with this!
Stefan
servo_TEST_September_NEU.ino (2.04 KB)
Have you looked at the random() function ? You can use it to generate (semi)random numbers to use as servo positions.
Was there a reason why you did not post your code here to make it easier to provide advice without the need to download it ?
system
September 24, 2015, 8:01am
3
My question is: How can i customize the code, so that the actions 1-6 will work randomly, so the eye movement looks more realistic?
Randomly moving up and down, left and right, and blinking will NOT look at all realistic. More like an eye that needs to see a doctor.
Thanks for the answers.
You can find the code in the attachment of the first post!
And of course you are right, that complete randomized actions will not look realistic,
but i want to use it just very rare. If the action always looks the same, you can see the pattern.
Thatss what i
m trying to avoid.
For example the blinking of the eye on servo3.
How can i change the code, so that this blinking-action sometimes happens one time, sometimes for 2 times..?
Thanks again,
Stefan
system
September 24, 2015, 8:47am
5
How can i change the code, so that this blinking-action sometimes happens one time, sometimes for 2 times..?
int timesToBlink = random(0, 10000);
for(int b=0; b<timesToBlink; b++)
{
blink();
}
You can find the code in the attachment of the first post!
Yes, I saw that, but it would have been easier if you had posted it here rather than attached it which would have avoided the need to download it.
At the time I am writing this your post has been viewed 36 times but the code has only been downloaded once. If you had posted it then it would have been seen 36 times instead of once.
Right. Here we go.
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
#define SERVOMIN (250) // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX (400) // this is the 'maximum' pulse length count (out of 4096)
int servo0 = 0;
int servo1 = 1;
int servo2 = 2;
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setPWMFreq(60);
}
// you can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise!
void setServoPulse(uint8_t n, double pulse) {
double pulselength;
pulselength = 1000000; // 1,000,000 us per second
pulselength /= 60; // 60 Hz
Serial.print(pulselength); Serial.println(" us per period");
pulselength /= 4096; // 12 bits of resolution
Serial.print(pulselength); Serial.println(" us per bit");
pulse *= 1000;
pulse /= pulselength;
Serial.println(pulse);
pwm.setPWM(n, 0, pulse);
}
void loop() {
/// Servo 0 (Up/Down)
Serial.println(servo0);
for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen += random(1, 5)) {
pwm.setPWM(servo0, 0, pulselen);
delay(random(3,6));
}
delay(600);// Delay
for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen -= random(1, 3)) {
pwm.setPWM(servo0, 0, pulselen);
delay(random(1,6));
}
delay(random(50,400)); // Delay between 2 servos
/// SERVO 2 (Left/Right)
for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
pwm.setPWM(servo1, 0, pulselen);
delay(random(3,8));
}
delay(600);// Delay
for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
pwm.setPWM(servo1, 0, pulselen);
delay(random(3,9));
}
delay(random(50,1000)); // Delay zwischen 2 servos
/// Servo3 (Blinking)
for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
pwm.setPWM(servo2, 0, pulselen);
}
delay(50);// Delay
for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
pwm.setPWM(servo2, 0, pulselen);
}
delay(600);
}
Better, but it would be even better if it were in code tags. Edit your post, select the code and click on the </> icon at the left above the editor window. The code will be displayed in a scrolling window with an option to select it all ready for copy/paste.
Ok. Thanks. Like i said, Just starting, but willing to learn!
system
September 24, 2015, 11:40am
10
One thing you should do is put the code to move the servo left and right in a function. Put the code to move up and down in another function. Put the code to blink in a third function.
Then, you'd see that all that loop() is doing is
void loop()
{
lookLeftAndRight();
lookUpAndDown();
blink();
}
Perhaps THAT is the real problem.
Ok. Got it. Now i implemented the function, what certainly was very important
But how do i use the random() command on my functions?
Let`s say the blinking() should come with a chance of 20 Percent in every loop:
void loop()
{
lookLeftAndRight();
lookUpAndDown();
blinking();
}
Here is the actual code with functions...
/// Randomize functions
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
// called this way, it uses the default address 0x40
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
#
//Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver(0x41);
#define SERVOMIN (250) // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX (400) // this is the 'maximum' pulse length count (out of 4096)
int servo0 = 0;
int servo1 = 1;
int servo2 = 2;
void setup() {
Serial.begin(9600);
pwm.begin();
pwm.setPWMFreq(60);
}
// you can use this function if you'd like to set the pulse length in seconds
// e.g. setServoPulse(0, 0.001) is a ~1 millisecond pulse width. its not precise!
void setServoPulse(uint8_t n, double pulse) {
double pulselength;
pulselength = 1000000; // 1,000,000 us per second
pulselength /= 60; // 60 Hz
Serial.print(pulselength); Serial.println(" us per period");
pulselength /= 4096; // 12 bits of resolution
Serial.print(pulselength); Serial.println(" us per bit");
pulse *= 1000;
pulse /= pulselength;
Serial.println(pulse);
pwm.setPWM(n, 0, pulse);
}
void loop()
{
lookLeftAndRight();
lookUpAndDown();
blinking();
}
/// Servo 0
void lookLeftAndRight(){
Serial.println(servo0);
for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen += random(1, 5)) {
pwm.setPWM(servo0, 0, pulselen);
delay(random(3,6));
}
for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen -= random(1, 3)) {
pwm.setPWM(servo0, 0, pulselen);
delay(random(50,800));
}}
/// SERVO 1
void lookUpAndDown()
{
for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
pwm.setPWM(servo1, 0, pulselen);
delay(random(3,8));
}
for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
pwm.setPWM(servo1, 0, pulselen);
delay(random(50,800));
}}
/// Servo 2
void blinking() {
for (uint16_t pulselen = SERVOMIN; pulselen < SERVOMAX; pulselen++) {
pwm.setPWM(servo2, 0, pulselen);
delay(20);// Delay
for (uint16_t pulselen = SERVOMAX; pulselen > SERVOMIN; pulselen--) {
pwm.setPWM(servo2, 0, pulselen);
}
}}
system
September 24, 2015, 2:10pm
12
Let`s say the blinking() should come with a chance of 20 Percent in every loop:
void loop()
{
lookLeftAndRight();
lookUpAndDown();
if(random(0, 101) > 20)
{
blinking();
}
}
GREAT. Thanks a lot again for your help! Big step forward for me
That´s exactly what i was looking for!
St
Let`s say the blinking() should come with a chance of 20 Percent in every loop:
void loop()
{
lookLeftAndRight();
lookUpAndDown();
if(random(0, 101) > 20)
{
blinking();
}
}
Strictly speaking that gives an 80% chance of calling the blinking() function rather than 20%, but it looks like the OP got the general idea.
system
September 24, 2015, 4:46pm
15
Strictly speaking that gives an 80% chance of calling the blinking() function rather than 20%
Point one stinking symbol the wrong way... 8)