erlerobot / smart_motor

4 stars 2 forks source link

Calculation review #41

Open imuguruza opened 8 years ago

imuguruza commented 8 years ago

@jlamperez and co, can you review if my calculations are the same as yours concerning ADC?

PGA-> 2/3 -> Full Scale Ragne is +- 6.144v

As the Vcc= 5v -> The scale that ADC reads is 0~5v. So, unused scale is 6.144-5 = 1.144v.

From other side -> 16 bits of resolution - > for 6.144v Means each step of ADC would read -> 6.144v / 2^15 = 0.1875 mv/step

Wasted steps are -> 1,144v / 0,1875mv/step = 6102 wasted steps of conversion

Useful ADC range -> 2^15-6102 = 26666 steps => 0x0000 to 0x682A 2666 steps for 180º -> 180º/2666 steps = 0,0675º/steps -> resolution offered by ADC

jlamperez commented 8 years ago

Yes your calculations are corrects.

Then if you do a bitwise for 12 bits and 10 bits to reduce the noise you have:

(12bits) ->1.5*10^-3 V/bit => 3333 steps => 0x0 to 0xD05 (10 bits) ->6.10^-3 V/bit => 833 steps => 0x0 to 0x341

imuguruza commented 8 years ago

10 bits resolution:

Total ADC steps: 2^10 = 1024

Wasted steps -> 1,144v / 1024 ticks = 0,006 V/ticks 1,144v/0,006 V/ticks => 191 ticks wasted

Real Range -> 2^10 - 191 = 2014 - 191= 833 ticks Range 0x0 - 0x341

Servo Motor Range -> 180º -> 180º/833 ticks = 0,21º/tick -> Enough for control

Servo Motor Range -> 360º -> 360º/833 ticks = 0,43º/tick -> Enough for control

imuguruza commented 8 years ago

Just a question @jlamperez: which control loop frequency are you using?

jlamperez commented 8 years ago

I'm using a timer. This timer takes samples at 50ms(now, want 10ms) an activates a flag. So in the main when this flag is 1 starts the control loop.

imuguruza commented 8 years ago

Aa that's true... BTW have you tried using a single channel of the ADC (the position readings) to check if affects the control?

jlamperez commented 8 years ago

Before doing the complete prototype I was doing only taking the position reading and the same happen. With 100ms it worked well but with 10ms not...

imuguruza commented 8 years ago

Well I was thinking:

1) As the ADC has 860 samples/second max, and we should take (aliasing and so on, 12 samples and filter them to have an average position value?)-> means we only could have ~860/12=~72Hz of loop control -> 14ms.So this should be achievable from ADC point of view.

That's the case when only 1 channel of ADC is used, because if we use more, and we switch at the same time of channels, it could be reduced by a fourth ...

2) You mentioned something about sampling time per channel, I cannot see it, where it is in the datasheet? This could be meaningful

jlamperez commented 8 years ago

Also you would need to take in account this:

The ADS1115 will be similar in that you need to consider internal oscillators that may vary from part to part. The ADS1115 can vary +/- 10%, so if you have a nominal data rate of 860, the minimum will be 90% of 860 (774sps.) This would require a minimum delay of 1.29ms.

https://e2e.ti.com/support/data_converters/precision_data_converters/f/73/t/203312

When I am reading a value the time needed to do the conversion inside the ads1115 is 1.29ms. In code here I use the delay function from the wiring pi library. I am not using the continuous mode.

The standard delay call, nanosleep(2) will sleep for at least how long you tell it, plus any operating system overhead and that comes to at least 20 to sometimes over 100 microseconds.

https://projects.drogon.net/accurate-delays-on-the-raspberry-pi/

The delay call it seems that it is not a problem because it is only 20-100 microseconds.

About the switching time between the 4 single ended I read in a forum that it was 10ms but I am not sure and do not take into account.

imuguruza commented 8 years ago

Just a question about the interface that is printing position and PWM values:

------------318--------------
Elapsed: 0.000537 seconds
Time: 10.255055 seconds
MAIN position value is: 146 
MAIN pwm value is: -12 

the "Main position value" is in ticks? Meaning that is the ADC reading converted into ticks?

So if read position is 146, means that in voltage, the A0 input voltage should be: (taken 10 bits resolution): 146 ticks * 0,006v/ticks = 0,876 volts at A0 input pin

jlamperez commented 8 years ago

Yes you are right. There the value is in ticks

imuguruza commented 8 years ago

I'm reading 216mV at the input of the A0 channel of the ADC, so in ticks should be, taking 10 bits of resolution:

216mv / 0,006v/tick = 36 ticks But I'm reading 150:

------------6014--------------
Elapsed: 0.000345 seconds
Time: 187.221827 seconds
MAIN position value is: 150 
MAIN pwm value is: -13 

Am I missing something?

Furthermore, 150 ticks * 0,21º/tick = makes 31,5º. Which does not make sense and 36 * 0,21º/tick = makes 7,56º which makes more sense (using CMD_GET_POSITION says motor is in 9,9º)

imuguruza commented 8 years ago

Another thing is that the PID is a PD control algorithm. May be using I the error could be minimized. What are you thoughts about this?

jlamperez commented 8 years ago

Wait,

The potentiometer range in this servo is between 0 to 220º so the 5V are distirbuted: 0V -> 0º and 5V -> 220º.

Here(12 bits) and here(10bits) the calculations.

So if you have in Main 150 -> Here calculation in code 150 ticks/ 15.15 ticks/º = 9.9º

Also you have to take into account that for 10 bits you have to change the config.h file here and put BITS_10 because by default I left it in 12 bits.

jlamperez commented 8 years ago

About the control algorithm you are right a PID algorithm can be implemented to minimize the error. To do this algorithm I follow openservo and they don`t use the "I" component so I decided not to use it also.

imuguruza commented 8 years ago

OK, that makes more sense to me. I have notice that sometimes, it is like the control it is not taking properly position. I mean: I turn on the servo, it is more or less a one edge (0ºc), but the control thinks it is in 30º for instance. Have you notice this before?

imuguruza commented 8 years ago

I will explain it better: I execute the controller: suod ./SmartServo

Enter command: CMD_GET_POSITION  
Server reply :
cmd: 1, position: 32.010582 

Even that truly is in 0º

Enter command: CMD_SET_GOAL
Enter goal to set:60
Server reply :
cmd: 31
Enter command: CMD_GET_POSITION  
Server reply :
cmd: 1, position: 56.613758 

But if you check the servomotor, it has not moved to 60º neither 30º that should have moved (from 30º to 60º). Any reason for this?

jlamperez commented 8 years ago

This produces a movement of the servo to origin (I'm supposing that is to 0º as seen in code)

Yes when the aplication is first execute the servo goes to 0º.

But if you check the servomotor, it has not moved to 60º neither 30º that should have moved (from 30º to 60º).

I don't understand very well the servo is not moving from the supossed initial state to 60º?

Any reason for this?

When I did a sweep of the potentiometer with the ADC and saw the voltage signal in the osciloscope I noticed that when the measured voltage reached to 500mV suddenly turned to 0V and then returned back to 600mV as if he had a discontinuity in this point but I don't know if this can be the cause..

imuguruza commented 8 years ago

I don't understand very well the servo is not moving from the supossed initial state to 60º?

Yeap, when is send to 0º, acutally the motor hits its mechanical barrier and is not going to 0º, the readings from the ADC say it is in ~30º. After when trying to move to 60º, the needed movement should be 60º-30º=30º. But is not moving 30º, is moving less

jlamperez commented 8 years ago

After when trying to move to 60º, the needed movement should be 60º-30º=30º. But is not moving 30º, is moving less

Yes, but is not moving 30º because of the error no? From the upper image is moving to 56º and then it is an error of 4º until 60º by my point of view.