Gast_79791
Gast
Oxymoron war schneller
Was ist ein 4,8V Block ??? NIMH ???? wenn ja sind es im Vollen zustand 5,72V
DAs bedeutet an VIN / RAW.
Ich habe nun alle Teile (hoffentlich) von Aliexpress bekommen.
Hat evtl jemand eine Beschreibung wie alles miteinander verlötet/verbunden wird?
Hardware: ADXL 345, LCD 1602 with I2C interface, ARDUINO pro mini
Wiring: ADXL 345 and LCD 1602 with I2C -> Arduino SDA and SCL
Buttons to Arduino D2, D3, D4 and D5
D2 - zero setting
D3, D4 - up and down depth value
D5 - write chord to eeprom
See https://www.arduino.cc/en/tutorial/button for wiring circuit
Added chord depth save to eeprom! LED on 13 BLINK 500ms
/*
STATUS OK
Version */
int ino_version = 5;
long ino_date = 171007;
/*
Kompiliert unter Arduino 1.8.3
1. Unter Verwendung der mit Arduino 1.8.3 mitglieferten libraries:
Wire
...\arduino-1.8.3\hardware\arduino\avr\libraries\Wire\src\Wire.cpp
...\arduino-1.8.3\hardware\arduino\avr\libraries\Wire\src\Wire.h
LiquidCrystal:
...\arduino-1.8.3\libraries\LiquidCrystal\src\LiquidCrystal.cpp
...\arduino-1.8.3\libraries\LiquidCrystal\src\LiquidCrystal.h
2. Zusaetzliche Libraries (https://www.i2cdevlib.com) im
libraries Verzeichnis innerhalb des Sketch Verzeichnis:
ADXL345
...\ARDUINO_SKETCHES\libraries\ADXL345\
...\ARDUINO_SKETCHES\libraries\ADXL345\ADXL345.cpp
...\ARDUINO_SKETCHES\libraries\ADXL345\ADXL345.h
I2Cdev
...\ARDUINO_SKETCHES\libraries\I2Cdev\
...\ARDUINO_SKETCHES\libraries\I2Cdev\I2Cdev.cpp
...\ARDUINO_SKETCHES\libraries\I2Cdev\I2Cdev.h
3. Verwendete Hardware, die bei mir funktioniert
3.1 LCD KeypadShield
3.2 Arduino UNO R3
3.3 ADXL345 BreakoutBoard, GY-291
-Fixes: Help Screen kommt nun zuverlaessiger, switch/case statt if/else
-Fixes: SerialDebug Schnittstelle, Ausgabe "Initialize Serial Port..." wird nun ausgegeben
-Verbesserung: Button RIGHT zeigt HELP Screen an
-Verbesserung: Ausgabe der Version und Datum
-Erweitert: Wert CHORD wird mit Button SELECT im EEPROM gespeichert
-Maximalwert CHORD 999mm begrenzt
-Ausgabe der Prefixe ANG und THR reduzuiert, damit konfigurierter Wert CHRORD angezeigt werden kann
-Sensor2 (rechter Sensor): Orientierung angepasst, Sensor um 180Grad gegenüber Sensor1 gedreht eingesetzt wird
-Code Review, Vereinfachung der Programmstruktur, LCD Ausgabe und Aktion in einem switch/case/.../default vereint
*/
/*******************************************************************************************/
// fuer den Betrieb von zwei ADXL Sensoren an einem Arduino eignet sich diese Library, zusammen mit I2Cdev
// https://www.i2cdevlib.com
// https://www.i2cdevlib.com/usage
// Arduino Wire library is required if I2Cdev I2CDEV_ARDUINO_WIRE implementation
// is used in I2Cdev.h
#include <Wire.h>
// https://www.i2cdevlib.com/usage
// I2Cdev and ADXL345 must be installed as libraries, or else the .cpp/.h files
// for both classes must be in the include path of your project
#include <ADXL345.h>
ADXL345 adxl1(0x53); // Default I2C Adresse, mit Pin SDO nicht beschaltet, interner PullDown
ADXL345 adxl2(0x1D); // Zweite I2C Adresse, mit Pin SDO an VCC
/*******************************************************************************************/
//Fuer das LCD KeyPad-Shield
#include <LiquidCrystal.h> // für das LCD
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
/*******************************************************************************************/
//Fuer das speichern von Werten
#include <EEPROM.h>
/*******************************************************************************************/
// define some address to write data
int addr = 0;
/*******************************************************************************************/
// define some values used by the LCD panel and KeypadShield buttons
int lcd_key = 0;
int adc_key_in = 0;
/*******************************************************************************************/
int toggle = LOW; // variable for toggling between THROW and SECANT
int chord; // chord depth [mm]
/*******************************************************************************************/
boolean serialDebug = true; // usefull using adruino uno, does not work on other arduino boards
/************************************ DEFINED VARIABLES ************************************/
// define some values used by angle calculation
int x1, y1, z1; // raw values from sensor (-255 ... 0 ... +255)
int x2, y2, z2; // raw values from sensor (-255 ... 0 ... +255)
int angle1;
int angle2;
int throw1;
int throw2;
int secant1;
int secant2;
int up1; // 1 -> up, 2 -> down
int up2; // 1 -> up, 2 -> down
int relative1; // for zeroing
int relative2; // for zeroing
float rad1;
float rad2;
float x1g, y1g, z1g; // g values
float x2g, y2g, z2g; // g values
float calc1;
float tilt1;
float calc2;
float tilt2;
/************************************ SENSORCALIBRATION ************************************/
#define offsetX1 0 // OFFSET values
#define offsetY1 0 // replace "0" with calculated value after sensor calibration
#define offsetZ1 0
#define offsetX2 0 // OFFSET values
#define offsetY2 0 // replace "0" with calculated value after sensor calibration
#define offsetZ2 0
#define gainX1 1 // GAIN factors
#define gainY1 1 // replace "1" with calculated value after sensor calibration
#define gainZ1 1
#define gainX2 1 // GAIN factors
#define gainY2 1 // replace "1" with calculated value after sensor calibration
#define gainZ2 1
/************************************ DEFINED CONSTANTS ************************************/
#define btnRIGHT 0
#define btnUP 1
#define btnDOWN 2
#define btnLEFT 3
#define btnSELECT 4
#define btnNONE 5
/************************************ Grapics for display **********************************/
uint8_t degree[8] = {140, 146, 146, 140, 128, 128, 128, 128}; // °
uint8_t arrowup[8] = {132, 142, 132, 132, 132, 128, 128, 128}; // Arrow up
uint8_t arrowdown[8] = {128, 128, 128, 132, 132, 132, 142, 132,}; // Arrow down
/*******************************************************************************************/
/************************************ DEFINED FUNCTIONS ************************************/
/*******************************************************************************************/
int read_LCD_buttonsFunction()
{
adc_key_in = analogRead(0); // read the value from the sensor / KeypadShield
// the values depends on KeypadShield, use
if (adc_key_in > 1000) return btnNONE;
if (adc_key_in < 50) return btnRIGHT;
if (adc_key_in < 150) return btnUP;
if (adc_key_in < 300) return btnDOWN ;
if (adc_key_in < 500) return btnLEFT;
if (adc_key_in < 700) return btnSELECT;
return btnNONE;
}
void show_UsageFunction(boolean los)
{
switch (los) {
case true:
{
lcd.home ();
lcd.print("RC - METER ");
lcd.setCursor (0, 1);
lcd.print("ANGLE AND THROW ");
delay(3000);
lcd.clear ();
lcd.print("RC - METER");
lcd.setCursor (0, 1);
lcd.print(" >> OR <<");
delay(1500);
lcd.clear ();
lcd.print("RC - METER");
lcd.setCursor (0, 1);
lcd.print("ANGLE AND SECANT");
delay(3000);
lcd.clear ();
lcd.print("to ZERO, press:");
lcd.setCursor (0, 1);
lcd.print("Key SELECT");
delay(3000);
lcd.clear ();
lcd.print("set CORD depth..");
delay(1500);
lcd.setCursor (0, 0);
lcd.print(".in [mm], press:");
lcd.setCursor (0, 1);
lcd.print("Key UP or DOWN");
delay(3000);
lcd.clear ();
lcd.print("choose THROW or.");
delay(1500);
lcd.setCursor (0, 0);
lcd.print("..SECANT, press:");
lcd.setCursor (0, 1);
lcd.print("Key LEFT");
delay(3000);
lcd.clear ();
lcd.print("to RESET, press:");
lcd.setCursor (0, 1);
lcd.print("Key RST");
delay(3000);
lcd.clear ();
lcd.print("for HELP screen");
lcd.setCursor (0, 1);
lcd.print("press: Key RIGHT");
delay(3000);
lcd.clear ();
lcd.print("Version: ");
lcd.print(ino_version);
lcd.setCursor (0, 1);
lcd.print("Date: ");
lcd.print(ino_date);
delay(3000);
}
break;
default:
{
lcd.home ();
lcd.print("RC - METER ");
lcd.setCursor (0, 1);
lcd.print("ANGLE AND THROW ");
delay(3000);
lcd.clear ();
lcd.print("for HELP screen");
lcd.setCursor (0, 1);
lcd.print("press: Key RIGHT");
delay(3000);
}
break;
}
}
/*******************************************************************************************/
/************************************** FUNCTION SETUP *************************************/
/*******************************************************************************************/
void setup() {
// https://www.i2cdevlib.com/usage
// join I2C bus (I2Cdev library doesn't do this automatically)
Wire.begin();
// power on , initialize acceleration sensors
adxl1.initialize();
adxl2.initialize();
// power on LCD
lcd.begin (16, 2); // for 16 x 2 LCD module
lcd.createChar(0, degree);
lcd.createChar(1, arrowup);
lcd.createChar(2, arrowdown);
/*******************************************************************************************/
// START SCREEN
/*******************************************************************************************/
show_UsageFunction(false);
/********************** Restore value of CHORD from last save ********************************/
chord = EEPROM.read(addr);
/********************** DEBUG output to serial port monitor **********************************/
if (serialDebug) {
while (!Serial) {
; // wait for serial port to connect. Needed for native USB
}
Serial.begin(9600);
Serial.print("Initialize Serial Port...");
delay(1000);
Serial.println("OK");
delay(1000);
};
}
/*******************************************************************************************/
/**************************************** FUNCTION MAIN LOOP *******************************/
/*******************************************************************************************/
void loop() {
adxl1.getAcceleration(&x1, &y1, &z1); // read the accelerometer values and store them in variables
x1g = 0.00385 * (x1 - offsetX1) / gainX1; // 0.00385 to convert the raw data to Gs
y1g = 0.00385 * (y1 - offsetY1) / gainY1; // offset and gain for calibration
z1g = 0.00385 * (z1 - offsetZ1) / gainZ1;
adxl2.getAcceleration(&x2, &y2, &z2); // read the accelerometer values and store them in variables
x2g = 0.00385 * (x2 - offsetX2) / gainX2; // 0.00385 to convert the raw data to Gs
y2g = 0.00385 * (y2 - offsetY2) / gainY2; // offset and gain for calibration
z2g = 0.00385 * (z2 - offsetZ2) / gainZ2;
calc1 = x1g / sqrt ((sq(y1g) + sq(z1g))); //sensor orientation!
tilt1 = atan(calc1) * 57.296;
angle1 = int(tilt1); //sensor orientation!
calc2 = x2g / sqrt ((sq(y2g) + sq(z2g))); //sensor orientation!
tilt2 = atan(calc2) * 57.296;
angle2 = int(tilt2) * -1; //sensor orientation! "* -1" because 180degrees rotated compared to sensor 1
if ((angle1 - relative1) > 0) {
up1 = 1; //arrow ↑↑↑
}
else {
up1 = 2; //arrow ↓↓↓
}
if ((angle2 - relative2) > 0) {
up2 = 1; //arrow ↑↑↑
}
else {
up2 = 2; //arrow ↓↓↓
}
/*******************************************************************************************/
rad1 = abs(angle1 - relative1) * 0.017453;
rad2 = abs(angle2 - relative2) * 0.017453;
throw1 = int(chord * sin(rad1));
throw2 = int(chord * sin(rad2));
secant1 = int(2 * chord * sin(rad1 / 2));
secant2 = int(2 * chord * sin(rad2 / 2));
/*******************************************************************************************/
lcd_key = read_LCD_buttonsFunction();
switch (lcd_key) // depending on which button was pushed, we perform an action
{
case btnSELECT:
{
relative1 = angle1;
relative2 = angle2;
EEPROM.update(addr, chord);
lcd.clear();
lcd.setCursor (0, 0); // go to start of 2nd line
lcd.print("zeroized...");
lcd.setCursor (0, 1); // go to start of 2nd line
lcd.print("CHORD saved...");
if (serialDebug) {Serial.println(lcd_key);} else {}
break;
}
case btnLEFT:
{
lcd.clear();
lcd.setCursor (0, 0); // go to start of 2nd line
if (toggle == HIGH) {
toggle = LOW;
lcd.print("TRHOW...");
if (serialDebug) {Serial.print(lcd_key); Serial.print(" THROW "); Serial.println(toggle); } else {}
}
else {
toggle = HIGH;
lcd.print("SECANT...");
if (serialDebug) {Serial.print(lcd_key); Serial.print(" SECANT "); Serial.println(toggle); } else {}
}
delay (300);
break;
}
case btnUP: {
if (chord < 999) {
chord = chord + 1;
}
else{}
lcd.clear();
lcd.setCursor (0, 0); // go to start of 1st line
lcd.print("CHORD DEPTH:");
lcd.setCursor (0, 1); // go to start of 2nd line
lcd.print(chord); lcd.print(" mm");
if (serialDebug) {Serial.print(lcd_key); Serial.print(" CHORD DEPTH:"); Serial.print(chord); Serial.println("mm");} else {}
break;
}
case btnDOWN: {
if (chord > 1) {
chord = chord - 1;
}
else{}
lcd.clear();
lcd.setCursor (0, 0); // go to start of 1st line
lcd.print("CHORD DEPTH:");
lcd.setCursor (0, 1); // go to start of 2nd line
lcd.print(chord); lcd.print(" mm");
if (serialDebug) { Serial.print(lcd_key); Serial.print(" CHORD DEPTH:"); Serial.print(chord); Serial.println("mm"); } else {}
break;
}
case btnRIGHT:
{
if (serialDebug) {Serial.println(lcd_key);} else {}
show_UsageFunction(true);
break;
}
default:
{
lcd.clear();
lcd.setCursor (0, 0); // go to start of 1st line
lcd.print("A:");
lcd.setCursor (2, 0);
if ((angle1 - relative1) == 0) {
lcd.print("0");
lcd.setCursor (14, 0);
lcd.write(byte(0));
}
else {
lcd.print(abs(angle1 - relative1)); lcd.write(byte(up1));
lcd.setCursor (14, 0);
lcd.write(byte(0));
}
lcd.setCursor (6, 0);
if ((angle2 - relative2) == 0) {
lcd.print("0");
lcd.setCursor (14, 0);
lcd.write(byte(0));
}
else {
lcd.print(abs(angle2 - relative2)); lcd.write(byte(up2));
lcd.setCursor (14, 0);
lcd.write(byte(0));
}
lcd.setCursor (0, 1); // go to start of 2nd line
if (toggle == HIGH) {
lcd.print("S:");
lcd.setCursor (9, 1);
lcd.print("("); lcd.print(chord); lcd.print(")");
lcd.setCursor (14, 1);
lcd.print("mm");
lcd.setCursor (2, 1);
if ((secant1) == 0) {
lcd.print("0");
}
else {
lcd.print(secant1);
}
lcd.setCursor (6, 1);
if ((secant2) == 0) {
lcd.print("0");
}
else {
lcd.print(secant2);
}
}
else {
lcd.print("T:");
lcd.setCursor (9, 1);
lcd.print("("); lcd.print(chord); lcd.print(")");
lcd.setCursor (14, 1);
lcd.print("mm");
lcd.setCursor (2, 1);
if ((throw1) == 0) {
lcd.print("0");
}
else {
lcd.print(throw1);
}
lcd.setCursor (6, 1);
if ((throw2) == 0) {
lcd.print("0");
}
else {
lcd.print(throw2);
}
}
if (serialDebug) {Serial.println(lcd_key);} else {}
break;
}
}
delay(300);
}
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("\nI2C Scanner");
}
void loop()
{
byte error, address;
int nDevices;
Serial.println("Scanning...");
nDevices = 0;
for(address = 1; address < 127; address++ )
{
// The i2c_scanner uses the return value of
// the Write.endTransmisstion to see if
// a device did acknowledge to the address.
Wire.beginTransmission(address);
error = Wire.endTransmission();
if (error == 0)
{
Serial.print("I2C device found at address 0x");
if (address<16)
Serial.print("0");
Serial.print(address,HEX);
Serial.println(" !");
nDevices++;
}
else if (error==4)
{
Serial.print("Unknown error at address 0x");
if (address<16)
Serial.print("0");
Serial.println(address,HEX);
}
}
if (nDevices == 0)
Serial.println("No I2C devices found\n");
else
Serial.println("done\n");
delay(5000); // wait 5 seconds for next scan
}
ADXL345 adxl1([B]0x53[/B]); // Default I2C Adresse, mit Pin SDO nicht beschaltet, interner PullDown
ADXL345 adxl2([B]0x1D[/B]); // Zweite I2C Adresse, mit Pin SDO an VCC