MasterFX
Themenersteller
Ich habe mich am WE mal daran gemacht eine digitale Wasserwaage für meine Kamera zu bauen. Es gab ja schon mehrere Ansätze wie DIESE aber das ist mir dann doch zu groß, zu teuer und zu 
Da ich gerade noch einen Freescale MMA8452Q (12 Bit) Beschleunigungssensor rumliegen hatte, habe ich gleich zum Lötkolben gegriffen.
Bauteile
Der Beschleunigungssensor hat eine Auflösung von 1024 counts/g. Das sollte für diesen Einsatzzweck normalerweise ausreichen.
Preislich tut es sich kaum was, egal ob man nur den 12 Bit (MMA8452Q) oder den mit 14-Bit (MMA8451Q) nimmt. Beide kosten weniger als 2€.
ACHTUNG: Der MMA8450Q arbeitet nur mit 1.8V Versorgungsspannung, der MMA845xQ hingegen mit 1,95-3,6V!
Als Anzeige habe ich mir einfach 5 LEDs im 0603 Gehäuse genommen, weil ich die noch rumliegen habe. Die mittlere LED ist grün die anderen rot.
Auch die Widerstände und Keramikkondensatoren (100nF und 4.7µF) sind 0603.
Tja und dann eben noch den Atmega48/88 da ich davon ebenfalls noch genug rumliegen habe.
Die Stromaufnahme liegt im "ON"-Betrieb bei ~2.2mA. Mit einer CR2032 reicht es also etwa für 90 Stunden Dauerbetrieb.
Da ich gerade keine Lust hatte eine Platine zu entwickeln und ätzen zu lassen, habe ich das ganze mal als "Doppel-Dead-Bug" auf ein kleines Stückchen Lochrasterplatine aufgebaut. Das Ergebnis sieht dann so aus
Die Drähte, die nach Rechts weg gehen, sind für die ISP-Schnittstelle und Stromversorgung.
Nachdem ich das ganze dann aufgebaut habe, habe ich mir dann auch mal den Schaltplan aufgezeichnet
, vielleicht lasse ich ja doch mal eine Platine dafür ätzen und dann habe ich das schonmal.
Ja ich weiß, ich habe nicht alle GNDs und VCCs des Atmegas verbunden, aber glaubt mir bei der Art von Aufbau versucht man zu sparen wo es nur geht
Da zu jedem Zeitpunkt nur eine LED an ist, braucht man auch nur einen Vorwiderstand.
Dass das ganze auch tatsächlich funktioniert kann man in diesem Video sehen: http://www.youtube.com/watch?v=fadT2ODVMbc
Sicherlich ist das ganze noch verbesserungswürdig, aber für den ersten kurzen Test recht annehmbar.
Zugegebenermaßen dürfte diese Art von Freiluftverdrahung nicht jedermanns Sache sein, vorallem nicht das Löten des Beschleunigungssensors mit 0.5mm Pitch, aber mir machts halt Spaß.
Der Quellcode ist nicht sonderlich komplex, da man für diese recht grobe (5-Stellige) Auflösung keine Winkelfunktionen oder so braucht. Da nimmt man einfach direkt den RAW-Wert der X-Achse und schaltet je nach Wertebereich eine andere LED an. Den "grünen" Bereich habe ich bewusst etwas enger gewählt, denn um den geht es ja schließlich. Der grüne Bereich dürfte mit dem 12-Bit Sensor etwa bei Bereich ±0,1° liegen (kann ja mal jemand ausrechnen).
Man könnte natürlich auch einen kleineren AVR nehmen, der Code ist bisher nur 670 Bytes groß. Nur genug Beinchen für die LEDs sollte man haben.
Wie man sieht bilde ich noch nicht mal den Mittelwert, denn bei der Samplerate und aktivem Low Noise Modus auch so sind die Rohdaten recht rauscharm.
Todo

Da ich gerade noch einen Freescale MMA8452Q (12 Bit) Beschleunigungssensor rumliegen hatte, habe ich gleich zum Lötkolben gegriffen.
Bauteile
Der Beschleunigungssensor hat eine Auflösung von 1024 counts/g. Das sollte für diesen Einsatzzweck normalerweise ausreichen.
Preislich tut es sich kaum was, egal ob man nur den 12 Bit (MMA8452Q) oder den mit 14-Bit (MMA8451Q) nimmt. Beide kosten weniger als 2€.
ACHTUNG: Der MMA8450Q arbeitet nur mit 1.8V Versorgungsspannung, der MMA845xQ hingegen mit 1,95-3,6V!
Als Anzeige habe ich mir einfach 5 LEDs im 0603 Gehäuse genommen, weil ich die noch rumliegen habe. Die mittlere LED ist grün die anderen rot.
Auch die Widerstände und Keramikkondensatoren (100nF und 4.7µF) sind 0603.
Tja und dann eben noch den Atmega48/88 da ich davon ebenfalls noch genug rumliegen habe.
Die Stromaufnahme liegt im "ON"-Betrieb bei ~2.2mA. Mit einer CR2032 reicht es also etwa für 90 Stunden Dauerbetrieb.
Da ich gerade keine Lust hatte eine Platine zu entwickeln und ätzen zu lassen, habe ich das ganze mal als "Doppel-Dead-Bug" auf ein kleines Stückchen Lochrasterplatine aufgebaut. Das Ergebnis sieht dann so aus

Die Drähte, die nach Rechts weg gehen, sind für die ISP-Schnittstelle und Stromversorgung.
Nachdem ich das ganze dann aufgebaut habe, habe ich mir dann auch mal den Schaltplan aufgezeichnet


Ja ich weiß, ich habe nicht alle GNDs und VCCs des Atmegas verbunden, aber glaubt mir bei der Art von Aufbau versucht man zu sparen wo es nur geht

Da zu jedem Zeitpunkt nur eine LED an ist, braucht man auch nur einen Vorwiderstand.
Dass das ganze auch tatsächlich funktioniert kann man in diesem Video sehen: http://www.youtube.com/watch?v=fadT2ODVMbc
Sicherlich ist das ganze noch verbesserungswürdig, aber für den ersten kurzen Test recht annehmbar.
Zugegebenermaßen dürfte diese Art von Freiluftverdrahung nicht jedermanns Sache sein, vorallem nicht das Löten des Beschleunigungssensors mit 0.5mm Pitch, aber mir machts halt Spaß.
Der Quellcode ist nicht sonderlich komplex, da man für diese recht grobe (5-Stellige) Auflösung keine Winkelfunktionen oder so braucht. Da nimmt man einfach direkt den RAW-Wert der X-Achse und schaltet je nach Wertebereich eine andere LED an. Den "grünen" Bereich habe ich bewusst etwas enger gewählt, denn um den geht es ja schließlich. Der grüne Bereich dürfte mit dem 12-Bit Sensor etwa bei Bereich ±0,1° liegen (kann ja mal jemand ausrechnen).
Man könnte natürlich auch einen kleineren AVR nehmen, der Code ist bisher nur 670 Bytes groß. Nur genug Beinchen für die LEDs sollte man haben.
Wie man sieht bilde ich noch nicht mal den Mittelwert, denn bei der Samplerate und aktivem Low Noise Modus auch so sind die Rohdaten recht rauscharm.
Code:
#include <avr/io.h>
#include <util/delay.h>
//i2c Master lib von Peter Fleury
#include "i2cmaster.h"
// I2C-Adresse vom MMA8452Q bereits geshiftet für 7 Bit
#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 x; //wir brauchen nur die x-Achse
/* LED Ports auf Ausgang Setzen*/
DDRB = (1<<PB2) | (1<<PB1) | (1<<PB0) ;
DDRD = (1<<PD7) | (1<<PD6);
i2c_init();
/* Beschleunigungssensor in Standby */
MMA8452_Act_Stby(0);
/* ODR = 12.5 Hz + Low-Noise */
i2c_write_reg(MMA8452_ADDR, 0x2A, 0x2C);
/* High Resolution Mode */
i2c_write_reg(MMA8452_ADDR, 0x2B, 0x02);
/* Beschleunigungssensor aktivieren*/
MMA8452_Act_Stby(1);
while(1){
i2c_start(MMA8452_ADDR+I2C_WRITE);
i2c_write( 0x01); //Register 1 => X-Achse
i2c_start(MMA8452_ADDR+I2C_READ);
x = (i2c_readAck()<<8); //MSB lesen
x |= i2c_readNak(); //LSB lesen
x >>= 6; //auf 12 Bit shiften, Vorzeichen bleibt erhalten
i2c_stop();
/* Updaterate ~200 Hz */
_delay_ms(5);
/* alle LEDs aus */
PORTB &= ~0x07;
PORTD &= ~((1<<PD6) | (1<<PD7));
/* Je nach Bereich LED einschalten */
if(x <= -3 && x > -10)
PORTB |= (1<<PB1);
if(x <= -10)
PORTB |= (1<<PB2);
if(x < 3 && x > -3)
PORTB |= (1<<PB0);
if(x >= 3 && x < 10)
PORTD |= (1<<PB7);
if(x >=10)
PORTD |= (1<<PB6);
}
}
Todo
- Taster für Ein/Aus/Kalibrierung fehlt noch
- Auto-Off bei Nicht-Benutzung
- Passendes Gehäuse für Blitzschuh welches auch eine CR2032 fasst (ggf. auch CR1620)
- "Richtiges" PCB (vielleicht, falls Interesse besteht)
Zuletzt bearbeitet: