Accelerometer data over bluetooth

From Electriki
Jump to: navigation, search

Introduction

The story begins in one nice suny morning when i came across project where the guy took a glove from some old nintendo console and remade it with accelerometer and bluetooth module. I watched his youtube movie without even breathing. A few months later came the time when it was necessary to pick up a bachelors project so i can get a degree. Searching for a right topic for me i came along "Data transmission over bluetooth" topic and i said myself, "this would be great to use bachelors project to make something i want". And that's, how it began :)

PS: Thanks to michai from #electronics@IRCnet, and other guys from #electronics.

Accelerometer module

Image of accelerometer module
Where to buy?

Bluetooth module

Image
Module image

Eagle library
Eagle library.
Datasheet
Datasheet.
PCB
I used only one foil with 1200dpi printed movite. I have HP LaserJet P1005 printer.
PCB for BTM-112 module PCB for BTM-112 module PCB for BTM-112 module

Schematic - Microcontrooller board

As you can see, i chosed the Atmega8 microprocessor. The reason was that i was playing a little bit with it before starting bachelors project, so i used my little base knowledge i already gained ;) What the Atmega does is that it reads and converts axes from accelerometer and send then over UART into bluetooth module.

Schematics of microcontroler board. Microcontroler board.
Motive Board


film


Schematics - Power supply board

I'm actually useing IO LP2951CM which is is low power, low dropout voltage, voltage regulator, handy for battery powered applications. I'm using this one as power supply for mictrocontroller, BT module and Accelerometer and voltage reference for ADC of uP.

Power supply schematics. Power supply board.
Supply motive. Board

Little Hack

Hack. Smd.

Parts

Accelerometer Motorola/Freescale MMA7260Q
Microprocessor Atmel Atmega8
BT module Rayson BTM-112

Final look

Moduly.jpg Modules.jpg
Box.jpg Case.jpg

Movie









May the source be with you

As would master Yoda say: A lot of to learn i still have!

#define F_CPU 8000000UL
#define BAUD_RATE 19200
 
#include <util/delay.h>
#include <avr/io.h>
 
void init_adc(void)
{
	ADCSRA = (1<<ADEN) | (0<<ADFR) | (0<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);
        ADMUX = (0<<REFS1) | (1<<REFS0) | (1<<ADLAR) | (0<<MUX3) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0);
}
 
 
void init_uart(void)
{
UCSRA = (0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<PE) | (0<<U2X) | (0<<MPCM);
UCSRB = (0<<RXCIE) | (0<<TXCIE) | (0<<UDRIE) | (0<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC = (1<<URSEL) | (0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
//UBRRH = 0b00000000;
//UBRRL = 0x02;
UBRRH = (((F_CPU/BAUD_RATE)/16)-1)>>8;          // set baud rate
UBRRL = (((F_CPU/BAUD_RATE)/16)-1);
}
 
 
unsigned char get_adc(unsigned char adc)
{
unsigned char value=0;
 
ADMUX = adc;
ADCSRA |= (1<<ADSC);
 
while(!(ADCSRA & (1<<ADIF))) 
	;
 
value = ADCH; 
 
ADCSRA &= ~(1<<ADIF);
 
return value;
}
 
 
void transmit( unsigned char data )
{
 
while( !(UCSRA & ( 1 << UDRE ) ) )
      ;
 
UDR = data;
 
while (!(UCSRA & (1 << TXC ) ) )  // TXC == 0;
        ;
 
if((UCSRA & (1<<TXC)))  // TXC != 0;
	UCSRA = (1 << TXC);
 
}
 
 
void decompose( unsigned char i )
{
unsigned char j;
unsigned int k = 1000;
 
while(i>0)
	{
	j=i/k;
	i -= k*j;
	j += 48;
	k /= 10;
	transmit(j);
	}
}
 
 
int main(void)
{
 
unsigned char i;
unsigned char adc=0x20;
unsigned int value=0,data[10];
 
init_adc();
init_uart();
 
while(1)
{
 
for(i=0;i<10;i++) {
	data[i] = get_adc(adc);
}
 
value = 0;
for(i=0;i<10;i++)
	value += (unsigned int) data[i];
	value /= 10;
 
 
switch(adc)
{
case 0x20: 
	transmit('x');
	transmit(':');
	decompose(value);
	transmit(' ');
	break;
case 0x21: 
	transmit('y');
	transmit(':');
	decompose(value);
	transmit(' ');
	break;
case 0x22: 
	transmit('z');
	transmit(':');
	decompose(value);
	transmit('\n');
	break;
 
 
default: transmit('0'); break;
}
++adc;
if(adc == 0x23)
	adc=0x20;
 
 
_delay_ms(30);
}
return 0;
}

Little java application

It's purpose is to read data from Bluetooth, write then on graphical Frame, then to process the data and to get g-values in all axis and write those numbers on the frame. It also has a feature to save data into file.

Screenshots

PCB for BTM-112 module PCB for BTM-112 module

Start == Start; Ulozit == Save; Koniec == Exit;

May the source be with you

Main.class

package bakula;
 
import java.io.*;
import java.util.*;
 
 
public class Main {
 
 
    public static void main(String[] args) {
 
 
        try {
            Input in = new Input();
            Process p = new Process(in);
            //in.start();
            while (1 != 0) {
                p.proc(in.next());
 
            }
 
        } catch (IOException e) {
            System.out.println("Pricina IOException: " + e.getMessage());
        } finally {
            //in.close();
            System.out.println("Closing stream");
 
        }
    }
}

Input.class

package bakula;
 
import java.io.*;
import java.util.*;
 
public class Input {
 
    BufferedReader br;
    BufferedWriter bw;
    FileOutputStream fos;
    Scanner sc;
    String s;
    int actChar = 0;
    char cc;
 
    public void getC() throws IOException {
        actChar = br.read();
 
        cc = (char) actChar;
 
 
    }
 
    public void start() throws IOException {
        fos.write('7');
 
 
 
 
    }
 
    public void close() throws IOException {
        bw.close();
        br.close();
    }
 
    Input() throws IOException {
        File f = new File("/dev/rfcomm1");
        FileReader fr = new FileReader(f);
        br = new BufferedReader(fr);
 
        fos = new FileOutputStream(f);
 
    }
 
    public void getN() throws IOException {
        while (!Character.isDigit(cc)) {
            getC();
        }
 
    }
 
    public void skipWS() throws IOException {
        while (actChar == ' ' || actChar == '\n') {
            getC();
        }
    }
 
    public Data next() throws IOException {
        int x = 0, y = 0, z = 0;
 
        getC();
        while (cc != '\n') {
            getC();
        }
 
        getC();
        while (actChar != '\n') {
 
            //  for(int i=0;i<30;i++) {
            // System.out.print((char)actChar);
            switch (actChar) {
 
                case -1:
                    return null;
                case 'x':
                    getN();
                    while (Character.isDigit((char) actChar)) {
 
                        x *= 10;
                        x += actChar - '0';
                        getC();
                    }
                    //System.out.println("x: " +x + " ");
                    break;
 
 
                case 'y':
                    getN();
                    while (Character.isDigit((char) actChar)) {
 
                        y *= 10;
                        y += actChar - '0';
                        getC();
                    }
                    // System.out.println("y: " +y + " ");
                    break;
 
 
                case 'z':
                    getN();
                    while (Character.isDigit((char) actChar)) {
 
                        z *= 10;
                        z += actChar - '0';
                        getC();
                    }
                    // System.out.println("z: " + z + " ");
 
                    break;
 
                default: {
                }
 
            }
            if (actChar != '\n') {
                getC();
            }
 
        }
 
        // System.out.println(x + " " + y+ " " + z);
        return new Data(x + 14, y + 16, z);   // 2G
        //return new Data(x+10,y+7,z);    // 4G
 
    }
}

Data.class

package bakula;
 
public class Data {
 
    double x, y, z;
 
    Data() {
        x = y = z = 0;
    }
 
    Data(int x, int y, int z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }
 
    public void setX(double x) {
        this.x = x;
    }
 
    public void setY(double y) {
        this.y = y;
    }
 
    public void setZ(double z) {
        this.z = z;
    }
 
    public double getX() {
        return x;
    }
 
    public double getY() {
        return y;
    }
 
    public double getZ() {
        return z;
    }
}

Process.class

package bakula;
 
import java.util.ArrayList;
import java.util.Collection;
 
public class Process {
 
    MyDataFrame df;
    Input in;
 
    public Process(Input in) {
        df = new MyDataFrame(this);
        this.in = in;
    }
 
    public void proc(Data d) {
 
        Data g = new Data();
 
        System.out.print("x: " + d.getX() + " y: " + d.getY() + " z: " + d.getZ());
 
        double x = d.getX() - 128;
        double y = d.getY() - 128;
        double z = d.getZ() - 128;
        // 2G
        g.setX(x / 50);
        g.setY(y / 50);
        g.setZ(z / 50);
 
        /*                          // 4G
        g.setX(x/25);
        g.setY(y/25);
        g.setZ(z/25);
         */
        System.out.println("   x: " + (double) x / 50 + " g" + " y: " + (double) y / 50 + " g" + " z: " + (double) z / 50 + " g");    // 2G
        //System.out.println("   x: " + (double) x/25 + " g" + " y: " + (double) y/25 + " g" + " z: " + (double) z/25 + " g");        // 4G
 
 
 
        df.writetext(d, g);
 
    }
}

MyDataFrame.class

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bakula;
 
import java.awt.BorderLayout;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneLayout;
 
/**
 *
 * @author sandi
 */
public class MyDataFrame extends JFrame { // implements ActionListener  {
 
    MyPanel jp;
    JTextArea ta;
    JScrollPane sp;
    File f;
    Process p;
    boolean setFile = false;
    BufferedWriter bw;
 
    MyDataFrame(Process p) {
        this.p = p;
 
        setSize(640, 480);
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
 
        jp = new MyPanel(this, p);
 
        ta = new JTextArea();
        ta.setSize(580, 400);
 
 
        sp = new JScrollPane(ta, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        sp.setLayout(new ScrollPaneLayout());
        sp.setSize(600, 400);
 
        add(sp, BorderLayout.CENTER);
        add(jp, BorderLayout.SOUTH);
        setVisible(true);
 
    }
 
    public void writetext(Data d, Data g) {
        ta.append("x: " + d.getX() + " y: " + d.getY() + " z: " + d.getZ() + "\t \t");
        ta.append("G: x:" + g.getX() + " y: " + g.getY() + " z: " + g.getZ() + "\n");
        ta.select(ta.getDocument().getLength(), ta.getDocument().getLength());
        if (setFile) {
            try {
                bw.write("x: " + d.getX() + " y: " + d.getY() + " z: " + d.getZ() + "\t \t");
                bw.write("G: x:" + g.getX() + " y: " + g.getY() + " z: " + g.getZ() + "\n");
                bw.flush();
            } catch (IOException ex) {
                System.out.println(ex.getMessage());
                try {
                    bw.close();
                } catch (IOException ex1) {
                    System.out.println("Chyba pri uzatvarani streamu vo vynimke ");
                    System.out.println(ex1.getMessage());
                }
            }
        }
    }
 
    public void writetext(Data d) {
        ta.append("x: " + d.getX() + " y: " + d.getY() + " z: " + d.getZ() + "\n");
        ta.select(ta.getDocument().getLength(), ta.getDocument().getLength());
    }
}

MyPanel.class

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bakula;
 
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
 
/**
 *
 * @author sandi
 */
public class MyPanel extends JPanel {
 
    MyDataFrame m;
    Process p;
    JButton jb;
    JButton jb2;
    JButton jb3;
 
    MyPanel(MyDataFrame m, Process p) {
        this.m = m;
        this.p = p;
 
        setLayout(new GridLayout());
 
        jb = new JButton("Exit");
        jb.setActionCommand("exit");
        jb.addActionListener(new AcListener(m, p));
 
        jb2 = new JButton("Save");
        jb2.setActionCommand("save");
        jb2.addActionListener(new AcListener(m, p));
 
        jb3 = new JButton("Start");
        jb3.setActionCommand("start");
        jb3.addActionListener(new AcListener(m, p));
 
        add(jb3);
        add(jb2);
        add(jb);
    }
}

AcListener.class

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bakula;
 
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
 
/**
 *
 * @author sandi
 */
public class AcListener implements ActionListener {
 
    MyDataFrame m;
    Process p;
    JFileChooser fc;
 
    AcListener(MyDataFrame m) {
        this.m = m;
    }
 
    AcListener(MyDataFrame m, Process p) {
        this.m = m;
        this.p = p;
    }
 
    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("exit")) {
            exit();
        }
        if (e.getActionCommand().equals("save")) {
        try {
            save();
        } catch (IOException io) {
            System.out.println(io.getMessage());
        }
        }
        if (e.getActionCommand().equals("start")) {
            start();
        }
    }
 
    public void exit() {
        System.exit(0);
        try {
            m.bw.close();
            p.in.close();
        } catch (IOException ex) {
            System.out.println("Chyba pri uzatvarani streamu v obsluche tlacitka exit");
            System.out.println(ex.getMessage());
        }
    }
 
    public void save() throws IOException {
        fc = new JFileChooser();
        fc.setDialogType(JFileChooser.OPEN_DIALOG);
        if (fc.showOpenDialog(m) == JFileChooser.APPROVE_OPTION) {
            m.f = fc.getSelectedFile();
        }
        try {
            if (!m.f.exists()) {
                System.err.println("Subor neexistuje");
                System.out.println(m.f);
                m.f.createNewFile();
                System.out.println("Vytvoril som subor " + m.f);
 
            }
            m.bw = new BufferedWriter(new FileWriter(m.f));
            m.setFile = true;
        } catch (IOException e) {
            System.out.println(e.getMessage());
        } catch (NullPointerException npe) {
            System.out.println("No file selected :)");
            System.out.println(npe.getMessage());
        }
    }
 
    public void start() {
        try {
            p.in.fos.write('7');
        } catch (IOException ex) {
            System.out.println("Chyba pri spustani ");
            System.out.println(ex.getMessage());
        }
    }
}

The final unknown

PCB for BTM-112 module

See Also

Btm-112