4 servos via zufall auslösen Anfänger braucht hilfe

Hallo,
ich habe von der ganzen Sache hier erst mal kein Plan . Sorry!
ich bastel viel zu selten mit servos und einen Arduino rum .
Wir wollten hier ein kleines spassprojekt basteln aber irgenwie finde ich keine lösung .
Um was gehts : Um ein Auge das sich bewegt :slight_smile: https://www.instructables.com/3D-Printed-Animatronic-Eye-Mechanism-on-the-Cheap/

Wir haben das mal gedruckt und aufgebaut aber das mit Taster und den verstellbaren wiederständen finde ich blöd und würde das ganze gerne via zufall haben wollen .
Geht das ? wenn ja würde ich mich über hilfe freuen . Für ein profi ist das sicher ein witz . Für uns hier nur der spass . ich habe mich mit random beschäftigt aber wie ich das so nutzen könnt ???
lg Toni

Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden. Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.

mfg ein Moderator.

Klar - zumal der Code recht einfach ist.

/*
  Controlling a servo position using a potentiometer (variable resistor)
  by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

  modified on 8 Nov 2013
  by Scott Fitzgerald
  http://www.arduino.cc/en/Tutorial/Knob
*/

#include <Servo.h>

Servo x;  // create servo object to control a servo
Servo y;
Servo b;
Servo t;

int xpotpin = 1;  // analog pin used to connect the potentiometer
int ypotpin = 0;
int opin = 2;
int bpin = 10;

int xval;    // variable to read the value from the analog pin
int yval;
int bval;
int tval;
int xxval;
int yyval;
int oval;
int blinkval;

void setup()
{
  pinMode(bpin, INPUT);
  x.attach(8);  // attaches the servo on pin 9 to the servo object
  y.attach(9);
  b.attach(6);
  t.attach(7);
  Serial.begin(9600);
}

void loop()
{
  blinkval = digitalRead(bpin);
  oval = analogRead(opin);
  xval = analogRead(xpotpin);            // reads the value of the potentiometer (value between 0 and 1023)
  yval = analogRead(ypotpin);
  oval = map(oval, 0, 1023, -10, 10);
  xxval = map(xval, 0, 1023, 65, 125);     // scale it to use it with the servo (value between 0 and 180)
  yyval = map(yval, 0, 1023, 100, 20);
  if (blinkval == 0)
  {
    bval = 60;
    tval = 50;
    b.write(bval);
    t.write(tval);
  }
  else
  {
    bval =  map(yval, 0, 1023, 110, 150);
    tval =  map(yval, 0, 1023, 120, 90 );
    b.write(bval + oval);
    t.write(tval + oval);
  }
  x.write(xxval);                  // sets the servo position according to the scaled value
  y.write(yyval);
  delay(5);                           // waits for the servo to get there
}

Alles was map ist raus und durch random ersetzt.
Im setup ein randomize(A0); ergänzt und dann den loop umgeschrieben:

void loop()
{
  blinkval = digitalRead(bpin);
  oval = random (-10, 11);
  xxval = random( 65, 126);     // scale it to use it with the servo (value between 0 and 180)
  yyval = random(20, 101);
  if (blinkval == 0)
  {
    bval = 60;
    tval = 50; random rein
    b.write(bval);
    t.write(tval);
  }
  else
  {
    bval =  random(110, 151);
    tval =  random(90, 121 );
    b.write(bval + oval);
    t.write(tval + oval);
  }
  x.write(xxval);                  // sets the servo position according to the scaled value
  y.write(yyval);
  delay(5);                           // waits for the servo to get there
}

Aber dann ggfls. auch das delay erhöhen um das erstmal auszutesten.
Später dann den Code erweitern um vernünftige Bewegungen zu bekommen.

Super Das teste ich dann gleich mal . Also lag ich ja mit random nicht mal falsch . nur eben null plan . danke Schön

also das läuft ja schon mal super . soweit ich das verstanden habe sagt mir ```
delay(1000); z.b. 1 sek das pass ganz gut nur das Augenlid oben müsse schneller gehen also ein extra delay haben . yyval = random(20, 101); also einfach dahinterschreiben geht schon mal nicht :slight_smile: da läuft alles schneller . gibts da noch was anderes als delay?
lg

nicht blockierendes Timing mit millis()

unsigned long DemoTimer      = 0; // variables that are used to store values of function millis()
unsigned long DemoTimerTwo   = 0; // the must be of type unsigned long to work properly all the time
unsigned long DemoTimerThree = 0;
unsigned long DoDelayTimer   = 0;

unsigned long myCounter = 0;

// 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
}


void setup() {
  Serial.begin(115200);
  Serial.println("Program started activate Show timestamp in serial monitor");
  Serial.println("maximise window of serial monitor");
  Serial.println("to see the the messages in full.......................................................length");
}


void myDemofunction_1() {
  Serial.println("once per second Huhu ! time for Action A ");
  Serial.print("myCounter=");
  Serial.println(myCounter);
}

void myDemoFuncB() {
  Serial.println("once every 3 seconds Hi there                      time for Action B once every 3 seconds");
}

void my_Demo_function_3() {
  Serial.print("once every 5 seconds ready now");
  for ( int i = 0; i< 40; i++) {
    Serial.print(".");
  }  
  Serial.println("time for Action C once every 5 seconds");
}


void loop() {
  myCounter++; // count up very fast to demonstrate the non-blocking character
  if (  TimePeriodIsOver(DemoTimer, 1000)  ) {
    myDemofunction_1();
  }


  if (  TimePeriodIsOver(DemoTimerTwo, 3000)  ) {
    myDemoFuncB();
  }

  if (  TimePeriodIsOver(DemoTimerThree, 5000)  ) {
    my_Demo_function_3();
  }

  // show the effect of BLOCKING timing caused by function delay()
  if (  TimePeriodIsOver(DoDelayTimer, 20000)  ) {
    Serial.println("every 20 seconds execute delay(5500)... to make all other timers overdue");
    
    Serial.print("value of myCounter right before delay =");
    Serial.println(myCounter);
    
    delay(5500);
    
    Serial.print("value of myCounter right AFTER delay =");
    Serial.println(myCounter);

    Serial.println("as delay(5500 has BLOCKED code-execution all three timers are overdue");
    Serial.println("which means all three timers fire in the SAME microsecond one after the other ");
  }
}

/*
  the basic principle of non-blocking timing is to check if a defined timeinterval
  has passed by.

  This can be done by using the function millis()
  The function millis()gives back the amount of milliseconds (hence the name millis)
  that have passed by since power-up of the microcontroller.
  It counts up to 2^32 which means reaching the max-value is reached after 49 days.
  There is a calculation-technique that even "rollover" from max to zero is handled
  automatically the right way

  This non-blocking timing needs a timer-variable which is used for taking
  snapshots of time as a comparison-point

  The variable-type for this variable MUST be of type unsigend long
  to make it work reliably all the time

  unsigned long myLcdUpdateTimer;

  now the following construction executes the code inside the if-condition
  only once every two seconds

  if ( TimePeriodIsOver(myLcdUpdateTimer,2000) ) {
     // time for timed action
  }

additionally the code demonstrates how you can code your own functions
and how to call/execute them.
The names of the functions are a bit lengthy to demonstrate which names 
inside the code you can choose freely and to demonstrate where really a relation
between names is and where NO relation between names is

*/

Hallo
Das IDE bietet ein super Beispiel für die Verwendung der millis() Funktion an.
Schaue im IDE Datei/Beispiele/Digital/BlinkWithoutDelay
Ich wünsche einen geschmeidigen Tag und viel Spass beim Programmieren in C++.

Das sich auf eine - meiner Meinung nach - völlig bescheuerte Art und Weise auf das Minimum beschränkt was man so programmieren muss um nicht blockierendes Timing zu machen. Aber gerade weil es so minimal ist und das wirklich wichtige am Grundprinzip NICHT in den Kommentaren steht ist es schwer zu verstehen.

Das das für Anfänger schwer zu verstehen ist, ist anscheinenend für Experten schwer zu verstehen.
vgs

ich sehe schon bei den counter sachen nicht mehr durch :slight_smile: bin wo zu alt dafür . irre . muss ich mir ganz ganz in ruhe ansehen . lg

Hallo
Ich habe es gelernt indem ich damit ein bißchen gespielt habe. Das IDE Beispiel lädt dazu förmlich ein, den Sketch zu verändern. Dabei muss ja nicht gleich OOP Code rauskommen.
Ich wünsche einen geschmeidigen Tag und viel Spass beim Programmieren in C++.

Ja.
Zeit auswerten und mit Ablauf Aktion ausführen und Zeit merken und wieder von vorn.

Das mit dem

Habe ich gewusst.

:slight_smile:

Vom Prinzip her ist das einfach zu lösen, indem für jeden Servo Anfang und Ende festgelegt und dann eine Position zufällig ausgewählt wird.
Diese Position wird dann Schrittweise im x*y ms-Takt angefahren.
Ist die ausgewählte Position GLEICH der angefahrenen Position wird eine neue Position per Zufall errechnet und von dort aus weiter gemacht.

Ich würde das mit dem Augenlied einzeln anfangen und den Rest erstmal auskommentieren.
Später kann der Code genauso weiterverwendet werden für die anderen beiden Servos - nur die Parameterliste wird erweitert.

Willst?

das klingt super . ich hab jetzt mal alles so bissel eingestellt und passt schon ganz gut nur eben mit dem Augenlied ... lg

bval = random(-10, 50 ); // servo linse hoch runter
tval = random(70, 130 ); // linse rechts links

// bval = 90;
//& tval = 50;// random rein
b.write(bval);
t.write(tval);
}
else
{
bval = random(110, 151);
tval = random(90, 121 );
b.write(bval + oval);
t.write(tval + oval);

die werte passen super von höhe und so . (servo)

kann man hier irgenwie ein video einstellen ? da könnte ich das mal zeigen wie es jetzt aussieht ?
lg

Na dann nur noch die Zeitkonstante. Las mir mal nen Moment ich muss hier parallel noch auf was aufpassen.

Sind das beide Servos für den Augenaufschlag?

warte
xxval = random(10, 100), yyval = random(-40, 90); // lid unten
// yyval = random(-40, 90); // lid open
....

bval = random(-10, 50 ); // servo linse hoch runter
tval = random(70, 130 ); // linse rechts links

es sind 4 servos

Anders: Welcher PIN macht was - ich komm hier derzeit nicht an das Original...

  x.attach(8);  // attaches the servo on pin 9 to the servo object
  y.attach(9);
  b.attach(6);
  t.attach(7);

7-8 sind linse
9-10 sind die augenlieder

/*
 Controlling a servo position using a potentiometer (variable resistor)
 by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>

 modified on 8 Nov 2013
 by Scott Fitzgerald
 http://www.arduino.cc/en/Tutorial/Knob
*/

#include <Servo.h>

Servo x;  // create servo object to control a servo
Servo y;
Servo b;
Servo t;

int xpotpin = 1;  // analog pin used to connect the potentiometer
int ypotpin = 0;
int opin = 2;
int bpin = 10;

int xval;    // variable to read the value from the analog pin
int yval; 
int bval;
int tval;
int xxval;
int yyval;
int oval;
int blinkval;

void setup() {
  pinMode(bpin, INPUT);
  x.attach(8);  // attaches the servo on pin 9 to the servo object
  y.attach(9);
  b.attach(6);
  t.attach(7);
  Serial.begin(9600);
}

void loop()
{
  blinkval = digitalRead(bpin);
 oval = random (-100, 100);
 xxval = random(10, 100), yyval = random(-40, 90); // lid unten
// yyval = random(-40, 90); // lid open
  

  if (blinkval == 0)
  {

  bval =  random(-10, 50 ); // servo linse hoch runter
  tval =  random(70, 130 ); // linse rechts links
 
  
  //  bval = 90;
  //& tval = 50;// random rein
    b.write(bval);
    t.write(tval);
  }
  else
  {
    bval =  random(110, 151);
    tval =  random(90, 121 );
    b.write(bval + oval);
    t.write(tval + oval);
  }
  x.write(xxval);                  // sets the servo position according to the scaled value
  y.write(yyval);
  delay(2000);                           // waits for the servo to get there
}

Moment...

da ist nichts mit 10 :face_with_monocle:
Für ein Auge: Welcher PIN ist für den Linse-Servo und welcher Pin ist für das LidServo?
Bitte...

stop hast recht :slight_smile: 8-9 sind die lider und 7-6 linse
hier mal das video dazu :slight_smile: hab es fix bei youtube hochgeladen