Sunday, January 6, 2013

Fritzing with Brython

The 2 bit H Bridge

In the article entitled "Rasberry Pi: 2 bit H Bridge" I said that I was working on a way to put breadboard layouts on the blog. Well, I finally got some time today to get something working.

SVG

Scalable Vector Graphics (SVG), is an xml vector format. It is supported by most modern browsers, and it is possible to interact wth SVG in a web page. For example, one can attach events to SVG groups, and it is possible to modify properties of the SVG XML tree from Javascript.

In theory, it shows a lot of potential, and can replace Flash. In practice, it is not as widespread as it should be.

Fritzing

Fritzing is an open source hardware initiative to help various type of people (designers, programmers, artists etc) to work with electronics. Part of that is a library of SVG components, built on the same scale, to work with diagrams, and, you guessed it, with breadboard layouts.

But, you cant build interactive layouts for tutorials, and it requires a program to design your layouts. I wanted to do this programmatically.

The other thing is that the core Fritzing breadboard SVG (the type of breadboard I use) is almost 600KB. Yet it looked like it could be done programatically. But SVG and Javascript without libraries, Hhuuhhg!

Brython

Brython offers SVG support through the keywork SVG. It feels just like using a Python module, without having to import it. To create a red rectangle, 100 x 100 in SVG, the XML would look like:

<rect width="100" height="100" style="fill: #FF0000" x="0" y="0" />

In Javascript, without a specialized library, this is not clean. It would be done something like this:

var NS="http://www.w3.org/2000/svg";
var SVGObj= document.createElementNS(NS,"rect");
SVGObj.width.baseVal.value=100;
SVGObj.height.baseVal.value=100;
SVGObj.setAttribute("width",100);
SVGObj.setAttribute("height",100);
SVGObj.style.fill="#FF0000";
...etc 

In Brython, we would do the equivalent with:

SVG.rect(width="100", height="100", fill="#FF0000", x="0", y="0")

Or you can create it blank and add the properties. Or modify the properties. In plain and simple Python syntax.

So I created a module (about 10K up to now) in Brython (you could run it server side with Python and a small SVG replacement) to set up a breadboard (implemented in 50 lines of code vs almost 600KB of SVG), and it knows how to do NPN or PNP transistors, wires, handles the row and column nomenclature of the breadboard, motors and resistors. Resistors get the correct color bands based on the value passed to it too!

The matrix (number, letter) to x/y pixel coordinates can be implemented trivially using:

def m2c(origin):
    number, letter = origin
    x = 5 + number * 9
    y = 180 - "mp  ABCDE  FGHIJ  MP".index(letter) * 9
    coords=(x, y)
    return coords

The X axis is a little more obvious than the Y axis. For the Y axis, the letter can be A through J, but between E and F, there is a channel with no pins. At the pitch of the board, this represents exactly two rows. Similarly between the bottom power rails and A and between J and the top rail exists this same 2 position skip. We do that with spaces in the string of letters. Lower rail is m (minus) and p (plus) and top rail is M(minus) and P(plus), by convention. The pitch of the board is 9 pixels, so 9 * the index at which we encounter the letter will give us our coordinate in pixel. Except that the Y axis in SVG is inverted compared to the breadboard letter coordinate system, hence the 180 - in front (the height is 189, but index is zero based, so we offset by 9).


The m2c call is built in the components, so to draw a 660 Ohm resistor at B27:

# first, we set up a breadboard
breadboard = board("breadboard")

# add a component to the breadboard
breadboard <= resistor((27,'B'),"660")

# let us show the breadboard
doc["breadboard"] <= breadboard

So let's see how we can instruct a breadboard layout now, by calling the right functions with some buttons:

The 2 bit breadboard



Put 4 x 660 Ohm resistors (anything around that ballpark, including 1K Ohm will work) in B27-B32, B34-B39, I27-I32, H34-H39
Put 4 x NPN (2N2222 type) transistors in C31-C33, D33-D35, H31-H33, I33-I35  (the flat side is facing us)
Put wire jumpers in B27-B32, B34-B39, I27-I32, H34-H39
Put jumpers (yellow, brown) pairing the 4 inputs into a 2 bit H bridge
Connect E33 to one side of the motor, and F33 to the other side

To connect the Raspberry Pi, this will depend on if you have a GPIO cable, a cobbler, t-cobbler or something else.

At the end of the day, though, you need to connect GPIO #4 to pin J39 (first input of the H bridge) and GPIO #23 to pin E39 (second input). You will also need to connect the + rail to the RPi 5V and the - rail to the RPi GND.

Using the code from the article mentioned at the onset, and you will be good to go.
One last point, to conclude on the circuit: I don't have a diode in my brython fritzing module yet, so I didn't include freewheeling diodes on the circuit. It will work as is, but it is a good practice to add freewheeling diodes. i will revisit this when I've added them to the module.

1 comment: