Reading values from Arduino nano 33 IOT while usign AS5600 seosnors and OPTO sensors ( OPB745WZ)

Hello,

I was wondering if anyone could help me or provide feedback on how to read two values of sensors that have totally opposite timing. One reading is coming from a DC motor, and another is coming from sprockets attached to the DC motor. The goal is to have both data at the same time.

I want to know how I can read the values coming from the AS5600 sensor and OPTO sensors simultaneously that does not affect any of the sensors; in this case, my AS5600 sensor reads data every 10th of a millisecond and the OPB745WZ sensor reads data every 1000 millisecond which is mounted on top of the 16 tooth sprocket. If I try to match the AS5600 sensor reading with OPTO sensor I will experience the Nyquist effect for the RPM of the dc motors at higher rpm where this dc motor is very effective by the voltage of batteries so the rpm of the dc motor will be at the higher pick of the 3000 rpm at 37 volts and can reach to the 800 rpm at 35.9 volts this relation can affect the gearbox that has two sets of the sprocket that are connected by a chain. So I would love to see both effects at the same time. Where later on, I can add my sensor on batties as well to get the reading of all three at the same time; I will attach my code here later on, I will be reading data through the IOT cloud arduino after figuring out the timing

 //#define IR_LED_PIN  9    // Pin connected to the LED anode of QRB1114 (via 470Ω resistor)
//#include <WiFiNINA.h>
#include <Wire.h>
#include "AS5600.h"
// #include <rtc_clock.h>
//#include <TimeLib.h>

#define SENSOR_PIN1  A1    // Analog pin connected to the collector of the phototransistor (via 10kΩ pull-up resistor)
#define SENSOR_PIN2  A2    // Analog pin connected to the collector of the phototransistor (via 10kΩ pull-up resistor)

const int threshold1 = 100; // Adjust based on calibration
volatile int toothCount1= 0;    // Counter for the number of teeth detected
int numberOfTeeth1 = 16; // Replace with the actual number of teeth on your sprocket
bool tooth_detection1 = false;
const int threshold2 = 150; // Adjust based on calibration
volatile int toothCount2= 0;    // Counter for the number of teeth detected
int numberOfTeeth2 = 16; // Replace with the actual number of teeth on your sprocket
bool tooth_detection2 = false;


unsigned long previousMillis_IR = 0; // Store the last time RPM was calculated
const int measurementInterval_IR = 1000;//1000; // Time interval for RPM measurement in milliseconds


#define TCAADDR 0x70  // I2C multiplexer address

AS5600L sensor1;  // Motor 1
AS5600L sensor2;  // Motor 2

int I2CA = 5;  // Sensor 1 channel
int I2CB = 7;  // Sensor 2 channel

// Timing and filtering
unsigned long lastTime_magnet = 0;
const unsigned long intervalmag = 10;  // 100 ms for stable RPM
float filteredRPM1 = 0, filteredRPM2 = 0;
const float alpha = 0.05;  // Smoothing factor
int lastAngle =0;
int cumulativePos2 = 0;


void TCA9548(int bus) {
  if (bus < 0 || bus > 7) return;
  Wire.beginTransmission(TCAADDR);
  Wire.write(1 << bus);
  Wire.endTransmission();
  delay(1);
}

void setup() {
  // pinMode(IR_LED_PIN, OUTPUT);  // Set the LED pin as an output
  // digitalWrite(IR_LED_PIN, HIGH);  // Turn on the IR LED continuously

  pinMode(SENSOR_PIN1, INPUT);  // Set sensor pin as input
  pinMode(SENSOR_PIN2, INPUT);  // Set sensor pin as input
  Serial.begin(115200);  // Begin serial communication for monitoring
  Wire.begin();
  Wire.setClock(400000);

  // --- Sensor_magnet 1 Setup ---
  TCA9548(I2CA);
  sensor1.begin(4);
  sensor1.setDirection(AS5600_CLOCK_WISE);  // Match physical rotation
  sensor1.setAddress(0x36);
  sensor1.setConfigure(0x1f00);
  if (!sensor1.isConnected()) {
     while(1);
    //  {
    //   // Serial.println("Sensor 1 not found!");
    //   // delay(1000);
    //   }
  }
  sensor1.resetCumulativePosition();  // Reset internal tracking
  // --- Sensor_magnet 2 Setup ---
  TCA9548(I2CB);
  sensor2.begin(4);
  sensor2.setDirection(AS5600_CLOCK_WISE);
  sensor2.setAddress(0x36);
  // sensor1.setConfigure(0x1f00);
  if (!sensor2.isConnected()) {
    // Serial.println("Sensor 2 not found!");
    while(1);
  }
  sensor2.resetCumulativePosition();
  lastAngle = sensor2.rawAngle();
  lastTime_magnet = millis();
  // Serial.println("Setup complete.");

  // setTime(8, 21, 0, 25, 2, 2025); // set initial time to 12:00:00 on January 1, 2020

}

void loop() {
  // Read the sensor value (analog)
  int sensorValue1 = analogRead(SENSOR_PIN1);
  int sensorValue2 = analogRead(SENSOR_PIN2);
  
  unsigned long currentTime1 = millis();

  if (currentTime1 - lastTime_magnet >= intervalmag) {
    lastTime_magnet = currentTime1;
    // float dt = (currentTime - lastTime) / 5000.0;  // Convert to seconds
      // --- Read Sensor 1 ---
    TCA9548(I2CA);
    long cp1 = sensor1.getCumulativePosition();
    float rev1 = sensor1.getRevolutions();  // Uses library's overflow handling
    float rpm1 = sensor1.getAngularSpeed(AS5600_MODE_RPM);  // Built-in RPM

    // --- Read Sensor 2 ---
    TCA9548(I2CB);
    //int currentAngle = sensor2.rawAngle();
    long cp2 = sensor2.getCumulativePosition()* float(-1);
    float rev2 = sensor2.getRevolutions()* float(-1);
    float rpm2 = sensor2.getAngularSpeed(AS5600_MODE_RPM) * float(-1);

    // Apply low-pass filter
    filteredRPM1 = (alpha * rpm1 + (1 - alpha) * filteredRPM1);
    filteredRPM2 = (alpha * rpm2 + (1 - alpha) * filteredRPM2);
    
    // lastAngle = currentAngle;
    
   // lastTime_magnet = currentTime;  // Update time for next interval
    // --- Output ---
    //  Serial.print("time run (min):,"); 
    //  Serial.print(minute()); // print current second
    //  Serial.print(",");
    //  Serial.print("Sensor 1 - Raw CP:,");
    //  Serial.print(cp1);
    //  Serial.print("|Revolutions1:|,");
    //  Serial.print(rev1);
    //  Serial.print("|RPM1_no_filter:|,");
     Serial.print("|,|");
    //  Serial.print("Sensor 1 - Raw CP:,");
      Serial.print(cp1);
     
      Serial.print("|,|");
    // //  Serial.print("|Revolutions1:|,");
      Serial.print(rev1);
    // //  Serial.print("|RPM1_no_filter:|,");
     Serial.print("|,|");
     Serial.print(rpm1);
     Serial.print("|,|");
    //  Serial.print("|RPM1_filter:|,");
     Serial.print(filteredRPM1);
     Serial.print("|,|");
    //  Serial.print("|,");
    //  Serial.print("Sensor 2 - Raw CP:,");
     Serial.print(cp2);
    // //  // Output: diff, cumulative revolutions, rev2, rpm22, filteredRPM2
    // //  Serial.print(",");
    // //   Serial.print("|Revolutions2:|");
    // //   // Serial.print(cumulativePos2 / 4096.0);
    // //   // Serial.print(",");
    // //   //Serial.print("3800, -3800,");
     Serial.print("|,|");
      Serial.print(rev2);

       Serial.print("|,|");
    // //   Serial.print("|RPM2_no_filter:|");
        Serial.print(rpm2);
       Serial.print("|,|");
    // //   Serial.print("|RPM2_no_filter:|,");
        Serial.println(filteredRPM2);
  }

 
 //// Check if the sensor detects a tooth
  if (sensorValue > threshold) { // Adjust this threshold based on your testing
    toothCount++;
    delayMicroseconds(50);  // Use a microsecond delay instead of delay(10)
    //delay(10); // Debounce delay to avoid counting the same tooth multiple times
  }
    if ((!tooth_detection1) && (sensorValue1 > threshold1)){
      tooth_detection1 = true;
      toothCount1++;
      //delay(10);
    }
  if ((tooth_detection1) && (sensorValue1 < (threshold1-30) )){
        tooth_detection1 = false;
      }

      if ((!tooth_detection2) && (sensorValue2 > threshold2)){
      tooth_detection2 = true;
      toothCount2++;
      //  delay(10);
    }
  if ((tooth_detection2) && (sensorValue2 < (threshold2-50) )){
        tooth_detection2 = false;
        //  delayMicroseconds(10);
      }
  // Check if it's time to calculate RPM
  // unsigned long currentTime = millis(); //millis();
  unsigned long currentTime = millis();
  if (currentTime - previousMillis_IR >= 1000) {
     // Calculate RPM
    previousMillis_IR = currentTime;
    float rpm11 = 5.5*(toothCount1 / (float)numberOfTeeth1) * (73.3);
    float rpm22 = 1.7*(toothCount2 / (float)numberOfTeeth2) * (60.7);
     
     Serial.print("time run (min) :,"); 
     Serial.print(minute()); // print current second

     //  Serial.print("tooth_Count1,");
     Serial.print(",");
     Serial.print(toothCount1);
     Serial.print("RPM1,");
     Serial.print(",");
     Serial.print(rpm11);
     Serial.print("|,");
     Serial.print("|tooth_Count2|,");
     Serial.print(",");
     Serial.print(toothCount2);
     Serial.print("RPM2,");
     Serial.print(",");
     Serial.println(rpm22);
     
    // // Reset the tooth count for the next measurement
    toothCount1 = 0;
    toothCount2 = 0;
    
  }



}

would appreciate any help.

Your topic does not indicate a problem with IDE 2.x and hence has been moved to a more suitable location on the forum.

I did see an attempt at using code tags but it did not work out. I've fixed it for you.

Code tags for a block of code are three back ticks (```) before and after the code; they need to be on their own line.

Thank you so much

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