Find a tip to inform the position to the stepper motor

n Processing, I made a simulation where I run an engine over several revolutions at a certain speed and in both directions.

I can track the position of the simulated motor using a stepper motor.

By giving the position information of the simulated motor (on a scale from 0 to 4095) to the stepper motor (which therefore makes a revolution in 4096 steps), the stepper motor follows the simulated movement very well. 8); D.

Everything is fine when the simulated engine does not exceed 1 revolution in one direction or the other.

But, when the simulated motor exceeds a revolution, when it starts a first revolution, Processing always sends positions between 0 and 4095.

Processing therefore sends at the start of the first lap, position 0 to my stepper motor on Arduino and therefore (instead of continuing forward) it goes back to go to position 0.

So to solve this problem, when the information of the simulated engine goes from 4095 to directly 0 or 1 or 23, Processing would have to send a virtual position equal to position 4096 + 0, 4096 + 1 or 4096 + 23.

Similarly, if at the start the simulated motor turns in the other direction, Processing sends the positions 0, 4096, 4085 for example and the stepper motor goes forward (from 0 to 4096) then back (from 4096 to 4085 ).

When I should send virtual positions 0, -1, -11.

Likewise if the second back turn is the same as the first, instead of Processing sending 0, 4096, 4085, Processing should send virtual positions
0- 4096, -1- 4096, -11 - 4097. So, -4096, -4097, -5008.

Hoping to have been clear, I thank you with my greatest gratitude. :muscle:

here what I tried but I don’t have all the data of position. It can to go straight to 4090 to 10 for exemple

 float pos0 = map ((net.phase[0]), 0, TWO_PI, 0, 4095); 
 
int positionMax=4095;
int Pos0= int (pos0);
    
 print ("Pos0    "); println (Pos0);

 // if motor goes forword
 if (( Pos0 - positionMax > -1) || ( positionMax- Pos0 < 1))  { 
     
            int VirtualPosition = Pos0+positionMax+0;
   
   } 
      
     String pos = (10.0)+"*"+(10.0) +"*"+(10.0)+"*"+(10.0)+"*"+(VirtualPosition) +"*"; 
     
 println (pos);
 
 arduinoport.write(pos); 
1 Like

Hello,

You have a related post here already:

I have worked with stepper motors.

I provided a minimal example of an approach I took to this:

  • Processing is sending integer “steps” and direction (this can be positive or negative) to the Arduino
  • “Position” can be translated to steps and direction; you will have to do this correctly relative to the current initial and final position. I did not do this in this example.
  • The Processing “simulation” should follow the expected motion of the stepper motor from the instructions you are sending.
  • The motor must complete its motion (code is blocking on Arduino side) so that must also be given consideration. This is not in this code example.

I did this simulation (rotating line) using:

  • A integer counter for steps.
  • Drawing a line that was rotated by steps*angle/step
  • Using modulo operator for the zero-crossing (0/360/720 deg… etc.) to determine the rotation and plot the line.
    Examples:
    4096%4096 = 0
    (4096 + 1024)%4096 = 1024
    And so on…

I left this uncommented and removed variable names so you can work through it:

float a;
int b, c;

void setup() 
  {
  size(400, 400, P2D);
  b = 32;
  }

void draw() 
  {
  background(64); 
  translate(width/2, height/2);    
  
  float d = TWO_PI/b;   
  a = (c%b)*d;
  rotate(a);
  strokeWeight(3);
  stroke(255, 0, 0);
  line(0, 0, 150, 0);
  
  println(a, degrees(a));
  }
  
void mousePressed()
  {
  if (mouseButton == LEFT) c++;
  if (mouseButton == RIGHT) c--;
  }

I used the modulo operator because floating point errors accumulated if I rotated the motor a few hundred thousand times; this kept the rotations to between 0 and 2Ď€.

References:

’ :slight_smile: ’

1 Like

Similarly, if at the start the simulated motor turns in the other direction, Processing sends the positions 0, 4096, 4085 for example and the stepper motor goes forward (from 0 to 4096) then back (from 4096 to 4085 ).

When I should send virtual positions 0, -1, -11.

Hello,

I’m very sorry, but when the simulated motor turns in the other direction, Processing sends the positions

0, -1 and -11 not 0, 4096 and 4085.

So it send good position for the first rotation, but for the second rotation I would like to send position 0-4096, -1-4096 and -11-4096.

In the same way, when the motor begin it first revolution in the clockwise rotation with position 0, 1 and 13, I would like to send position 0+ 4096, 1+ 4096 and 13 + 4096.

So, how could I use the modulo to account the number of rotation?

I put the program transformed. Thank you

// MANAGE ARDUINO
import processing.serial.*;
Serial arduinoport; 
 
 int VirtualPosition;

float a;
int b, c;

void setup() 
  {
  size(400, 400, P2D);
  b = 32;
  }

void draw() 
  {
     background(64); 
     translate(width/2, height/2);    
    
    
     if (key == '0') { println ("CONTROL MOTOR 0 UP: CLOCKWISE");
     
         
          VirtualPosition=  VirtualPosition+1;
                  
    }
 
  
      if (key == 'P') {  println ("CONTROL MOTOR 0 DOWN: CCW");
          
     
          VirtualPosition= VirtualPosition-1;
          
              
      } 
    
 
  c = VirtualPosition;
  float d = TWO_PI/(b);   
  a = (c%b)*d;
  rotate(a);
  
  float  pos=  map( a, -TWO_PI, TWO_PI, -4096, 4096);
 
  int Pos= int (pos); 
  
  datatoArduino(Pos);  
  
  strokeWeight(3);
  stroke(255, 0, 0);
  line(0, 0, 150, 0);
  
  println(a, degrees(a));
  
 
  }
  
   
void datatoArduino( int Pos)  {
  
   print ("  pos  "); println (Pos);
  // arduinoport.write(pos); 
 }


1 Like

Use integer division for revolutions and modulo for remainder (partial rotation).

In my example a complete revolution is 32 steps/revolution.
The variable c is number of steps (steps).

For a rotation of rotation of 65 steps:

76/32 = 2 revolutions (64 steps) using integer math.
65%32 = 12 steps … you can do more math to convert to degrees.

You will have to sort the rest out for your project based on how you decide to deal with the control data; I have not looked at your detailed description.

I shared a simple example based on my initial thoughts and it is not intended as solution for your project; I have since written a some servo motor control code and added a nice GUI.

This is an achievable exercise. Keep working at it.

:)

1 Like

Hello glv.

I made on other program simulating the rotation movement with 200 step/revolution and no more 4096.

I’m not sure We need to calculate the modulo when we pass over 200 steps but why not ??

I would prefer to have a fonction computing the “deltaposition” between the old position and the current position based on virtualPosition between -200, 200.

In the cases below the delta position should be:
If I go from 188 to 11, I need to go to 12+11= 23 step. Or If go from -189 to -3, I need to go to 14 step.

If I go from 100 to 99, I need to make one step, and not 100+ 99.

I made a fonction and it works only for first revolution in CCW. It’s just for the example :wink:

Thanks a lot.

// MANAGE ARDUINO
import processing.serial.*;
Serial arduinoport; 
 
 int VirtualPosition;
 int numberofStep= 200;
 int stepOnce;


void setup() 
  {
  size(400, 400, P2D);
  stepOnce = 25;
  }

void draw() 
  {
     background(64); 
     translate(width/2, height/2);    
    
    
     if (key == '0') { println ("CONTROL MOTOR 0 UP: CLOCKWISE");
     
         delay (300);
     //     VirtualPosition=  VirtualPosition+1;
          VirtualPosition=  VirtualPosition+stepOnce;
                  
    }
 
  
      if (key == 'P') {  println ("CONTROL MOTOR 0 DOWN: CCW");
          
          delay (300);
      //    VirtualPosition= VirtualPosition-1;
          VirtualPosition=  VirtualPosition-stepOnce;
                  
          
              
      } 
      
      
    
   if ( VirtualPosition> numberofStep)  {
     
     VirtualPosition= 0;
 
   }
   
    if ( VirtualPosition< -numberofStep)  {
     
     VirtualPosition= 0;
 
   }
   
   float rad =  map (VirtualPosition, -200, 200, -TWO_PI, TWO_PI);
     
  rotate(rad);
  strokeWeight(3);
  stroke(255, 0, 0);
  line(0, 0, 150, 0);
  
  datatoTransfrom ( VirtualPosition, rad);  
  computeDeltaPosition (VirtualPosition); 

  }
  
   
void datatoTransfrom (int VirtualPosition, float rad)  {
  
   print ("  pos  "); println (VirtualPosition, rad);
 
 }
 
void computeDeltaPosition (int VirtualPosition)   {

   int oldPositionAbsolue = 0;
   int positionAbsolue = VirtualPosition;
   int resultat;
   
   if(positionAbsolue < oldPositionAbsolue)
    positionAbsolue-= numberofStep;
    
    print ("positionAbsolue: "); println (positionAbsolue);
    
   if(positionAbsolue - oldPositionAbsolue <  numberofStep/2)
   resultat = positionAbsolue - oldPositionAbsolue;
  else
    resultat = positionAbsolue - oldPositionAbsolue - numberofStep;
  oldPositionAbsolue = VirtualPosition;
   // return resultat;
 
  //  arduinoport.write(positionAbsolue);

 }
2 Likes