How to get sensor angles values using Interrupts in arudin mega ?

NEW_hep.ino (14.5 KB)

i want to control the vfd motor rotation movement based on the angle values from sensors and previously in this i tried using delay in function sensors don 't get values during delay so it misses that position it starts to rotate continuously and i want to stop the vfd motor when it reaches the exact position let s say 90 degree s how to achieve this ??? please help with this .........
code is there in the above ino file

///// sensor 1 pins const int ClockPin = 6; //output to clock const int CSnPin = 5; //output to chip select const int InputPin = 4; //read AS5040 //////////////////////////////////////////////

/////////sensor 2 pins
const int ClockPin2 = 11; //output to clock
const int CSnPin2 = 12; //output to chip select
const int InputPin2 = 10; //read AS5040
/////////////////////////////////////////////////////////////////////////////////////////
int enablePin2 = 8;
int enablePin1 = 9;

// slave 1 COMMANDS
byte FWD1[] = {0x01, 0x06, 0x11, 0x00, 0x00, 0x01, 0x4D, 0x36};
byte REV1[] = {0x01, 0x06, 0x11, 0x00, 0x00, 0x02, 0x0D, 0x37};
byte STOP1[]= {0x01, 0x06, 0x11, 0x00, 0x00, 0x06, 0x0C, 0xF4};
byte SPD01[] = {0x01, 0x06, 0x10, 0x00, 0x00, 0x00, 0x8D, 0x0A}; // 0 % OF MAX SPEED AT SLAVE 1
byte SPD101[]= {0x01, 0x06, 0x10, 0x00, 0x03, 0xE8, 0x8D, 0xB4}; // 10 % OF MAX SPEED AT SLAVE 1
byte SPD251[]= {0x01, 0x06, 0x10, 0x00, 0x09, 0xC4, 0x8A, 0xC9}; // 25 % OF MAX SPEED AT SLAVE 1
byte SPD501[]= {0x01, 0x06, 0x10, 0x00, 0x13, 0x88, 0x80, 0x5C}; // 50 % OF MAX SPEED AT SLAVE 1
byte SPD751[]= {0x01, 0x06, 0x10, 0x00, 0x1D, 0x4C, 0x85, 0xAF}; // 75 % OF MAX SPEED AT SLAVE 1
byte SPD1001[]= {0x01, 0x06, 0x10, 0x00, 0x27, 0x10, 0x97, 0x36}; // 100 % OF MAX SPEED AT SLAVE 1

// slave 2
byte FWD2[] = {0x02, 0x06, 0x11, 0x00, 0x00, 0x01, 0x4D, 0x05}; // FWD : 02 06 11 00 00 01 4D 05
byte REV2[] = {0x02, 0x06, 0x11, 0x00, 0x00, 0x02, 0x0D, 0x04}; // REV : 02 06 11 00 00 02 0D 04
byte STOP2[]= {0x02, 0x06, 0x11, 0x00, 0x00, 0x06, 0x0C, 0xC7}; // STOP : 02 06 11 00 00 06 0C C7
byte SPD02[] = {0x02, 0x06, 0x10, 0x00, 0x00, 0x00, 0x8D, 0x039}; // SPEED0 : 02 06 10 00 00 00 8D 39
byte SPD102[]= {0x02, 0x06, 0x10, 0x00, 0x03, 0xE8, 0x8D, 0x87}; // SPEED10 : 02 06 10 00 03 E8 8D 87
byte SPD252[]= {0x02, 0x06, 0x10, 0x00, 0x09, 0xC4, 0x8A, 0xFA}; // SPEED25 : 02 06 10 00 09 C4 8A FA
byte SPD502[]= {0x02, 0x06, 0x10, 0x00, 0x13, 0x88, 0x80, 0x6F}; // SPEED50 : 02 06 10 00 13 88 80 6F
byte SPD752[]= {0x02, 0x06, 0x10, 0x00, 0x1D, 0x4C, 0x85, 0x9C}; // SPEED75 : 02 06 10 00 1D 4C 85 9C
byte SPD1002[]={0x02, 0x06, 0x10, 0x00, 0x27, 0x10, 0x97, 0x05}; // SPEED100 : 02 06 10 00 27 10 97 05

// value of runcom is 1 then it indicates fwd
// value of runcom is 2 then it indicates rev // speedcontrol is given in percentage basically four values can be chosen 25% ,50% , 75% ,100%
// this function is to run motor 1
///////////////////////////////////////////////////////
// defining the range of motor's rotation
// every value is in angle value of degree
const long potMini=0; //450;
const long potMaxi=360; //723;

// sets value to 562
// inital posn value
long axis1=206,prev_axis1=206,inv_axis1=206; //middle position 0-1024 val=586
long axis2=206,prev_axis2=206,inv_axis2=206; //middle position 0-1024 val=586

static long brakingDistance=7;
static unsigned long sensor1,sensor2;

////////////////////////////////////////////////////////////////
void Run_motor1( int runCom, int speedControl)
{
if (runCom==1 )// it indicates fwd
{
Serial1.write(SPD01, sizeof(SPD01));
delay(20);
Serial1.write(FWD1, sizeof(FWD1));
delay(20);
if (speedControl==25)
{
Serial1.write(SPD251, sizeof(SPD251));
delay(20);
}
else if (speedControl==50)
{
Serial1.write(SPD501, sizeof(SPD501));
delay(20);
}
else if (speedControl==75)
{
Serial1.write(SPD751, sizeof(SPD751));
delay(20);
}
else if (speedControl==100)
{
Serial1.write(SPD1001, sizeof(SPD1001));
delay(20);
}
}
///////////////////////////////////////////////////////////////////
if (runCom== 2)// it indicates rev
{
Serial1.write(SPD01, sizeof(SPD01));
delay(20);
Serial1.write(REV1, sizeof(REV1));
delay(20);

////////////////////////////////////////////
 if (speedControl==25)
{
  Serial1.write(SPD251, sizeof(SPD251));
  delay(20);
}
 else if (speedControl==50)
{
  Serial1.write(SPD501, sizeof(SPD501));
  delay(20);
}
 else if (speedControl==75)
{
  Serial1.write(SPD751, sizeof(SPD751));
  delay(20);
}
 else if (speedControl==100)
{
  Serial1.write(SPD1001, sizeof(SPD1001));
  delay(20);
}

}
}

// this function is to run motor 2
void Run_motor2( int runCom, int speedControl)
{
if (runCom==1 )// it indicates fwd
{
Serial2.write(SPD02, sizeof(SPD02));
delay(20);
Serial2.write(FWD2, sizeof(FWD2));
delay(20);
if (speedControl==25)
{
Serial2.write(SPD252, sizeof(SPD252));
delay(20);
}
else if (speedControl==50)
{
Serial2.write(SPD502, sizeof(SPD502));
delay(20);
}
else if (speedControl==75)
{
Serial2.write(SPD752, sizeof(SPD752));
delay(20);
}
else if (speedControl==100)
{
Serial2.write(SPD1002, sizeof(SPD1002));
delay(20);
}
}
///////////////////////////////////////////////////////////////////
if (runCom== 2)// it indicates rev
{
Serial2.write(SPD02, sizeof(SPD02));
delay(20);
Serial2.write(REV2, sizeof(REV2));
delay(20);

////////////////////////////////////////////
 if (speedControl==25)
{
  Serial2.write(SPD252, sizeof(SPD252));
  delay(20);
}
 else if (speedControl==50)
{
  Serial2.write(SPD502, sizeof(SPD502));
  delay(20);
}
 else if (speedControl==75)
{
  Serial2.write(SPD752, sizeof(SPD752));
  delay(20);
}
 else if (speedControl==100)
{
  Serial2.write(SPD1002, sizeof(SPD1002));
  delay(20);
}

}
}

// to stop both motor 1 and 2

void Stop ()
{
Serial2.write(SPD02, sizeof(SPD02));
delay(20);
Serial1.write(SPD01, sizeof(SPD01));
delay(20);
Serial2.write(STOP2, sizeof(STOP2));
delay(20);
Serial1.write(STOP1, sizeof(STOP1));
delay(20);
}

// to stop motor 2

void Stop_2()
{

Serial2.write(STOP2, sizeof(STOP2));
delay(20);
Serial2.write(SPD02, sizeof(SPD02));
delay(20);
}

// to stop motor 1
void Stop_1()
{
Serial1.write(STOP1, sizeof(STOP2));
delay(20);
Serial1.write(SPD01, sizeof(SPD01));
delay(20);
}

// this func is to get the angle from sensor

unsigned int GetSensorValue(uint8_t CS,uint8_t CLK,uint8_t SerD){
static unsigned long angle = 0;
digitalWrite(CS, LOW); // CSn low: start of transfer
delayMicroseconds(1);
digitalWrite(CLK, LOW); // CLK goes low: start clocking
delayMicroseconds(1);
angle = 0;
for (int x = 0; x < 10; x++) // clock signal, 16 transitions, output to clock pin
{
digitalWrite(CLK, HIGH); //clock goes high
delayMicroseconds(1);
angle = ((angle << 1) | digitalRead(SerD));// left-shift summing variable, add pin value
digitalWrite(CLK, LOW);
delayMicroseconds(1);
}
digitalWrite(CS, HIGH); // CSn high
digitalWrite(CLK, HIGH); //clock goes high

return uint16_t((angle * 45) >> 7) ;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void motorMotion(int motor_num, long actualPos,long targetPos)
{
// here i am using two while loop to run please check the logic
while (actualPos != targetPos)
{

   if (motor_num ==1)
  {
  // actualPos= sen1();
  }
  else 
  {
 // actualPos= sen2();
  }
//

int Tol=2;
// 2 degree no order to move will be sent to the motor if the target is close to the actual position
// this prevents short jittering moves

int gap;
int pwm=50;

// security concern : targetPos has to be within the mechanically authorized range
targetPos=constrain(targetPos,potMini+brakingDistance,potMaxi-brakingDistance);

gap=abs(targetPos-actualPos);

if (gap<= Tol)
{

   if (motor_num==1)
  {
   Stop_1();
   delay(20);
          
  }
  else 
  {
   Stop_2();//too near to move: stop motor 
  delay(20);
  }    

}

else
{
// PID : calculates speed according to distance
pwm=25;
if (gap>17) pwm=50;
if (gap>26) pwm=75;
if (gap>35) pwm=100;

// pwm=map(pwm, 0, 255, 0, pwmMax);  //adjust the value according to pwmMax for mechanical debugging purpose !
Serial3.println("Moving MOTOR"+String(motor_num)+" PWM:"+String(pwm)+" | APOS:"+String(actualPos)+" | GAP:"+String(gap)+" | TPOS:"+String(targetPos));

// if motor is outside from the range, send motor back to the limit !
// below condition is to check to rotation of motor if it is nearer to clockwise then rotate clockwise or else rotate anti clockiwise 

// please check here
if ( ( ( (actualPos<potMini) || (actualPos<targetPos) )*1-( (actualPos>potMaxi) || (actualPos>targetPos) )*1)==1 )
{
if ( motor_num==1)
{
delay(20);
while (actualPos != targetPos){
Run_motor1(1,pwm);// motor 1 rotates in clk wise ( 1 inside the paramter indiactes forward dirn )
// actualPos= sen1();
}

   }
   else 
   {
       delay(20);
           while (actualPos != targetPos){
         Run_motor2(1,pwm);// motor 2 rotates in clk wise ( 1 inside the paramter indiactes forward dirn )
         // actualPos= sen2();
        }
    
   }    
 }
 if ( ( ( (actualPos<potMini) || (actualPos<targetPos) )*1-((actualPos>potMaxi) || (actualPos>targetPos))*1)==-1)
{  if ( motor_num==1)
   {
       delay(20);
           while (actualPos != targetPos){
       Run_motor1(2,pwm);// motor 1 rotates in anticlk wise ( 2 inside the paramter indiactes revr dirn )
       //actualPos= sen1();
        }
   }
   else 
   {
     //Run_motor2(2,pwm); 

       while (actualPos != targetPos){
       Run_motor2(2,pwm); // motor 2 rotates in anticlk wise ( 2 inside the paramter indiactes revr dirn )
      // actualPos= sen2();
        }
   }
}    

}

}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
Serial3.begin(115200);
pinMode(ClockPin, OUTPUT); // SCK
pinMode(CSnPin, OUTPUT); // CSn -- has to toggle high and low to signal chip to start data transfer
pinMode(InputPin, INPUT); // SDA
//////////////////////////////////////////
pinMode(ClockPin2, OUTPUT); // SCK
pinMode(CSnPin2, OUTPUT); // CSn -- has to toggle high and low to signal chip to start data transfer
pinMode(InputPin2, INPUT); // SDA
///////////////////////////////////////////////////
/// setup for vfds
Serial1.begin(19200); // slave 2
Serial2.begin(19200); // slave 1
pinMode(enablePin2, OUTPUT);
pinMode(enablePin1, OUTPUT);
delay(10);
digitalWrite(enablePin2, HIGH); // Always high as Master Writes data to Slave
digitalWrite(enablePin1, HIGH);
}

void loop()
{

sensor1=GetSensorValue( CSnPin, ClockPin, InputPin);
sensor2=GetSensorValue( CSnPin2, ClockPin2, InputPin2);
Serial3.print("the angle from the motor 1 is ");
Serial3.println(sensor1);
delay (50);
Serial3.print("the angle from the motor 2 is ");
Serial3.println(sensor2);
}

no communication is possible while interrupt.

actually i want to get continuous sensor values from as5040 sensors and if it rotates target angle then i want to stop the vfd motor

how to achieve this ??
i am new to this field please help with this

You better know how to handle the device before buying it.

anyway thanks for the help

if you interested, you should help us to help you: edit the first post. use proper tag or attach INO file.

yeah sure ready to help at present i am newbie here, i have edited the first post .

(actualPos < targetPos) ) * 1 - ( (actualPos > potMaxi) || (actualPos > targetPos) ) * 1)

* 1 ? really ?
pls delete unneccecery lines from the code. or better make code which only read sensor.

i have changed the file and also i have added some comments to understand

try this. if it work proper then we go further

//   sensor 1 pins
const int clockPin = 6; //output to clock
const int CSnPin = 5; //output to chip select
const int inputPin = 4; //read AS5040

void setup() {
  Serial3.begin(115200);
  pinMode(clockPin, OUTPUT); // SCK
  pinMode(CSnPin, OUTPUT); // CSn -- has to toggle high and low to signal chip to start data transfer
  pinMode(inputPin, INPUT); // SDA
  pinMode(enablePin1, OUTPUT);
}

void loop() {
  static unsigned long angle = 0; //holds processed angle value
  // CSn needs to cycle from high to low to initiate transfer. Then clock cycles. As it goes high
  // again, data will appear on sda
  digitalWrite(CSnPin, HIGH); // CSn high
  digitalWrite(clockPin, HIGH); // CLK high
  delay(10);// wait for 0.2 second for no particular reason
  digitalWrite(CSnPin, LOW); // CSn low: start of transfer
  delay(10); // delay for chip -- 1000x as long as it needs to be
  digitalWrite(clockPin, LOW); // CLK goes low: start clocking
  delay(10); // hold low for 10 ms
  angle = 0;
  for (int x = 0; x < 10; x++) // clock signal, 16 transitions, output to clock pin
  {
    digitalWrite(clockPin, HIGH); //clock goes high
    delay(10); // wait 10ms
    angle = ((angle << 1) | digitalRead(inputPin));// left-shift summing variable, add pin value
    digitalWrite(clockPin, LOW);
    delay(10); // end of one clock cycle
  }
  // mask rightmost 6 digits of packeddata to zero, into angle.// shift 16-digit angle right 6 digits to form 10-digit value//
  angle = (angle * 45) >> 7 ;
  Serial3.print("angle from sensor 1 : ");
  Serial3.println(angle, DEC);
}


it works fine sensor angles are coming correct ..

show.

image
as you can see the values are coming perfect, i have changed the dirn and checked the values are fine
image

here sensor checking as a function

unsigned int GetSensorValue(uint8_t CS,uint8_t CLK,uint8_t SerD) {
  static unsigned long angle = 0;
  digitalWrite(CS, LOW); // CSn low: start of transfer
  delayMicroseconds(1);
  digitalWrite(CLK, LOW); // CLK goes low: start clocking
  delayMicroseconds(1);
  angle = 0;
  for (int x = 0; x < 10; x++) // clock signal, 16 transitions, output to clock pin
  {
    digitalWrite(CLK, HIGH); //clock goes high
    delayMicroseconds(1);
    angle = ((angle << 1) | digitalRead(SerD));// left-shift summing variable, add pin value
    digitalWrite(CLK, LOW);
    delayMicroseconds(1);
  }
  digitalWrite(CS, HIGH); // CSn high
  digitalWrite(CLK, HIGH); //clock goes high
  
  return  uint16_t((angle * 45) >> 7) ;
}

okay thanks it is working very good values are accurate after getting value from the senor i want to make rotation of lets say 90 give a me path or way to rotating without using any delay how to do this

what do you mean?

sorry i mean to say this how to go ahead .
for controlling the motor

Is this what you mean? Do you have a program that controls the rotation and that is all it does?

motorMotion function is the func i have written for controlling the vfd motor . but i unable to control it starts continuously to rotate,
to avoid this situation what should i do in the code is the correct approach ?? please help with this .
i have attached the code in the first post please check that ..