1

I'm currently reading 3 limit switches and sending those data over Serial.write using the following code.

#include <SPI.h>
#include <Wire.h>
#include <arduino-timer.h>

//Define limit switch pins
#define LEFT_SWITCH_PIN 5
#define RIGHT_SWITCH_PIN 6
#define REAR_SWITCH_PIN 7

bool left_switch_state;
bool right_switch_state;
bool rear_switch_state;
bool switch_state_array[3] = {left_switch_state,right_switch_state,rear_switch_state};
int switch_pin_array[3] = {LEFT_SWITCH_PIN,RIGHT_SWITCH_PIN,REAR_SWITCH_PIN};

int send_status_state = 0;

void setup() {
    Wire.begin();
    Serial.begin(115200);
    status_timer.every(200, sendStatus);
}

void sendStatus() {
  if (send_status_state == 0) {
    getLimitSwitch();
  
    unsigned char buf[5];
    buf[0] = 'S';
    buf[1] = switch_state_array[0];
    buf[2] = switch_state_array[1];
    buf[3] = switch_state_array[2];
    buf[4] = '|';
    Serial.write(buf,5);
    send_status_state = 1;
    
  } 
}

void loop() {
    status_timer.tick();
  }

void getLimitSwitch()
{
  for (int i=0; i<3; i++)
  {
    switch_state_array[i] = digitalRead(switch_pin_array[i]);
  }
}
/*********************************************************************************************************
    END FILE
*********************************************************************************************************/

as you can see I'm currently using 3 bytes to send the states of each limit switch separately.

    buf[1] = switch_state_array[0];
    buf[2] = switch_state_array[1];
    buf[3] = switch_state_array[2];

How can I send all limit switch data in one byte?

1 Answer 1

5

You should learn how to use bitwise operators. These are needed to do what you want.

We can save the state of each switch in one bit each. For this we first define our global variable that will hold the switch states:

byte switch_states = 0;

Then in getLimitSwitch() we loop through our pins. The result of digitalRead() is always one of 0 and 1. So we can take this value and bit shift it to the left. Then we do bitwise OR operations to put the value into our switch_states variable:

void getLimitSwitch()
{
  for (int i=0; i<3; i++)
  {
    switch_states |= ( digitalRead(switch_pin_array[i]) << i );
  }
}

Then you can send that byte over Serial. It can hold up to 8 states.

Serial.write(switch_states);

The most interesting line here is

switch_states |= ( digitalRead(switch_pin_array[i]) << i );

Lets follow here with an example: Lets assume we look at the pin with index 2 and it is HIGH. So we have switch_states |= ( 1 << 2 ). This equates to the following representation in binary switch_states |= ( 0b00000001 << 2 ). << shifts the bit pattern to the left; by 2 digits in this case. So we get switch_states |= 0b00000100;. That is equal to switch_states = switch_states | 0b00000100;. The bitwise OR operator | return a value where each bit is set to 1, if the corresponding bit in at least one of the two operants is 1. Here we use this to put the bits together.

If the pins have the states HIGH,LOW,HIGH the resulting value will be 0b00000101, aka. 5 in decimal.


On the other side you might want to decode this value. How it is done depends on the architecture (using a PC, a microcontroller, ...). But on an Arduino you can test for a pin to be HIGH with this:

if(received_states_variable & (1 << pin_index))

Note: Doing this

bool left_switch_state;
bool right_switch_state;
bool rear_switch_state;
bool switch_state_array[3] = {left_switch_state,right_switch_state,rear_switch_state};

doesn't make much sense. You initialize the array elements just with the implicitly to false initialized variables. You just don't need the normal bool variables. You can just simply define your bool array. If you want to initialize it explicitly, just use true or false directly:

bool switch_state_array[3] = {false, false, false};

or even

bool switch_state_array[3] = {false};
2
  • "These are needed to do what you want." Well, there are also bit field structs. I like to use them extensively in C and then in Rust I get told that transmutation is bad and I should feel bad.
    – AndreKR
    Oct 20, 2021 at 22:37
  • 1
    I don't know Rust and I don't know why this should be so bad. But you are right. You can also ise bitfield structs. Maybe you want to add another answer with a short explanation how to use them. I personally use bitshifting but for the OP and others knowing all the options can help further
    – chrisl
    Oct 21, 2021 at 6:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.