Digital read out in position measurement's problem

Discussion in 'General Electronics Chat' started by raychar, Dec 12, 2011.

  1. raychar

    Thread Starter Member

    Nov 8, 2011
    82
    0
    Hello,
    I am doing a project of building a digital readout (DRO). I use PIC18F452
    controller. There are positive and negative sign readout digits when the moving head moves above or below a set zero respectively. Every thing
    goes fine when the head move generally. However, when the head or stepper motor was driven up and down rapidly which likes an oscillation, wrong readings appear.

    The construction of circuit includes feeding the positive and negative inputing pulses to the stepper driver to the microcontroller's first interrupt pin(INT0) and second interrupt pin(INT1). The program includes two interrupt subrountines to record number of positive and negative steps at every moment. Another subroutine does the multiplication of the number of steps with the length of step, it is a 16bits and 16bits multiplication.

    The weird data include a sudden big increment or sudden opposite
    sign in the data. I admit that the environment condition is not good because there is high frequency and large current sparkings which were emitted by the motor and relay when the head or motor reverses in directions.

    So, there may be one of following cause or some others that I haven't figure out:
    1) Sparkings. However, I may rule it out?? because, in the same program,
    I write a timer to have readout of each second elapsing and there is no
    erratic time readings occur. As well as, I have another IC 18F458 to
    have PWM output to control PWM frequency and duty cylce. I haven't
    observed any erratic waveform of it from scope, may be the enhance
    pwm module have more interferenc immunity??
    2) The controller and the program can't cope with the very short interval
    time between consercutive pulses inputing to it, because time needed in
    doing the multiplication subroutine takes much longer time than this
    interval. The controller already run at 40MHz at maximum, is it
    sufficient??

    Does anyone have the knowledge and experience of this and share the advice and ammendments.
    Thanks, and thanks for reading the long descriptions.
     
  2. MrChips

    Moderator

    Oct 2, 2009
    12,421
    3,357
    A number of suggestions are appropriate here. Post your circuit and the code. Is the code written in asm or C? Are you doing floating point math? Are you using interrupts? Are you doing calculations in the interrupt routines? If we knew clearly what you are doing we may be able to help you.
     
  3. raychar

    Thread Starter Member

    Nov 8, 2011
    82
    0
    It is in C, it should be 8x8bits multiplier, and I do 16bit multiplication by softwares as listed in below, because program is long, I listed the multiplication and the interrupts only, it a bit mesh but runs okay and hoping you can understand:

    Code ( (Unknown Language)):
    1.  
    2.  
    3. /* *****************Multiplication************************************************/
    4. unsigned long Position(unsigned char G,unsigned char G1,unsigned char G2)
    5. {
    6. /*----------------------------K=(V+8*V1+8*48*V2)-------------------------*/
    7. /*----------------------------K=(V+8*V1+8*16*3*V2)-------------------------*/
    8.  unsigned long S1,S2,S3,S4,S5,S6,Z1,Z2,Z3,Z4;
    9.  unsigned long P,Q,R,S,T,U,X,W;
    10.   K=(G+(G1<<3)+(3*(G2<<7)));
    11.   A=(K&0xFF00)>>8;   //upper bits of 16-bits
    12.   B=(K&0x00FF);    //lower bits of 16-bits
    13. /*-----------------------------e.g 79.997917mm--------------------------*/
    14. /*------------------------------A10=(V+8*V1+384*V2) * (0.8/(48*8)------------------------*/
    15. /*----magnified by 10^7---------A10=(V+8*V1+384*V2) * (0.8/(48*8) *10^7/10^7------------------------*/
    16. /*------------------------------A10=decimal 799966367 or 0x2FAE849F -----------------------------*/
    17. /*----divided by 10^4-----------A10=(V+8*V1+384*V2) * 20833 /10^7 -------------------------*/
    18. /*------------------------------A10=(V+8*V1+384*V2) * (0x5161)/10^7 ----still magnified by 10^3-----------*/
    19. /*------------------------------Displaying 079.997 (6 digits)--------------------------*/
    20.  
    21.  Z1=B*0x61;   //  was B*97
    22.  P=((Z1&0xFF00)>>8); //0x96
    23.  Q=(Z1&0x00FF);  //0x69
    24.  Z2=A*0x61;   //  was A*97
    25.  R=((Z2&0xFF00)>>8); //0x57
    26.  S=(Z2&0x00FF);  //0xE3
    27.  Z3=B*0x51;   //  was B*98
    28.  T=((Z3&0xFF00)>>8); //0x97
    29.  U=(Z3&0x00FF);  //0x68
    30.  Z4=A*0x51;   //  was A*98
    31.  W=((Z4&0xFF00)>>8); //0x58
    32.  X=(Z4&0x00FF);  //0x78
    33.  
    34.  S1=Q;  //0x69 was D2
    35.  S5=P+S;  //0x179 was 0x1E
    36.  S6=R+T;  //0xEE was 0x132
    37.  S4=W;  //0x58 was B2 wss 59
    38.  if(S5==0x100)
    39.   {
    40.   S6=S6+0x01;
    41.   S5=0x00;
    42.   goto loop_p;
    43.   }
    44.  if(S5>0x100)  //0x179
    45.   {
    46.   S6=S6+0x01;  //0xEE+1=0xEF
    47.   S5=S5&0x0FF; //0x79  
    48.   }
    49. loop_p:
    50.  S2=S5+U; //0x79+0x968=0xE1 was 0x1E+0xFF=0x11D, 3C
    51.  if(S2==0x100) //0xE1=P+S+U
    52.   {
    53.   S6=S6+0x01;  //  was 0x132+0x01=0x133
    54.   S2=0;
    55.   goto loop_q;
    56.   }
    57.  if(S2>0x100)  //=P+S+U
    58.   {
    59.   S6=S6+0x01;  //  was 0x132+0x01=0x133
    60.   S2=S2&0x0FF; //  was 0x1D
    61.   }
    62. loop_q:
    63.  S3=S6+X; //0xEF+0x78=0x167 was 0x133+0x22=0x155, =77=R+T+X
    64.  if(S3==0x100)
    65.   {
    66.   S4=S4+1;
    67.   S3=0;
    68.   goto loop_r;
    69.   }
    70.  if(S3>0x100)  //0x167
    71.   {
    72.   S4=S4+1;  //0x58+1=0x59 was S4=B2+1=B3
    73.   S3=S3&0x0FF; //was 0x67
    74.   }
    75. loop_r:
    76.  
    77.  
    78.  A10=((S4&0x000000FF)<<24)+((S3&0x000000FF)<<16)+((S2&0x000000FF)<<8)+(S1&0x000000FF); //decimal
    79.  
    80.  return(A10);
    81. }
    82. /* *******************Interrupts*********************************** */
    83.  
    84. /*--------------------------------------------------*/
    85. void interrupt HI_ISR()
    86. {
    87.  if(INT0IF==1)  //Downward
    88.  {
    89.   INT0IF=0;
    90.    V=V+0x01;
    91.     if(V>=0x08)
    92.      {  
    93.      V=0x00;
    94.      V1=V1+0x01; //V1*(+8) half-steps done  
    95.      if(V1>=0x30) //=48
    96.       {
    97.       V1=0x00;
    98.       V2=V2+0x01;  //V2*(+1) revolutions done
    99.       if(V2>=0x64)  //=100
    100.        {
    101.        V2=0x00;
    102.        }
    103.       }
    104.      }
    105.  }
    106.  if(INT1IF==1)  //Upward
    107.  {
    108.   INT1IF=0;
    109.    Y=Y+0x01;
    110.     if(Y>=0x08)
    111.      {  
    112.      Y=0;
    113.      Y1=Y1+0x01; //Y1*(+8) half-steps done  
    114.      if(Y1>=0x30) //was 72 was 12
    115.       {
    116.       Y1=0x00;
    117.       Y2=Y2+0x01;  //Y2*(+1) revolutions or Y2*(+96) half-steps done
    118.       if(Y2>=0x64)
    119.        {
    120.        Y2=0x00;
    121.        }
    122.       }
    123.      }
    124.  }
    125. }
    126. /*--------------------------------------------------*/
    127.  
    128.  
     
    Last edited by a moderator: Dec 12, 2011
  4. MrChips

    Moderator

    Oct 2, 2009
    12,421
    3,357
    Why do you use hexadecimal notation in your code?
     
  5. raychar

    Thread Starter Member

    Nov 8, 2011
    82
    0
    I don't know my thinking is correct or not. Because those variables are later used in 8bits and 8 bits multiplication, so they are valued as hex. at first.

    Thanks
     
  6. MrChips

    Moderator

    Oct 2, 2009
    12,421
    3,357
    This is a common misunderstanding from people who have not fully grasped the basics. The compiler and the MCU do not care whether you use binary, hexadecimal or decimal. They are all the same. The MCU sees BINARY only.

    What matters is what humans see in the code!
    The rule of thumb is: use whatever representation makes the most sense to the programmer and reader.

    If I am going to do a mathematical calculation or a loop counter, I use decimal, e.g. F = C*9/5 + 32;
    (just an example. In integer arithmetic, I would do it differently.)

    If I am creating a word mask, I use hex, e.g. low_nibble_mask = 0x0F;

    If I am creating a bit mask, I use binary, e.g. EOC = 0b0001000;
     
Loading...