Digitale Wasserwaage mit MEMS Beschleunigungssensor (MMA8452Q)

Digitale Wasserwaage

Nachdem ich ja HIER vor einiger Zeit schon einen kleinen Artikel zum Freescale Beschleunigungssensor MMA8452Q veröffentlicht habe, habe ich mir kurzerhand mal eine digitale Wasserwaage mit diesem Sensor gebaut. Das ganze ist ein recht eigenwilliger Aufbau, da ich dafür jetzt nicht gleich eine Platine layouten wollte. Also wurde das ganze auf einer Lochrasterplatine mit SMD (0603) Bauteilen und “Doppel-Dead-Bug” aufgebaut.
Die Visualisierung wird über 5 LEDs realisiert, wobei die mittlere ~0° grün ist.

Zunächst erstmal ein kurzes Video wie das ganze aussieht

Der Aufbau wurde so minimalistisch wie möglich gehalten, da man bei dieser Art der Verdrahtung spart wo es geht.
Die Schaltung ist daher relativ übersichtlich.

Digitale Wasserwaage Schaltplan

Firmware

Da bei der Darstellung über 5 LEDs der genaue Winkel gar nicht relevant ist, brauchen gar keine Winkelfunktionen verwendet werden. Das Spart RAM und Flash-Speicher und der Programmcode ist sehr übersichtlich:

#include <avr/io.h>
#include <util/delay.h>

#include "i2cmaster.h"

#define MMA8452_ADDR 0x38

void i2c_write_reg(uint8_t addr, uint8_t reg, uint8_t val){

	i2c_start(addr+I2C_WRITE);
	i2c_write(reg);
	i2c_write(val); // Low Noise
	i2c_stop();

}

uint8_t i2c_read_reg(uint8_t addr, uint8_t reg){
	uint8_t val;

	i2c_start(addr+I2C_WRITE);

	i2c_write(reg);	//Status register
	i2c_start(addr+I2C_READ);	//Register 1

	val = i2c_readNak();

	i2c_stop();
	return val;
}

void MMA8452_Act_Stby(uint8_t active_bit){
	uint8_t val;

	val = i2c_read_reg(MMA8452_ADDR, 0x2A);

	if(active_bit)
		val |= 0x01;
	else
		val &= ~0x01;

	i2c_write_reg(MMA8452_ADDR, 0x2A,val);

}

int main(void)
{
	int16_t i=0, last_i, value,abs;
	uint8_t last_tsop_state,tsop_state, val;
	int16_t x,y,z,x1,y1,z1;
	double angle, gk, ak;

	DDRB = (1<<PB2) | (1<<PB1) | (1<<PB0) ;
	DDRD = (1<<PD7) | (1<<PD6);
	i2c_init();

	MMA8452_Act_Stby(0);

 	i2c_write_reg(MMA8452_ADDR, 0x0F, 0x00);

	i2c_write_reg(MMA8452_ADDR, 0x2A, 0x2C);

	i2c_write_reg(MMA8452_ADDR, 0x2B, 0x02);

	MMA8452_Act_Stby(1);

	val = i2c_read_reg(MMA8452_ADDR,0x2A);

	while(1){
		i2c_start(MMA8452_ADDR+I2C_WRITE);
		i2c_write( 0x01);	//Register 1
		i2c_start(MMA8452_ADDR+I2C_READ);	//Register 1

		x = (i2c_readAck()<<8);
		x |= i2c_readNak();
		x >>= 6;

		i2c_stop();

		_delay_ms(5);

		//alle LEDs aus
		PORTB &= ~0x07;
		PORTD &= ~((1<<PD6) | (1<<PD7));

		//LED je nach "Winkel" einschalten
		if(x1 <= -3 && x1 > -10)
 			PORTB |= (1<<PB1);
		if(x1 <= -10)
			PORTB |= (1<<PB2);
		if(x1 < 3 && x1 > -3)
			PORTB |= (1<<PB0);
		if(x1 >= 3 && x1 < 10)
			PORTD |= (1<<PB7);
		if(x1 >=10)
			PORTD |= (1<<PB6);

	}
}
Dieser Beitrag wurde unter Allgemein, Basteleien veröffentlicht. Setze ein Lesezeichen auf den Permalink.

Hinterlasse eine Antwort

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *

*


sieben + 7 =

Du kannst folgende HTML-Tags benutzen: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>