Meaning of "if ((PINB & _BV(BUTTON_PIN)) == 0) {"

I am trying to understand the following project: blog/main.c at master · lpodkalicki/blog · GitHub.

With respect to

if ((PINB & _BV(BUTTON_PIN)) == 0) {

a && is AND so what is a single &, also what does the _ mean?

Is it saying something like, "if (PINB and Button) pressed then ......."?

&&
&

&& is boolean AND. It adds more elements to a test for true/false so you can say

if (this == true && that == true)
  {
     //execute code here if both are true
  }

& is bitwise AND and is used to compare individual bits so you can say

byte a = 0b00000001;
byte b = 0b00000001;
byte c = 0b00000010;
byte d = a & b;  //the result is 0b00000001 because both have a 1 in bit 0
byte e = a & c;  //the result is 0b00000000  because no bits have 1 in both

The _ has no meaning. It is part of the name of a defined value and is used to help prevent the same name being used as a variable or #defined value by a user in a sketch. The _BV macro is defined as part of the Arduino system and returns a value with the single bit set by the value supplied

You may be interested to try this

void setup()
{
  Serial.begin(115200);
  while (!Serial);
  for (byte x = 0; x < 8; x++ )
  {
    printFullBin(_BV(x));
  }
}

void loop()
{
}

void printFullBin(byte value)
{
  for (int bit = 7; bit > 0; bit--)
  {
    Serial.print(bitRead(value, bit));
  }
  Serial.println();
}

Many thanks for that explanation.

I might battle to discribe what I am trying to achieve but here goes.

I am wanting to take blog/main.c at master · lpodkalicki/blog · GitHub. and modify it so that instead of activating the timer when a button is pressed, the timer is activated by a cetain analogRead value.

As a result of some googling, I have added the following code in order to set button pin to an analogue input

/* ADDED */
int analogData;       //declare analogData variable
/* */

And in at the top of timer_init

/* ADDED */
  ADMUX |= (1 << REFS0);   //use internal reference voltage of 1.1V (https://www.instructables.com/id/ATTiny-Port-Manipulation-Part-2-AnalogRead/)
  ADMUX |= (1 << MUX0);   //combined with next line…
  ADMUX |= (0 << MUX1);   //sets ADC2 as analog input channel
  ADMUX |= (1 << ADLAR);   //Left Adjust the ADCH and ADCL registers; 8 bit resolution

  ADCSRA = 0b10000011;  //turn on ADC, keep ADC single conversion mode,
  //and set division factor-8 for 125kHz ADC clock
  ADCSRA = 0b10000011;  //turn on the ADC, keep ADC single conversion mode
  //set division factor-8 for 125kHz ADC clock
/* */

I am not sure if I have applied the above correctly or if it contraticts some of the code later on.

If the above is correct then i am not sure how to alter the following code in timer_process

  if ((PINB & _BV(BUTTON_PIN)) ==0) {
    _delay_ms(10); // time for debounce
    while ((PINB & _BV(BUTTON_PIN)) ==0);

So that instead of checking for a button being pressed that it triggers when a particualr value or value range is read. I am wanting to do this using Port Manipulation as I am trying to get my code to fit on an ATTiny13.

I missed that I need the following:

  ADCSRA |= (1 << ADSC);         //start conversion
           analogData = ADCH;             //store data in analogData vari

I am guessing that I then change the following code

  if ((PINB & _BV(BUTTON_PIN)) == 0) {
    _delay_ms(10); // time for debounce
    while ((PINB & _BV(BUTTON_PIN)) == 0);

to something like

  if (analogdata >= "some desired value") {
    _delay_ms(10); // time for debounce
    while (analogdata >= "some desired value");