Weired torque senor reading

Status
Not open for further replies.

geralde.givens

New member
Hello folks,

We are using a torque senor (TRT-500, reaction torque sensor) to measure the torque produced from our motorized knee exoskeleton. Our motor system uses maxon motor and gearbox and is coupled with external bevel gears. We are now just testing its system response. The motor system is controlled using the current controller mode of maxon motor drive board (ESCON 50/5). We are using Teesy 3.2 as our microcontroller.

Now one task is that we are commanding the motor system to produce 2A current that is equivalent to 10Nm torque (based on our setup) at a fixed position. The reading from torque sensor is 10Nm when the microcontroller sent the instant command of 2A current to the motor system. The strangest thing is that the reading from torque sensor would be only 6Nm when the microcontroll send the command that ramps up the current to 2A in a short time (lets say in 1 second). This problem has been consistent. It happens to the other torque levels as well. We checked that the current to drive the motor is same during the instant case and ramping case.

We are bothered by this issue for a few weeks. Please let us know if you have any ideas. Thank you so much folks.

The portion of code for instant current and ramping current are as below.
Code:
if (option_motor == 'instant current') {      
      allprintln("\n\nYou selected send one current command...");
      allprint("Enter Torque (in Nm) you want to apply: ");
      while ((!Serial.available()) && (!BLE.available())) {}
      digitalWrite(onoff, LOW); analogWrite(motor, midpoint);
      float torqs = 0.0;
      update_float(torqs);
      allprintln(torqs);
      float bits_to_write = map((torqs/(0.0136*3*51*1.4)), -5.00, 5.00, 0.0, 4096.0); //##** if change from -5 to 5 change the -7,7 here   ... 1.0 value is efficiency.... dunno if we need it
      allprintln(bits_to_write);
      int bits_written = int(bits_to_write);
      if (bits_written > 4096) {
        bits_written = 4096;
      }
      else if (bits_written < 0) {
        bits_written = 0;
      }
      float volts_written = map(float(bits_to_write), 0., 4096., 0.0, 3.3);
      float current_written = map(volts_written, 0, 3.3, -5.00, 5.00);  //##** if change from -5 to 5 change the -7,7 here
      allprint(bits_written); allprint(", "); allprint(volts_written); allprint("V, "); allprint(current_written); allprintln("A");
      digitalWrite(onoff, HIGH);
      unsigned long timer_test = millis();
      analogWrite(motor, bits_written);
      while (entry != STOP) {
        if (millis() - timer_test > print_freq) {
          float current = map(float(bits_written), 0.0, 4096.0, -5.00, 5.00);
  //        allprint(x); allprint("\t");
          allprint(current);// * .0136 * 3*51); 
          allprint("\t"); allprint(read_torq(torq_pin));
          allprint("\t"); allprintln(motor_angle*motor_angle_conversion);
          timer_test = millis();
        }
        update_char(entry);  //update entry value
        //
      }
    }

    if (option_motor == 'raming current') {
      allprintln("\n\nYou selected ramp up to current command...");
      allprint("Enter Torque (in Nm) you want to apply: ");
      while ((!Serial.available()) && (!BLE.available())) {}
      digitalWrite(onoff, LOW); analogWrite(motor, midpoint);
      float torqs = 0.0;
      update_float(torqs);
      allprintln(torqs);
      float bits_to_write = map((torqs/(0.0136*3*51*1.4)), -5.00, 5.00, 0.0, 4096.0); //##** if change from -5 to 5 change the -7,7 here   ... 1.0 value is efficiency.... dunno if we need it
      int bits_written = int(bits_to_write);
      if (bits_written > 4096) {
        bits_written = 4096;
      }
      else if (bits_written < 0) {
        bits_written = 0;
      }
      float volts_written = map(bits_to_write, 0, 4096, 0.0, 3.3);
      float current_written = map(volts_written, 0, 3.3, -5.00, 5.00);  //##** if change from -5 to 5 change the -7,7 here
      allprint(bits_written); allprint(", "); allprint(volts_written); allprint("V, "); allprint(current_written); allprintln("A");
      digitalWrite(onoff, HIGH);
      unsigned long timer_test = millis();
      int x = midpoint;
      
      while (entry != STOP) {  
        delay(1); //delayMicroseconds(75);
        analogWrite(motor, x);  
        if (x < bits_written) {
          x++;
        }
        else if (x > bits_written) {
          x--;
        }
        //for printing torq and testing
  //      allprint("\nTorq (N/m)"); allprint("\t"); allprintln("Angular Velocity (deg/s)"); 
        if (millis() - timer_test > print_freq) {
          float current = map(float(x), 0.0, 4096.0, -5.00, 5.00);
  //        allprint(x); allprint("\t");
          allprint(current);// * .0136 * 3*51); 
          allprint("\t"); allprint(read_torq(torq_pin));
          allprint("\t"); allprintln(motor_angle*motor_angle_conversion);
          timer_test = millis();
        }
        update_char(entry);  //update entry value
        //
      }
    }
 
There's only limited advice I can offer for a motor controller I've never used, and a sensor I've never used, and a fairly complex code fragment that doesn't show all the variable types or definitions of several functions it calls.

However, it is pretty easy to see that the "instant" case does a single analogWrite(motor, bits_written). The "raming" (maybe "ramping") case does analogWrite(motor, x) inside a loop:

Code:
  while (entry != STOP) {
    delay(1); //delayMicroseconds(75);
    analogWrite(motor, x);
    if (x < bits_written) {
      x++;
    }
    else if (x > bits_written) {
      x--;
    }
    // ...more stuff...
    update_char(entry);  //update entry value
  }

Now I hope you can understand how impossible it is for me to comment much on this code. I don't see where "entry" is declared so I don't even know what type it is. The update_char() function doesn't appear in the code fragment you gave, and the comment "//update entry value" is a pretty meaningless extra bit of info!

The first obvious question is whether "x" manages to increment or decrement fully to the final "bits_written" value of the instant case before "entry" somehow becomes "STOP". If update_char() is causing "entry" to become STOP before x reaches the final intended value, then of course you'd get the wrong result.

Perhaps you could print the value "bits_written" before starting the loop, and the value of "x", then watch in the serial monitor to see whether it actually gets to the final intended value. Or you could use a voltmeter or oscilloscope to monitor the analog output.

You might also try to simplify this code a bit. It seems quite complicated for such a simple task. At the very least, choosing better variable names that really express what the variable means and using Tools > Auto Format would probably help.

If you post more code, please consider the "Forum Rule". We ask for complete code because fragments without the variable defs are quite difficult to read. Usually the very best thing you can do is try to reduce your program to just a small piece which shows the problem (and actually test it to make sure it really does have the problem). Then you can share a small but complete program. We're usually pretty good on this forum at helping when you do this. Without a complete program, usually the results are so great.
 
Status
Not open for further replies.
Back
Top