Friday, May 24, 2013

DIY Quad

Hi funsters! Below is a guide on what you'll need to bring to the course, in terms of electronics.
All of the components below are very general-purpose for RC hobbies, so you can always re-use them in other projects down the track.

Radio

You'll need at least a 4 channel radio (transmitter and receiver). Modern radios use the 2.4GHz spectrum, but if you still have an old FM radio, that should still be usable.

If you think you'll be getting into RC models, like helicopters, in the future then I'd recommend buying a 6 channel radio, with multi-model memory support and various plane/heli mixing functions.

Also, the two transmitter control sticks come in two main configurations: mode 1, or mode 2.
If you will be buying a new radio and have never flown a plane or heli before, I recommend the mode 2 configuration. This has the throttle stick on the left, but more importantly the aileron and elevator controls are on the one stick, which is more natural. (I actually fly mode 1, but that's what I learned on and it's too late to change now). Here are some recommendations:

Motors

For this project we'll just be in the 'micro' quad scale, so will be using quite small motors. The modern brushless motors are very powerful for their size, though, and have more than enough grunt.

There are a number of motors I can recommend, the only important thing is that you get 4 of the same kind.
These must match the specs of the motors you buy, and more importantly you need to buy a set with at least two clockwise (CW) and two counter-clockwise (CCW) types. 

ESC's (Electronic Speed Controllers)

Brushless motors need to be controlled with a brushless ESC. You'll need an ESC for each motor, so four all up. ESC's typically have a maximum Amp specification, indicating what kind of load they can handle without burning out. 

Flight Controller Board

This is the heart/brain of the quad, and they have progressed in leaps and bounds in recent years. They have gyro sensors to automatically stabilise the quad, and now accellerometers for auto-levelling.  Pick one from these:

Misc Connectors

You'll need short male-to-male connectors from your radio receiver to the controller board:
Also, you'll need a power distribution cable, which has battery connector split to four ESC connectors:
The small motors sometimes don't have bullet connectors, or the wrong size ones, so these will be needed:

Batteries/Chargers

If you already have some LiPo batteries, you may be able to use them. For this project, you need to use LiPo's with either 2S or 3S (cells), and roughly 800-1200mAh capacity. Here are some links:
Most batteries use JST balance leads, for charging, so any compatible charger will do the job. Here's my recommendation (this one you can use out at fields, from car battery):

Sunday, April 18, 2010

Underlined text in Android

Again, I found it surprisingly hard to find a TextStyle for underlined text in a standard TextView. After spending Too Long navigating API reference, it dawned on me that good-ol' OO concepts can come to the rescue--sub-classing. So, here's a neat little class that achieves underlining in a TextView:


public static class TitleTextView extends TextView
{
public TitleTextView(Context c)
{
super(c);
mPaint = new Paint();
mPaint.setColor(Color.BLACK);
}

Paint mPaint;

@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);

// underline the text
canvas.drawLine(0, super.getHeight() - 1, super.getWidth(),
super.getHeight() - 1, mPaint);
}
}

Monday, March 22, 2010

Getting Onto The Wave

Google has continued to frustrate us Australian Android developers by continuing to ignore emails and developer forum posts to the tune of "when can Australian Android developers publish paid apps?"

Well, I've gotten tired of waiting so have researched alternatives like the Nokia Ovi Store. Granted it's not Android, but they do support JavaME content, so off we go. Am going to try out the new easy-peasy business model offered by the new slew of app-stores, and see how it goes.

I will be debuting with an arcade game called Emerald Hunt, which I originally developed for the humble Palm Pilot. Huzzah!

Tuesday, October 13, 2009

Google Health Viewer

I am preparing to take on the task of writing a Google Health Viewer for Android phones. I have done a bit of background reading, but still not enough to launch into the project. What I'm wondering, by publishing this post, is whether there are like-minded collaborators out there, also interested in such a product.

Firstly, I should state that it's my wish to make this an open-source project, and, like the Google Health service itself, be a free app.

I know a lot of folk have concerns about Digital Medical Records, but surely the usefulness, and potentially life-saving benefits to come from it outweigh whatever overly sensitive, and largely unfounded anxieties we have about privacy?

So, if anyone's interested just bung a comment to this post. Would be interested in knowing if things like useful wrapper classes on the Google Data API's are available? Or even ready-made classes for Google Health data entities themselves?

Wednesday, September 2, 2009

Xml Handling in Android

In recent years I have mostly coded in C#, so on entering the wonderful world of Android and polishing up my Java skills, I find I sorely miss some of the niftier C# language elements like indexers and properties and their proliferation throughout various .NET frameworks classes.

When it came to querying/modifying XML in Android, I found it handy to write a handful of helper methods which achieve the equivalents of the below in C#:


XmlElement XmlNode[string name]; (get)
string XmlNode.InnerText; (get)
string XmlNode.InnerText; (set)
string XmlNode.OuterText; (get)


Also, note a solution to the very annoying org.w3c.dom.Node.setNodeValue(String) problem/workaround in setInnertext().

Enjoy:



import java.io.IOException;

import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmlpull.v1.XmlSerializer;

/**
* A class containing a collection of helper methods for common Xml node navigation/query
*
* @author Scott Powell
*/
public class XmlUtils
{
public static Element getChildByName(Element e, String name)
{
NodeList l = e.getChildNodes();
if (l == null || l.getLength() == 0)
return null; // not found

for (int i = 0; i < l.getLength(); i++)
{
Node n = l.item(i);
if ((n instanceof Element) && n.getNodeName().equals(name))
return (Element)n;
}
return null; // not found
}

public static String getInnerText(Element e)
{
NodeList l = e.getChildNodes();
if (l == null || l.getLength() == 0)
return ""; /// empty

int idx = 0;
while (idx < l.getLength())
{
if (l.item(idx).getNodeType() == Node.TEXT_NODE)
return l.item(idx).getNodeValue();
idx++;
}
return ""; // no #text node found, so return empty string
}

public static void setInnerText(Element e, String val)
{
NodeList l = e.getChildNodes();
if (l != null && l.getLength() > 0)
{
int idx = 0;
while (idx < l.getLength())
{
Node n = l.item(idx);
if (n.getNodeType() == Node.TEXT_NODE)
{
//n.setNodeValue(val); // this isn't changing value!!
Node text = e.getOwnerDocument().createTextNode(val);
e.replaceChild(text, n);
return;
}
idx++;
}
}
// no #text Node, so create one
Node text = e.getOwnerDocument().createTextNode(val);
e.appendChild(text);
}

public static void writeElementTo(Element e, XmlSerializer s) throws IOException
{
s.startTag("", e.getNodeName());
if (e.hasAttributes())
{
NamedNodeMap m = e.getAttributes();
for (int i = 0; i < m.getLength(); i++)
{
Node n = m.item(i);
s.attribute("", n.getNodeName(), n.getNodeValue());
}
}
if (e.hasChildNodes())
{
NodeList kids = e.getChildNodes();
for (int i = 0; i < kids.getLength(); i++)
{
Node n = kids.item(i);
if (n.getNodeType() == Node.ELEMENT_NODE)
writeElementTo((Element)n, s); // recursively write child element
else if (n.getNodeType() == Node.TEXT_NODE)
{
s.text(n.getNodeValue());
}
}
}

s.endTag("", e.getNodeName());
}
}

Auto-repeat Buttons in Android

To my surprise there doesn't seem to be an attribute with the standard android.View.Button class to make it auto-repeat while the Button is pressed. I've seen this behaviour in the DatePicker dialog, so assumed the behaviour is standard. Well, unless I'm going blind and just missed it, I went and wrote my own AutoRepearButton class.

For the Android fans out there, here is the source:


package com.spleenware;

import java.util.TimerTask;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.Button;

/**
* Surprisingly, an AutoRepeatButton doesn't seem to be in the standard Android View frameworks.
* So, simple implementation here. When Button is held down its onClickListener is called on a timer.
*
* @author Scott Powell
*/
public class AutoRepeatButton extends Button
{
public AutoRepeatButton(Context c)
{
super(c);
}

/**
* Constructor used when inflating from layout XML
*/
public AutoRepeatButton(Context c, AttributeSet attrs)
{
super(c, attrs);
}

/**
* TODO: These could be made variable, and/or set from the XML (ie. AttributeSet)
*/
private static final int INITIAL_DELAY = 900;
private static final int REPEAT_INTERVAL = 100;

private TimerTask mTask = new TimerTask()
{
@Override
public void run()
{
if (isPressed())
{
performClick(); // simulate a 'click'
postDelayed(this, REPEAT_INTERVAL); // rinse and repeat...
}
}
};

@Override
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() == MotionEvent.ACTION_DOWN)
postDelayed(mTask, INITIAL_DELAY);
else if (event.getAction() == MotionEvent.ACTION_UP)
removeCallbacks(mTask); // don't want the pending TimerTask to run now that Button is released!

return super.onTouchEvent(event);
}

}