Need a help for encoder reading by Xmos startkit

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

Need a help for encoder reading by Xmos startkit

Post by darshan2210 »

I am beginner to XMOS.
I want to read one of the Incremental Shaft Encoder by XMOS startkit.
But the my code (button_counter(); Function) can only scan inputs maximum 3500 pulse per second.
I need to scan and count about 1 Mhz frequency pulses.
i have used Standard GPIO Library.
My code is attached here.
please suggest if i have made some mistakes in code.



#include <xs1.h>
#include <stdio.h>
#include <platform.h>
#include <print.h>
#include <timer.h>
#include <uart.h>
#include <gpio.h>


#define RX_BUFFER_SIZE 20

typedef interface b1{

// param data The data to write.
void f1(char data1); // this fuction is used for moving data from client to server
} b1;

typedef interface b2{

// param data The data to write.
void fm1(unsigned int data3); // this fuction is used for moving data from client to server
} b2;

port p1= XS1_PORT_1D ;
port p3= XS1_PORT_1A ;

port p_uart_rx = XS1_PORT_1H;
port p_uart_tx = XS1_PORT_1G;
port p_inputsw = XS1_PORT_1E;//32A;


void button_counter(client input_gpio_if sw1,client interface b2 m1)
{
char button_status=0;
int current_val = 0;

while(1)
{
if(sw1.input()==0)
{

while(sw1.input()==0)
{
//p1<:1;
}


count_data++;
}
else
{
p1<:0;
m1.fm1(count_data); // interface passes count to Other Task on other core
}

}
}


int main()
{
interface uart_rx_if i_rx;
interface uart_tx_if i_tx;
interface b1 i1;
interface b2 m1;
input_gpio_if i_gpio_rx[1];
input_gpio_if i_gpio_sw;
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].core[0] : input_gpio_with_events(i_gpio_rx, 1, p_uart_rx, null);
on tile[0].core[1]: uart_rx(i_rx, null, RX_BUFFER_SIZE,115200, UART_PARITY_NONE, 8, 1,i_gpio_rx[0]);
on tile[0].core[2] : input_gpio_1bit_with_events(i_gpio_sw, p_inputsw);

on tile[0] : button_counter(i_gpio_sw,m1);//(p_inputsw,m1);//
on tile[0].core[1]: receive(i1,i_rx);
on tile[0]:transmit(i1,i_tx,m1);

}


User avatar
andrew
Experienced Member
Posts: 114
Joined: Fri Dec 11, 2009 10:22 am

Post by andrew »

Could you describe the encoder a little more? What are the signals you expect? Is it a simple AB pulse encoder? i.e. A and B are offset by 90 degrees. Thanks
darshan2210
Member++
Posts: 22
Joined: Tue Jan 24, 2017 10:47 am

Post by darshan2210 »

Yes my encoder is Simple AB type .
Model number is 725.
It gives approx 10000 per revolution.
And i need to count 23 Revolution per second means 23*10000 pulses per second.
So that's the case.
User avatar
andrew
Experienced Member
Posts: 114
Joined: Fri Dec 11, 2009 10:22 am

Post by andrew »

Assuming you can dedicate a core to the rotary encored then the best way to do it is to poll the ports.

Set up the ports to be unbuffered one bit ports.
for example:


unsigned prev_a, prev_b;
port_a :> prev_a;
port_b :> prev_b;

unsigned position = 0;

unsigned a_stability_counter = 0;
unsigned b_stability_counter = 0;

while(1){

port_a :> new_a;
port_b :> new_b;

//do some processing
if(new_a == prev_a)
a_stability_counter++;
else
a_stability_counter = 0;

//same for b

//if (stability_counter == some threshold) then move the position appropriately based on the
//known phases. maybe broadcast the new position on a channel or save it to memory etc

prev_a = new_a;
prev_b = new_b;
}

Hope that helps. Sorry it's rough
darshan2210
Member++
Posts: 22
Joined: Tue Jan 24, 2017 10:47 am

Post by darshan2210 »

How i Configure unbuffered input port ?
like this?

port p_inputsw = XS1_PORT_1E;
User avatar
andrew
Experienced Member
Posts: 114
Joined: Fri Dec 11, 2009 10:22 am

Post by andrew »

Correct, also you can add direction:
in port p_inputsw = XS1_PORT_1E;

but this only adds safety
darshan2210
Member++
Posts: 22
Joined: Tue Jan 24, 2017 10:47 am

Post by darshan2210 »

not working still i cant scan fast inputs ..
same issue repeated.


declaration:

port p_uart_rx = XS1_PORT_1H;
port p_uart_tx = XS1_PORT_1G;
port p_inputsw = XS1_PORT_1E;//32A;

void button_counter(port p_inputsw ,client interface b2 m1)//(port p_inputsw,client interface b2 m1)//
{
char button_status=0;
int current_val = 0;
unsigned prev_a,new_a=0;
p_inputsw :> prev_a;
unsigned a_stability_counter = 0;

while(1)
{


p_inputsw:>new_a;

if(new_a!=prev_a)
{
count_data++;

prev_a=new_a;
}
if(count_data>=5000)
{
m1.fm1(count_data);
}

}

//// main Function

int main()
{ chan counts;
//
//counts<:0;
interface uart_rx_if i_rx;
interface uart_tx_if i_tx;
interface b1 i1;
interface b2 m1;
input_gpio_if i_gpio_rx[1];
//input_gpio_if i_gpio_sw;
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].core[0] : input_gpio_with_events(i_gpio_rx, 1, p_uart_rx, null);
on tile[0].core[1]: uart_rx(i_rx, null, RX_BUFFER_SIZE,115200, UART_PARITY_NONE, 8, 1,i_gpio_rx[0]);
// on tile[0]: my_application(i_tx, i_rx);
// on tile[0].core[2] : input_gpio_1bit_with_events(i_gpio_sw, p_inputsw);
//on tile[0]: fun1(counts);





on tile[0] : button_counter(p_inputsw,m1);//(i_gpio_sw,m1);//
on tile[0].core[1]: receive(i1,i_rx);
on tile[0]:transmit(i1,i_tx,m1);
on tile[0]: task1();

}
darshan2210
Member++
Posts: 22
Joined: Tue Jan 24, 2017 10:47 am

Post by darshan2210 »

I solved my problem i just become foolish. My hardware related issue. The opto coupler is slower one..
Thanks a lot Andrew for support..