Servo angle, speed, and interval all random?

hey all,
ok so here's Part Duex, sorry couldn't resist, to my crow dilemma. Alto777 was able to help me through the programming of the eyes (led) to run randomly (on & off duration, intervals all at random each loop), now I need a way to bring in the 2 servos (crow heads) to run randomly as well. I would like random angles, at random speeds, and at random times. Also a way to speed up the operation of all when triggered by a pir.

While I'm at it, I would also like my own island, one of the first condos in space, and to be able understand the inner workings of a woman's mind.
:rofl: :joy: :grin:

Ok, I'll just settle for help with the servo. I've tried several different ways but just have become lost.

anyone have any suggestions or push me in the right direction?

Show us your sketch, start a project in Wokwi and add the servo motors and a pir sensor, try something and show us how far you got.
It is hard work.

For your own island, start digging a pool and make a small island in it. A condos in space or on the moon or mars will not happen in our lifetime for the average human being, and search for "the nothing box".

#include <Servo.h>   //include servo library

unsigned long currentTime = millis();  // intitalizes start time
unsigned long servo1Time;   //used by code for formula
unsigned long servo2Time;   //used by code for formula
long posMin = 15;   //minimum servo position
long posMax = 145;   //maximum servo position
long spdMin = 1;   // min speed of servo
long spdMax = 5;   // max speed of servo
long waitMin = 500;   //minimum time between servo position changes
long waitMax = 1000;   //maximum time between servo position changes
unsigned long ranPos = random(posMin, posMax);
unsigned long spd = random(spdMin, spdMax);
unsigned long wait = random(waitMin, waitMax);
long pos;

Servo servo1; // name servo 1
Servo servo2; // name servo 2

void setup(){
servo1.attach(11);   //sets crow 1 servo to pin 8
servo2.attach(12);   //sets crow 2 servo to pin 9
ranPos = random(posMin, posMax);
spd = random(spdMin, spdMax);
wait = random(waitMin, waitMax);
}

void loop(){
  if (currentTime - servo1Time >= wait){
    for (pos >= posMin; pos <= posMax; pos = spd) {
    servo1.write(ranPos);
    servo2.write(ranPos);
    }
  }
}

I would like to appeal to all users here:

When I look at the program that user pwoordward has posted, he doesn't even seem to have understood what the function setup and what the function loop is for. He didn't understand what the fundamental difference is.

I think that's too easy a behavior. I urge all users to only post hints again when user woordwart can explain what function setup does and what function loop does.
Or if user pwoodward has modified the above code example in such a way that you can see from it that he knows what function setup and what function loop are used for.

The other possible explanation for the code that user pwoodward posted is that it was too convenient to write more.

For you It is about time to learn what function setup does and what function loop does

Be the change you want to see in the world
best regards Stefan

ok well, hopefully you've gotten that out of your system.

  1. its woodward, not woodwart
  2. I'm not somebody that hasn't been trying to figure this out on their own, I hate asking for help especially when I get responses like this
  3. you could've just gone by the thread if you weren't interested in helping

be the change you want to see
say nice things or say nothing

What do you expect that for loop to do?

The ranPos and spd variables are randomized in setup and never change thereafter. If the for loop worked, it would just write the same number to the servos over and over.

The currentTime and servo1Time are declared and initialized and never changed. Servo1Time is not updated.

Review these non-blocking timing tutorials:
Blink without delay().
Beginner's guide to millis().
Several things at a time.

That code does not really do anything. It looks like you are posting code and hoping someone will correct it for you.

Look at using VarSpeedServo.h rather Servo.h. It has a speed parameter to the write() that will do some of the work for you.

Steve

I can post every single version Ive done, because I saved every one in hopes that something I've tried actually starts to do something. Sure I could post a code for sweep and hope someone fixes it but thats not what I am looking for. I not actually even asking anyone to solve it for me, just give me some tips, pointers, a direction and I go with it

Thanks to all who like to help

thanks Steve I'll look into that

I asked a question and pointed out a couple of issues. Are you going to address those or am I wasting my time?

  • determining random values once in setup() doesn't seem very random. new random values need to be gotten each iteration they are used
  • presumably servo1Time is the timestamp of the previous iteration. i would simply call it msecLast. it needs to be updated each time the wait period has expired
  • updating pos to spd in the for loop doesn't seem right. should is be a delay between each servo position change
  • seems the for loop sequences the value of pos, but the servos are repeatedly set to ranPos. is pos intended to move from the previous random position to a new random position? will a dir value be needed to update pos in the for loop depending on if the current pos is > or < the new random position?

I didn't think that blink without delay would help me in this aspect, but yes I've read that and watched several YouTube videos on it.

Again, the same with beginners guide to millis().

and again, the same with several things at a time.

actually the last one was the one that helped me the most but still couldn't quite get what I was looking for. I guess I am making it too complicated for someone like me who doesn't fully grasp some concepts.

If there will be condescension, please don't waste your time on me.

So I would be adding something like this?

void loop(){
ranPos = random(posMin, posMax);
spd = random(spdMin, spdMax);
wait = random(waitMin, waitMax);

  if (currentTime - servo1Time >= wait){
    for (pos >= posMin; pos <= posMax; pos = spd++) {
    servo1.write(ranPos);
    servo2.write(ranPos);

I didn't think that using "delay" in a code using millis() was a "proper' thing to do. I am going to add this code in an already formatted code for leds using millis.

Yes I am looking for the servo to move to a new position at each random time interval at a random speed. The position doesn't necessarily be greater or less than the previous one.

I guess I am making it more complicated than it needs to be. I probably will just need to break down the code into each segment (random angle, random speed, random interval), then try to get all of them together.

since servo1Time is never updated, this condition will always be true once currentTime >= wait.

this loop will continue forever since pos is never set to anything other than spd

depends on their values. what is the purpose of the wait period

what is the purpose of the for loop changing pos if the servo is always set to ranPos

consider

    int dir = 1;
    if (posLst > ranPos
        dir  = -1;
    for (pos >= posLast; pos <= ranPos; pos  += dir) {
        servo1.write (pos);
        delay (spd);
    }
    posLst = pos;

does the above make sense

seems like you need to learn what the code is doing before you can do what you say

No. Please go back to the code in your other thread. You are repeating the same mistakes in this effort as you did in the other thing.

Read the different versions, look at how the one that works isn't like the one that doesn't. And note that you are doing something very similar here, both in the sense of what you want to have happen, and the slight being off the rails a bit when expressing yourself in the code.

The main thing is that in code like this you can put your pencil down on it and step through it all by yourself, no microprocessor needed. The code happens one line at a time, nothing up a sleeve anywhere, no mirrors, no smoke.

I think you may still feel that you can have set a relationship between a variable and a computation that will remain happening. For a few variables.

a7

Ok so correct me if I dont understand it....

    int dir = 1;  //positive direction equal to 1
    if (posLst > ranPos; //if last position is greater than the new chosen random position
        dir  = -1;  // go in opposite direction in increments of 1
    for (pos >= posLast; pos <= ranPos; pos  += dir) {
        servo1.write (pos);
        delay (spd);  //for the current positions that are greater than or equal to the last position AND positions that are less than or equal to the new random position, go in increments of 1 in the positive direction
    }
    posLst = pos; //the last position now becomes the current position

I needed the wait period so it wasn't constantly changes positions. A little "breather" if you will between changes, but didn't want it set to a certain time, and wanted all other functions to operate without be blocked by a delay.

The spd, I thought or I was trying to, adjust the rate at which it went from one position to the next.

You have been helpful and given me some things to look at, learn, and consider.

Thanks

Sorry Obi-Wan, i will go back to my training and see where I've messed up again

lol, thanks

incrementally (+/-1) increase the value of pos, moving the servo from posLst (sic) to ranPos delaying by spd-millisecond between each iteration

see for loop in C

are you taking this seriously?
you need to me more appreciative

And this is where

  • non-blocking timing based on function millis()
  • and doing certain things at the same time comes into play.

As a starting point a demo-code that prints a random value to the serial monitor once every second
using non-blicking timing


// easy to use helper-function for non-blocking timing 
boolean TimePeriodIsOver (unsigned long &expireTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - expireTime >= TimePeriod ) {
    expireTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  }
  else return false;            // not expired
}

unsigned long MyTestTimer =  0; // Timer-variables MUST be of type unsigned long
const byte    OnBoard_LED = 13;

long randomlyAssignedStart;
int  myRandomNr;

void setup() {
  Serial.begin(115200);
  Serial.println( F("Setup-Start") );
  Serial.println( F("Demonstrating randomSeed()") );
  Serial.println( F("Demonstrating get randomised values") );
  
  // use floating IO-pin A0 to obtain a somehow randomly chosen number
  // to "shake through" function random with function randomSeed()
  randomlyAssignedStart = analogRead(A0);
  randomSeed(randomlyAssignedStart);
  myRandomNr = random(0, 1000);
  Serial.print("function random() starts with ");
  Serial.println(myRandomNr);
  MyTestTimer = millis(); // initialise Timer-variable 
}


// a function that does a senseful sub-unit of things
// with a SELF-explaining name
void GetAndPrintRandmoNr() {                         // first  line of declaration
  myRandomNr = random(0, 1000);                      // second line of declaration
  Serial.print("function random() has given value ");// third  line of declaration
  Serial.println(myRandomNr);                        // fourth line of declaration
}                                                    // last   line of declaration


void loop() {

      // function TimePeriodIsOver results in true of amount if milliseconds
      // specified in the second parameter have passed by
      // otherwise results in false 
  if ( TimePeriodIsOver(MyTestTimer, 1000) ) {
    // if 1000 milliseconds = 1 second have passed by
    GetAndPrintRandmoNr(); // line that  "calls"  the function = execute lines of code given in the declaration
  }
}

Be the change you want to see in the world
best regards Stefan