Bit Reversal (LSB - MSB)

Now I gave you a bit-reversal routine that will run faster than the data comes in and avoids the -overhead- of running a lookup table and all the confusion entailed therein.

I sort of understand the "block diagram" of the routine as you explained it. Would you help code it?

I'll be taking the delay out of the code at the end, so reading will be taken as fast as the user can rotate a gear in the jaws and readjust the mic.

// It should have a 1 byte arg and return 1 byte. -- example: byte reverse_bits( byte data)
// It should have a for-loop that counts an index from 0 to 3
// It should use BitRead() to get the value of bit index of byte arg and use BitWrite() to set bit (3-index) of the return byte to that value for each iteration of the for-loop.
// Then it should return the now-C-readable return value.

void  setup(void) {
  Serial.begin(9600);
  Serial.println("Test nibble bit reverser");
  byte B;  // this would be your nibble stored in a byte
  for (byte i=0; i<16; i++)  {
    B = i;
    Serial.print(B, DEC);
    Serial.print(" = 0x");
    Serial.print(B, HEX);
    Serial.print(" <--> 0x");
    B = reverse_bits(B);
    Serial.println(B, HEX);
  }  
}

byte  reverse_bits(byte Mitutoyo) {
  byte  rtn = 0;
  for (byte i=0; i<4; i++) {
    bitWrite(rtn, 3-i, bitRead(Mitutoyo, i));
  }
  return rtn;
}

void  loop(void)  {
}

If the bits are reversed, how do you explain the last entry? 1111 reversed is not 0. It's not 10 either.

Nick, we don't care about anything that returns 1111. It's a non-interesting entry.

GoForSmoke,

your test sketch works wonderfully.

Now, to integrate this into the micrometer read, so that the array gets filled with the correct bits, instead of the reversed bits.

BTW, I made a simple change, adding decimal outputs:

// It should have a 1 byte arg and return 1 byte. -- example: byte reverse_bits( byte data)
// It should have a for-loop that counts an index from 0 to 3
// It should use BitRead() to get the value of bit index of byte arg and use BitWrite() to set bit (3-index) of the return byte to that value for each iteration of the for-loop.
// Then it should return the now-C-readable return value.

void  setup(void) {
  Serial.begin(9600);
  Serial.println("Test nibble bit reverser");
  byte B;  // this would be your nibble stored in a byte
  for (byte i=0; i<16; i++)  {
    B = i;
    Serial.print(B, DEC);
    Serial.print(" = 0x");
    Serial.print(B, HEX);
    Serial.print(" <--> 0x");
    B = reverse_bits(B);
    Serial.print(B, HEX);
    Serial.print(" = ");
    Serial.println(B, DEC);
  }  
}

byte  reverse_bits(byte Mitutoyo) {
  byte  rtn = 0;
  for (byte i=0; i<4; i++) {
    bitWrite(rtn, 3-i, bitRead(Mitutoyo, i));
  }
  return rtn;
}

void  loop(void)  {
}

giving results that look like this:

Test nibble bit reverser

0 = 0x0 <--> 0x0 = 0

1 = 0x1 <--> 0x8 = 8

2 = 0x2 <--> 0x4 = 4

3 = 0x3 <--> 0xC = 12

4 = 0x4 <--> 0x2 = 2

5 = 0x5 <--> 0xA = 10

6 = 0x6 <--> 0x6 = 6

7 = 0x7 <--> 0xE = 14

8 = 0x8 <--> 0x1 = 1

9 = 0x9 <--> 0x9 = 9

10 = 0xA <--> 0x5 = 5

11 = 0xB <--> 0xD = 13

12 = 0xC <--> 0x3 = 3

13 = 0xD <--> 0xB = 11

14 = 0xE <--> 0x7 = 7

15 = 0xF <--> 0xF = 15

It's even more interesting displaying BIN instead of HEX:

Test nibble bit reverser

0 = 0 <--> 0 = 0

1 = 1 <--> 1000 = 8

2 = 10 <--> 100 = 4

3 = 11 <--> 1100 = 12

4 = 100 <--> 10 = 2

5 = 101 <--> 1010 = 10

6 = 110 <--> 110 = 6

7 = 111 <--> 1110 = 14

8 = 1000 <--> 1 = 1

9 = 1001 <--> 1001 = 9

10 = 1010 <--> 101 = 5

11 = 1011 <--> 1101 = 13

12 = 1100 <--> 11 = 3

13 = 1101 <--> 1011 = 11

14 = 1110 <--> 111 = 7

15 = 1111 <--> 1111 = 15

Awesome!, I integrated your bit reversal routine into my sketch, and get the results I'm looking for:

When the mic is reading 1.447 mm

I get

15151515000144730,

int req = 5; //mic REQ line goes to pin 5 through q1 (arduino high pulls request line low)
int dat = 2; //mic Data line goes to pin 2
int clk = 3; //mic Clock line goes to pin 3
int i = 0; int j = 0; int k = 0;

byte mydata[14];

void setup()
{
  Serial.begin(19200);
  pinMode(req, OUTPUT);
  pinMode(clk, INPUT);
  pinMode(dat, INPUT);
  digitalWrite(clk, HIGH); // enable internal pull ups
  digitalWrite(dat, HIGH); // enable internal pull ups
  digitalWrite(req,LOW); // set request at high
}

byte  reverse_bits(byte Mitutoyo) {
  byte  rtn = 0;
  for (byte i=0; i<4; i++) {
    bitWrite(rtn, 3-i, bitRead(Mitutoyo, i));
  }
  return rtn;
}

void loop()
{  // while( digitalRead(clk) == LOW) { } // hold until clock is high
    digitalWrite(req, HIGH); // generate set request
   // while( digitalRead(clk) == HIGH) { } // hold until clock is low
    for( i = 0; i < 13; i++ ) {
      k = 0;
      for (j = 0; j < 4; j++) {
      while( digitalRead(clk) == LOW) { } // hold until clock is high
      while( digitalRead(clk) == HIGH) { } // hold until clock is low
      //k = (k << 1) | (digitalRead(dat) & 0x1);
      k = k | (digitalRead(dat) & 0x1) << ( 3 - j);
      }
      k = reverse_bits(k);
      mydata[i] = k;

 Serial.print(k);

      
    }


  
    Serial.println(",");
    digitalWrite(req,LOW);
    delay(100); // do a reading every 2 seconds
}

And you see why the table is really not necessary and actually runs slower? While the serial data is taking time to come in you might as well get the conversion done for each with while waiting for the next byte, and you still have time to process the BCD value into long int and do your other logic -as the data comes in- before actually doing anything with the results. Think of it as production-line at microseconds speed.

I've seen bit and byte order reversals before. At least your caliper uses ascii instead of eia (IBM) code.

Oh, just saw your next post and maybe you'll kick yourself since I'm too far to reach...

    for( i = 0; i < 13; i++ ) {
      k = 0;
      for (j = 0; j < 4; j++) {
      while( digitalRead(clk) == LOW) { } // hold until clock is high
      while( digitalRead(clk) == HIGH) { } // hold until clock is low
      //k = (k << 1) | (digitalRead(dat) & 0x1);
//  don't need     k = k | (digitalRead(dat) & 0x1) << ( 3 - j);
        bitWrite(k, j, (digitalRead(dat) & 0x1)); // edit post, added a )
      }
//   don't need    k = reverse_bits(k);
      mydata[i] = k;

Fantastic. Thanks bunches, and for the record, I kicked myself.

This is the current sketch, and it works beautifully:

int req = 5; //mic REQ line goes to pin 5 through q1 (arduino high pulls request line low)
int dat = 2; //mic Data line goes to pin 2
int clk = 3; //mic Clock line goes to pin 3
int i = 0; int j = 0; int k = 0;

byte mydata[14];

void setup()
{
  Serial.begin(19200);
  pinMode(req, OUTPUT);
  pinMode(clk, INPUT);
  pinMode(dat, INPUT);
  digitalWrite(clk, HIGH); // enable internal pull ups
  digitalWrite(dat, HIGH); // enable internal pull ups
  digitalWrite(req,LOW); // set request at high
}

void loop()
{   digitalWrite(req, HIGH); // generate set request
    for( i = 0; i < 13; i++ ) {
      k = 0;
      for (j = 0; j < 4; j++) {
      while( digitalRead(clk) == LOW) { } // hold until clock is high
      while( digitalRead(clk) == HIGH) { } // hold until clock is low
        bitWrite(k, j, (digitalRead(dat) & 0x1)); // edit post, added a )
      }

      mydata[i] = k;
      Serial.print(k);
                 
    }

  Serial.println(",");
    digitalWrite(req,LOW);
    delay(100); 
}

Since the bit reversal piece is finished, want to jump on over to http://arduino.cc/forum/index.php/topic,79174.90.html, where we can tackle assembling the bits back into variables?