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 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.
/*
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.
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 da läuft alles schneller . gibts da noch was anderes als delay?
lg
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
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.
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.
/*
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
}