Ich verwende den Arduino Nano Every und den VL53L1X-Sensor zum Messen von Entfernungen. Diese gebe ich über das LiquidCrystal-Display aus. 4 Leds leuchten je nach Entfernung in 100er-Schritten und der passive Buzzer quietscht, wenn sich die Entfernung in Dezimeter ändert (damit das Teil nicht permanent quietscht).
Nur Letzteres funktioniert nicht richtig - der Buzzer quietscht nur manchmal. Vlt. ist der Code nicht optimal, der Nano zu langsam oder ich hab irgendwo einen Denkfehler.
Ausserdem flimmert das Display ständig.
Ich ersuche höflichst um Unterstützung.
/*
This example shows how to take simple range measurements with the VL53L1X. The
range readings are in units of mm.
*/
#include <Wire.h>
#include <VL53L1X.h>
VL53L1X sensor;
#include <LiquidCrystal.h>
const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const byte speakerPin = 12;
int sens_read = 0;
long previousMillis = 0;
long interval = 20;
void setup() {
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
pinMode(8, OUTPUT);
while (!Serial) {}
Serial.begin(115200);
Wire.begin();
Wire.setClock(400000); // use 400 kHz I2C
sensor.setTimeout(500);
if (!sensor.init()) {
Serial.println("Failed to detect and initialize sensor!");
while (1)
;
}
// Use long distance mode and allow up to 50000 us (50 ms) for a measurement.
// You can change these settings to adjust the performance of the sensor, but
// the minimum timing budget is 20 ms for short distance mode and 33 ms for
// medium and long distance modes. See the VL53L1X datasheet for more
// information on range and timing limits.
sensor.setDistanceMode(VL53L1X::Long);
sensor.setMeasurementTimingBudget(33000);
// Start continuous readings at a rate of one measurement every 50 ms (the
// inter-measurement period). This period should be at least as long as the
// timing budget.
sensor.startContinuous(33);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
}
void loop() {
Serial.print(sensor.read());
if (sensor.timeoutOccurred()) { lcd.print("Time out"); }
// Tonausgabe
// unsigned long currentMillis = millis();
// if (currentMillis - previousMillis > interval) {
// previousMillis = currentMillis;
if (sens_read != sensor.read() / 100) {
tone(speakerPin, 2000, 100);
}
//}
// LED-Ausgabe
Serial.println();
if (sensor.read() < 100) {
digitalWrite(11, HIGH);
} else {
digitalWrite(11, LOW);
}
if (sensor.read() < 200) {
digitalWrite(10, HIGH);
} else {
digitalWrite(10, LOW);
}
if (sensor.read() < 300) {
digitalWrite(9, HIGH);
} else {
digitalWrite(9, LOW);
}
if (sensor.read() < 400) {
digitalWrite(8, HIGH);
} else {
digitalWrite(8, LOW);
}
sens_read = sensor.read() / 100;
// Displayausgabe
lcd.setCursor(0, 0);
//lcd.print(sensor.read() + String(" mm / ") + sens_read);
lcd.print(sensor.read() + String(" mm "));
lcd.setCursor(0, 1);
lcd.print(sens_read + String(" "));
}
Du solltest das Display nur beschreiben, wenn sich der Wert geändert hat.
Wozu mehrere Aufrufe von sensor.read() für einmal anzeigen?
Speichere den Wert in einer Variablen und verwende diesen. Merke Dir den alrten Wert in einer anderen Variablen und nur wenn beide unterschiedlich sind, dann nutze das Display.
weitere Optionen wären den Sensorwert zu filtern und/oder das Display im Minimum aller halben Sekunde zu beschreiben. Sonst nimmt man das ggf. erneut als flimmern wahr wenn sich der Wert zügig ändern sollte.
Den versteh ich noch nicht ganz.
Ich werd auch der Stelle im Code nicht schlau.
das mit dem /100 sollen dein dcm werden? dann nicht teilen, sondern abziehen.
Aber Du misst alle 33ms - was bewegt sich da in 33ms um mehr als 10cm?
Und dann teile auf, was zusammengehört.
Zum Display wurde schon gesagt.
ungetestet - ich hab keinen every und compilieren geht auch nicht, da ich keine VL53L1X lib an Board habe...
/*
This example shows how to take simple range measurements with the VL53L1X. The
range readings are in units of mm.
*/
#include <Wire.h>
#include <VL53L1X.h>
VL53L1X sensor;
#include <LiquidCrystal.h>
const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const byte ledPin[4] = {8, 9, 10, 11};
const byte speakerPin = 12;
unsigned long previousMillis = 0;
unsigned long intervall = 20;
unsigned int sensorWert;
bool sensorTimeOut = false;
void setup()
{
while (!Serial) {}
Serial.begin(115200);
Serial.println(F("Start..."));
for (byte b = 0; b < sizeof(ledPin); b++)
{
pinMode(ledPin[b], OUTPUT);
}
Wire.begin();
Wire.setClock(400000); // use 400 kHz I2C
sensor.setTimeout(500);
if (!sensor.init())
{
Serial.println("Failed to detect and initialize sensor!");
while (1)
;
}
// Use long distance mode and allow up to 50000 us (50 ms) for a measurement.
// You can change these settings to adjust the performance of the sensor, but
// the minimum timing budget is 20 ms for short distance mode and 33 ms for
// medium and long distance modes. See the VL53L1X datasheet for more
// information on range and timing limits.
sensor.setDistanceMode(VL53L1X::Long);
sensor.setMeasurementTimingBudget(33000);
// Start continuous readings at a rate of one measurement every 50 ms (the
// inter-measurement period). This period should be at least as long as the
// timing budget.
sensor.startContinuous(33);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
}
void loop()
{
sensorRead();
buzzerAction();
ledAction();
lcdAusgabe();
}
//
void sensorRead()
{
sensorWert = sensor.read();
Serial.println(sensorWert);
if (sensor.timeoutOccurred())
{
sensorTimeOut = true;
}
}
//
void buzzerAction()
{
static unsigned int lastSensorWert = 0;
if (sensorWert < lastSensorWert - 100)
{
tone(speakerPin, 2000, 100);
}
lastSensorWert = sensorWert;
}
//
void ledAction()
{
bool leds[4] = {LOW, LOW, LOW, LOW};
for (byte b = 0; b < sizeof(ledPin); b++)
{
if (sensorWert < 100U * (b + 1))
{
leds[b] = HIGH;
}
}
for (byte b = 0; b < sizeof(ledPin); b++)
{
digitalWrite(ledPin[b], leds[b]);
}
}
//
void lcdAusgabe()
{
static uint16_t lastSensorWert = 0;
lcd.setCursor(0, 0);
if (sensorTimeOut)
{
lcd.println(F(" Sensor Timeout "));
}
else if (lastSensorWert != sensorWert)
{
lastSensorWert = sensorWert;
lcd.print(sensorWert);
lcd.print(F(" mm"));
if (sensorWert < 10)
{
lcd.print(' ');
}
if (sensorWert < 100)
{
lcd.print(' ');
}
if (sensorWert < 1000)
{
lcd.print(' ');
}
if (sensorWert < 10000)
{
lcd.print(' ');
}
}
}
Warum eigentlich? Geht das Display sonst kaputt? Ich dachte immer es wird ja nur in den Ram vom Display geschoben den man unendlich beschreiben kann oder die Libary erkennt, dass sich nichts geändert hat.