The other day, I wrote an article about using a 3D accelerometer with
MSP430. Now I am going to push the experiment one step further and
combine this bluetooth experiment and this accelerometer experiment.
This experiment has a great advantage for me: it is a lot more
spectacular than BlueTooth only and accelreometer only, and the
development effort is close to 0.
This can be taken as a basis for any wireless sensor development.
The hardware
I have just received a printed circuit allowing to easily adapt a bluetooth
module to the Soroban development board. This printed circuit has some
extra room for sensors, which makes the board particularily fitted
for any kind of wireless sensor. Here is an image of this board mounted
on Soroban. The rubber band is used to hold the battery together.
The hardware wiring is exactly the same as in the BlueTooth experiment
written previously. This time, as I have a printed circuit, it is even easier.
As you probably noticed, I had grounding problems with the chip antenna,
and I had to add a fat cable so that it works better. it is a bit strange to
me since the two points were already connected, but I know very little
about high frequencies...
As for the accelerometer itself, as I had only one, the most difficult was to
take it off the previous board. I made again the same wiring (VCC, ground
and XYZ).
The software
As the wiring was the same, I just verified that the accelerometer was
still working. It was. Then I merged the Bluetooth project (adding the
UART files to the accelerometer project only). There was very little to
change beside that. I just noticed that the baud rate is diffrent to my
previous implementation. The defaule value is 57600 bps while the
first version was 115200. Byt since I am going to sample at 20 Hz, this
is not a big problem.
In order to easily verify that it works, I usually send printable characters.
Therefore, using the command cat in a MacOS terminal makes all the
job.
Now I am not going to describe the interrupt which is exactly the same
as in the accelerometer (set it up as consecutive for 3 samples and you're
done.
I use a 6 character buffer called valuestring for coordinates transmission.
Coordinate X is transmitted as "Xabcdx" where abcd is a 4-digit number
representing the output of the ADC.
So in the MSP430 main loop, once the global variables X, Y and Z
exist, I have:
- Code: Select all
while(!exit) {
pack_value(x, 'X');
Usart0SendBuffer(valuestring, 6);
pack_value(y, 'Y');
Usart0SendBuffer(valuestring, 6);
pack_value(z, 'Z');
Usart0SendBuffer(valuestring, 6);
Usart0SendByte(eoln); // End of line
SDC12CTL0 |= ADC12SC;
_BIS_SR(LPMO_bits + GIE);
}
That's it. pack_value is a function that puts an integer in decimal
format in a string starting with X and ending with x.
Once this program runs bug free, then you can open a terminal and run:
- Code: Select all
Mercure:~ pascal$ cat /dev/cu.JepicoBluePlum-II-Seria-1
X2790x Y2100y Z2240z
X2793x Y2099y Z2262z
X2799x Y2106y Z2255z
X2756x Y2071y Z2227z
X2793x Y2104y Z2255z
X2797x Y2105y Z2257z
X2776x Y2101y Z2248z
X2805x Y2109y Z2258z
X2805x Y2106y Z2270z
X2785x Y2104y Z2248z
X2812x Y2114y Z2270z
X2796x Y2104y Z2256z
And you can verify that the raw values change significantly when you
turn the board.
Graphic display at MacIntosh side
As MacOS-X is one flavor of Unix and as we use only the usart
profile of the bluetooth interface, we can just open a file descriptor.
The path of the socket is /dev/cu.JepicoBluePlum-II-Seria-1. This name
may change if you use another mdule.
So it can be opened exactly like a file.
- Code: Select all
fd = fopen("/dev/cu.JepicoBluePlum-II-Seria-1", "rb");
Of course, you have to verify that FD is valid before reading its data.
As reading in the file can begin at any time, you are very likely to
start at the middle of one xyz frame, so you have to first wait for the
next "X", and you will be sure the frame starts.
Then you can pass this frame to the view in order to parse it (note
that there is probably a simpler way to do it, but it works):
- Code: Select all
// vs is the value string, an array of characters
while(vs[i] != 0) {
if((vs[i] == 'X') || (vs[i] == 'Y') || (vs[i] == 'Z') ||
(vs[i] == 'x') || (vs[i] == 'y') || (vs[i] == 'z')) vs[i] = ' ';
i++;
}
// Read xx, yy, zz from the value string
sscanf(vs, "%d %d %d", &xx, &yy, &zz);
// Get the signed values. The sampling ref was VCC, so 0 is VCC/2.
X = (float)xx - 2048;
Y = (float)yy - 2048;
Z = (float)zz - 2048;
// Calculate the only angle we need here.
if((X > 0) && (Y > 0)) {
XYangle = atan(Y/X) * (180 / pi);
}
else if((X < 0) && (Y > 0)) {
XYangle = 180 + atan(Y/X) * (180 / pi);
}
else if((X > 0) && (Y < 0)) {
XYangle = atan(Y/X) * (180 / pi);
}
else if((X < 0) && (Y < 0)) {
XYangle = -180 + atan(Y/X) * (180 / pi);
}
else {
XYangle = (Y > 0) ? 90 : -90;
}
That's it, we have the angle, and we can switch to the graphics part.
Here is the whole drawRect function:
- Code: Select all
- (void)drawRect:(NSRect)rect {
NSBezierPath * P;
NSRect R = [self bounds];
int offx = R.size.width/2;
int offy = R.size.height/2;
NSAffineTransform * T1;
NSAffineTransform * T2;
T2 = [NSAffineTransform transform];
[T2 translateXBy:offx yBy:offy];
// Draw the view backgroound
[[NSColor colorWithDeviceRed:0.9 green:0.9 blue:0.9 alpha:1] set];
[NSBezierPath fillRect:rect];
// Draw the rectangle
[[NSColor blackColor] set];
if(valueString != nil) {
T1 = [NSAffineTransform transform];
[T1 rotateByDegrees:-XYangle];
[T1 scaleBy:3];
[[NSColor blackColor] set];
P = [NSBezierPath bezierPath];
[P appendBezierPath:boardPath];
[P transformUsingAffineTransform:T1];
[P transformUsingAffineTransform:T2];
[P setLineWidth:5];
[P stroke];
}
}
Note that we need 2 affine transtorms. I tried to use one only and to
turn the rectangle before shifting it.For some reason it does not work,
everything turns around the bottom left corner of the window.
Once this is done, the results are like this:
Conclusion
In this report, I have explained how to easily implement a wireless
sensor with Soroban. An accelerometer was used to implement an
inclinometer, and as it can be seen from the pictures, the result is very
close to the reality: the board ant its image on the screen are always
parallel.
As the module we have used is a class 1 module, it is possible to receive
sensor data from a few hundredths of meters when in sight. Since the
power is high, it has a great immunity to noise and can therefore be
used for industrial wireless sensors.
We will propose this module as a standard extension board for Soroban.
Pascal
