Rotary encoder

279 views
Skip to first unread message

Inês Vaz

unread,
Feb 18, 2019, 6:09:12 PM2/18/19
to pyControl
Hello, 

    Tanya and I are trying to use the new rotary_encoder boards and we noticed that the baseline value seems to drift away. For example, it starts at 0 and then when I use the encoder it moves from the baseline to a value higher than before independently of which direction I moved it. This is kinda problematic for myself. For this test we had the hardware def as follows:

from devices import *
board = Breakout_1_2()
poke4  = Poke(board.port_6, 'poke4_in', 'poke4_out')
joystick = Rotary_encoder(name='joystick', sampling_rate=100, output='position')
 
     In the meantime I changed the sampling of the encoder in the hardware definition to 1 and it seems much better. But we want to understand if this is something you saw before and fixed or if it's just something we have to deal with. 
Also, we tested 3 different encoders and they all have this drift (when the sampling is at 100) so we think this might be from the boards that read them and not from the encoders.

    Thank you for your help, 

PS: Bellow is the simple task we used to play/test the encoder:

from pyControl.utility import *
from hardware_definition import *

# States and events.
  
states = ['wait_for_poke',
          'wait_for_running',
          'other_state',
          'pull_reward',
          'push_reward']

events = ['poke4_in',
          'poke4_out',
          'state_timer',
          'running_start',
          'running_stop',
          'iti_timer']

initial_state = 'wait_for_running'

# Variables.

v.n_release = 5
v.del_dur  = 50 * ms
v.n = 0
v.current_position = 0
v.push_position = 100
v.pull_position = -100
v.quiet_duration = 10 * ms


# Run start and stop behaviour.
def run_start():  # 
    poke4.LED.on()

def run_end():  
    off()


 # State & event dependent behaviour.
def wait_for_running(event):
  if event == 'entry':
    poke4.LED.on()
    joystick.record()
    v.current_position = joystick.position
    print('Position: {}'.format(v.current_position))
    reset_timer('iti_timer', v.quiet_duration)
  elif event == 'iti_timer':
        poke4.LED.off()
        #goto('wait_for_poke')
        #v.current_position = joystick.position
        #print('Position: {}'.format(v.current_position))
        if v.current_position > v.push_position:
          #print('Position: {}'.format(v.current_position))
          print('Push!')
          goto('push_reward')
        elif v.current_position < v.pull_position:
          #print('Position: {}'.format(v.current_position))
          print('Pull')
          goto('pull_reward')
        else:
          goto('wait_for_running')

def push_reward(event):
    if event == 'poke4_in':
        #running_wheel.stop()
        for i in range(0, v.n_release):
            #houselight.on()
            poke4.SOL.on()
            poke4.LED.on()
            #speaker.sine(4000) # Play a 5KHz sine wave.() 
            pyb.delay(v.del_dur)
            poke4.SOL.off()
            poke4.LED.off()
            #speaker.off() # Turn off sound output.
            pyb.delay(v.del_dur)
            goto('wait_for_running')
            print('Push rewarded')

def pull_reward(event):
    if event == 'poke4_in':
        #running_wheel.stop()
        for i in range(0, v.n_release):
            #houselight.on()
            poke4.SOL.on()
            poke4.LED.on()
            #speaker.sine(4000) # Play a 5KHz sine wave.() 
            pyb.delay(v.del_dur)
            poke4.SOL.off()
            poke4.LED.off()
            #speaker.off() # Turn off sound output.
            pyb.delay(v.del_dur)
            goto('wait_for_running')
            print('Pull rewarded')

def other_state(event):
  if event == 'entry':
    poke4.LED.on()
    v.current_position = joystick.position
    print('Position: {}'.format(v.current_position))

Thomas Akam

unread,
Feb 19, 2019, 6:15:32 AM2/19/19
to pyControl
Hi Inês,

The way the task is implemented currently it it putting a lot of load on the pyboard by triggering a state transition and printing output every 10ms.  Attached is a simple task for testing the joystick which uses the ability of the Rotary_encoder to generate events when a threshold is crossed to detect when the joystick is pushed.  Can you test your setup using this task to see if you still get drift?

Thomas
joystick_test.py

Inês Vaz

unread,
Feb 19, 2019, 3:00:22 PM2/19/19
to pyControl
Hi Tom, 
 
 So we tested with your code and although we couldn't see the values of the baseline using the GUI we could see the drift of the baseline. We got the 2 mages attached with 2 different encoders. 
Do you have any ideas why this would be happening? 

image (1).png

image (2).png

Thomas Akam

unread,
Feb 20, 2019, 4:20:07 PM2/20/19
to pyControl
Hi Inês,

From the images you sent it looks like the drift is only occuring when the encoder is moving, i.e. when the encoder is not moving the signal is stable, but after you move the joystick the signal does not necessarily return to the same baseline level.  Is that correct?

To work out what may be going on it would be useful to know some more details of the setup.

What model of rotary encoder are you using?

How is the encoder connected to the pyboard?

How is the encoder mechanically attached to the joystick?  Is it possible that the drift is mechanical? - e.g. the joystick not moving back into exactly the same position, or the encoder slipping relative to the joystick.

Inês Vaz

unread,
Feb 20, 2019, 6:30:17 PM2/20/19
to pyControl
Hi Tom, 
 
 Yes, if we don't move it it's basically stable. 

 We tested initially 3 different encoders. For those last images we used the Avago 1746 A and the US digital S5-720-250-IE-S-B

 The first one is attached directly to the board using its own female pins. The second is attached with male pin wires. 

Is this useful? 
Thank you for your time, 

Thomas Akam

unread,
Feb 22, 2019, 5:56:45 AM2/22/19
to pyControl
Hi Ines,

A colleague tried the joystick_test task with one of their running wheel setups (thanks Sev!).  The setup uses a model HEDM-5500#B13 rotary encoder on the running wheel shaft, connected to the breakout board using the pyControl rotary encoder adaptor board.  As far as he could tell the rotary encoder position did not drift, and reliably returned to zero when the wheel was moved back to its baseline position (see trace below).

This makes me think that the drift problems in your setup are most likely either mechanical - e.g. the encoder is slipping relative to the joystick, or electrical, e.g. the encoder is not wired up correctly, there is a loose connection, or there is elecrical noise affecting the signal.

Have you tried using one of the HEDM series encoders connected to pyControl using the rotary encoder adaptor board? 

T



Tanya Sippy

unread,
Mar 19, 2019, 9:41:08 PM3/19/19
to pyControl
Hello, 

We are (still) looking into this problem. We tried it with arduino and the problem remained but the drift was much less. We think it may have something to do with the way the displacement is calculated in python. 

The rotatory encoder has three outputs (well 5, but 3 relevant for this discussion): A, B and I. 

A is one direction. B is the other direction and I which is the index of the displacement. Which one of these does PyControl use to calculate the displacement and how does it do this? Our hypothesis is that if A and B are used and the program is counting the number of "ticks" displaced that the acquisition rate of the board may not be keeping up with the speed of the movement of the joystick. If I is used, then this would negate our hypothesis. 

I hope that made sense. 

Thanks!!!!

Thomas Akam

unread,
Mar 20, 2019, 10:52:35 AM3/20/19
to pyControl
Hi Tanya,

The Rotary_encoder class is designed to work with rotary encoders that generate a quadrature output signal, i.e. a pair of sqare waves with a 90 degree phase shift between them. These are the A and B outputs on a quadrature encoder.  The encoder will generate a given number of cycles of the square wave on each revolution, e.g. 1000 cycles per revolution.  Some encoders also have an I output that generates a single pulse per revolution at a fixed position, this can be used to correct any drift that accumulates in the quadrature decoding.  The pyControl rotary encoder class uses only the A and B channel quadrature signals and does not currently use the I channel. 

The quadrature signal is read using dedicated quadrature decoding functionallity of the STM32F405RG microcontroller on the pyboard.  I do not know the exact implementation but it uses the microcontrollers hardware timers and is happening at a low level on the hardware, rather than being done in software.  It should therefore be OK with the high pulse rate signals generated by the encoder.  The quadrature encoder functionality is accessed in micropython using the Timer class, and the integration with pyControl is via the Rotary_encoder class.

I think it sould be possible to use the I channel to correct drift in your setup and have attached a modified version of the rotary encoder class called Position_encoder that aims to do this.  This class will only work for situations where the encoder only moves through less than a full cycle of rotation, and only outputs position not velocity.  Also, you will need to make sure that the physical position on the encoders rotation where the I output pulse is generated is located in the range of movement of the joystick - otherwise the encoder will never output pulses on the I output.  The drift correction works by storing the encoder position the first time a pulse is detected on the I output, then resetting the position to the stored value whenever a subsequent pulse is recieved on the I output.  To use this class, put the file in the pyControl/devices folder and reload the framework to the board. Connect the rotary encoder A and B outputs as normal to micropython pins X1 (DIO-A and DIO-B on port 1 of breakout board 1.2), additionally connect the I output of the rotary encoder to annother input pin on the microcontroller and specify this input as the I_pin argument when you instantiate the Position encoder.   I have attached a version of the joystick test task modified to work with this.  Rather than using the I output of the encoder, you could alternatively connect a switch or IR beam break to the I_pin input to trigger a position reset whenever the joystick reached the neutral position.

Let me know how you get on,

T
_position_encoder.py
joystick_test_II.py

Inês Vaz

unread,
Mar 20, 2019, 3:09:52 PM3/20/19
to pyControl
Hi Tom, 
 I think this works better (please see bellow) 
 Previous device version + previous test:

image.png

 The new one you just sent:

image.png

Do you think it's good ?

I think we got how this works but if the one puts some displacement onto the joystick to beginning with this will gives a wrong 0 value. Is it your suggestion to use the IR beam to define this 0 value? But if so why use this version of the device that cannot output velocity to use the I_output to use the IR beam instead of just adding another board that reads IR beams ? I feel like I'm missing something.

Thank you for being so fast at implementing this. It looks way better =)

--
You received this message because you are subscribed to a topic in the Google Groups "pyControl" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pycontrol/hkhFBrc9GVM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pycontrol+...@googlegroups.com.
To post to this group, send email to pyco...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/pycontrol/3ca096b9-b870-4606-b923-92e3444a6d4a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Inês Rodrigues-Vaz
PhD student
Neurobiology of Action Lab
Champalimaud Foundation
Av. de Brasilia, Doca de Pedrouços
1400-038 Lisboa, Portugal

Thomas Akam

unread,
Mar 22, 2019, 1:37:15 PM3/22/19
to pyControl
That looks much better! 

The way the Position_encoder class is currently setup the position the encoder is in when the Position_encoder is instantiated is defined as 0.  This will happen when you load the task, so as long as you make sure the joystick is in the neutral position then you should be OK right?

Also, I have a couple of questions.

Did you check at what joystick position the I pulse is generated?  Ideally you should make sure this position is near to the neutral position of the joystick to ensure that it is crossed regularly.

In addition to adding support for the I input restting the position, I also removed code that was not needed for this application, making the function executed each time a sample is read simpler.  I would be interested to know which of these changes has caused the big reduction in drift.  To test this, please could you modify the joystick_test_II task so that rather than saying I_pin='X12' when the encoder is instantiated it says I_pin=None.  This will stop it using the I pulses to reset the position.  Can you test it like this and let me know how it behaves?





On Wednesday, 20 March 2019 19:09:52 UTC, Inês Vaz wrote:
Hi Tom, 
 I think this works better (please see bellow) 
 Previous device version + previous test:

image.png

 The new one you just sent:

image.png

Do you think it's good ?

I think we got how this works but if the one puts some displacement onto the joystick to beginning with this will gives a wrong 0 value. Is it your suggestion to use the IR beam to define this 0 value? But if so why use this version of the device that cannot output velocity to use the I_output to use the IR beam instead of just adding another board that reads IR beams ? I feel like I'm missing something.

Thank you for being so fast at implementing this. It looks way better =)

To unsubscribe from this group and all its topics, send an email to pycontrol+unsubscribe@googlegroups.com.

To post to this group, send email to pyco...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/pycontrol/3ca096b9-b870-4606-b923-92e3444a6d4a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Inês Vaz

unread,
Mar 22, 2019, 5:07:08 PM3/22/19
to Thomas Akam, pyControl
Hi Tom, 
 I don't really get what you mean by this:
Did you check at what joystick position the I pulse is generated?  Ideally you should make sure this position is near to the neutral position of the joystick to ensure that it is crossed regularly.  

So this is what it looks like when we use the "None" option:
image.png

And this is what it looked before with the "X12" option:
image.png 

Do you think that we could use A and B to calculate the velocity if we don't use the "X12" for resetting?

Also, can you get back to me on the IR beam idea? =) 

Thanks a ton,
i

On Fri, Mar 22, 2019 at 1:37 PM Thomas Akam <thoma...@neuro.fchampalimaud.org> wrote:
That looks much better! 

The way the Position_encoder class is currently setup the position the encoder is in when the Position_encoder is instantiated is defined as 0.  This will happen when you load the task, so as long as you make sure the joystick is in the neutral position then you should be OK right?

Also, I have a couple of questions.

Did you check at what joystick position the I pulse is generated?  Ideally you should make sure this position is near to the neutral position of the joystick to ensure that it is crossed regularly.

In addition to adding support for the I input restting the position, I also removed code that was not needed for this application, making the function executed each time a sample is read simpler.  I would be interested to know which of these changes has caused the big reduction in drift.  To test this, please could you modify the joystick_test_II task so that rather than saying I_pin='X12' when the encoder is instantiated it says I_pin=None.  This will stop it using the I pulses to reset the position.  Can you test it like this and let me know how it behaves?





On Wednesday, 20 March 2019 19:09:52 UTC, Inês Vaz wrote:
Hi Tom, 
 I think this works better (please see bellow) 
 Previous device version + previous test:

image.png

 The new one you just sent:

image.png

Do you think it's good ?

I think we got how this works but if the one puts some displacement onto the joystick to beginning with this will gives a wrong 0 value. Is it your suggestion to use the IR beam to define this 0 value? But if so why use this version of the device that cannot output velocity to use the I_output to use the IR beam instead of just adding another board that reads IR beams ? I feel like I'm missing something.

Thank you for being so fast at implementing this. It looks way better =)

To unsubscribe from this group and all its topics, send an email to pycontrol+...@googlegroups.com.

To post to this group, send email to pyco...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/pycontrol/3ca096b9-b870-4606-b923-92e3444a6d4a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Inês Rodrigues-Vaz
PhD student
Neurobiology of Action Lab
Champalimaud Foundation
Av. de Brasilia, Doca de Pedrouços
1400-038 Lisboa, Portugal

--
You received this message because you are subscribed to a topic in the Google Groups "pyControl" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/pycontrol/hkhFBrc9GVM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to pycontrol+...@googlegroups.com.

To post to this group, send email to pyco...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Inês Vaz

unread,
Mar 25, 2019, 6:42:12 PM3/25/19
to Thomas Akam, pyControl
Hi Tom, 
 I was testing this a bit more and this is what the baselines look like when the position_encoder device:

image.png 

Clearly the drift is still there so I think we will need to use the IR beam option. Can you elaborate on that please? I really didn't get what you meant on the first explanation about this. 

Thanks a lot, 
i

Tanya Sippy

unread,
Apr 12, 2019, 6:26:47 PM4/12/19
to pyControl
Hello Thomas, 
I am trying to plot the rotary enocoder position files so that you can visualize better our drift problem. However, I am having trouble opening the .pca analog files. On read the docs it says that I should be able to open these files in Python using the function load_analog_data but I cannot find this function in PyControl when I import numpy. Do i need to import something else? 
Thank you 


On Monday, February 18, 2019 at 6:09:12 PM UTC-5, Inês Vaz wrote:

Thomas Akam

unread,
Apr 15, 2019, 5:12:29 AM4/15/19
to pyControl

Hi Tanya,

You need to import the pyControl data import module that is the file data_import.py in the folder pyControl/tools. Put this file somewhere on the Python path (i normally put a copy of it in the same folder the rest of my analysis code is in for that experiment), then you can import the module with:

import data_import as di

You can then import an analog data file with:

analog_data = di.load_analog_data('path//to//analog_data_file.pca')

best,

Thomas

Tanya Sippy

unread,
Apr 24, 2019, 9:32:22 PM4/24/19
to pyControl
Hello Thomas, 

When we last exchanged about this it was by email, so I move the conversation back here to reply to some of your points (Pasted from the email in italics below):

I don't think the drift should be as bad as this so I wonder whether there is any way of reducing it so that you do not need to reset the position often.  You mentioned in a mail a long time ago that the drift seemed worse when the sampling rate of the encoder was set to higher values, is that still the case?  Yes, the drift seems slightly worse at higher sampling rates. However even at sampling rates of 100Hz we still get the drift. 

Also, your task currently checks the position of the encoder every 10ms using a timer, and repeated re-entries into the wait_for_press state.  This is incurring a lot of processor load and I wonder if that is affecting the rotary encoder accuracy.  Could you test using the simple joystick_test task to see if the drift is less bad.  We tested this code and we still have the drift - it is about the same. 

It would incur less processor overheads if you did not have to check the position using a timer but instead could use the ability of the encoder class to trigger framework events when thresholds are crossed.  I can see that for your current task you would need more than a single threshold, but if it seems like the perfomance is much better when you are not checking with a timer, I could probably modify the code to allow more thresholds to be specified for triggering events. I do indeed need two thresholds and it would be ABSOLUTELY GREAT if you could modify the code to incorporate this. 

Do you think the drift happens specifically when the joystick moves really fast on being let go by the mouse?  If so you could mechanically modify the design to make it return to the center more slowly, for example by replacing the springs that move it back into position with something like these shock absorbers from remote control cars, which have an oil filled piston that generates friction when the position is changed rapidly. The drift happens mostly when the mouse moves the joystick to one direction for awhile with small, incremental movements without crossing i. The mouse rarely lets go once trained so to this is not a the problem.

We are currently working with Rick here who provides support for these types of issues. He was impressed with the microcontroller that keeps track of the quadrature and was not exactly sure why we are getting so much drift. He will be doing some testing in the next days and we will let you know the outcome. 

For now, if you could implement the two thresholds, it would be REALLY AWESOME.

THANK YOU VERY MUCH. 

On Monday, February 18, 2019 at 6:09:12 PM UTC-5, Inês Vaz wrote:

Tanya Sippy

unread,
May 15, 2019, 10:28:53 AM5/15/19
to pyControl
Hello Thomas, 
I hope all is well. Just spoke with Filipe and Goncalo about the rotatry encoder drift issue - they asked if the hardware keeps track of the position of the incremental encoder in an absolute or differential manner? They said if it is absolute, there should be no drift but if it is differential this might be the issue. 
If the hardware reading is differential can it be changed to absolute? 
Thank you for your continued help with this. 
All the best, 
Tanya 

On Monday, February 18, 2019 at 6:09:12 PM UTC-5, Inês Vaz wrote:

Thomas Akam

unread,
May 15, 2019, 3:15:53 PM5/15/19
to pyControl
Hi Tanya,

I am not completely sure what they are referring to. 

They might be refering to the difference between an incremental encoder vs an absolute encoder - incremental encoders output pulses when the position changes, absolute encoders output a different code for each position.  The encoders you are using are incremental encoders, and this is what the pyControl rotary encoder class works with.  Absolute encoders would not suffer from drift but I have never tried to interface one with pyControl and it would require different hardware and control code. 

Alternatively they might be referring to whether the signal from the incremental encoder is transmitted as a differential or single ended electrical signal, for information on the difference see here. Differential signalling is more robust agains electrical noise but more complicated to implement.  You are using single ended signalling, but this should not be a problem unless there is a lot of electrical noise around your setups.  The easist way to check this would be to measure the voltage signal on the micropython input pins that are reading the encoder signals while the encoder is moving, to see if the signal is clean or noisy.

best,

Thomas

On Wednesday, 15 May 2019 15:28:53 UTC+1, Tanya Sippy wrote:
Hello Thomas, 
I hope all is well. Just spoke with Filipe and Goncalo about the rotatry encoder drift issue - they asked if the hardware keeps track of thie position of the incremental encoder in an absolute or differential manner? They said if it is absolute, there should be no drift but if it is differential this might be the issue. 

Tanya Sippy

unread,
May 15, 2019, 3:54:06 PM5/15/19
to pyControl
Hi Thom, 

They were NOT talking about the type of the encoder, rather they were asking about what type of data PyControl is getting from the hardware keeps track of the encoder

Filipe asked what type of data PyControl software is getting from the hardware - is it the difference between the latest position and the current one (a "differential") or an absolute counter of the numbers of the encoder? They said that if the dedicated hardware is accumulating the ticks in the hardware without any CPU intervention you will be reading the absolute position and we should not have drift. Is this the case?

Thank you, 


On Monday, February 18, 2019 at 6:09:12 PM UTC-5, Inês Vaz wrote:

Tanya Sippy

unread,
Sep 12, 2019, 1:25:16 PM9/12/19
to pyControl
HI Thom, 
I hope all is well. 
A couple of updates:

1) Good news first - I am now running a task using your _position_encoder_2_threshold.py script. Having a framework event generated each time the joystick passes the index has been helpful, and we are having much better results with the mice learning the task. Even though the drift is still an issue, when the mice are only required to do 1 action, they cross the index enough so that they get trials regularly. 
2) now the bad news: Ines and I finally ran your minimal encoder script and it looks like the drift is there even with this minimal script. I think this means that the problem is occurring in micropythons reading of the position, is that right? This continues to be a problem for us especially when we ask the mice to do two actions, as they do not as regularly cross the index when asked to do this.  

We are implementing a gear system as you suggested but we think that the reading of the position could somehow be optimized more - any additional advice here? 

Please let us know. 
Thank you so much, 
Tanya 


On Monday, February 18, 2019 at 6:09:12 PM UTC-5, Inês Vaz wrote:

Thomas Akam

unread,
Sep 13, 2019, 7:41:28 AM9/13/19
to pyControl
Hi Tanya,

My sense from the tests you have done is that you are not going to be able to completely get rid of drift issues if you use an incremental rotary encoder to measure small changes in absolute angular position.  These sensors are not really designed for this application and I think that a better approach would be to use a sensor specifically designed to measure absolute angular position rather than relative changes in position.

I think the easiest such sensor to integrate into your existing system would be an Hall effect position sensor.  These sensors measure absolute angular position by attaching a magnet to the object that will rotate and measuring the magnetic field at a fixed position nearby.  You can get versions of these sensors that output a voltage proportional to the rotation angle.  From a software perspective, this would be very easy to integrate into your existing task, because the pyControl rotary encoder class that you are currently using is a sub-class of the pycontrol Analog input which can  measure analog voltage signals and trigger events when they cross specified thresholds.  Therefore you would only have to minimally modify your existing task code, and would not need to implement any special interface for the sensor as it would just use a standard analog input.

Here are two example analog output hall effect angular position sensors:



It is likely that the above sensors have too much friction to work for your joystick application.  Instead you could get the type of sensor used in those modules, but without the enclosure, just the actual sensor itself:


To use this you would attach a small permanant magnet to the joystick and position the sensor close to the magnet, such that as the joystick moves the magnetic field at the sensor would change. This would be a bit more fidely to set up as you would have to optimise the relative positions of the magnet and sensor, but when set up properly it should give accurate absolute position sensing while adding essentially zero friction to the joystick.  I think this would probably give much better results than anything you will be able to achieve by optimsing the rotary encoder.

best,

Thomas




What would probably be a better approach would be to use a




This type of sensor is not really designed for this application, but rather for measuring the speed of continous rotat

Tanya Sippy

unread,
Sep 13, 2019, 2:39:54 PM9/13/19
to pyControl
Hello Thomas, 
Thank you for your suggestions which we will keep in mind as we trouble shoot. Filipe had suggested something similar when I saw him a few months back.  
We are in touch with a group here in NYC that is using an incremental encoder plugged into a National Instruments Card and read out in MATLAB at sample rates even lower than 1000kHz without any issues. I am going to visit that lab on Monday to see how their system works, but they assure me they do not have this issue. Therefore, I am reluctant to change the hardware at this stage. 
As a next test, What I might do is plug the encoder attached to our joystick to the same NI card they use and run their code to see if this solves the issue. I will then let you know the result and see if you have any further suggestions. 
Thanks so much and have a good weekend. 
Tanya 

On Monday, February 18, 2019 at 6:09:12 PM UTC-5, Inês Vaz wrote:

Tanya Sippy

unread,
Sep 13, 2019, 6:30:24 PM9/13/19
to pyControl
Hello Thomas, 
OK so some good news  - I tested the incremental encoder with an NI board and MATLAB code to read the position and there is NO DRIFT. :)))))) I think the problem must have been with micropython's readout of the encoder (too slow, maybe?). 
Now, I would like to know if there is a way I can use a digital or analog output from the NI board into the Pycontrol Board such that I can readout the position of the encoder. 
Would this be relatively easy to do? 
Thank you for your time and help. 
Tanya 

On Monday, February 18, 2019 at 6:09:12 PM UTC-5, Inês Vaz wrote:

Thomas Akam

unread,
Sep 18, 2019, 10:03:25 AM9/18/19
to pyControl
Hi Tanya,

If you can setup the NI board to output the joystick position as an analog voltage signal (between 0 and 3.3V) then you can read it in pyControl using the Analog Input class.  The analog input class works a lot like the rotary encoder class you have been using so should be easy to integrate into your task.  The standard Analog input only allows for a single threshold but there is a 2 threshold version defined in the _position_encoder_2_threshold.py device driver module (attached). This works just like the standard analog input but has two threshold that can be specified to generate framework events when crossed.  It takes the following syntax to instantiate:

Analog_input_2_threshold(pin, name, sampling_rate, data_type='H', threshold_A=None, rising_event_A=None, falling_event_A=None, threshold_B=None, rising_event_B=None, falling_event_B=None)

best,

Thomas


_position_encoder_2_threshold.py
Reply all
Reply to author
Forward
0 new messages