Author Topic: Using the Quadrature Encoder (QDEC)  (Read 3427 times)

waynek

  • RFduino Newbie
  • *
  • Posts: 8
  • Karma: +0/-0
    • View Profile
    • Cannybots
Using the Quadrature Encoder (QDEC)
« on: January 07, 2015, 01:14:15 AM »
Hi,

I'd like to use the quadrature encoder of the underlying NRF51822. 
I see from the ref manual (v3.0 page 158) that the pins used are configurable and that the RFduiono source has a default interrupt vector pointing to a empty handler.

Has anyone already tried todo this on the RFduino?
Has anyone got any pointers, examples or advice please?

All the best
Wayne

olekristensen

  • RFduino Newbie
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Re: Using the Quadrature Encoder (QDEC)
« Reply #1 on: April 24, 2015, 05:51:28 AM »
+1

olekristensen

  • RFduino Newbie
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Re: Using the Quadrature Encoder (QDEC)
« Reply #2 on: April 28, 2015, 06:56:30 AM »
Hi Wayne

I'm looking into it now, downloaded the nordic sdk. From what I can see we do not have access to the driver layer of the nrf SDK, but it should be possible using the defines provided in the nrf Hardware abstraction layer. However, it is a bit longwinded to implement without the driver layer, and requires quite a bit of reading.

I'm not sure about the version used by rfduino yet, but here's the most recent HAL documentation
https://developer.nordicsemi.com/nRF51_SDK/nRF51_SDK_v8.x.x/doc/8.0.0/s110/html/a00762.html#ga61d9d6fb2bfdb1a4d9f539e2fc0c84f4

Did you get further with it since january?

best / ole

tolson

  • Global Moderator
  • *****
  • Posts: 854
  • Karma: +20/-0
    • View Profile
    • Thomas Olson Consulting
Re: Using the Quadrature Encoder (QDEC)
« Reply #3 on: April 29, 2015, 01:00:43 AM »
Hi,

I'd like to use the quadrature encoder of the underlying NRF51822. 
I see from the ref manual (v3.0 page 158) that the pins used are configurable and that the RFduiono source has a default interrupt vector pointing to a empty handler.

Has anyone already tried todo this on the RFduino?
Has anyone got any pointers, examples or advice please?

All the best
Wayne

Can you try this code? Let me know how it works. I don't have a quadrature pot right now. Just used another RFduino to emulate quadrature data. If anything, perhaps it will get you started. You may have to play with the sampling rates.

Don't need no interrupts. The quadrature counter count up and down automatically. Just need to read the ACC register when you want to know what the position is. The ACC range is -1024 to +1024.

Code: [Select]
// quadrature detector test
// Thomas Olson
// teo20150310.01
// Not interested in interrupts in this example.
// Just need to read the position value from ACC (-1024 to +1024).

int phaseApin = 2;
int phaseBpin = 3;

void setup() {
  delay(1500); // give me time to start serial monitor
  Serial.begin(9600);
  Serial.println("quadrature detector test");


  // setup Quadrature Pins
  NRF_QDEC->PSELA = phaseApin;
  NRF_QDEC->PSELB = phaseBpin;

// LED drive not used PSELLED default is off.
  NRF_QDEC->PSELLED = 0xFFFFFFFF; // Make sure it is OFF
// LEDPRE is don't care if not using LED.
// LEDPOL don't care about LED Polarity.
// DBFEN default debounce disabled.
  NRF_QDEC->DBFEN = 0; // 0=disabled, 1=enabled
// The SAMPLEPER default is 128 us.
  NRF_QDEC->SAMPLEPER = 3; // 0=128us, 3=1024us
  NRF_QDEC->REPORTPER = 4; //Not sure I need this if not using interrupts
// Clear the accumulators with READCLRACC .. init I don't care
  NRF_QDEC->TASKS_READCLRACC = 1;
  NRF_QDEC->ACCREAD;
  NRF_QDEC->ACCDBLREAD;
 
// Turn on QDEC - ENABLE bit 1 - 0=DISABLE, 1=ENABLE
  NRF_QDEC->ENABLE = 1;
 
// Start the QDEC
  NRF_QDEC->TASKS_START = 1;

}


void loop() {
 
  delay(1000);
  Serial.print("ACC: ");
  Serial.println(NRF_QDEC->ACC);
 
  Serial.print("ACCREAD: ");
  Serial.println(NRF_QDEC->ACCREAD);
 
  Serial.print("ACCDBL: ");
  Serial.println(NRF_QDEC->ACCDBL);
 
  Serial.print("ACCDBLREAD: ");
  Serial.println(NRF_QDEC->ACCDBLREAD);
 
  Serial.print("SAMPLE: ");
  Serial.println(NRF_QDEC->SAMPLE);
 
  Serial.print("ACCOF: ");
  Serial.println(NRF_QDEC->EVENTS_ACCOF,HEX);
 
  Serial.println("");
 
}

olekristensen

  • RFduino Newbie
  • *
  • Posts: 4
  • Karma: +0/-0
    • View Profile
Re: Using the Quadrature Encoder (QDEC)
« Reply #4 on: May 19, 2015, 02:32:17 AM »
Hi again,

Thanks tolson! Much simpler than the HAL examples from Nordic - i was getting lost in their scroll wheel demo when you posted this...

And, yes - it works, however there are some omissions, like setting up the pins to INPUT_PULLUP, clearing the ACCREAD buffer and updating an integer. I've added this to a working example below where i've used the ALPHA 318-ENC130175F-12PS Rotary encoder sold as COM-09117 by Sparkfun.

Code: [Select]
// quadrature detector test
// Thomas Olson
// teo20150310.01
// Not interested in interrupts in this example.
// Just need to read the position value from ACC (-1024 to +1024).
// Ole Kristensen added pinModes, TASKS_READCLRACC, and updating a pos integer.

int phaseApin = 3;
int phaseBpin = 4;

int pos = 0;

void setup() {
  delay(1500); // give me time to start serial monitor
  Serial.begin(9600);
  Serial.println("quadrature detector test");

  // setup Quadrature Pins
  pinMode(phaseApin, INPUT_PULLUP);
  pinMode(phaseBpin, INPUT_PULLUP);
  NRF_QDEC->PSELA = phaseApin;
  NRF_QDEC->PSELB = phaseBpin;

  // LED drive not used PSELLED default is off.
  NRF_QDEC->PSELLED = 0xFFFFFFFF; // Make sure it is OFF
  // LEDPRE is don't care if not using LED.
  // LEDPOL don't care about LED Polarity.
  // DBFEN default debounce disabled.
  NRF_QDEC->DBFEN = 0; // 0=disabled, 1=enabled
  // The SAMPLEPER default is 128 us.
  NRF_QDEC->SAMPLEPER = 3; // 0=128us, 3=1024us
  NRF_QDEC->REPORTPER = 4; //Not sure I need this if not using interrupts
  // Clear the accumulators with READCLRACC .. init I don't care
  NRF_QDEC->TASKS_READCLRACC = 1;
  NRF_QDEC->ACCREAD;
  NRF_QDEC->ACCDBLREAD;

  // Turn on QDEC - ENABLE bit 1 - 0=DISABLE, 1=ENABLE
  NRF_QDEC->ENABLE = 1;

  // Start the QDEC
  NRF_QDEC->TASKS_START = 1;

}

void loop() {

  delay(1000);

  NRF_QDEC->TASKS_READCLRACC = 1;  // the QDEC is double buffered, we tell it to swap here.
                                   // this allows it to update the encoder in a clear ACC 'in the background'
  int accread = NRF_QDEC->ACCREAD; // while we muddle around with the values from ACCREAD
  pos += accread;                  // ie. by upating our position variable.

  Serial.print("POS: ");
  Serial.println(pos);

  Serial.print("ACC: ");
  Serial.println(NRF_QDEC->ACC);

  Serial.print("ACCREAD: ");
  Serial.println(accread);

  Serial.print("ACCDBL: ");
  Serial.println(NRF_QDEC->ACCDBL);

  Serial.print("ACCDBLREAD: ");
  Serial.println(NRF_QDEC->ACCDBLREAD);

  Serial.print("SAMPLE: ");
  Serial.println(NRF_QDEC->SAMPLE);

  Serial.print("ACCOF: ");
  Serial.println(NRF_QDEC->EVENTS_ACCOF, HEX);

  Serial.println("");

}

nicoschtein

  • RFduino Newbie
  • *
  • Posts: 1
  • Karma: +0/-0
    • View Profile
Re: Using the Quadrature Encoder (QDEC)
« Reply #5 on: March 27, 2017, 11:33:25 AM »
Sorry to revive this old topic... Has anyone used more than one QDEC on a Simblee or nRF51822 ?
I have one working but need to add more..

tolson

  • Global Moderator
  • *****
  • Posts: 854
  • Karma: +20/-0
    • View Profile
    • Thomas Olson Consulting
Re: Using the Quadrature Encoder (QDEC)
« Reply #6 on: March 27, 2017, 02:33:37 PM »
Sorry to revive this old topic... Has anyone used more than one QDEC on a Simblee or nRF51822 ?
I have one working but need to add more..

There can be only one.
Unless you use external decoders.

 

anything