text:
Using Internal Timer Interrupt to Read Analog Sensor
I'm having difficultly using an internal timer interrupt with my Arduino Nano to properly capture a specific value from a linear potentiometer and then instantly stopping the actuator.
I basically have the wiper of a linear potentiometer connected to the end of a linear actuator.  The actuator extends/retracts via a L298N module being controlled by a Nano.  From where its positioned, the potentiometer reads around "80" when the actuator is fully extended, and around "25" when fully retracted.  I'm entering numbers via the serial monitor to prompt the actuator to move up or down, these numbers are being stored in the Nano's EEPROM.
My interrupt seems not to work while the actuator is in motion.  For example, if I set the interrupt to stop the motor when the potentiometer reads "50", it just skips past this number without stopping the actuator.  But if I set the interrupt to stop the motor when the potentiometer reads the minimum or maximum (where the actuator is currently located before activation), the actuator correctly doesn't extract or retract.  I would think my interrupt is fast enough at 8Khz, so I feel there is something else prohibiting the actuator from stopping at a specific value between the max and min.
The my current code is below, any help would be much appreciated.
    //timer2 will interrupt at 8kHz

    #include <EEPROM.h>
    #define EEPROM_SIZE

    long number;
    long x;

    int toggle=0;
    int old_x=0;

    const int linPot = A1;

    int MotorSpeed=255;

    int enA = 9;
    int in1 = 8;
    int in2 = 7;

    int currentPosition;

    enum {IdleState, UpState, DownState} State;

    void setup(){

      Serial.begin(9600);

      number = EEPROM.read(0);

      x=number;

      pinMode(enA, OUTPUT);
      pinMode(in1, OUTPUT);
      pinMode(in2, OUTPUT);

      State = IdleState;

    //cli();//stop interrupts

    //set timer2 interrupt at 8kHz
      TCCR2A = 0;// set entire TCCR2A register to 0
      TCCR2B = 0;// same for TCCR2B
      TCNT2  = 0;//initialize counter value to 0
      // set compare match register for 8khz increments
      OCR2A = 249;// = (16*10^6) / (8000*8) - 1 (must be <256)
      // turn on CTC mode
      TCCR2A |= (1 << WGM21);
      // Set CS21 bit for 8 prescaler
      TCCR2B |= (1 << CS21);
      // enable timer compare interrupt
      TIMSK2 |= (1 << OCIE2A);

    sei();//allow interrupts

    }//end setup

    ISR(TIMER2_COMPA_vect){//timer1 interrupt 8kHz
    //generates pulse wave of frequency 8kHz/2 = 4kHz

    if(currentPosition==50){

      HALT();

    }

    }

    void loop(){

    if ((Serial.available()&&toggle==0)){

            x=Serial.parseInt();
            old_x=x;
            toggle=1;
          }

          if((Serial.available())&&(toggle==1)&&(Serial.parseInt()!=old_x)){
              toggle=0;
          }

            if((toggle==1)&&(Serial.parseInt()==0)){
              toggle=0;
          }

          if(x>78){
            x=78;
          }

           if(x<0){
            x=0;
          }

        EEPROM.write(0, x);
        Serial.print("X :");
        Serial.println(x);

        int data = analogRead(linPot);
        currentPosition = map(data, 0, 1023, 0, 100);
        Serial.print("Potentiometer at ");
        Serial.print(currentPosition);
        Serial.println("%");

        long difference = currentPosition-x;
        Serial.print("Difference :");
        Serial.println(difference);

    if(difference>0){

        State = UpState;

    }

    if(difference>0){

       State = DownState;
    }

    if(difference==0){

       State = IdleState;
    }

     switch (State) {

                   case IdleState:
                   Serial.println("Idle State");
                    HALT();
                    if((currentPosition-number)<0){
                     State = UpState;
                    }
                    if((currentPosition-number)>0){
                     State = DownState;
                    }
                    break;

                  case UpState:
                  Serial.println("Up State");
                    //Need to move down
                    DOWN();
                    if((currentPosition-number)>0){
                     State = DownState;
                    }
                    if((currentPosition-number)==0){
                     State = IdleState;
                    }
                    break;

                  case DownState:
                  Serial.println("Down State");
                    //Need to move up
                    UP();
                    if((currentPosition-number)<0){
                     State = UpState;
                    }
                    if((currentPosition-number)==0){
                     State = IdleState;
                    }
                    break;

     }

    }

    void DOWN(){
        analogWrite(enA, MotorSpeed);
        digitalWrite(in1, HIGH);
        digitalWrite(in2, LOW);
      }

    void UP() {
        analogWrite(enA, MotorSpeed);
        digitalWrite(in1, LOW);
        digitalWrite(in2, HIGH);

      }

    void HALT () {
        digitalWrite(in1, LOW);
        digitalWrite(in2, LOW);
    }

how is the potentiometer connected? ... please add a wiring diagram to your question

why are you trying to use an interrupt on a snail-pace event? ... just monitor the potentiometer inside the loop() block

Given that currentPosition is updated in loop(), possibly at a very slow pace (as Serial.parseInt() can block for up to a whole second), it makes no sense to fire an interrupt just to test its value.

I initially tried monitoring the position within the void loop and that didn't work either.  I need the actuator to stop when the  potentiometer hits a specific value which I haven't determined yet (so right now I'm just trying to get the code to stop at random value I choose).   I connected a button to D2 in order to have an external interrupt, which stopped the actuator whenever the button was pressed.  So if an external interrupt had no problem with the Serial.parseInt(), shouldn't the internal interrupt behave the same?

Maybe use Direct Port Manipulation for faster GPIO operations? That would be faster than digitalWrite() and digitalRead()

First, read Nick Gammon's answer: all his points are perfectly valid. He
notes that the serial prints can be quite slow. And indeed, as I counted
the characters, I find that the prints should take at least 54 ms
per loop iteration. This is really very slow. In addition to this, the
calls to parseInt() can be much slower yet, especially considering
that one of them is not conditioned on Serial.available().
Currently, the code that takes care of reading the potentiometer and
stopping the actuator looks like this:
int currentPosition;

// Triggered every 125 µs.
ISR(TIMER2_COMPA_vect) {
    if (currentPosition == 50) HALT();
}

void loop() {
    // Potentially extremely slow code...
    currentPosition = map(analogRead(linPot), 0, 1023, 0, 100);
    // Definitely very slow code: takes at least 54 ms.
}

This is reading the potentiometer at best every 54 ms, and
potentially much more slowly. On every read, currentPosition is
updated. In parallel, the value of currentPosition is being tested
every 125 µs.
Note that there is really no point in testing currentPosition that
often. Once the value has been tested, testing it again before it is
updated serves no purpose. Your code would actually be a tiny bit faster
if you test the value right after updating it:
void loop() {
    // Potentially extremely slow code...
    currentPosition = map(analogRead(linPot), 0, 1023, 0, 100);
    if (currentPosition >= 50) HALT();
    // Definitely very slow code: takes at least 54 ms.
}

Note that I changed the equality test to an inequality test, for a
reason explained in Nick Gammon's answer.
You still have the problem that the loop is very slow. If you want the
potentiometer to be tested more frequently, you have several options.

The bad option: do it in the interrupt handler:
// Triggered every 125 µs.
ISR(TIMER2_COMPA_vect) {
    currentPosition = map(analogRead(linPot), 0, 1023, 0, 100);
    if (currentPosition >= 50) HALT();
}

This is a bad option because analogRead() takes at least
112 µs, which means that the ISR will eat 98.6% of the CPU
cycles. You could make this work kind of reasonably if you lower the
interrupt frequency to something like 1 kHz or below. Still,
such a long ISR is not really good practice.

The better option: make loop non-blocking:
void loop() {
    // Non-blocking, very fast code.
    currentPosition = map(analogRead(linPot), 0, 1023, 0, 100);
    if (currentPosition >= 50) HALT();
    // More very fast code.
}

To read the serial port in a non-blocking way, see Reading Serial on
the Arduino. For writing to the serial port in a
non-blocking way, simply refrain to print very frequently.

The hard option: configure the ADC to read continuously.
You can program the ADC in “self-running mode”: it will then take a
reading every 104 µs. You can program it to also deliver an
interrupt every time a new reading is available: you can test the
reading in this interrupt handler. This will give you the best
possible response time:
void setup() {
    // Set the ADC to free running mode.
    // Enable the ADC interrupt.
}

volatile int raw_adc_reading;

// Triggered on every fresh ADC reading.
ISR(ADC_vect) {
    raw_adc_reading = ADC;
    if (raw_adc_reading >= RAW_THRESHOLD) STOP();
}

Note that I prefer to test the raw reading rather than the converted
one. This is because map() is slow (it involves a long division)
and an ISR should ideally be as fast as possible.
You will have to dig into the MCU datasheet to learn how to configure
the ADC in free running mode.

For one thing, currentPosition is not declared volatile so the compiler may be keeping that value in a register, which is not consulted inside the ISR.
I'm also concerned about all the serial prints at 9600 baud (quite slow) which may make the position skip from 49 to 51 while you are busy printing values.
Comparing to be exactly equal in order to do something is always fraught.

   x=Serial.parseInt();
    old_x=x;
    toggle=1;
  }

  if((Serial.available())&&(toggle==1)&&(Serial.parseInt()!=old_x)){
      toggle=0;
  }

    if((toggle==1)&&(Serial.parseInt()==0)){
      toggle=0;
  }

Are you expecting three integers from serial?


text:
Voltage increasing when charging a battery using arduino
I am making a solar charge controller using Arduino. So for starting, I thought I should calibrate the voltage so that I am able to read the exact voltage of battery and solar charger. For testing purposes, I do not have any solar panel, so I used a 12V power supply and set its output voltage to 13.56. I used the following calculations for getting exact voltage:
float solarData = 0;
float batData = 0;
float batScale = 0;
float solarScale = 0;
float batPinVolt = 0;
float solPinVolt = 0;
float batVolt = 0;
float solVolt = 0;

Vcc = readVcc()/1000.00;    //getting the exact voltage of arduino
Serial.print(Vcc);
solarScale = analogRead(A0);  //reading solar analog data
batScale = analogRead(A1);    //reading battery analog data
solPinVolt = (solarScale/1024.0) * Vcc;
solVolt = solPinVolt * (9.80 + 2.168)/2.168;    //I used 10k & 2.2k so entered their exact value
batPinVolt = (batScale/1024.0) * Vcc;
batVolt = batPinVolt * (9.80 + 2.168)/2.168;

Initially, I faced few problem regarding the exact voltage of the Arduino which I used as a reference voltage to calculate voltage. But then I found a solution here. So below is the code which calculate the voltage of Arduino
long readVcc()
{
  long result;
  // Read 1.1V reference against AVcc
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA,ADSC));
  result = ADCL;
  result |= ADCH<<8;
  result = 1125300L / result; // Back-calculate AVcc in mV
  return result;
 }

Now when I uploaded the code, I got the exact values of the voltages.
Now I wrote a logic where if the battery voltage is less than 12V then start charging until it is above 13V. Following is the code:
if((solVolt > batVolt)&& ( batVolt <= 12.00 ))
{
digitalWrite(chargePin,HIGH);  //enable charging
digitalWrite(loadPin,LOW);     //load off
}
else if((solVolt > batVolt)&&(batVolt > 12.00)&& (batVolt <= 13.00 ))
{
 digitalWrite(chargePin,HIGH);   //enable chargin
 digitalWrite(loadPin,LOW);      //load off
}
// // shut down when battery is fully charged or when sunlight is not enough
else if ((batVolt > 13.00) or (solVolt < batVolt))
{
 digitalWrite(chargePin,LOW);    //disable charging
 digitalWrite(loadPin,HIGH);     //load on
}

But when I uploaded the code, the Arduino started showing wrong values of the voltages. Power supply was set to 13.5, but it showed 13.15 and battery voltage was 11.8, but it showed 12.7.
Now due to this what exactly happened was it started charging so the value of battery voltage 12.7 (which is wrong) started increasing. When it was above 13V, Arduino turned off the chargePin. So when the chargePin is low, it shows the exact battery voltage which is low so it again started charging it and this loop keeps on going. This is all because of the wrong values of voltages. Following is the schematic:

I am following the article I found on Instructables. (cannot post more links due to reputation). I want to know why there is change in voltage. Can anyone please help me on what I am doing wrong.

And now you know why you need to stop charging when reading the voltage.

@IgnacioVazquez-Abrams I am trying to stop the charging by setting the chargePin to low which will turn off the transistor. But when the charging stops it shows the exact value of battery voltage which is lower than what arduino shows. So it again charging it rather than cut off. I want to know why it shows wrong values.

What tolerance are the resistors in the voltage divider?

What are those variable data types? Float?

@IgnacioVazquez-Abrams Resistor values are R1=10k R2=2.2k.

@NickGammon Yes all the variables are float. I have edited the code

Not the values, the tolerance.

@IgnacioVazquez-Abrams I guess the tolerance is 10% as the last color in the resistor is silver.

Now that you know the tolerance you can figure out just how terrible your voltage divider is.

@IgnacioVazquez-Abrams yes you are right. I never thought about this. So I should use resistance with 1% or 2% tolerance which might give correct values. Am I right.?

You need to use resistors with equal or better tolerance than the voltage you need to maintain. You also need to determine the exact value of the bandgap reference in the chip itself.

@IgnacioVazquez-Abrams I didnt get you by bandgap reference. Please explain.

There may be a voltage drop acros the wires (and fuse) running to and from the battery. One solution to this is to have separate wires going directly to the battery for measuring the voltage.

In order to charge a battery you have to apply a voltage to the battery terminals that is higher than the batteries own internal voltage. That's pretty much the definition of charging a battery.
Basically you're trying to do the impossible, you can't measure the batteries off charge voltage while charging it because as soon as you start charging the voltage at that point changes.
When charging your supply is 3.5V and your supply measurement is 13.15. That means you're loosing 0.35V in battery cables and F1.
The battery voltage is 12.7V so that's 0.45V loss in D1 and Q1.
That first loss seems too high and the second one too low, D1 should drop typically drop 0.58V, so you may have some resistor tolerance or noisy reading issues. The total voltage drop seems reasonable but the split looks wrong.
The best solution to what your are trying to do is to measure the charge current.
Move D1 to the other side of R1 so there is no diode drop between your two voltage measurements and add a small resistor in series where D1 used to be. The difference between the two measured voltages and the resistance between those points now tells you the charge current. Stop charging when the current drops below a certain threshold. Larger resistors make it easier to measure accurately but have an obvious efficiency hit, make sure you check the resistors power rating.
You may be able to avoid adding the resistor and simply use the on resistance of Q1 as your resistor. This will be a little variable between devices so it's not suitable for mass production but for a one off it should be good enough as long as it's not too small for you to measure the current accurately.
One further note: With a supply of 13.5V you will never get the battery to 13V. You have a diode in there with a 0.6V drop so the highest you could get is 12.9V. On the plus side this means you can keep charging until the current drops to 0 with no risk of overcharging.
Or alternatively switch D1 for a schottky diode with a drop of around 0.2V

I made my circuit according to the schematic which I have posted but there were few things which I was doing wrong. After your suggestions I have made few changes. Now at least I am getting accurate voltage. I want to know how to measure the actual voltage when the battery is charging. As you said, when we connect battery to solar/power supply, its voltage increase, if it was 11 v, then it started showing 12v. So in code also it will consider it as 12v. Then how can we measure the actual battery voltage while charging..? I need this because I also need to protect the battery....

...the battery from overcharging. If it will show voltage other than actual voltage, then I guess its impossible to measure its voltage. Is there any way of protecting the battery from overcharging.??

You can't charge unless you apply a voltage greater than the batteries voltage to its terminals. Which means it is impossible to know for sure the voltage you will measure when you remove the charge voltage. It may be possible to estimate what it will be as a function of charge voltage and charge current but that won't be perfect. If you want to prevent overcharging then limit the charge voltage to the maximum battery voltage and charge until the charge current is almost zero.

Lets say I have set max voltage to be 13v. Current battery volt is 11v. So as soon as I start charging, MOSFET conducts and battery volts increases to 12v(lets say). So it will charge till 13v and stop charging. When no charge voltage, actual battery volt has increase from 11v to 12v so it will again start charging. How to handle this condition.

If you charge to the point where there is no charge current flowing then the voltage you are measuring will be the batteries at rest voltage. If there is still a charge current then the amount the battery voltage will drop will be roughly proportional to the charge current.  You need to stop thinking purely about voltages, you need to take the current into account.

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Connect a 3-pin 5V DC fan to a Grove - 16 Channel PWM Driver
I wish to connect a 3-pin 5V DC fan like Arctic f9  to a Grove - 16 Channel PWM Driver (PCA9685)
Does the fan cable match the connector. What is the correct seeeduino connector type shown in

Thanks a lot

That fan cannot be controlled via PWM. The third pin is the sense output, where you can measure the actual speed of the fan. It is NOT a PWM input. You can see this in the pin diagram in the spec sheet.
To control the speed of the fan you need to vary the voltage, that you power the fan with, between 4V and 12V. (See the part "Controlling the fan" -> "In a DIY project" in the manual) When you find a fitting MOSFET or transistor you could use it in its linear range so build a simple amplifiern which could be controlled with a PWM signal filtered through a low pass filter (using a capacitor and a resistor) to get an analog voltage from PWM.
Or - and this would be simpler - just buy a fan, that actually can be controlled via PWM. The 4-pin variants should work for that, but always check in the spec sheet and the manual beforehand.
The connector shown in the diagram from seeeduino is a simple female dupont connector, so nothing specific to seeeduino.

Thanks a lot, it is a big help. so can I connected the F9 to one of the PWM Channel and treat it like a normal fan running at constant speed? Furthermore, how do I deal with the connections to the board with F9 PWM https://www.arctic.de/en/F9-PWM/ACFAN00213A

You can only connect the 4-pin variant to the PWM directly. That is important. For the 3-pin variant you would need additional electronics. And for the connector: You need to change the pin order of the fans connector to match the output of the seeeduino board. Sometimes the pins can be pulled out of the dupont connector (when pulling on a small tap) and put back together in the needed order (depends on how arctic does its connectors). Or you would need to cut off the original connector and put on your own dupont connector with the correct order

Thanks for the question, answers and discussion.
What about using Noctua NF-A14 5V
https://noctua.at/en/nf-a14-5v and this driver.
I can not find any information about its 3-pin cable and I do not know if it fits the dupont  connecters . BTW I have  do not need the PWM. Thanks

@jane please post your own question ... the comment section of an answer is not the place for it

The connector shown in the image from Seeedstudio is a JST-PH 4-pin connector, which is typical for Grove modules. It won’t directly match the fan's 3-pin connector, so you’ll need a custom solution to connect them.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Can I control a 28BYJ-48 5V stepper with a DVR8825 driver?
I have a stepper motor 28BYJ-48 rated 5 V and I want to use a DVR8825 driver so I can use the 1/32 micro-stepping feature. My problem is that DVR8825 has a minimum operating voltage of 8.2 V. Would the 28BYJ-48 stand a 10 V input?
Is there any alternative to the DVR8825 that operates at 5 V and has at least 1/32 micro-stepping?

just because the DVR8825 uses a 10 V power supply, it does not mean that it necessarily delivers 10 V to the motor

Having the same concerns. There is a 12 volt variation of that motor. I just ordered a pair and found this article. I'll now try Towe's remedy above. Thank you.

Stepper motors are rated in two different ways. Some provide a "rated voltage" in combination with a "DC resistance", others provide a "phase current" and a "phase resistance". The way they operate is identical.
Stepper motors such as your 28BYJ-48 are usually intended to be driven with a fixed voltage, their rated voltage. At this voltage, the maximum permittable current flows in the steppers windings - determined mostly by cooling and wire thickness. If you exceed that voltage, more current will flow and will damage / destroy the stepper motor.
The DRV8825 is a current controlled stepper motor driver - it always uses the full available supply voltage - 8.2V+ - but uses PWM to limit the current actually flowing in the stepper. This is possible because the stepper motor coils are inductors, which inhibit the flow of current.
To use your stepper motor with a DRV8825 driver, you'll have to calculate the steppers equivalent "maximum phase current". According to this datasheet, it's rated 5 V at 50 Ohms, giving us a current of 0.1 A. You can then set this current via the potentiometer on the driver chip. The Vref voltage should be set so that Vref = Imax / 2.
Start at a Vref of 50 mV, and see how warm the motor gets and whether it's as strong as you would expect it to be.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Connect to wifi works only without password (Problem around WPA security)
I have an ESP32 Joy-it - SBC NodeMCU-ESP32 that should be use with board "ESP32 Dev Module". IDE says : Chip is ESP32-D0WDQ6 (revision v1.0).
Website product: https://joy-it.net/en/products/SBC-NodeMCU-ESP32
When I make a wifi scan, I find my AP, but if I connect with SSID + Password (both WPA (Internet box router - Freebox Crystal France) and WPA2 Personal (Xiaomi A2 Lite)), it doesn't work.
So I tried to make an AP without password on my phone, and ESP32 can connect without problem.
To do that, I used the default sketch "Wifi -> Wifi Client". My SSID and my password contain only letters/numbers (Only ASCII chars).
I tried to burn the bootloader, but nothing change.
I am using :

IDE Arduino 2.2.1
esp32 by espressif 2.0.14

Does somebody have an idea ?

I tried to burn the bootloader ... what does that mean?

Click on Tools -> Burn bootloader in Arduino IDE GUI :)

Have you tried older esp32 core?

Solution, I'm using an old Freebox, which has only Open or WPA security,
Just add : WiFi.setMinSecurity(WIFI_AUTH_WPA_PSK); to allow connection to my router.
For people with WEP security, just use WIFI_AUTH_WEP

"which has only Open or WPA security" ... WIFI_AUTH_WEP.  You meant "open or WEP" right?

In fact, I copy paste line before move minmal security to wpa, my bad


text:
Are global variables evil in Arduino?
I'm relatively new at programming and many of the coding best practices I'm reading effectively state that there are very few good reasons to use a global variable (or that the best code has no globals at all).
I've done my best to keep this in mind, when writing software to make an Arduino interface with an SD card, talk to a computer and run a motor controller.
I currently have 46 globals for about 1100 lines of "beginner level," code (no line having more than one action). Is this a good ratio or should I look at reducing it more? Also what practices can I employ to reduce the number of globals further?
I'm asking this here because I'm specifically concerned with best practices for coding on Arduino products rather than computer programming in general.

@LookAlterno Err, can you not write classes in Ardunio, since it's just C++ with weird macros and libraries? If so, not every variable is global. And even in C, it's usually considered best practice to prefer passing variables (perhaps inside structs) into functions rather than having global variables. Might be less convenient for a small program but it usually pays off as the program gets larger and more complex.

@LookAlterno: "I avoid" and "you can't" are very different things.

@LookAlterno That's a mundane truism of C/C++ (namespaces notwithstanding), which is not specific to Arduino at all, and as you then yourself indicated, does not by any means lead to the conclusion that global variables cannot be avoided; they can, and often should. Where the answer to this question might differ when the platform is an Arduino is not on the level of the language, but rather in the design patterns that make sense on the platform and whether they make globals desirable.

Actually, some embedded programmers ban local variables and require global variables (or function scoped static variables) instead.  When the programs are small, it can make it easier to analyze it as a simple state machine; because variables never overwrite each other (ie: as they do stack and heap allocated variables).

Static and global variables offer the advantage of knowing memory consumption at compile time. With an arduino having very limited memory available, this can be an advantage. It quite easy for a novice to exhaust the available memory and experience untraceable failures.

Global variables on an Arduino are less evil that on a PC.  I have seen people declaring a loop variable, i, as a global variable.  TBH I try and avoid them, but they do have their place in memory management.

@LookAlterno - The biggest issue with global variables is poor programmers.  You should pass every value as an argument (try to keep it less than 5), because that compartmentalises your code and allows for reuse.  Copy and pasting functions together into programs is really easy, but only if you avoid globals as much as possible.  It also prevents monolithic functions, if you are passing in 20 args into a 2000 line function then you should be refactoring it.

@Muzer huh, always thought it was Processing. TIL

related: https://electronics.stackexchange.com/questions/97241/use-of-global-variables-in-embedded-systems

Hey All: This got a lot more popular than expected. I've learned a lot in the last 9 months and would like to make this as useful to "other me's" as possible. Would people appreciate it if I appended this post with links to tutorials/ideas that helped me as a beginner improve my code? I'm still not 100% confident on stack exchange's edicate, so I thought I'd ask 1st.

They aren't evil per se, but they do tend to get overused where there is no good reason to use them.
There are plenty of times when global variables are advantageous. Especially since programming an Arduino is, under the hood, vastly different to programming a PC.
The biggest benefit to global variables is static allocation. Especially with large and complex variables such as class instances. Dynamic allocation (the use of new etc) is frowned upon due to lack of resources.
Also you don't get a single call tree like you do in a normal C program (single main() function calling other functions) - instead you effectively get two separate trees (setup() calling functions, then loop() calling functions), which means that sometimes global variables are the only way to achieve your goal (i.e., if you want to use it in both setup() and loop()).
So no, they're not evil, and on an Arduino they have more and better uses than on a PC.

Ok, What if it's something I'm only using in loop() (or in multiple functions called in loop())? would it be better to set them up in a different way than defining them at the beginning?

In that case I would probably define them in loop() (maybe as static if I needed them to retain their value across iterations) and pass them through the function parameters down the call chain.

Ok, I think I can do that. If I have (for example) static var n defined in loop(). If I pass n to foo(var) and in foo(var) I set n=[new value]. Will I need to have  return [new value] and have n=[new value] in loop()?

That is one way, or pass it as a reference: void foo(int &var) { var = 4; } and foo(n); - n is now 4.

Classes can be stack-allocated. Admittedly, it's not good to put large instances on the stack, but still.

@JAB Anything can be stack allocated.

Right, I skimmed over too quickly and conflated some of the comments on the question regarding non-use of classes.

The fact no communication is possible between setup() and loop() is, by itself, an excellent reason to use a more standard toolsuite and have a good old main() or _main() entry point.

One of the reasons I've heard to avoid global variables has more to do with a system other than an Arduino, Global variables can be exposed external to, or outside of the program itself. This C++ statement states it best.
"The C language does not have a global keyword. Variables declared outside a function have "file scope," meaning they are visible within the file."
This exposes the variable space to being modified outside of the program's scope before running, as in the case of statics where the file variable space can be edited before running, creating potential security risks

It's very difficult to give a definitive answer without seeing your
actual code.
Global variables are not evil, and they often make sense in an embedded
environment where you typically do a lot of hardware access. You have
only four UARTS, only one I2C port, etc. So it makes sense to use
globals for variables tied to specific hardware resources. And indeed,
the Arduino core library does that: Serial, Serial1, etc. are global
variables. Also, a variable representing the global state of the program
is typically a global.

I currently have 46 globals for about 1100 lines of [code]. Is this a
  good ratio [...]

Is not about the numbers. The right question you should ask yourself is,
for each of these globals, whether it makes sense to have it in global
scope.
Still, 46 global seems a bit high to me. If some of these hold constant
values, qualify them as const: the compiler will usually optimize out
their storage. If any of those variables is only used inside a single
function, make it local. If you want its value to persist between calls
to the function, qualify it as static. You could also reduce the
number of “visible” globals by grouping variables together inside an
class, and having one global instance of this class. But only do so when
it makes sense to put stuff together. Making a big GlobalStuff class
for the sake of having only one global variable will not help make your
code clearer.

Ok! I didn't know about static if I have a variable that is used only in one function but get a new value every time a function is called (like var=millis() ) should I make that static ?

No. static is only for when you need to keep the value. If the first thing you do in the function is set the value of the variable to the current time there is no need to keep the old value. All that static does in that situation is wasting memory.

This is a very well-rounded answer, expressing both points in favour of, and scepticism about, globals. +1

The main issue with global variables is code maintenance. When reading a line of code, it is easy to find declaration of variables passed as parameter or declared locally. It is not so easy to find declaration of global variables (often it requires and IDE).
When you have many global variables (40 is already a lot), it becomes difficult to have an explicit name that is not too long. Using namespace is a way to clarify role of global variables.
A poor way to mimic namespaces in C is:
static struct {
    int motor1, motor2;
    bool sensor;
} arm;

On intel or arm processor, access to global variables is slower than other variables. It is probably the opposite on arduino.

On AVR, globals are on RAM, whereas most non-static locals are allocated to CPU registers, which makes their access faster.

The problem isn't really finding the declaration; being able to quickly understand the code is important but ultimately secondary to what it does - and there the real problem is finding which varmint in which unknown part of your code is able to use the global declaration to do weird things with an object you left out in the open for everyone to do whatever they want with.

As with everything (other than gotos which are truly evil) globals have their place.
e.g. If you have a debug serial port or a log file that you need be to able to write to from everywhere then it often makes sense to make it global. Similarly if you have some critical piece of system status information then making it global is often the easiest solution. There is no point in having a value that you have to pass to every single function in the program.
As others have said 46 seems a lot for only just over 1000 lines of code but without knowing the details of what you are doing it's hard to say if you are over using them or not.
However for every global ask yourself a few important questions:
Is the name clear and specific so that I don't accidentally try to use the same name somewhere else? If not change the name.
Does this need to ever change? If not then consider making it a const.
Does this need to be visible everywhere or is it only global so that the value is maintained between function calls? Is so consider making it local to the function and using the keyword static.
Will things really screw up badly if this gets changed by a piece of code when I'm not being careful? e.g. if you have two related variables, say name and ID number, that are global (see previous note on using global when you need some information almost everywhere) then if one of them gets changed without the other nasty things could happen. Yes you could just be careful but sometimes it's good to enforce carefulness a little. e.g put them in a different .c file and then define functions that set both of them at the same time and allow you to read them. You then only include the functions in the associated header file, that way the rest of your code can only access the variables through the defined functions and so can't mess things up. This is basically a pure c way of doing what a c++ class would allow but without having to learn how to define and create classes so you aren't learning too much at once.
-- update -- I just realized that you had asked about Arduino specific best practice rather than general coding and this is more of a general coding reply. But honestly there isn't much difference, good practice is good practice. The startup() and loop() structure of Arduino means that you have to use globals a little more than other platforms in some situations but that doesn't really change much, you always end up aiming for the best you can do within the limitations of the platform no matter what the platform is.

I know nothing about Arduinos but do a lot of desktop and server development. There is one acceptable usage (IMHO) for gotos and that's to break out of nested loops, it's much cleaner and easier to understand than the alternatives.

If you think goto's are evil, check out Linux code. Arguably, they are just as evil as try...catch blocks when used as such.

gotos aren't evil. They are used in production, professional C code all the time for error handling, including in safety-critical real-time software for life-saving devices, aircraft, etc. They just have to be used properly is all, and their usage pattern is limited and well-defined. Additionally, to keep the project MISRA-compliant, if that's something the project cares about, the usage pattern of gotos in the project must be documented as an exception, which is commonly done in MISRA-compliant software.

Here's some examples I wrote showing reasonable goto usage: https://stackoverflow.com/a/54488289/4561887. I've added additional references to justify their usage at the bottom of the answer. Of course, no code cannot be done without goto (ie: all code can be done withOUT goto), but many instances of code are greatly benefited and made more readable by properly using goto. Some professional teams even mandate the usage of goto in a standardized way in order to have cleaner, more-readable code. It's all about tradeoffs.

Although I wouldn't use them when programming for a PC, for the Arduino they have some benefits. Most if it has already been said:

No dynamic memory usage (creating gaps in the limited heap space of an Arduino)
Available everywhere, thus no need to pass them as arguments (which costs stack space)

Also, in some cases, especially performance-wise it can be good to use global variables, instead of creating elements when needed:

To decrease gaps in heap space
Dynamically allocating and/or freeing memory can take substantial time
Variables can be 'reused', like a list of elements of a global list that are used for multiple reasons, e.g. once as a buffer for the SD, and later as a temporary string buffer.

Are they evil? Maybe. The problem with globals is that they may be accessed and modified at any point in time by any function or piece of code being executed, without restrictions. This may lead to situations that are, let's say, difficult to trace back and explain. Minimizing the amount of globals, if possible bringing the amount back to zero, is therefore desirable.
Can they be avoided? Almost always yes. The problem with Arduino is, that they force you into this two function approach in which they assume you setup() and you loop(). In this particular case you have no access to the scope of the caller function of these two functions (probably main()). If you had, you would be able to rid yourself of all globals and use locals instead.
Picture the following:
int main() {
  setup();

  while (true) {
    loop();
  }
  return 0;
}

This is probably more or less what the main function of an Arduino program looks like. Variables you need in both the setup() and the loop() function would then preferably be declared inside the scope of the main() function rather than the global scope. They could then be made accessible to the two other functions by means of passing them as arguments (using pointers if necessary).
For example:
int main() {
  int myVariable = 0;
  setup(&myVariable);

  while (true) {
    loop(&myVariable);
  }
  return 0;
}

Note that in this case you also need to change the signature of both functions.
As this might not be feasible nor desirable, I see really only one way to remove most globals from an Arduino program without modifying the forced upon program structure.
If I recall correctly, you're perfectly able to use C++ while programming for Arduino, rather than C. If you're not familiar (yet) with OOP (Object Oriented Programming) or C++, it might take some getting used to and some reading.
My proposal would be to create a Program class and create a single global instance of this class. A class should be considered the blueprint for objects.
Consider the following example program:
class Program {
public:
  Program();

  void setup();
  void loop();

private:
  int myFirstSampleVariable;
  int mySecondSampleVariable;
};

Program::Program() :
  myFirstSampleVariable(0),
  mySecondSampleVariable(0)
{

}

void Program::setup() {
  // your setup code goes here
}

void Program::loop() {
  // your loop code goes here
}

Program program; // your single global

void setup() {
  program.setup();
}

void loop() {
  program.loop();
}

Voilà, we've rid ourselves of almost all globals. The functions in which you would start adding your application logic would be the Program::setup() and Program::loop() functions. These functions have access to the instance specific member variables myFirstSampleVariable and mySecondSampleVariable whereas the traditional setup() and loop() functions do not have access as these variables have been marked class private. This concept is called data encapsulation or data hiding.
Teaching you OOP and/or C++ is a bit out of scope of the answer to this question so I'll stop here.
To summarize: globals should be avoided and it's almost always possible to drastically reduce the amount of globals. Also when you're programming for Arduino.
Most importantly I hope my answer is somewhat useful to you :)

You can define your own main() in the sketch if you prefer. This is what the stock one looks like: https://github.com/arduino/Arduino/blob/1.8.3/hardware/arduino/avr/cores/arduino/main.cpp#L33-L51

A singleton is effectively a global, just dressed up in an extra confusing way. It has the same downsides.

@patstew Do you mind explaining me how you feel it has the same downsides? In my opinion it doesn't since you're able to use data encapsulation to your benefit.

@per1234 Thanks! I'm definitely no Arduino expert, but I suppose my first suggestion could work also then.

Well, it's still global state that can be accessed anywhere in the program, you just access it through Program::instance().setup() instead of globalProgram.setup(). Putting related global variables into one class/struct/namespace can be beneficial, especially if they're only needed by a couple of related functions, but the singleton pattern doesn't add anything. In other words static Program p; has global storage and static Program& instance() has global access, which amounts to the same as simply Program globalProgram;.

@patstew I didn't think of it that way. I think you're right. I'll modify my post. It will make it more easy to understand also.

As a long-time embedded coder, I fairly regularly have to train people out of the cast-iron rule of "Global Variables Bad".  Passing arguments always makes code slower.  On a PC this is pretty much immaterial, but in the embedded world this is still a very big deal.  The accessor/mutator pattern is a way to guarantee sound encapsulation at the cost of processing time.  It's perfectly possible to write well-encapsulated code with global variables - but you do have to apply discipline to how you design it, and specify clearly how other people should use it.

@Graham I'm curious to find out what kind of discipline you're talking about? I think I have an idea what you're talking about, but discipline isn't going to create 'well-encapsulated code'. The accessor/mutator pattern will sometimes come with a slight performance cost, depending on how you setup your code, agreed. However, lots of expensive operations may be optimized out by a compiler.

Global variables are never evil. A general rule against them is just a crutch to let you survive long enough to gain the experience to make better decisions.
What a global variable is, is an inherent assumption that there is only one of a thing (it doesn't matter if we're talking about a global array or map that might contain multiple things, that still contains the assumption that there is only one such list or mapping, and not multiple independent ones).
So before you make use of a global, you want to ask yourself: is it conceivable that I will ever want to use more than one of this thing? If it turns out to be true down the line, you will have to modify the code to un-globalize that thing, and you'll probably find out along the way that other parts of your code depend on that assumption of uniqueness, so you'll have to fix them as well, and the process becomes tedious and error-prone. "Don't use globals" is taught because usually it's a pretty small cost to avoid globals from the beginning, and it avoids the potential of having to pay a large cost later on.
But the simplifying assumptions that globals allow also make your code smaller, faster, and use less memory, because it doesn't have to pass around a notion of which thing it's using, doesn't have to do indirection, doesn't have to consider the possibility of the desired thing maybe not existing, etc. On embedded you're more likely to be constrained for code size and/or CPU time and/or memory than you are on a PC, so these savings can matter. And many embedded applications also have more rigidity in the requirements — you know that your chip only has one of a certain peripheral, the user can't just plug another one into a USB port or something.
Another common reason for wanting more than one of something that seems unique is testing — testing the interaction between two components is easier when you can just pass a testing instance of some component to a function, whereas trying to modify the behavior of a global component is a trickier proposition. But testing in the embedded world tends to be very different from elsewhere, so this may not apply to you. As far as I know, Arduino has no test culture whatsoever.
So go ahead and use globals when they seem worthwhile. The code police won't come and get you. Just know that the wrong choice could lead to a lot more work for you down the road, so if you're not sure...

Are Global Variables Evil in Arduino?

nothing is inherently evil, including global variables. I would characterize it as a "necessary evil" - it can make your life much easier but it should be approached with caution.

Also what practices can I employ to reduce the number of globals further?

use wrapper functions to access your global variables. so you at least are managing it from the scope perspective.

If you use wrapper functions to access global variables, you may as well put your variables inside these functions.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Arduino Uno - ESP 8266: sending AT commands via Code
I bought a ESP 8266 & I am able to send AT commands and receive response via serial monitor when I upload a empty sketch. I changed the baud rate from 115200 to 9600 by using AT+CIOBAUD=9600 and am able to run AT commands at 9600 baud rate.
Empty Sketch:
void setup()
{

}
void loop()
{

}

Here is how my circuit looks:

Problem
The problem is when I create a custom sketch to run AT commands it doesn't work. Here is how my sketch looks:
#include <SoftwareSerial.h>
SoftwareSerial esp8266(0,1); //RX,TX

void setup()
{

  Serial.begin(9600);
  esp8266.begin(9600);

  Serial.println("Run AT Command");

   esp8266.print("AT\r\n");

}

void loop(){
   String response = "";
   while(esp8266.available())     {
        char c = esp8266.read();
        response+=c;
        Serial.print(c);
      }

      if(response != ""){
        Serial.println(response);
      }

}

ESP8266 is receiving 3.3V but I have read TX and RX sends 5V, and they also need to be 3.3V. Don't know if thats what is causing it, but I am able to run AT commands on empty sketch, so this is a bit weird.

UPDATE:

My sketch is:
#include <SoftwareSerial.h>
SoftwareSerial esp8266(2, 3); //RX,TX

void setup()
{

  Serial.begin(9600);
  esp8266.begin(9600);

  esp8266.print("AT\r\n");

}

void loop() {
  String response = "";
  while (esp8266.available())     {
    char c = esp8266.read();
    response += c;
  }

    if (response != "") {
      Serial.println("Response: " + response);
    }

}

Serial Monitor shows this:
Response: A
Response: T

OK
Response:

OUTPUT when I run AT+CIFSR command:
Response: A
Response: T+CIFSR

Response:
+CIFSR:APIP
Response: ,"192.168.4.1
Response: "
+CIFSR:APMA
Response: C,"5e:cf:7f:80
Response: :f7:74"

OK

Question now is: How do I store the string being returned from the esp8266. I thought my response string was suppose to store the "OK" but that did not happen.

Why are you using software serial?

Because most of the examples I saw used them

Ok, makes sense. I usually use a Mega with Serial and Serial 2. According to your frizting diagram, it looks like you have RX and TX reversed.

I did try to change TX to RX and RX to TX, in arduino but when I do that, I dont get response from AT commands, on the serial monitor

If you are using an Uno like in the image, use different pins for Software Serial like 2,3. Connect pin 2 to the ESP TX and pin 3 to the ESP RX. In your code, try SoftwareSerial(2,3);

Actually It worked, Thanks. I got a ok response. But it seems my "response string" is not actually the string being returned from the ESP8266. I have updated my main question. Please check it out

You are over-driving the ESP's receive pin by connecting to a 5v transmitter. While this isn't likely to be the source of your issue, it will damage the ESP. (The ESP's transmit side is OK because the Arduino receiver will still see a HIGH at 3.3v.) You should put a voltage divider on its receive pin:   Ardu Tx ----- 1KOhm ---- ESP Rx ----- 2KOhm ----- GND

I get your point, could you show with a frtizing diagram, It will be much easier for me.

Of course you cannot use the same pins for both hardware and software serial, but that part seems to have been solved in comments.

Question now is: How do I store the string being returned from the esp8266. I thought my response string was suppose to store the "OK" but that did not happen.

 while (esp8266.available())     {
    char c = esp8266.read();
    response += c;
 }

This will only read as long as characters are available, but the ATmega is able to run this loop much more quickly than characters are received, so unless the entire message was previously transferred it will likely only get a character or two before the receive buffer is found (temporarily) empty and it terminates.
You should instead read until a terminating condition is found, such as a newline character.  For safety you might also put in a "give up and try again" timeout, but make it long.
Some would try to solve this problem by inserting short delays before trying to read, but that is unwise - depending on delays creates unreliability as the necessary delay can easily change due to conditions that may on the surface seem to have little relevance, for example the esp866 might respond more slowly if it is seeing a lot of broadcast traffic on a network, or if the firmware version changes.

There is another technique that you can use, instead of hanging around waiting for more characters from the ESP8266. Your code starts:
void loop() {
    String response = "";
    while (esp8266.available())     {
        char c = esp8266.read();
        response += c;
    } // while

This has the effect of creating a new String every time loop() is entered, and you accumulate the data from the ESP8266 in that - but it's lost if you leave loop(). So it may be better to do it differently:
const char EOL = '\n'; // End of line
String response = ""; // Create String once, outside loop()

void loop() {
    char c = '\0'; // Initialise to NUL
    while (esp8266.available() && c!=EOL) { // Wait for End of Line
        c = esp8266.read();
        response += c;
    } // while
    if (c==EOL) {
        Serial.print("Response: "); // Don't use '+' if you can help it!!!
        Serial.println(response);
        // Do other processing
        response = ""; // Clear response for next string
    } // if

This has three effects:

It keeps an incomplete response between calls to loop().
It only processes response once the end-of-line is read.
It keeps loop() running nicely (important on other Arduino), rather than hanging around

Just check if this answer helps.
Here is the thing, For AT commands from serial monitor, RX or arduino should be connected to RX of ESP and TX of arduino to TX of ESP. That is the reason you are able to enter AT commands with your circuit when empty program is uploaded.
Now for arduino to communicate with ESP using program, you have to connect RX of arduino to TX of ESP and TX of Arduino to RX of ESP. In your case if using software serial 2 & 3, then pin2 to TX of Esp and pin3 to RX of ESP.
To read "OK" from ESP, try below code:
if(esp8266.find("OK"))

Also you may try this code to read:
esp8266.find("pin="); //this acts like a pointer.
int value = esp8266.read(); //returns ASCII Code. this will read value which comes after pin=

Refer : https://www.arduino.cc/en/Serial/read


text:
Read BLE Characteristic Value in Arduino Uno
I am trying to build a Smart Led project using Arduino Uno, RGB Led, HM-10 BLE module, and Android device.
I am able to connect HM-10 with my android device and read and write characteristic values using Android BlueDroid stack.
But for this project to work I need to check changes in characteristic value in Arduino and process color value and produce output to light up LED.
I thought I could possibly use AT commands (like AT+Name? AT+POWE? AT+CHAR?) parse their result , but I couldn't find any AT command to read characteristic value. If anyone know such working AT commands for HM-10, please answer?
Also, I looked into CurieBLE library from Intel for Arduino. I think the library is to work on an Arduino board which has BLE hardware as a built-in feature. If that's not the case, please help me how can I communicate Arduino and HM-10 using CurieBLE or any other available library?

It sounds like you need to either find the manual for whatever firmware is loaded on your HM10, or else get the TI CC254x SDK and programmer so that you can treat the HM10 as a generic CC254x development board and create your own program for it.

I was able to communicate Arduino UNO and HM-10. Whenever one writes a characteristic on BLE using Android application, the exact bytes are transmitted to Tx/Rx channel to Arduino and can be read using SoftwareSerial Arduino library.
CurieBLE library works on Genuino/Arduino 101 board which has Intel Curie Module.

This doesn't even remotely try to answer "how". It just answers the "what".

I found this site that discusses the HM-10 and they linked to the datasheet which lists all the AT commands. The set/query characteristics AT command is listed as #13 on page 24.
Datasheet link.
"Bluetooth 4.0 with HM-10" tutorial for MIT course "How To Make (almost) Anything"
Hope this helps.

It is helpful to add some information of where the link directs to in case the link ever gets broken or moved.


text:
Remap SPI functions to default pins Arduino Zero via software?
I am looking at the documentation for the Arduino Zero, and I am a little confused.
It indicates that pins 13, 12, and 11 can be used for CIPO, COPI and SCK, but using SPI.begin() puts the signals on the 6-pin header SPI pinout, which makes sense since it is designated for SPI.
Is there a way to switch to the digital pins via C code? Or do I need to edit the header files?  We are using another board that can only attach to the digital pins.

it looks like SERCOM1 could be configured as SPI on pins 11, 12, 13, but how do you want to use it?

I am sending a 32-bit word to another device via SPI protocol, and want to use all the same functions as the 6-pin header on the default digital pins.  I tried some pin mapping with the SERCOM but the code didn't seem to work.

the guide doesn't show how to use SERCOM for SPI, but similar approach as for Wire should work: https://docs.arduino.cc/tutorials/communication/SamdSercom

guide for SPI by Adafruit https://learn.adafruit.com/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports/creating-a-new-spi

EDIT: Provably wrong answer below, see comments from though.

Unfortuantely the Arduino Zero doesn't support remapping of SPI pins as far as I know. Many other modern boards do, like the ESP8266/ESP32, but not the Zero, at least as far as I can tell.

That's really unfortunate if that's the case. Why would they include the SPI options on the digital pins on the documentation?  Or is it just outdated? https://docs.arduino.cc/static/b1fbc77f1b73dcd9ac379af596e3472e/ABX00003-full-pinout.pdf

@eramirez2024 That it can't be remapped doesn't mean it has only one SERCOM, you can probably use another one. For example SERCOM0 is on pins PA04..PA07

@KIIV Apologies, I didn’t realize the Zero ran on the SAMD21, and I am not super knowledgeable about SERCOM, however I found this extremely relevant guide that may help (particularly pages 11-14) https://cdn-learn.adafruit.com/downloads/pdf/using-atsamd21-sercom-to-add-more-spi-i2c-serial-ports.pdf


text:
Arduino Pro Micro not recognizing INPUT or INPUT_PULLUP
I tried to make a controller box with multiple buttons. Sadly, when I tried to connect the buttons, the Arduino Pro Micro didn't recognize them being pressed. I even tried to connect a wire directly (and a directly a resistor from GND to the ports) from GND to the ports but it doesn't seem to matter.
OUTPUT works on the same ports, but INPUT/INPUT_PULLUP does not.
Is there something wrong with the code?
My Arduino Pro Micro is a Chinese knockoff. Keyboard and Mouse are working, OUTPUT is working. It doesn't seem to work with the input.
PS: I have worked with Arduino UNO before (and also the ESP family (ESP8266, ESP32)).
PS2: Sometimes, if I touch the microcontroller's back side some values register (like I pushed all the buttons at once)
#define LED_PIN 4
#define BUTTON_1 10
#define BUTTON_2 16
#define BUTTON_3 14
#define BUTTON_4 9

byte ledState = LOW;

void setup() {
  Serial.begin(9600);
  pinMode(LED_PIN, OUTPUT);
  pinMode(BUTTON_1, INPUT_PULLUP);
  pinMode(BUTTON_2, INPUT_PULLUP);
  pinMode(BUTTON_3, INPUT_PULLUP);
  pinMode(BUTTON_4, INPUT_PULLUP);
}

void loop() {

  byte one = digitalRead(BUTTON_1);
  byte two = digitalRead(BUTTON_2);
  byte three = digitalRead(BUTTON_3);
  byte four = digitalRead(BUTTON_4);

  if (one == HIGH) {
    Serial.println("BUTTON_1");
  }
  if (two == HIGH) {
    Serial.println("BUTTON_2");
  }
  if (three == HIGH) {
    Serial.println("BUTTON_3");
  }
  if (four == HIGH) {
    Serial.println("BUTTON_4");
  }

  digitalWrite(LED_PIN, ledState);
  ledState = !ledState;
  delay(1000);
}

Edit: corrected the code
Mention: I wired the buttons the following way (I have to mention it, because the Arduino Pro Micro doesn't have a sepparate 3V/5V pin, it only has RAW output that by my undertanding can fry the board)
Tutorial from where I inspired the button wiring:
https://arduinogetstarted.com/tutorials/arduino-button

try byte one = digitalRead(BUTTON_1);

Or closer to the form you have it: digitalRead(BUTTON_1) == HIGH; though the form jsotola suggests is better. What you have is a typo, unless you basically didn't already know this was incorrect and need an explanation as to why the placement of ) matters.

As mentioned it really matters where you put parentheses. As none of your button pins is pin 1, comparing them with HIGH (== 1) always results into 0 and that exact 0 was used for all digitalReads.

Sorry....I modified the code in the meanwhile (I observed after I posted that I haven't copyed the good code....it looks like so, because the if's were looking the following way, but I started using variables instead: if(digitalRead(BUTTON_1) == HIGH) to rule out the compiler problems (and when I deleted the parantheses, I deleted the wrong ones) => I have corrected the code in the meantime but still it doesn;t work)

With your latest schematic/code (a) the buttons will be LOW when pressed, not HIGH  (b) your schematic shows the connection of a button on pin 7 but your code has no entry for pin 7 and (c) the delay of 1 second in the loop means you may have to hold the button for up to 1 second to see a response. If touching pins on the board has the same effect as pressing a button then the buttons are in a floating state indicating that the wiring is incorrect.

It's confusing showing a Uno when in the text you say you have a Pro Micro, and then you also tag the question with Leonardo.

@6v6gt Of course the image is for the UNO, because it's from a tutorial (the concept of wiring and the code should be similar, in the background the compiler/correct library should be used by Arduino IDE when I select the board) .
Mention: The picture is NOT mine, I only use the same wiring tehnique as in the picture.

@NickGammon I am using an Arduino Micro Pro (small version of Leonardo, that's why I tagged also Leonardo in the question).

OK. It is clear you've used a picture from a tutorial and not your real layout. One classic error with those tactile push buttons is to rotate them through 90 degrees giving the effect that these are permanently in a "pushed" on state. Do you still get the phenomenon that when you touch the board at the back of the pins that this simulates the pressing of the buttons ?

The way you have it wired, INPUT_PULLUP will make the buttons look HIGH, so in your code you need to test if they are going LOW, which is what grounding the button would do.

Yes, this was also a problem. I tried setting the pins previously to HIGH/LOW but it worked only on the first button press, after that it worked as before (could not read button state correctly).
An improvement to the code can be adding a previous state check also.

After looking at many tutorials and trying many approaches with different Arduinos (Uno, because it's easyer to prototype) (and taking a short brake so I can try again from 0 with a new mindset) I made it work.
Before, I could do it because I was using Microcontrollers that had a 3/5V output also (ex. Uno, Mega, Nano, STM32, ESP8266, ESP32), so I could do a pull-up/down circuit, but because the Arduino Micro doesn't have such pins (it has only RAW as output, which can fry the board if it's externally powered) I had to use this method where I only use a GND pin and a Digital Input without any ressistors wired to the button.
Thanks for the answers and suggestions!
The new code (without the LED functionality):
#include "Keyboard.h"

// defining button pin numbers
// TODO: rename variables according to functionality
#define BUTTON_10 10
#define BUTTON_16 16
#define BUTTON_14 14
#define BUTTON_9 9

// giving them a first-state of HIGH
int previousButtonState10 = HIGH;
int previousButtonState16 = HIGH;
int previousButtonState14 = HIGH;
int previousButtonState9 = HIGH;

void setup() {
  // initializing the buttons as INPUTS with PULLUP (internal pull-up resistor from Arduino)
  pinMode(BUTTON_10, INPUT_PULLUP);
  pinMode(BUTTON_16, INPUT_PULLUP);
  pinMode(BUTTON_14, INPUT_PULLUP);
  pinMode(BUTTON_9, INPUT_PULLUP);

  // only for test
  // TODO: Move this only to the function needed when more functionality is added
  Keyboard.begin();

}

void loop() {
  // checking if any of the buttons were pressed and saving the state in a variable
  previousButtonState10 = checkButton(BUTTON_10, previousButtonState10);
  previousButtonState16 = checkButton(BUTTON_16, previousButtonState16);
  previousButtonState14 = checkButton(BUTTON_14, previousButtonState14);
  previousButtonState9 = checkButton(BUTTON_9, previousButtonState9);
}

// function: reads the button state and compares it with the previous state to find out if it was pressed or not
// params: buttonPin => the pin number of the button; previousButtonState => the state corresponding for each button
// return: it returns the red state, so it can be saved as previousState in the coresponding parameter
int checkButton(int buttonPin, int previousButtonState) {
  int buttonState = digitalRead(buttonPin);

  if (buttonState == LOW && previousButtonState == HIGH) {
    Keyboard.println(buttonPin);
    // some minimal debouncing
    // TODO: WIll be a problem when using millis() in the future
    delay(50);
  }

  if (buttonState == HIGH && previousButtonState == LOW) {
    // not needed, but some functionality could be added in the future
    // Keyboard.println("release");
    delay(50);
  }

  return buttonState;
}

Now I can work further on improving and extending the code to make the "Macro Board" project with mouse movement (and I also have to solder the buttons and LEDs to the board :P )


text:
MQTT connection fails when using String objects
On my ESP32 I am trying to connect to my HomeAssistant server using ArduinoHA library.
I can easily connect when hard-coding the credentials: mqtt.begin("server", "username", "password");
But I recently tried to move the credentials to a config file that I read on setup:
typedef struct {
  String url;
  String username;
  String password;
} Credentials;

Credentials creds = readCredentials(credsFile);
mqtt.begin(creds.url.c_str(), creds.username.c_str(), creds.password.c_str());

The connection fails and the MQTT state returns -2 (StateConnectionFailed).
I tried comparing the read values to the hard-coded values:
  Serial.println(strcmp("192.168.1.45", creds.url.c_str()));
  Serial.println(strcmp("username", creds.username.c_str()));
  Serial.println(strcmp("passwird", creds.password.c_str()));

But it all returns 0 (i.e., its the same string).
Out of curiosity I tried it without reading the config file, and got same result:
  String url = "192.168.1.45";
  String username = "username";
  String password = "password";
  mqtt.begin(url.c_str(), username.c_str(), password.c_str());

So, does anyone know why the connection fails when using String object? Is there something I am missing?
== EDIT ==
It seems that the issue is memory related, the Strings are deleted before mqtt uses them to connect.
So I tried extracting the char* from the String object, but still got the same result:
  String urlStr = String("192.168.1.45");
  char url[urlStr.length() + 1];
  strcpy(url, urlStr.c_str());
  String usernameStr = String("username");
  char username[usernameStr.length() + 1];
  strcpy(username, usernameStr.c_str());
  String passwordStr = String("password");
  char password[passwordStr.length() + 1];
  strcpy(password, passwordStr.c_str());
  mqtt.begin(url, username, password);

One interesting thing I noticed is that using const char* instead of String does work, but I guess its just the compiler converting it to the original hard-coded version.
The only thing that worked for me is to define the Credentials object as a global variable, that way the credentials won't be cleared from memory.

The library could possibly store the addresses of the C strings and use them later, but your arguments do not live long enough. Please check what happens if you copy the C strings into some other variables. -- Or use C string variables as experiment before (in this comment just shorted: char url[] = "192.168.1.45"; /* ... */ mqtt.begin(url, ...);)

@thebusybee Interesting, it does seems to be memory related. I'll update the question with the modifications.

It does look like the begin() method expects the user to provide static storage for the char* arguments as said by @the busybee. The class retains only a copy of the pointer. See: https://github.com/dawidchyrzynski/arduino-home-assistant/blob/main/src/HAMqtt.cpp and the corresponding .h file.  Here is a similar case (see my comments). Unfortunately, you have to poke around in the source code to see if the method retains an expanded copy of the arguments or simply a pointer. https://arduino.stackexchange.com/questions/96796/wifi-credentials-pulled-from-an-sd-card-fail-but-work-hard-coded

@6v6gt Yeah, I just looked at the source code as well. It seems that the class doesn't create a copy of the credentials so I need to make the credentials a global variable...

You do not need global variables for the strings, just static variables.

3 lines of code to assign a char array? char url[]="192.168.1.45";...

Thanks to the comments from @thebusybee and @6v6gt and looking at the source code for the HAMqtt class I realized that the begin method stores the reference to the strings and doesn't create a copy.
bool HAMqtt::begin(
    const char* serverHostname,
    const uint16_t serverPort,
    const char* username,
    const char* password
)
{
    /*
        ...
    */

    _username = username;
    _password = password;
    _initialized = true;

    _mqtt->setServer(serverHostname, serverPort);
    _mqtt->setCallback(onMessageReceived);

    return true;
}

Since the String objects I have are deleted from memory after the setup function, I had to save the Credentials object either by making it global variable or by making it static. So this is the solution that worked for me:
typedef struct {
  String url;
  String username;
  String password;
} Credentials;

HAMqtt mqtt(client, device);

void setup() {
  static Credentials creds = readCredentials();
  mqtt.begin(creds.url.c_str(), creds.username.c_str(), creds.password.c_str());
}

void loop() {
  mqtt.loop();
}

Is the code working now?

@liaifat85 Yeah, seems to work fine ☺


text:
Error: "invalid use of non-static member function" while calling a function from my own class-method
I'm having a bad time trying to call a correctly-working expression (ultra[currentSensor].ping_timer(echoCheck)) from an own class method (myclass::run) instead of from void loop().
I'm getting the following compiler error:
"invalid use of non-static member function".
If I call ultra[currentSensor].ping_timer(echoCheck) directly from void loop() it gives me no error, so I may be missing something.
Here's the (shortened) piece of code which is generating the error:
#include <NewPing.h>

#define ULTRA_NUM      3
#define MAX_DISTANCE 200

class myclass {
  public:

    void run();
    void echoCheck();

    unsigned int distance[ULTRA_NUM];
    uint8_t currentSensor = 0;
};

NewPing ultra[ULTRA_NUM] = {
  NewPing(4, 5, MAX_DISTANCE),
  NewPing(6, 7, MAX_DISTANCE),
  NewPing(8, 9, MAX_DISTANCE)
};

void myclass::run() {
// ....
      ultra[currentSensor].ping_timer(echoCheck);  // Compiler error
  }

void myclass::echoCheck() {
  if (ultra[currentSensor].check_timer())
    distance[currentSensor] = ultra[currentSensor].ping_result
}

ping_timer() is defined as it follows:
void NewPing::ping_timer(void (*userFunc)(void), unsigned int max_cm_distance) {
    if (max_cm_distance > 0) set_max_distance(max_cm_distance);

    if (!ping_trigger()) return;
    timer_us(ECHO_TIMER_FREQ, userFunc);
}

I hope any of you can help me!
Thanks in advance,
Eduardo

Edit:
What I am trying to do is to adapt this example (from NewPing Arduino Library) so that the sonar ping (sonar[currentSensor].ping_timer(echoCheck)) is done from a class method, and not from void loop().

This might help. There is a discussion about calling a class function from an ISR.

Solved:
I moved the event handler out of the class, and made it static void.
Then the code compiled properly
D

The problem is that echo_check isn't void echo_check() but void echo_check(myclass *this) because it's a member function of a class.
You can make the whole thing static (along with run()) by:
class myclass {
    public:
        static void run();
        static void echo_check();
};

static void myclass::run() {
    ....
}

void myclass::echo_check() {
    ....
}

And then you call:
myclass::run();

instead of instantiating an object.

mm seems to solve the problem, but I'm getting now compiler errors wherever the class members are used (and also inside the class definition): "invalid use of member 'Ultrabot::_xxxxxxx' in static member function"

A static function can only call other static functions or global normal functions, or functions of other classes that are defined as static members.

So now I have compiling functions which can't make what they are supposed to? :/

I don't know since you never bothered to show us your real code, only some tiny snippet.

It's not about bothering to do it or not, it's about trying not to bother you with all my partially built code. I hope it's more clear now with the edit.

Well, the answer I gave addresses the question you asked. Since that then breaks unspecified code in some unspecified way then I cannot help you further.

The edit doesn't make anything any clearer at all, no. That is precisely what I assumed you were doing. You need to either re-work your code so it can be all static, or re-work NewPing so it can accept the right kind of function as a callback and not have any of it static. Take your pick.


text:
How accurate is arduino time keeping?
I want to use my arduino to turn a light off for 16 hours and on for 8 hours. I know the general code, just using delays and the relay shield code as well. I want to know how accurate this will be? ( I tagged uno and leonardo, as I have access to both)

Arduino delay() is not really meant for timekeeping.  In single uses at moderate duration it might in the best case approach the accuracy of the clock, but using it repetitively to add up to a longer period of time is a mistake as the start/end error and granularity will accumulate.  Instead, you should use something that looks at the cumulative number of clock ticks that have elapsed over the entire interval of interest.

By definition, the Arduino is as accurate as it's crystal clock/resonator.
This clock runs at approximately 16mhz for an Uno.
The Arduino's internal time is just a count of how many times this crystal has vibrated.
READ THIS! - these next two paragraph are apparently incorrect. See Nick Gammon's comment below.

The crystal in question is approximately like this one: https://www.sparkfun.com/products/536 - this one from SparkFun is accurate to 50 ppm - that's parts per million. So, if your Arduino has that EXACT crystal, it may lose or gain 50 parts per million - in a million seconds, it would count somewhere between 999,950 and 1,000,050 seconds. This would mean you gain/lose less than 4.3 seconds per day, or 2 minutes per month.
  If you find the crystal on your board, google the code (probably something like 16.000N, for the Sparkfun one), which should tell you exactly what the accuracy is for that chip. Note that, if you can find the datasheet, it should tell you the accuracy, at particular temperatures - as the temperature goes up and down, the error will change too.

Remember also that an Arduino's clock is in volatile memory - that is, if you power down the Arduino, and power it back up, it has no idea what time it is - you would need to set the clock again, either by connecting it to a PC, network, or via buttons/display on your project.
There are a number of alternatives, depending on your need, to work around this: you can get the data from LAN or WIFI, if your project has that, or you can use a RTC module - you need to set this to the correct time once, then it will remember after that.
Alternatively, you can use a light-dependent resistor (aka photoresistor), and trigger automatically when it gets dark. This may trigger when it gets dark for some other reason, e.g. a storm, which may or may not be an advantage.

The Uno has a resonator connected to the Atmega328P, not a crystal. The crystal you see on the board is connected to the Atmega16U2 (the USB interface) because that needs more accurate timing. A resonator is not as accurate as a crystal, generally speaking.

H'm, if there is an accurate crystal for the USB, would it not have made design sense to push the output of that to the AtMega328P? I know the AtMega328P has a clock-out, I assume the 16U2 has a clock out too? The AtMega328P definitely has a clock in....

Interesting question. They could have saved a cent or two by doing that. There must be some reason, if only the desire to keep high frequency signals from going from one side of the board to the other.

Would that be an issue? The signal delay would not - the two chips aren't synchronized, and nothing assumes that they are (obviously, otherwise separate clocks wouldn't work). The clock-out is generated by the first chip, so I would expect it to be a strong clear signal - surely 16mhz over a few cm wouldn't be an issue? It would also save a pin (as the crystal requires two pins).

True. And the two chips are quite close together too. I don't know why. Maybe by the time it occurred to them it was too late because of the way the other traces on the board ran.

the below information is incorrect... i'm not sure why you say it is incorrect. I would argue that you are largely accurate in that with good coding, the long-term accuracy of arduino, or any other mcu, is only a function of the oscillator. the fact that the oscillator is a crystal, or a txco, or an internal oscillator, etc., doesn't fundamentally change that fact.

@dannyf - edited post to mark just a single paragraph as "inaccurate", not the entire post. I've been unable to identify a part number, so cannot say how accurate it is.

There are multiple versions and "clones" of the Arduino, and each one will probably use different components. The time you refer, in this case "millis()" I believe, is maintained from a timer interrupt, which is derived from the main clock (normally 16Mhz).
The main clock on your board might be generated by a ceramic resonator, which is not very accurate: around 0.5%-1% error. It also might be from good quartz crystal, with up to 0.001% accuracy. Those variations on the frequency source will produce some drift over time... Like your watch needs to be readjusted from time to time.
Another factor that affects accuracy, including for RTCs using a 32.768KHz crystal, is the temperature. Here an Application Note on this: http://www.st.com/content/ccc/resource/technical/document/application_note/55/e2/3d/2a/87/ab/4d/e1/CD00232494.pdf/files/CD00232494.pdf/jcr:content/translations/en.CD00232494.pdf
Your application might not require too much precision, and you could simply write a sketch to print the time every second on the serial... let it run from one hour, one day, and check how much drift you're getting. After that will be easy to estimate how much drift you'll have a after a month.

“you still have some losses for the little overhead of your software to increment millis()”. No, you don't. The hardware timer driving millis() does not stop counting while the software increments timer0_millis. Unless you do something very wrong, like blocking interrupts for more than 1 ms, you will not loose a single tick of the crystal/resonator.

Yep, you're right, the little overhead to increment the millis won't be cumulative.

I made a temperature and humidity sensor in August 2013. It uses a RTC chip (DS1307) which you can buy on eBay for $1 if not less. It has a battery backup (lithium cell).
I don't recall ever resetting the clock on it. It is now about 3 years later, and it is running about 11 minutes slow. This would be an acceptable error for something like turning garden lights on and off. Even for taking the temperature, a few minutes out when logging a reading is probably not going to matter.
Using the internal clock probably won't be as accurate, but could be OK in this case. I suggest you follow Chris Stratton's suggestion and code so that errors are not cumulative. For example, if you delay for an hour, and then do something, make sure that the "do something" isn't added to the next delay time.
If you want super accuracy (sounds like you don't) then connecting up a GPS module lets you query the exact time from the satellite, which could cut the error down to negligible amounts. Those GPS modules however aren't cheap.

Something to consider if you try to make do with the internal clock is: what happens if the power goes off? Then it loses track of when to turn the lights on and off. A clock chip however (usually) has a battery backup, and will "know the time" once the power comes back on.

If you go to eBay, to buy and RTC, just spend an extra buck and get a DS3231 instead of a DS1307. This one has a temperature compensated oscillator, resulting in even better accuracy. 2 minutes off per year, maximum. I have mine running for 2 year, and it is still correct to the minute (i.e. less than 60 seconds off).

Sounds like very good advice. :)

I think that RTC modules and real time clock chips have some sort of "mistake" said that, it CAN max. delay for fast forward for max. 6 seconds per month. Something as this, I've read year or so ago, when I was dealing with some sort of doors locking mechanism.
But for app. 8 hours, there's an arduino RTC module more than enough, I'd say. I assume, that seconds doesn't matter.

Just because it's always an option...  I'm usually connecting my Arduinos to the Internet one way or another, so I just get the time from NTP servers once every day or so using UDP to keep the clock accurate, or accurate enough.
The advantage is that, even if power is lost, it's relatively easy to ask Arduino to get the time while booting up.  Then it always knows, and is always on time.
Happy to share fave code, but I found mine in UDP library examples and have adapted it to my own needs.

I want to know how accurate this will be?

accuracy is a function of coding and hardware. with good coding, you can make it as accurate as your hardware is capable of.
I experimented with a tco-919 high accuracy oscillator (19.2Mhz), in an unairconditioned environment, no meaningful timing drift after a month.
So if you really want accuracy, go with a good oscillator.
if you just care about reasonable accuracy (1%?), the internal oscillator will do.

Not very.
For that kind of period of timing you are far better off using a Real Time Clock (RTC) module.

How long off will I end up being? It doesn't need to be super accurate

The longer it is running for the longer it will drift. The oscillator (ceramic) on the Arduino Uno is very poor. It's better on the Leonardo since it has to drive USB, but the whole delay() / millis() thing is inaccurate at best.

Alright, I may just use a phone and another shield to interface with it and get the time. Thank you very much :)

That sounds massively more complex and expensive than using an RTC...

You may think, but I have all the materials and an old ipod that just begs to be used for this :)

authors: ธิติ ศรีประสงค์


text:
changing a single bit in an arduino EEPROM byte
In my code I have a number of boolean flags that tell me if data has been written to specific places in the EEPROM. I need to save these flags to the EEPROM and recover them on a restart.
Is the following syntax valid to update a single bit in an EEPROM cell?
EEPROM.update (0, EEPROM.read(0)| 0x20);

ie I'm reading cell '0' , putting a '1' into bit 5 and then updating cell; '0' of the EEPROM. There will be several other bits to be updated throughout the running of the programme.

how frequently?

perehaps you better first collect all bit changes and update the value only once.

Yes, your syntax is indeed correct. The | operator is the bitwise OR operator in C and C++, and it's used to set a specific bit in a byte. Here's a breakdown of what your line of code does:

EEPROM.read(0) reads the current value of the first byte in the EEPROM.
0x20 is the hexadecimal representation of 32, which is 00100000 in binary. This means that the fifth bit (counting from zero) is set to 1, and all other bits are set to 0.
EEPROM.read(0) | 0x20 performs a bitwise OR operation on the current value of the first byte in the EEPROM and 0x20. This will set the fifth bit of the byte to 1, and leave the other bits unchanged.
EEPROM.update(0, EEPROM.read(0) | 0x20) updates the first byte in the EEPROM with the new value.

So, your approach to set a specific bit in an EEPROM byte is correct.
Here's a more detailed example:
byte bitToSet = 5; // Bit number to set (0-7)
byte eepromAddress = 0; // EEPROM address (0-1023 for ATmega328)

// Read current value
byte currentValue = EEPROM.read(eepromAddress);

// Create mask for bit to set
byte mask = 1 << bitToSet;

// Update value
byte newValue = currentValue | mask;

// Write updated value back to EEPROM
EEPROM.update(eepromAddress, newValue);

It's worth noting that the EEPROM.update() function is smart enough to only perform a write if the new value is different from the old one. This is important because the EEPROM has a limited number of write cycles. So using EEPROM.update() instead of EEPROM.write() can help extend the life of the EEPROM.

Note: unprogrammed eeprom/flash values are 0xFF so if you left it unprogrammed it might not work as intended


text:
avrdude: ser_open(): can't open device "\\.\COM5": Access is denied
I'm getting the error as follows

Sketch uses 2952 bytes (9%) of program storage space. Maximum is 32256 bytes.
Global variables use 196 bytes (9%) of dynamic memory, leaving 1852 bytes for local variables. Maximum is 2048 bytes.
avrdude: ser_open(): can't open device "\.\COM5": Access is denied.
Failed uploading: uploading error: exit status 1

The board I am using is Arduino Uno and checked the ports too. Also restarted and installed IDE again. But still not being able to deal with it.
I will be happy with the help!

Are you sure that COM5 is your Arduino Uno? On the device manager check if you unplug Arduino Uno, COM5 goes away.

In Windows (if you are using windows), There are two things may caused the problem:

go to device manager >> ports >> and Uninstall all ports related to Arduino (including the COM5). Then connect the arduino again and it install it again automatically.
Make sure that you close all "serial monitor", before uploading the sketch.

I did that too. I even tried with Arduino cloud web editor. But no results.

I am sure about it. I am aware of the above mentioned method. And even tried with other ports. Still the error message is same.

Jeez, I pulled my hair out for 30 minutes trying to figure this out. Turned out to be the serial monitor in the IDE. You would think the Arduino IDE would have some awareness of this conflict. Thank you for the help.


text:
Portenta H7 with Breakout Board, USB A as client and USB-C as Host
Portenta H7 with Breakout Board. I would like to use the USB-A on Breakout Board as a client to send debug messages back to the terminal.
USB-C on the H7, I would like to use as a Host for Keyboards etc.
Is this possible?
If so does anyone have some example code because I have been going around in circles for a while now.


text:
Confusion on bit shifting
I am trying to read-in two separate, 3 byte messages over CAN, add them together, and send back out over CAN, on a CANBED V1 which uses a Leonardo.
My confusion is using bit shifting.
If I attempt to shift 1 by 1..14 bits I seem to understand,
uint32_t hdbs = 1 << (14) ;
Serial.println(hdbs, BIN);

this codes gives me 100000000000000 in the display window if printing binary or 16384 decimal.
But if I try a bit shift of 15 or more
uint32_t hdbs = 1 << (15) ;
Serial.println(hdbs, BIN);

I am now confused as I get

11111111111111111000000000000000 or 4294934528 in decimal

What basic concept am I missing?  I tried using unsigned long, long, etc.,
If I do some simple math and use hdbs = 8 * 4095 I get the correct answer of 32760, but when I try 8*4096 I get 4294934528, which should be 32768 (which seems like would exceed a 16 bit unsigned, but I thought I was declaring hdbs as a 32 bit variable.

This is really more of a C++ question, but I don't know whether or not you know that. Roughly speaking, in C, C++ (and so "Arduino" language) expressions are evaluated for types in parallel with their values from the inside out following operator precedence rules much like regular algebra.
You must ensure the type on the left-hand-side of the << is already prepared to accept the resulting value. E.g.:
uint32_t hdbs = static_cast<uint32_t>(1) << 15;

uint32_t hdbs = (uint32_t)1 << 15;

uint32_t hdbs = uint32_t(1) << 15;

uint32_t hdbs = uint32_t{1} << 15;

uint32_t hdbs = 1UL << 15;

1 is of type int, which for Leonardo is a 16-bit type.
Usually when binary operators like + or / are evaluated for result type, the both sides are taken into account in something called usual arithmetic conversions. For << it just looks at the type of the thing being shifted and takes that. So your result of 1 << 15 is being evaluated in an int, which cannot store that value on the AVR. The fact that you later use that in initializing uint32_t hdbs is beside the point when calculating 1 << 15 itself.
I would have tentatively guessed you'd get 0x8000 which when converted to 32-bit under sign extension would have resulted in 11111111 11111111 10000000 00000000. But, an attempt to overflow a signed integer type like this is undefined. It cannot be reliability expected to produce any particular behaviour, let alone value.
Had you been using 32-bit chip like an ARM or ESP32/ESP8266, this would have just worked because the int type there is 32-bit.

Thats amazing!  Thank you!  I am such a newb (Mechanical Engineer) pretending to write hack code, super appreciate your time!

Ah, I was off by 8-bits on my "would guessed" thing. So, you are getting what I would have guessed. Though again, by "luck". Going to edit for that.

This is how C type cast works.
C expressions are of signed type by default. If an expression type has too small bit length than it may get also negative due to overflow (into the high bit which is also a sign bit).
Whenever a signed expression needs to fit into more bits, it gets expanded into longer signed value first (which is effectively the same as duplicating the high bit as many times as needed). And only after that, it will be converted to unsigned (which is basically no-op).
So to overcome this thing you need to change cast order by making 1U or 1UL instead of just 1. Then you will never run into signed values and, so, no sign bit expansion.