Binary value to SPI.transfer

Hi everyone,

I'm a bit new to C# and data types. I'm attempting to control a chip via SPI via an 8-bit serial word.

According to the documentation (https://datasheets.maximintegrated.com/en/ds/MAX5408-MAX5411.pdf) that would look something like 10111111 in binary.

In the above example, the first three digits are used to select what is bring controlled, and the next five what changes need to be made.

So for the above command, I would like to XXX + YYYYY.

I would like to maintain them as separate variables, and concatenate them before sending the SPI transfer. I believe I have to add a "B" to the

Something like:

  String concatenatedString = "";

  concatenatedString = "B" + String(XXX) + String(YYYYY);
  
  SPI.transfer(concatenatedString);

What is the most valid way to do so?

uint8_t top = some_number;
uint8_t bottom = some_number;

uint8_t command = (uint8_t) ((top << 5) | (bottom & 0x1F));

Thank you for the answer!

Would you mind explaining what's happening here?

Lets say your top value is 0x01 or 00000001

0x01 << 5 will shift the bits to the left 5 times

0x01 << 5 = 00100000

You do binary OR to combine the lower and top value

00100000 | some_number

So if some_number is 00000101

00100000 | 00000101 = 00100101

1 Like
const byte XXX = 0b101 << 5;
const byte YYYYY = 0b11111;

  SPI.transfer(XXX+YYYYY);

Since they have no 1-bits in common you can use either '+' or '|' (bitwise OR) interchangeably.

1 Like

Thanks @johnwasser. Trying to think back to my digital electronics classes here.

I would guess since I am using variables here, it would be safer to use the bitwise operator? It's only this specific example that would be safe?

As long as the two fields being merged don't share any 1 bits you can merge them with +.

0 | 0 == 0 + 0 == 0
0 | 1 == 0 + 1 == 1
1 | 0 == 1 + 0 == 1
The only problem is if they share a 1 bit:
1 | 1 == 1
1 + 1 == 0 with a carry

1 Like

Thank you for the explanation.

Given the following code:

void digitalPotWrite(int address, int command) {
  // take the SS pin low to select the chip:
  digitalWrite(slaveSelectPin, LOW);
  delay(100);
  const byte XXX = address;
  const byte YYYYY = command;

  SPI.transfer(XXX | YYYYY);
  Serial.println(XXX | YYYYY, BIN);

  delay(100);
  // take the SS pin high to de-select the chip:
  digitalWrite(slaveSelectPin, HIGH);
}

Serial.println(XXX | YYYYY, BIN); is returning a 7-bit string, rather than an 8. E.g.: Expecting 01000000 but get 1000000

Is this a result of Serial.println or do I have an issue?

How can I be sure the chip is getting the correct value?

Try the following to see the missing leading zero:

  byte x = XXX | YYYYY;
  
  for(int i = 7; i>=0; i--)
  {
    Serial.print(bitRead(x, i), BIN);
  }

Serial.println() always suppresses leading zeroes. You can rest assured that any bits on the left that aren't shown are zeroes.

SPI.transfer() only sends 8-bit values.

1 Like

SPI.transfer() also returns 8-bit data.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.