# Bit manipulation of sensor data

Hello
i am new to programming also new to arduino. I have a set of 8 sensors

The 8 sensor gives us a bit stream. The bit stream corresponds to the relative position. From the sensors three samples are collected .

For example , the structure looks as follows

sens1 sens2 sens3 sens4 sens5 sens6 sens7 sens8 output
samp1 1 1 0 1 1 1 1 0 2 ,4
samp2 0 0 0 1 1 1 0 0 3
samp3 0 1 0 1 1 0 1 1 2 ,2

So for samp1 it should return values of 2 & 4
samp 2 it should return values of 3
samp3 it should return value of 2 & 2

Basically it should count the number of consecutive ones from a the matrix of sensor and samples. Any help with example codes (bit manipulation, storing of bit count in array) would be really helpful.

Have a look at the following code

``````byte sample1 = B11011110;
byte sample2 = B00011100;
byte sample3 = B01011011;
byte sample4 = B00000000;
byte sample5 = B11111111;

void scanByte(byte sample)
{
// we are looking for 2 or more consecutive bits set to 1
bool patternStarted = false;
byte patternLength = 0;
byte nbPatterns = 0;

// let's print all the bits. not using the binary print version because it will not print starting 0. I want to see the 8 bits
Serial.print ("B");
for (int currentBit = 7; currentBit >= 0; --currentBit) Serial.print(bitRead(sample, currentBit));
Serial.print ("--> ");

// parse each bit and look for a pattern of two or more consecutive 1
for (int currentBit = 7; currentBit >= 0; --currentBit) {

// if we have already started a pattern, check if we can confirm and continue the pattern
if (patternStarted) {
if (bitRead(sample, currentBit) == 1) {
// we found another 1, pattern is confirmed, we keep counting
patternLength++;
if (currentBit == 0) {
// we need to deal with the case that we are at the end of the byte
if (nbPatterns) Serial.print(","); //we already printed something, print a comma
nbPatterns++;
Serial.print(patternLength);
patternLength = 0;
patternStarted = false;
}
} else {
// we found a zero, if the patternLength is more than 1 then we really had a pattern
if (patternLength > 1) {
if (nbPatterns) Serial.print(","); //we already printed something, print a comma
nbPatterns++;
Serial.print(patternLength);
}
patternLength = 0;
patternStarted = false;
}
}

// we have not yet identified a possible pattern, check if this is the start of one
if ((!patternStarted) &&  (bitRead(sample, currentBit) == 1)) {
// we found a 1, that's possibly the start of a pattern
patternStarted = true;
patternLength = 1;
}

} // end for each bit in the sample

Serial.print(" Matching = ");
Serial.println(nbPatterns);

}

void setup() {
Serial.begin(115200);
Serial.println("-------------");
scanByte(sample1);
scanByte(sample2);
scanByte(sample3);
scanByte(sample4);
scanByte(sample5);
}

void loop() {}
``````

the output in the console (set at 115200 bauds) should be

``````-------------
B11011110--> 2,4 Matching = 2
B00011100--> 3 Matching = 1
B01011011--> 2,2 Matching = 2
B00000000-->  Matching = 0
B11111111--> 8 Matching = 1
``````

of course instead of printing as I do you could store the count and hits into an array.

did you give it a try?

Hello
Thanks a lot for your detailed explanation. As a beginner it helped me to understand the code in detailed manner .
I had some problems with the simulator to start with but i went through it and It helped me to understand about it in quite a bit details and it feels good. I did some additional programming to basically the shifting towards negative axis and positive axis,
I have currently incoming 15 bit binary vector That look like this

1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 --> vec1

1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 --> vec 2

I wanted to compare each of the incoming vectors with a reference vector which I define as Reference_vector as
1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 --> ref vec

The idea was to define this as an Boolean array
boolean reference_array []= {1, 1, 1, 1, 1,1 ,1,1,1,0, 0, 0, 0, 0,0};

which is also a 15 bit array. I am not sure if this is the best way to define the bit vector in Arduino. I want to compare the incoming 15 bit stream with this reference_array and based on that I can say if it is to positive X direction or Negative X direction.
So for example if the incoming array is
1 1 1 1 1 1 0 0 0 0 0 0 0 0 0
and comparing it to reference array . there are three more 0s to the left of the reference_array and thus corresponding -3X in distance ?

and if its as follows
1 1 1 1 1 1 1 1 1 1 1 0 0 0 0

There are two more ones than the reference vector then it results in +2X distance
I am looking for a very simple way to do that manipulation. Perhaps bit shifting is the easiest way forward but I am not comfortable with that as of now. I am thinking on these lines

Binary_input [z] -->15 different values
for (int z=1; z<16;)
{
boolean reference_array []= {1, 1, 1, 1, 1,1 ,1,1,1,0, 0, 0, 0, 0,0};

if (//Binary_input[z]) and reference_array--> doing a comparison )
//No of Binary 0s is to the left of the reference vector for ex if its 3 zeros as shown above it will result in -3x )
else
(// If the shift there are 2 more 1s the number of ones in reference vector it result in +2x distance (as I tried to explain in the example)
z++;

}

I am looking for a very simple way to do that manipulation. Perhaps bit shifting is the easiest way forward but I am not comfortable with that as of now. I am thinking on these lines

Binary_input [z] -->15 different values

Because of the format of your data, the comparisons can be done numerically. Here's a test sketch which does that.

``````unsigned int referenceValue = 0x7fc0;//0111 1111 1100 0000

unsigned int testValue[15] = {0x7fff, 0x7ffe, 0x7ffc, 0x7ff8,
0x7ff0, 0x7fe0, 0x7fc0, 0x7f80,
0x7f00, 0x7e00, 0x7c00, 0x7800,
0x7000, 0x6000, 0x4000
};

unsigned int difference = 0;

void setup() {
Serial.begin(9600);
Serial.println("starting reference value");
Serial.println(referenceValue, BIN);
Serial.println();

Serial.println("15 possible test values");

for (int i = 0; i < 15; i++)
{ Serial.print(testValue[i], HEX);
Serial.print('\t');
Serial.println(testValue[i], BIN);
}
Serial.println();
delay(1000);
}

void loop() {
Serial.println("         |      ");//mark reference length
byte r = random(0, 15);//exclusive of upper bound
Serial.print(testValue[r], BIN);
Serial.print('\t');

if (testValue[r] >= referenceValue)
{
difference = testValue[r] - referenceValue;
}

else
{
difference = referenceValue - testValue[r];
}

switch (difference)
{
case 0:
Serial.println("no difference");
break;

case 32:
Serial.println("+1X");
break;

case 48:
Serial.println("+2X");
break;

case 56:
Serial.println("+3X");
break;

case 60:
Serial.println("+4X");
break;

case 62:
Serial.println("+5X");
break;

case 63:
Serial.println("+6X");
break;

case 64:
Serial.println("-1X");
break;

case 192:
Serial.println("-2X");
break;

case 448:
Serial.println("-3X");
break;

case 960:
Serial.println("-4X");
break;

case 1984:
Serial.println("-5X");
break;

case 4032:
Serial.println("-6X");
break;

case 8128:
Serial.println("-7X");
break;

case 16320:
Serial.println("-8X");
break;

}
delay(1000);
}
``````

Thanks for the heads up. I actually get 15 binary sensors in the following way . In the void loop before calculating the difference as you suggested it

I do a simple Serial printing of the input from the sensors as follows

for (int z=1; z<16;)
{
z++;
}
I get the following out put

On the serial monitor The output looks like as follows

1 1 1 1 1 1 0 0 0 0 0 --> 0x7e0
1 1 1 1 1 1 0 0 0 0 0
1 1 1 1 1 1 0 0 0 0 0
1 1 1 1 1 1 0 0 0 0 0
1 1 1 1 1 1 0 0 0 0 0

I added the code as follows

int difference = 0;
for (int z=1; z<16;)
{
z++;
unsigned int referenceValue = 0x7e0;// Binary equivalen phase binary mapped is of the tyoe byte
{
difference = phase_binary_mapped[z] - referenceValue;
Serial.print("positive distance");
Serial.print(difference);
}
else
{
Serial.print("negative distance");
Serial.print(difference);
}

}

I am getting some garbage values on executing the sketch. I was excpeting for each iteration , to have one value of difference in integer form based on the difference.
I am doing something wrong but unable to figure out what exactly .

``````[color=red]for (int z=1; z<16;)[/color]
{
[color=red]  z++;[/color]
unsigned int referenceValue = 0x7e0;// Binary equivalen phase binary mapped is of the tyoe byte
{
difference = phase_binary_mapped[[color=red]z[/color]] - referenceValue
``````

this is not the typical way to write a for loop.. and are you sure you want to increment z at the beginning of that loop and use it after??

feels weird

Sorry i did a mistake in that part of the code , I was wrong in the loop what i was trying to say was as such

int difference = 0;
for (int z=1; z<16;)
{
unsigned int referenceValue = 0x7e0;// Binary equivalen phase binary mapped is of the type byte
{
difference [z] = [z] - referenceValue;

}
else
{
difference [z] = referenceValue - Received_Binary_Bits[z];

}

serial.print(difference[z]);
z ++
]

I am trying to get something like this as end , for difference for different value of Received_Binary_Bits.

example
a) (Received_Binary_Bits = 1 1 1 1 1 1 1 0 0 0 0
Refernce Value = 1 1 1 1 1 1 0 0 0 0 0
Difference = 1 extra bit to the right -> 20
b) Received_Binary_Bits = 1 1 1 1 1 1 1 1 0 0 0
Refernce Value = 1 1 1 1 1 1 0 0 0 0 0
Difference = 2 extra bit to the right --> 40

Othercase if its (negative direction

c) Received_Binary_Bits = 1 1 1 1 1 0 0 0 0 0 0
Refernce Value = 1 1 1 1 1 1 0 0 0 0 0
Differnece = 0 bit to left --> -15
d) Received_Binary_Bits = 1 1 1 1 0 0 0 0 0 0 0
Refernce Value = 1 1 1 1 1 1 0 0 0 0 0
Difference = 2 extra bit to the right -> -30

The syntax of a for loop in C++ is:

``````for ( init; condition; [color=green]increment[/color] )
{
statement(s);
}
``````

while you can leave the increment piece empty and do it indeed in the statement(s), it is far from being a best practice.

Standard way of writing this loop would be this way, not have the z++ in the

``````for (int z=1; z<16;[color=limegreen]++zz[/color]) {
...
}
``````

why are you iterating from 1 to 15 versus 0? which is the standard way to address arrays?

difference [z] = [z] - referenceValue;

what is this [z]?

Z is the binary input we get , so for each biary input we have a value of 1 or 0
……………………………………………………………………….
………………………………………………………………………..
………………………………………………………………………….
………………………………………………………………………….

That is why the iteration is done from z=1 to z=15.

for now , from your guidance , i am currently just running print to see that bits.

for (int z=1; z<16;z++)
{
Serial.print(Recieved_Binary[z]);
}

have you looked at cattledog code?

Yes , I have done it something as follows looking into the hint provided by cattledog’s code

//---------------------
// Add the binary to cm conversion below
for (int z=1; z<16;z++)
{
unsigned int referenceValue = 0x7e0;// Binary equivalen phase binary mapped is of the tyoe byte
{

}
else
{

}
Serial.print(difference);
}

Serial.print ("After ----->");
for (int z=1; z<16;z++)
{

}

I added the second print statement to see if the difference actually leads to 0 in its mean position 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0

I acutally see the following in the serial monitor

201520152015201520152016201620162016201620162016201620162016After--> 11111000000

So I don’t know what I am printing out . I was thinking to get a 0 , since it is at the referenceValue. Maybe there is to be some conversion done ?

Please post some complete test code which compiles instead of the partial snippets. The variable declarations are important. We have no idea of what Actual_Binary[] is, and why the indexes are running to 99.

How are your receiving the 15 binary sensor bits? Are there values received over serial, or are you directly reading pins? Are you dealing with ascii chars representing 0 and 1 or with actual digital data? Are you working with 12 bit or 15 bit values? You have not posted the code which reads the sensors and accumulates the values.

There is confusion in your code as to whether you are handling the sensor values bitwize or as combined 15 bit numbers.

In my test code, I was comparing the complete combined numbers to the reference number, there were no bitwize calculations.

It would help if you took this back to the beginning, and show us the setup and declarations. Break the loop into functions like readSensors(), createBinaryValue(), compareValueToReference().

Hello
Sorry for misunderstanding . I should have added the declaration and setup part. From the functions you mentioned as readSensors() , createBinaryValue() and comapreValuetoReference() , do you mean that I break down the cdoe and then print out the values at each step ?

Are there values received over serial, or are you directly reading pins?
I am trying to read the values from PIN directory.

Are you dealing with ascii chars representing 0 and 1 or with actual digital data?
The values I am trying to run are actual digital value.

Are you working with 12 bit or 15 bit values?
Working with 15 bit values.

My rogh sketch looks like this ,
<
byte Actual_binary[32];
int period_Length[32];
int difference = 0;

void setup()
{
initSerialConnection(serialPin2);
PIOB -> PIO_OER = 0b11111111111111111111111111111111 ;
PIOC -> PIO_ODR = 0b00000000000111111111111111111111 ;
PIOC -> PIO_PER = 0b11111111111111111111111111111111 ;
Serial.begin(115200);

}

void loop()
{
// To take a number of readings
{
Binary_Data[z] = PIOC->PIO_PDSR;

}

for (int z=1; z<16;z++)
{
unsigned int referenceValue = 0x7e0;// Binary equivalen phase binary mapped is of the tyoe byte
{
}
else
{

}

Serial.print(difference);

}
Serial.print ("After ----->");
for (int z=1; z<16;z++)
{
}
}
/>

Are you running on an arduino DUE??

Where is Received_Binary declared? What's the purpose of reading 400 and keeping 15? Why don't you start your array index for Received_Binary at 0?

``````[color=red]Acrual[/color]_Binary[99];
``````

Unlikely to compile...

Give us real code that pass at least the preprocessing state or really compiles....

Yes I am running on Arduino DUE

Can you post full code that compiles? So that we don't have to do guess work? also your code does something today. What's wrong in your eyes with it?

Below is initial code. THe output is also attached in the picture. The first shoot is with the neutral point commented.

``````#define serialPin2 16
#define noOfSamples 350
int rawdata[noOfSamples];
int relPos[32];
int lengthOfSample[32];
byte Actual_Binary[32];
int i, Global_Trig;
int High = 110;
int Low = 40;
int difference = 0;
uint32_t SendData ;
uint32_t SendSignal ;

void setup()
{
initSerialConnection(serialPin2);

PIOB -> PIO_OER = 0b11111111111111111111111111111111 ;
PIOC -> PIO_ODR = 0b00000000000111111111111111111111 ;
PIOC -> PIO_PER = 0b11111111111111111111111111111111 ;

Serial.begin(115200);

pinMode (33, INPUT) ;
pinMode (49, INPUT) ;
}

void loop() {

for (int i=0; i<noOfSamples; i++)
{
rawdata[i] = PIOC->PIO_PDSR;

}
Global_Trig = Trigger1(19 );

for (int i=0; i<31; i++)
{
relPos[i]=RelativeData(i,Global_Trig);
}

for (int i=0; i<31; i++)
{
if  (((relPos[i]) > High) || ((relPos[i]) < Low))
{
Actual_Binary[i]= 0;
bitSet(SendData,i);
}
else
{
Actual_Binary[i]= 1;
bitClear(SendData,i);
}
}

for (int i=0; i<31; i++)
{
lengthOfSample[i]=Calc_Period_time(i);
{
if  ((lengthOfSample[i]) > 40 )
{
bitSet(SendSignal,i);
}
else
{
bitClear(SendSignal,i);
}
}

}

for (int i=1; i<16;i++)
{
unsigned int referenceValue = 0x7e0;// Binary equivalen phase binary mapped is of the tyoe byte
{

}
else
{

}

Serial.print(difference);

}

Serial.print ("  <----Send Data ----->       ");
for (int i=1; i<16;i++)
{

}
delay(2000);
Serial.print ("  <-----end Data ---->");

}

int Trigger1(int Data )
{
int count;

count =  0;
while (( (rawdata[count] & mask) == mask ) &  (count < noOfSamples))
{
count++;
}
{
count++;
}
return(count);

}

int RelativeData(int Data, int Trig_1 )
{  int count;
count =Trig_1;

while (( (rawdata[count] & mask) == mask ) &  (count < noOfSamples))
{

count++;
}

{

count++;

}

return (count-Trig_1);
}

int Calc_Period_time(int Data )
{
int Time_period, Slack_Count;
Slack_Count=0;

{

Slack_Count++;
}

while (( (rawdata[Slack_Count] & mask) != mask ) &  (Slack_Count < noOfSamples))
{

Slack_Count++;
}
Time_period =Slack_Count;

{

Time_period++;
}

return (Time_period-Slack_Count);
}
``````

Thank you for posting complete code and using code tags.

``````Serial.print ("  <----Send Data ----->       ");
for (int i=1; i<16;i++)
{

}
``````

As I understand it, this is printing out 111111010000000, and this is supposed to be the extracted 15 bits from the complete port reading. According to the previous postings, the 0 at bit#8 between the two ones should not be present. Is that correct? For this test, should you be reading 111111110000000?

Are you sure that you have the correct input to the pins? If the input is correct, than the extraction program is incorrect. I have not examined your code in detail, but I know the extraction can be tricky given the pin arrangement on the ports of the Due.

I would recommend that you work through the issue without the complete port readings, but just assemble the received binary value with digitalRead(). When everthing is working to your satisfaction you can add the direct port readings and extraction to speed things up if necessary,

``````unsigned int referenceValue = 0x7e0;// Binary equivalen phase binary mapped is of the tyoe byte
``````

The comment does not make sense, and in the original postings the 15 bit reference value was 0x7fc0.
111111111000000.

``````for (int i=1; i<16;i++)
{
unsigned int referenceValue = 0x7e0;// Binary equivalen phase binary mapped is of the tyoe byte
{

}
else
{

}

Serial.print(difference);
``````

Received_Binary[] is a bit value. You can not compare the individual bit value to the reference. If you want to use the difference method, you must combine the 15 bits into an actual value for testing against the reference. You will need to compose that number using bit shifting or multiplication of each bit by the appropriate power of 2.

You actually may want to do this as part of the extraction routine. Here's an example of how I selected and reassembled 16 bits out of PortC on pins 34-41 and 44-51. You should be able to adapt it to your task.

``````long value = REG_PIOC_PDSR;
value = value & 0xffffc; //clear top 11 and bottom 2 bits with mask
value = value >> 2; //shift away the lower 2 cleared bits
//remove the two junk bits from center of data
int lo8 = value & 0xff; //mask and save lower 8 bits
value = value >> 10; //shift away the lower 10 bits to clear middle two
value = value << 8 | lo8; //reassemble continuous 16 bits
``````

You need to define `[color=green]unsigned[/color] int rawdata[noOfSamples];  ` because you store a 32 bit register in it so don't want to deal with negative numbers.

All Your whiles are not great. They will somehow do what you think they might do but that's a bit of luck.. you use & instead of && - I'm unsure of what you count but this & stuff is right for bitmasking but stick to && for logical AND)

``````while (( (rawdata[count] & mask) == mask ) [color=red]& [/color](count < noOfSamples))
``````

This will never be true: `if ( [color=red]Received_Binary[ i ][/color] >= referenceValue)`
Because `Received_Binary` is a byte array so holds data between 0 and 255 in the general case and in your case initialized with 0 or 1.... As referenceValue is 0x7e0 so always larger than a byte the test will never be true in general and in your specific case because you have stuffed 0 or 1 in these, there is not even a chance this can compare...

Then `difference` will be 0x7e0 - 0 or 0x7e0 -1 which is 2016-0 or 2016-1 ==> this is why you see 2016 or 2015 in your output.

I think you need to go back to the drawing board, describe what your algorithm needs to do in plain English and then code. I think this is quite confused and you are getting lost in what you do