Arduino besturing voor animatronic op menselijke grootte

Als U een gezamenlijk project wil starten of aan projecten van anderen mee wilt werken.
Berichten: 1
Geregistreerd: 03 Aug 2014, 18:26

Arduino besturing voor animatronic op menselijke grootte

Berichtdoor rickvanriel » 03 Aug 2014, 19:22

Hallo Allemaal!

Ik ben nieuw op dit forum en ook nieuw met Arduino!
Mijn naam is Rick van Riel, ik ben 20 jaar en heb een grote interesse voor attractieparken e.d.
De afgelopen jaren heb ik in mijn hobby verschillende attractiepark-gerelateerde projecten gerealiseerd,
waarover meer te zien is op mijn youtube kanaal: http://www.youtube.com/rickvanriel

Voor mijn nieuwste project ben ik op zoek naar iemand die het leuk vind om mij een handje te helpen bij
het schrijven van een Arduino programma voor een animatronic op menselijke grootte.
("menselijke robot" zoals die veel te zien zijn in Disneyland, Efteling enz.)
De robot is mechanisch al helemaal klaar en functioneert naar behoren, echter het schrijven van een
Arduino programma is voor mij nog een grijs gebied.

Vandaar de vraag of er mensen op dit forum zijn die mij hiermee kunnen / willen helpen?
Mocht je interesse hebben stuur dan even een mailtje, dan zorg ik voor aanvullende informatie.

Alvast vriendelijk bedankt!

Rick van Riel
rick.van.riel@hotmail.com

Advertisement

Berichten: 4067
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Arduino besturing voor animatronic op menselijke grootte

Berichtdoor shooter » 03 Aug 2014, 22:50

na het zien van jouw fm wil ik graag een avondje schrijven, heb je al een beschrijving van je robot en een flow wat er moet gebeuren.
ik ben een boschenaar (kruiskamp) dus wellicht woon je nog dichtbij ook nog.
een arduino is echt simpel, een paar simpele instructies en het gaat al goed kmen.

ik zag dat je al ervaring hebt met een plc dus geen probleem lijkt mij.

wel een vraagje natuurlijk, waarom heb je het slepen omgebouwd naar een rijdend karretje (veel meer techniek, wat kapot kan, je kunt de zaak wel voeden via de vloer, waardoor het allemaal door kan lopen.
paul deelen
shooter@home.nl

Berichten: 4067
Geregistreerd: 16 Okt 2013, 14:31
Woonplaats: s hertogenbosch

Re: Arduino besturing voor animatronic op menselijke grootte

Berichtdoor shooter » 30 Aug 2014, 23:29

ach ik was toch bezig dus voor jou ook maar wat gemaakt.
cpp code
// anima.ino
/* program to run the robot with 13 motors
written paul deelen
*/

//declaration
int const maxsteps = 6 ; // number of steps to evaluate in sequence
int const maxmotors = 13 ; // number of motors
int SequenceStep; // which step is active
unsigned long stepstarttime ; // starttime of step
unsigned long StepTime ; // time of step
unsigned long actualtime ; // time from actual taken once every loop
byte motorspeed;
unsigned long elapsetime;
unsigned long runtime;
unsigned long oldactualtime ;
float part;
float one=1;


// structure of motorpins
typedef struct
{
int SpeedPin ;
int Dir1Pin ;
int Dir2Pin ;
int SensorPin ;
}
structmotor ;
structmotor MotorPins[maxmotors]; //array with pins of motors
/* explanation
the array motorpins has 2 dimensions 1 for the motornumber and the other with
the pinnumbers on the arduino Mega
calling is by MotorPins[motornumber].pinname
*/
// structure of sequence
typedef struct //defining structure for the sequence
{
unsigned long nextsteptime;
int number;
int mode;
byte speed;
unsigned long time;
}
structseq;
structseq sequence[maxsteps]; // making an array of this structure for starter it is 20 steps

// structure of motormode
typedef struct // defining structure for motormode
{
int mode ; // mode type of motor
boolean Dir1 ; // direction bit
boolean Dir2 ;
byte startspeed ; // motorspeed at beginning of sequence
byte endspeed ; // desired motorspeed at end of sequence
unsigned long starttime ; // when is this sequence line started
unsigned long endtime ; // how long is this mode active
unsigned long runtime ; // what time is already done since start of sequence line start
byte actualspeed ; // motorspeed
}
structmode;
structmode motorvalue[maxmotors]; // array of motorvalues

// for simulator the functions need to go on top, they have to be defined before called.

// motor is reset to sensor is active
void functionreset(int _motornumber)
{
if (_motornumber == 0 ) // if number = 0 then all motors are affected (for setting up or emergencystop)
{
for (int counter = 1 ; counter <= maxmotors; counter ++){
boolean delayset ;
while (digitalRead(MotorPins[counter].SensorPin) == HIGH ) // wait until sensor is active
{
digitalWrite (MotorPins[counter].Dir1Pin,HIGH); // direction right
digitalWrite (MotorPins[counter].Dir2Pin,LOW);
analogWrite (MotorPins[counter].SpeedPin,255); // full speed
delayset = true ;
}
// sensor is low so next step
digitalWrite (MotorPins[counter].Dir1Pin,HIGH);
digitalWrite (MotorPins[counter].Dir2Pin,HIGH);
analogWrite (MotorPins[counter].SpeedPin,255); // full break
if (delayset == true ) // if motor was running wait until motor is stopped.
{
delay (250); // wait for motor to stop
delayset= false;
}
Serial.println (counter);
}
}
else{ // reset only one motor
boolean delayset ;
while (digitalRead(MotorPins[_motornumber].SensorPin) == LOW ){
digitalWrite (MotorPins[_motornumber].Dir1Pin,HIGH);
digitalWrite (MotorPins[_motornumber].Dir2Pin,LOW);
analogWrite (MotorPins[_motornumber].SpeedPin,255);
delayset = true ;
}

digitalWrite (MotorPins[_motornumber].Dir1Pin,HIGH);
digitalWrite (MotorPins[_motornumber].Dir2Pin,HIGH);
analogWrite (MotorPins[_motornumber].SpeedPin,255);
if (delayset == true ){
delay (250);
delayset= false;
}


}

}
// function to read step from sequence
void functionModeMotor(int _motornumber,int _motormode,byte _motorspeed,unsigned long _motortime)
{
boolean Dir1 ;
boolean Dir2 ;

switch (_motormode) {
case 0: // stop
Dir1 = LOW ;
Dir2 = LOW ;
break;
case 1: // CW speed constant
Dir1 = HIGH ;
Dir2 = LOW ;
break;
case 2: // CCW speed constant
Dir1 = LOW ;
Dir2 = HIGH ;
break;
case 3: // Active break
Dir1 = HIGH ;
Dir2 = HIGH ;
break;
case 5: //ascending speed
Dir1 = HIGH ;
Dir2 = LOW ;
break;
case 6: // descending speed
Dir1 = LOW ;
Dir2 = HIGH ;
break;
case 99:
functionreset (_motornumber);
break;
} //end of case motormode

if (_motornumber == 0 ) // if number = 0 then all motors are affected (for setting up or emergencystop)
{
for (int counter = 1; counter <= maxmotors; counter ++){

digitalWrite (MotorPins[counter].Dir1Pin,Dir1);
digitalWrite (MotorPins[counter].Dir2Pin,Dir2);
motorvalue[counter].endspeed = _motorspeed;
motorvalue[counter].mode = _motormode;
motorvalue[counter].startspeed = motorvalue[counter].actualspeed;
motorvalue[counter].Dir1 = boolean(Dir1);
motorvalue[counter].Dir2 = boolean(Dir2);
motorvalue[counter].mode = _motormode;
motorvalue[counter].starttime = actualtime;
motorvalue[counter].runtime = _motortime;
motorvalue[counter].endtime = _motortime+actualtime;
}
}
else{
digitalWrite (MotorPins[_motornumber].Dir1Pin,Dir1);
digitalWrite (MotorPins[_motornumber].Dir2Pin,Dir2);
motorvalue[_motornumber].endspeed = _motorspeed;
motorvalue[_motornumber].mode = _motormode;
motorvalue[_motornumber].startspeed = motorvalue[_motornumber].actualspeed;
motorvalue[_motornumber].Dir1 = boolean(Dir1);
motorvalue[_motornumber].Dir2 = boolean (Dir2);
motorvalue[_motornumber].mode = _motormode;
motorvalue[_motornumber].starttime = actualtime;
motorvalue[_motornumber].runtime = _motortime;
motorvalue[_motornumber].endtime = _motortime+actualtime;
}

Serial.print ("Step ");
Serial.print (SequenceStep);
Serial.print (" motor ");
Serial.print (_motornumber);
Serial.print (" motormode ");
Serial.print (_motormode);
Serial.print (" motorspeed ");
Serial.print (_motorspeed);
Serial.print (" motortime ");
Serial.print (_motortime);
Serial.println () ;


} // end of function motormode

void printstatus (int _motornumber){
Serial.print (" motor ");
Serial.print (_motornumber);
Serial.print (" mode ");
Serial.print (motorvalue[_motornumber].mode);
Serial.print (" dir1 ");
Serial.print (motorvalue[_motornumber].Dir1);
Serial.print (" dir2 ");
Serial.print (motorvalue[_motornumber].Dir2);
Serial.print (" speed ");
Serial.print (motorvalue[_motornumber].actualspeed);
Serial.print (" start ");
Serial.print (motorvalue[_motornumber].startspeed);
Serial.print (" end ");
Serial.print (motorvalue[_motornumber].endspeed);
Serial.print (" starttime ");
Serial.print (motorvalue[_motornumber].starttime);
Serial.print (" endtime ");
Serial.print (motorvalue[_motornumber].endtime);
Serial.print (" runtime ");
Serial.print (motorvalue[_motornumber].runtime);
Serial.print (" actual ");
Serial.print (actualtime);
Serial.println ();

}
void functionspeed()
{
for (int counter=1 ; counter <= maxmotors ; counter ++)
{
switch (motorvalue[counter].mode){
//case 0 :
case 1 :
case 2 :
case 3 :

if (actualtime > motorvalue[counter].endtime) // timelimit of motor so stop it
{
motorspeed=0;
}
else{
motorspeed=motorvalue[counter].endspeed;
}
break;
case 5 :
case 6 :

if (actualtime > motorvalue[counter].endtime) // timelimit of motor so stop it
{
motorspeed=0;
}
else{ // change speed according to time
elapsetime = (actualtime-motorvalue[counter].starttime);
runtime = (motorvalue[counter].runtime);
part = float(elapsetime)/ float(runtime);
motorspeed = byte(float(((one-part)*float(motorvalue[counter].startspeed))+float((part*motorvalue[counter].endspeed))));

}
break;
} //end of switch case

if (motorvalue[counter].actualspeed != motorspeed){ //update only if different
if (counter != 13 ){
analogWrite(MotorPins[counter].SpeedPin,motorspeed);
}
motorvalue[counter].actualspeed = byte(motorspeed);
}
}

}

void stepup(){
SequenceStep=SequenceStep+1; // stepnumber is increased
if (SequenceStep > maxsteps) // if max number of steps is found reset sequencer
{
SequenceStep=0;
Serial.println ("going to step 0 ");
delay (10000);
}
stepstarttime=actualtime;
StepTime = (sequence[SequenceStep].nextsteptime);
functionModeMotor(sequence[SequenceStep].number,sequence[SequenceStep].mode,sequence[SequenceStep].speed,sequence[SequenceStep].time);



}

void setup() // this is done once
{
Serial.begin(115200); // making communications to PC at 9600 baud

// Motor 01 (heupen bukken)
MotorPins[1].SpeedPin = 2 ; //speed pin
MotorPins[1].Dir1Pin = 22 ; // direction CW rechtsom
MotorPins[1].Dir2Pin = 23 ; // direction CCW linksom
MotorPins[1].SensorPin = A1 ; // sensor analog input

// Motor 02 (heupen draaien)
MotorPins[2].SpeedPin = 3 ; //speed pin
MotorPins[2].Dir1Pin = 24 ; // direction CW rechtsom
MotorPins[2].Dir2Pin = 25 ; // direction CCW linksom
MotorPins[2].SensorPin = A2 ; // sensor analog input

// Motor 03 (linkerarm 1)
MotorPins[3].SpeedPin = 4 ; //speed pin
MotorPins[3].Dir1Pin = 26 ; // direction CW rechtsom
MotorPins[3].Dir2Pin = 27 ; // direction CCW linksom
MotorPins[3].SensorPin = A3 ; // sensor analog input

// Motor 04 (linkerarm 2)
MotorPins[4].SpeedPin = 5 ; //speed pin
MotorPins[4].Dir1Pin = 28 ; // direction CW rechtsom
MotorPins[4].Dir2Pin = 29 ; // direction CCW linksom
MotorPins[4].SensorPin = A4 ; // sensor analog input

// Motor 05 (linkerarm 3)
MotorPins[5].SpeedPin = 6 ; //speed pin
MotorPins[5].Dir1Pin = 30 ; // direction CW rechtsom
MotorPins[5].Dir2Pin = 31 ; // direction CCW linksom
MotorPins[5].SensorPin = A5 ; // sensor analog input

// Motor 06 (linkerarm 4)
MotorPins[6].SpeedPin = 7 ; //speed pin
MotorPins[6].Dir1Pin = 32 ; // direction CW rechtsom
MotorPins[6].Dir2Pin = 33 ; // direction CCW linksom
MotorPins[6].SensorPin = A6 ; // sensor analog input

// Motor 07 (rechterarm 1)
MotorPins[7].SpeedPin = 8 ; //speed pin
MotorPins[7].Dir1Pin = 34 ; // direction CW rechtsom
MotorPins[7].Dir2Pin = 35 ; // direction CCW linksom
MotorPins[7].SensorPin = A7 ; // sensor analog input

// Motor 08 (rechterarm 2)
MotorPins[8].SpeedPin = 9 ; //speed pin
MotorPins[8].Dir1Pin = 36 ; // direction CW rechtsom
MotorPins[8].Dir2Pin = 37 ; // direction CCW linksom
MotorPins[8].SensorPin = A8 ; // sensor analog input

// Motor 09 (rechterarm 3)
MotorPins[9].SpeedPin = 10 ; //speed pin
MotorPins[9].Dir1Pin = 38 ; // direction CW rechtsom
MotorPins[9].Dir2Pin = 39 ; // direction CCW linksom
MotorPins[9].SensorPin = A9 ; // sensor analog input

// Motor 10 (rechterarm 4)
MotorPins[10].SpeedPin = 11 ; //speed pin
MotorPins[10].Dir1Pin = 40 ; // direction CW rechtsom
MotorPins[10].Dir2Pin = 41 ; // direction CCW linksom
MotorPins[10].SensorPin = A10 ; // sensor analog input

// Motor 11 (hoofd knikken)
MotorPins[11].SpeedPin = 12 ; //speed pin
MotorPins[11].Dir1Pin = 48 ; // direction CW rechtsom
MotorPins[11].Dir2Pin = 49 ; // direction CCW linksom
MotorPins[11].SensorPin = A11 ; // sensor analog input

// Motor 12 (hoofd draaien)
MotorPins[12].SpeedPin = 13 ; //speed pin
MotorPins[12].Dir1Pin = 50 ; // direction CW rechtsom
MotorPins[12].Dir2Pin = 51 ; // direction CCW linksom
MotorPins[12].SensorPin = A12 ; // sensor analog input

// Motor 13 (vleugels)
MotorPins[13].SpeedPin = 44 ; //speed pin
MotorPins[13].Dir1Pin = 52 ; // direction CW rechtsom
MotorPins[13].Dir2Pin = 53 ; // direction CCW linksom
MotorPins[13].SensorPin = A13 ; // sensor analog input

// setting of pins from above array
for (int counter = 1;counter <= maxmotors;counter++){
pinMode (MotorPins[counter].SpeedPin, OUTPUT);
pinMode (MotorPins[counter].Dir1Pin, OUTPUT);
pinMode (MotorPins[counter].Dir2Pin, OUTPUT);
pinMode (MotorPins[counter].SensorPin, INPUT_PULLUP);
}
Serial.println ("pinmode done");

// here each step is set
/* nextsteptime is the time in milliseconds, before the next step is activated
motornumber is the motor that is changed in mode or speed or duration.
if motornumber = 0 then all motors are affected (like in general stop mode=0 or in reset mode = 99)

motormode the mode a motor is going to:
mode 0: normal stop
mode 1: normal right turn CW
mode 2: normal left turn CCW
mode 3: breaking stop
mode 4: not used (bit 2 for acceleration)
mode 5: accelarate right from actualspeed to motorspeed in motortime
mode 6: accelarate left from actualspeed to motorspeed in motortime
mode 7: not used
mode 8: not used (bit 3 for deceleration)
mode 9: decelerate right from actualspeed to motorspeed in motortime
mode 10: decelerate left from actual speed to motorspeed in motortime

motorspeed wanted speed

motortime the time used for this motion ( so you start a motion and do not have to stop it in the sequence)
the time to be used when accelarate or decelarate
*/
sequence[0].nextsteptime = 1000 ;
sequence[0].number = 0 ;
sequence[0].mode = 0 ;
sequence[0].speed = 0 ;
sequence[0].time = 1000 ;
sequence[1].nextsteptime = 20000 ;
sequence[1].number = 12 ;
sequence[1].mode = 5 ;
sequence[1].speed = 10 ;
sequence[1].time = 10000 ;
sequence[2].nextsteptime = 5000 ;
sequence[2].number = 12 ;
sequence[2].mode = 5 ;
sequence[2].speed = 50 ;
sequence[2].time = 10000 ;
sequence[3].nextsteptime = 20000 ;
sequence[3].number = 12 ;
sequence[3].mode = 5 ;
sequence[3].speed = 0 ;
sequence[3].time = 10000 ;
sequence[4].nextsteptime = 20000 ;
sequence[4].number = 12 ;
sequence[4].mode = 5 ;
sequence[4].speed = 250 ;
sequence[4].time = 2000 ;
sequence[5].nextsteptime = 10000 ;
sequence[5].number = 12 ;
sequence[5].mode = 5 ;
sequence[5].speed = 100 ;
sequence[5].time = 1000 ;
sequence[6].nextsteptime = 10000 ;
sequence[6].number = 12 ;
sequence[6].mode = 5 ;
sequence[6].speed = 50 ;
sequence[6].time = 1000 ;

actualtime= millis();
stepstarttime = actualtime;


} // end setup

void loop() // this is the loop
{
actualtime = millis(); //use this time for the entire loop
if (oldactualtime != actualtime){ // only run when time is changed > 1 millisecond
functionspeed(); // check speeds and achange if needed
oldactualtime = actualtime ;
}
if ((actualtime-stepstarttime) >= StepTime) // if steptime is expired
{
stepup();
}
}
paul deelen
shooter@home.nl

Terug naar Gezamenlijke projecten

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers en 13 gasten