Thursday, March 15, 2012

Servo Control and Multiplexing

I've been thinking more and more about Servo control, PWM and multiplexing. As I need at least 14 servos for the project, the Fio only has 12 digital out pins, and only 6 of those are PWM pins. My first instinct was to buy a couple of 4051 mux/demux chips, drive them from dI/O pins and feed the signal from one of the PWM pins. While I still think this is a good idea, I think I now have one that won't require any hardware modification.

From what I've read a Servo needs to receive a signal every 20ms. During that 20ms if it receives a burst of about 1ms it will go to position 0, if it receives a burst of 2ms it will go to 180. Apparently this is depended on the exact specifications of the Servo, unfortunately I haven't found a specsheet for the DFRobot SER0006. I have found however that the default settings in the Servo library from Arduino seem to suffice. They are set to 544us = 0, 1500us = 90, 2400 us = 180. note: us = microseconds

Now, with a max required burst time of 2400us, and a required repeat time of 20000us. It's obvious that we can get 20000/2400 = 8.33 ~= 8 signals out per cycle. The Arduino Fio has an ATmega328P which has 3 timers on it, only one of which is a 16 bit timer (timer1). 16 bit is preferable because it means that we can address more angles.  Each timer on the controller has 2 comparators (2 outputs) which means that in a given 20ms span we can get 2*8 = 16 outputs.

The other major part of this puzzle is the number of pins we have accessible, luckily the Arduino documentation states that
While the main function of the analog pins for most Arduino users is to read analog sensors, the analog pins also have all the functionality of general purpose input/output (GPIO) pins (the same as digital pins 0 - 13).  Consequently, if a user needs more general purpose input output pins, and all the analog pins are not in use, the analog pins may be used for GPIO.
We can therefore use all a grand total of 20 pins.  With 16 PWM timer outputs per cycle we could theoretically have enough outs to control all the servos I need.

The Servo Library only accounts for up to 12 servos.  So I will need to either modify it or write a new one entirely.  I'm thinking the second is more likely as I want to add in collision avoidance and better limits.

Reference:  A good article about Arduino PWM

Tuesday, March 13, 2012

Leg Collisions


To prevent leg collisions I will be implementing this check.  If you assume that the top leg wants to swing down, then we need to find theta 1 which is the maximum allowable angle before a collision occurs.


Sunday, March 11, 2012

Android test

Managed a fair bit yesterday, got most of the major code done on the Android app.  Here's a demo video of it connecting to the Arduino and controlling it.



There's still quite a bit to do of course, namely the following:


Arduino:
  • Normalize input between 0-180 for set limits.
  • Associate related Servos and set relation limits so that they can't cross.
  • Make sure that the servos don't move outside their limits on startup.
  • Write a Servo library for multiplexed servos.

Android:

  • Crashes if move before bluetooth
  • Preset movements
  • Read back from the servos in case of dissallowed movements
  • Read in from servos to map legs when walking.
  • Leg animations

Physical:

  • Build Styrofoam model of legs and body
  • Figure out servo layout.

Electrical:

  • 5v power supply for servos.
  • Charging for servo power supply.
  • 4051 multiplexers

Friday, March 9, 2012

Micro Quadcopters

After watching the following video today I think once I'm done this walker bot I'll take on the challenge of doing a micro quadcopter.


The only things I think I'd like to add is possibly a cell phone camera with a 360 degree lense.  Heck, with one on the top and one on the bottom you could technically do 360 stereoscopic vision.  Would be amazing little bots for mapping.

Android Arduino communication

I've managed to get my Android phone (Galaxy Nexus) and the arduino fio communicating over bluetooth.  There were a couple of things to watch out for however,

  1. When programming the Bluetooh Bee you have to use a baud rate of 38400.  When it's in normal mode it will use whatever baud rate you have set via AT+BAUD.
  2. Some android devices can't see Bluetooth devices that have a device class of 0 (which is the bluetooth bee default).  I'd suggest setting the device class, in my case the command looks like: "AT+CLASS=0x8C080C\r\n".  You can generate a device class numbers from this CoD Generator
  3. For some reason my phone would not create a valid socket to the device using the standard createRfcommSocket.  After searching around a bit I found this tread, changing this code made it work.
  4. Silly note, but:  you have to pair your phone with the device.  It is necessary to go to the bluetooth menu in the settings on the Android device, select the Arduino device (in my case called "DefilerBot"), and enter the pin.  The pin by default is "1234" but can be changed with the "AT+PSWD=1122" command.
// Change
tmp = device.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
// To
Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
tmp = (BluetoothSocket) m.invoke(device, 1);

The base code for the Bluetooth connection and messaging came from the Android Bluetooth chat example.

My Bluetooth Bee Arduino config program now looks like this.

void setup(){
  Serial.begin(38400);
  Serial.write("AT+UART=57600,0,0\r\n");
  checkResponse();
  Serial.write("AT+CLASS=0x8C080C\r\n");
  checkResponse();
  Serial.write("AT+ROLE=0\r\n");
  checkResponse();
  Serial.write("AT+NAME=DefilerBot\r\n");
  checkResponse();
}

void checkResponse(){
  delay(500);
  String inputString = "";
  if(!Serial.available())
  {
     digitalWrite(13, HIGH);
     delay(1000);
     digitalWrite(13, LOW);
  }
  while (Serial.available()){
    char inChar = (char)Serial.read(); 
    inputString += inChar;
    if (inChar == '\n'){
      if(inputString == "OK\r\n"){
        digitalWrite(13, HIGH);
        delay(200);
        digitalWrite(13, LOW);
        delay(200);
        digitalWrite(13, HIGH);
        delay(200);
        digitalWrite(13, LOW);
        delay(200);
        digitalWrite(13, HIGH);
        delay(200);
        digitalWrite(13, LOW);
      }
      else
      {
        digitalWrite(13, HIGH);
        delay(1000);
        digitalWrite(13, LOW);
      }
    } 
  }
  delay(1000);
}

void loop(){
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13, LOW);
  delay(500);
}

Thursday, March 8, 2012

Yay Servos

Servos arrived today!


Yay Servos!

Android Controller GUI

After spending a fair amount of time looking into using a PS3 controller, I decided it's just not worth it.  I could feasibly sink 2 months into building a comprehensive library that would work.  Instead I started looking into using my Android phone as the primary controller and got carried away.  The last couple of nights have been spent buried in code.  I've just now finished the initial elements of the GUI.


The above is a screenshot of the Android emulator running my code.  Each foot and the head have individual controllers.  Therefor if the user desires they can move each limb independently.  The large semi circle is what you see when you press one of the control nodes.  It shows the valid range of motion for the node.  If the user drags their finger outside of the valid area, the control node follows as closely as it can, but never goes outside the range.  Also note this supports multi-touch, so you can control multiple limbs simultaneously.

Still missing is a large circle in the center of the body for controlling global movement, like walking.  As well as some icons along the bottom for predefined moves like a swipe or a shake fist.

As for the back end, I still need to implement Bluetooth pairing and communication.

Saturday, March 3, 2012

Bluetooth Cont.

Ok so I've been messing with bluetooth for the last few days and have consequently been bashing my head against the keyboard.

I wanted to be able to program the Arduino through the bluetooth bee wirelessly, but I'm not sure that it's actually possible.  I'll have to try a few more things yet.

Useful resources I have found are

DFRobot bluetooth bee wiki (kind of lacking)
DFRobot bluetooth bee PDF specsheet (extremely useful)

To test everything out I did the following.  Upload this sketch to the Arduino.


char val = 'e';

void setup(){
  Serial.begin(38400);
  Serial.write("AT+UART=38400,0,0\r\n");
  Serial.write("AT+ROLE=0");
}

void loop(){
}

This will set the bluetooth module into a slave mode and the baud rate to 38400.  I disconnected the FTDI cable and plugged the Bluetooth bee in.  I flicked the switch on the bee to "AT Mode", this allows it to be programmed.  I then plugged in the battery, waited 5 seconds, and unplugged it.  I removed the Bee and plugged the FTDI cable back in.

I then uploaded this sketch.


char val = 'e';

void setup(){
  Serial.begin(38400);
  digitalWrite(13, LOW);
}

void loop(){
  if(Serial.available() > 0){
      val = Serial.read();
      if(val == 'H'){
          digitalWrite(13, HIGH);
      }
      if(val == 'L'){
          digitalWrite(13, LOW);
      }
  }
  delay(250);
  Serial.write("loop\r\n");
}

I unplugged the FTDI, and plugged in the Bee.  I flicked the switch off of "AT Mode" and plugged the battery in.

I then clicked on the bluetooth icon on my computer and selected "add a new device", the bluetooth bee was listed.  Clicking on it, I selected pair with this device using a code.  The default code for this bluetooth device is "1234".  Once connected I right clicked on it and selected properties.  This will give you the COM # you need to talk to the device.

I opened putty from the radio buttons I selected serial.  I entered COM4 and 38400.  Clicked open.

Bam, now when I hit H the led comes on, L and it goes off.





Thursday, March 1, 2012

Load testing

Got 2 new servos in yesterday.  1 x DFRobot Micro Servo Motor and 1 x Dagu Micro Servo Motor.

The specs seem to claim that they have a 1.6kg stall torque.  They seem so small I'm very curious if they'll actually be able to get anything close to that.  So I've devised an extremely primitive load test.

I taped together 50g worth of coins.  1 twonie, 2 loonies, 5 quarters, 1 nickel and 1 penny.  I put them on the end of a 10cm boom arm.  When the servo has the arm parallel to the ground it should be experiencing
t = 10 x 0.05 x sin(90) = 0.5 kg cm of torque.


Time to see how it holds up.

Edit:
PASSED!  with flying colours!  with the 0.5kg cm load it did not even blink.  The servo rotated just as quickly as it did with no load at all.   I'm impressed.

Quick note about the Dagu Servo... it's definitely much lower quality than the DFRobot one.  I won't be ordering any more of them.  Especially when they cost that much more.