If you intend to use you Raspberry Pi with lot's of power hungry USB device(s), such as USB-HDD, then be prepared to buy a powered USB Hub because the Raspberry Pi USB ports only deliver 100mA each (at most).
I bought one today which is not exactly mentioned over at the Raspberry Pi peripheral compatibility list (powered USB hub section). However, once I used the hub, I checked the USB device id with lsusb. It turns out the device id is in there: 1A40:0201 which translates to Terminus Technology Inc. FE 2.1 7-port Hub. The hub itself named Mumuksu (product code: MU109) and contains 13 USB ports. The cost is around $17. It comes with a power adapter (US-type connector unfortunately, so I needed a converter coz in my country the plug is European type). The power adapter output is rated at 5V and 3A.
The USB hub is powerful enough to power USB HDD and "back-power-ing" the Raspberry Pi without problem. I have yet to add another power hungry device to the mix. But again, this shows that one of the indicator of a good USB hub for raspberry pi is the huge amount of current that it provides.
Sunday, December 30, 2012
Friday, December 28, 2012
Raspberry Pi LXDE (X Server) Auto Login
I'm using Raspbian Wheezy at the moment and it's very easy to make the Raspberry Pi to do auto login to the LXDE (X server), just run raspi-config and select boot_behaviour, then select boot directly to desktop. This should run LXDE under user pi.
All is great with that, but I'm curious to know what exactly the raspi-config script do to accomplish that. Well, time to fire up grep and do some digging. I found several remnants left by raspi-config while executing this command:
All is great with that, but I'm curious to know what exactly the raspi-config script do to accomplish that. Well, time to fire up grep and do some digging. I found several remnants left by raspi-config while executing this command:
pi@raspberrypi ~ $ sudo grep -r -w 'pi' /etc/ | lessThere is an intriguing result while scrolling through less output like these:
... /etc/lightdm/lightdm.conf:autologin-user=pi ... /etc/passwd:pi:x:1000:1000:,,,:/home/pi:/bin/bash /etc/passwd-:pi:x:1000:1000:,,,:/home/pi:/bin/bashI have yet to decipher the whole stuff, but searching for the remnants of the intriguing raspi-config changes is certainly worthwile.
Thursday, December 27, 2012
Calling Python Module from C
This is a sample function (modified from python docs) to call python function in a python module from C language:
It's the job of the python function to convert to the right type as needed. For example, if you pass float value as string then you have to convert the float string to float in your python code. Let's see how to do this. Take a look at the python function as follows:
/** \brief This function executes python module passed in args[0]
*
* \param argCount number of arguments passed to this function in args parameter
* \param args array of string containing the parameters. The first parameter is
* the name of the python module, the second parameter is the
* function name in the python module. The third and latter parameters
* are the parameters to the python function in the python module.
*/
int
exec_python_module(int argCount, char *args[])
{
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue, *pFloatValue;
int i;
if (argCount < 2) {
fprintf(stderr,"exec_python_module() usage: pythonfile funcname [args]\n");
return 1;
}
Py_Initialize();
pName = PyString_FromString(args[0]);
/* Error checking of pName left out */
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule, args[1]);
/* pFunc is a new reference */
if (pFunc && PyCallable_Check(pFunc)) {
/* NOTE: The function parameters start at
args[2], that's why the index must be
subtracted with two below */
pArgs = PyTuple_New(argCount - 2);
for (i = 0; i < argCount - 2; ++i) {
pValue = PyString_FromString(args[i + 2]);
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, i, pValue);
}
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
printf("Result of call: %ld\n", PyInt_AsLong(pValue));
Py_DECREF(pValue);
}
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
}
}
else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", args[1]);
}
Py_XDECREF(pFunc);
Py_DECREF(pModule);
}
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\" module\n", args[0]);
return 1;
}
Py_Finalize();
return 0;
}
The main difference to the sample code in python 2.7.3 docs (section Embedding Python in Another Application | Pure Embedding) is that instead of PyInt_FromLong(), I'm using PyString_FromString() function. Therefore, the assumption is that all of the function arguments are passed as string, in order not to truncate anything.It's the job of the python function to convert to the right type as needed. For example, if you pass float value as string then you have to convert the float string to float in your python code. Let's see how to do this. Take a look at the python function as follows:
def My_Function(my_float_string_param):
converted_float = float(my_float_string_param)
## Process using float here
## ...
The python code above converts the float string into float with the float() function. This is needed, otherwise the python interpreter would balk out with error message if you use my_float_string_param directly on function calls that expects a python float variable. Instead of using my_float_string_param, you should use converted_float in those function calls.
Adding New Path to PYTHONPATH
If you've made a module in python, chances are, you would like to be able to import the module into one of your python script. However, if you don't want to place your script in the "standard" python location, you have to add the path of the directory containing your module to PYTHONPATH environment variable. You can check the value of the PYTHONPATH like this:
me@mymachine ~/work $ python Python 2.7.3rc2 (default, May 6 2012, 20:02:25) [GCC 4.6.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.path ['', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/usr/lib/python2.7/lib-tk', '/usr/lib/python2.7/lib-old', '/usr/lib/python2.7/lib-dynload', '/usr/local/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages', '/home/pi/work/c_to_python', '/usr/lib/pymodules/python2.7'] >>>This link explains the alternatives to do that. I choose the easiest path, i.e. adding a *.pth file to one of the path already parsed by python. For example, adding my_path.pth to /usr/lib/python2.7/dist-packages directory, with the content of my_path.pth as follows:
/home/me/my_python_lib_dirThis of course assume that your python module is in /home/me/my_python_lib_dir. That's it, hopefully this could be useful for those wanting to place a python module in "non-standard" python path(s).
Subscribe to:
Posts (Atom)
