Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reading position from a quadrature encoder #619

Open
sarrfar opened this issue Jul 25, 2024 · 4 comments
Open

Reading position from a quadrature encoder #619

sarrfar opened this issue Jul 25, 2024 · 4 comments

Comments

@sarrfar
Copy link

sarrfar commented Jul 25, 2024

I am using an NI cDAQ-9184 with the NI 9411 module to read a quadrature encoder, but I can't seem to figure out how to get position readings from it. I have a voltage pulse signal wired into the 9411 to act as my external sample clock, and the sample timestamps seem to be right, but I seem to be getting edge counts or something rather than actual angular position measurements. I'm assuming I need to use some other piece of the library to convert to position, but I can't seem to figure that part out. I would welcome any help!

    task_a = nidaqmx.Task()
    sample_rate = 2000  # Hz
    n_tot = sample_rate*seconds_to_record
    data_matrix = np.zeros((n_tot,))

    task_a.ci_channels.add_ci_ang_encoder_chan(
        counter="cDAQ9184-1C3169FMod3/ctr0",
        name_to_assign_to_channel="encoder 1",
        decoding_type=nidaqmx.constants.EncoderType.X_1,
        zidx_enable=True,
        units=nidaqmx.constants.AngleUnits.DEGREES,
        pulses_per_rev=4096
    )

    task_a.timing.cfg_samp_clk_timing(
        rate=sample_rate,
        source="/cDAQ9184-1C3169FMod3/PFI3",  
        sample_mode=AcquisitionType.CONTINUOUS,
        samps_per_chan=sample_rate*seconds_to_record
    )

    print("beginning data collection. time of collection is approx ", seconds_to_record, " seconds.")

    task_a.start()
    stream = stream_readers.CounterReader(task_a.in_stream)

    stream.read_many_sample_double(
        data=data_matrix,
        number_of_samples_per_channel=n_tot
    )

    task_a.stop()
    task_a.close()
@zhindes
Copy link
Collaborator

zhindes commented Jul 25, 2024

A few questions:

  • What is the data you are reading?
  • How have you hooked your encoder up to the 9411?
  • Do you know the part number or have the datasheet for your encoder?

For details on how encoders work see NI Hardware Encoder Measurements: How-To Guide.

My best guess at what might be happening is that your encoder connections to the 9411 don't match the DAQmx defaults. See CIChannel.ci_encoder_a_input_term, CIChannel.ci_encoder_b_input_term, and CIChannel.ci_encoder_z_input_term

@sarrfar
Copy link
Author

sarrfar commented Jul 25, 2024

The data I am reading looks like a series of extremely quick fluctuations when I turn the encoder about 45 degrees, which is what led me to assume I'm reading pulses instead of position. Every peak maxes around +/-0.09, the sign seemingly dependent on which direction it's rotating
image
zoomed in image:
image

The encoder is hooked up using the AMT-18C-3-072 cord from the encoder manufacturer (ending in pigtails) wired into a DB15 connector, which plugs in directly to the 9411. I did follow the diagram from NI on which wires to connect where, but maybe the defaults are different in the nidaqmx package?
image

The encoder is the AMT132Q-V from CUI devices, datasheet here: CUI AMT Series Encoders

@zhindes
Copy link
Collaborator

zhindes commented Jul 25, 2024

From what I can tell the defaults should match that diagram, but it doesn't hurt to set them to be certain. you can modify your code this way:

    encoder_chan = task_a.ci_channels.add_ci_ang_encoder_chan(
        counter="cDAQ9184-1C3169FMod3/ctr0",
        name_to_assign_to_channel="encoder 1",
        decoding_type=nidaqmx.constants.EncoderType.X_1,
        zidx_enable=True,
        units=nidaqmx.constants.AngleUnits.DEGREES,
        pulses_per_rev=4096
    )
    encoder_chan.ci_encoder_a_input_term = "cDAQ9184-1C3169FMod3/PFI0"
    encoder_chan.ci_encoder_b_input_term = "cDAQ9184-1C3169FMod3/PFI1"
    encoder_chan.ci_encoder_z_input_term = "cDAQ9184-1C3169FMod3/PFI2"

That data is very interesting. You're only ever getting two values: 0 and -0.087 degrees. That second value is a single tick of the encoder, 360/4096. So you're resetting back to 0 very quickly. I wonder if the Z Index signal is not configured correctly, noisy, or bad? I can't tell from the data sheet how that Z index is supposed to behave. You could try these settings:

@sarrfar
Copy link
Author

sarrfar commented Sep 25, 2024

I just came back to this after a long hiatus - setting the defaults seems to have fixed everything. I'm now getting numbers that make sense. Great call, thank you!
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants