Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

Quadrature encoder programming using DDK or DAQmx base

I spent sometime trying to get my Quad encoder working on a 6229 using either RLP or DAQmx Base.

On the RLP side I did the following modifications base on NI suggestions:

in gpctex1.cpp - simpleEventCountConfigGPCT0()
board->G0_MSeries_Counting_Mode.writeG0_MSeries_Alternate_Synchronization(1); // uncomment this line
board->G0_Counting_Mode.writeG0_Encoder_Counting_Mode(4); // add this line

No luck the GPCT0 value remains at 0x00000000

if I comment the second line (...writeG0_Encoder_Counting_Mode)
the GPCT0 value increase, (or decrease as specified by setG0_Up_Down())
But conting/deconting does not work!


I've hacked DAQmx base to reflect the above modification, without success.
In DAQmxBase Start Task MSeries.vi I forced 'Operation' to be 'position' (not 'CountEdges') and added [G0EncoderCountingMode] + [G0MSeriesAlternateSynchronization] (see the attached picture). Again no luck.

I've checked that I got pulses at both PFI8 (A) and PFI10 (B)

I must be missing *something* in the board configuration!

Your help is welcome

Chris
0 Kudos
Message 1 of 14
(15,461 Views)

Try setting the A and B source using the G0_MSeries_ABZ register

    board->G0_MSeries_ABZ.setG0_A_Select(9);    //PFI8=9,
    board->G0_MSeries_ABZ.setG0_B_Select(21);  //PFI10=21

I also verified that these register fields are available in the M Series MHDDK in LabVIEW and C.
 
FYI: (there is also a register field for G0_Z_Select if you are using a Z index.
Message 2 of 14
(15,446 Views)
Also, since you are hacking NI-DAQmx Base, please note that the "position" cases are entirely untested since NI-DAQmx Base does not really support position measurements.  The code was written by copying other code and could have errors.  None of the top level NI-DAQmx VIs (create channel, start task, etc.) ever traverse the position code path.  Just post back if you find any unexplained behavior and we'll try to figure out what's going on.
Message 3 of 14
(15,441 Views)
Thanks for your reply,

Setting the A and B source might have helped going in the right direction, but it is not enough.
I still have GPCT0 counting only in one direction despite the encoder going in both directions.

This triggered a question regarding the difference between the setxx and the writexx instructions. It looks like that after a setxx, a flushxx is required (it is used to have all the setxx operations commited at the same time?) while the writexx does write directly to the registers.
So I added " board->G0_MSeries_ABZ.flush(); " Unfortunatly it did not help my quest.

I've look at what DAQmx does, but the interesting part is hidden in nilvaiu.dll. I would be interresting to know what is performed within DAQmxCreateCIAngEncoderChan()

So I would love to get a working example. I'm sure we can go on trying to play with one register after the other, but it sounds quite unefficiant.
Message 4 of 14
(15,431 Views)
I hacked DAQmx Base to get this working.  I was missing a few things earlier.  Attached is a screenshot of the hack I made to DAQmxBase Start Task MSeries.vi and then tested running the Count Digital Events.vi example.  I did not get a chance to create a new example for the C MHDDK but hope to soon.
 
The changes should essentially be:
//Set Counting Mode
board->G0_MSeries_Counting_Mode.setG0_MSeries_Alternate_Synchronization(1);
board->G0_MSeries_Counting_Mode.setG0_MSeries_Encoder_Counting_Mode(1); //1 for X1 encoder counting
board->G0_MSeries_Counting_Mode.flush();

//Enable Input Pins
board->G0_MSeries_ABZ.setG0_A_Select(9); //PFI8=9,
board->G0_MSeries_ABZ.setG0_B_Select(21); //PFI10=21
board->G0_MSeries_ABZ.flush();

// Set counter to use HW signal for up/down selection
board->G0_Command.writeG0_Up_Down(2): // Software_Down=0, Software_Up=1, Hardware=2, Hardware_Gate= 3
board->G0_Input_Select.setG0_Source_Select(20); //PFI8=9, 0=20 MHz

Message Edited by Malcolm on 10-12-2005 04:51 PM

Message 5 of 14
(15,424 Views)
Works like a charm 🙂 Thanks Malcolm!

I've propagated the hacks from the DAQmx base lower VIs to the top level ones. I'll post it tomorrow. For sure NI solution will be different, but at least one could read Quadrature encoder.

Again Thanks Malcolm
0 Kudos
Message 6 of 14
(15,408 Views)
As promised here is the modified DAQmx base VIs to implement Quadrature encoder on M-Series board, please note that:

- THIS IS NOT AN OFFICIAL NI PRODUCT
- You should do a backup prior to install these VIs
- NI will most likely implement the quadrature encoder support differently
- The modifications involved change the structure and the behavior of some DAQmx Base VIs, do a backup
- The implementation is not complete, i.e. Z channel is not supported
- usual blabla about your responsibility when using this code, do a backup


See the ReadMe file to learn where to put the modified VIs/Typedefs

Chris
0 Kudos
Message 7 of 14
(15,400 Views)
Let's play with the Z channel. Here is the C equivalent of my G programming.

I've added  

board->G0_MSeries_ABZ.setG0_Z_Select(10);  //PFI9=10

I need to tell CTR0 to reset when the index go low, I tried to use

board->G0_MSeries_Counting_Mode.setG0_MSeries_Index_Enable(1);
board->G0_MSeries_Counting_Mode.setG0_MSeries_Index_Phase(1);

Then CTR0 constantly reset, conting only to one or two.

So what do I need to add to have CTR0 correctly reset when the Z goes to 0?

Thanks

Chris
0 Kudos
Message 8 of 14
(15,384 Views)
The three relevant bits from the Counting Mode register are below.  You probably need to adjust the Index_Phase
 
G0_Index_Phase  bit: 6..5 
This bitfield determines the state of the A and B quadrature signals, and is where the index (or Z signal) is acted upon. The Z index can span multiple phases of the quadrature, but you should reload the counter in only one of the phases.
0: A low, B low
1: A low, B high
2: A high, B low
3: A high, B high
 
G0_Index_Mode  bit: 4
The effect of setting this bit depends on the counting mode.
Quadrature Mode:  The index (Z) reloads the counter in the phase determined by the value of G1_Index_Phase when the Z input is high.
Two-Pulse Mode:  The counter reloads while Z is active.
Fast Gate Mode:  The gate is synchronized to the counter clock.
Synchronous Source Mode:  Disables edge detection on the source pin, allowing it to be asynchronous.
 
G0_Counting_Mode  bit: 2..0
This field determines the counting mode to use to interface to different encoders and applications.
0: Normal counting mode
1: Quadrature Mode X1
2: Quadrature Mode X2
3: Quadrature Mode X4
4: Two-Pulse Mode
5: Fast Gate Mode
Message 9 of 14
(15,368 Views)
Thanks,

Something elese must be missing. Since I can't reset CTR0 when the Z index goes to 0.

In DAQmx base I've set the set G0_MSeries_Encoder_Counting_Mode to

0b1010011 = A high - B low (10)| index one (1) |bit 3 unused (0)| X4 mode (011)

do I need to set G0_MSeries_Counting_Mode.setG0_MSeries_Index_Enable to 1? what else?

What is the difference between G0_MSeries_Index_Enable and the bit 4 of Encoder_Counting_Mode ?

Thanks for you enlightenment

Chris
0 Kudos
Message 10 of 14
(15,351 Views)