Hi
How do I declare and initiate an array of bits ?
How do I assign/read bits at runtime ?
Elico
Hi
How do I declare and initiate an array of bits ?
How do I assign/read bits at runtime ?
Elico
In C you can't have an array of anything you can't point to.
You can't have a bit pointer, because you can't take the address of a bit.
You can use bitRead and bitWrite and modulo arithmetic to do what you need.
The closest you can come to an "array of bits" is an array of boolean. Each boolean will have a value of 0 or 1 (like a bit) but will probably take up 8 bits of memory space:
boolean array[] = {true, false, true, 1, 1, 0, HIGH, LOW, LOW, HIGH}; // ten boolean values
I have a question as I'm always learning more.
Couldn't any number be thought of as an array of bits? Not technically an array but a declared byte value has eight bits. Couldn't a person check to see if an individual bit is set or not and even perform logical operations?
It's sort of an array with the index being based on powers of two.
Couldn't any number be thought of as an array of bits?
Of course. Though integers tend to translate to bit patterns that have more meaning to people than floats do.
Not technically an array but a declared byte value has eight bits.
And an int has 16 and a long has 32.
Couldn't a person check to see if an individual bit is set or not and even perform logical operations?
Absolutely.
Thanks Paul.
I see now, when I follow the links, that AWOL was basically saying that. Not needing them I hadn't looked at any of those bit() functions. They probably hold the answer for the OP.
For memory conservation purposes you can make your own and write a function to access it.
So how does this request/question relate or apply to the built in "bit field structure" that C has? I don't think I've ever used them or even know of a good example using them, but I recall reading years ago in my K&R bible about's Cs ability to work with bit level addressing:
Lefty
You could have a struct of, say, eight single bits, but they would be individually named, not an array.
A pointer could only be to the struct.
retrolefty:
So how does this request/question relate or apply to the built in "bit field structure" that C has? I don't think I've ever used them or even know of a good example using them, but I recall reading years ago in my K&R bible about's Cs ability to work with bit level addressing:
As I recall the compiler supports that, at least at the definition level, but at some cost at runtime (ie. code bloat).
AWOL:
You could have a struct of, say, eight single bits, but they would be individually named, not an array.
A pointer could only be to the struct.
So you can't assign to or read from a specific bit field defined within it's parent structure?
Lefty
From the example on the page you linked:
struct taxonomy {
int kingdom : 12;
int phylum : 6;
int genus : 2;
};
The individual bits cannot be accessed (as far as I know) using a variable. So you would have to use each name. For 8 bits you would have 8 names. So I don't think this has got you much further than a simple function that bit shifts and tests.
retrolefty:
AWOL:
You could have a struct of, say, eight single bits, but they would be individually named, not an array.
A pointer could only be to the struct.So you can't assign to or read from a specific bit field defined within it's parent structure?
You can, but only by name, not by index. You can use a bitfield called 'bit3' but you can't call it 'bit[3]'.
What I learned today.
struct myByte {
unsigned value : 1;
};
myByte bit[8];
I would never do that but I do find it amusing.
Well from that link I found they give specific info on what you can't do with bit fields:
The following restrictions apply to bit fields. You cannot:
Define an array of bit fields
Take the address of a bit field
Have a pointer to a bit field
Have a reference to a bit field
But that doesn't give me a feel for would be useful things I could do with bit fields. Anyone up to and able to show a simple, or useful, or at least something fun using a bit field structure?
Well now, this is puzzling. Case 1 uses a bit field:
struct myByte {
int foo : 1;
};
volatile myByte bar;
void setup ()
{
Serial.begin (115200);
bar.foo = 1;
Serial.println (bar.foo);
}
void loop () {}
Compiling for Uno:
Binary sketch size: 2,312 bytes (of a 32,256 byte maximum)
Case 2 uses "and" and "or":
volatile byte bar;
void setup ()
{
Serial.begin (115200);
bar |= 1;
Serial.println (bar & 1);
}
void loop () {}
Compiled for Uno:
Binary sketch size: 2,302 bytes (of a 32,256 byte maximum)
OK, it saved 8 bytes. But now change Case 1 to be:
struct myByte {
byte foo : 1;
};
volatile myByte bar;
void setup ()
{
Serial.begin (115200);
bar.foo = 1;
Serial.println (bar.foo);
}
void loop () {}
(The bit field "foo" changed from int to byte).
Now I get:
Binary sketch size: 2,198 bytes (of a 32,256 byte maximum)
In this particular case, using the bit-field saved 114 bytes of program memory.
I haven't been doing any Arduino programming lately. I'm not sure if this solves
the particular problem at hand, but it is something I've been using with my PIC24
programs. I moved it over into an Arduino sketch, where it compiles and seems
to work ok. Maybe someone can see if it works in a real Arduino program, maybe
it can be massaged into what the OP wants to do. ???
/*
test_struct sketch
*/
typedef struct {
union {
struct {
unsigned F15:1;
unsigned F14:1;
unsigned F13:1;
unsigned F12:1;
unsigned F11:1;
unsigned F10:1;
unsigned F9:1;
unsigned F8:1;
unsigned F7:1;
unsigned F6:1;
unsigned F5:1;
unsigned F4:1;
unsigned F3:1;
unsigned F2:1;
unsigned F1:1;
unsigned F0:1;
};
struct {
unsigned char hiflags;
unsigned char loflags;
};
};
} GFLAGS;
/**** General Use Flags ****/
GFLAGS SYSflags; // 16-bit flag struct.
#define _FEXIT (SYSflags.F0) // received exit signal.
#define _fECHO (SYSflags.F1) // echo enable flag.
#define _fU1 (SYSflags.F2) // redirect comms to UART1.
#define _fU2 (SYSflags.F3) // redirect comms to UART2.
#define _fRXD1 (SYSflags.F4) // U1 char has been received.
#define _fTXD1 (SYSflags.F5) // U1 char has been sent.
#define _fRXD2 (SYSflags.F6) // U2 char has been received.
#define _fTXD2 (SYSflags.F7) // U2 char has been sent.
#define _fCMDBUG (SYSflags.F15) // cmd debug enable.
void setup()
{
SYSflags.hiflags=0xE0;
_fCMDBUG=1;
}
void loop()
{
}
A few things to consider when using bit fields.
c99 - Bit Fields.
An implementation may allocate any addressable storage unit large enough to hold a bitfield.
If enough space remains, a bit-field that immediately follows another bit-field in a structure shall be packed into adjacent bits of the same unit.
If insufficient space remains, whether a bit-field that does not fit is put into the next unit or overlaps adjacent units is implementation-defined.
The order of allocation of bit-fields within a unit (high-order to low-order or low-order to high-order) is implementation-defined.
The alignment of the addressable storage unit is unspecified.
Also note that the standard says that a "bit-field shall have a type that is a qualified or unqualified
version of int, unsigned int, or signed int", so having a bit-field in a char type is non-standard.
Oh, and nick, the bitfield using 'byte' is non-standard it should be 'unsigned int', the size difference is due to things using the bitfield, not the actual bitfield itself. Try casting foo like: 'Serial.println( ( char ) bar.foo );'
#define pinb 8
#define pinr 9
#define v12pin 11
int dataPin = 2;
int dataPin2 = 5;
int latchPin = 3;
int clockPin = 4;
int LR = 0;
byte bitarray[7];
int bval = 1;
//int b1 = 1;
//int b2 = 256;
#define MaxShiftRegisters 1
#define SpeedCnst 66
#define SubSpeedCnst 66
char YourName[] = "";
void setup()
{
pinMode(dataPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
void loop()
{
MyRider(true); //working
MyRider(false); //working
MyRider(true); //working
MyRider(false); //working
byte RP=random(MaxShiftRegisters)+1;
switch (RP)
{
case 1: for(int n=1; n<10; n++) Pattern1();
case 2: for(int n=1; n<10; n++) Pattern2();
case 3: for(int n=1; n<10; n++) Pattern3();
case 4: for(int n=1; n<10; n++) Pattern4();
}
}
void Pattern1()
{
LR=random(MaxShiftRegisters)+1;
byte bp[4] = {B10000001,B01000010,B00100100,B00011000};
for (int n=0; n<=5; n++)
{
ShiftByteOut(LR,bp[n]);
delay(SubSpeedCnst);
// bitWrite(bp,i2,0);
}
for (int n=4; n>=0; n--)
{
ShiftByteOut(LR,bp[n]);
delay(SubSpeedCnst);
}
}
void Pattern2()
{
LR=random(MaxShiftRegisters)+1;
byte bp[4] = {B11000000,B00110000,B00001100,B00000011};
for (int n=0; n<=5; n++)
{
ShiftByteOut(LR,bp[n]);
delay(SubSpeedCnst);
// bitWrite(bp,i2,0);
}
for (int n=4; n>=0; n--)
{
ShiftByteOut(LR,bp[n]);
delay(SubSpeedCnst);
}
}
void Pattern3()
{
LR=random(MaxShiftRegisters)+1;
byte bp[4] = {B11111111,B00000000,B11111111,B00000000};
for (int n=0; n<=5; n++)
{
ShiftByteOut(LR,bp[n]);
delay(SubSpeedCnst);
// bitWrite(bp,i2,0);
}
for (int n=4; n>=0; n--)
{
ShiftByteOut(LR,bp[n]);
delay(SubSpeedCnst);
}
}
void Pattern4()
{
LR=random(MaxShiftRegisters)+1;
byte bp[4] = {B01010101,B10101010,B01010101,B10101010};
for (int n=0; n<=5; n++)
{
ShiftByteOut(LR,bp[n]);
delay(SubSpeedCnst);
// bitWrite(bp,i2,0);
}
for (int n=4; n>=0; n--)
{
ShiftByteOut(LR,bp[n]);
delay(SubSpeedCnst);
}
}
void ShiftByteOut(byte chip, byte b)
{
byte bp = B00000000;
byte bp2 = B00000000;
digitalWrite(latchPin, LOW);
for(byte n2=0; n2<MaxShiftRegisters+1; n2++)
{
if (chip==n2)
shiftOut(dataPin, clockPin, MSBFIRST, b);
else
shiftOut(dataPin, clockPin, MSBFIRST, bp2);
}
digitalWrite(latchPin, HIGH);
}
void MyRider(boolean up)
{
byte bp = B00000000;
byte bp2 = B00000000;
// LR=random(3)+1; //random 74hc595 chip
LR++;
if (LR>3)
LR=1;
if (up==true)
for (int i2=0; i2<=7; i2++)
{
bitWrite(bp,i2,1);
ShiftByteOut(LR,bp);
delay(SpeedCnst);
bitWrite(bp,i2,0);
}
if (up==false)
for (int i2=7; i2<=0; i2++)
{
bitWrite(bp,i2,1);
ShiftByteOut(LR,bp);
delay(SpeedCnst);
bitWrite(bp,i2,0);
}
}
void BinaryKnightRider(boolean up)
{
byte wclear = 0;
int b1 = 1; //original
int b2 = 256; //original value 256
if (up==true)
{
while (b1<177)
{
digitalWrite(latchPin, LOW);
// Send the value as a binary sequence to the module
// shiftOut(dataPin, clockPin, MSBFIRST, wclear);
shiftOut(dataPin, clockPin, MSBFIRST, b1);
shiftOut(dataPin, clockPin, MSBFIRST, b2);
// shiftOut(dataPin, clockPin, MSBFIRST, wclear);
// Enable the latch again to set the output states
digitalWrite(latchPin, HIGH);
delay(SpeedCnst);
b2 = b2 >> 1;
b1 = b1 << 1;
// b2--;
// b1++;
}
}
if (up==false)
{
b2=256;
//b2=256; //original value 256
b1=1;
// b1=1; //original
while (b2>0)
{
digitalWrite(latchPin, LOW);
// Send the value as a binary sequence to the module
shiftOut(dataPin, clockPin, MSBFIRST, b2);
// shiftOut(dataPin, clockPin, MSBFIRST, wclear);
shiftOut(dataPin, clockPin, MSBFIRST, b1);
// shiftOut(dataPin, clockPin, MSBFIRST, wclear);
// Enable the latch again to set the output states
digitalWrite(latchPin, HIGH);
delay(SpeedCnst);
// b2--;
// b1++;
b2 = b2 >> 1;
b1 = b1 << 1;
}
}
}
void Clear()
{
digitalWrite(latchPin, LOW);
// Send the value as a binary sequence to the module
shiftOut(dataPin, clockPin, MSBFIRST, 0);
// Enable the latch again to set the output states
digitalWrite(latchPin, HIGH);
}
void DisplayName()
{
char c;
int i = 0;
c=YourName[i];
while(c!='\0')
{
// Disable the latch while we clock in data
digitalWrite(latchPin, LOW);
// Send the value as a binary sequence to the module
shiftOut(dataPin, clockPin, MSBFIRST, c);
// Enable the latch again to set the output states
digitalWrite(latchPin, HIGH);
delay(SpeedCnst);
i++;
c=YourName[i];
}
}
void BinaryCountUp()
{
int currentValue = 1;
while (currentValue<=255)
{
// Disable the latch while we clock in data
digitalWrite(latchPin, LOW);
// Send the value as a binary sequence to the module
shiftOut(dataPin, clockPin, MSBFIRST, currentValue);
// Enable the latch again to set the output states
digitalWrite(latchPin, HIGH);
delay(SpeedCnst);
currentValue = currentValue << 1 ;
}
}
void BinaryC3()
{
int currentValue = 1;
int currentValue2 = 255;
// int bval = B10101010;
// int bval2 = B11110000;
while (currentValue<=255)
{
// Disable the latch while we clock in data
digitalWrite(latchPin, LOW);
// Send the value as a binary sequence to the module
shiftOut(dataPin, clockPin, MSBFIRST, currentValue2);
shiftOut(dataPin, clockPin, MSBFIRST, currentValue);
// Enable the latch again to set the output states
digitalWrite(latchPin, HIGH);
// digitalWrite(latchPin, LOW);
// shiftOut(dataPin2, clockPin, MSBFIRST, currentValue2);
// digitalWrite(latchPin, HIGH);
delay(SpeedCnst);
currentValue++;
// currentValue2--;
}
}
void BinaryCR()
{
int currentValue = 255;
while (currentValue>=1)
{
// Disable the latch while we clock in data
digitalWrite(latchPin, LOW);
// Send the value as a binary sequence to the module
shiftOut(dataPin, clockPin, MSBFIRST, currentValue);
// Enable the latch again to set the output states
digitalWrite(latchPin, HIGH);
delay(SpeedCnst);
currentValue = currentValue >> 1 ;
}
}
void BinaryCR2()
{
int currentValue = 255;
while (currentValue>=1)
{
// Disable the latch while we clock in data
digitalWrite(latchPin, LOW);
// Send the value as a binary sequence to the module
shiftOut(dataPin, clockPin, LSBFIRST, currentValue);
// Enable the latch again to set the output states
digitalWrite(latchPin, HIGH);
delay(SpeedCnst);
currentValue = currentValue >> 1 ;
}
}
this is my code playing with 3 74HC595N registers.
this is the way i got around the "bit" issue.
pYro_65:
Also note that the standard says that a "bit-field shall have a type that is a qualified or unqualified
version of int, unsigned int, or signed int", so having a bit-field in a char type is non-standard.Oh, and nick, the bitfield using 'byte' is non-standard it should be 'unsigned int', the size difference is due to things using the bitfield, not the actual bitfield itself. Try casting foo like: 'Serial.println( ( char ) bar.foo );'
Agreed and confirmed.