"can anyone help me " Avago HCTL-2022 with arduino mega 2560

Iam trying to interface linear encoder( 1 micron resolution and 1mm = 250 pulses ) with HCTL 2022 with Arduino Mega 2560 but Iam stuck on the programming part and connecting the external clock with the HCTL 2022. Can someone please help me out in this one.

Please post your entire sketch, in code tags.


Arduino Pin HCTL-2022 function
------------------------------------
DIG 9 /RST (active low)
DIG 11 SEL1
DIG 12 SEL2
DIG 13 /OE (active low)
DIG 22->29 Data pins D0->D7
+5V VDD
GND VSS
from encoder CHA
from encoder CHB
not connected INDEX
not connected U/D
not connected TEST 
External clock CLK
*/

// Global variable declaration
volatile long countData = 0; // 32-bit int (signed?) the count represents absolute position

void setup() {
Serial.begin(9600);

pinMode(9, OUTPUT);
//digitalWrite(9, LOW); // /RST resets the internal counter between runs
// delay(10);
digitalWrite(9, HIGH); // Stay high for rest of the run
// Set all pins in PORTA (digital pins 22->29 on the Mega) as input pins
for(int i = 22; i<30; i++) {
pinMode(i, INPUT);
}
// Set pins 5,6,7 in PORT B (digital pins 11,12,13 on the Mega) as output pins
for(int j = 11; j<14; j++) {
pinMode(j, OUTPUT);
digitalWrite(j, LOW);

}

}
/*-------------------------------------------------
-------------------Functions---------------------
-------------------------------------------------*/
byte getMSB(){
/*Get stable data for the most significant byte of countData*/

byte MSBold = PINA; // read datapins D0->D7 and store in MSBold
byte MSBnew = PINA; // read again immediatly after to assure stable data
if (MSBnew == MSBold){ 
byte MSBresult = MSBnew;
return MSBresult; 
}
else getMSB();
}

byte getSecond(){
/*Get stable data for the 2nd byte of countData*/
byte secondOld = PINA; // read datapins D0->D7 and store in secondOld
byte secondNew = PINA; // read again immediatly after to assure stable data
if (secondNew == secondOld){ 
byte secondResult = secondNew;
return secondResult; 
}
else getSecond();
}

byte getThird(){
/*Get stable data for the 3rd byte of countData*/
byte thirdOld = PINA; // read datapins D0->D7 and store in thirdOld
byte thirdNew = PINA; // read again immediatly after to assure stable data
if (thirdNew == thirdOld){ 
byte thirdResult = thirdNew;
return thirdResult; 
}
else getThird();
}

byte getLSB(){
/*Get stable data for the least significant byte of countData*/
byte LSBold = PINA; // read datapins D0->D7 and store in LSBold
byte LSBnew = PINA; // read again immediatly after to assure stable data
if (LSBnew == LSBold){ 
byte LSBresult = LSBnew;
return LSBresult; 
}
else getLSB();
}

long mergeFunc(byte MSBresult, byte secondResult, byte thirdResult, byte LSBresult){
/*Merges the 4 bytes returning one 32-bit variable called countData*/
long tempVar = 0;
tempVar |= ((long) MSBresult << 24) | ((long) secondResult << 16) | ((long) thirdResult << 8) | ((long) LSBresult << 0);
countData = tempVar;
return countData;
}

void loop() {

digitalWrite(13, HIGH); // Set OE to HIGH (disable)
delay(25); // need a better way

digitalWrite(11, LOW);
digitalWrite(12, HIGH); // SEL1 = 0 and SEL2 = 1

digitalWrite(13, LOW); // Set OE to LOW (enable)
byte MSBresult = getMSB();

digitalWrite(11, HIGH);
digitalWrite(12, HIGH); // SEL1 = 1 and SEL2 = 1
byte secondResult = getSecond();

digitalWrite(11, LOW);
digitalWrite(12, LOW); // SEL1 = 0 and SEL2 = 0
byte thirdResult = getThird();

digitalWrite(11, HIGH);
digitalWrite(12, LOW); // SEL1 = 1 and SEL2 = 0
byte LSBresult = getLSB();

digitalWrite(13, HIGH); // Set OE to HIGH (disable)
delay(25);

countData = mergeFunc(MSBresult, secondResult, thirdResult, LSBresult);
Serial.println("Counter: ");
Serial.println(countData);
Serial.println("\n");

}
  byte MSBold = PINA;       // read datapins D0->D7 and store in MSBold
  byte MSBnew = PINA;       // read again immediatly after to assure stable data

This is pointless. Nanoseconds later, the offs of PINA having a different value are vanishingly small.

Ok. I just removed the extra line but still the counter value is 0


Arduino Pin HCTL-2022 function
------------------------------------
DIG 9 /RST (active low)
DIG 11 SEL1
DIG 12 SEL2
DIG 13 /OE (active low)
DIG 22->29 Data pins D0->D7
+5V VDD
GND VSS
from encoder CHA
from encoder CHB
not connected INDEX
not connected U/D
not connected TEST 
External clock CLK
*/

// Global variable declaration
volatile long countData = 0; // 32-bit int (signed?) the count represents absolute position
const int freqOutputPin = 7;
const int prescale = 1;
const int ocr2aval = 3; 
const float period = 5.0 * prescale * (ocr2aval+1) / (F_CPU/1.0e6);
const float freq = 1.0e6 / period;
void setup() {
pinMode(freqOutputPin, OUTPUT);
Serial.begin(9600);
TCCR2A = ((1 << WGM21) | (1 << COM2A0));
TCCR2B = (1 << CS20);
TIMSK2 = 0;
OCR2A = ocr2aval;

pinMode(9, OUTPUT);
//digitalWrite(9, LOW); // /RST resets the internal counter between runs
// delay(10);
digitalWrite(9, HIGH); // Stay high for rest of the run

// Set all pins in PORTA (digital pins 22->29 on the Mega) as input pins
for(int i = 22; i<30; i++) {
pinMode(i, INPUT);
}
// Set pins 5,6,7 in PORT B (digital pins 11,12,13 on the Mega) as output pins
for(int j = 11; j<14; j++) {
pinMode(j, OUTPUT);
digitalWrite(j, LOW);

}

}
/*-------------------------------------------------
-------------------Functions---------------------
-------------------------------------------------*/
byte getMSB(){
/*Get stable data for the most significant byte of countData*/

//byte MSBold = PINA; // read datapins D0->D7 and store in MSBold
byte MSBnew = PINA; // read again immediatly after to assure stable data
// if (MSBnew == MSBold){ 
byte MSBresult = MSBnew;
return MSBresult; 
//}
// else getMSB();
}

byte getSecond(){
/*Get stable data for the 2nd byte of countData*/
//byte secondOld = PINA; // read datapins D0->D7 and store in secondOld
byte secondNew = PINA; // read again immediatly after to assure stable data
//if (secondNew == secondOld){ 
byte secondResult = secondNew;
return secondResult; 
//}
//else getSecond();
}

byte getThird(){
/*Get stable data for the 3rd byte of countData*/
//byte thirdOld = PINA; // read datapins D0->D7 and store in thirdOld
byte thirdNew = PINA; // read again immediatly after to assure stable data
// if (thirdNew == thirdOld){ 
byte thirdResult = thirdNew;
return thirdResult; 
// }
// else getThird();
}

byte getLSB(){
/*Get stable data for the least significant byte of countData*/
// byte LSBold = PINA; // read datapins D0->D7 and store in LSBold
byte LSBnew = PINA; // read again immediatly after to assure stable data
// if (LSBnew == LSBold){ 
byte LSBresult = LSBnew;
return LSBresult; 
// }
// else getLSB();
}

long mergeFunc(byte MSBresult, byte secondResult, byte thirdResult, byte LSBresult){
/*Merges the 4 bytes returning one 32-bit variable called countData*/
long tempVar = 0;
tempVar |= ((long) MSBresult << 24) | ((long) secondResult << 16) | ((long) thirdResult << 8) | ((long) LSBresult << 0);
countData = tempVar;
return countData;
}



void loop() {

digitalWrite(13, HIGH); // Set OE to HIGH (disable)
delay(25); // need a better way

digitalWrite(11, LOW);
digitalWrite(12, HIGH); // SEL1 = 0 and SEL2 = 1

digitalWrite(13, LOW); // Set OE to LOW (enable)
byte MSBresult = getMSB();


digitalWrite(11, HIGH);
digitalWrite(12, HIGH); // SEL1 = 1 and SEL2 = 1
byte secondResult = getSecond();

digitalWrite(11, LOW);
digitalWrite(12, LOW); // SEL1 = 0 and SEL2 = 0
byte thirdResult = getThird();

digitalWrite(11, HIGH);
digitalWrite(12, LOW); // SEL1 = 1 and SEL2 = 0
byte LSBresult = getLSB();

digitalWrite(13, HIGH); // Set OE to HIGH (disable)
delay(25);

countData = mergeFunc(MSBresult, secondResult, thirdResult, LSBresult);
Serial.println("Counter: ");
Serial.println(countData);
Serial.println("\n");


}

tempVar |= ((long) MSBresult << 24) | ((long) secondResult << 16) | ((long) thirdResult << 8) | ((long) LSBresult << 0);

Well, there’s your problem. What does left shifting by 8) mean?

sorry that was typing mistake maybe i dont know how it came

tempVar |= ((long) MSBresult << 24) | ((long) secondResult << 16) | ((long) thirdResult << 8) | ((long) LSBresult << 0);

i dont know why that emoji is coming actually its ‘8’ am no able to see that until i post the code

tempVar |= ((long) MSBresult << 24) | ((long) secondResult << 16) | ((long) thirdResult << 8 ) | ((long) LSBresult << 0);

Hi, [u]PLEASE!!![/u]

Please read the first post in any forum entitled how to use this forum. http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code. It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom..

Hello,

reviving a dead post but was wondering if OP ended up figuring out a coding solution for their problem?

beefung: Hello,

reviving a dead post but was wondering if OP ended up figuring out a coding solution for their problem?

It is pointless to revive a dead post without posting YOUR code and describing YOUR problem.

Hello PaulS,

sorry for not including my code and problem. I have similar problem to the OP in that I am having problems reading information for from HCTL-2022. I have the following pin configuration with my Arduino Mega currently,

D0-D7 → Arduino
SEL1 → Arduino
SEL2 → Arduino
~RST → Arduino
~OE → Arduino
~U/D → Arduino

CLK → external 20 MHz clock (ECS-100 series, powered by arduino 5V)
TEST → GND
VSS → GND
INDEX → GND

CHA → Slot Detector Sensor (GP1A52HRJ00F)
CHB → 2nd Slot Detector Sensor (GP1A52HRJ00F, powered by Arduino 5V)

And here is my code

//-------PIN LABELS--------//

// QuadDec Pins
int sel1   = 22;
int sel2   = 24;
int RST_L  = 26;
int OE_L   = 28;
int U_D_L  = 30;

int dataPin[] = {12, 11, 10, 9, 8, 7, 6, 5};

void setup()
{
  Serial.begin(9600);
  
  // QuadDec Pin Setup
  pinMode(U_D_L, OUTPUT);       // U/~D
  digitalWrite(U_D_L, HIGH);    // count-up mode
  
  pinMode(OE_L, OUTPUT);        // ~OE
  digitalWrite(OE_L, HIGH);     // initially, you don't want to read anything
  
  pinMode(RST_L, OUTPUT);       // ~RST
  digitalWrite(RST_L, LOW);
  delayMicroseconds(5);
  digitalWrite(RST_L, HIGH);    // reset internal counter sequence

  Serial.println("Test Begin");
  pinMode(sel2, OUTPUT);        // SEL2
  pinMode(sel1, OUTPUT);        // SEL1

  pinMode(dataPin[0], INPUT);
  pinMode(dataPin[1], INPUT);
  pinMode(dataPin[2], INPUT);
  pinMode(dataPin[3], INPUT);
  pinMode(dataPin[4], INPUT);
  pinMode(dataPin[5], INPUT);
  pinMode(dataPin[6], INPUT);
  pinMode(dataPin[7], INPUT);
  
}

void loop()
{
  long counterVal = 0;
  
  counterVal = readQuadDec();
  delay(2000);
}

//----- FUNCTIONS ------//

//-- reads the current counter data from quad dec
long readQuadDec()
{
  long counter = 0;
  byte data[4];
  int i;

  digitalWrite(OE_L, LOW);               // enable inhibit logic (do this only once per read)
  delayMicroseconds(5);

  // get MSB
  digitalWrite(sel1, LOW);               // select MSB
  digitalWrite(sel2, HIGH);
  delayMicroseconds(5);
  data[3] = readByte();
  // get byte2
  digitalWrite(sel1, HIGH);              // select byte2
  digitalWrite(sel2, HIGH);
  delayMicroseconds(5);
  data[2] = readByte();
  // get byte3
  digitalWrite(sel1, LOW);               // select byte2
  digitalWrite(sel2, LOW);
  delayMicroseconds(5);
  data[1] = readByte();// get byte2
  // get byteLSB
  digitalWrite(sel1, HIGH);              // select byte2
  digitalWrite(sel2, LOW);
  delayMicroseconds(5);
  data[0] = readByte();

  digitalWrite(OE_L, HIGH);                 // disable inhibit logic

  // concentanate the bits to one long 32 bit data
  for (i = 3; i >= 0; i--) {
    counter += long(data[i]) << 8 * i;
  }

  // Debug print statements
  Serial.println(data[3], HEX);
  Serial.println(data[2], HEX);
  Serial.println(data[1], HEX);
  Serial.println(data[0], HEX);

  Serial.println(counter, HEX);
  return (counter);
}

byte readByte(void)
{
  byte old_value = 0;
  byte new_value = 0;
  byte result    = 0;
  int i;

  for (i = 0; i < 8; i++)
  {
    old_value |= digitalRead(dataPin[i]) << i;
  }
/*
  for (i = 0; i < 8; i++)
  {
    new_value |= digitalRead(dataPin[i]) << i;
  }

  if (new_value == old_value)
    result = new_value;
  else
  {
    result = 0;
    Serial.println("Unstable Byte");
  }   
  
  return(result);
  */
  return(old_value);
}

I am currently monitoring the counter readings using the Serial Monitor feature; however, even when nothing is being passed through the slot detector, the values being printed to the monitor are varying and unstable. I was wondering if anyone could help me spot my mistake.

Okay so I think I fixed one issue, I forgot to connect the grounds on both sides of my breadboard. I updated my code to include PORTA for the Arduino MEGA as a way to skip the reading byte function part of reading from the QuadDecoder; however,

I now have a new problem where after rotating my encoder disc a few times through the slot detector, it will jump from progressing through a positive number to a negative number or sometimes the data would reset to 0.

//-------PIN LABELS--------//

// QuadDec Pins
int sel1   = 34;
int sel2   = 35;
int RST_L  = 37;
int OE_L   = 32;
int U_D_L  = 33;

int dataPin[] = {22, 23, 24, 25, 26, 27, 28, 29};


//---Global Vals---//
long counterVal = 0;
void setup()
{
  Serial.begin(9600);
  
  // QuadDec Pin Setup
  pinMode(U_D_L, OUTPUT);       // U/~D
  digitalWrite(U_D_L, HIGH);    // count-up mode
  
  pinMode(OE_L, OUTPUT);        // ~OE
  digitalWrite(OE_L, HIGH);     // initially, you don't want to read anything
  
  pinMode(RST_L, OUTPUT);       // ~RST
  digitalWrite(RST_L, LOW);
  delayMicroseconds(50);
  digitalWrite(RST_L, HIGH);    // reset internal counter sequence

  Serial.println("Test Begin");
  pinMode(sel2, OUTPUT);        // SEL2
  pinMode(sel1, OUTPUT);        // SEL1

  pinMode(dataPin[0], INPUT);
  pinMode(dataPin[1], INPUT);
  pinMode(dataPin[2], INPUT);
  pinMode(dataPin[3], INPUT);
  pinMode(dataPin[4], INPUT);
  pinMode(dataPin[5], INPUT);
  pinMode(dataPin[6], INPUT);
  pinMode(dataPin[7], INPUT);  
}

void loop()
{
  counterVal = readQuadDec();
  Serial.println(counterVal);
  delay(2000);
}

//----- FUNCTIONS ------//

//-- reads the current counter data from quad dec
long readQuadDec()
{
  long counter = 0;
  byte data[4];
  int i;

  digitalWrite(OE_L, LOW);               // enable inhibit logic (do this only once per read)
  delayMicroseconds(5);

  // get MSB
  digitalWrite(sel1, LOW);               // select MSB
  digitalWrite(sel2, HIGH);
  delayMicroseconds(5);
  data[3] = PINA;
  // get byte2
  digitalWrite(sel1, HIGH);              // select byte2
  digitalWrite(sel2, HIGH);
  delayMicroseconds(5);
  data[2] = PINA;
  // get byte3
  digitalWrite(sel1, LOW);               // select byte2
  digitalWrite(sel2, LOW);
  delayMicroseconds(5);
  data[1] = PINA;// get byte2
  // get byteLSB
  digitalWrite(sel1, HIGH);              // select byte2
  digitalWrite(sel2, LOW);
  delayMicroseconds(5);
  data[0] = PINA;

  digitalWrite(OE_L, HIGH);                 // disable inhibit logic

  // concentanate the bits to one long 32 bit data
  for (i = 3; i >= 0; i--) {
    counter += long(data[i]) << 8 * i;
  }

  // Debug print statements
  
  Serial.print(data[3], HEX);
  Serial.print("\t");
  Serial.print(data[2], HEX);
  Serial.print("\t");
  Serial.print(data[1], HEX);
  Serial.print("\t");
  Serial.println(data[0], HEX);

  Serial.println(counter, HEX);
  
  return (counter);
}
long counterVal = 0;

Do you plan to count a negative number of things? Counters should usually be unsigned types.

    counter += long(data[i]) << 8 * i;

The cast should be to an unsigned type, like the original value is.

Hello PaulS,

My encoder disc may spin in either direction so negative numbers might be useful for tracking direction. I did give the unsigned long a try and changed the shifting bit of my code to

  // concentanate the bits to one long 32 bit data
  for (i = 3; i >= 0; i--) {
    counter += (unsigned long)data[i] << 8 * i;
  }

however, while spinning my encoder disc in one direction it will start off fine but then jump from a low number to almost max number for example

17 → FFFFFFD8

Now, it is time to look up “operator precedence”, and see the relative positions of + and <<.

Hey PaulS,

thanks for the tips, I looked up operator precedence and I believe my bitshift line should be working the way I am intending. I did fix one thing that seems to help with stabilizing my outputs. I didn’t realize that the U/D pin on the HCTL-2022 was an output and not an INPUT. I’ve been sending from the microcontroller a LOW value to the Quad-Decoder. It seems to be working now.

I believe the issues with consistent output are due to signal stability now. Is there a simple way to stabilize the outputs from the QuadDec with hardware components or perhaps someway in code?

beefung Hello friend, did you solve the problem when reading the HCTL decoder data? since I'm in a similar problem I hope you can help me