Sunday, November 25, 2012

kdev-python 1.4 stable released!

I'm happy to announce the release of the first stable version of kdev-python, version 1.4! As this is the first stable release, this post is supposed to be an overview about what kdev-python actually does.

KDevelop with kdev-python 1.4
First of all, kdev-python is a plugin for KDevelop. Its purpose is to make development of python applications more convenient. The main focus of the program is static analysis of source code, and providing features which use the information gathered, such as
  • Semantic syntax highlighting (not the regex-stuff kate does, but real highlighting, showing your defined functions colorized etc.)
  • Intelligent code completion, depending on where the cursor is and what variables exist etc.
  • Navigation features, such as Jump to Declaration, searching for functions/classes, class browser, ...
  • and many more
There's also a few features other than static code analysis, such as debugger integration, but the former is clearly the main focus of the project. kdev-python itself is written in C++.

Blender: exporting camera tracking markers to CSV

For university, I needed a camera tracker which could track motion of some particles under a microscope, and give me the coordinates of a particle for each frame. Blender has a very nice camera tracker which is ridiculously easy to use (and very fast), but it cannot export its results in a gnuplot-compatible format. But, it has a nice Python API, so you can just do it yourself! This is a script which exports all camera tracking markers of all videos in a blender file to CSV files in a directory called "data":
import bpy
D = bpy.data

for clip in D.movieclips:
    for track in clip.tracking.tracks:
        fn = 'data/tr_{0}_{1}.csv'.format(clip.name.split('.')[0], track.name)
        with open(fn, 'w') as f:
            frameno = 0
            while True:
                markerAtFrame = track.markers.find_frame(frameno)
                if not markerAtFrame:
                    break
                frameno += 1
                coords = markerAtFrame.co.xy
                f.write('{0} {1}\n'.format(coords[0], coords[1]))
Just paste this to a blender text editor window and press Alt+P to run it. You have to create a directory named "data" manually before that.

Careful: The coordinate output is in units of the video height / width. So if your video is not square sized, you need to multiply the output by the video clip dimensions (clip.size[0] and clip.size[1]).

Raspberry Pi i2c and repeated start condition and MAG3110 magnetometer

i2c is a protocol to communicate with microchips. It is widely used if the required data rate is not that high (up to few thousand bytes per second or similar). Reading data from some client (which could be some sort of sensor, or an Analog-Digital-Converter for example) with the Raspberry Pi is usually as easy as just reading from a device file (/dev/i2c-0 for example), specifying the device address beforehand, due to the magic the underlying kernel driver does. Some i2c clients, such as this MAG3110 magnetometer I'm using, require you to specify a register address to read from on each data access, tough. For this, technically, you need to send a START (to tell the device you want to communicate), then the register address you want to read from, then a REPEATED START (to tell the device you're done with sending the address and want to read the data now), then you can read the data, and then you send a STOP (to tell the device you're done). Sounds easy, right? It is however not quite obvious to me how to do that. Just sending the register address, then reading does not work, since that will send a STOP after the register address has been written, which leads to the device assuming you're done and forgetting about everything.

Other people seem to be confused about this as well. Some threads in the internet even conclude that the i2c controller used in the Raspberry Pi is not capable of this functionality at all. However, this fortunately does not seem to be the case: using the i2cget program, you can specify a register to read from, and it will work just fine (same goes for writing).
Edit on 01.01.2013: Seems to be that it is right what people say after all: The Raspberry Pi does not support repeated start. The stuff below still works for my device, but apparently only by chance; the behaviour of the controller is not correct. Here's a screenshot of the communication:
Communication generated by the code below. After the first data byte (the register address, 4) has been transferred, you can easily spot the spike in SDA (yellow) while SCL (teal) is high, meaning STOP START. This is incorrect.
So, since this is the open source part of the world, we can just go look at what they do, and steal it! ;)
The sources are easy to find (here, for example), and you can just modify i2cget.c to do what you need. Here is my code for accessing the magnetometer mentioned above, as an example. I hope this might help other people which are confused about this too.

Oh, and here's a fancy image of the board with the magnetometer mentioned above:
Board with a three-axis magnetometer, in a 2mm x 2mm DFN package
The actual sensor is the small part in the middle. Doesn't it look nice? :)

I should also mention that the magnetometer itself is pretty awesome! It's a three-axis magnetometer with 16 bits resolution per axis (!), and it costs less than two euros at farnell (actually the whole board shown above is only about two euros in total if you add up the components, PCB, and the solder). The device is well sensitive enough to measure the earth's magnetic field; thus, you can use it to accurately determine its absolute rotation. I did a test which rotates meshes in blender in real-time when you rotate the device -- it worked quite well! It needs a lot of adjustment to the axes tough, they don't really match yet. I'll write about that again if I get it to work nicely.

Here's an example plot when rotating the device around a bit:
Raw data received from magnetometer when rotating it by hand
Here's moving a magnet towards the device, starting from about 1m away:
Moving a large magnet towards the device. t=0 corresponds to ~1m distance. The peaks in the y and z axes in the end originate from the magnet being rotated a bit while moving it away.
Edit on 01.01.2013: Hahaha, look at the photo of the board again -- do you notice something? Yep, half of the GND isn't even connected to anything. That's what happens if you make just a layout without a proper connection diagram + DRC ;) After fixing that with some zero-ohm resistors across the traces, the noise level of the device has gone way down. The curves are much smoother than in the plot above now.

Wednesday, November 21, 2012

Note about SPI chips behaving in a weird way

In my recent electronics projects, I encountered two cases where a chip supporting the SPI protocol behaved in a weird or inconsistent way when communicating with the computer controlling it. I had an ADS 8320 Analog-Digital-converter (which should measure some voltage 100k times per second in 16bit resolution), which reported data like this when given a monotoneously rising, then falling voltage:
Weird data received from an AD converter via SPI (axes are x: t/samples, y: voltage/LSB)
And recently, I had an ADF 4350 (a RF frequency synthesizer), which randomly sometimes reacted to my commands sent via SPI, and sometimes did not.

The problem turned out to be the same in both cases: the cable from the SPI controller to the chip was too long, apparently, and the signal got corrupted a bit -- not much, but obviously enough for it to stop working (altough the signal looked perfectly clean on an oscilloscope!). Soldering 100pF condensators from the SPI lines to GND close to the chip instantly made both chips work reliably; the data from the ADC is nice and clean, and the ADF 4350 executes all commands as it should.
Same test as above, but with 100pF condensators on the SPI lines :)
So, if you're using SPI with a controller which is not very close to your chip (like, when using the raspberry pi and a breadboard), make sure to add some noise reduction circuitry!

Friday, November 16, 2012

SMD soldering with a pre-heater and self-etched boards

I'm planning to build another radio telescope (I'll write more about that once it's a bit more advanved), and for that, I need to solder a lot of SMD stuff -- mostly because many of the parts I need are only available in SMD. This has a few advantages -- especially it's cheaper and smaller -- but it can also be very difficult to do with a soldering iron, for QFN packages for example. Common methods to solder such things include insane soldering iron skills (which I don't have), temperature-regulated ovens (which are large and not that cheap), hot-air guns (which are quite expensive), and hot plates (which I tried, but it didn't turn out to be very convenient -- the heating times are long, and the temperature is difficult to control). So recently I found this nice product (called "TENMA - 21-10135 - PRE-HEATER") and figured that it might be useful for this purpose (and with around 45 euros, it's quite a bit cheaper than the alternatives). And indeed, it is:
A test-board with 0805 / 0603 resistors / LEDs soldered by a SMD pre-heater

Friday, November 9, 2012

kdev-python beta 2 released!

I'm happy to announce the immediate availability of the second beta version of kdev-python, the python language plugin for KDevelop!
You can download the sources from kde.org; those can be compiled against KDevelop 4.4 (which is the current stable version).

Changes over the first beta release include:
  • Two crash bugs fixed
  • Fix a bug in parse priority things (it did sometimes cause documents not to be reparsed after a dependency was changed, which led to imports not being handled correctly)
  • Now full support for PyKDE4 and PyQt4!
Please try to make this version crash as hard as you can -- if no further grave issues are found, then the first stable version can be released soon!

Another note about the state of python 3 support: I'll probably merge the python 3 branch into master soon. All subsequent releases of master will support python 3 *only*. There will be a python 2 version of the plugin, which will be updated to work with new versions of KDevelop for quite a while (I'd guess at least two years from now), but I will not spend considerable time to backport features to that branch if they're not easily portable (I just don't have the time, sorry). I think my time is spent better on integrating the features new in python 3 and on polishing the new version instead of supporting two versions at once.
I also don't think it will be possible to have both the python 3 and the python 2 version installed at once, since that will require UI and logic for determining which version to use for what. I don't really want to write that, knowing that it will become more obsolete every day. If you really need it, you can still just install the two versions in two directories and start two instances of kdevelop (one for python 2 and one for python 3) with the two different install paths in $KDEDIRS.