Add a counter to know the number of revolution

Hello gentlemen!

I would like to have a fonction telling me the number the revolution when I control the rotation of the axis with the keypads 0 and P. (the program is below)

At the beginning, I should have 0, and at the first revolution I should have 1.
At the beginning, if I turn at the opposite way, I should have 0 and at the first revolution I should have -1.

Thanks you very much! :rofl:

// 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);  
 
  }
  
   
void datatoTransfrom (int VirtualPosition, float rad)  {
  
   print ("  pos  "); println (VirtualPosition, rad);
 
 }
1 Like

Reading your code, it is not clear if a revolution is from -200 to 200. The map() call needs to be revised as you mapping from -2PI to 2PI aka 2 revolutions.

So from what I understand, when a full revolution occur, that is, when going above 200, the position should become negative and start counting from -200. The following algorithms shows the concept.

also, do not use delay() in draw() or at least avoid it if possible. I have modified your code to propose another approach.

Kf

final int DELAYTIME_MS=300; //in msecs
final int STEPS_FOR_HALF_REVOLUTION= 200;  //Motor steps
final int STEPONCE=25; //Motor steps

int VirtualPosition;
int revolutionCtr;

int nextTime;
boolean blocking;


void setup() {
  size(400, 400, P2D);
  revolutionCtr=0;
  nextTime=0;
  blocking=false;
}

void draw() {
  background(64); 
  translate(width/2, height/2);    

  if (millis()+DELAYTIME_MS>nextTime) {
    blocking=false;
  }

  rotate(inRadians(VirtualPosition));
  strokeWeight(3);
  stroke(255, 0, 0);
  line(0, 0, 150, 0);
}

void keyPressed() {
  if (key == '+') { 
    updateMotorPosition(STEPONCE);
  } else if (key == '-') { 
    updateMotorPosition(-STEPONCE);
  }
}

void updateMotorPosition(int step) {

  blocking=true;
  nextTime=millis()+DELAYTIME_MS;

  println ("CONTROL MOTOR 0 ", step>0 ? "UP: CLOCKWISE" : "DOWN: CCW");

  int tmp=VirtualPosition+step;

  if (tmp >= STEPS_FOR_HALF_REVOLUTION) {
    VirtualPosition = -STEPS_FOR_HALF_REVOLUTION + (tmp%STEPS_FOR_HALF_REVOLUTION);     
    revolutionCtr++;
    println("...", tmp, VirtualPosition, revolutionCtr);
  } else if (tmp <= -STEPS_FOR_HALF_REVOLUTION) {
    VirtualPosition = STEPS_FOR_HALF_REVOLUTION - (abs(tmp)%STEPS_FOR_HALF_REVOLUTION);
    revolutionCtr--;
    println("...", tmp, VirtualPosition, revolutionCtr);
  } else {
    VirtualPosition=tmp;
  }  

  printData( VirtualPosition);
}

void printData(int VirtualPosition) {
  println("pos", VirtualPosition, nf(inRadians(VirtualPosition), 0, 3), "Rev:", revolutionCtr);
}

float inRadians(int val) {
  return  map (val, -STEPS_FOR_HALF_REVOLUTION, STEPS_FOR_HALF_REVOLUTION, 0, TWO_PI);  // -2pi to 2pi is 2 revolutions, the original transform is NOT correct
  //return radians(VirtualPosition);
}

2 Likes

There is a concept of not repeating yourself which I did above. The above code was to demonstrate a simple approach to deal with both edge cases when going from 200 to -200 or visceversa, explicitely. The code can be simplified to this next version. It is very likely there is a easier way to do this so the code is easier to read and probably only using the modulus operator.

Kf

void updateMotorPosition(int step) {

  blocking=true;
  nextTime=millis()+DELAYTIME_MS;

  println ("CONTROL MOTOR 0 ", step>0?"UP: CLOCKWISE":"DOWN: CCW");

  int tmp=VirtualPosition+step;


  if (abs(tmp) >= STEPS_FOR_HALF_REVOLUTION) {
    int sign = step>0?-1:1;  // Yes, CW revolution drives to a negative sign
    tmp = sign * (STEPS_FOR_HALF_REVOLUTION - (tmp%STEPS_FOR_HALF_REVOLUTION) );     
    revolutionCtr-=sign; //Double negative
    println("...", tmp, VirtualPosition, revolutionCtr);
  }

  VirtualPosition=tmp;
  printData( VirtualPosition);
}
2 Likes

Hi kfrajer,
Thanks for this quick and pedagogic answer!

A revolution in my code is from 0,200 in a way of rotation, and 0, -200 in the other way of rotation.

Actually, this program simulate a mouvement of rotation with a beginning at the position 0 and an end at the position 199 in the clockwise way. When the movement keep on to turn in clockwise way, the first revolution begins at 0 and finish at 199 too.
In the other way, in CCW, when the motor reaches the beginning (the position 0) and even if the movement is at the third revolution for exemple, the position is 0 and decrease at -199, -198 until 0.

Please, could you manage the program with this setting?

Thanks, Benjamin

Here the solution, with a setting of 200 step for one revolution, so .STEPS_FOR_HALF_REVOLUTION should be named STEPS_FOR_FULL_REVOLUTION. That what I did.

final int DELAYTIME_MS=300; //in msecs
final int STEPS_FOR_ONE_REVOLUTION= 200;  //Motor steps
final int STEPONCE=25; //Motor steps

int VirtualPosition;
int revolutionCtr;

int nextTime;
boolean blocking;


void setup() {
  size(400, 400, P2D);
  revolutionCtr=0;
  nextTime=0;
  blocking=false;
}

void draw() {
  background(64); 
  translate(width/2, height/2);    

  if (millis()+DELAYTIME_MS>nextTime) {
    blocking=false;
  }

  rotate(inRadians(VirtualPosition));
  strokeWeight(3);
  stroke(255, 0, 0);
  line(0, 0, 150, 0);
}

void keyPressed() {
  if (key == '+') { 
    updateMotorPosition(STEPONCE);
  } else if (key == '-') { 
    updateMotorPosition(-STEPONCE);
  }
}

void updateMotorPosition(int step) {

  blocking=true;
  nextTime=millis()+DELAYTIME_MS;

  println ("CONTROL MOTOR 0 ", step>0 ? "UP: CLOCKWISE" : "DOWN: CCW");

  int tmp=VirtualPosition+step;

  if (tmp >= STEPS_FOR_ONE_REVOLUTION) {
    VirtualPosition = 0 + (tmp%STEPS_FOR_ONE_REVOLUTION);     
    revolutionCtr++;
    println("...", tmp, VirtualPosition, revolutionCtr);
  } else if (tmp <= -STEPS_FOR_ONE_REVOLUTION) {
    VirtualPosition = 0 - (abs(tmp)%STEPS_FOR_ONE_REVOLUTION);
    revolutionCtr--;
    println("...", tmp, VirtualPosition, revolutionCtr);
  } else {
    VirtualPosition=tmp;
  }  

  printData( VirtualPosition);
}

void printData(int VirtualPosition) {
  println("pos", VirtualPosition, nf(inRadians(VirtualPosition), 0, 3), "Rev:", revolutionCtr);
}

float inRadians(int val) {
     

  return  map (val, -STEPS_FOR_ONE_REVOLUTION, STEPS_FOR_ONE_REVOLUTION, -TWO_PI, TWO_PI);  // -2pi to 2pi is 2 revolutions, the original transform is NOT correct
  //return radians(VirtualPosition);
}

Thank you very very much kfrajer

2 Likes