Arduino Uno and Nano connect to ADXL 345 I2C

Hi there as many people I am new to Arduino programming and have been doing research but to no avail. I have a project where I need to connect and Arduino Uno and an Arduino Nano to 1 ADXL 345 accelerometer. I need to be able to get the same x y z coordinates displayed in visual basic using 1 form and 2 graphs, I also need to be a be able to export these values for further analyzing. Since I am using two Arduino Boards I am also force to utilizing 2 com ports. The way I am accomplishing this goal is by running 2 Arduino IDE program simultaneously, however there is a big issue with lag. Is there a way to be able to read the data simultaneously and send it to visual studio without any lag?
The second issue that I'm also experiencing seems to be with VB or Arduino I'm not sure but just in case I can also get help on that I will post the question as well. I notice that there are times when Visual studio seem to not grab the X1 at the right time. For example my X1 Value should always be the first value sent to VB by Arduino but there are times where the first value sent is the Y1 or at times the Z1 therefore I had to implement a loop to check all 3 lines to be able to locate the X1 value. There has been instances where the Data given is as shown "X1=0.03 Y1=0.05 Z1=3.02" which is perfect displayed but then on the second loop it would probably show as "=0.03 Y1=0.05 Z1=3.02" it would erase the remaining values or even erase the X1 so in this instance none of my loops would locate and X1 value and it would just use the last recorded value stored in X1 which is inaccurate, I've found that if I delay by 100 in Arduino and collect the data in VB at 10 interval this issue doesn't occur. However my professor has informed me that no delay can be used in vibration. Can someone determine if this a coding problem in Arduino? is it a code issue with Arduino or VB? Note to save space I've deleted the VB codes i deemed unnecessary, the VB code given shows in what variable the data is stored and how it is displayed in the TEXTBOX for both COM PORT 5 and 6.
Code 1

/*
    Arduino and ADXL345 Accelerometer Tutorial
*/
#include <Wire.h>  // Wire library - used for I2C communication
int ADXL345 = 0x53; // The ADXL345 sensor I2C address
float X_out, Y_out, Z_out;  // Outputs
float X1, Y1, Z1;
void setup() {
  Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor
  Wire.begin(); // Initiate the Wire library
  // Set ADXL345 in measuring mode
  Wire.beginTransmission(ADXL345); // Start communicating with the device
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  // Enable measurement
  Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable
  Wire.endTransmission();


}
void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  X_out = ( Wire.read() | Wire.read() << 8); // X-axis value
  X1 = X_out / 256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Y_out = ( Wire.read() | Wire.read() << 8); // Y-axis value
  Y1 = Y_out / 256;
  Z_out = ( Wire.read() | Wire.read() << 8); // Z-axis value
  Z1 = Z_out / 256;
  Serial.print("X1");
  Serial.println(X1);
  Serial.print("Y1");
  Serial.println(Y1);
  Serial.print("Z1");
  Serial.println(Z1);


}

Code 2

/*
    Arduino and ADXL345 Accelerometer Tutorial

*/
#include <Wire.h>  // Wire library - used for I2C communication
int ADXL345 = 0x53; // The ADXL345 sensor I2C address
float X_out, Y_out, Z_out;  // Outputs
float X2,Y2,Z2;
void setup() {
  Serial.begin(9600); // Initiate serial communication for printing the results on the Serial monitor
  Wire.begin(); // Initiate the Wire library
  // Set ADXL345 in measuring mode
  Wire.beginTransmission(ADXL345); // Start communicating with the device 
  Wire.write(0x2D); // Access/ talk to POWER_CTL Register - 0x2D
  // Enable measurement
  Wire.write(8); // (8dec -> 0000 1000 binary) Bit D3 High for measuring enable 
  Wire.endTransmission();


}
void loop() {
  // === Read acceleromter data === //
  Wire.beginTransmission(ADXL345);
  Wire.write(0x32); // Start with register 0x32 (ACCEL_XOUT_H)
  Wire.endTransmission(false);
  Wire.requestFrom(ADXL345, 6, true); // Read 6 registers total, each axis value is stored in 2 registers
  X_out = ( Wire.read()| Wire.read() << 8); // X-axis value
  X2 = X_out/256; //For a range of +-2g, we need to divide the raw values by 256, according to the datasheet
  Y_out = ( Wire.read()| Wire.read() << 8); // Y-axis value
  Y2 = Y_out/256;
  Z_out = ( Wire.read()| Wire.read() << 8); // Z-axis value
  Z2 = Z_out/256;
  Serial.print("X2");
  Serial.println(X2);
    Serial.print("Y2");
  Serial.println(Y2);
    Serial.print("Z2");
  Serial.println(Z2);


}

VB CODE

Public Class Form1

Private Sub TimerSerial_Tick(sender As Object, e As EventArgs) Handles TimerSerial.Tick
        Try
            Dim StrSerialIn As String = SerialPort1.ReadExisting
            Dim StrSerialInRam As String
            Dim StrSerialIn2 As String = SerialPort2.ReadExisting
            Dim StrSerialInRam2 As String




            Dim TB As New TextBox
            TB.Multiline = True
            TB.Text = StrSerialIn
            Dim TB2 As New TextBox
            TB2.Multiline = True
            TB2.Text = StrSerialIn2


'--------------------------COM 5

            StrSerialInRam = TB.Lines(0).Substring(0, 2)
            If StrSerialInRam = "X1" Then
                X_1 = TB.Lines(0)
                X_1L = X_1.Length
            Else
                StrSerialInRam = TB.Lines(1).Substring(0, 2)
                If StrSerialInRam = "X1" Then
                    X_1 = TB.Lines(1)
                    X_1L = X_1.Length
                Else
                    StrSerialInRam = TB.Lines(2).Substring(0, 2)
                    If StrSerialInRam = "X1" Then
                        X_1 = TB.Lines(2)
                        X_1L = X_1.Length
                    End If
                End If
            End If


            '-------------------
            StrSerialInRam = TB.Lines(0).Substring(0, 2)
            If StrSerialInRam = "Y1" Then
                Y_1 = TB.Lines(0)
                Y_1L = Y_1.Length
            Else
                StrSerialInRam = TB.Lines(1).Substring(0, 2)
                If StrSerialInRam = "Y1" Then
                    Y_1 = TB.Lines(1)
                    Y_1L = Y_1.Length
                Else
                    StrSerialInRam = TB.Lines(2).Substring(0, 2)
                    If StrSerialInRam = "Y1" Then
                        Y_1 = TB.Lines(2)
                        Y_1L = Y_1.Length
                    End If
                End If
            End If
            '----------------
            StrSerialInRam = TB.Lines(0).Substring(0, 2)
            If StrSerialInRam = "Z1" Then
                Z = TB.Lines(0)
                ZL = Z.Length
            Else
                StrSerialInRam = TB.Lines(1).Substring(0, 2)
                If StrSerialInRam = "Z1" Then
                    Z = TB.Lines(1)
                    ZL = Z.Length


                Else
                    StrSerialInRam = TB.Lines(2).Substring(0, 2)
                    If StrSerialInRam = "Z1" Then
                        Z = TB.Lines(2)
                        ZL = Z.Length
                    End If
                End If
            End If
 
            LabelX.Text = "X1 = " & Mid(X_1, 3, X_1L)
            LabelY.Text = "Y1 = " & Mid(Y_1, 3, Y_1L)
            LabelZ.Text = "Z1 = " & Mid(Z, 3, ZL)
            '--------------------------------------------------------------------------------------------- COM 6
            StrSerialInRam2 = TB2.Lines(0).Substring(0, 2)
            If StrSerialInRam2 = "X2" Then
                X_2 = TB2.Lines(0)
                X_2L = X_2.Length
            Else
                StrSerialInRam2 = TB2.Lines(1).Substring(0, 2)
                If StrSerialInRam2 = "X2" Then
                    X_2 = TB2.Lines(1)
                    X_2L = X_2.Length
                Else
                    StrSerialInRam2 = TB2.Lines(2).Substring(0, 2)
                    If StrSerialInRam2 = "X2" Then
                        X_2 = TB2.Lines(2)
                        X_2L = X_2.Length
                    End If
                End If
            End If

Great first post but I gave up reading at the second line as I ran out of breath.

Consider editing to make the text more readable please.

Why do you need to connect both an Uno and a Nano to the same sensor? Both Code1 and Code2 do the same thing so why not just send the data once to your PC and deal with it there? I am confused.

With this approach both the Uno and the Nano are masters on the i2c bus which can lead to issues.

blh64:
Why do you need to connect both an Uno and a Nano to the same sensor? Both Code1 and Code2 do the same thing so why not just send the data once to your PC and deal with it there? I am confused.

With this approach both the Uno and the Nano are masters on the i2c bus which can lead to issues.

The reason I'm connecting two arduino board is because when it's time to test the arruracy of the data received we will be using the arduino uno board and a separate DAQ system which has been proved to gather accurate data. Therefore I am doing the data build first using two different arduino board.

Code one and two are the same as you mentioned but I'm using 2 com ports, since I'm using 2 com ports I'm also using two instances of arduino IDE.

Question: if I use one arduino as the master and the other as the slave, will I be able to update the data simultaneously without lag ? Isn't the master code processed first then the slave's one which would bring about lag ?

ballscrewbob:
Great first post but I gave up reading at the second line as I ran out of breath.

Consider editing to make the text more readable please.

I know it's a lot to read an even take in, I've looked over it over and over to shorten the text but all information given was what I felt vital in understanding my issue. If how can I help to make you understand my question? You help is vital. Thanks

jamaya026:
The reason I'm connecting two arduino board is because when it's time to test the arruracy of the data received we will be using the arduino uno board and a separate DAQ system which has been proved to gather accurate data. Therefore I am doing the data build first using two different arduino board.

Code one and two are the same as you mentioned but I'm using 2 com ports, since I'm using 2 com ports I'm also using two instances of arduino IDE.

Question: if I use one arduino as the master and the other as the slave, will I be able to update the data simultaneously without lag ? Isn't the master code processed first then the slave's one which would bring about lag ?

This doesn't quite make sense. You are communicating with the sensor over i2c which has nothing to do with the accuracy of the sensor itself. Does this DAQ also connect to the same sensor over i2c or does this DAQ have some other sensor? If you truly only have this one sensor, it does not matter at all what other device asks for the data over i2c. Accuracy come in the actual conversion inside the chip.
As for making a master/slave arrangement, a slave would not be able to query the sensor for data. Only a master can do that. In a multi-master system, whenever either chip tries to take control of the i2c bus, they may collide, but ultimately one of them will succeed and the other will have to wait. Google "arduino multi-master i2c" for more info

You are allowed to use line breaks and paragraphs to make it easier to read.

blh64:
This doesn't quite make sense. You are communicating with the sensor over i2c which has nothing to do with the accuracy of the sensor itself. Does this DAQ also connect to the same sensor over i2c or does this DAQ have some other sensor? If you truly only have this one sensor, it does not matter at all what other device asks for the data over i2c. Accuracy come in the actual conversion inside the chip.
As for making a master/slave arrangement, a slave would not be able to query the sensor for data. Only a master can do that. In a multi-master system, whenever either chip tries to take control of the i2c bus, they may collide, but ultimately one of them will succeed and the other will have to wait. Google "arduino multi-master i2c" for more info

This other DAQ will be connected to the same sensor but the DAQ has some additionally built in features that help with calibration and shock. It's more of an industrial DAQ. If I do the multimaster as suggested and there is a possibility of both colliding wouldn't this cause lag which the initial problem I'm trying to solve ? Can you also advice why when the data is being transfered over to VB it seems to be deleting some of the value spat out by arduino. My gut tells me it has something to do with the speed of arduino and VB not coinciding but I'm unsure.

So the DAQ does some post processing/filtering on the exact same data? You could do the same thing. Fundamentally, if you are requesting the current reading over i2c from the same device, it is just transmitting the same value is has stored internally in some of its registers.

If you want faster transfer from Arduino to VB, up the serial baud rate. 9600 is painfully slow compared to how fast the processor is running. It may very well fill up the transmit buffer and cause your arduino code to block until there is room to transmit more. Go up to 115200 and adjust your VB code to the same.

At the core of it all, I think your approach of having two controllers requesting data from 1 sensor is flawed.

If you want the same data on two COM ports on the PC, only use one board (e.g. the Uno) and use a TTL-to-USB adaptor on the Uno's TX pin to connect it to the PC.

You can use the Nano as TTL-to-USB adaptor as well; connect the Uno's TX pin to the Nano's TX pin and keep the Nano permanently in reset.

blh64:
So the DAQ does some post processing/filtering on the exact same data? You could do the same thing. Fundamentally, if you are requesting the current reading over i2c from the same device, it is just transmitting the same value is has stored internally in some of its registers.

If you want faster transfer from Arduino to VB, up the serial baud rate. 9600 is painfully slow compared to how fast the processor is running. It may very well fill up the transmit buffer and cause your arduino code to block until there is room to transmit more. Go up to 115200 and adjust your VB code to the same.

At the core of it all, I think your approach of having two controllers requesting data from 1 sensor is flawed.

Yes to the filtering data question. Thanks again for your time and effort to help. So it would be advisable to do one sensor per board ? I was also thinking that it would probably be a lot more efficient to do the same the board's connected to the same sensor but running the IDEand VB on separate computers . I have a single chart version too That way there would be no lag an the data collected would be from the same sensor which makes the testing still accurate. I just thought what I was trying to do would be a breeze. Underestimated it.

sterretje:
If you want the same data on two COM ports on the PC, only use one board (e.g. the Uno) and use a TTL-to-USB adaptor on the Uno's TX pin to connect it to the PC.

You can use the Nano as TTL-to-USB adaptor as well; connect the Uno's TX pin to the Nano's TX pin and keep the Nano permanently in reset.

Since I'm new I'm uncertain of your answer. I'm sorry for my lack of knowledge I will surely research this but would it work without lag? Can you also provide a link to a diagram of what you explained ?

Your code will run on the UNO in below drawing; ADXL only connected to Uno.

Note:
I forgot to draw a ground between the Uno and the Nano; it's not strictly necessary as the ground connection between the two also happens via the PC.

The only lag will be caused by the difference between the two TTL-to-USB adapters on the Uno and the Nano.

sterretje:
Your code will run on the UNO in below drawing; ADXL only connected to Uno.

Note:
I forgot to draw a ground between the Uno and the Nano; it's not strictly necessary as the ground connection between the two also happens via the PC.

The only lag will be caused by the difference between the two TTL-to-USB adapters on the Uno and the Nano.

Thank you so much brother I'll look more info this and give it a go.

It would be easier to just use SoftwareSerial for the connection between the uno and Nano on pins other than the serial pins.

SoftwareSerial affects the performance of the code. And I find 3 wires easier :wink:

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