sure electronics LED dot matrix HT1632c Energia example

32x8 LED dot matrix display

32×8 LED dot matrix display

This LED array has been sitting in my room for months now so I decided to hook it up to an msp430g2553 and get it displaying stuff. I bought it from ebay from a chinese supplier called sure electronics. The array is controlled by a ht1632c led matrix driver chip and the interface required is clocked serial data which I wrote in software for the msp430. There are arduino libraries out there for interfacing with this driver chip and I used them as a reference when putting this together. Right now all I have working is initialising the driver chip and writing data to its ram to display various patterns. The leds are mapped directly to the ht1632c ram. i.e. if you write a ‘1’ to a certain memory address that led will come on and writing a ‘0’ will turn it off. The chip has some other cool features like 16 level PWM dimming also. Only 4 wires (plus Vcc and GND) are needed to interface with the led array. The four wires are DATA, WR(clock), CS (this pin is pulsed to switch between read,write and command modes on the ht1632c) and the RD pin which is the data out from the ht1632c. This data out could be the contents of the RAM so you could find out which leds are on. I didn’t use this pin at all so it’s really only 3 wires which is pretty handy. These LED array boards can be chained together up to a max of 4. Right now I only have one so the code written is meant to just control one chip. That being said it shouldn’t be too much hassle to get it working with several boards at once.

Here is the code I wrote using the Energia IDE :

If you connect the LED array using the same pins I’ve defined for DATA, WR and CS it should work right away displaying the twitter logo scrolling across the screen. Here is a picture of it displaying a speaker of some type:

led array displaying speaker

led array displaying speaker

If you’re interested in displaying text then check out this really extensive arduino library for the ht1632c.

How to get the most voltage out from your wheatstone bridge

Wheatstone bridges. Great craic. But how do you get the biggest voltage swing possible out of it? Lets examine an example situation:

Lets say someone throws a PT100 thermometer* on your lap and orders you to plug it in to a Wheatstone Bridge. This person also tells you that the temperature span to be measured is 20 – 100°C.

PT100 *(basically a variable resistor whose resistance varies with temperature)

PT100 *(basically a variable resistor whose resistance varies with temperature)

After consulting the PT100 datasheet we get the following information:

pt100 resistance @ 20°C = 120Ω
pt100 resistance @ 80°C = 340Ω

This gives us a total change in resistance of 220Ω.
With this basic information we can start to work out the values of R1, R2 and R3. First, check out the circuit diagram of a wheatstone bridge:

wheatstone bridge circuit diagram

wheatstone bridge circuit diagram

The equation that relates the voltage out to the supply voltage and resistor values is given as:

V_{out} = Vs(\frac{R_{2}} {R_{1} + R_{2}} - \frac{R_{x}}{R_{3} +R_{x} })

To simplify the maths we can set the two top resistors equal to one another. i.e R1 = R3. To make things even easier, lets just call them both by the one letter : R. This change can be seen in the diagram below. Also note that R2 has been set to 120Ω


For this example Rx is a pt100 thermometer but this tutorial applies to anything with variable resistance.
At the low end of our range (120Ω @ 20°C) we want the bridge to ideally output zero voltage. This is achieved by setting the resistor across from it (R2) equal to this lowest resistance of 120Ω. The ultra cool group of people that know wheatstone bridge lingo would say that the bridge is ‘balanced’ when Rx = 120Ω ( when the temperature is 20°C).

Before going any further, lets first answer the question “why should I bother trying to get the maximum voltage out possible?”

There are probably lots of reasons, but the main one I can think of right now is that when the time comes to amplify the wheatstone bridge output voltage, you want to use the smallest gain possible. For example, which is better, amplifying a 0-10mv signal by 100 to get 0-1v out or multiplying a 0-30mv signal by 33.3 to get 0-1v out. The second case is better because it will be far less susceptible to noise.

The next question is : “What value of R should I choose to get the biggest possible output voltage”?
This is best answered by plotting Vout vs R. First we need to fill into the wheatstone bridge equation:

R1 = R3 = R
Vs = 5V
Rx = 340Ω
R2 = 120Ω

For filling into this equation we choose Rx = 340Ω because we want the max Vout when Rx is at its max range.

V_{out} = 5(\frac{120\Omega } {R + 120\Omega} - \frac{340\Omega}{R +340\Omega })

by simplifying the right hand side of the equation we get:
V_{out} = \frac{-1100R}{R^2 +460R + 40800  }

If we now graph Vout vs R we get:
(click on graph to enlargify)

We want to find the value of R that gives us the maximum Vout. This is pretty easy to see on the graph. Just look at the peak of the curve and look at what R value it is.

To do this using maths we have to differentiate the above equation. This is because the part of the graph we are interested in is where the slope of Vout = 0 (in other words the peak of the graph)

\frac{d.V_{out}}{d.R} = \frac{1100(R^2 - 40800)}{(R^2 +460R + 40800)^2} This is the above equation differentiated with respect to R.

Now set the left hand side to 0 to find the value of R when the slope of Vout = 0.
0 = \frac{1100(R^2 - 40800)}{(R^2 +460R + 40800)^2}

and solve for R:
R = 201.99\Omega

This value seems to match up with the plot of Vout vs R. It’s kind of unfortunate how small a change it makes in choosing R. Looking at the above graph the difference is only tens of mV, hardly worth thinking about for most applications probably. This might be because I chose such a big change in resistance for this example (220Ω). Some strain gauges vary by as little as 1-2Ω! Maybe it is more worthwhile to find the best R value when the change in resistance is tiny.

PRBS array C code generator (pretty nasty)

Needed an 11 bit PRBS (Pseudo Random Binary Sequence) for use in a project. After some searching online, I came across this sweet wikipedia article on Linear Feedback Shift Registers (LFSRs). This article includes some sample C code to generate a PRBS sequence so I modified this code to generate a sequence that is 2048 bits in length.

// taken from the prbs wikipedia page and modified to make an 11 bit prbs and print to file
// wattnotions april 18th 2015
# include <stdint.h>
# include <stdio.h>
# include <stdbool.h>

bool prbs[2047]; 

int main(void)
    uint16_t start_state = 0x7D0;  /* Any nonzero start state will work. */
    uint16_t lfsr = start_state;
    bool bit;
    unsigned period = 0;
	FILE *fp;
	fp=fopen("test.txt", "w");
	fflush( stdout );
        /* taps: 11 and 9; feedback polynomial: x^11 +x^9 + 1 */
        bit  = ((lfsr >> 0) ^ (lfsr >> 2) ) & 1;
		fprintf(fp, "%d", bit);
        lfsr =  (lfsr >> 1) | (bit << 10);
    } while (lfsr != start_state);

This 2048 bit sequence in printed as a sequence of 1s and 0s to a .txt file. It looks something like this:
0010010001110110101101011000110001110111101101010010110000110011100111111011110000101001100100011111101……you get the idea

Fairly useless in its current state so some Python magic is required to convert this in to C code.

# opens file containg prbs sequence, parses it into an array of bytes in C code
f = open('Cgen.h', 'w')  # open the file that will hold the generated C code

with open ("test.txt", "r") as myfile:   # open the file containing the prbs 1s and 0s'\n', '')

num = 0

f.write('int prbs[] = {\n')
for i in range( ((len(data))//8)  ):
	f.write("'0b" + data[i:i+8] +"'")
	if( i != (((len(data))//8) -1) ):
		f.write(", ")
	num = num + 1
	if (num == 7):        # print a newline after every 7th element to keep things pretty
		num = 0

The output from this python script is saved in a file called Cgen.h . It looks like this:
int prbs[] = {
‘0b00100100′, ‘0b01001000′, ‘0b10010001′, ‘0b00100011′, ‘0b01000111′, ‘0b10001110′, ‘0b00011101′,
‘0b00111011′, ‘0b01110110′, ‘0b11101101′, ‘0b11011010′, ‘0b10110101′, ‘0b01101011′, ‘0b11010110′,
‘0b10101101′, ‘0b01011010′, ‘0b10110101′, ‘0b01101011′, ‘0b11010110′, ‘0b10101100′, ‘0b01011000′,
‘0b10110001′, ‘0b01100011′, ‘0b11000110′, ‘0b10001100′, ‘0b00011000′, ‘0b00110001′, ‘0b01100011′,
‘0b11000111′, ‘0b10001110′, ‘0b00011101′, ‘0b00111011′, ‘0b01110111′, ‘0b11101111′, ‘0b11011110′,

….and so on, then near the end it looks like this:

‘0b10011001′, ‘0b00110010′, ‘0b01100101′, ‘0b11001010′, ‘0b10010101′, ‘0b00101011′, ‘0b01010111′,
‘0b10101111′, ‘0b01011111′, ‘0b10111111′, ‘0b01111110′, ‘0b11111100′, ‘0b11111000′, ‘0b11110000′,
‘0b11100001′, ‘0b11000010′, ‘0b10000100′);

So its just an array definition that can be conveniently hidden away in a header file. There’s a github repo called prbs_C_gen with all of the source files and example output files if you fancy taking a peek.

Low power magnetic hold and release mechanism

How it works:


Explanation of the idea:

With the inductor and magnet combined, ferrous metal objects can be held without any power indefinitely. To release the metal object the magnetic field holding it up needs to be temporarily cancelled out. This happens by pulsing current through the inductor which generates a magnetic field separate to that of the magnet. These two magnetic fields are of the opposite polarity meaning the inductors field cancels out the magnets field. The inductor only has to be powered long enough for the item to drop which I haven’t measured but its probably somewhere in the hundreds of milliseconds lets say around 100 milliseconds at a guess. This means you can hold an object for potentially a very long time (months, years maybe I dunno!) and expend a relatively small amount of power releasing it compared to if you’d used an electromagnet to hold the thing up which required a constant power source.

Or you could disregard the above explanation and look to this meme for guidance: