please help
Moderators: adafruit_support_bill, adafruit

Re: please help

by djdc23 on Thu May 30, 2013 10:22 am

Thanks again and I will post pics very soon and then when its completed.
djdc23
 
Posts: 37
Joined: Tue May 28, 2013 4:07 pm

Re: please help

by djdc23 on Thu May 30, 2013 11:33 am

Pics as requested

Thanks Again for all your help!
Attachments
IMG_1297s.jpg
A close up of the mouth operated by a Arduino Uno and a waveshield
IMG_1297s.jpg (159.03 KiB) Viewed 640 times
IMG_1296s.jpg
The head next to the now working moving mouth
IMG_1296s.jpg (170.94 KiB) Viewed 640 times
IMG_1114s.jpg
Heres the complete body and head excluding the moving mouth
IMG_1114s.jpg (156.41 KiB) Viewed 640 times
djdc23
 
Posts: 37
Joined: Tue May 28, 2013 4:07 pm

Re: please help

by adafruit_support_bill on Thu May 30, 2013 11:40 am

Thanks for the photos! This looks like one for the blog :D
User avatar
adafruit_support_bill
 
Posts: 29218
Joined: Sat Feb 07, 2009 9:11 am

Re: please help

by djdc23 on Thu May 30, 2013 11:46 am

Kool I'm glad you like. It's being made for a Halloween party im having in October

heres one more with me holding the mouth in position

IMG_1299s.jpg
IMG_1299s.jpg (163.58 KiB) Viewed 635 times
djdc23
 
Posts: 37
Joined: Tue May 28, 2013 4:07 pm

Re: please help

by djdc23 on Sat Jun 08, 2013 9:15 am

Hi All, Thanks for everyones help so far I've now painted the head and mounted the mouth But the problem is now the mouth moves too far out.

IMG_1476s.jpg
IMG_1476s.jpg (167.93 KiB) Viewed 590 times


Ive tried adjusting the settings but then the move doesnt close please help again lol.

Code: Select all | TOGGLE FULL SIZE
//////////////////////////////////////////////////////////////////// libraries
    #include <FatReader.h>
    #include <SdReader.h>
    #include <avr/pgmspace.h>
    #include <WaveHC.h>
    #include <WaveUtil.h>
    ///////////////////////////////////////////////////////// constant pins, values

    #define swPin 14


    SdReader card;    // This object holds the information for the card
    FatVolume vol;    // This holds the information for the partition on the card
    FatReader root;   // This holds the information for the filesystem on the card
    FatReader f;      // This holds the information for the file we're play

    WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

    // this handy function will return the number of bytes currently free in RAM, great for debugging!   
    int freeRam(void)
    {
       extern int  __bss_end;
       extern int  *__brkval;
       int free_memory;
       if((int)__brkval == 0) {
          free_memory = ((int)&free_memory) - ((int)&__bss_end);
       }
       else {
          free_memory = ((int)&free_memory) - ((int)__brkval);
       }
       return free_memory;
    }

    void sdErrorCheck(void)
    {
       if (!card.errorCode()) return;
       putstring("\n\rSD I/O error: ");
       Serial.print(card.errorCode(), HEX);
       putstring(", ");
       Serial.println(card.errorData(), HEX);
       while(1);
    }

    ///////////////////////////////////////////////////////////////////////////////////////////

    int inputPin = 8;               // choose the input pin (for PIR sensor)
    int servoPin = 16;              // choose the input pin (for Servo)
    int pirState = LOW;             // we start, assuming no motion detected
    int val = 0;                    // variable for reading the pin status for motion sensor
    int minPulse     =  600;  // minimum servo position
    int maxPulse     =  1800; // maximum servo position
    int turnRate     =  1800;  // servo turn rate increment (larger value, faster rate)
    int refreshTime  =  20;   // time (ms) between pulses (50Hz)
    int mouthchange = 6;  //checks to see if mouth position needs to be changed





    /** The Arduino will calculate these values for you **/
    int centerServo;         // center servo position
    int pulseWidth;          // servo pulse width
    long lastPulse   = 0;    // recorded time (ms) of the last pulse

    /////////////////////////////////////////////////////////////////////////// setup

    void setup() {

       pinMode(inputPin, INPUT);     // declare sensor as input for PIR

       // set up servo pin
       pinMode(servoPin, OUTPUT);  // Set servo pin 18 (analog 4) as an output pin
       centerServo = maxPulse - ((maxPulse - minPulse)/2);
       pulseWidth = centerServo;   // Give the servo a starting point (or it floats)

       // set up serial port
       Serial.begin(9600);


       putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
       Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!

       // Set the output pins for the DAC control. This pins are defined in the library
       pinMode(2, OUTPUT);
       pinMode(3, OUTPUT);
       pinMode(4, OUTPUT);
       pinMode(5, OUTPUT);

       //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
       if (!card.init()) {         //play with 8 MHz spi (default faster!)
          putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
          sdErrorCheck();
          while(1);                            // then 'halt' - do nothing!
       }

       // enable optimize read - some cards may timeout. Disable if you're having problems
       card.partialBlockRead(true);

       // Now we will look for a FAT partition!
       uint8_t part;
       for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
          if (vol.init(card, part))
             break;                             // we found one, lets bail
       }
       if (part == 5) {                       // if we ended up not finding one  :(
          putstring_nl("No valid FAT partition!");
          sdErrorCheck();      // Something went wrong, lets print out why
          while(1);                            // then 'halt' - do nothing!
       }

       // Lets tell the user about what we found
       putstring("Using partition ");
       Serial.print(part, DEC);
       putstring(", type is FAT");
       Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?

       // Try to open the root directory
       if (!root.openRoot(vol)) {
          putstring_nl("Can't open root dir!"); // Something went wrong,
          while(1);                             // then 'halt' - do nothing!
       }

       // Whew! We got past the tough parts.
       putstring_nl("Ready!");

    }

    //////////////////////////////////////////////////////////// loop
    void loop() {

       val = digitalRead(inputPin);  // read input value

       if (val == HIGH)          // check if the input is LOW
       {
          if (pirState == LOW)
          {
             Serial.println("Motion Detected!");
             playcomplete("PUPPET~2.WAV");
             playcomplete("PUPPET~2.WAV");

             pirState = HIGH;

          }
       }

       else
       {
          if (pirState == HIGH)
              delay(50000);
          {

             Serial.println("Motion ended!");
             
             pirState = LOW;

          }
       }
    }


    // Plays a full file from beginning to end with no pause.

    void playcomplete(char *name)
    {
       char i;
       uint8_t volume;
       int v2;

       playfile(name);

       while (wave.isplaying)
       {
          volume = 0;
          v2 = 0;

          for (int i = 0; i < 80; i++)
          {
             v2 = max(v2, analogRead(1));
          }

          if (true)
          {
             for(int pos = 0; pos < 50; pos += 1)  // goes from 0 degrees to 50 degrees
             {                                  // in steps of 1 degree
                servoPulse(servoPin, pos);                // tell servo to go to position in variable 'pos'
                delay(2);                       // wait 20 ms for pulse period
             }
             for(int pos = 30; pos>=1; pos-=1)     // goes from 50 degrees to 0 degrees
             {                               
                servoPulse(servoPin, pos);      // tell servo to go to position in variable 'pos'
                delay(3);                       // wait 20 ms for pulse period
             }
          }
       }
    }

    // generate a servo pulse - converts degrees to microseconds
    void servoPulse(int pin, int deg)
    {
       int pulseWidth = map(deg, 0, 180, 1000, 2000);

       digitalWrite(pin, HIGH);   // start the pulse
       delayMicroseconds(pulseWidth);  // pulse width
       digitalWrite(pin, LOW);    // stop the pulse
    }


    void playfile(char *name)
    {
       //////// stop any file already playing//////////////////////////
       if (wave.isplaying) {// already playing something, so stop it!
          wave.stop(); // stop it
       }
       // look in the root directory and open the file
       if (!f.open(root, name)) {
          putstring("Couldn't open file ");
          Serial.print(name);
          return;
       }
       // OK read the file and turn it into a wave object
       if (!wave.create(f)) {
          putstring_nl("Not a valid WAV");
          return;
       }

       // ok time to play! start playback
       wave.play();
    }
djdc23
 
Posts: 37
Joined: Tue May 28, 2013 4:07 pm

Re: please help

by CircuitBurner on Sat Jun 08, 2013 10:36 am

Code: Select all | TOGGLE FULL SIZE
int minPulse     =  600;  // minimum servo position
    int maxPulse     =  1800; // maximum servo position



heres the very 1st parameter you need to work out.
plus any animatronic stops or moves you may have in store for it need to have their points figured out within these two settings.
My bot has camera gimbal swing, but needed to idle in a central position.
So the easy way was two 45 degree arc segments, and two separate commands like this ---
Code: Select all | TOGGLE FULL SIZE
  void lookleft()
 { servo1.write(1);
 delay(8000);      // head return after pause
     servo1.write(90);
              tone (200,1020,500);
 }
 
 void lookright()
 { servo1.write(180);
 delay(8000);      // head return after pause
     servo1.write(90);
                 tone(200,1320,500);   
 }
AMSAT terrestrial loc - (grid square) EM-12

wings are for fairies, and runways are for fashion models!
User avatar
CircuitBurner
 
Posts: 21
Joined: Mon Apr 15, 2013 1:18 am
Location: grand prairie, texas

Re: please help

by djdc23 on Sat Jun 08, 2013 10:45 am

Thanks for the reply but i didnt quite understand what you meant sorry.

Was you saying that I should change the minimum and maximum servo positions?

Thanks
djdc23
 
Posts: 37
Joined: Tue May 28, 2013 4:07 pm

Re: please help

by djdc23 on Sat Jun 08, 2013 10:53 am

if it helps i have been working on just mouth movement but cant work out how to add it on my sketch as it uses a servo library :(

Code: Select all | TOGGLE FULL SIZE
void loop() {

  if(digitalRead(pirPin) == HIGH){

    for(pos = 0; pos < 60; pos += 1)  // goes from 0 degrees to 90 degrees
    {                                  // in steps of 1 degree
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(4);                       // waits 4ms for the servo to reach the position
    }
    for(pos = 60; pos>=1; pos-=1)     // goes from 90 degrees to 0 degrees
    {                               
      myservo.write(pos);              // tell servo to go to position in variable 'pos'
      delay(4);                       // waits 4ms for the servo to reach the position
    }
    if(lockLow){

      lockLow = false;           
      Serial.println("---");
      Serial.print("motion detected at ");
      Serial.print(millis()/1000);
      Serial.println(" sec");
      delay(50);
    }       
    takeLowTime = true;
  }

  if(digitalRead(pirPin) == LOW){     

    if(takeLowTime){
      lowIn = millis();
      takeLowTime = false;
    }

    if(!lockLow && millis() - lowIn > pause){

      lockLow = true;                       
      Serial.print("motion ended at ");
      Serial.print((millis() - pause)/1000);
      Serial.println(" sec");
      delay(50);
    }
  }
}
djdc23
 
Posts: 37
Joined: Tue May 28, 2013 4:07 pm

Re: please help

by CircuitBurner on Sat Jun 08, 2013 11:21 am

yea, the endpoints is your solution. tweek the minimums and max, and then if needed, split your servo command in two like I showed.-with the common center rest being the shared location at one extreme of a servo arc.
AMSAT terrestrial loc - (grid square) EM-12

wings are for fairies, and runways are for fashion models!
User avatar
CircuitBurner
 
Posts: 21
Joined: Mon Apr 15, 2013 1:18 am
Location: grand prairie, texas

Re: please help

by djdc23 on Sat Jun 08, 2013 11:30 am

Thanks for the reply I have tweaked my min and max but didnt seem to make a difference :(

even if i change the degree of angles it doesnt move. And i understand what you mean with another command but i dont think i need that as the sketch works fine apart from servo moving to far
djdc23
 
Posts: 37
Joined: Tue May 28, 2013 4:07 pm

Re: please help

by CircuitBurner on Sat Jun 08, 2013 3:44 pm

i will take your program and load it with a standard servo on an uno or a 2560 to see if I can tweek it a bit for you.
What servos you trying to use?
I hope you dont say "360 degree cont rotation servo.... cause There might be a reason why its going too far, lol
AMSAT terrestrial loc - (grid square) EM-12

wings are for fairies, and runways are for fashion models!
User avatar
CircuitBurner
 
Posts: 21
Joined: Mon Apr 15, 2013 1:18 am
Location: grand prairie, texas

Re: please help

by djdc23 on Sat Jun 08, 2013 5:58 pm

Hi I appreciate that very much. Im using just a standard servo thats what its called anyway lol. A arduino uno r3 and it doesnt need to move far at all about roughly 50 or 40 degrees.

Thanks
djdc23
 
Posts: 37
Joined: Tue May 28, 2013 4:07 pm

Re: please help

by CircuitBurner on Sun Jun 09, 2013 7:08 am

ok kewl,
also, the simplest method to determine throws on servo linkages is by choosing the length of the servo horn to suit mechanical requirements.
The closer to the center servo axis you position your link, the less or shorter your resulting servo throw will be. Need longer throws, you would use longer horn, or move further down the horn you already have, since most have multiple holes already. If you need less throw, find or drill a hole closer to the servo axis to position you link from.

I didnt get a chance to load that sketch, will get to that part today.
AMSAT terrestrial loc - (grid square) EM-12

wings are for fairies, and runways are for fashion models!
User avatar
CircuitBurner
 
Posts: 21
Joined: Mon Apr 15, 2013 1:18 am
Location: grand prairie, texas

Re: please help

by djdc23 on Sun Jun 09, 2013 9:46 am

Ok thanks for the reply yeah it might be an idea to try that. I know why its off now because when i mounted in the head it has to sit with a tilt forward to fit in the head, This throws off the angle and makes it stick out further. :(
djdc23
 
Posts: 37
Joined: Tue May 28, 2013 4:07 pm

Re: please help

by djdc23 on Sun Jun 09, 2013 2:35 pm

Please could anyone explain how this code works perfect and then sometimes the servo would stick and not move?

Thanks heres the code im using

Code: Select all | TOGGLE FULL SIZE
//////////////////////////////////////////////////////////////////// libraries
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include <WaveHC.h>
#include <WaveUtil.h>
///////////////////////////////////////////////////////// constant pins, values

#define swPin 14


SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

// this handy function will return the number of bytes currently free in RAM, great for debugging!   
int freeRam(void)
{
  extern int  __bss_end;
  extern int  *__brkval;
  int free_memory;
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  }
  else {
    free_memory = ((int)&free_memory) - ((int)__brkval);
  }
  return free_memory;
}

void sdErrorCheck(void)
{
  if (!card.errorCode()) return;
  putstring("\n\rSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  putstring(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

///////////////////////////////////////////////////////////////////////////////////////////

int inputPin = 8;               // choose the input pin (for PIR sensor)
int servoPin = 16;              // choose the input pin (for Servo)
int pirState = LOW;             // we start, assuming no motion detected
int val = 0;                    // variable for reading the pin status for motion sensor
int minPulse     =  600;  // minimum servo position
int maxPulse     =  800; // maximum servo position
int turnRate     =  800;  // servo turn rate increment (larger value, faster rate)
int refreshTime  =  10;   // time (ms) between pulses (50Hz)
int mouthchange = 6;  //checks to see if mouth position needs to be changed



/** The Arduino will calculate these values for you **/
int centerServo;         // center servo position
int pulseWidth;          // servo pulse width
long lastPulse   = 0;    // recorded time (ms) of the last pulse

/////////////////////////////////////////////////////////////////////////// setup

void setup() {

  pinMode(inputPin, INPUT);     // declare sensor as input for PIR
 
  digitalWrite(inputPin, HIGH);

  // set up servo pin
  pinMode(servoPin, OUTPUT);  // Set servo pin 18 (analog 4) as an output pin
  centerServo = maxPulse - ((maxPulse - minPulse)/2);
  pulseWidth = centerServo;   // Give the servo a starting point (or it floats)

  // set up serial port
  Serial.begin(9600);


  putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!

  // Set the output pins for the DAC control. This pins are defined in the library
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!) 
    putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
    sdErrorCheck();
    while(1);                            // then 'halt' - do nothing!
  }

  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);

  // Now we will look for a FAT partition!
  uint8_t part;
  for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
    if (vol.init(card, part))
      break;                             // we found one, lets bail
  }
  if (part == 5) {                       // if we ended up not finding one  :(
    putstring_nl("No valid FAT partition!");
    sdErrorCheck();      // Something went wrong, lets print out why
    while(1);                            // then 'halt' - do nothing!
  }

  // Lets tell the user about what we found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?

  // Try to open the root directory
  if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
  }

  // Whew! We got past the tough parts.
  putstring_nl("Ready!");

}

//////////////////////////////////////////////////////////// loop
void loop() {

  val = digitalRead(inputPin);  // read input value

  if (val == HIGH)          // check if the input is LOW
  {
    if (pirState == LOW)
    {
      Serial.println("Motion Detected!");
      playcomplete("PUPPET~2.WAV");
      playcomplete("PUPPET~2.WAV");
     
      pirState = HIGH;

          }
       }

       else
       {
          if (pirState == HIGH)
              delay(50000);
          {

             Serial.println("Motion ended!");
             
             pirState = LOW;

          }
       }
    }
     
 

// Plays a full file from beginning to end with no pause.

void playcomplete(char *name) {
  char i;
  uint8_t volume;
  int v2;

  playfile(name);

  while (wave.isplaying)
  {
    volume = 0;
    for (i=0; i<40; i++)
    {
      v2 = analogRead(1);
      delay(1);
    }
    if (v2 > 440)
    { 
      pulseWidth = 1200;
      mouthchange = 1;
    }
    else
    {
      pulseWidth = 600;
      mouthchange = 1;
    }
    digitalWrite(servoPin, HIGH);   // start the pulse
    delayMicroseconds(pulseWidth);  // pulse width
    digitalWrite(servoPin, LOW);    // stop the pulse
  }
}


void playfile(char *name)
{
  //////// stop any file already playing//////////////////////////
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file ");
    Serial.print(name);
    return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV");
    return;
  }

  // ok time to play! start playback
  wave.play();
}
djdc23
 
Posts: 37
Joined: Tue May 28, 2013 4:07 pm