I am using multiple VL53L0X distance sensors and LCD with I2C communication. When I used them individually they work fine, but altogether after a while some of VLX sensors stop measuring and some unmeaningfull symbols written on LCD. All device adresses are different. In some forums, equivalent resistance of parallel pull-up resistors in the breakout bords of individual devices may became smaller than the min resistor value for pull-up resistor. I calulated the value and I think my problem is this. So I need to seperate the I2C lines, Teensy 3.5 has three I2C port, but I think I need wire1/2.h and .cpp file to use all the I2C port. So:
1-Are there any wire1/2.h and .cpp files that can be share with us?
2- Are there any critical coding when I use more than one I2C? can you share if there is a sample code that uses more than one I2C?
3- do I need to use pull-up resirtors for my SDA-SCL line in my board because of internall pull-up resistor in the teensy/VL53L0X/LCD board?
some part of my code:
#include <Wire.h>
#include <VL53L0X.h>
#include <Encoder.h>
#include <Arduino.h>
#include <TeensyThreads.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
//#define XSHUT girisleri sensorun adreslemesi icin kullaniliyor.
#define solXSHUT_pini 21
#define sagXSHUT_pini 20
#define solSensorAdresi 42 //ilk VLX adresi her zaman 41
#define onsolSensorAdresi 43
#define onsagSensorAdresi 43
#define btStatePin 35
#define altSag 37
/********* Motor ***************/
Encoder solSayici(28, 27);
#define motorSolHiz 5 // enable1
#define motorSol1 6 // motor1geri
#define motorSol2 7 // motor1ileri //Sag
Encoder sagSayici(29, 30);
#define motorSag1 8 // motor2geri
#define motorSag2 9 // motor2iler //sol
#define motorSagHiz 10 // enable2
#define solLED 26
#define onsolLED 25
#define onLED 24
#define onsagLED 12
#define sagLED 11
#define altSagLED 2
#define altSolLED 3
VL53L0X sagSensor;
VL53L0X solSensor;
VL53L0X onsagSensor;
VL53L0X onsolSensor;
//Programda kullanilan islevler tanimlaniyor
void motorlariAyarla(boolean ileri);
void toleransKontrol();
void yamuklukDuzelt();
void readLiDAR();
void kesme();
void engelKontrol();
int engelKontrol_1();
volatile int lidarValue = 0;
/***** BT *****/
int btStateValue;
boolean taramaBayragi = true; // sagdan veya soldan donecegini belirleyen bayrak
boolean yamukDuzeltiliyor = false;
/***** Mesafe parametreleri *****/
const int ENGELMESAFE_ON = 400;
const int ENGELMESAFE_YAN = 100;
const int ENGELMESAFE_YAN_DONUS = 700;
void setup() {
Wire.begin();
Serial.begin(115200); // Serial output through USB to computer
Serial1.begin(115200); // Serial communmication of LIDAR
Serial5.begin(9600); // Serial communmication of BT
pinMode(btStatePin, INPUT); //BT
/************************ VLX ***************/
//Shutdown pins of VL53L0X ACTIVE-LOW-ONLY NO TOLERANT TO 5V will fry them
pinMode(sagXSHUT_pini, OUTPUT);
pinMode(solXSHUT_pini, OUTPUT);
pinMode(onsagXSHUT_pini, OUTPUT);
pinMode(onsolXSHUT_pini, OUTPUT);
pinMode(onsolXSHUT_pini, INPUT);
delay(10);
solSensor.setAddress(onsolSensorAdresi);
pinMode(onsagXSHUT_pini, INPUT);
delay(10);
solSensor.setAddress(onsagSensorAdresi);
pinMode(solXSHUT_pini, INPUT);
delay(10);
solSensor.setAddress(solSensorAdresi);
pinMode(sagXSHUT_pini, INPUT);
delay(10);
sagSensor.init();
solSensor.init();
onsagSensor.init();
onsolSensor.init();
sagSensor.setTimeout(500);
solSensor.setTimeout(500);
onsagSensor.setTimeout(500);
onsolSensor.setTimeout(500);
sagSensor.startContinuous();
solSensor.startContinuous();
onsagSensor.startContinuous();
onsolSensor.startContinuous();
/***************** LIDAR ********************/
delay (100); // Give a little time for things to start
// Set to Standard Output mode
Serial1.write(0x42);
Serial1.write(0x57);
Serial1.write(0x02);
Serial1.write(0x00);
Serial1.write(0x00);
Serial1.write(0x00);
Serial1.write(0x01);
Serial1.write(0x06);
// Setup thread for reading serial input from TFmini
threads.addThread(readLiDAR);
/************ Sharp **********/
pinMode(altSag, INPUT);
//pinMode(altSol, INPUT);
attachInterrupt(altSag, kesme, LOW); //gercekte HIGH olacak
//attachInterrupt(altSol, kesme, LOW);
/*********** LCD *************/
lcd.init(); // initialize the lcd
lcd.backlight();
// Print a message to the LCD.
lcd.setCursor(0, 0);
lcd.print("2-Line DISPLAY");
delay(500);
lcd.setCursor(0, 1);
lcd.print("VLX 1:");
delay(500);
lcd.setCursor(10, 1);
lcd.print("VLX 2:");
delay(500);
lcd.setCursor(0, 2);
lcd.print("VLX 3:");
delay(500);
lcd.setCursor(10, 2);
lcd.print("VLX 4:");
delay(500);
lcd.setCursor(0, 3);
lcd.print("LIDAR:");
lcd.print(lidarValue);
delay(500);
}
void loop() {
btStateValue = Serial5.read();
/*** Enkoder islemleri ******/
solSayac = solSayici.read();
sagSayac = sagSayici.read();
if (solSayac != eskiSolSayac || sagSayac != eskiSagSayac) {
eskiSolSayac = solSayac;
eskiSagSayac = sagSayac;
}
// if a character is sent from the serial monitor, reset both back to zero.
if (Serial.available()) {
Serial.read();
Serial.println("Reset both knobs to zero");
solSayici.write(0);
sagSayici.write(0);
}
/******** Otonom - Manuel Kullanim ayarlamasi ****/
if (btStateValue == 'A')
kontrolYontemi = 'A';
else if (btStateValue == 'M')
kontrolYontemi = 'M';
/*************** Manuel Kullanim *****************/
if (kontrolYontemi == 'M') {
int solMesafe = solSensor.readRangeContinuousMillimeters();
Serial.print("\t solMesafe:");
Serial.print(solMesafe);
int sagMesafe = sagSensor.readRangeContinuousMillimeters();
Serial.print("\t sagMesafe:");
Serial.print(sagMesafe);
int onMesafe = lidarValue;
delay(100); //gecikme verilemdiginde VLX ler mesafe okumuyor, VLX Teensynin hizina cikamiyor!!!
Serial.print("\t onMesafe:");
Serial.println(onMesafe);
if (btStateValue == 'F') { // If btStateValue is equal to 'F', go forward
solSayici.write(0);
sagSayici.write(0);
mevcutIslem = 1;
tolerans = TOLERANS_DUZ;
sagHiz = baslangicHizi; // hizlar hiz1,2 diye devam edebilir mi?
solHiz = baslangicHizi;
motorlariAyarla(true);
}
else if (btStateValue == 'B') { //If btStateValue is equal to 'B', go backward
solSayici.write(0);
sagSayici.write(0);
mevcutIslem = 2;
tolerans = TOLERANS_DUZ;
sagHiz = baslangicHizi; // hizlar hiz1,2 diye devam edebilir mi?
solHiz = baslangicHizi;
motorlariAyarla(false);
}
else if (btStateValue == 'R') { //If btStateValue is equal to 'R', turn right
solSayici.write(0);
sagSayici.write(0);
mevcutIslem = 3; //saga veya sola donecek
tolerans = TOLERANS_180;
ileriVirajBaslat(90);
}
else if (btStateValue == 'L') { //If btStateValue is equal to 'L', turn left
solSayici.write(0);
sagSayici.write(0);
mevcutIslem = 3; //saga veya sola donecek
tolerans = TOLERANS_180;
ileriVirajBaslat(-90);
}
else if (btStateValue == 'S') { //If btStateValue is equal to 'S', stop
solSayici.write(0);
sagSayici.write(0);
mevcutIslem = 0;
sagHiz = 0;
solHiz = 0;
motorlariAyarla(true);
}
if (((mevcutIslem == 1) || (mevcutIslem == 2)) && (solSayac != eskiSolSayac || sagSayac != eskiSagSayac)) {
//ileri veya geri gidiyor ve sag veya sol sayactan biri değişti ise düz gitmeyi sagla...
yamuklukDuzelt();
}
}
/********* OTOMATIK MODE **************/
else {
engelKontrol_1();
}
}
int engelKontrol_1(){
//0:engel yok, 1:sadece onde, 10:sadece sol, 11:sadece on & sol,
//20:sadece sag, 21:sadece on & sag, 30:sag & sol,
//31: hertaraf
int sonuc=0;
int solUzaklik = solSensor.readRangeContinuousMillimeters();
Serial.print("\t solMesafe:");
Serial.print(solUzaklik);
int sagUzaklik = sagSensor.readRangeContinuousMillimeters();
Serial.print("\t sagMesafe:");
Serial.print(sagUzaklik);
int onUzaklik = lidarValue;
delay(100); //gecikme verilemdiginde VLX ler mesafe okumuyor, VLX Teensynin hizina cikamiyor!!!
Serial.print("\t onMesafe:");
Serial.println(onUzaklik);
if (onUzaklik > 400)
{ //onde engel yok
digitalWrite(onLED, LOW);
}
else
{
sonuc = 1;
digitalWrite(onLED, HIGH);
}
if (solUzaklik > 700)
{ //solda engel yok
digitalWrite(solLED, LOW);
}
else {
sonuc += 10;
digitalWrite(solLED, HIGH);
}
if (sagUzaklik > 700){ //sagda engel yok
digitalWrite(sagLED, LOW);
}
else {
sonuc += 20;
digitalWrite(sagLED, HIGH);
}
return sonuc;
}
void readLiDAR() {
// Data Format for Benewake TFmini
// ===============================
// 9 bytes total per message:
// 1) 0x59
// 2) 0x59
// 3) Dist_L (low 8bit)
// 4) Dist_H (high 8bit)
// 5) Strength_L (low 8bit)
// 6) Strength_H (high 8bit)
// 7) Reserved bytes
// 8) Original signal quality degree
// 9) Checksum parity bit (low 8bit), Checksum = Byte1 + Byte2 +...+Byte8. This is only a low 8bit though
while (1) { // Keep going for ever
while (Serial1.available() >= 9) // When at least 9 bytes of data available (expected number of bytes for 1 signal), then read
{
if ((0x59 == Serial1.read()) && (0x59 == Serial1.read())) // byte 1 and byte 2
{
unsigned int t1 = Serial1.read(); // byte 3 = Dist_L
unsigned int t2 = Serial1.read(); // byte 4 = Dist_H
t2 <<= 8;
t2 += t1;
lidarValue = t2;
t1 = Serial1.read(); // byte 5 = Strength_L
t2 = Serial1.read(); // byte 6 = Strength_H
t2 <<= 8;
t2 += t1;
for (int i = 0; i < 3; i++)Serial1.read(); // byte 7, 8, 9 are ignored
}
}
}
}
1-Are there any wire1/2.h and .cpp files that can be share with us?
2- Are there any critical coding when I use more than one I2C? can you share if there is a sample code that uses more than one I2C?
3- do I need to use pull-up resirtors for my SDA-SCL line in my board because of internall pull-up resistor in the teensy/VL53L0X/LCD board?
some part of my code:
#include <Wire.h>
#include <VL53L0X.h>
#include <Encoder.h>
#include <Arduino.h>
#include <TeensyThreads.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27,20,4);
//#define XSHUT girisleri sensorun adreslemesi icin kullaniliyor.
#define solXSHUT_pini 21
#define sagXSHUT_pini 20
#define solSensorAdresi 42 //ilk VLX adresi her zaman 41
#define onsolSensorAdresi 43
#define onsagSensorAdresi 43
#define btStatePin 35
#define altSag 37
/********* Motor ***************/
Encoder solSayici(28, 27);
#define motorSolHiz 5 // enable1
#define motorSol1 6 // motor1geri
#define motorSol2 7 // motor1ileri //Sag
Encoder sagSayici(29, 30);
#define motorSag1 8 // motor2geri
#define motorSag2 9 // motor2iler //sol
#define motorSagHiz 10 // enable2
#define solLED 26
#define onsolLED 25
#define onLED 24
#define onsagLED 12
#define sagLED 11
#define altSagLED 2
#define altSolLED 3
VL53L0X sagSensor;
VL53L0X solSensor;
VL53L0X onsagSensor;
VL53L0X onsolSensor;
//Programda kullanilan islevler tanimlaniyor
void motorlariAyarla(boolean ileri);
void toleransKontrol();
void yamuklukDuzelt();
void readLiDAR();
void kesme();
void engelKontrol();
int engelKontrol_1();
volatile int lidarValue = 0;
/***** BT *****/
int btStateValue;
boolean taramaBayragi = true; // sagdan veya soldan donecegini belirleyen bayrak
boolean yamukDuzeltiliyor = false;
/***** Mesafe parametreleri *****/
const int ENGELMESAFE_ON = 400;
const int ENGELMESAFE_YAN = 100;
const int ENGELMESAFE_YAN_DONUS = 700;
void setup() {
Wire.begin();
Serial.begin(115200); // Serial output through USB to computer
Serial1.begin(115200); // Serial communmication of LIDAR
Serial5.begin(9600); // Serial communmication of BT
pinMode(btStatePin, INPUT); //BT
/************************ VLX ***************/
//Shutdown pins of VL53L0X ACTIVE-LOW-ONLY NO TOLERANT TO 5V will fry them
pinMode(sagXSHUT_pini, OUTPUT);
pinMode(solXSHUT_pini, OUTPUT);
pinMode(onsagXSHUT_pini, OUTPUT);
pinMode(onsolXSHUT_pini, OUTPUT);
pinMode(onsolXSHUT_pini, INPUT);
delay(10);
solSensor.setAddress(onsolSensorAdresi);
pinMode(onsagXSHUT_pini, INPUT);
delay(10);
solSensor.setAddress(onsagSensorAdresi);
pinMode(solXSHUT_pini, INPUT);
delay(10);
solSensor.setAddress(solSensorAdresi);
pinMode(sagXSHUT_pini, INPUT);
delay(10);
sagSensor.init();
solSensor.init();
onsagSensor.init();
onsolSensor.init();
sagSensor.setTimeout(500);
solSensor.setTimeout(500);
onsagSensor.setTimeout(500);
onsolSensor.setTimeout(500);
sagSensor.startContinuous();
solSensor.startContinuous();
onsagSensor.startContinuous();
onsolSensor.startContinuous();
/***************** LIDAR ********************/
delay (100); // Give a little time for things to start
// Set to Standard Output mode
Serial1.write(0x42);
Serial1.write(0x57);
Serial1.write(0x02);
Serial1.write(0x00);
Serial1.write(0x00);
Serial1.write(0x00);
Serial1.write(0x01);
Serial1.write(0x06);
// Setup thread for reading serial input from TFmini
threads.addThread(readLiDAR);
/************ Sharp **********/
pinMode(altSag, INPUT);
//pinMode(altSol, INPUT);
attachInterrupt(altSag, kesme, LOW); //gercekte HIGH olacak
//attachInterrupt(altSol, kesme, LOW);
/*********** LCD *************/
lcd.init(); // initialize the lcd
lcd.backlight();
// Print a message to the LCD.
lcd.setCursor(0, 0);
lcd.print("2-Line DISPLAY");
delay(500);
lcd.setCursor(0, 1);
lcd.print("VLX 1:");
delay(500);
lcd.setCursor(10, 1);
lcd.print("VLX 2:");
delay(500);
lcd.setCursor(0, 2);
lcd.print("VLX 3:");
delay(500);
lcd.setCursor(10, 2);
lcd.print("VLX 4:");
delay(500);
lcd.setCursor(0, 3);
lcd.print("LIDAR:");
lcd.print(lidarValue);
delay(500);
}
void loop() {
btStateValue = Serial5.read();
/*** Enkoder islemleri ******/
solSayac = solSayici.read();
sagSayac = sagSayici.read();
if (solSayac != eskiSolSayac || sagSayac != eskiSagSayac) {
eskiSolSayac = solSayac;
eskiSagSayac = sagSayac;
}
// if a character is sent from the serial monitor, reset both back to zero.
if (Serial.available()) {
Serial.read();
Serial.println("Reset both knobs to zero");
solSayici.write(0);
sagSayici.write(0);
}
/******** Otonom - Manuel Kullanim ayarlamasi ****/
if (btStateValue == 'A')
kontrolYontemi = 'A';
else if (btStateValue == 'M')
kontrolYontemi = 'M';
/*************** Manuel Kullanim *****************/
if (kontrolYontemi == 'M') {
int solMesafe = solSensor.readRangeContinuousMillimeters();
Serial.print("\t solMesafe:");
Serial.print(solMesafe);
int sagMesafe = sagSensor.readRangeContinuousMillimeters();
Serial.print("\t sagMesafe:");
Serial.print(sagMesafe);
int onMesafe = lidarValue;
delay(100); //gecikme verilemdiginde VLX ler mesafe okumuyor, VLX Teensynin hizina cikamiyor!!!
Serial.print("\t onMesafe:");
Serial.println(onMesafe);
if (btStateValue == 'F') { // If btStateValue is equal to 'F', go forward
solSayici.write(0);
sagSayici.write(0);
mevcutIslem = 1;
tolerans = TOLERANS_DUZ;
sagHiz = baslangicHizi; // hizlar hiz1,2 diye devam edebilir mi?
solHiz = baslangicHizi;
motorlariAyarla(true);
}
else if (btStateValue == 'B') { //If btStateValue is equal to 'B', go backward
solSayici.write(0);
sagSayici.write(0);
mevcutIslem = 2;
tolerans = TOLERANS_DUZ;
sagHiz = baslangicHizi; // hizlar hiz1,2 diye devam edebilir mi?
solHiz = baslangicHizi;
motorlariAyarla(false);
}
else if (btStateValue == 'R') { //If btStateValue is equal to 'R', turn right
solSayici.write(0);
sagSayici.write(0);
mevcutIslem = 3; //saga veya sola donecek
tolerans = TOLERANS_180;
ileriVirajBaslat(90);
}
else if (btStateValue == 'L') { //If btStateValue is equal to 'L', turn left
solSayici.write(0);
sagSayici.write(0);
mevcutIslem = 3; //saga veya sola donecek
tolerans = TOLERANS_180;
ileriVirajBaslat(-90);
}
else if (btStateValue == 'S') { //If btStateValue is equal to 'S', stop
solSayici.write(0);
sagSayici.write(0);
mevcutIslem = 0;
sagHiz = 0;
solHiz = 0;
motorlariAyarla(true);
}
if (((mevcutIslem == 1) || (mevcutIslem == 2)) && (solSayac != eskiSolSayac || sagSayac != eskiSagSayac)) {
//ileri veya geri gidiyor ve sag veya sol sayactan biri değişti ise düz gitmeyi sagla...
yamuklukDuzelt();
}
}
/********* OTOMATIK MODE **************/
else {
engelKontrol_1();
}
}
int engelKontrol_1(){
//0:engel yok, 1:sadece onde, 10:sadece sol, 11:sadece on & sol,
//20:sadece sag, 21:sadece on & sag, 30:sag & sol,
//31: hertaraf
int sonuc=0;
int solUzaklik = solSensor.readRangeContinuousMillimeters();
Serial.print("\t solMesafe:");
Serial.print(solUzaklik);
int sagUzaklik = sagSensor.readRangeContinuousMillimeters();
Serial.print("\t sagMesafe:");
Serial.print(sagUzaklik);
int onUzaklik = lidarValue;
delay(100); //gecikme verilemdiginde VLX ler mesafe okumuyor, VLX Teensynin hizina cikamiyor!!!
Serial.print("\t onMesafe:");
Serial.println(onUzaklik);
if (onUzaklik > 400)
{ //onde engel yok
digitalWrite(onLED, LOW);
}
else
{
sonuc = 1;
digitalWrite(onLED, HIGH);
}
if (solUzaklik > 700)
{ //solda engel yok
digitalWrite(solLED, LOW);
}
else {
sonuc += 10;
digitalWrite(solLED, HIGH);
}
if (sagUzaklik > 700){ //sagda engel yok
digitalWrite(sagLED, LOW);
}
else {
sonuc += 20;
digitalWrite(sagLED, HIGH);
}
return sonuc;
}
void readLiDAR() {
// Data Format for Benewake TFmini
// ===============================
// 9 bytes total per message:
// 1) 0x59
// 2) 0x59
// 3) Dist_L (low 8bit)
// 4) Dist_H (high 8bit)
// 5) Strength_L (low 8bit)
// 6) Strength_H (high 8bit)
// 7) Reserved bytes
// 8) Original signal quality degree
// 9) Checksum parity bit (low 8bit), Checksum = Byte1 + Byte2 +...+Byte8. This is only a low 8bit though
while (1) { // Keep going for ever
while (Serial1.available() >= 9) // When at least 9 bytes of data available (expected number of bytes for 1 signal), then read
{
if ((0x59 == Serial1.read()) && (0x59 == Serial1.read())) // byte 1 and byte 2
{
unsigned int t1 = Serial1.read(); // byte 3 = Dist_L
unsigned int t2 = Serial1.read(); // byte 4 = Dist_H
t2 <<= 8;
t2 += t1;
lidarValue = t2;
t1 = Serial1.read(); // byte 5 = Strength_L
t2 = Serial1.read(); // byte 6 = Strength_H
t2 <<= 8;
t2 += t1;
for (int i = 0; i < 3; i++)Serial1.read(); // byte 7, 8, 9 are ignored
}
}
}
}