Go Down

Topic: Converting byte [] to binary to send it over SPI (Read 1 time) previous topic - next topic

deathlock

Oct 08, 2016, 09:17 am Last Edit: Oct 08, 2016, 09:40 am by deathlock
Hi,

I am using tc4021B to read parallel inputs from push button over SPI rather than the shiftIn. I got the input debounce to work with the ic and I am saving the states in a byte array. There are eight pushbuttons and each array index has a value either 0 or 1.

Now, i have to transfer the whole array as binary to 74ch595 which controls an array of leds.

So i basically,

if state[0]=1,

the value to be sent over spi should be 0b00000001

if state[5] and state[1] is high,

the value sent over SPI should be 0b00100010

and so on..

My question is how to convert the whole byte state[8] array to a binary value to send it over SPI?

Thanks


AWOL

"Pete, it's a fool (who) looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

Grumpy_Mike

I would use a for loop to go through each array element. Then shift the array element into an accumulating variable.
Code: [Select]

acc =0;
for(int i =0;i<8;i++)
acc = (acc <<1) | state[i] ;

PaulRB

#3
Oct 09, 2016, 08:49 am Last Edit: Oct 09, 2016, 09:04 am by PaulRB
I am saving the states in a byte array.
Don't do that part. Keep your button states in a single byte. That way, it is already in the correct format to send to the '595. Instead, change your debounce code to work on all 8 button states together. Post your code and I will show you what I mean.

sterretje

#4
Oct 10, 2016, 02:47 pm Last Edit: Oct 10, 2016, 02:50 pm by sterretje
As I asked in your (now locked) other thread, why don't you read the data straight away into a byte? PaulRB is asking (or stating) the same.

Would be nice if we got an answer :D
If you understand an example, use it.
If you don't understand an example, don't use it.

Electronics engineer by trade, software engineer by profession. Trying to get back into electronics after 15 years absence.

Grumpy_Mike


deathlock

thanks for the reply..

I was using SPI and not shiftin and out so having problems(I'm a noob) and couldn't find any proper tutorial anywhere.. I would be better if there was one here.

I got the solution myself after tweaking the code for some time..

I was away for sometime so sorry for the late reply..

Thanks once again guys...

bkirkby

Quote
I got the solution myself after tweaking the code for some time..
What was the solution? I am now having the same issue.

I don't think I want to read the buttons directly in to a byte because I am getting them(along with other data) over i2c.

I looked into bitWrite() but I don't understand how that will help and I can't find an example of it anywhere.

My code goes something like this:

Code: [Select]

byte shiftData[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};

void shiftReg() {

  for(int i = 6; i<14; i++){
    byte j = shiftData[i];
    digitalWrite(latchPin, LOW);
    shiftOut(dataPin, clockPin, LSBFIRST, j);
    digitalWrite(latchPin, HIGH);
    Serial.print(j);
  }
}

This is writing the correct numbers to my 595, but the 595 doesn't recognise them as a the proper data type(this is my best guess). If I just write something like:
Code: [Select]
shiftOut(dataPin, clockPin, LSBFIRST, 0b11101100);
The 595 recognises this and works.
Is there a way I could include the "0b" in my variable somehow, or would that not work either?

Thanks for any help/explanations in advance!

PaulRB

#8
Oct 26, 2018, 08:18 am Last Edit: Oct 26, 2018, 08:19 am by PaulRB
Quote
I looked into bitWrite() but I don't understand how that will help and I can't find an example of it anywhere.
It will help you by fixing exactly the problem you have got now. Of course there are examples to be found. Try Google.

The shiftOut() function always sends out 1 byte = 8 bits. If you use it to send out a byte which contains only one bit of the data you want to send, it will send out that bit and 7 other bits that are probably zero. You must use bitWrite() to pack your 8 bits of data that are currently in 8 different bytes into a single byte, before you give that byte to shiftOut().

bkirkby

Thanks PaulRB!!

I think I just needed to look at it with fresh eyes.

I still was not able to find any good examples of bitWrite() from an array so I am including my code below.
Code: [Select]

byte shareData[14] = {1,1,1,1,1,1,1,0,0,0,0,0,0,1};
String tempString;
byte byteA;

void setup() {
  Serial.begin(9600);
}

void loop() {
 
  tempString = "";
  byteA = "";
  for(int i = 6; i<14; i++){
    tempString += shareData[i];
  }
  for(int i=0;i<8;i++){
    int x = tempString[i];// this still writes x as a character, 48=0 and 49=1 so I follow this with an if statement to write 1 or 0 instead...
    if(x == 48){
      bitWrite(byteA, i, 0);
    }else if(x ==49){
      bitWrite(byteA, i, 1);
    }
  }
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, LSBFIRST, byteA);
  digitalWrite(latchPin, HIGH);
 
  delay(5000);
 
}

PaulRB

Well done for getting your head around shiftOut() and bitWrite() and packing bits into bytes. And thank you for thinking of others who may be having similar problem in the future and providing your solution/code as an example to help them.

But your code needs a little work before it can be called a "good" example. It's much more complex and potentially confusing for beginners than it needs to be. Also it uses "String" which is a hazardous thing to do on Arduino with small amounts of RAM memory and can lead to various difficult to diagnose bugs, and in this case is completely unnecessary anyway.

So loose the String variable. Here is a suggestion to replace it:
Code: [Select]

  for(int i=0;i<8;i++){
    bitWrite(byteA, i, shareData[i+6]);
  }

bkirkby

Thanks PaulRB! That is a much more simple and elegant solution.

PaulRB

No problem. Will you update your example for the benefit of others?

Go Up