Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

How to convert these raw adc values to milli seconds ?

Status
Not open for further replies.

pic.programmer

Advanced Member level 3
Joined
Aug 19, 2015
Messages
773
Helped
141
Reputation
284
Reaction score
140
Trophy points
43
Activity points
7,531
How to convert these raw adc values to milli seconds ?

I am using PIC18F and 10 bit ADC. The adc value should be converted to millis sec. The function is not linear.

raw adc value 1023 = 6 ms (10000 steps, 50 RPM)
raw adc value 511 = 12 ms (5000 steps, 25 RPM)
raw adc value 255 = 24 ms (2500 steps, 12.5 RPM)
raw adc value 127 = 48 ms (1250 steps, 6.25 RPM)
raw adc value 63 = 96 ms (625 steps, 3.125 RPM)
raw adc value 31 = 192 ms (312.5 steps, 1.5625 RPM)

raw adc value 1 = 300 ms (200 steps, 1.5625 RPM)
raw adc value 0 = infinity ms (0 steps, 0 RPM)
 

No, the question is not absurd. These was a mistake in the values. here are the new values.

raw adc value 1023 = 6 ms (10000 steps, 50 RPM)
raw adc value 511 = 12 ms (5000 steps, 25 RPM)
raw adc value 255 = 24 ms (2500 steps, 12.5 RPM)
raw adc value 127 = 48 ms (1250 steps, 6.25 RPM)
raw adc value 63 = 96 ms (625 steps, 3.125 RPM)
raw adc value 31 = 192 ms (312.5 steps, 1.5625 RPM)
raw adc value 15 = 384 ms (156.25 steps, 0.78125 RPM)
raw adc value 0 = infinity ms (0 steps, 0 RPM)

I am using POT to control the stepper motor. Step angle is 1.8 degree. I need 200 steps for 1 revolution.

If I need 50 RPM then I need 10000 steps and it needs 5.988 approx 6 ms for each step.

6 ms * 10000 = 60 sec

I need to convert the raw adc value to milli second range. I am using 1 ms Timer Interrupt.

So, if 50 RPM is needed then I use a counter and check if counter has reached 6 (6 ms) and if it is 6 then one step is given to the stepper.
 

@ FvM and what are y, a and x ?

Y is milli sec.

x is adc value ?

a = 1 ?

Ok. a = 6138

y = 6138 / 1023
 

As FvM suggested, didn't you notice that there exists an almost constant relation at the product of each row of the above values of time and adc ?

The solution to your problem can be found using the same methodology that CataM used in this other discussion here. Using the Inverse regression Calculator available on this website here, we find the following result:

Code:
Delay = 0.697 + 5,947/ADC_Result
 
@andre_teprom

Yes but adc value was going from 0 to max and required milli second value was decreasing from max to min. I had problem finding out the function.

Here is the code I made for PIC18F. Is this correct ? Code contains comments for understanding. I am taking adc values between 0 and 1023 and converting them to required milli seconds and I have created 1 ms timer interrupt/ A counter is used for each stepper motor control in the ISR and it is incremented only if that steppers adc value is greater than 0. If that counter value matches the required delay then a proper step is given to the stepper. a flag controlled by switch is used for each stepper and it decides the direction of the stepper. If stepper direction control flag is set then forward step sequence is provided and if flag is clear then reverse step sequence is provided.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
unsigned int stepper_1_control_value = 0, stepper_2_control_value = 0, stepper_3_control_value = 0;
unsigned int old_stepper_1_control_value = 0, old_stepper_2_control_value = 0, old_stepper_3_control_value = 0;
unsigned int stepper_1_required_delay_value_in_ms = 0, stepper_2_required_delay_value_in_ms = 0, stepper_3_required_delay_value_in_ms = 0;
long counter_1 = 0, counter_2 = 0, counter_3 = 0;
char stepper_sequence[4] = {0xC0, 0x06, 0x03, 0x09};
signed char i = 0, j = 0, k = 0;
unsigned char myFlags = 0;
 
#define STEPPER_1_PORT LATC
#define STEPPER_2_PORT LATC
#define STEPPER_3_PORT LATB
 
sbit stepper_1_direction_flag at myFlags.B0;
sbit stepper_2_direction_flag at myFlags.B1;
sbit stepper_3_direction_flag at myFlags.B2;
 
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
 
//Timer1
//Prescaler 1:1; TMR1 Preload = 60536; Actual Interrupt Time : 1 ms
//Place/Copy this part in declaration section
void InitTimer1() {
    T1CON = 0x01;
    TMR1IF_bit = 0;
    TMR1H = 0xEC;
    TMR1L = 0x78;
    TMR1IE_bit = 1;
    INTCON = 0xC0;
}
 
void Interrupt() {
 
    if(TMR1IF_bit){  //Interrupt every  3 ms
        TMR1IF_bit = 0;
        TMR1H = 0xEC;
        TMR1L = 0x78;
        //Enter your code here
 
        //if adc(0) value is greater than 0
        if(stepper_1_control_value > 0) {
            //if required milli seconds elapsed
            if(++counter_1 == stepper_1_required_delay_value_in_ms) {
                //provide the proper step sequence to stepper 1
                STEPPER_1_PORT = (STEPPER_1_PORT & 0xF0) | stepper_sequence[i];
 
                //if stepper 1 direction is clockwise
                if(stepper_1_direction_flag == 1) {
                  i++; //increment the stepper 1 sequence index
                }
                //else if stepper 1 direction is anti-clockwise
                else if(stepper_1_direction_flag == 0) {
                  i--; //decrement the stepper 1 sequence index
                }
 
                if(i < 0)i = 3;
                if(i > 3)i = 0;
                
                counter_1 = 0;
            }
        }
        
        //if adc(1) value is greater than 0
        if(stepper_2_control_value > 0) {
            //if required milli seconds elapsed
            if(++counter_2 == stepper_2_required_delay_value_in_ms) {
                //provide the proper step sequence to stepper 2
                STEPPER_2_PORT = (STEPPER_2_PORT & 0xF0) | stepper_sequence[j];
 
                //if stepper 2 direction is clockwise
                if(stepper_2_direction_flag == 1) {
                  j++; //increment the stepper 2 sequence index
                }
                //else if stepper 2 direction is anti-clockwise
                else if(stepper_2_direction_flag == 0) {
                  j--; //decrement the stepper 2 sequence index
                }
 
                if(j < 0)j = 3;
                if(j > 3)j = 0;
 
                counter_2 = 0;
            }
        }
        
        //if adc(2) value is greater than 0
        if(stepper_3_control_value > 0) {
            //if required milli seconds elapsed
            if(++counter_3 == stepper_3_required_delay_value_in_ms) {
                //provide the proper step sequence to stepper 3
                STEPPER_3_PORT = (STEPPER_3_PORT & 0xF0) | stepper_sequence[k];
 
                //if stepper 3 direction is clockwise
                if(stepper_3_direction_flag == 1) {
                  k++; //increment the stepper 3 sequence index
                }
                //else if stepper 3 direction is anti-clockwise
                else if(stepper_3_direction_flag == 0) {
                  k--; //decrement the stepper 3 sequence index
                }
 
                if(k < 0)k = 3; //
                if(k > 3)k = 0;
 
                counter_3 = 0;
            }
        }
    }
}
 
 
void main() {
 
    asm clrwdt
    
    TRISA = 0xC0;
    TRISB = 0x00;
    TRISC = 0x00;
 
    PORTA = 0x00;
    PORTB = 0x00;
    PORTC = 0x00;
    
    LATA = 0x00;
    LATB = 0x00;
    LATC = 0x00;
    
    asm clrwdt
    
    InitTimer1();
    Delay_ms(200);
    
    asm clrwdt
    
    while(1) {
    
          asm clrwdt
          
          stepper_1_control_value = ADC_Read(0);
          Delay_ms(20);
          stepper_2_control_value = ADC_Read(1);
          Delay_ms(20);
          stepper_3_control_value = ADC_Read(2);
          Delay_ms(20);
          
          //if adc(0) value changed
          if(old_stepper_1_control_value != stepper_1_control_value) {
              //convert adc value to required milli seconds
              stepper_1_required_delay_value_in_ms = (6138 / stepper_1_control_value);
              
              old_stepper_1_control_value = stepper_1_control_value;
          }
          
          //if adc(1) value changed
          if(old_stepper_2_control_value != stepper_2_control_value) {
              //convert adc value to required milli seconds
              stepper_2_required_delay_value_in_ms = (6138 / stepper_2_control_value);
              
              old_stepper_2_control_value = stepper_2_control_value;
          }
          
          //if adc(2) value changed
          if(old_stepper_3_control_value != stepper_3_control_value) {
              //convert adc value to required milli seconds
              stepper_3_required_delay_value_in_ms = (6138 / stepper_3_control_value);
              
              old_stepper_3_control_value = stepper_3_control_value;
          }
    }
}




Edit

Thank you FvM and andre_teprom

I am having problem using that tool. I have entered the values in the table but clicking execute doesn't show the graph not it is giving the result. What should I do to get the result ?
 

Attachments

  • inverse regression.png
    inverse regression.png
    48.8 KB · Views: 117
Last edited:

I had problem finding out the function.
...
Here is the code I made for PIC18F. Is this correct ?

Your original question was regarded to find a way to determine a relationship between ADC_result and Delay as quoted straight bellow, and honestly I did not understand what you meant at the newest question. I take this opportunity to suggest that you start developping by yourself the means to debug your programs in order to find at which piece of code the problem is supposed to be; posting the complete code do not add any benefit in determining the cause of a specific problem.

How to convert these raw adc values to milli seconds ?
...
The adc value should be converted to millis sec. The function is not linear.

- - - Updated - - -

I am having problem using that tool. I have entered the values in the table but clicking execute doesn't show the graph not it is giving the result. What should I do to get the result ?

Maybe it's a problem with your browser:

graph.png
 

Hi,

The answer is already given.

About:
t(ms) = 6138 / adc_value.
Or even better :
t(ms) = 6144 / (adc_value + 1)

****
But if you don't mind i'd optimize it.
A stepper motor needs about linear acceleration. This means linear increase of frequency. But this is difficult to achieve with your timer function.
Therefore i recommend a solution like an NCO:
Use a timer with fixed interrupt rate of 1ms = 1kHz.
One variable is "speed". Let'say an 8 bit variable. 0 means stop, 255 means full speed --> 6ms step time.
Here speed is linear..
Within the ISR:
nco_val = nco_val + speed
If nco_val > = 1530 then
(
nco_val = nco_val - 1530
Motor_step= motor_step +1 (motor makes the next step)
)
End isr

Klaus
 
@KlausST

I will try your method and update.


@andre_teprom

What browser are you suing ? I tried Chrome and IE but they are not showing the results.
 
Last edited:

In the code I posted it is mentioned

Code:
if(TMR1IF_bit){  //Interrupt every  3 ms

It should be

Code:
if(TMR1IF_bit){  //Interrupt every  1 ms

Edit:

In the code this was wrong

Code:
STEPPER_2_PORT = (STEPPER_2_PORT & 0xF0) | stepper_sequence[j];

Change it to

Code:
STEPPER_2_PORT = (STEPPER_2_PORT & 0xF0) | (stepper_sequence[j] << 4);
 
Last edited:

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top