why not running real time?

If you have a simple question and just want an answer.
Post Reply
darshan2210
Member++
Posts: 22
Joined: Tue Jan 24, 2017 10:47 am

why not running real time?

Post by darshan2210 »

I am new to xmos and i am using XMOS start kit
I am first trying to read general encoder data which gives 2500 pulses per revolution and transfer it to serial terminal of PC.
But i am facing this problem:
Reading encoder pulses is not accurate missing 50% pulses . with my logic i should get 5000 per revolution but i am getting 2300 to 2500 pulses randomly.

Have i used interface perfectly?
Where is the problem in my logic? I cant understand.
Try to help me.

I have attached my code here.



Code: Select all

//##### Port Declaration ####//
port p1= XS1_PORT_1D ;       // PIN LED D2
port p3= XS1_PORT_1A ;       // PIN LED D1
out port clk=XS1_PORT_1I;    // PIN D24
in port home=XS1_PORT_1J;    // PIN D25
//port p2= XS1_PORT_32A;
// uart tx D22= 1G
// uart rx D23= 1H
port p_uart_rx = XS1_PORT_1H;   // PIN D23
port p_uart_tx = XS1_PORT_1G;   // PIN D22
in port p_inputsw = XS1_PORT_1E;// PIN D12
in port p_drip = XS1_PORT_1F;   // PIN D13
clock iclk = XS1_CLKBLK_1 ;
clock jclk = XS1_CLKBLK_3 ;


// interface declaration
  typedef interface enc_data{
      [[clears_notification]]void got_data(long long data1);
      [[notification]]slave void note_data(void);

}enc_data; 




// encoder pulse reading function
void encoder_read(in port p_inputsw,client interface enc_data enc_data1,streaming chanend datachannel, server interface dcs drip_counts1_start, server interface dcs drip_counts2_start)//,streaming chanend data)
{

    unsigned prev_a,new_a=0;
    char local_drip1_start=0;

     p_inputsw :> prev_a; 


     while(1)
     {


     select{
         case enc_data1.note_data(void):
             enc_data1.got_data(count_data1);
             break;


    default:
                   p_inputsw:>new_a;
                      if(new_a!=prev_a)
                      {
                         count_data1++;                       
                         prev_a=new_a;
                      }
  
    break;

     }
     }
} // end function



 // this function uses standard uart library from xmos
void transmit(server interface b1 i1, client interface uart_tx_if uart_tx,server interface enc_data enc_data1,streaming chanend datachannel)
{
    char a[]="    LED ON";
    char b[]="    LED OFF";
    char c[30]="shiva";
    char n=0;
    char temp_flag=0; 

  long long unsigned local_enc_counts1=0;
 while(1)
 {


 select
 {
         case enc_data1.got_data(long long data1):
         local_enc_counts1=data1;

         break;
  


    default :  

        sprintf(c, "  %d  ",local_enc_counts1);

              while(c[n]!=0)
                {
                    uart_tx.write(c[n]);

                    n++;
                }
              n=0;

           delay_milliseconds(100);
     
           enc_data1.note_data();




  

    break;

  }// select
 }// while

} // end




int main()
{   streaming chan drip1counts,drip2counts,datachannel;  // we are counters for encoder pulses
    chan common_start_flag;
  


    interface uart_rx_if i_rx;
    interface uart_tx_if i_tx;
    interface b1 i1;
    interface b2 m1;
    interface task_starter ts1,ts2;
    interface dcs drip_counts1_start,drip_counts2_start;
    interface reset_counts rst1;
    interface parameter drill_cap_pos;
    interface enc_data enc_data1;
    input_gpio_if i_gpio_rx[1];
    //input_gpio_if i_gpio_drip[1];
    output_gpio_if i_gpio_tx[1];


    par
    {
   on tile[0]: output_gpio(i_gpio_tx, 1, p_uart_tx, null);
    on tile[0]:uart_tx(i_tx, null,115200, UART_PARITY_NONE, 8, 1,i_gpio_tx[0]);
   on tile[0]: encoder_read(p_inputsw,enc_data1,datachannel,drip_counts1_start,drip_counts2_start);

   on tile[0]: transmit(i1, i_tx, enc_data1,datachannel);

}



    return 0;

}


peter
XCore Addict
Posts: 230
Joined: Wed Mar 10, 2010 12:46 pm

Post by peter »

Does the signal on p_inputsw have an even duty cycle? What is the width of the pulse? If the pulse is less than the time around the loop then it will miss edges. A more efficient way will be to use the pins not equals comparison in your select. Also, this could be a lot clearer if you simply request the count with one interface call:

Code: Select all

    select{
      case enc_data1.get_count(void) -> unsigned count:
        count = count_data1;
        break;

      case p_inputsw when pinsneq(prev_a) :> prev_a:
        count_data1++;                       
        break;
     }
   }
And your transmitter will then be:

Code: Select all

void transmit(server interface b1 i1, client interface uart_tx_if uart_tx,server interface enc_data enc_data1,streaming chanend datachannel)
{
    char a[]="    LED ON";
    char b[]="    LED OFF";
    char c[30]="shiva";

    while(1) {
        unsigned local_enc_counts1 = enc_data1.get_count();
        sprintf(c, "  %d  ",local_enc_counts1);

	int n = 0;
        while(c[n]!=0) {
          uart_tx.write(c[n]);
          n++;
        }
        delay_milliseconds(100);
    }
}
Hope that helps. Having the interaction between the interface calls is not going to help.
darshan2210
Member++
Posts: 22
Joined: Tue Jan 24, 2017 10:47 am

Post by darshan2210 »

yahh its running Thanks Peter.
Can you tell me in my program What is the logical mistake by me?
peter
XCore Addict
Posts: 230
Joined: Wed Mar 10, 2010 12:46 pm

Post by peter »

I expect that the problem is that you make one interface call which then calls back to the other interface and during that time the port transitions are missed.
Post Reply