Is it possible to use bitRead?

Hi all,

my plan is to call a spark function which accepts a string, turn “5” into a int 5 and then use bitRead to identify if individual bits are turned on or off (I use the integer for a 16 channel input so to say):

int l = command.toInt();

for (int i = 0; i < 16; i++)
{
mylights[i] = bitRead(l,i);
}

Now, bitRead does not exist. And I am not a super smarty when it comes to bit-wise operations. How can I rewrite that so it works?

Here they are:

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))

Don’t forget that int on :spark: is 32-bits, not 16. A 16-bit type if you really need it would be uint16_t. I suspect that is why they did not include these by default.

4 Likes

This and a few more things from Arduino.h should be pull requested into the spark_wiring.h file :wink:

#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105

#define abs(x) ((x)>0?(x):-(x))
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))

#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))

typedef uint16_t word;

#define bit(b) (1UL << (b))

certain more when we convert them…

2 Likes

thx a lot! that works perfectly.

A few of these #define's from Arduino are problematic for the 16- versus 32-bit change:

The second one, for instance, should be:

#define highByte(w) (((uint8_t) ((w) >> 8) & 0xff))

to strip off the upper sixteen bits.

That’s probably safer, agreed… but it’s still assumed if you are talking high byte and low byte that you are dealing with 16 bit words. And we could probably add highWord(x) and lowWord(x) for breaking up a 32 bit value… probably not as useful as adding highNibble(b) and lowNibble(b) though :wink:

Like the original poster, I (think) want to use an integer to keep track of relay channel states by breaking the integer down into bits and checking if each bit is 0 or 1 (relay off or on, respectively). However, it seems that no matter what I try, my integer value is always returned as 0. The code is below. I’ve toggled all 4 relays in various states and the toggleRelay() return integer value and relayStates value are always 0. Am I doing it wrong?

#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))

uint8_t relayStates = 0;

void setup() {
    Spark.function("toggleRelay", toggleRelay);
    Spark.variable("relayStates", &relayStates, INT);
    
    for(uint8_t i=0; i<4; i++) {
        pinMode(i, OUTPUT);
        digitalWrite(i, !bitRead(relayStates, i));
    }
}


void loop {
	// Do nothing
}


int toggleRelay(String command) {
    command.trim();
    command.toUpperCase();
    
    if(command.equals("RELAY1ON")) {
        bitWrite(relayStates, 0, 1);
    } else if(command.equals("RELAY1OFF")) {
        bitWrite(relayStates, 0, 0);
    } else if(command.equals("RELAY2ON")) {
        bitWrite(relayStates, 1, 1);
    } else if(command.equals("RELAY2OFF")) {
        bitWrite(relayStates, 1, 0);
    } else if(command.equals("RELAY3ON")) {
        bitWrite(relayStates, 2, 1);
    } else if(command.equals("RELAY3OFF")) {
        bitWrite(relayStates, 2, 0);
    } else if(command.equals("RELAY4ON")) {
        bitWrite(relayStates, 3, 1);
    } else if(command.equals("RELAY4OFF")) {
        bitWrite(relayStates, 3, 0);
    } else
        return -1;
        
    relayStates = 0;
    
    for(uint8_t i=0; i<4; i++)
        digitalWrite(i, !bitRead(relayStates, i));
    
    return relayStates;
}

And, yes @Bdub, it’s one of those backward Sainsmart relays, hence the digitalWrite(i, !bitRead(relayStates, i));.

And, is it possible to use a nibble instead of a full byte (ignorance–)?

wgbartley, I believe the Spark.variable uses the “int” type, expecting 4 bytes instead of 1 even though you defined as that. So, one way to get around the issue with you bit operations is to cast relayStates as a uint8_t in your call. For example:

int relayStates = 0;

void setup() {
    Spark.function("toggleRelay", toggleRelay);
    Spark.variable("relayStates", &relayStates, INT);

    for(uint8_t i=0; i<4; i++) {
        pinMode(i, OUTPUT);
        digitalWrite(i, !bitRead((uint8_t)relayStates, i));
    }
}

Hopefully, that will work. :smile:

Nope. That didn’t fix it.

You know what did?

...
    if(command.equals("RELAY4ON")) {
        bitWrite(relayStates, 3, 1);
    } else if(command.equals("RELAY4OFF")) {
        bitWrite(relayStates, 3, 0);
    } else
        return -1;

    relayStates = 0; // <-- What moron put that there? Oh, right...

    for(uint8_t i=0; i<4; i++)
        digitalWrite(i, !bitRead(relayStates, i));
...

… if we had a nickel …

1 Like

Doh! I wasn’t even looking for that. Glad it’s working… though my explanation sounded really good an all and made me look smart until… LOOK OVER THERE!!! (runs away) :smile:

1 Like

I originally had it as uint8_t relayStates = 0; and must have changed it when I made that post. I came back after getting the kids to bed, and I had set it back to uint8_t again. I shouldn’t be programming this weekend…

That would be good. But don’t like the typedef for word which should be 32bits. Just about the only use for word is to help with the alignment issue @ScruffR discusses here: https://community.spark.io/t/how-to-know-how-much-ram-flash-i-am-using/2150/11

1 Like