Need some pointers with VL53L1X and sounding tones

Hello everyone I'm working with a a couple of VL53L1X sensors and I have successfully managed to get them to both work and report in with accurate enough measurements for what I intend to use them for which is a great start.

The next hurdle I'm trying to figure out is how to get a tone out based upon the measurement being seen, the ideal scenario is that I have the tone speed consistent (beeps 4 times a second for example) but the closer you get the tone changes and the left side ands the right side will have different tone ranges (left side has tone range of 110-150 and the right side would have a tone range of 1568-1976).

I know what I want to do but I'm struggling to have the brainwave needed to achieve this so I'm reaching out to see if I could grab some help.

Below is my code so far and below that I will show you the serial output.

/*
Code for the left/right device.
The Tone pin that will be used is Digital pin 3
RGB LEDs are also controlled once the sensor has been triggered - TODO
*/

#include <Wire.h>
#include <VL53L1X.h>

// Left side tones

#define NOTE_A2 110
#define NOTE_AS2 117
#define NOTE_B2 123
#define NOTE_C3 131
#define NOTE_CS3 139

// Right side tones

#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976

// The number of sensors in your system.
const uint8_t sensorCount = 2;

// The Arduino pin connected to the XSHUT pin of each sensor.
const uint8_t xshutPins[sensorCount] = { 6, 7 };

VL53L1X sensors[sensorCount];

void setup()
{
  while (!Serial) {}
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000); // use 400 kHz I2C

  // Disable/reset all sensors by driving their XSHUT pins low.
  for (uint8_t i = 0; i < sensorCount; i++)
  {
    pinMode(xshutPins[i], OUTPUT);
    digitalWrite(xshutPins[i], LOW);
  }

  // Enable, initialize, and start each sensor, one by one.
  for (uint8_t i = 0; i < sensorCount; i++)
  {
    pinMode(xshutPins[i], INPUT);
    delay(10);

    sensors[i].setTimeout(500);
    if (!sensors[i].init())
    {
      Serial.print("Failed to detect and initialize sensor ");
      Serial.println(i);
      while (1);
    }

    sensors[i].setAddress(0x2A + i);

    sensors[i].startContinuous(50);
  }
}

void loop()
{
  //for (uint8_t i = 0; i < sensorCount; i++)
  //for (uint8_t i = 0; i < 1; i++)
  {
//    Serial.print(sensors[i].read());
    Serial.print((String)"Left side sensor "+sensors[0].read());
    Serial.println();
    Serial.print((String)"Right side sensor "+sensors[1].read());
    Serial.println();
//    if (sensors[i].timeoutOccurred()) { Serial.print(" TIMEOUT"); }
//    Serial.print('\t');
  }
//  Serial.println();
}

Output of Serial

21:06:34.040 -> Left side sensor 2777
21:06:34.040 -> Right side sensor 2788
21:06:34.133 -> Left side sensor 2766
21:06:34.133 -> Right side sensor 2784
21:06:34.226 -> Left side sensor 2770
21:06:34.226 -> Right side sensor 2786

Please ignore the commented out sections that due to me doing some testing

I do not know if I fully understand, but it sounds like you want to make LEFT and RIGHT have the same output range. Would "map" suit your need?

output = map (input_lowest_range, input_highest_range, output_lowest_range, output_highest_range);

and so, for you...

left_output = map ( left_side ( 110, 150, 0, 4));
right_output = map ( right_side ( 1568, 1976, 0, 4));

Hi mate, I can't say I've heard of or used map before so that's one I will look into as always good to learn something new.

When I say range I mean a tone range so the pitch of a tone changes (goes higher) the closer you get to the sensor (the lower distance the sensor registers).

Hopefully I'm explaining it well enough as I know I can confuse things sometimes.

Cheers

Like a theremin?

I suppose now you mention it that seems similar but this pitch change as you get closer is only the start I'm going to be adding further functionality to it.

Am I close to your goal by saying you want a nominal 250ms (1/4 second) beep rate, changing the beep rate proportional to the change of distance, with left side being an octave (or part of one) different from the right side? I do not think that is possible using tones (notes of a given frequency). The Arduino uses timers to make tones, even at register-level of programming, and the use of one timer to make one sound seems (to me) to mean another tone must wait for the timer to finish. However... you can make LEDs flash at different rates, and even overlapping rates. Maybe you can do your change in beep rate if you use active buzzers that only need a voltage level, and not a frequency of vibrating the speaker? Here is a simulation of variable blink rates - and maybe just hook up active buzzers to the LED pins and give left-side a one-beep routine, with the right side a two-beep routine.

Ok I have managed to figure out how to change the tone of sound by using the following logic it's very basic logic but functional.

/*
Code for the yes/no device.
The Tone pin that will be used is Digital pin 3
RGB LEDs are also controlled once the sensor has been triggered
RGB Pins on LED1:
G=D11
R=D12
B=D13
Red colour is RGB(255, 0, 0) or #ff0000
Red colour is RGB(0, 255, 0) or #00ff00
Static orange colour for when sensor has not been set off RGB(255, 128, 0) or #ff8000

// No side tones

#define NOTE_A2 110
#define NOTE_AS2 117
#define NOTE_B2 123
#define NOTE_C3 131
#define NOTE_CS3 139

// Yes side tones

#define NOTE_G6 1568
#define NOTE_GS6 1661
#define NOTE_A6 1760
#define NOTE_AS6 1865
#define NOTE_B6 1976
*/

#include <Wire.h>
#include <VL53L1X.h>

int redPinNo=12;
int greenPinNo = 11;
int bluePinNo = 13;

// The number of sensors in your system.
const uint8_t sensorCount = 2;

// The Arduino pin connected to the XSHUT pin of each sensor.
const uint8_t xshutPins[sensorCount] = { 6, 7 };

VL53L1X sensors[sensorCount];

void setup()
{
  
  pinMode(redPinNo, OUTPUT);
  pinMode(greenPinNo, OUTPUT);
  pinMode(bluePinNo, OUTPUT);

  while (!Serial) {}
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000); // use 400 kHz I2C

  // Disable/reset all sensors by driving their XSHUT pins low.
  for (uint8_t i = 0; i < sensorCount; i++)
  {
    pinMode(xshutPins[i], OUTPUT);
    digitalWrite(xshutPins[i], LOW);
  }

  // Enable, initialize, and start each sensor, one by one.
  for (uint8_t i = 0; i < sensorCount; i++)
  {
    // Stop driving this sensor's XSHUT low. This should allow the carrier
    // board to pull it high. (We do NOT want to drive XSHUT high since it is
    // not level shifted.) Then wait a bit for the sensor to start up.
    pinMode(xshutPins[i], INPUT);
    delay(10);

    sensors[i].setTimeout(500);
    if (!sensors[i].init())
    {
      Serial.print("Failed to detect and initialize sensor ");
      Serial.println(i);
      while (1);
    }

    // Each sensor must have its address changed to a unique value other than
    // the default of 0x29 (except for the last one, which could be left at
    // the default). To make it simple, we'll just count up from 0x2A.
    sensors[i].setAddress(0x2A + i);

    sensors[i].startContinuous(50);
  }
}

void loop()
{
  int MaxDistanceValue = 2000;
  int DistanceNo = sensors[0].read();
  int DistanceYes = sensors[1].read();

  //for (uint8_t i = 0; i < sensorCount; i++)
  //for (uint8_t i = 0; i < 1; i++)
  //{
//    Serial.print(sensors[i].read());
  
    //Serial.print((String)"NO side sensor "+sensors[0].read());
    //Serial.println();
    //Serial.print((String)"YES side sensor "+sensors[1].read());
    //Serial.println();

    Serial.print((String)"NO side sensor "+DistanceNo);
    Serial.println();
    Serial.print((String)"YES side sensor "+DistanceYes);
    Serial.println();

    if (DistanceNo<MaxDistanceValue*0.1) {
      tone(3, 147, 50 );
    }

    else if (DistanceNo<MaxDistanceValue*0.2) {
      tone(3, 139, 50 );
    }

    else if (DistanceNo<MaxDistanceValue*0.4) {
      tone(3, 139, 50 );
    }

    else if (DistanceNo<MaxDistanceValue*0.6) {
      tone(3, 123, 50 );
    }

    else if (DistanceNo<MaxDistanceValue*0.8) {
      tone(3, 117, 50 );
    }

    else if (DistanceNo<MaxDistanceValue*1) {
      tone(3, 110, 50 );
    }

    else {
      noTone(3);
    }

    if (DistanceNo<MaxDistanceValue*1) {
      analogWrite(redPinNo, 255);
      analogWrite(greenPinNo, 0);
      analogWrite(bluePinNo, 0);
      delay(50);
      analogWrite(redPinNo, 0);
      analogWrite(greenPinNo, 0);
      analogWrite(bluePinNo, 0);
    }
}

More updated code to cover the "fix" for this. Once again please ignore a lot of the comments they were used during testing etc.

/*
Code for the yes/no device.
The Tone pin that will be used is Digital pin 3
RGB LEDs are also controlled once the sensor has been triggered
RGB Pins on LED1:
G=D11
R=D12
B=D13
Red colour is RGB(255, 0, 0) or #ff0000
Red colour is RGB(0, 255, 0) or #00ff00
Static orange colour for when sensor has not been set off RGB(255, 128, 0) or #ff8000
*/

#include <Wire.h>
#include <VL53L1X.h>

int redPinNo = 8;
int greenPinNo = 9;
int bluePinNo = 10;

int redPinYes = 12;
int greenPinYes = 11;
int bluePinYes = 13;

// The number of sensors in your system.
const uint8_t sensorCount = 2;

// The Arduino pin connected to the XSHUT pin of each sensor.
const uint8_t xshutPins[sensorCount] = { 6, 7 };

VL53L1X sensors[sensorCount];

void setup()
{
  
  pinMode(redPinNo, OUTPUT);
  pinMode(greenPinNo, OUTPUT);
  pinMode(bluePinNo, OUTPUT);

  pinMode(redPinYes, OUTPUT);
  pinMode(greenPinYes, OUTPUT);
  pinMode(bluePinYes, OUTPUT);

  while (!Serial) {}
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000); // use 400 kHz I2C

  // Disable/reset all sensors by driving their XSHUT pins low.
  for (uint8_t i = 0; i < sensorCount; i++)
  {
    pinMode(xshutPins[i], OUTPUT);
    digitalWrite(xshutPins[i], LOW);
  }

  // Enable, initialize, and start each sensor, one by one.
  for (uint8_t i = 0; i < sensorCount; i++)
  {
    // Stop driving this sensor's XSHUT low. This should allow the carrier
    // board to pull it high. (We do NOT want to drive XSHUT high since it is
    // not level shifted.) Then wait a bit for the sensor to start up.
    pinMode(xshutPins[i], INPUT);
    delay(10);

    sensors[i].setTimeout(500);
    if (!sensors[i].init())
    {
      Serial.print("Failed to detect and initialize sensor ");
      Serial.println(i);
      while (1);
    }

    // Each sensor must have its address changed to a unique value other than
    // the default of 0x29 (except for the last one, which could be left at
    // the default). To make it simple, we'll just count up from 0x2A.
    sensors[i].setAddress(0x2A + i);

    sensors[i].startContinuous(50);
  }
}

void loop()
{
  int MaxDistanceValue = 1000;
  int DistanceNo = sensors[0].read();
  int DistanceYes = sensors[1].read();

  //for (uint8_t i = 0; i < sensorCount; i++)
  //for (uint8_t i = 0; i < 1; i++)
  //{
//    Serial.print(sensors[i].read());
  
    //Serial.print((String)"NO side sensor "+sensors[0].read());
    //Serial.println();
    //Serial.print((String)"YES side sensor "+sensors[1].read());
    //Serial.println();

    Serial.print((String)"NO side sensor "+DistanceNo);
    Serial.println();
    Serial.print((String)"YES side sensor "+DistanceYes);
    Serial.println();
    
    
    if (DistanceNo<MaxDistanceValue*0.1) {
      tone(3, 147, 50 );
    }

    else if (DistanceNo<MaxDistanceValue*0.2) {
      tone(3, 139, 50 );
    }

    else if (DistanceNo<MaxDistanceValue*0.4) {
      tone(3, 131, 50 );
    }

    else if (DistanceNo<MaxDistanceValue*0.6) {
      tone(3, 123, 50 );
    }

    else if (DistanceNo<MaxDistanceValue*0.8) {
      tone(3, 117, 50 );
    }

    else if (DistanceNo<MaxDistanceValue*1) {
      tone(3, 110, 50 );
    }

    //else {
    //  noTone(3);
    //}

    if (DistanceNo<MaxDistanceValue*1) {
      analogWrite(redPinNo, 255);
      analogWrite(greenPinNo, 0);
      analogWrite(bluePinNo, 0);
      delay(50);
      analogWrite(redPinNo, 0);
      analogWrite(greenPinNo, 0);
      analogWrite(bluePinNo, 0);
    }

     else {
      analogWrite(redPinNo, 0);
      analogWrite(greenPinNo, 0);
      analogWrite(bluePinNo, 255);
    }

    //delay(50);

    if (DistanceYes<MaxDistanceValue*0.1) {
      tone(3, 1976, 50 );
    }

    else if (DistanceYes<MaxDistanceValue*0.2) {
      tone(3, 1865, 50 );
    }

    else if (DistanceYes<MaxDistanceValue*0.4) {
      tone(3, 1760, 50 );
    }

    else if (DistanceYes<MaxDistanceValue*0.6) {
      tone(3, 1661, 50 );
    }

    else if (DistanceYes<MaxDistanceValue*0.8) {
      tone(3, 1568, 50 );
    }

    else if (DistanceYes<MaxDistanceValue*1) {
      tone(3, 1480, 50 );
    }

    //else {
    //  noTone(3);
    //}

    if (DistanceYes<MaxDistanceValue*1) {
      analogWrite(redPinYes, 0);
      analogWrite(greenPinYes, 255);
      analogWrite(bluePinYes, 0);
      delay(50);
      analogWrite(redPinYes, 0);
      analogWrite(greenPinYes, 0);
      analogWrite(bluePinYes, 0);
    }

     else {
      analogWrite(redPinYes, 0);
      analogWrite(greenPinYes, 0);
      analogWrite(bluePinYes, 255);
    }    

//    if (sensors[i].timeoutOccurred()) { Serial.print(" TIMEOUT"); }
//    Serial.print('\t');
  //}
//  Serial.println();
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.