Ruderweg Messung mit Arduino

Ich habe versucht aus zu finden wie Genau es jetzt ist.
Weil ich f3b fliege, sollte die Einstellungen ziemlich genau sein.
Zufallig hatte ich auch gefraste Teilen zu verfugung
Das display habe ein klein bischen angepasst. (als Newbie in Arduino geht das noch ;-) )
Ich brauche nur "Throw" und um es mehr deutlicher zu machen habe ich es Li und Re genennt.
Die kalkulation ist nicht geandert.

Ich habe ein paar fragen.
Wenn ich die UNO auf "zero" drucke und warte ruhig ab dann ist es nicht 100% stabiel.
Ich kann nicht programmieren aber kann mann das nicht weg "filtern" oder so?
Ich kann mich vorstellen das 20 Messungen gemacht werden und davon die Durchschnitt berechnet wird?

Ander Frage:
Wenn ich die sensoren auf "Zero" einstellen und ich bewege die Sensoren nach eine Seite dann ist dass Ergebnis nicht schlecht.
Bewege ich die Sensoren nach die andere Seite dann ist dass unterschied schon 3 mm.
Bewege ich die sensoren nach ein bestimmte Winkel wird das unterschied noch viel grosser. (und dann ist es fur mich leider nicht nutzbar).
Veilleicht tu ich etwas falsch.
Hat das doch zu tun mit "Abgleichen" ?


Gruss

Jeroen
 

Eckehard

User
Hallo....

ich habe gerade es einmal mit meinem RC-Meter probiert, kann es aber nicht nachvollziehen....

Daher nun folgender Vorschag:
Stell Deine Version des ino Files hier zur Verfügung, dann lad ich den Sketch auf meine Hardware..... und dann wissen wir vielleicht etwas mehr.....

Müde Grüße
Eckehard
 

kalle123

User
Weil ich f3b fliege, sollte die Einstellungen ziemlich genau sein.

Jeroen, ich hatte im thread cg-scale hier im Forum schon mal danach gefragt und von Tobias diese Antwort erhalten.

uyZdcPkl.png


Das wird ja anscheinend unterschiedlich gesehen ;)

Mir reicht 1° Genauigkeit und die hab ich hier. Mache vielleicht noch mal ein Video vom Verhalten zweier ADXL345 hier.

Gruß KH
 

Eckehard

User
Hallo,

Kalle schrieb:
Mir reicht 1° Genauigkeit und die hab ich hier. Mache vielleicht noch mal ein Video vom Verhalten zweier ADXL345 hier.

Jeroen schrieb:
Bewege ich die Sensoren nach die andere Seite dann ist dass unterschied schon 3 mm.

Ihr sprecht also von Unterschieden einmal vom Winkel (Kalle) und dann vom Ausschlag (Jeroen), oder?

Nunja... es kommt auf die Klappentiefe an.....

Bei sehr großen Klappentiefen führen klitzekleine Unterschiede im Winkel zu großen Unterschieden im Ausschlag.....

Grüße
Eckehard
 
Kalle hat geschrieben
Das wird ja anscheinend unterschiedlich gesehen
Ich habe ein Ruderbrete von 56 mm, dass heisst 1 grad => 1 mm unterschied.
Ist fur mich schon an die Grenze. (speedstellung ist oft nur 1 mm).

Tobias hat recht beim Hoheleitwerk aber fur die Flachen habe ich ein andere Meinung ;-)


Kalle, ich mochte gerne auch deine varianten bauen zu vergleich aber findet nicht richtige Zeichnung. Kannst du sagen wo ich die finden kann?
(ich habe etwas gefunden aber wenn ich die Bilder anschaue sehe ich mehr wiederstanden)

Schon Danke.


PS https://www.rcgroups.com/forums/showthread.php?3025585-Aaro-s-inclinometer
"accuracy shall not be worse than 0.1 degrees (stabile reading, no jumping, repeatable results)"
mmm das deutsche Program sollte doch besser sein ;-)
 

kalle123

User
Kalle, ich mochte gerne auch deine varianten bauen zu vergleich aber findet nicht richtige Zeichnung. Kannst du sagen wo ich die finden kann?
(ich habe etwas gefunden aber wenn ich die Bilder anschaue sehe ich mehr wiederstanden)


PS https://www.rcgroups.com/forums/showthread.php?3025585-Aaro-s-inclinometer
"accuracy shall not be worse than 0.1 degrees (stabile reading, no jumping, repeatable results)"
mmm das deutsche Program sollte doch besser sein ;-)

Hallo Jeroen.

Erst mal dank dir für den Link aus rcgroups. Interessant das mit den Wäscheklammern ;)

Aaro sagt ja nicht viel zur verwendeten Elektronik, ich nehme mal an Arduino und ADXL 345.

Er redet da von 1/10°. NUR, dann musst du auch die Servos, Anlenkung usw. haben, die diese Präzision haben.

Das hab ich hier nicht, daher reichen mir 1°.

Ich glaube nicht, das es lohnt, meine Version nach zubauen. Vom Rechenansatz unterscheidet die sich wohl nicht von Eckehards. Also mach besser mit der Version Eckehard weiter. Da wird kein Unterschied sein. Und wegen Auflösung und Filterung -> Eckehard.

Ich muss jetzt mal hier ran.

MYzfretl.png


Das ist eine Frequenzanzeige bis 5 MHz, die ich mit dem RPM Sensor bisher genommen hab, um die Drehzahl von BL-Motoren zu bestimmen. Aber da müssen jetzt schnell ein paar Taster dran und das Programm muss umgeschrieben werden. Bin es leid, jedesmal zu rechnen :cool:

Gruß KH
 
hallo Kalle,

Ich denk das meine Servo's, anlenkungen usw nicht ganz schlecht sein ;-)

Wann ich deine Variante baue mit nur eine 345 dann kann ich die abgleichen (und ja nicht kalibrieren ;-) ) und sehen ob es besser wird.

Wahrschein habe ich die Teile noch irgend wo liegen.

Gruss,


PS Aaron sagt nicht wie er dass gemacht hatte weil er wahrscheinlich die verkaufen mochte.
 

Eckehard

User
Hallo Kalle, Jeroens

Ich glaube nicht, das es lohnt, meine Version nach zubauen. Vom Rechenansatz unterscheidet die sich wohl nicht von Eckehards. Also mach besser mit der Version Eckehard weiter. Da wird kein Unterschied sein.
Korrekt, meine Version basiert ja auf Deinen/Kalle s Anregungen zu diesem Projekt....

Und wegen Auflösung und Filterung -> Eckehard.
Hierzu habe ich eine ganz klare Meinung:

Eine Erweiterung werde ich aktuell nicht machen. Meine Erwartungen sind erfüllt. Es gibt andere, interessantere Projekte.

Anregungen zu Erweiterungen (besonders die Bedienung) kann man sich aus dem verlinkten youtube Video holen.... wirklich toll gemacht!

Grüße
Eckehard
 

kalle123

User
Warte mal ab, was Eckehard sagt. Ich bin mir recht sicher, das zwischen seinem und meinem Programm kein Unterschied in der Berechnung ist.

Zum Abgleich: Schließe einfach direkt den abzugleichenden ADXL345 an den Uno an.

Pack das sketch hier auf den Uno

// Refer to SparkFun ADXL345 Hook Up Guide: https://learn.sparkfun.com/tutorials/adxl345-hookup-guide

#include <SparkFun_ADXL345.h>

/*********** COMMUNICATION SELECTION ***********/
/* Comment Out The One You Are Not Using */
//ADXL345 adxl = ADXL345(10); // Use when you want to use Hardware SPI, ADXL345(CS_PIN);
ADXL345 adxl = ADXL345(); // Use when you need I2C

/****************** VARIABLES ******************/
/* */
int AccelMinX = 0;
int AccelMaxX = 0;
int AccelMinY = 0;
int AccelMaxY = 0;
int AccelMinZ = 0;
int AccelMaxZ = 0;

int accX = 0;
int accY = 0;
int accZ = 0;

int pitch = 0;
int roll = 0;

/************** DEFINED VARIABLES **************/
/* */
#define offsetX 0 // OFFSET values
#define offsetY 0
#define offsetZ 0

#define gainX 1 // GAIN factors
#define gainY 1
#define gainZ 1

/******************** SETUP ********************/
/* Configure ADXL345 Settings */
void setup()
{
Serial.begin(9600); // Start the serial terminal
Serial.println("SparkFun ADXL345 Accelerometer Breakout Calibration");
Serial.println();

adxl.powerOn(); // Power on the ADXL345

adxl.setRangeSetting(2); // Give the range settings
// Accepted values are 2g, 4g, 8g or 16g
// Higher Values = Wider Measurement Range
// Lower Values = Greater Sensitivity

adxl.setSpiBit(0); // Configure the device to be in 4 wire SPI mode when set to '0' or 3 wire SPI mode when set to 1
// It is set to 1 by Default.
// SPI pins on the ATMega328 as reference in SPI Library are 11, 12, and 13

}

/****************** MAIN CODE ******************/
/* Accelerometer Readings and Min/Max Values */
void loop()
{
Serial.println("Send any character to display values.");
while (!Serial.available()){} // Waiting for character to be sent to Serial
Serial.println();

// Get the Accelerometer Readings
int x,y,z; // init variables hold results
adxl.readAccel(&x, &y, &z); // Read the accelerometer values and store them in variables declared above x,y,z

if(x < AccelMinX) AccelMinX = x;
if(x > AccelMaxX) AccelMaxX = x;

if(y < AccelMinY) AccelMinY = y;
if(y > AccelMaxY) AccelMaxY = y;

if(z < AccelMinZ) AccelMinZ = z;
if(z > AccelMaxZ) AccelMaxZ = z;

Serial.print("Accel Minimums: "); Serial.print(AccelMinX); Serial.print(" ");Serial.print(AccelMinY); Serial.print(" "); Serial.print(AccelMinZ); Serial.println();
Serial.print("Accel Maximums: "); Serial.print(AccelMaxX); Serial.print(" ");Serial.print(AccelMaxY); Serial.print(" "); Serial.print(AccelMaxZ); Serial.println();
Serial.println();


/* Note: Must perform offset and gain calculations prior to seeing updated results
/ Refer to SparkFun ADXL345 Hook Up Guide: https://learn.sparkfun.com/tutorials/adxl345-hookup-guide
/ offsetAxis = 0.5 * (Acel+1g + Accel-1g) // (+1g = 255, -1g = -255 at 2g range setting)!
/ gainAxis = 0.5 * ((Acel+1g - Accel-1g)/1g) */

// UNCOMMENT SECTION TO VIEW NEW VALUES
//accX = (x - offsetX)/gainX; // Calculating New Values for X, Y and Z
//accY = (y - offsetY)/gainY;
//accZ = (z - offsetZ)/gainZ;

//Serial.print("New Calibrated Values: "); Serial.print(accX); Serial.print(" "); Serial.print(accY); Serial.print(" "); Serial.print(accZ);
//Serial.println();

while (Serial.available())
{
Serial.read(); // Clear buffer
}
}

Mach in der Arduino IDE den Termianl (9600 baud) auf und mach den Sensorabgleich. Schau dir an, was ich dazu geschrieben habe ....


So sehen "gute" ;) Servoanlenkung bei mir aus und da ist Spiel drin. Ich habe keine Hightech Flieger wir ihr "Spezialisten" und daher interessieren mich da die 1/10° einfach nicht. Sorry.

6GyXb7yl.png


Ich hab mit mal die Dinger (post #5) gebastelt und die reichen mir voll aus. Die Arduino Sache war nur eine zusätzliche Spielerei.

Wenn du dir das Datenblatt vom ADXL345 anschaust, wirst du sehen, das der Sensor wohl im 1/10° Bereich arbeiten kann.

Aber dazu muss der Sensor abgeglichen werden und du musst einen Messstand (oder ein Modell) haben, wo du sehr kleine Winkeländerungen machen kannst ....

Gruß KH
 

kalle123

User
Anregungen zu Erweiterungen (besonders die Bedienung) kann man sich aus dem verlinkten youtube Video holen.... wirklich toll gemacht!

Eckehard, der kocht auch nur mit Wasser :D

Die Klammern aus dem 3-D Drucker sind ganz nett. Kabellänge sehr sparsam und das OLED ... Naja, mir persönlich ist ein 1602 oder 2004 lieber.

Und mit 3-D Druck fang ich auf meine alten Tage nicht mehr an. Hab genug Baustellen.

Es sei denn, ich seh die erste Schieblehre (aka Messschieber) aus dem xxx € Drucker, mit der ich 1/20 sauber reproduzieren kann .....

KH
 
Ich habe die Zwei Sensoren seperat angeschlossen.
Die haben noch dass unterschiedliche Adresse.
Sollte ich noch etwas dafur eindern so dass die beide Sensoren erkannt werden?


Code:
/*  *****************************************
 *  ADXL345_Calibration
 *  ADXL345 Hook Up Guide Calibration Example 
 *  
 *  Utilizing Sparkfun's ADXL345 Library
 *  Bildr ADXL345 source file modified to support 
 *  both I2C and SPI Communication
 *  
 *  E.Robert @ SparkFun Electronics
 *  Created: Jul 13, 2016
 *  Updated: Sep 13, 2016
 *  
 *  Development Environment Specifics:
 *  Arduino 1.6.11
 *    
 *  Hardware Specifications:
 *  SparkFun ADXL345
 *  Arduino Uno
 *  *****************************************/
 
#include <SparkFun_ADXL345.h>

/*********** COMMUNICATION SELECTION ***********/
/*    Comment Out The One You Are Not Using    */
//ADXL345 adxl = ADXL345(10);           // USE FOR SPI COMMUNICATION, ADXL345(CS_PIN);
ADXL345 adxl = ADXL345();             // USE FOR I2C COMMUNICATION

//ADXL345 adxl(0x53); // die habe ich jetzt angeschlossen
//ADXL345 adxl(0x1D);

/****************** VARIABLES ******************/
/*                                             */
int AccelMinX = 0;
int AccelMaxX = 0;
int AccelMinY = 0;
int AccelMaxY = 0;
int AccelMinZ = 0;
int AccelMaxZ = 0; 

int accX = 0;
int accY = 0;
int accZ = 0;

/************** DEFINED VARIABLES **************/
/*                                             */
#define offsetX   -123       // OFFSET values
#define offsetY   -16
#define offsetZ   -10

#define gainX     133        // GAIN factors
#define gainY     261
#define gainZ     248 

/******************** SETUP ********************/
/*          Configure ADXL345 Settings         */
void setup()
{
  Serial.begin(9600);                 // Start the serial terminal
  Serial.println("SparkFun ADXL345 Accelerometer Breakout Calibration");
  Serial.println();
  
  adxl.powerOn();                     // Power on the ADXL345

  adxl.setRangeSetting(2);           // Give the range settings
                                      // Accepted values are 2g, 4g, 8g or 16g
                                      // Higher Values = Wider Measurement Range
                                      // Lower Values = Greater Sensitivity
                                      
  adxl.setSpiBit(0);                // Configure the device: 4 wire SPI mode = '0' or 3 wire SPI mode = 1
                                      // Default: Set to 1
                                      // SPI pins on the ATMega328: 11, 12 and 13 as reference in SPI Library 
}

/****************** MAIN CODE ******************/
/*  Accelerometer Readings and Min/Max Values  */
void loop()
{
  Serial.println("Send any character to display values.");
  while (!Serial.available()){}       // Waiting for character to be sent to Serial
  Serial.println();
  
  // Get the Accelerometer Readings
  int x,y,z;                          // init variables hold results
  adxl.readAccel(&x, &y, &z);         // Read the accelerometer values and store in variables x,y,z

  if(x < AccelMinX) AccelMinX = x;
  if(x > AccelMaxX) AccelMaxX = x;

  if(y < AccelMinY) AccelMinY = y;
  if(y > AccelMaxY) AccelMaxY = y;

  if(z < AccelMinZ) AccelMinZ = z;
  if(z > AccelMaxZ) AccelMaxZ = z;

  Serial.print("Accel Minimums: "); Serial.print(AccelMinX); Serial.print("  ");Serial.print(AccelMinY); Serial.print("  "); Serial.print(AccelMinZ); Serial.println();
  Serial.print("Accel Maximums: "); Serial.print(AccelMaxX); Serial.print("  ");Serial.print(AccelMaxY); Serial.print("  "); Serial.print(AccelMaxZ); Serial.println();
  Serial.println();

  
  /* Note: Must perform offset and gain calculations prior to seeing updated results
  /  Refer to SparkFun ADXL345 Hook Up Guide: https://learn.sparkfun.com/tutorials/adxl345-hookup-guide
  /  offsetAxis = 0.5 * (Acel+1g + Accel-1g)
  /  gainAxis = 0.5 * ((Acel+1g - Accel-1g)/1g) */

  // UNCOMMENT SECTION TO VIEW NEW VALUES
  //accX = (x - offsetX)/gainX;         // Calculating New Values for X, Y and Z
  //accY = (y - offsetY)/gainY;
  //accZ = (z - offsetZ)/gainZ;

  //Serial.print("New Calibrated Values: "); Serial.print(accX); Serial.print("  "); Serial.print(accY); Serial.print("  "); Serial.print(accZ);
  //Serial.println(); 
  
  while (Serial.available())
  {
    Serial.read();                    // Clear buffer
  }
}

Ich habe das gGefuhl das es nicht richting funtionieert.
Wenn ich die Sensor nur in eine Richtung bewege, andert nur einmal die Zahlen.
Stimmt dass? ich muss auch jede mal ein Karakter nach das Display schicken um ein Ergebnis zu bekommen.

Code:
SparkFun ADXL345 Accelerometer Breakout Calibration

Send any character to display values.

Accel Minimums: 0  -11  0
Accel Maximums: 5  0  261

Send any character to display values.

Accel Minimums: 0  -290  0
Accel Maximums: 5  0  261

Send any character to display values.

Accel Minimums: 0  -290  0
Accel Maximums: 5  0  261

Send any character to display values.

Accel Minimums: 0  -290  0
Accel Maximums: 7  0  261

Send any character to display values.

Accel Minimums: 0  -290  0
Accel Maximums: 7  0  261

Send any character to display values.

Accel Minimums: 0  -291  0
Accel Maximums: 7  0  261

Send any character to display values.
 

kalle123

User
Löte doch mal das Kabel an SDO ab.

bv9mPGol.png


Du musst ALLE 3 ACHSEN ( X, Y und Z) in BEIDE RICHTUNGEN positionieren und dann JEWEILS im Terminal eine Eingabe machen. Es müssen 6 Werte bestimmt werden. X, -X, Y, -Y, Z, -Z.

Dann musst du rechnen und die Werte ins Programm eintragen.

Gruß KH
 
Hallo Kalle,

Ich habe das Programm komplet falsch interpretiert (kommt wahrschein durch mein Rudy Carrell Deutsch ;-) )

Ich habe 5 Messungen gemacht und die waren siemlich stabil.

X Y Z
-272 -290 -252
288 270 261

Offset
X : 288+-272 = 16 16/2 = 8
Y : 270+-290 = -20 -20/2 = -10
Z : 261+-252 = 9 9/2 = 4.5

Gain

X : 288+272 = 560 560/255/2 = 1.098
Y : 270+290 = 560 560/255/2 = 1.098
Z : 261+252 = 513 513/255/2 = 1.006



im Program sieht es dann so aus:

************************************ DEFINED VARIABLES ************************************/
/************************************ SENSORCALIBRATION ************************************/

#define offsetX 8 // OFFSET values
#define offsetY -10 // replace "0" with calculated value after sensor calibration
#define offsetZ 4.5

#define gainX 1.098 // GAIN factors
#define gainY 1.098 // replace "1" with calculated value after sensor calibration
#define gainZ 1.006


Ich hoffe das es so stimmt ;-)

Gruss
 

kalle123

User
Sieht doch schon mal gut aus ;)

Ich hab dir ja geschildert, warum mich (und Eckehard wohl auch) Anzeigen in 1/10° und 1/10 mm nicht interessieren.

Aber du kannst das ändern. Speichere das sketch und fange einfach an, die Kopie zu ändern.

Hab mal bei meinem Programm rein geschaut.

Hier definiere ich den Winkel als Integer


und hier setze ich den "throw" ebenfalls als Integer.

lcd.print("THROW:"); lcd.print(int(count * sin(rad))); lcd.print("mm"); lcd.print(" (");
lcd.print(count); lcd.print(")");


Der Sinn, dass die Arduino Programme von Vielen offen gestellt werden, ist wohl, dass man damit lernen soll und auch die Programme für eigene Ansprüche abändern kann.

Versuch es einfach mal, macht Spass - Gruß KH
 
Hallo Kalle,

erstmal danke fur deine schnelle Antworten!
Ich mochte erstmal ein uno am laufen haben und dann kann ich weiter schauen (Mein Ziel ist nicht um Arduino Programierer zu werden aber muss sagen es ist doch schon was die moglichkeiten sind und auch noch billig!)

Am moment habe ich dass problem das ich die sketch nicht laden kann.

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

Arduino: 1.8.5 (Windows XP), Board:"Arduino/Genuino Uno"

RC_ANGLE_THROW_js:97: error: 'class ADXL345' has no member named 'powerOn'
adxl.powerOn();
C:\Documents and Settings\jeroen\Mijn documenten\Downloads\RC_ANGLE_THROW_js\RC_ANGLE_THROW_js.ino: In function 'void loop()':
RC_ANGLE_THROW_js:163: error: 'class ADXL345' has no member named 'readAccel'
adxl.readAccel(&x, &y, &z); // read the accelerometer values and store them in variables
^
exit status 1
'class ADXL345' has no member named 'powerOn'

Wenn ich ADXL345.h andern in SparkFun_ADXL345.h wird er nicht "orange" und dass stimmt auch nicht.

ist dass ein Library Problem?
 

kalle123

User
Hallo Kalle,

erstmal danke fur deine schnelle Antworten!
Ich mochte erstmal ein uno am laufen haben und dann kann ich weiter schauen (Mein Ziel ist nicht um Arduino Programierer zu werden aber muss sagen es ist doch schon was die moglichkeiten sind und auch noch billig!)

Am moment habe ich dass problem das ich die sketch nicht laden kann.

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

Arduino: 1.8.5 (Windows XP), Board:"Arduino/Genuino Uno"

RC_ANGLE_THROW_js:97: error: 'class ADXL345' has no member named 'powerOn'
adxl.powerOn();
C:\Documents and Settings\jeroen\Mijn documenten\Downloads\RC_ANGLE_THROW_js\RC_ANGLE_THROW_js.ino: In function 'void loop()':
RC_ANGLE_THROW_js:163: error: 'class ADXL345' has no member named 'readAccel'
adxl.readAccel(&x, &y, &z); // read the accelerometer values and store them in variables
^
exit status 1
'class ADXL345' has no member named 'powerOn'

Wenn ich ADXL345.h andern in SparkFun_ADXL345.h wird er nicht "orange" und dass stimmt auch nicht.

ist dass ein Library Problem?

Welchen sketch denn? Calibration, Eckehards ???

Hast du den ADXL SDO wieder verlötet?

Versuch mal, die Lib wieder neu ins Programm einzubinden ...

SEAj2kYl.png


Mein Ziel ist nicht um Arduino Programierer zu werden

Meins auch nicht, aber es ist mir zu kalt draussen, um zu fliegen ;)
 
Hallo KAlle,

Nach 5 Stunden und deine unterstutzung lauft jetzt dein Program
Die Library war nicht die richtige.

Nochmals danke

Code:
/*
  .........................................................................................
  ................... based and inspired on a video by Stefan Pynappels ...................
  ................... https://www.youtube.com/watch?v=FW8ivDylOr8 .........................
  .........................................................................................

  Measuring princible - gravity with 3 axis accelerometer ADXL345

  For further information
  
  http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL345.pdf
  http://www.analog.com/media/en/technical-documentation/application-notes/AN-1057.pdf 
   
  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 and D4, jumper to D5
  
  See https://www.arduino.cc/en/tutorial/button for wiring circuit
  
  Added:

  2017.05.20
  
  Sensor calibration, button decrease chord, using all 3 sensor axis, 
  throw or secant measurement (throw measurement common with model aircraft,
  secant measurement sometimes in "real" aircraft)
*/

/*******************************************************************************************/

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

// LiquidCrystal_I2C  lcd(0x3F, 2, 1, 0, 4, 5, 6, 7); // PCF8754 - 0x27, PCF8754A - 0x3F !
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // ich habe nur ein 20*4 mit adress 0x27


ADXL345 adxl;                   // variable adxl is an instance of the ADXL345 library

const int buttonPin1 = 2;       // Zero angle and throw/secant values
int buttonState1 = 0;           // variable for reading the pushbutton status
const int buttonPin2 = 3;       // Chord depth increase [1 mm step]
int buttonState2 = 0;           // variable for reading the pushbutton status
const int buttonPin3 = 4;       // Chord depth decrease [1 mm step]
int buttonState3 = 0;           // variable for reading the pushbutton status

const int jumper = 5;           // Throw or secant measurement (Jumper OPEN -> throw)
// int jumperState = 0;            // variable for reading the jumper status (SET -> secant) will not be used

int count = 1;                  // Start chord depth [mm]

int x, y, z;	                  // raw values from sensor (-255 ... 0 ... +255)
int angle;
int up;                         // 1 -> up, 2 -> down
int relative;                   // for zeroing
float rad;
float xg, yg, zg;               // g values
float calc;
float tilt;


/************************************ DEFINED VARIABLES ************************************/
/************************************ SENSORCALIBRATION ************************************/

#define offsetX   8       // OFFSET values
#define offsetY   -10     // replace "0" with calculated value after sensor calibration
#define offsetZ   4.50

#define gainX     1.098   // GAIN factors
#define gainY     1.098   // replace "1" with calculated value after sensor calibration
#define gainZ     1.006

/************************************ 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

/*******************************************************************************************/

void setup() {

  lcd.begin (20,4);            // for 20 x 4 LCD module
  lcd.setBacklight(HIGH);

  lcd.createChar(0, degree);
  lcd.createChar(1, arrowup);
  lcd.createChar(2, arrowdown);

  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);
  pinMode(buttonPin3, INPUT);
  pinMode(jumper, INPUT);

  adxl.powerOn();

/*******************************************************************************************/
// START SCREEN
/*******************************************************************************************/

  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(1000);
  lcd.clear ();
  lcd.print("RC - METER");
  lcd.setCursor (0, 1);
  lcd.print("ANGLE AND SECANT");
  delay(3000);

  lcd.clear ();
  lcd.print("ZERO SET");
  lcd.setCursor (0, 1);
  lcd.write(byte(2));
  delay(3000);

  lcd.clear ();
  lcd.print("CORD depth[mm]");
  lcd.setCursor (5, 1);
  lcd.write(byte(1)); lcd.setCursor (7, 1); lcd.write(byte(2));
  delay(3000);
}

/*******************************************************************************************/

void loop() {
  // read the state of the pushbutton/jumper value:

  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);
  buttonState3 = digitalRead(buttonPin3);
  // jumperState  = digitalRead(jumper);

  // check if the pushbutton is pressed.
  // if it is, the buttonState is HIGH:

  if (buttonState1 == HIGH) {
    relative = angle;
  }

  else if (buttonState2 == HIGH) {
    count = count + 1;
    lcd.setCursor (0, 0);           // go to start of 1st line
    lcd.clear();
    lcd.print("CHORD DEPTH:"); lcd.print(count); lcd.print("mm");
  }

  else if ((buttonState3 == HIGH) && (count > 1)) {
    count = count - 1;
    lcd.setCursor (0, 0);           // go to start of 1st line
    lcd.clear();
    lcd.print("CHORD DEPTH:"); lcd.print(count); lcd.print("mm");
  }

  adxl.readAccel(&x, &y, &z); // read the accelerometer values and store them in variables
  xg = 0.00385 * (x - offsetX) / gainX; // 0.00385 to convert the raw data to Gs
  yg = 0.00385 * (y - offsetY) / gainY; // offset and gain for calibration
  zg = 0.00385 * (z - offsetZ) / gainZ;

  calc = xg / sqrt ((sq(yg) + sq(zg)));	//sensor orientation!
  tilt = atan(calc) * 57.296;
  angle = int(tilt) * -1;               //sensor orientation!
  
  lcd.setCursor (0, 0);         // go to start of 1st line
  lcd.clear();
  if ((angle - relative) > 0) {
    up = 1;                     //arrow ↑↑↑
  }
  else {
    up = 2;                     //arrow ↓↓↓
  }

/*******************************************************************************************/
  
  if ((angle - relative) == 0) {
    lcd.print("ANGLE:"); lcd.print(abs(angle - relative)); lcd.write(byte(0));
  }
  else {
    lcd.print("ANGLE:"); lcd.print(abs(angle - relative)); lcd.write(byte(0)); 
    lcd.write(byte(up));
  }
  lcd.setCursor (0, 1);
  rad = abs(angle - relative) * 0.017453;
  
  // read the state of the jumper value:
  // ich brauche kein secant
  // if (jumperState == HIGH) {
  //  lcd.print("SECANT:"); lcd.print(int(2 * count * sin(rad / 2))); lcd.print("mm"); 
  //   lcd.print(" ("); lcd.print(count); lcd.print(")");
  // }
  // else {
    lcd.print("THROW:"); lcd.print(int(count * sin(rad))); lcd.print("mm"); lcd.print(" ("); 
    lcd.print(count); lcd.print(")");
  //}
  delay(300);
}
 
Ansicht hell / dunkel umschalten
Oben Unten