Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Pages: [1]   Go Down
Author Topic: Encoding from Binary Bits to Decimal / Hex  (Read 725 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi There,
I have data read (via DigitalRead) from 17, 9 PhotoTransistors which are used to calculate a coordinate position. At the moment I directly send the streams (Such as "01111110110000011", "111111000") as a stream of characters via Serial.Print(). however, since I wish to speed up the process, for better performance, I'm thinking on whether to encode the bitstream as a Decimal or Hexacimal number, and send that number as a set of several characters.

In this case, the 9 bit sensor value will vary from 0-512 in decimal and the 17 bit sensor value will vary from 0-131072. However, i cant seem to find a function to convert this. 
In the foll wing reference,
http://arduino.cc/en/Serial/Print

I note that Serial.print(78, BIN) gives "1001110" but what I really need is a function to do the opposite.

Although I do not know whether performing such a conversion in the arduino will itself slow down the process, my intention is to ensure output at a higher data speed via COM.

Thanks in advance,
LasithG
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 654
Posts: 35023
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I note that Serial.print(78, BIN) gives "1001110" but what I really need is a function to do the opposite.
Anything stored in a variable is already in binary, there is no need to convert it. You do the conversion when you do the print in any other number base.
So gather your bits into a variable and print it out in any form you want.
Logged

Sydney, Australia
Online Online
Edison Member
*
Karma: 33
Posts: 1288
Big things come in large packages
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If your intention is to minimise the use of your serial bandwidth, then the best way to send it is as a series of bytes whose bits are on or off as per the pattern.

You have 17+9 bits to send. If these are packet into 8 bit bytes, then you will have to send 26/8=3.25 or 4 bytes. If you are sending the string "010..." as per your example you will be sending 26 bytes.

Computers do not need to 'read' the data like we do, so converting to ASCII characters is very wasteful. What you are actually sending down the line is a byte representing the characters '0' (0x30) and the byte for '1' (0x31), which differ only by one bit, so you are wasting the information contained in the other 7 bits.
Logged

Arduino libraries http://arduinocode.codeplex.com
Parola hardware & library http://parola.codeplex.com

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you Marco_C and Grumpy_Mike for your suggestions.

Right now, This is how I code it,
..
delay(ReadDelay);
   SensorValue = digitalRead(SensorA); // read the arduino input pin
   Serial.print(SensorValue); //use the result
delay(OutDelay);

for all 26 Sensors.

But I'm thinking of adding them into a linear array (Char or Int) in this case marked ShortSide[ ]

   ShortSide[8] = digitalRead(ChipB); // read the arduino input
...
...
   ShortSide[7] = digitalRead(ChipC); // read the arduino input
...

And finally use Serial.Print(Shortside); to output the stream.

As suggested by Marco_C, what I want to do is to ..but I'm not sure which coding constructs / data types to use.
   

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 671
Posts: 51669
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But I'm thinking of adding them into a linear array (Char or Int) in this case marked ShortSide[ ]
Sending one value at a time, or sending an array of values, makes no difference on the amount of data being sent.

If you pack the data into a 4 byte array, using bitWrite(), and send just those 4 bytes, there WILL be a considerable reduction in the amount of data being sent.

Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 654
Posts: 35023
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
for all 26 Sensors.
So you can fit it all into a long int
Code:
long int results;

// then gather the data into the variable
  results = 0;
for(int i =0; i< 26; i++){
results |= (digitalRead(pin[i]) & 0x01) << i;
}
where pin[] is an array defining what pins to use.

The all your results are in a single variable.

Then you can output it as a hex number:-
Code:
Serial.print(results, HEX);
it will contain up to 6 characters.
If you want it to be in only 4 characters, use:-
Code:
Serial.write(char(results & 0xff) );
Serial.write(char( (results>>8) & 0xff) );
Serial.write(char( (results>>16) & 0xff) );
Serial.write(char( (results>>24) & 0xff) );
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you Grumpy Mike!. I think it looks like what I need...just a few queries on the code : I did some referencing on the bit shift operator etc...but just to be sure..

Code:
results |= (digitalRead(pin[i]) & 0x01) << i;

In this statement, why do you use an AND operator with the pin result and HEX 1 ?

Also in
Code:
Serial.write(char(results & 0xff) );

you perform a AND operation with Hex FF..

I'm a bit unclear on the reason behind it...

Many Thanks Once again!
Logged

UK
Offline Offline
Faraday Member
**
Karma: 100
Posts: 4153
Where is your SSCCE?!?!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you Grumpy Mike!. I think it looks like what I need...just a few queries on the code : I did some referencing on the bit shift operator etc...but just to be sure..

Code:
results |= (digitalRead(pin[i]) & 0x01) << i;

In this statement, why do you use an AND operator with the pin result and HEX 1 ?

Belt and braces.  We want either 0x00 or 0x01 for shifting in.  digitalRead should only ever return 0 or 1, but just in case we force it in to the right value range.


Also in
Code:
Serial.write(char(results & 0xff) );

you perform a AND operation with Hex FF..

I'm a bit unclear on the reason behind it...
That returns just the lower 8 bits of the long value - returning one byte of data.  The next three Serial.print's return the next three bytes of data (shift right, and mask, 3 times).  For the first one you don't need to shift right as it's already in the right alignment.
Logged

Get 10% off all 4D Systems TFT screens this month: use discount code MAJENKO10

Offline Offline
Newbie
*
Karma: 0
Posts: 36
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thank you very much. Now its clear to me!
Logged

Pages: [1]   Go Up
Arduino Forum upgrade scheduled for Monday, October 20th, 11am-4pm (CEST). Sorry for the inconvenience!
Jump to: