Go Down

Topic: Roll-Your-Own Serial output && Bitwise operations..... (Not for beginners) (Read 438 times) previous topic - next topic

raysot

I am designing my own serial communication for a hardware circuit that takes 16 bits of data serially. (Think Aircore Gauges)

Outputs I need: CLOCK, CHIPSELECT, DATA (this requirement negates using any of the built-in serial libraries)

CLOCK and CHIPSELECT are easy-shmeazy. DATA, not so much (Yet)

I have an Integer I need to send to this device.

Let's use an INT of 20. (or  0b0000000000010100)

I have a loop that executes 16 times, I need to Bitwise AND to build my DATA stream:

My LOOP uses an interim INT value that increments from 1 thru 16, then back to 1 when it is finished.

My question is: How can I test each individual bit in the INT I want to send to see if it's a 1 or 0 and then set my DATA line accordingly?

Desired output:

on CLK 1: DATA = 0
on CLK 2: DATA = 0
on CLK 3: DATA = 1
on CLK 4: DATA = 0
on CLK 5: DATA = 1
on CLK 6: DATA = 0














Coding Badly

if ( data & 1 )
{
  // set the digital pin HIGH
}
else
{
  // set the digital pin LOW
}

data = data >> 1;

raysot

What I came up with: (Basically I'm just incrementing the Loop counter by a factor of 2, ensuring I can always use it as a bitmask)

  for (long _CLK = 1; _CLK <= DATA_width; _CLK *=2)
  {
    //delayMicroseconds(halfBit9600Delay);

    //Set the DATA line accordingly (Where the magic happens)
    if(_CLK & _ANGLE)
    {
     digitalWrite(tx, HIGH); 
    } 
 
    // turn the pin on:
    digitalWrite(CLK, HIGH);   
    delayMicroseconds(halfBit9600Delay);                 
   
    // turn the pin off:
    digitalWrite(CLK, LOW);
    digitalWrite(tx, LOW);   
   
    //delayMicroseconds(halfBit9600Delay);
  }

Go Up