I need a code that can detect direction change, or sensor HIGH to LOW change.

I want to be able to use a sensor reading from my encoders, gyros, or laser distance sensors to make an event happen when they change direction. I have only been using Arduino for about 3 months. I have learned a lot of code and can make pretty much anything do what I want, except for detect the change in direction as a switch. I am really not interested in becoming a programmer, I just want to get this working for a project I am trying to complete.

For instance if my sensor was reading 100 101 102 103 102 101 100, I would want to instruct a servo or step motor to got to a certain position at the time it goes from 103 to 102.

Even if i could get an LED to light, I can easily write the rest. But this has been very frustrating try to figure out how to do this one.

I would be willing to pay someone to help me with this. Please don't send me to code links to make a servo or something follow an encoder or other sensor. That's not what I need.

Thanks

Dean Elliott

Depending on the encoder code you could sense direction and set/clear a boolean. If direction is CW set boolean true and vicey versey. Or, do the same by sensing if last reading (101) is less than current reading (102). IDE - file/examples/digital/state change detection may also be useful.

I have tried the state change example. It works great for button presses.

To better explain what I am doing; I am reading the swing of a pendulum. I want to activate a motor changing the center of mass precisely when the pendulum is at 0 gravity on each side. There by moving 33% of the overall mass to maximum gravitational potential when it is weightless. Kinda like a person on a swing that is always facing the center.

With an encoder I had it set up reading -90 to 90 with 0 being at the bottom of the swing. The frequency can change due to a load on the pendulum fulcrum slowing it down. I was able to set a if < or >reading on each side to move the mass. However that puts me at a fixed degrees. I want it to adapt to loads / frequency changes on the swing.

I don’t have the hardware hooked up right now but will dig through my sketches and find one of my failures.

I can measure the swing with a multitude of sensors, however when I try to capture the last reading vs the current reading. The last reading changes to the current reading. nothing in this particular code grabs last state. And some reed switches/buttons were removed.

//--------------------STEPPER Variables START------------------------- 
const int stepPin = 10;                           // DM542s PUL+ pin connected to stepper controller pin   //PUL- to Ground
const int dirPin = 11;                            // DM542s DIR+ pin connected to controller pin   //DIR- to Ground                   
const int enPin = 12;                             // DM542s ENA+ pin connected to controller pin   //ENA- to Ground
float pulsesR = 6400;                             // Number of pulses to send to stepPin PUL+ when DIR+ is HIGH
float pulsesL = 6400;                             // Number of pulses to send to stepPin PUL+ when DIR+ is LOW
const int pulsedelay = 0;                         // Delay time between Pulses sent to stepPin
int cycledelay= 20;                               // Delay time before stepper can reverse directions
//--------------------STEPPER Variables FINISH------------------------- 
//--------------------ENCODER Variables START------------------------- 
//float temp;
float counter;                                     // Count logger for steps taken by encoder.
int leftPin = 2;                                   // encoder data pin 
int rightPin = 3;                                  // encoder data pin 
// const int Home = 0;
float degree;  
//--------------------ENCODER Variables FINISH------------------------- 
//--------------------BUTTON Variables START------------------------- 
//--------------------BUTTON Variables FINISH------------------------- 
void setup() {
  Serial.begin(115200);
//--------------------BUTTON Setup START------------------------- 
  pinMode(6, INPUT_PULLUP);
  pinMode(7, OUTPUT);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, OUTPUT);  
  //--------------------BUTTON Setup FINISH------------------------- 
//--------------------STEPPER Setup START------------------------- 
  pinMode(stepPin,OUTPUT); 
  pinMode(dirPin,OUTPUT);

  pinMode(enPin,OUTPUT);
  digitalWrite(enPin,LOW);
//--------------------STEPPER Setup FINISH------------------------- 

//--------------------ENCODER Setup START------------------------- 
  pinMode(leftPin, INPUT_PULLUP);                   // internal pullup input pin leftPin 
  
  pinMode(rightPin, INPUT_PULLUP);                  // internal pullup input pin rightPin

  pinMode(Home,INPUT);
 
//Setting up interrupt
  //A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr leftPin on moust Arduino.
attachInterrupt(0, SwingRight, RISING);
 
  //B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr rightPin on moust Arduino.
attachInterrupt(1, SwingLeft, RISING);
//--------------------ENCODER Setup FINISH-------------------------
}
void loop() {

//--------------------ENCODER Loop START------------------------- 
     
     degree = counter /2 ;

//--------------------ENCODER Loop FINISH------------------------- 

//--------------------STEPPER Loop START--------------------------
//--------------------STEPPER Right START--------------------------
  int sensorVal6 = digitalRead(6);    //Button Input 
  if (sensorVal6 == LOW) {
  digitalWrite(dirPin,HIGH);                       // Enables the motor to move in a particular direction
                                                   // 200 number of pulses for making one full cycle rotation
  for(int x = 0; x < pulsesR; x++) {
    digitalWrite(stepPin,HIGH);                    // write pulses to stepper pin 5 moving ccw right
    delayMicroseconds(pulsedelay); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(pulsedelay); 
    digitalWrite(7, HIGH);
    }
      
        } else {
    digitalWrite(7, LOW);
    delay (50);
    }  
   delay(cycledelay);                                      //Delay before rotaion of stepper can reverse
//--------------------STEPPER Right Finish--------------------------
//--------------------STEPPER Left START--------------------------
  int sensorVal4 = digitalRead(4);
   if (sensorVal4 == LOW) {
  digitalWrite(dirPin,LOW);                                //Changes the rotations direction
                                                           // 400 pulses for making two full cycle rotation
  for(int x = 0; x < pulsesL; x++) {
    digitalWrite(stepPin,HIGH);                            // write pulses to stepper pin 5 moving ccw right
    delayMicroseconds(pulsedelay);                         // delay between steps sent to motor (speed)
    digitalWrite(stepPin,LOW);
    delayMicroseconds(pulsedelay);
    digitalWrite(5, HIGH);                            
    }
        
      } else {
    digitalWrite(5, LOW);
    }
  delay(cycledelay);                                  // Delay before rotaion of stepper can reverse
//--------------------STEPPER Left Finish--------------------------
}
//--------------------STEPPER Loop FINISH--------------------------

//--------------------ENCODER SwingRight Interrupt START------------------------ 
void SwingRight() {
                                                       // ai0 is activated if DigitalPin nr leftPin is going from LOW to HIGH
                                                       // Check pin rightPin to determine the direction
  if(digitalRead(rightPin) == LOW) {
  counter++;
     Serial.print("                            SwingingRight at ");
        Serial.println (degree,0);
  }else{
  counter--;
  }
  }
 //--------------------ENCODER SwingRight Interrupt FINISH------------------------
 //--------------------ENCODER SwingLeft Interrupt START------------------------  
  void SwingLeft() {
                                                      // ai0 is activated if DigitalPin nr rightPin is going from LOW to HIGH
                                                      // Check with pin leftPin to determine the direction
  if(digitalRead(leftPin) == LOW) {
     counter--;
   Serial.print("SwingingLeft at ");
     Serial.println (degree,0);
  }else{
  counter++;
  }
  }
//--------------------ENCODER Swingleft INterrupt FINISH------------------------

There are some issues to be resolved with your ISR(s).

  • Using serial.Print()inside an ISR is a bad idea since print also uses interrupts and it takes a long time compared other things going on. A guiding principle with ISR's is to do the minimum required - in this case, record for processing elsewhere that a transition was sensed at the encoder and update the current position then - get out.

  • Variables changed inside the ISR and used elsewhere should be declared with the volatile keyword.

  • Your ISR construction is ... unusual, to my eye. The interrupts are declared as RISING, which means they'll be HIGH yet you're testing to see if they're low.

  • Also, the two encoder signals are normally used in concert, as in if B just *changed * the state of A determines CW/CCW direction.

some links to encoder info : https://www.pjrc.com/teensy/td_libs_Encoder.html http://www.mathertel.de/Arduino/RotaryEncoderLibrary.aspx

if ($now > $last) { // did angle increase? then;

$last = $now  // update $last variable

}

else { // if no increase then;

$max_angle = $last  // save $last variable

}

Is this what you are looking for?

dougp, The Using serial.Print() was int the codes I Frankensteined. I realized it slowed it down and left it there to slow things down when I was experimenting obviously there would be no serial prints in the finished code.

The code actually runs perfectly, its just not what i need to do. I don’t know what code you mean in the interrupts used elsewhere, other than the prints which are there for visual testing only.

I appreciate your input. But keep in mind I’m not a programmer. That’s why my code probably looks so weird. I’m self taught over the last couple months.

The interrupts rising seems to work very well the way it was written. But may not work for my end needs.

I have a lot of different sensors and my only objective in this particular post is to figure out a way to continuously read the last value and compare it to the current value. When current reading is < or = last reading on right/ccw or > or = last reading on left/cw to trigger a if’ write function or boolean value. I am using a latching switch at 0 during each swing its LOW when 0 to -90 and HIGH when 0 to 90 for && condition.

Using rotary encoder LPD3806-360BM-G5-24C
Using stepper driver dm542S
Also have used i2c laser distance sensor CJUL53LOX V2 in place of encoder.
Also have used gyro accelerometer GY-521 MPU6050_tockn.h in place of the encoder.

I can make any device follow correspond to the data input but just can’t seem to capture the switch state of direction change at the reading right and left extents.

Thanks for your input.

TechnoMonkeys, Thanks so much for your reply. It looks like a simple solution to my dilemma. I will try this and see if i can figure out how to use it. I will start by trying to make it work with this example code.

Would you mind showing me how to insert it into this example code?

/* This example shows how to use continuous mode to take
range measurements with the VL53L0X. It is based on
vl53l0x_ContinuousRanging_Example.c from the VL53L0X API.

The range readings are in units of mm. */

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

VL53L0X sensor;

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

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

  // Start continuous back-to-back mode (take readings as
  // fast as possible).  To use continuous timed mode
  // instead, provide a desired inter-measurement period in
  // ms (e.g. sensor.startContinuous(100)).
  sensor.startContinuous();
}

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

  Serial.println();
}

TechnoMonkeys, This is my first attempt I guess I was close before and just didn’t realize it. This should get me on the right track. At least its working. Any other tips? Now i need to make it work in both directions.

/* This example shows how to use continuous mode to take
  range measurements with the VL53L0X. It is based on
  vl53l0x_ContinuousRanging_Example.c from the VL53L0X API.

  The range readings are in units of mm. */

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

VL53L0X sensor;
float sensornow;
float sensorlast;
float sensormax;
int led = 7;
void setup()
{
  Serial.begin(9600);
  Wire.begin();
  pinMode (led, OUTPUT);
  sensor.init();
  sensor.setTimeout(500);

  // Start continuous back-to-back mode (take readings as
  // fast as possible).  To use continuous timed mode
  // instead, provide a desired inter-measurement period in
  // ms (e.g. sensor.startContinuous(100)).
  sensor.startContinuous();
}

void loop()
{
  Serial.print(sensor.readRangeContinuousMillimeters());
  if (sensor.timeoutOccurred()) {
    Serial.print(" TIMEOUT");
  }
  sensorlast = (sensor.readRangeContinuousMillimeters());
  sensornow = (sensor.readRangeContinuousMillimeters());
  
  if (sensornow < sensorlast) { // did angle increase? then;
    sensorlast = (sensor.readRangeContinuousMillimeters());  // update sensorlast variable
    Serial.print ("sensor last "); Serial.println (sensorlast);
    digitalWrite (led, HIGH);
    delay (20);
  }
  else { // if no increase then;

    sensormax = sensorlast;  // save sensorlast variable

  }

  Serial.println();
}

YOL THANK YOU. THANK YOU. THANK YOU… Amazing how such a simple thing had me stumped.

DeanElliottIT: I don't know what code you mean in the interrupts used elsewhere, other than the prints which are there for visual testing only.

The global float counteris adjusted in the ISR and accessed in the line degree = counter /2 ;.

Arduino reference to volatile qualifier.

You need to store [sensor.readRangeContinuousMillimeters()] in a variable, then use that variable instead of [sensor.readRangeContinuousMillimeters()].

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

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

  $now = 0;
  $last = 0;
  $max_angle = 0;

  // Start continuous back-to-back mode (take readings as
  // fast as possible).  To use continuous timed mode
  // instead, provide a desired inter-measurement period in
  // ms (e.g. sensor.startContinuous(100)).
  sensor.startContinuous();
}

void loop()
{

  $now = sensor.readRangeContinuousMillimeters(); // need to store in variable

  Serial.print($now);
  if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); }

  Serial.println();

  if ($now > $last) { // did angle increase? then;

  $last = $now;  // update $last variable

  }

  else { // if no increase then

  $max_angle = $last  // save $last variable

  Serial.println($max_angle);

  }

}

TechnoMonkey, I get stray $ in program error when compiling. highlighted line

Serial.println($max_angle);

Let me play with that and we will see

Again, thanks so much.

TechnoMonkey, I cant seem to complile anything with a $ in code.

So i been playing with this and;

This works perfectly.

/* This example shows how to use continuous mode to take
  range measurements with the VL53L0X, and set triggers
  at different distances. It is based on
  vl53l0x_ContinuousRanging_Example.c from the VL53L0X API.

  The range readings are in units of mm. */

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

VL53L0X sensor;
float sensornow;
float sensorlast;
void setup()
{
  Serial.begin(9600);
  Wire.begin();
  sensor.init();
  sensor.setTimeout(500);

  // Start continuous back-to-back mode (take readings as
  // fast as possible).  To use continuous timed mode
  // instead, provide a desired inter-measurement period in
  // ms (e.g. sensor.startContinuous(100)).
  sensor.startContinuous();
}

void loop()
{
  Serial.println(sensor.readRangeContinuousMillimeters());
  if (sensor.timeoutOccurred()) {
    Serial.print(" TIMEOUT");
  }
  sensorlast = (sensor.readRangeContinuousMillimeters());
  sensornow = (sensor.readRangeContinuousMillimeters());
  
  if (sensornow < sensorlast +5 && (sensornow < 100)) {        // did direction change? then;
                                                                    // sensornow > 100 will be replaced with boolean input switch

    //sensorlast = (sensor.readRangeContinuousMillimeters());  // update sensorlast variable
    Serial.println ("Run stepper XX Steps Left cw "); 
   // Serial.println (sensorlast);
       delay (200);
  
  }else{
  sensorlast = (sensor.readRangeContinuousMillimeters());
  sensornow = (sensor.readRangeContinuousMillimeters());
  if (sensornow > sensorlast -5 && (sensornow > 500)) {        // did direction change? then;
                                                               // sensornow > 500 will be replaced with boolean input switch

    //sensorlast = (sensor.readRangeContinuousMillimeters());  // update sensorlast variable
    Serial.println ("Run stepper XX Steps Right ccw "); 
   // Serial.println (sensorlast);
       delay (200);
   
  }
  }

//  Serial.println();
}

Just drop the $. My bad. I have been programming a lot of PHP lately.

But use variables. Lots of variables. Each time you call the function, the reading will have changed. You only need to call the function once per loop. Use variables.

TechnoMonkeys, I really appreciate your help. Now I just need to apply this and integrate it with my hall sensors, step motor, and encoder. But I think I can handle it. I learn things by seeing example. Sometimes I read the instructions on here and its Greek to me. But when i see an actual example, i can usually bend it to my needs. I guess i learn things differently. I have been building computers for 30 years, But I done very little actual programming. And that was years ago..... not like riding a bicycle lol..

I will post any updates or finding and codes for anything I figure out. Hopefully I will be able to pay it forward.. ..

On my earlier sketch posted here, I was able to achieve the direction change detection with a laser distance sensor. Now I am trying to make the same principals work with a gyro.

I can detect and if/print (rightlast > 20) or (rightnow > 20) to see that it indeed holding values.

I can get it to print the readings when I move the gyro past 20 degrees in either direction.

However, I cannot get the last and now > or < comparison to work. the && rightnow > rightlast doesn’t work.

The prints will be replaced with stepper motor commands and a && limit switch state will be added to if statement.

#include <MPU6050_tockn.h>
#include <Wire.h>

MPU6050 mpu6050(Wire);

long timer = 10;
int rightnow;
int rightlast;
int leftnow;
int leftlast;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);
 // setupMPU();
  

}

void loop() {
  mpu6050.update();
  leftlast = (mpu6050.getGyroAngleX());
  leftnow = (mpu6050.getGyroAngleX());                                                   
    if (leftlast < -20 ){                              // && leftnow > leftlast){ //(doesn't work?) // reading 0 to -90 
    Serial.print("left gyroAngleX : ");                               
    Serial.println(mpu6050.getGyroAngleX());
    }
    
mpu6050.update();
  rightnow = (mpu6050.getAngleX());
  rightlast = (mpu6050.getAngleX());  
    if (rightlast > 20 ){                               //&& rightnow < rightlast){ //(doesn't work?) // readings 0 to 90 
    Serial.print("            right angleX : ");                     
    Serial.println(mpu6050.getAngleX());
    }
   // Serial.print();
timer = millis();
  }

Thanks

Here’s a part of an anti-dither sketch that might give you some ideas, type some numbers in top of serial monitor and hit [ENTER] after each (set serial monitor line ending to “newline”).

// detect direction change

int newVal, oldVal;
bool dir, oldDir;

void setup() {
  Serial.begin(9600); // Set line ending in Serial Monitor
                      // to "Newline" 
}
void loop() {
  if (Serial.available() > 0)
  {
    newVal =  Serial.parseInt();
    Serial.print(newVal); Serial.print("  ");
    if (Serial.read() == '\n') {}
    if (newVal != oldVal)
      dir = newVal < oldVal;
    Serial.print(dir); Serial.print("  ");
    if (dir != oldDir)
      Serial.print("changed");
    oldVal = newVal;
    oldDir = dir;
    Serial.println();
  }
}

Serial Monitor

100  0  
101  0  
102  0  
101  1  changed
102  0  changed
103  0  
102  1  changed
101  1  
100  1  
101  0  changed

Thanks outsider,

Ill play with that..

Well this works with other sensors. cant make it work with a gyro… anyone know why? doset observe the comparison.

#include <MPU6050_tockn.h>
#include <Wire.h>

MPU6050 mpu6050(Wire);
float sensornow;
float sensorlast;
long timer = 0;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  mpu6050.begin();
  mpu6050.calcGyroOffsets(true);
  Serial.println();
  Serial.println(" READY ");}

void loop() {
  if(millis() - timer > 0){
  mpu6050.update();
  if (mpu6050.getAngleX() < -10){
        sensornow = (mpu6050.getAngleX());
        sensorlast = sensornow;                             // update sensorlast variable
    if (sensornow > sensorlast) {                           // did direction change? then....
    Serial.print ("Run stepper XX Steps Left cw "); 
    Serial.println (sensorlast);}}

  if (mpu6050.getAngleX() > 10){
        sensornow = (mpu6050.getAngleX());
        sensorlast = sensornow;                             // update sensorlast variable
    if (sensornow < sensorlast) {                           // did direction change? then;
    Serial.print ("Run stepper XX Steps Right ccw "); 
    Serial.println (sensorlast);}}
    Serial.println(sensorlast);
 
    timer = millis();  }}

I give up. I have wasted my whole weekend trying to get this one function to work. I tried dozens of sketches and codes. nothing seems to work. I am not a programmer, that is for sure.

I need to find someone to pay to do this so i can move on with my project.

My last shreds of an attempt below:

#include <MPU6050_tockn.h>                       // MPU-6050 Library
#include <Wire.h>

MPU6050 mpu6050(Wire);                           // Global name for MPU-6050
long timer = 0;                                  // Timer unknown function

void setup() {
  Serial.begin(9600);                            // Start Serial Monitor
  Wire.begin();
  mpu6050.begin();                               // Start MPU-6050 Initilization
  mpu6050.calcGyroOffsets(true);                 // Sets Gyro offsets, calibrate XYZ axis to 0
  Serial.println();
  Serial.println();
  Serial.println(" OFFSETS CALIBRATED AND READY ");}      // Show when Calibration is finished on ther serial monitor

void loop() {
  float sensorlastleft;                             // varible for getlastleft loop
  float sensorlastright;                            // varible for getlastright loop
  float lastreadleft;                               // varible returned from getlastleft loop
  float lastreadright;                              // varible returned from getlastright loop
  if(millis() - timer > 0){                         
  mpu6050.update();                                 // get reading from gyro

  if (mpu6050.getAngleX() < -3){                             // if pendulum is going from right to left
getlastleft(sensorlastleft,lastreadleft);                    // get reading from getlast loop
  if (mpu6050.getAngleX() > lastreadleft) {                  // compare last reading with current reading
     Serial.print ("Run stepper XX Steps Left cw ");         // stepper motor trigger placed here 
     Serial.println (mpu6050.getAngleX());}}

  if (mpu6050.getAccAngleX() > 3){                           // if pendulum is going from left to right
getlastright(sensorlastright,lastreadright);                 // get reading from getlast loop                     
  if (mpu6050.getAccAngleX() < lastreadright) {              // compare last reading with current reading
    Serial.print ("Run stepper XX Steps Right ccw ");        // stepper motor trigger placed here 
    Serial.println (mpu6050.getAccAngleX());}}
    
  Serial.print(" Left ");Serial.print(lastreadleft);                    // View getlast loop feedback
  Serial.print("            Right ");Serial.println(lastreadright);     // View getlast loop feedback
    timer = millis();  }
}
    
 void getlastleft(float sensorlastleft, float &lastreadleft){       // Loop to aquire lastmpu6050.getAngleX()reading
  sensorlastleft = mpu6050.getAngleX();                             // Get last reading
  lastreadleft = sensorlastleft;}                                   // Varible to return to Void Loop

void getlastright(float sensorlastright, float &lastreadright){     // Loop to aquire mpu6050.getAccAngleX() reading
  sensorlastright = mpu6050.getAccAngleX();                         // Get Last Reading
  lastreadright = sensorlastright;}                                 // Varible to return to Void Loop







 
/*
      //Serial.println("======TEST READINGS COPY TO LOOP TO RUN====================");
    //Serial.print("                                                temp : ");
    //Serial.println(mpu6050.getTemp());
    
    //Serial.print("                                                accX : ");
    //Serial.println(mpu6050.getAccX());
    
    //Serial.print("                                                \taccY : ");
    //Serial.println(mpu6050.getAccY());
    
    //Serial.print("                                                \taccZ : ");
    //Serial.println(mpu6050.getAccZ());
  
    //Serial.print("                                                gyroX : ");
    //Serial.println(mpu6050.getGyroX());
    
    //Serial.print("                                                \tgyroY : ");
    //Serial.println(mpu6050.getGyroY());
    
    //Serial.print("                                                \tgyroZ : ");
    //Serial.println(mpu6050.getGyroZ());
  
    //Serial.print("                                                accAngleX : ");
    //Serial.println(mpu6050\\.getAccAngleX());
    
    //Serial.print("                                                \taccAngleY : ");
    //Serial.println(mpu6050.getAccAngleY());
  
    //Serial.print("                                                gyroAngleX : ");
    //Serial.println(mpu6050.getGyroAngleX());
    
    //Serial.print("                                                \tgyroAngleY : ");
    //Serial.println(mpu6050.getGyroAngleY());
    
    //Serial.print("                                                \tgyroAngleZ : ");
    //Serial.println(mpu6050.getGyroAngleZ());
    
    //Serial.print("                                                angleX : ");
    //Serial.println(mpu6050.getAngleX());
    
    //Serial.print("                                                \tangleY : ");
    //Serial.println(mpu6050.getAngleY());
    
    //Serial.print("                                                \tangleZ : ");
    //Serial.println(mpu6050.getAngleZ());
    
    //Serial.println("=======================================================\n");
    */
 */

PLEASE HELP, I AM GOING CRAZY TRYING TO FIGURE THIS OUT... offering $50 for working code.....

This is the basic unedited encoder code I downloaded for rotary encoder LPD3806-360BM-G5-24C. It works fine and with some added calculation.

I can get readings on a pendulum with the fulcrum point being the encoder from (straight down) 0, 0 to -90 cw or left, and 0 to 90 ccw or right.

I still cannot figure out a way to capture the moment when it changes from left to right at the weightless moment of maximum potential energy. Basically i need to make something happen just at the moment the mass weighs 0.

volatile unsigned int temp, counter = 0; //This variable will increase or decrease depending on the rotation of encoder
    
void setup() {
  Serial.begin (9600);

  pinMode(2, INPUT_PULLUP); // internal pullup input pin 2 
  
  pinMode(3, INPUT_PULLUP); // internalเป็น pullup input pin 3
//Setting up interrupt
  //A rising pulse from encodenren activated ai0(). AttachInterrupt 0 is DigitalPin nr 2 on moust Arduino.
  attachInterrupt(0, ai0, RISING);
   
  //B rising pulse from encodenren activated ai1(). AttachInterrupt 1 is DigitalPin nr 3 on moust Arduino.
  attachInterrupt(1, ai1, RISING);
  }
   
  void loop() {
  // Send the value of counter
  if( counter != temp ){
  Serial.println (counter);
  temp = counter;
  }
  }
   
  void ai0() {
  // ai0 is activated if DigitalPin nr 2 is going from LOW to HIGH
  // Check pin 3 to determine the direction
  if(digitalRead(3)==LOW) {
  counter++;
  }else{
  counter--;
  }
  }
   
  void ai1() {
  // ai0 is activated if DigitalPin nr 3 is going from LOW to HIGH
  // Check with pin 2 to determine the direction
  if(digitalRead(2)==LOW) {
  counter--;
  }else{
  counter++;
  }
  }