Go Down

Topic: BitBool Class ( boolean array ), upto 16000 elements on UNO. (Read 2035 times) previous topic - next topic

pYro_65

Oct 22, 2012, 01:21 am Last Edit: Apr 25, 2014, 01:47 pm by pYro_65 Reason: 1
This is a small class designed to lower SRAM usage for bool arrays. Values can be inspected or assigned using standard array sub-script operators ( '[]' ), the code below is the library, and underneath that is a sample sketch of generic array usage, it contains a #define called USE_STANDARD_BOOL which if uncommented will use a standard bool array, otherwise a BitBool array is used. The internal data is accessible allowing manipulation of bits and bytes.

Some usages may be: large sets of bool flags, LED patterns/shift data.

This is only a basic implementation, if anybody has a need for some form of shifting / conversion /any other mod, please post your ideas.

BitBool.h
Code: [Select]
#ifndef HEADER_BITBOOL
 #define HEADER_BITBOOL
 #include "Arduino.h"

  template< size_t _Count, bool _Reverse = false >
    class BitBool{
      protected:
        struct BitRef{
       
          BitRef( uint8_t &u_DataRef, const uint8_t u_Idx ) : u_Data( u_DataRef ), u_Index( _Reverse ? ( 0x80 >> u_Idx ) : ( 0x1 << u_Idx ) ) { return; }

          operator const bool() const { return this->u_Data & this->u_Index; }
         
          const bool operator =( const BitRef &b_Copy ) const { return *this = ( const bool ) b_Copy; }

          const bool operator =( const bool &b_Copy ) const
            {
              if( b_Copy )  this->u_Data |= this->u_Index;
              else          this->u_Data &= ~this->u_Index;
              return b_Copy;
            }     
           
          uint8_t &u_Data;
          uint8_t const u_Index;
        }; 
      public:
        enum{ BitCount = _Count, ByteCount = ( BitCount / 0x8 ) + ( ( BitCount % 0x8 ) ? 0x1 : 0x0 ) };

        BitRef operator []( const uint16_t i_Index ) { return BitRef( this->Data[ i_Index >> 0x3 ], i_Index & 0x7 ); } 
        uint8_t Data[ ByteCount ];
  };
#endif


Sketch
Code: [Select]
//#define USE_STANDARD_BOOL
#define MAX_ITEMS 100

#include <BitBool.h> //use "BitBool.h" if file is local, or remove include and copy class directly in.

#ifdef USE_STANDARD_BOOL
 bool b_Array[ MAX_ITEMS ] = { true, true, true };
#else
 BitBool< MAX_ITEMS > b_Array = { B00000111 };
#endif

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

void loop()
 {
   bool b_TempCopy = b_Array[ MAX_ITEMS - 1 ];
   
   //Roll items up.
   for( int i_Index = MAX_ITEMS - 1 ; i_Index ; --i_Index )
     b_Array[ i_Index ] = b_Array[ i_Index - 1 ];
   b_Array[ 0 ] = b_TempCopy;
   
   //Show contents.
   Serial.print('[');
   for( int i_Index = 0 ; i_Index < MAX_ITEMS ; ++i_Index )
     Serial.print( b_Array[ i_Index ] ? '#' : '-' );
   Serial.print("]\r\n");
 }


Cheers

Coding Badly

[font=Courier New]
         BitRef( uint8_t &u_DataRef, const uint8_t u_Idx ) : u_Data( u_DataRef ), u_Index( 0x1 << u_Idx ) { return; }
[/font]

[font=Courier New]
       byte b_Data[ ( _Count / 0x8 ) + ( ( _Count % 0x8 ) ? 0x1 : 0x0 ) ];
[/font]


Different data-types?

Coding Badly


For what it's worth, I prefer something that looks more like rounding...

[font=Courier New]
        byte b_Data[ ( (_Count + 0x7) / 0x8 ) ];
[/font]

Coding Badly

Code: [Select]
...
#else
 BitBool< MAX_ITEMS > b_Array; = { B00000111 };
#endif
...


Quote
Topic_128407:8: error: braces around initializer for non-aggregate type 'BitBool<100u>'


...which compiler version are you using?

pYro_65

#4
Oct 22, 2012, 10:12 am Last Edit: Oct 22, 2012, 10:27 am by pYro_65 Reason: 1
I agree that the names should match, I have extracted this from a larger library I plan to release once the Due is here, so artifacts have crept in. Also I assume you do already know 'byte' is simply an alias for uint8_t.

And as far as sizing the types, its done in compile time, and I don't believe your method is any more intuitive. I have my own style of writing expressions, I think it is  more of a personal preference thing.

I'll edit the code in a sec, another artifact... done.

b_Data cannot be private.
Original code is fixed now.

Oh and I'm using the Arduino IDE, nothing special ( not relevant now as it was my code error ), thanks for the find.

robtillaart


16000 elements ??

Have you tried your class in PROGMEM?  You could have a really big bitarray - although readonly,  e.g. 25KB ==> 200.000 fixed booleans.

What to do with it?
- for games a fixed bit array (2 dimensional) could hold a playing field e.g. think minesweeper
- a spelling checker (Bentley in Programming pearls), that used a hash function that mapped strings on a bool array. Every bit indicated right or wrong.
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

pYro_65

Hmmm, I'm not sure, I'll have to do some investigation on making it compatible, but as it stands I don't think it would work, needs a way to retrieve the data.

You have given me some more ideas anyway. I also have a class for dealing with PROGMEM types which may be better for this type of thing.

Go Up