Digitale Wasserwaage: ADXL345, TFT (HY-1.8 SPI) und ein Arduino

Mithilfe eines Beschleunigungssensors, welcher aufgrund seiner Eigenschaften sich die Gravitation zu nutze zu machen, auch als Lagesensor verwendet werden kann, simulieren wir heute eine Wasserwaage. Dazu verwenden wir einen ADXL345, einen Arduino Nano ein TFT-Display (HY-1.8 SPI) und ein paar weitere Teile.

Digitale Wasserwaage: ADXL345, TFT (HY-1.8 SPI) und ein Arduino

Digitale Wasserwaage: ADXL345, TFT (HY-1.8 SPI) und ein Arduino

Schaltplan (Verdrahtung):

Schaltplangröße:

1afbgchdie1j5510101515202025253030353540404545505055556060afbgchdiej1.8 SPI TFT 128*160HY-1.8 SPI-+-+5V OFF 3.35V OFF 3.3
Für weitere Informationen (z.B. Pinbelegungen von Bauteilen oder genaue Kabelverbindungen)
mit der Maus über Elemente fahren (oder im Touch-Modus: Elemente antippen)...

Arduino
(NanoUno, Pro Mini)
ADXL345-Breakoutboard TFT-Display
HY-1.8 SPI
Spannungsquelle 5V
(z.B. Breadboard Power Supply)
5V (VCC)
Nur wenn USB-Kabel nicht verbunden!
VCC VCC, LED+ VCC VCC 5V
GND GND GND, LED- GND GND
A4 (SDA) SDA
A5 (SCL) SCL
D9 A0
D10 CS
D11 SDA
D13 SCK
D8 RESET

Achtung, es gibt diverse ADXL345-Breakoutboards wovon einige keinen Spannungsregler haben und welche deshalb mit 3,3V betrieben werden müssen, auf diese wird hier nicht eingegangen!

Ansonsten kann natürlich jedes andere ADXL345-Breakoutboard verwendet werden, jedoch muss dann natürlich die Verdrahtung angepasst werden.

Zusätzlich wird noch ein Taster (der Widerstand an Masse ist 10kOhm) benötigt,  welcher dazu dient die Wasserwaage zu Eichen. Dazu wird der ganze Aufbau auf den Boden oder eine sich in Waage befindliche Oberfläche gelegt und der Taster kurz gedrückt.

Programmcode (Sketch):

Zuerst benötigen wir noch eine ADXL345-Bibliothek und 2 Bibliotheken zur Ansteuerung des Displays. Dies wäre einerseits die Adafruit-Bibliothek zur Ansteuerung des Display-Chipsatzes (ST7735) und dann eine Grafik-Bibliothek ebenfalls von Adafruit. Nun laden wir noch folgenden Sketch auf den Arduino:

#include <Wire.h>
#include <ADXL345.h>

#define cs   10 // Arduino-Pin an Display CS   
#define dc   9  // Arduino-Pin an Display A0
#define rst  8  // Arduino Reset-Pin

#include "Adafruit_GFX.h"    // Adafruit Grafik-Bibliothek
#include "Adafruit_ST7735.h" // Adafruit ST7735-Bibliothek
#include <SPI.h>

Adafruit_ST7735 tft = Adafruit_ST7735(cs, dc, rst);  // Display-Bibliothek Setup


ADXL345 accel;

#define button_correction 3

void setup(void){

	Serial.begin(9600);

	pinMode(button_correction, INPUT);

	// Sensor
	accel.begin();				// Sensor initialisieren
	accel.setRange(accel.RANGE_16G);	// Empfindlichkeit einstellen
  
	// Display
	tft.initR(INITR_BLACKTAB);    // ST7735-Chip initialisieren
	tft.setTextWrap(true); 
  
	display_show();
}

const float alpha = 0.5;
double fXg = 0;
double fYg = 0;
double fZg = 0;

double x_correction=0;
double y_correction=0;

int x_value=0;
int y_value=0;
int old_x_value=1;
int old_y_value=1;

#define filter_count_max 40
byte filter_count=0;

#define correction_precision 300  // Sollte Anzeige im Liegen wackeln Wert vermindern

void loop(void){
 
	double pitch, roll, Xg, Yg, Zg;
	accel.read(&Xg, &Yg, &Zg);
	
	fXg+=Xg;
	fYg+=Yg;
	filter_count++;
	
	if(filter_count==filter_count_max-1){
	
		fXg/=filter_count_max;
		fYg/=filter_count_max;

		if(digitalRead(button_correction)==HIGH){
			x_correction=fXg; 
			y_correction=fYg;
		}
		
		x_value=(fXg-x_correction)*correction_precision;
		y_value=(fYg-y_correction)*correction_precision;

		//display_info();
		display_graphic();
		
		old_x_value=x_value;
		old_y_value=y_value;
		
		fXg=0;
		fYg=0;
		filter_count=0;
	}
	
	delay(5);

}

#define hx 27
#define hy 16
#define hw 95
#define hh 18
#define hb 7

#define vx 5
#define vy 38
#define vw 18
#define vh 95
#define vb 7

#define cx 75
#define cy 86
#define cr 45
#define cb 5

void display_show(){

	tft.fillScreen(ST7735_BLACK); 
  
	set_text(32,3,"Wasserwaage",ST7735_BLUE,1);  
	set_text(14,149,"blog.simtronyx.de",ST7735_GREEN,1);
  
	tft.drawRect(hx-1,hy-1,hw+2,hh+2,rgb565(128,128,128));
	tft.drawRect(hx+1,hy+1,hw-2,hh-2,rgb565(128,128,128));
	tft.drawRect(hx,hy,hw,hh,ST7735_WHITE);
  
	tft.drawRect(vx-1,vy-1,vw+2,vh+2,rgb565(128,128,128));
	tft.drawRect(vx+1,vy+1,vw-2,vh-2,rgb565(128,128,128));
	tft.drawRect(vx,vy,vw,vh,ST7735_WHITE);
  
	tft.drawCircle(cx,cy,cr+1,rgb565(128,128,128));
	tft.drawCircle(cx,cy,cr-1,rgb565(128,128,128));
	tft.drawCircle(cx,cy,cr,ST7735_WHITE);
}

void display_graphic(){
	
	if(x_value!=old_x_value){
		
		tft.drawRect(hx+hw/2+constrain(old_x_value,-hw/2+(hb+1)/2,hw/2-(hb+1)/2)-(hb-1)/2,hy+2,hb,hh-4,rgb565(0,0,0));
		tft.drawRect(hx+hw/2,hy+2,1,hh-4,rgb565(255,255,255));
		tft.drawRect(hx+hw/2+constrain(x_value,-hw/2+(hb+1)/2,hw/2-(hb+1)/2)-(hb-1)/2,hy+2,hb,hh-4,rgb565(0+constrain(abs(x_value)*10,0,255),255-constrain(abs(x_value)*10,0,255),0));
	}
    if(y_value!=old_y_value){
		
		tft.drawRect(vx+2,vy+vh/2-(constrain(old_y_value,-vh/2+(vb+1)/2,vh/2-(vb+1)/2)+(vb-1)/2),vw-4,vb,rgb565(0,0,0));
		tft.drawRect(vx+2,vy+vh/2,vw-4,1,rgb565(255,255,255));
		tft.drawRect(vx+2,vy+vh/2-(constrain(y_value,-vh/2+(vb+1)/2,vh/2-(vb+1)/2)+(vb-1)/2),vw-4,vb,rgb565(0+constrain(abs(y_value)*10,0,255),255-constrain(abs(y_value)*10,0,255),0));
	}
	if((x_value!=old_x_value)||(y_value!=old_y_value)){

		float hxv=old_x_value;
		float hyv=old_y_value;
		float l=sqrt(hxv*hxv+hyv*hyv);
		if(l>cr-cb-2){
			hxv=hxv/l*(cr-cb-2);
			hyv=hyv/l*(cr-cb-2);
		}
		
		tft.fillCircle(cx+hxv,cy-hyv,cb,rgb565(0,0,0));
		tft.drawCircle(cx,cy,cb+2,rgb565(255,255,255));
		
		hxv=x_value;
		hyv=y_value;
		l=sqrt(hxv*hxv+hyv*hyv);
		if(l>cr-cb-2){
			hxv=hxv/l*(cr-cb-2);
			hyv=hyv/l*(cr-cb-2);
		}
		tft.fillCircle(cx+hxv,cy-hyv,cb,rgb565(0+constrain((((abs(x_value)+abs(y_value))/2)*10),0,255),255-constrain((((abs(x_value)+abs(y_value))/2)*10),0,255),0));
	}
}

void display_info(){
	   
	if(x_value!=old_x_value){
	
		set_text(4,16,value_to_string(old_x_value),ST7735_BLACK,1);
		set_text(4,16,value_to_string(x_value),ST7735_WHITE,1);
	}
	
    if(y_value!=old_y_value){
	  
		set_text(4,26,value_to_string(old_y_value),ST7735_BLACK,1);
		set_text(4,26,value_to_string(y_value),ST7735_WHITE,1);
	}
}


void set_text(int x,int y,String text,int color,int size){
  
	tft.setTextSize(size);
	tft.setCursor(x,y);
	tft.setTextColor(color);
	tft.print(text);
}

// Hilfsfunktionen
uint16_t rgb565(uint8_t r, uint8_t g, uint8_t b){

	return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3);
}

String value_to_string(int value){
  
	String value_string = String(value);
	return value_string;
}

Download Source Code

und schon ist die Wasserwaage einsatzbereit.

Bauteile (Bezugsquellen):

eBay: 1.8 Zoll TFT SPI Display
ADXL345
Breadboard
Breadboard Kabel
Breadboard Power Modul
Taster
Widerstand 10k
Amazon: 1.8 Zoll TFT SPI Display
ADXL345
Breadboard
Breadboard Kabel
Breadboard Power Modul
Taster
Widerstand 10k

Gut?

Facebooktwittergoogle_plusredditpinterestlinkedinmailFacebooktwittergoogle_plusredditpinterestlinkedinmail