Define name and access bits of a byte

Hi, I have searched for an answer to this (apparently) simple question on Google and Arduino so I am hoping that someone can explain how to do an assignment of bits either by structure or union and how to access / manipulate them.
I am simply trying to assign bits of a byte to use as a flag indicator to remember is a function was on or off when a subroutine is called.
I have stripped the code just to the bones as I keep getting out of scope errors in my current program. I have this little bit of code which I would like to use:

  struct {
    uint8_t  _0 : 1; // bit position 0
    uint8_t  _1 : 1; // bit position 1
    uint8_t  _2 : 1; // bit position 2
    uint8_t  _3 : 1; // bit position 3
    uint8_t  _4 : 1; // bit position 4
    uint8_t  _5 : 1; // bit position 5
    uint8_t  _6 : 1; // bit position 6
    uint8_t  _7 : 1; // bit position 7
    // total # of bits just needs to add up to the uint8_t size
  } flagss;




 uint8_t i;


      
void setup() {
  // put your setup code here, to run once:

flagss == 0;
flagss._0 = true;
flagss._1 = true;
}

I used flagss in case flags is a reserved word by the way.
The first line of set up throws an error:
"sketch_dec21a:25:8: error: no match for 'operator==' (operand types are '' and 'int')
flagss == 0;

exit status 1
no match for 'operator==' (operand types are '<unnamed struct>' and 'int')"

I have tried a simple = sign same error type , but more errors generated:

"C:\Users\US6233\Documents\Arduino\sketch_dec21a\sketch_dec21a.ino: In function 'void setup()':

sketch_dec21a:25:10: error: no match for 'operator=' (operand types are '<unnamed struct>' and 'int')
flagss = 0;
^
C:\Users\US6233\Documents\Arduino\sketch_dec21a\sketch_dec21a.ino:3:10: note: candidate: <unnamed struct>&<unnamed struct>::operator=(const<unnamed struct>&)

struct {

^
C:\Users\US6233\Documents\Arduino\sketch_dec21a\sketch_dec21a.ino:3:10: note: no known conversion for argument 1 from 'int' to 'const<unnamed struct>&'

C:\Users\US6233\Documents\Arduino\sketch_dec21a\sketch_dec21a.ino:3:10: note: candidate: <unnamed struct>&<unnamed struct>::operator=(<unnamed struct>&&)

C:\Users\US6233\Documents\Arduino\sketch_dec21a\sketch_dec21a.ino:3:10: note: no known conversion for argument 1 from 'int' to '<unnamed struct>&&'

exit status 1"

no match for 'operator=' (operand types are '<unnamed struct>' and 'int')
If that line flagss == 0; or flagss = 0; is commented out it complies fine.
Is there a way to clear the whole byte flagss in one instruction, or do I need to explicitly clear or set required bits at run time?
Is there another way to declare this apparently simple variable?
flagss == 0;

I don't know what you're trying do, with a comparison, but not doing anything with the result.

why not simple treat the variable bitwise?

Or if you want to use something Arduino like:

The old-fashioned way to treat a byte as both a byte and as a struct of bit fields is to use a 'union':

union
{
  struct
  {
    uint8_t  _0 : 1; // bit position 0
    uint8_t  _1 : 1; // bit position 1
    uint8_t  _2 : 1; // bit position 2
    uint8_t  _3 : 1; // bit position 3
    uint8_t  _4 : 1; // bit position 4
    uint8_t  _5 : 1; // bit position 5
    uint8_t  _6 : 1; // bit position 6
    uint8_t  _7 : 1; // bit position 7
    // total # of bits just needs to add up to the uint8_t size
  } flagss;
  byte b;
} val;


uint8_t i;


void setup()
{
  Serial.begin(115200);


  val.b = 0;
  val.flagss._0 = true;
  val.flagss._3 = true;
  Serial.println(val.b, BIN);
}
void loop() {}

The new-fashioned way would be to add operator definitions to the struct, like you would for a class. Define what bit goes where when the struct is on the left side and an integer type is on the right side. Similarly, define what value to use when the struct is converted to an integer type.

Thank you all for those responses.

I had tried the union and struct way but obviously not correctly. Thanks to johnwasser, I understand the old fashioned way now and it works for me. It also makes sense to someone who has used basic for many years.

I have no idea how to do it with classes , but any pointers (no pun intended) would be really helpful as I am trying to write some re-useable libraries and I just don't get classes.

I get my projects to work fine with tabs but as soon as I extract then to a cpp/header file it all goes pear shaped.
I really only want to simplify my code to make it more readable and more maintainable but the general suggestion seems to be to make re-usable libraries.
Does a library need to use classes to achieve this, or can headers and cpp files exist virtually as extracted files from the ino tabs?

To my (simple C++ deficient) mind classes appear to add a much greater layer of files/complications. The way to implement interactions between the main program and classes escapes me and usually I get "not declared in this scope" errors. At this point I tend to give up, but with a bit of time on my hands I would like to progress this further, if only to get a handle on expanding my knowledge of the subject.

Is there a simple, explained example around that could be used with this code to turn it into a library. The classic MORSE example works fine, but how to turn what I have here into a useable class is beyond me at the moment. Any help would be appreciated.

//Demonstrates calls to functions with return value
//-------------------------------------------------------------------------------------------

#include "vars.h"                             //global vars shifted to header file  "vars.h"

//Does not work if these are put in a tab!  #include "vars.ino" no longer works (if it ever did).
//Only way to have Globals visible to all tabs in project is with header file as above or all vars in main project tab as they were before moving.
//Handy to be able to move in a long program with lots of variables for better readability.

//setup vars for this test Global vars visible to all program.
//  uint8_t Ckstr[3]= {"STI"};  
//  uint8_t DV1 = 0x1F;
//  uint8_t DV2 = 0x0A;
//  uint8_t CKSM;
//  const uint8_t addr = 0x01;


//----------------------------------------------------------------------------------------------

void setup()
{                                             // sets up required things  
  pinMode(LED_BUILTIN, OUTPUT);              // tells arduiono to use builtin LED
  Serial.begin(9600);                         // starts the serial tx,rx at 9600
  delay(500);                                //let Uart Settle
  while (!Serial);                            // loop that can be used to catch a fault with the serial 
  Serial.println();                           //starts on new line
  Serial.print("starting now.");
}
//-------------------------------------------------------------------------------------------------------------

// This function moved to tab "checksum". Works fine this way
//uint8_t getCksum()     // returns value of CKSM 
//{
// int summ = 0;      //all 3 vars private to this function
// int nums = 0;
// byte i;
//   for (i=0; i < 3; i++){
//     summ = (summ + byte(Ckstr[i]));
//   }                                     
//   nums = (summ + DV1 + DV2 + addr); 
//   CKSM = (nums%256);
//   return CKSM;
//} 

void loop()
//Simply writes LED high, gets checksum, prints information to Serial then port waits 250mS,
//then writes LED low for 250mS and loops forever.
{
  digitalWrite(LED_BUILTIN, HIGH); 
  getCksum();         //calls function from "checksum" tab
  
  Serial.println();   //starts new line
  Serial.print(addr,HEX);
  Serial.print(": ");    
  for (byte i = 0; i < 3; i++)
    {
       Serial.print(char(Ckstr[i]),HEX);
       Serial.print(": ");
    }
    Serial.print(DV1,HEX);
    Serial.print(": ");    
    Serial.print(DV2,HEX);
    Serial.print(": "); 
    Serial.print(CKSM,HEX);
    
    Serial.println();   //starts new line 
  delay(250);
  digitalWrite(LED_BUILTIN, LOW); 
  delay(250);
}

ino file for sketch

#ifndef VARS_H     //guard for header
#define VARS_H

#include <Arduino.h>                     //maybe needed for any header files????

//Variables for test sketch

  uint8_t Ckstr[3]= {"STI"};  
  uint8_t DV1 = 0x1F;
  uint8_t DV2 = 0x0A;
  uint8_t CKSM;
  const uint8_t addr = 0x01;

  #endif  //VARS_H

Header file Global Vars

//cpp file with function defined


#include "checksum.h"  //refers to header

Checks:: Checks uint8_t (getCksum())     // return value of CKSM is unsigned byte
 
{
 int summ = 0;      //all 3 vars private to this function
 int nums = 0;
 byte i;
   for (i=0; i < 3; i++){
     summ = (summ + byte(Ckstr[i]));
   }                                     
   nums = (summ + DV1 + DV2 + addr); 
   CKSM = (nums%256);
   return CKSM;
};

My attempt at a cpp file

// defines functions in cpp file
#ifndef CHECKSUM_H     //guard for header
#define CHECKSUM_H
#include "vars.h"
#include <Arduino.h>

class Checks
{
 public:
  //byte rval;
  byte getChecksum();


};

#endif //CHECKSUM_H

My attempt at an associated header file.
Needless to say it is rubbish!
If the getChecksum() function part is in a tab, (no header or cpp) it is fine.
Any advice (apart from get back to VB)!

To my (simple C++ deficient) mind classes appear to add a much greater layer of files/complications.

It depends on the project complexity. A very complex project usually requires the construction of a system of interrelated data and code that transcends the simple procedural tools available in C. Before OO, programmers had to implement a lot of class-like behaviour manually, that is now possible to express literally in C++.

So for a very simple program, it's easier to code in basic C. But as soon as the complexity grows, the limitations of the language begin to engage, and some kind of "meta programming" is necessary. You can do it yourself, or let OO do it for you.

Dangerous2A:
I am simply trying to assign bits of a byte to use as a flag indicator to remember is a function was on or off when a subroutine is called.

Unless you are short of memory wouldn't it be a lot simpler to use an array of 8 bytes rather than trying to figure out individual bits?

...R

I didn't see it named so maybe you're looking for bit fields?

dougp:
I didn't see it named so maybe you're looking for bit fields?

They didn't use the name but that's what they tried originally. It didn't do what they wanted (to be able to reference the variable as a byte or as individual bits).

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.