[Please Help] Why the outcomes are some weird characters??

I am new to HCTL2020 which is a 8pins encoder but with 16 bits value. Is there any code can read the value from HCTL-2020 by reading High8 Byte and Low8 Byte and show them on Arduino in dec?

Thanks a lotttttt!


8 Apr 2011

Thanks for robtillart's kindly help!

Unfortunately, the program still can't work.

I don't know why the outcomes are some unknown characters. Is there any method to give numerical result instead of some weird characters??

Welcome ,

Do you have a link to the datasheet? What do you want ot connect to this chip? purpose of your project? somae background is allways informative. Maybe you can do without?

robtillaart: Welcome ,

Do you have a link to the datasheet? What do you want ot connect to this chip? purpose of your project? somae background is allways informative. Maybe you can do without?

Robtillaart,thanks for your reply! :)

Here is the link where you can download HCTL2020 datasheet http://www.alldatasheet.com/view.jsp?Searchword=HCTL-2020

I am going to design a robot car, and using the Arduino to control it. The encoder HCTL2020 is used to record the distance travelled of the car. After that the data will be sent back to the Arduino serial monitor to show the distance in Dec.

However,the 8 pins encoder HCTL2020 will give a 16 bits value, I was suggested to write a program which read the High 8 Byte first, and then the Lower8 Byte, after that combine the value which gives a 16 bits.

For the breadboard, the Clock, HCTL2020 are used.

Since the example of HCTL2020 on the Internet is very less, so I would like to know if anyone can provide the code.

this one is an interesting read - http://www.arduino.cc/en/Tutorial/ShiftIn - sort of parallel to serial (check the 74HC595 too) use NewSoftSerial - http://arduiniana.org/libraries/newsoftserial/ - to clock the data in

but that said you can also use the Arduino's interrupt routines to directly read the A and B channel. When channel A rises you get an IRQ and in that IRQ you check if chan B is HIGH or LOW then you know if turns CW or CCW. Add a long counter and that's about it. - http://www.arduino.cc/en/Reference/AttachInterrupt -

pseudo code to get you started

volatile long counter = 0;

void IRQ()   // called when A rising
{
  if (digitalRead(chanB) == LOW) counter++;  // CW
  else counter--;  // CCW
}

in your main code 
#define COUNTSPERROTATION 100 // example value
loop()
{
...
  position = counter % COUNTSPERROTATION;
  rounds = counter / COUNTSPERROTATION;
...
}

Thanks robtillaart for the efficient reply =)

Actually the initial code had been designed,
but I would like to know how can I edit the below progarm,
so that the value shown is not “combined numbers” but is a “values”,
which allows me to convert the “values” into Dec??

int SELPin = 2; 
int OEPin = 3; 
long(StrCombine);

void setup() {

	int pin;

	pinMode (SELPin, OUTPUT); 
	pinMode (OEPin, OUTPUT); 
	for (pin=5; pin <= 12; pin++)
	{
	pinMode (pin, INPUT); 
 	}
	Serial.begin (9600);

	}

void loop() { 

	int i;
	int j;

	digitalWrite(SELPin, HIGH); // SEL = 1
	digitalWrite(OEPin, HIGH); // OE = 1

	digitalWrite(SELPin, LOW); // SEL = 0
	digitalWrite(OEPin, LOW); // OE = 0
	
	String StrCombine = “ ”; 
	for (i=5; i<= 12; i++)
	{
	StrCombine += digitalRead(i); 
	}

	digitalWrite(SELPin, HIGH); // SEL = 1
	digitalWrite(OEPin, LOW); // OE = 0

	for (j=5; j<= 12; j++)
	{
	StrCombine += digitalRead(j); 
	}

	
	Serial.println(StrCombine, DEC);

	}

This code should read the high byte

byte hiByte = 0;
for(byte i = 0; i < 8; i++){
  if(digitalRead(i+5)){
    hiByte |= 1 << i;
  }
}

The code to read the low byte will be the same. Then, to combine those into a 16bit value:

unsigned int EncoderVal16bit = (unsigned int(hiByte) << 8) + loByte;

Thanks jraskell so much for your kindly help =)

I have tried to edit my program as follow,
but it still can’t work… the serial monitor shows some unknown characters…
What can I do to improve??

int SELPin = 38; 
int OEPin  = 39; 

void setup() {

	int pin;

	pinMode (SELPin, OUTPUT); 
	pinMode (OEPin, OUTPUT); 	
	for (pin=30; pin <= 37; pin++)
	  {
	  pinMode (pin, INPUT); // 8-bit Data port
 	  }
	  Serial.begin (9600);

	}

void loop() 
{ 

	int i;
	int j;
        unsigned int EncoderVal16bit;
        
	digitalWrite(SELPin, HIGH); // SEL = 1
	digitalWrite(OEPin, HIGH); // OE = 1

	digitalWrite(SELPin, LOW); // SEL = 0
	digitalWrite(OEPin, LOW); // OE = 0
	
        byte hiByte = 0;
        for(byte k = 0; k < 8; k++)
        {
          if(digitalRead(k+5))
          {
          hiByte |= 1 << k;
          }
        }

	digitalWrite(SELPin, HIGH); // SEL = 1
	digitalWrite(OEPin, LOW); // OE = 0

        byte loByte = 0;
        for(byte k = 0; k < 8; k++)
        {
          if(digitalRead(k+5))
          {
          loByte |= 1 << k;
          }
        }

	EncoderVal16bit = ((hiByte) << 8) + loByte;
        
        Serial.println(EncoderVal16bit);
}

the serial monitor shows some unknown characters…
What can I do to improve??

Try changing the print statement:
Serial.print ("Encoder value: ");
Serial.println(EncoderVal16bit, DEC);
Or, HEX or BIN to see the value as a number in various formats.

Thanks for PaulS's reply :)

I have tried the code :

Serial.print ("Encoder value: "); Serial.println(EncoderVal16bit, DEC); Or, HEX or BIN to see the value as a number in various formats.

However, it still show the unknown characters on the screen... Is there anyone know how to show the correct result??

What do you get? What did you expect?

Hi robtillaart!

This is what the result I had so far

But I expected result should be something like this:

0 1 2 3 4 5 6 7 8 9 10

Made some changes with the datatypes

Try this and post what you get

Code:

int SELPin = 38; 
int OEPin  = 39; 

void setup() {

	int pin;

	pinMode (SELPin, OUTPUT); 
	pinMode (OEPin, OUTPUT); 	
	for (pin=30; pin <= 37; pin++)
	  {
	  pinMode (pin, INPUT); // 8-bit Data port
 	  }
	  Serial.begin (9600);

	}

void loop() 
{ 

	int i;
	int j;
        unsigned int EncoderVal16bit;
        
	digitalWrite(SELPin, HIGH); // SEL = 1
	digitalWrite(OEPin, HIGH); // OE = 1

	digitalWrite(SELPin, LOW); // SEL = 0
	digitalWrite(OEPin, LOW); // OE = 0
	
        Serial.println("HIGH: ");
        int hiByte = 0;
        for(byte k = 0; k < 8; k++)
        {
          int x = digitalRead(k+5);
          Serial.print(x, DEC);
          if(x)
          {
            hiByte |= (1 << k);
          }
        }
        Serial.println();

	digitalWrite(SELPin, HIGH); // SEL = 1
	digitalWrite(OEPin, LOW); // OE = 0

        Serial.println("LOW: ");
        int loByte = 0;
        for(byte k = 0; k < 8; k++)
        {
          int x = digitalRead(k+5);
          Serial.print(x, DEC);
          {
          loByte |= (1 << k);
          }
        }
        Serial.println();

	EncoderVal16bit = (((int)hiByte) << 8) + loByte;
        
        Serial.println(EncoderVal16bit);
}

this is the result...

Here is the code which can show the “combined value of the pins”

int SELPin = 38; 
int OEPin = 39; 
long StrCombine;
void setup() {

	int pin;

	pinMode (SELPin, OUTPUT); 
	pinMode (OEPin, OUTPUT); 
	
	for (pin=30; pin <= 37; pin++)
	{
	pinMode (pin, INPUT); // 8-bit Data port
 	}
	Serial.begin (9600);

	}

void loop() { 

	int i;
	int j;
        int s;
	digitalWrite(SELPin, HIGH); // SEL = 1
	digitalWrite(OEPin, HIGH); // OE = 1

	digitalWrite(SELPin, LOW); // SEL = 0
	digitalWrite(OEPin, LOW); // OE = 0
	
	String StrCombine ; 

	for (i=30; i<= 37; i++)
	{
	StrCombine += digitalRead(i); 
	}

	digitalWrite(SELPin, HIGH); // SEL = 1
	digitalWrite(OEPin, LOW); // OE = 0

	for (j=30; j<= 37; j++)
	{
	StrCombine += digitalRead(j); 
	}
    //   StrCombine=s;


	Serial.println(StrCombine);

	}

The result shown on the monitor…(Sorry that photobucket is under maintance now and I can’t upload it)
http://www.sendspace.com/file/rz4zbb

However, what I want is “a set of DEC single value” but not the “a set of combined value of the 8 pins”

Did you notice the difference between:

	for (i=30; i<= 37; i++)
	{
	StrCombine += digitalRead(i); 
	}

and

        int hiByte = 0;
        for(byte k = 0; k < 8; k++)
        {
          int x = digitalRead(k+5);
          if(x)
          {
            hiByte |= (1 << k);
          }
        }
        Serial.println();

digitalRead(k+5); ==> digitalRead(k+30); ???

Thanks robtillaart for your remind!!

int SELPin = 38;
int OEPin = 39;

void setup() {

int pin;

pinMode (SELPin, OUTPUT);
pinMode (OEPin, OUTPUT);
for (pin=30; pin <= 37; pin++)
{
pinMode (pin, INPUT); // 8-bit Data port
}
Serial.begin (9600);

}

void loop()
{

int i;
int j;
unsigned int EncoderVal16bit;

digitalWrite(SELPin, HIGH); // SEL = 1
digitalWrite(OEPin, HIGH); // OE = 1

digitalWrite(SELPin, LOW); // SEL = 0
digitalWrite(OEPin, LOW); // OE = 0

Serial.println("HIGH: ");
int hiByte = 0;
for(byte k = 0; k < 8; k++)
{
int x = digitalRead(k+30);
Serial.print(x, DEC);
if(x)
{
hiByte |= (1 << k);
}
}
Serial.println();

digitalWrite(SELPin, HIGH); // SEL = 1
digitalWrite(OEPin, LOW); // OE = 0

Serial.println("LOW: ");
int loByte = 0;
for(byte k = 0; k < 8; k++)
{
int x = digitalRead(k+30);
Serial.print(x, DEC);
{
loByte |= (1 << k);
}
}
Serial.println();

EncoderVal16bit = (((int)hiByte) << 8) + loByte;

Serial.println(EncoderVal16bit);
}

I change my code as above but the program still gives me lots of unknown characters…

I don't understand it, the bits seem to come in right the merging code looks fine, ????

please add at the end

  Serial.println(loByte , HEX);
  Serial.println(hiByte , HEX);
  EncoderVal16bit = word(hiByte, loByte);
  Serial.println(EncoderVal16bit, HEX);
}

Thanks for robtillart's kindly help!

Unfortunately, the program still can't work.

I don't know why the outcomes are some unknown characters. Is there any method to give numerical result instead of some weird characters??

Test that you can print ANYTHING correctly to the serial monitor. In the setup() function, send some known data to the serial monitor:

Serial.println("ABCDEFGH");
Serial.println("rstuvwxyz");
Serial.print("123 ==>");
int num = 123;
Serial.println(num, DEC);

However, what I want is "a set of DEC single value" but not the "a set of combined value of the 8 pins"

I don't understand this statement. Can you explain?

Thanks PaulS for your kindly reply :smiley:

I have tried your code to test of the arduino is okay or not. And it gave correct results.
However, when I tried my program:

int SELPin = 38; 
int OEPin  = 39; 

void setup() {

   int pin;

   pinMode (SELPin, OUTPUT); 
   pinMode (OEPin, OUTPUT);    
   for (pin=30; pin <= 37; pin++)
     {
     pinMode (pin, INPUT); // 8-bit Data port
      }
     Serial.begin (9600);

   }

void loop() 
{ 

   int i;
   int j;
        unsigned int EncoderVal16bit;
        
   digitalWrite(SELPin, HIGH); // SEL = 1
   digitalWrite(OEPin, HIGH); // OE = 1

   digitalWrite(SELPin, LOW); // SEL = 0
   digitalWrite(OEPin, LOW); // OE = 0
   
        Serial.println("HIGH: ");
        int hiByte = 0;
        for(byte k = 0; k < 8; k++)
        {
          int x = digitalRead(k+30);
          Serial.print(x, DEC);
          if(x)
          {
            hiByte |= (1 << k);
          }
        }
        Serial.println();

   digitalWrite(SELPin, HIGH); // SEL = 1
   digitalWrite(OEPin, LOW); // OE = 0

        Serial.println("LOW: ");
        int loByte = 0;
        for(byte k = 0; k < 8; k++)
        {
          int x = digitalRead(k+30);
          Serial.print(x, DEC);
          {
          loByte |= (1 << k);
          }
        }
        Serial.println();

   EncoderVal16bit = (((int)hiByte) <<  + loByte;
        
        Serial.println(EncoderVal16bit);
}

The outcomes are some unknown characters again.

“a set of DEC single value” but not the “a set of combined value of the 8 pins”

It means that I can now show the signals of the 8 pins (High/Low) respectively.
It can’t convert the value to DEC because it’s the combine value…
e.g. “0+0+0+0+0+0+0+1” ----> “00000001”
But I would like to general a value which is EXACTLY the value of the 8 pins (added together already)
so that it can allow me to convert the value from BIN to DEC.
e.g. “00000001” ------> 1

Is there any codes allow me to add the 8 pins together and gives a DEC value correctly?