ich bin ein Arduino- und Programmieranfänger. Ich habe mir folgende Idee in den Kopf gesetzt und benötige nun eure Hilfe:
Ich baue einen LED Streifen auf eine Fußsockelleiste und möchte nun, dass an der Stelle an der ich stehe der LED-Strip an geht.
Bisher habe ich hierfür zwei VL53L0X ToF Sensoren (SDA an PIN A4 und SCL an PIN A5) hintereinander geschaltet. Und meinen RGBW LED Strip an PIN 3 eingesteckt.
Mein bisheriger Code kann nun eine anfängliche Initialmessung durchführen und diese Maximaldistanzen (je eine pro ToF Sensor) in einem Array abspeichern. Nun wird kontinuierlich weiterhin die aktuelle Distanz gemessen.
Und nun komme ich an meine Grenzen: Ich möchte, dass wenn die Maximaldistanz von Sensor 1 durch die aktuell gemessene Distanz von Sensor 1 unterschritten wird, dass die LEDs 0 bis 31 warm weiß leuchten. Parallel und unabhängig von dem gerade beschrieben Vorgang sollen die LEDs 32 bis 72 warm weiß leuchten, wenn die Maximaldistanz von Sensor 2 durch die aktuell gemessene Distanz von Sensor 2 unterschritten wird.
Anbei mein bisheriger Code:
#include <Wire.h>
#include <Adafruit_VL53L0X.h>
#define FIRST_SENSOR_ADDRESS 0x31
#define SECOND_SENSOR_ADDRESS 0x32
#define MEASUREMENT_INTERVAL 300000 // Messintervall in Millisekunden (5 Minuten)
Adafruit_VL53L0X sensor1, sensor2;
uint16_t maxDistances[2]; // Array zur Speicherung der Maximaldistanzen
void setup() {
Serial.begin(9600);
Wire.begin();
if (!sensor1.begin(FIRST_SENSOR_ADDRESS)) {
Serial.println("Unable to find VL53L0X sensor 1");
while (1);
}
if (!sensor2.begin(SECOND_SENSOR_ADDRESS)) {
Serial.println("Unable to find VL53L0X sensor 2");
while (1);
}
// Erhöhe die Messdauer für jedes Messintervall
sensor1.setMeasurementTimingBudgetMicroSeconds(50000); // Beispielwert, experimentiere mit unterschiedlichen Werten
sensor2.setMeasurementTimingBudgetMicroSeconds(50000); // Beispielwert, experimentiere mit unterschiedlichen Werten
// Führe die Initialmessung durch
performInitialMeasurement();
delay(500);
}
void loop() {
// Führe Messung durch
VL53L0X_RangingMeasurementData_t measure1, measure2;
sensor1.rangingTest(&measure1, false);
sensor2.rangingTest(&measure2, false);
// Gib die aktuellen Messwerte und abgespeicherten Maximaldistanzen aus
printMeasurements(measure1, measure2);
delay(1000);
}
void performInitialMeasurement() {
// Führe die Initialmessung durch und speichere die Maximaldistanzen
VL53L0X_RangingMeasurementData_t measure1, measure2;
sensor1.rangingTest(&measure1, false);
sensor2.rangingTest(&measure2, false);
maxDistances[0] = measure1.RangeMilliMeter;
maxDistances[1] = measure2.RangeMilliMeter;
}
void printMeasurements(VL53L0X_RangingMeasurementData_t measure1, VL53L0X_RangingMeasurementData_t measure2) {
// Überprüfe und aktualisiere Maximaldistanzen alle 5 Minuten
static uint32_t lastUpdateTime = 0;
if (millis() - lastUpdateTime >= MEASUREMENT_INTERVAL) {
lastUpdateTime = millis();
performInitialMeasurement();
}
// Gib die aktuellen Messwerte und abgespeicherten Maximaldistanzen aus
Serial.print("Sensor 1: ");
if (measure1.RangeStatus != 4) {
Serial.print(measure1.RangeMilliMeter);
Serial.print(" mm");
} else {
Serial.print("Out of range");
}
Serial.print("\tMaximaldistanz 1: ");
Serial.print(maxDistances[0]);
Serial.print(" mm");
Serial.print("\tSensor 2: ");
if (measure2.RangeStatus != 4) {
Serial.print(measure2.RangeMilliMeter);
Serial.print(" mm");
} else {
Serial.print("Out of range");
}
Serial.print("\tMaximaldistanz 2: ");
Serial.print(maxDistances[1]);
Serial.println(" mm");
}
Ich hoffe ihr könnt mir weiterhelfen und bedanke mich vorab schonmal!
Das ist mir auch klar. Ich habe es auch schon geschafft, dass Sensor 1 auf die LEDs 0 - 31 zugreift. Aber als ich dann mit Sensor zwei die LEDs 32- 72 ansteuern wollte ging garnichts mehr.
Vielen Dank, nun kommt keine Fehlermeldund mehr. Aber ich kann den Code gerade nicht testen, da meine ToF Sensoren beide die I2C Adresse "0x31" haben. Ich habe schonmal mit folgendem Code gescannt
#include <Wire.h>
void setup()
{
Wire.begin();
Serial.begin(9600);
while (!Serial); // Leonardo: wait for serial monitor
Serial.println("I2C 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");
else
Serial.println("done");
delay(5000); // wait 5 seconds for next scan
}
Aber wenn ich mit diesem Code die Adresse ändern möchte, dann änder sich die Adresse aber nicht. Ich habe es zwar schon ein paar mal geschafft aber nicht immer. Und wenn ich den Stromstecker ziehe dann setzen die sich wieder zurück.
#include "Adafruit_VL53L0X.h"
Adafruit_VL53L0X lox = Adafruit_VL53L0X();
void setup() {
// Robojax.com I2C address update 20181206
lox.begin(0x32);// put any address between 0x29 to 0x7F
}
void loop(){
}
I2C only allows one address-per-device so you have to make sure each I2C device has a unique address. The default address for the VL53L0X is 0x29 but you can change this in software.
To set the new address you can do it one of two ways. During initialization, instead of calling lox.begin(), call lox.begin(0x30) to set the address to 0x30. Or you can, later, call lox.setAddress(0x30) at any time.
The good news is its easy to change, the annoying part is each other sensor has to be in shutdown. You can shutdown each sensor by wiring up to the XSHUT pin to a microcontroller pin. Then perform something like this pseudo-code:
Reset all sensors by setting all of their XSHUT pins low for delay(10), then set all XSHUT high to bring out of reset
Keep sensor #1 awake by keeping XSHUT pin high
Put all other sensors into shutdown by pulling XSHUT pins low
Initialize sensor #1 with lox.begin(new_i2c_address) Pick any number but 0x29 and it must be under 0x7F. Going with 0x30 to 0x3F is probably OK.
Keep sensor #1 awake, and now bring sensor #2 out of reset by setting its XSHUT pin high.
Initialize sensor #2 with lox.begin(new_i2c_address) Pick any number but 0x29 and whatever you set the first sensor to
Repeat for each sensor, turning each one on, setting a unique address.
Note you must do this every time you turn on the power, the addresses are not permanent!
Ja, wenn man eben pro Sensor einen Controllerpin für die Steuerung des XSHUT einganges des VL53L0X opfert dann geht das und funktioniert auch problemlos. Hab das beim Futterportionierer für meine Katze gemacht. Da nutze ich die 2 ToF Sensoren zuer Ermittlung der Futerstände im Vorratsbehälter und in der Ausgabeschale (während der Ausgabe um ein überfüllen der Schale zu vermeiden.) Steuer da nen Schrittmotor mit Stall Erkennungssensorv, 2 ToF, Notstrom Batterie überwachung , Animiertes 128x64 i2c Oled , RTC 3231 , I2C FRAM , ein 2 Tasten joypad und nen Buzzer alles mit 1 ATTiny 167.
über den XShot kannst Du die beiden Sensoren mit jeweils ner eigenen Adresse initialisieren um sie gleichzeitig nutzen zu können. Die Initialisierung Funktioniert jedoch NUR , wenn gerage nur derjenig, der im Moment initialisiert wird aktiv ist, da ja beide vorerst auf dieselbe Adresse hören. Deshalb wissen ja dann , wen beide beim Initialisieren Ariv wären, die Sensoren nicht, welcher nun Gemeint ist, respektive, sie reagieren BEIDE auf die Adressänderung. Somit hätte man dann wiederum 2 Sensoren, die auf die Gleiche (jetzt halt neue) Adresse hören- Meistens lgeht dann jedoch die initialisierung eh schief und löst eine Fehlermeldung aus. Deshalb muss mann über den XSHUT Eingang erst die sensoren resetten, und dann nur den gerede zu Initialisirenden aktivieren um Ihm die Adresse zu verpassen und das BasisInit durchzuführen. Danach sind beide Sensoren aktiv und können ederzeit über ihre eigene Adresse (ohder das für den Sensor erstellte Objekt angesprochen werden. In meinem Futterprotionierer habich das so umgesetzt, dass ich die XShut Eingänge , die ja NUR im Setup benötigrt werden, am Attiny an zwei pins gehängt habe, die ich NACH dem Setup für andere Aufgaben (als Eingänge nutze. über externe Flipflops und ein paar GMos Gatter hab ich nen Sschalter aufgebaut, der die XShut nach erfolgtem Setup vom ATTiny trennt, da ich sonst nicht genügend Pins gehabt hätte um alle Sensoren und Aktoren zu bedienen. So komme ich mit den 16 I/O Pins des ATTiny 167 aus.