Multiple I2C communication, wire1 and wire2 files

Status
Not open for further replies.

vtavas

New member
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
}
}
}
}
 
Can you scope the i2c bus?

How many devices do you have on the i2c bus? Are you using the Adafruit modules? Do all of them have pull-up resistors?
 
1-Are there any wire1/2.h and .cpp files that can be share with us?

Wire.h has Wire1 and Wire2. No need to include more stuff to get the other ports.

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?

Wire1 and Wire2 work the same as regular Wire. There's nothing particularly special you need to do, other than use those names instead of regular Wire.

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?

Teensy 3.5 does not have built-in pullup resistors for the I2C ports. Each SDA & SCL line must have at least 1 real pullup resistor. If they're built into the modules, then you should be good to go. If you connect chips directly, or boards without the resistors, then you must add real pullup resistors.
 
I can not scope the i2c bus. I have 4 VL53L0X pololu modue, and one LCD I2C converter modüle. I am not using Adafruit modüle. I don't have any knowledge that my LCD I2C converter modüle hase any pull-up resistor. I think pololu VL53L0X modules have resistor of 10K.
 
Wire.h has Wire1 and Wire2. No need to include more stuff to get the other ports.

Wire1 and Wire2 work the same as regular Wire. There's nothing particularly special you need to do, other than use those names instead of regular Wire.


I examined the wire1 or wire2 with only one VL53L0X sensor but it did not work. I connected the sensor to SCL1/SDA1 for wire1 and SCL2/SDA2 for wire2. Only the sensor is connected to teensy 3.5 as a peripheral device, Teensyduino 1.42 and Arduino 1.8.5 are versions of IDE. What am I missing in the below code for wire1?


----

#include <Wire.h>
#include <VL53L0X.h>

VL53L0X sensor;


void setup()
{
Serial.begin(9600);
Wire1.begin();

sensor.init();
sensor.setTimeout(500);

#if defined LONG_RANGE

sensor.setSignalRateLimit(0.1);

sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodPreRange, 18);
sensor.setVcselPulsePeriod(VL53L0X::VcselPeriodFinalRange, 14);
#endif

#if defined HIGH_SPEED

sensor.setMeasurementTimingBudget(20000);
#elif defined HIGH_ACCURACY

sensor.setMeasurementTimingBudget(200000);
#endif
}

void loop()
{
Serial.print(sensor.readRangeSingleMillimeters());
if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }

Serial.println();
}
 
Status
Not open for further replies.
Back
Top