text:
How does a callback function get revoke itself eg. Connect function get revoked when there is new connection
Further to my previous question here
Can anyone help me understand how the callback function gets revoked itself? The connect function, disconnect function.
BLE custom UUID code source here
Another example is BLEUART which have callback functions:
/*********************************************************************
 This is an example for our nRF52 based Bluefruit LE modules

 Pick one up today in the adafruit shop!

 Adafruit invests time and resources providing this open source code,
 please support Adafruit and open-source hardware by purchasing
 products from Adafruit!

 MIT license, check LICENSE for more information
 All text above, and the splash screen below must be included in
 any redistribution
*********************************************************************/

/*
 * This sketch demonstrate the central API(). A additional bluefruit
 * that has bleuart as peripheral is required for the demo.
 */
#include <bluefruit.h>

BLEClientBas  clientBas;  // battery client
BLEClientDis  clientDis;  // device information client
BLEClientUart clientUart; // bleuart client

void setup()
{
  Serial.begin(115200);
//  while ( !Serial ) delay(10);   // for nrf52840 with native usb

  Serial.println("Bluefruit52 Central BLEUART Example");
  Serial.println("-----------------------------------\n");

  // Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1
  // SRAM usage required by SoftDevice will increase dramatically with number of connections
  Bluefruit.begin(0, 1);

  Bluefruit.setName("Bluefruit52 Central");

  // Configure Battery client
  clientBas.begin();

  // Configure DIS client
  clientDis.begin();

  // Init BLE Central Uart Serivce
  clientUart.begin();
  clientUart.setRxCallback(bleuart_rx_callback);

  // Increase Blink rate to different from PrPh advertising mode
  Bluefruit.setConnLedInterval(250);

  // Callbacks for Central
  Bluefruit.Central.setConnectCallback(connect_callback);
  Bluefruit.Central.setDisconnectCallback(disconnect_callback);

  /* Start Central Scanning
   * - Enable auto scan if disconnected
   * - Interval = 100 ms, window = 80 ms
   * - Don't use active scan
   * - Start(timeout) with timeout = 0 will scan forever (until connected)
   */
  Bluefruit.Scanner.setRxCallback(scan_callback);
  Bluefruit.Scanner.restartOnDisconnect(true);
  Bluefruit.Scanner.setInterval(160, 80); // in unit of 0.625 ms
  Bluefruit.Scanner.useActiveScan(false);
  Bluefruit.Scanner.start(0);                   // // 0 = Don't stop scanning after n seconds
}

/**
 * Callback invoked when scanner pick up an advertising data
 * @param report Structural advertising data
 */
void scan_callback(ble_gap_evt_adv_report_t* report)
{
  // Check if advertising contain BleUart service
  if ( Bluefruit.Scanner.checkReportForService(report, clientUart) )
  {
    Serial.print("BLE UART service detected. Connecting ... ");

    // Connect to device with bleuart service in advertising
    Bluefruit.Central.connect(report);
  }else
  {
    // For Softdevice v6: after received a report, scanner will be paused
    // We need to call Scanner resume() to continue scanning
    Bluefruit.Scanner.resume();
  }
}

/**
 * Callback invoked when an connection is established
 * @param conn_handle
 */
void connect_callback(uint16_t conn_handle)
{
  Serial.println("Connected");

  Serial.print("Dicovering Device Information ... ");
  if ( clientDis.discover(conn_handle) )
  {
    Serial.println("Found it");
    char buffer[32+1];

    // read and print out Manufacturer
    memset(buffer, 0, sizeof(buffer));
    if ( clientDis.getManufacturer(buffer, sizeof(buffer)) )
    {
      Serial.print("Manufacturer: ");
      Serial.println(buffer);
    }

    // read and print out Model Number
    memset(buffer, 0, sizeof(buffer));
    if ( clientDis.getModel(buffer, sizeof(buffer)) )
    {
      Serial.print("Model: ");
      Serial.println(buffer);
    }

    Serial.println();
  }else
  {
    Serial.println("Found NONE");
  }

  Serial.print("Dicovering Battery ... ");
  if ( clientBas.discover(conn_handle) )
  {
    Serial.println("Found it");
    Serial.print("Battery level: ");
    Serial.print(clientBas.read());
    Serial.println("%");
  }else
  {
    Serial.println("Found NONE");
  }

  Serial.print("Discovering BLE Uart Service ... ");
  if ( clientUart.discover(conn_handle) )
  {
    Serial.println("Found it");

    Serial.println("Enable TXD's notify");
    clientUart.enableTXD();

    Serial.println("Ready to receive from peripheral");
  }else
  {
    Serial.println("Found NONE");

    // disconnect since we couldn't find bleuart service
    Bluefruit.disconnect(conn_handle);
  }
}

/**
 * Callback invoked when a connection is dropped
 * @param conn_handle
 * @param reason is a BLE_HCI_STATUS_CODE which can be found in ble_hci.h
 */
void disconnect_callback(uint16_t conn_handle, uint8_t reason)
{
  (void) conn_handle;
  (void) reason;

  Serial.print("Disconnected, reason = 0x"); Serial.println(reason, HEX);
}

/**
 * Callback invoked when uart received data
 * @param uart_svc Reference object to the service where the data
 * arrived. In this example it is clientUart
 */
void bleuart_rx_callback(BLEClientUart& uart_svc)
{
  Serial.print("[RX]: ");

  while ( uart_svc.available() )
  {
    Serial.print( (char) uart_svc.read() );
  }

  Serial.println();
}

void loop()
{
  if ( Bluefruit.Central.connected() )
  {
    // Not discovered yet
    if ( clientUart.discovered() )
    {
      // Discovered means in working state
      // Get Serial input and send to Peripheral
      if ( Serial.available() )
      {
        delay(2); // delay a bit for all characters to arrive

        char str[20+1] = { 0 };
        Serial.readBytes(str, 20);

        clientUart.print( str );
      }
    }
  }
}

The following helps set the callback functions:
clientUart.setRxCallback(bleuart_rx_callback);
...
Bluefruit.Central.setConnectCallback(connect_callback);
...
Bluefruit.Central.setDisconnectCallback(disconnect_callback);

Tracing back the libraries I found :
void BLEPeriph::setConnectCallback( ble_connect_callback_t fp )
{
  _connect_cb = fp;
}

void BLEPeriph::setDisconnectCallback( ble_disconnect_callback_t fp )
{
  _disconnect_cb = fp;
}

But I can't understand how this initializes the calling of the connect or disconnect function while getting a new connection or break in connection respectively.

All a callback function assignment does is link an internal pointer to the function that you provide.
Any time the callback is needed to be called the code just uses the pointer that your function has been assigned to.
Thus _connect_cb and connect_callback() are one and the same thing. Any time connect_callback() would be expected to be used _connect_cb() is used instead.
It is, in effect, just creating an internal alias to your code then using that alias to call your code when it needs to.

Okay I got the pointer assigning part clear and _connect_cb have assigned value of the function connect_callback(). But the one more thing I need to clarify is where did I call _connect_cb in my main code?
When there is new connection it get revoke itself. So I want to know is it defined somewhere in the library?

You don't call anything. That's the whole point of a callback - it's the library that calls it. Somewhere in the library there will be a call to _connect_cb().

@JustdoinGodswork, you call BLE functions in loop(). any of them can call the callback

Okay got it, I'll try searching the connect_cb() in the libraries.


text:
DS18B20 doesn't work with pinMode for other devices
i do some project. There is DS18B20, 3 mosfet modules, 1 relay, display 1602, buzzer... I built it on bread board, everything worked.
Now i soldered it: arduino works, display works but DS18B20 doesn't return temperature.
I tried to solder thermometer over again - no result.
Then i glanced at my sketch and tried to remove some code in loop and setup. I understood that DS18B20 works only if in setup function no pinMode(...) for other modules. It's odd!
This is part of my code:
#include <EncButton.h>     // For buttons
#include <microDS18B20.h>  // For thermometer DS18b20
#include <EEPROM.h>        // For EEPROM memory to save settings
#include <ezBuzzer.h>      // For buzzer
#include "Screen.h"

/* --- PINS --- */
#define kettle_relay_pin 4     // Relay of kettle
#define mixer_pin 5            // Mixer pin
#define termometer_pin A2      // Termometer pin
#define hot_pump_pin A0        // Hot water
#define sugar_dispenser_pin A1 // Sugar dispenser
#define buzzer_pin 9           // Buzzer pin

#define l_button_pin 11      // Left button
#define r_button_pin 12      // Right button
#define potent_pin A3        // Potentiometer pin for set int values
/* --- PINS --- */

#define INIT_ADDR 1023  // EEPROM addres for init key
#define INIT_KEY 1      // EEPROM init key

/* --- Initialize objects --- */
// Connect thermometer DS18b20
MicroDS18B20<termometer_pin> ds;

ezBuzzer buzzer(buzzer_pin); // create ezBuzzer object that attach to a pin;

// Buttons
EncButton<EB_TICK, l_button_pin> l_button;
EncButton<EB_TICK, r_button_pin> r_button;

// LCD Display
#define _LCD_TYPE 1
#include <LCD_1602_RUS_ALL.h>
LCD_1602_RUS lcd(0x27, 16, 2);
Screen screen(&lcd); // Create screen object instance for convient work with lcd display
/* --- Initialize objects --- */

/* --- Initial values --- */
enum modes {
  // ...
};
modes currentMode = normalMode;

// Default settings
struct Settings{
   //...
} settings;

// Current values
int current_temp = 25; // Current temperature
// ...
/* --- Initial values --- */

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

    // Buttons and potentiometer
    r_button.setButtonLevel(HIGH);
    l_button.setButtonLevel(HIGH);
    pinMode(potent_pin, INPUT);

    // Kettle
    pinMode(kettle_relay_pin, OUTPUT);
    digitalWrite(kettle_relay_pin, LOW);

    // Pump
    pinMode(hot_pump_pin, OUTPUT);
    digitalWrite(hot_pump_pin, LOW);

    // Mixer
    pinMode(mixer_pin, OUTPUT);
    digitalWrite(mixer_pin, LOW);

    // Sugar dispenser motor
    pinMode(sugar_dispenser_pin, OUTPUT);
    digitalWrite(sugar_dispenser_pin, LOW);

    // Buzzer
    pinMode(buzzer_pin, OUTPUT);

    // Init EEPROM
    if (EEPROM.read(INIT_ADDR) != INIT_KEY) {
        // EEPROM haven't been initialized yet
        EEPROM.write(INIT_ADDR, INIT_KEY); // Write init key
        EEPROM.put(0, settings); // Set default data
    }

    // Read settings and apply it
    EEPROM.get(0, settings);
    tea_temp = settings.tea_temp_default;
    sugar_count = settings.sugar_count_default;
    settings.mixer_time = 15 * 1000;

    // Init display
    screen.init();
}

unsigned long screenUpdateTimer = 0;

void loop() {
  buzzer.loop();

  l_button.tick();
  r_button.tick();

  creen.render(); // Always render information on display

  Serial.println(ds.online()); // TRUE

  // For ds18b20 tests
  ds.requestTemp();
  delay(1000);
  if (ds.readTemp()) Serial.println(ds.getTemp());
  else Serial.println("error");

  menuControl();
}

What's problem?
If i comment all pinMode and digitalWrite code, ds.readTemp works, else it's error.
UPDATE #1
I figured out that if i use ports A0 and A1, i get message "error" for this sketch:
#include <microDS18B20.h>
MicroDS18B20<A2> sensor;
void setup() {
  Serial.begin(9600);
}
void loop() {
  sensor.requestTemp();

  delay(1000);

  if (sensor.readTemp()) Serial.println(sensor.getTemp());
  else Serial.println("error");
}

And more. I get this message "error" every time without any connected modules. After some connects and disconnects of mosfet module to pins A0, A1, D5, D6. No temperature at all!

Update #2
I think it's died.
My main sketch (it worked yesterday) now doesn't work at all. But then i try some reboots and it works but not properly...
So, if it works, i can see my menu on display but it's ierogliphs sometimes. also sometimes buttons stop to work...
Is aruino dead?

This doesn't really match your problem description, but it is a problem, I think. LCD_1602_RUS lcd(0x27, 16, 2); 16 is another name for A2 on the atmega328p/atmega168p Nano. Half expect you just typo'd it. Maybe you wired to 6? No diagram so, no way to know.

No, 1602 must be connected to A4, A5. And it worked for bread board

Now i figured out one more thing. If i connect mosfet module to A0 or to A1 pin, DS18B20 show error... IDK how it works...

i tried disconnect 1602 as well, no result

Include all this stuff you're figuring out in your question. Add a diagram. Remove any unnecessary stuff. If you can create the same problem without a 1602 display involved, remove it it from both your test setup and the question.

it looks like something is mis-wired

Welcome! Posting an annotated schematic, not a frizzy picture would go a long way in us helping you. Links to "Technical" information on the  hardware devices will also help.

source: Stack Exchange

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

sort: votes


text:
Arduino keyboard Input language problem
I need my Arduino (Leonardo) to open cmd, but if keyboard input language isn’t English it prints another language letters.
——— code ———
Keyboard.begin();
Keyboard.press(KEY_LEFT_GUI);
Keyboard.press('r');
delay(1000);
Keyboard.releaseAll();
Keyboard.write("cmd");
Keyboard.press(KEY_RETURN);
Keyboard.releaseAll();
delay(1000);

——— ——— ———
So my question is: can I somehow detect language, and if it’s not there add it?
My idea was to set languagelist via powershell, and it would be perfect for my program, but I don’t know how I can write English text from Arduino on pc with another language :(
Also my Arduino has sd card, maybe it helps.
——— code ———
powershell $OldList = Get-WinUserLanguageList

powershell Set-WinUserLanguageList -LanguageList en-US -Force

-something

powershell Set-WinUserLanguageList -LanguageList $OldList -Force

——— ——— ———
Sorry if it is 0iq question, I’m very new to Arduino, it will be great to hear your ideas!

your question is not about Arduino

@jsotola, oh sorry, but about what is it then?
Can i rephrase my question like: Is there a way to print english text via arduino on system with another input language?
thank you for your reply!

As any other USB keyboard, your Arduino cannot change the host's input language. There is no way that your keyboard can directly change the input language.

Absolutely no way? Like copy from file from sd or check it somehow?
Thank you anyway @thebusybee!

Maybe there is a way to check printed text and if it is not english alt+shift?

@Mapagmataas a computer keyboard cannot look at the screen

Your Arduino will be virtually typing on a keyboard like this:

© Aon fi – CC-BY 3.0
See the labels on the keys? There are none. Your Windows OS has its
own idea of what each key means, but the Arduino has no way of knowing
that. Instead, you have to tell it explicitly what keyboard layout to
use, e.g.:
Keyboard.begin(KeyboardLayout_fr_FR);

If you don't, the Keyboard library will assume KeyboardLayout_en_US.
There is no way the computer can tell the keyboard what layout it
expects.

That's sad, thank you for your reply, now i'm undarstand it

Sorry, Maybe there is a way to check printed text and if it is not english alt+shift? @EdgarBonet

@Mapagmataas: Yes, you can check by looking at the screen. But a keyboard cannot do that, and neither can an Arduino posing as a keyboard.

Sorry, i am newby with arduino) Thank you!

@Mapagmataas it has nothing to do with Arduino ... the problem is with computers and keyboards

@jsotola: In principle you are right. However, this is the kind of info you only care about when you start using the Arduino Keyboard library.

i finaly found a solution for my problem. I wrote an algorithm, that automaticly change system input language if there are only two languages and one of them is English. This code is writen on Duckduino shortcuts, but it is not a problem to convert it back.
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "ok"
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList en-US, ru -Force
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

ALT SHIFT
DELAY 1000
GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "ok"
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList ru, en-US -Force
ENTER
DELAY 1000
ALT SHIFT
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "ENGLISH"
ENTER
DELAY 1000

You can use for ru another language, for "ok" i want to add Get-WinUserLanguageList | ConvertTo-Json | Out-File C:\WinUserLanguageList.json to save user's list.

Than language is different than english this code makes errors, and than language is right it changes language list, thats how it works!

Update:
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING Get-WinUserLanguageList | ConvertTo-Json | Out-File C:\WinUserLanguageList.json
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList en-US, ru -Force
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

ALT SHIFT
DELAY 1000
GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING Get-WinUserLanguageList | ConvertTo-Json | Out-File C:\WinUserLanguageList.json
ENTER
DELAY 1000
STRING Set-WinUserLanguageList -LanguageList ru, en-US -Force
ENTER
DELAY 1000
ALT SHIFT
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING "CODE IN ENGLISH"
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING powershell
ENTER
DELAY 1000
STRING Get-WinUserLanguageList
ENTER
DELAY 1000
STRING $importedFile = Get-Content C:\WinUserLanguageList.json | ConvertFrom-Json
ENTER
DELAY 1000
STRING $langCollection = New-Object System.Collections.Generic.List[Microsoft.InternationalSettings.Commands.WinUserLanguage]
ENTER
DELAY 1000
STRING foreach ($item in $importedFile) {
ENTER
DELAY 1000
STRING $lang = [Microsoft.InternationalSettings.Commands.WinUserLanguage]::new($item.LanguageTag)
ENTER
DELAY 1000
STRING $lang.InputMethodTips.Clear()
ENTER
DELAY 1000
STRING foreach ($inputMethod in $item.InputMethodTips) {
ENTER
DELAY 1000
STRING $lang.InputMethodTips.Add($inputMethod) }
ENTER
DELAY 1000
STRING $lang.Handwriting = $item.Handwriting
ENTER
DELAY 1000
STRING $lang.Spellchecking = $item.Spellchecking
ENTER
DELAY 1000
STRING $langCollection += $lang }
ENTER
DELAY 1000
STRING Set-WinUserLanguageList $langCollection -Force
ENTER
DELAY 1000
STRING Remove-Item C:\WinUserLanguageList.json
ENTER
DELAY 1000
STRING exit
ENTER
DELAY 1000

GUI r
DELAY 1000
STRING https://ma.kak.si
ENTER

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


text:
Fedora 36 cannot find TTGO32 arduino board
I've been trying to solve this problem for a while now. Fedora 36 cannot recognise my arduino board. Well, not correctly at least.
Arduino IDE v2 picks it up as ttyS4, but platformio only has an empty list for "pio device list".
In addition, "dmesg -w" and any other variation of it doesn't see any new USB devices, even if they do work.
I've tried installing the independent drivers to no avail. I bought a new board to make sure it's not a fried board. I also checked quite a number of USB cables, but still be problem persists.
Finally, I made sure to only use a fresh install of Fedora 36 but still no luck.
Has anyone here had similar problems before and if so any advice on how to get this sorted out? I'm currently using a laptop.

If there is nothing in dmesg -w when you plug the board in then it sounds like you're not using a proper USB data cable but a USB charger cable.

That actually makes a lot of sense... I'll see if I can scavange some more cables and test them as well.

It seems like I did indeed choose the wrong cable. Thank you for your help!


text:
How to correctly synchronize time with NTP server?
I want to synchronize time with NTP server once in some time. I am using DOIT ESP32 DEVKIT V1, I tried with getLocalTime() function but it returned true even without wifi, but as I know without wifi it can not conect to NTP server. Can anyone say if it is possible how to correctly synchronize time with NTP server? Maybe with some other libraries or with other functions.
    #include <WiFi.h>
    #include "time.h"

    const int  gmtOffset_sec = 7200;
    const int  daylightOffset_sec = 3600;
    const char* ntpServer = "pool.ntp.org";

    void setup() {
        Serial.begin(115200);
        Serial.println("Board started\n");
        WiFi.begin("<ssid>", "<password>");
        struct tm timeinfo;

        Serial.print("Connecting...");
        while (WiFi.status() != WL_CONNECTED) {
            delay(500);
            Serial.print(".");
        }
        Serial.println("");
        Serial.println("WiFi connected.");
        configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
        if (!getLocalTime(&timeinfo)) {
            Serial.println("Failed to obtain time 1");
        } else {
            Serial.println("Time obtained 1");
        }
        WiFi.disconnect(true);
        WiFi.mode(WIFI_OFF);
        if (!getLocalTime(&timeinfo)) {
            Serial.println("Failed to obtain time 2");
        } else {
            Serial.println("Time obtained 2");
        }
    }

    void loop() {
    }

The output to console is:
Board started
Connecting....
WiFi connected.
Time obtained 1
Time obtained 2

But I would expect 2nd output to be Failed to obtain time 2.

Also, why the code I posted does not have syntax highlighted?

You can get syntax highlighting with a line \``c++before the code, and```` after it.

upvote for asking how to present readable code

what is the question? it can take some seconds until time is retrieved after connected to WiFi and Internet.  getLocalTime returns time from internal RTC which is set with time retrieved from NTC server

This link may help: https://linuxconfig.org/stay-time-synchronized-with-internet-time-server

@Juraj I want to update rtc time with NTP server time periodically. How to do it the first time - is known, just call getLocalTime() after setting parameters with configTime(). But how to do it the 2nd, 3rd, ... time? getLocalTime() will return the local time and will not sync it with NTP server, am I right?

getLocalTime has nothing to do with NTP. It gets time from RTC. the SDK retrieves time from the Internet and sets it to RTC periodically. study this example https://github.com/esp8266/Arduino/blob/master/libraries/esp8266/examples/NTP-TZ-DST/NTP-TZ-DST.ino


text:
When Writing Library, return String or return char *
I am trying to write my own Arduino library and I would like to make it useful not just for ESP32/ESP8266 boards but also with Arduino boards.
I have created my header file like this

test.cpp

#ifndef TEST
#define TEST
#include "Arduino.h"

#define MAX_STRING_LEN 50

class MyClass{
    private:

    public:
        String getString();
        char * getCharPointer();
        char * getAnotherCharPointer();
};

#endif

and my

test.cpp

#include "test.h"

static char buffer[MAX_STRING_LEN+1];

String MyClass::getString(){
    // Sample REST API call
    String testString = String("{\"test:\" \"hello String json\"}");

    return testString;
}

char * MyClass::getCharPointer(){
    // Sample REST API call
    const char * sample_json = "{\"test:\" \"hello Char Pointer json\"}";
    strcpy(buffer, sample_json);
    return buffer;
}

char * MyClass::getAnotherCharPointer(){
    // Sample REST API call
    const char * sample_json = "{\"test:\" \"hello Another Char Pointer json\"}";
    strcpy(buffer, sample_json);
    return buffer;
}

My test file main.cpp

main.cpp

#include <Arduino.h>
#include "test.h"

MyClass myClass;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);

  Serial.println(myClass.getString());
  Serial.println(myClass.getCharPointer());
  Serial.println(myClass.getAnotherCharPointer());
}

void loop() {
  // put your main code here, to run repeatedly:
}

Result is ok
{"test:" "hello String json"}
{"test:" "hello Char Pointer json"}
{"test:" "hello Another Char Pointer json"}

I have these doubts that I would like to ask for suggestions.

Is returning the String class in Header files, not a good idea?  For ESP32/ESP8266 they are okay as they have big memory but for Arduino Uno boards I see a lot of discussions about not using String because it is bad and causes memory fragmentation etc.
Is returning char * the safest way to make it compatible and useful to all MCU boards?
Next question in char pointer, I often see this pattern done when returning char pointers like in this Time.cpp wherein a static buffer is used and defined at the implementation file (test.cpp) and all functions(getCharPointer, getAnotherCharPointer) that needs to return a char pointer just manipulates the static char buffer by using strcpy.  Is this the proper way to go in Arduino programming?

Can somebody please clear my doubts?  Thank you.

Good question! I am afraid it may be a bit opinion based though. I like the static buffer approach for its memory friendliness. It is, however, dangerous unless the library user is well aware of its implications. Not sure it's suitable for beginners...

If all your functions do is to return a string literal, then just use the string literal directly, those functions are not necessary. The pattern you sited do that because the string literals are stored in the flash memory (PROGMEM) and therefore need to be copy-out into RAM, this however depends on your chip architecture, you need copy-out from FLASH to RAM for classic AVR chips (like ATmega328), however it doesn't required for ARM chips, ESP or even modern AVR chips released since 2016...

@hcheung: I believe those string literals are here only to provide simple dummy examples, and the actual library is going to build the strings from data gathered at run time.

[The OP asks:] For ESP32/ESP8266 they are okay as they have big memory but for Arduino Uno boards I see a lot of discussions about not using String because it is bad and causes memory fragmentation etc.

On Unos and other boards with very low memory, fragmentation won't take very long to happen. On boards with larger memories, it will merely take longer! but it will happen; it's just a difference of when. (And for completeness, I should say that allocating a few objects, once, and within the device's available free memory, won't cause fragmentation, any more than static allocation would).

So why is allocation/deallocation used at all [I ask, rhetorically...]?

On systems running a full OS, driven by ourselves with a keyboard and mouse, most application programs are transient - they start up, do a job, and exit; even longer running ones like office applications are fairly speed-limited by us slow humans. And if a program crashes, we're still sitting there to re-run it, and no external device gets left hanging for hours or days, maybe destroying itself (by overheating, perhaps), maybe injuring or killing a patient (in the case of a medical device), injuring or killing many people (in case of a vehicle's engine- or flight controls).
Otherwise, run-time memory allocation is a convenience for the programmer.

So what to do in an embedded system, instead [asks I]?

I use two techniques to get around the crash-proneness of the compiler-libraries' allocator/deallocators:

When I write a library, I design it to expect an (object *) from the caller, as you anticipated in your 'doubt #3'. All the library has to do is put its result there; the memory will already have been allocated. The library doesn't need to know or care how it was allocated. Does this sound like I'm avoiding solving the problem and leaving memory issues for some else to deal with? Yes, indeed, and it is deliberate! The user of my library - you, (or me, some other day), the application writer/system architect - is the best one to anticipate their particular system's memory needs, and to decide how best to meet them.Writing my library this way lets the library-user decide whether a static buffer, a local one, or a dynamic allocation is the best fit for their application.

I write my own memory management (probably at the application level rather than in the library). This almost always takes the form of an array of fixed-length buffers. No matter how much memory the caller asks for, as long as it is less than that fixed size, and one is available, then the call succeeds and a buffer will be returned; otherwise, the call fails. The caller doesn't know, or need to know, that the buffer returned to them might be larger than they requested.Why is this technique any better? malloc()/free() and new()/delete() break up free memory into ever smaller pieces, as they are requested. A fixed-size-buffer allocater does not break up memory.

A system using these techniques together avoids memory fragmentation. The only way such a system can fail (due to memory allocation) is to not have enough in the first place, and the only fixes are 1) for the programmer to assign more memory for fixed-size buffers; or, if the board doesn't have enough more, then 2) build the system with a host board that has enough memory.

I often see this pattern done when returning char pointers like in this Time.cpp wherein a static buffer is used and defined at the implementation file (test.cpp) and all functions(getCharPointer, getAnotherCharPointer) that needs to return a char pointer just manipulates the static char buffer by using strcpy. Is this the proper way to go in Arduino programming?

Arduino programming is C++ programming. You can return a pointer to a static buffer, of course. But the user of your function needs to know that if they call the function a second time the data will be overwritten. So, they would need to strcpy (that is, copy) the data before it is overwritten.
Personally I would stay away from the String class, unless it is being used only occasionally. It is fine with strings that are always the same size, but if they are not, memory fragmentation will be an issue.


text:
What happen with my code? My sensor module LED2 Always ON
I got this code from robojax.com
i have follow all the step but when i try to clap its not turn off or turn on
but when i blowing on the sound sensor it reacts and makes the light turn on
int soundInPin = 2;// connect output to Sound module DO
int relayPin = 8;// Connected to relay or buzzer (or LED)
int extra5V = 12;// define a pin for extra extra 5V

// do not change values bellow
int val = 0; // sound value from pin 2
int relayON = 0;//light status
int heard = 0;//sound heard status

void setup() {

//Robojax Arduino Step By Step Course http://robojax.com/L/?id=338
  Serial.begin(9600);
  pinMode(soundInPin, INPUT_PULLUP);
  pinMode(relayPin, OUTPUT);
  pinMode(extra5V,OUTPUT);// set extra5V as output
  digitalWrite(extra5V,HIGH);// turn the extra5V pin HIGH to get 5V

}

void loop() {
//Robojax Arduino Step By Step Course http://robojax.com/L/?id=338
  val = digitalRead(soundInPin);// read the sound pin

  if(val == HIGH && relayON == LOW){

    heard = 1-heard;// toggle the value of "heard" from HIGH to LOW or from LOW to HIGH
    delay(100);
  }
//Robojax Arduino Step By Step Course http://robojax.com/L/?id=338
  relayON = val;// save the value of pin 2

      if(heard == HIGH){
        Serial.println("Light ON");
        digitalWrite(relayPin, LOW); // turn relay ON

      }else{
        Serial.println("Light OFF");
        digitalWrite(relayPin, HIGH);// turn relay OFF

      }

//Robojax Arduino Step By Step Course http://robojax.com/L/?id=338
  delay(100);
}

Welcome to Arduino:SE.  If you want us to be able to help you, we'll need to see how you wired the hardware together as well as your code.

Is there something on the sound sensor board to adjust the threshold? Like potentiometer ?

With no schematic it is difficult to understand what to expect at soundInPin.  That said, inspecting the code, if "val" changes to 1,  "heard" changes to 1, "relayON" changes to 1, the LED is turned on then the LED is never turned off because "relayON" is 1 which does not allow "heard" to change ever again.  So despite what the hardware does, the code appears to need some more work.

Hello, Mr. Myth! Let's start from the basics: 1. What Arduino board? 2. What is it you are trying to do (explain, please), and 3. (As others have said) what does your schematic look like?

Have you seen this answer? https://arduino.stackexchange.com/a/54495/37523

This is not an answer, so I will delete it after you read it.
Since you are a beginner, here is a comment on programming style.
Your code feels very cluttered and overwhelming because the comments are made a part of the program lines.
There is a difference in readability between these two lines.
digitalWrite(extra5V,HIGH);// turn the extra5V pin HIGH to get 5V
digitalWrite(extra5V,HIGH);                // turn the extra5V pin HIGH to get 5V
The comments are there for future, like next year, to remind you what the program does.
Also the following two lines are on the same indentation level
  relayON = val;     // save the value of pin 2

      if(heard == HIGH){

and should be
  relayON = val;     // save the value of pin 2

  if(heard == HIGH){

With some formatting changes, your code could look something like this.
int soundInPin =  2;                       // connect output to Sound module DO
int relayPin   =  8;                       // Connected to relay or buzzer (or LED)
int extra5V    = 12;                       // define a pin for extra extra 5V

// do not change values below

int val        =  0;                       // sound value from pin 2
int relayON    =  0;                       // light status
int heard      =  0;                       // sound heard status

void setup() {                             // Robojax Arduino Step By Step Course http://robojax.com/L/?id=338

  Serial.begin(9600);

  pinMode(soundInPin, INPUT_PULLUP);
  pinMode(relayPin,   OUTPUT);
  pinMode(extra5V,    OUTPUT);             // set extra5V as output

  digitalWrite(extra5V,HIGH);              // turn the extra5V pin HIGH to get 5V

}

void loop() {                              // Robojax Arduino Step By Step Course http://robojax.com/L/?id=338

  val = digitalRead(soundInPin);           // read the sound pin

  if (val == HIGH && relayON == LOW) {

    heard = 1-heard;                       // toggle the value of "heard" from HIGH to LOW or from LOW to HIGH
    delay(100);

  }                                        // Robojax Arduino Step By Step Course http://robojax.com/L/?id=338

  relayON = val;                           // save the value of pin 2

  if (heard == HIGH) {

    Serial.println("Light ON");
    digitalWrite(relayPin, LOW);           // turn relay ON

  } else {

    Serial.println("Light OFF");
    digitalWrite(relayPin, HIGH);          // turn relay OFF

  }
                                           // Robojax Arduino Step By Step Course http://robojax.com/L/?id=338
  delay(100);
}


text:
How to get the scan duration below 1 sec with Arduino BLE?
I want to scan continuously for other Bluetooth devices with my ESP32 using BLE. The scan method only accepts integers larger than 0, such as scan->start(1, false). However I want the results to be more "responsive" and a 1-second scanning duration is too long. This is my sample code:
#include <Arduino.h>
#include <BLEAdvertisedDevice.h>
#include <BLEDevice.h>
#include <BLEScan.h>
#include <string>
#include <iostream>

const int PIN = 2;
const int CUTOFF = -40;
BLEScan* scan;

#define SERVICE_UUID "f5aeb701-4395-4387-b8d4-e1f542b05151"
#define CHARACTERISTIC_UUID "b2bd617f-6f78-45e7-bfdd-3edf29a5661a"

void setup() {
  pinMode(PIN, OUTPUT);
  BLEDevice::init("ESP32 GrooveBrick");
  Serial.begin(9600);
  BLEServer *pServer = BLEDevice::createServer();
  BLEService *pService = pServer->createService(SERVICE_UUID);
  BLECharacteristic *pCharacteristic = pService->createCharacteristic(
    CHARACTERISTIC_UUID,
    BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_WRITE);
  pService->start();
  BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
  pAdvertising->addServiceUUID(SERVICE_UUID);
  pAdvertising->setScanResponse(true);
  pAdvertising->setMinPreferred(0x06);  // functions that help with iPhone connections issue
  pAdvertising->setMinPreferred(0x12);
  scan = BLEDevice::getScan();
  scan->setActiveScan(true);
  /*!< Scan interval. This is defined as the time interval from
    when the Controller started its last LE scan until it begins the subsequent LE scan.
    Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
    Time = N * 0.625 msec
    Time Range: 2.5 msec to 10.24 seconds*/
  scan->setInterval(100); //interval (how often there is a scan)
  /*!< Scan window. The duration of the LE scan. LE_Scan_Window
    shall be less than or equal to LE_Scan_Interval
    Range: 0x0004 to 0x4000 Default: 0x0010 (10 ms)
    Time = N * 0.625 msec
    Time Range: 2.5 msec to 10240 msec */
  scan->setWindow(99);  // window (how long the scans are) must be <= interval
  BLEDevice::startAdvertising();
}

void loop() {
  BLEScanResults results = scan->start(1, true);
  int best = CUTOFF;

  std::cout << "Scanning!" << "\n";
  for (int i = 0; i < results.getCount(); i++) {
    BLEAdvertisedDevice device = results.getDevice(i);
    std::cout << "Found BT-device: " << device.getName() << " RSSI: " << std::to_string(device.getRSSI()) << "\n";
    int rssi = device.getRSSI();
    if (rssi > best) {
      best = rssi;
    }
  }
  digitalWrite(PIN, best > CUTOFF ? HIGH : LOW);
  scan->clearResults();   // delete results fromBLEScan buffer to release memory
}

Did you ever resolve this issue?

Hi, IIRC I never solved this.. sry

You can't using the callback from that function, but what you can do is add you own callback that will receive every new radio event.
Add this to your init code:
BLEDevice::setCustomGapHandler(custom_handler);

and this before it:
static void it_gap_cb(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param_t *param)
{
    switch (event)
    {
        case ESP_GAP_BLE_SCAN_RESULT_EVT:
            if (param->scan_rst.search_evt == ESP_GAP_SEARCH_INQ_RES_EVT)
            {
                // This event is triggered every time a new device is found, and contains the advertised data.
                // We should avoid processing or printing anything here to avoid hardware congestion
                // log_i("ESP_GAP_BLE_SCAN_RESULT_EVT");

                if (param->scan_rst.ble_adv != NULL)
                {
                    //this makes sure that there is data to be processed
                }
            }
            break;
        default:
            // log_i("Event %d unhandled", event);
            break;
    }
}


text:
DHT11 stops working when power comes from a power supply board
I had a mini project with a DHT11, a temperature and humidity sensor, working perfectly on my Arduino UNO clone. Then, I bought a power supply board, that can feed the sensor with the 5V it requires, but for some reason, it does not work. Powering the sensor with the Arduino makes it get the correct values, powering it with the board makes it to stop working at all.
I have used a multimeter for checking the volts and amps. The readings on the sensor are the same with the Arduino and the board, 5V, but the amps are not. It seems that the sensor only uses power for an instant, while "sensing". Using Arduino, a 1.62mA current flows to the sensor and then drops to 0, but using the board it never gets higher than 0.001mA.
I repeated the test with different wires, protoboards and even power supply boards. I have three of them, all working apparently ok and reading the same on the multimeter. The board have the jumpers in the correct position: 5V.
I am just an amateur learning how electronics works, and I do not understand what is happening here. Some ideas?
Working:

Not working:

I don't think the problem is in the code, but just in case...
#include "DHTStable.h"

DHTStable DHT;

#define DHT11_PIN 5

void setup() {
    Serial.begin(115200);
    Serial.println(__FILE__);
    Serial.print("LIBRARY VERSION: ");
    Serial.println(DHTSTABLE_LIB_VERSION);
    Serial.println();
    Serial.println("Type,\tstatus,\tHumidity (%),\tTemperature (C)");
}

void loop() {

    // READ DATA
    Serial.print("DHT11, \t");
    int chk = DHT.read11(DHT11_PIN);

    switch (chk)
    {
        case DHTLIB_OK:
            Serial.print("OK,\t");
            break;
        case DHTLIB_ERROR_CHECKSUM:
            Serial.print("Checksum error,\t");
            break;
        case DHTLIB_ERROR_TIMEOUT:
            Serial.print("Time out error,\t");
            break;
        default:
            Serial.print("Unknown error,\t");
            break;
    }

    // DISPLAY DATA
    Serial.print(DHT.getHumidity(), 1);
    Serial.print(",\t");
    Serial.println(DHT.getTemperature(), 1);

    delay(2000);
}

Sensors needs to be connected to the same ground as the Arduino. In the image below that is not the case. Connect the ground (and only the ground, not the +5V) of your external power supply to the ground of the Arduino and the DHT11 will probably work again.

@StarCat That was it! Adding a wire for connecting the power supply board ground to the Arduino ground made it work. Could you post your comment as an answer for me to mark it as the correct one? Also, if you could explain a little why was that necessary it would be great. Thank you.

In your question in the image below your grounds are not connected. The solution to your problem is to connect the ground (and only the ground, not the +5V) of your external power supply to the ground of the Arduino and the DHT11 will probably work again.
A bit of background
Sensors needs to be connected to the same ground as the Arduino. This is true in general with all parts of an electronic circuit. Ground functions as a fixed, common, reference voltage by which other signals (such as the digital data that's exchanged between the DHT11 sensor and the Arduino) are measured.
By connecting grounds, you make sure that a "high" that is output by the DHT11 is read as a "high" by Arduino and vice versa. When grounds are not connected, voltages between two parts of the circuit would "float" relative to each other and they would not be able to communicate. This link explains a bit more.

Thank you very much! I learned something today.


text:
Why wont my custom Arduino-Micro-based board receive power via USB?
UPDATE: I believe I have mostly solved the power issues, but now have USB connectivity issues described in EDIT 3 at the bottom.
I designed and printed a PCB for my MIDI controller project with a modified Arduino Micro microcontroller built in. I swapped out the USB Micro for a USB-C type port (just using the 2.0 protocol), but when I plug it in, after programming the bootloader to the ATMEGA32U4 via "Arduino as ISP" with an Uno as ISP to the ICSP of my board, my board seems to get no power from the USB bus (the power LED doesn't light up, nor is it recognized as a USB device), but it does get power over the ICSP and I got a success message after programming it with the Uno.
I have tried many USB cables, including USB-C ones I know to be 2.0 compatible and USB Micro cables (which have been tested with regular Arduino Micros) with micro-to-C adapters, but still get nothing. My PCB has full parity with my SCH file, and I tested it on multiple  of these boards that I got printed, so I am pretty sure I must have messed something up in the schematic or in component selection (not all the exact components from the official Arduino Micro schematic were available at JLCPCB where I had mine printed so I made some substitutions).
Can anyone help me figure out what the issue might be?
EDIT 1: So I found out that the power is coming in through the USB,  its reading 5V at the USB pins, 5V on either side of the fuse F1 and the VUSB pin of the T1 FDN340P/PMV48XP, but 0V at both the VIN and +5V pins of the same T1, so that seems to be the problem component? I'm using a PMV48XP in that position, not sure if I messed that up somehow? I'm a bit out of my depth here I think
I've uploaded the schematic and the component list below:

Components:
| Designator                                             | Value                   | Component                |
|:--------------------------------------------------------|:-------------------------|:--------------------------|
| C_ARD_1, C_ARD_2, C_ARD_6, C_ARD_9, C_ARD_10, C_ARD_11 | 100n                    | CL05B104KO5NNNC          |
| C_ARD_3, C_ARD_14                                      | 22u                     | RVT22UF16V67RV0017       |
| C_ARD_4, C_ARD_5, C_ARD_7                              | 1uF                     | CL05A105KA5NQNC          |
| C_ARD_12, C_ARD_13                                     | 22pF                    | 0402CG220J500NT          |
| D_ARD_2                                                | CD1206-S01575           | CDSU4148-HF              |
| F1                                                     | MF-MSMF050-2 500mA      | MF-MSMF050-2             |
| J3                                                     | USB_C_Receptacle_USB2.0 | KH-TYPE-C-16P            |
| L1                                                     | green                   | 19-217/GHC-YR1S2/3T      |
| L2                                                     | MH2029-300Y             | BLM21PG300SN1D           |
| ON1                                                    | blue                    | 19-217/BHC-ZL1M2RY/3T    |
| R_ARD_1, R_ARD_2, R_ARD_4, R_ARD_9                     | 10K                     | 0402WGF1002TCE           |
| R_ARD_5, R_ARD_6, R_ARD_7, R_ARD_8                     | 1K                      | 0402WGF1001TCE           |
| R_ARD_10, R_ARD_11                                     | 5.1k                    | 0402WGF5101TCE           |
| RP3                                                    | 22R                     | 4D03WGJ0220T5E           |
| RX1, TX1                                               | yellow                  | 19-213/Y2C-CQ2R2L/3T(CY) |
| T1                                                     | FDN340P/PMV48XP         | PMV48XP                  |
| T2                                                     | PMV48XP                 | PMV48XP                  |
| U1                                                     | ATMEGA32U4-XUMU         | ATMEGA32U4-MU            |
| U2                                                     | NCP1117-5               | NCP1117ST50T3G           |
| U4                                                     | LP2985-33DBVR           | LP2985-33DBVR            |
| Y3                                                     | 16MHz KX-7              | 3225-16.00-10-10-10/A    |
| Z1, Z2                                                 | CG0603MLC-05E           | EZJZ0V500AA              |

EDIT 2: I think I found the problem. It looks like something got messed up when I was choosing the footprints of the MOSFET transistors T1 and T2. Here is a screenshot from the datasheet of the PMV48XP datasheet showing the pinning info:

and now here is a screenshot of the relevant part of my PCB file:

So according to my schematic (again, based on the official Arduino Micro SCH, so I'm assuming its correct?) T1 Gate should be VIN, T1 Source should be +5V, T1 Drain should be VUSB. On my PCB T1 Gate is actually VUSB, T1 Source is +5V, T1 Drain is actually VIN. So it looks like the Gate and Drain pins got swapped between my SCH and my PCB. Same story for T2.
Can anyone with more knowledge confirm that the connections outlined in the schematic are correct? And whether that would explain the problems I've described?
EDIT 3: I have de-soldered T1 and T2, which were in indeed incorrectly wired. I have shorted the contacts between VUSB and +5V on the footprint of T1 and the board is getting power as it is supposed to.
Now I have a new issue which is that after I have programmed the board via ICSP (using the Arduino as ISP method, burning the Arduino Micro bootloader to it), when I plug the board into my computer (again, testing with a variety of cables and ports), my computer won't recognize it as a USB device. I'm not sure if this is a related problem to my previous one (and maybe I should make a new post if not?) or where I am going wrong now.

Were you testing with a USB-A to USB-C table?

@timemage I have tried several USB-A to USB-C and a couple different USC-C to USB-C cables (as well as both to micro to micro-to-C adapters)

@jsotola Great point, not sure why I didn't try measuring it. I updated my post with more details, but I'll reiterate it here: I found out that the power is coming in through the USB, it's reading 5V at the USB pins, 5V on either side of the fuse F1 and the VUSB pin of the T1 FDN340P/PMV48XP, but 0V at both the VIN and +5V pins of the same T1, so that seems to be the problem component? I'm using a PMV48XP in that position, not sure if I messed that up somehow? I'm a bit out of my depth here I think

See if 5V gets to pin 2 of J4. If it does you're probably just having trouble getting through oxide or flux gunk or something directly at the T1 lead.

@timemage So I'm not getting 5V at pin 2 of J4 or anywhere else +5V is marked on the SCH, but I think I found the problem. I added more details at the bottom of my original post, but I somehow have the drain and gate pins mixed up for each of my transistors T1 and T2 between my schematic and my PCB file, so I believe that's what's causing my problems, if I'm reading my own SCH and PCB files correctly

The T1 and T2 footprints are incorrect as you have said. If you are not going to use Vin to power the device and are going to use the USB  cable only,  you could unsolder T1 and T2. On the footprint of T1, bridge the pads marked VUSB and +5V.
During programming via the ICSP header, ensure the USB cable is disconnected. That all as an alternative to reworking the board in a more substantial way.

@6v6gt Appreciate the confirmation and the suggestion. I gave it a try and it seems to be getting power from the USB now! I must have messed something else up however  or have missed a step, since my computer isn't recognizing it as a USB device even after I have programmed it via the ICSP

I think you need to understand a little bit of how the T1 and T2 functions in order to troubleshoot. The purpose of T1 is when power is supplied via VBUS, and when Vin is not presented (i.e. at 0v), the VUSB is directly supplied as the 5V(bypassing the NCP1117 regulator). However, when you power via Vin and it is at least higher than 5V(likely at 7V), it will turn off the T1 and cut off the VUSB supply, and T2 is on, Vin is apply as the input to the NCP1117.
So with this in mind, if you connect your board via VBUS but can't get 5V, then you either has a malfunction T1 or you had connect T1 drain and source wrongly. However, if you supply your board via Vin, and don't get the 5V, there could be that your Vin is not high enough to turn on the T2, or your had wrong connection on T2.

Thanks, I appreciate the info as I am clearly not super knowledgeable here. It looks as though I incorrectly connected the gate and drain on both T1 and T2 and have de-soldered them and shorted VUSB and +5V to use VUSB directly.
In the future I hope to revise my board to fix the error without needing to short any connections, and since I plan on always powering the board via the USB, it sounds like the best approach is to simplify the design and remove unneeded components, if I am understanding things correctly? Could I simply remove T1, T2 and the NCP1117 regulator and use VUSB as +5V?

If you do not breaks out the Vin pin for user to connnect via Vin, then yes, you can remove T1, T2, R_ARD_9 and NCP1117, and supply the board directly via USB.


text:
How do I go about pausing/stopping the timer1 task setup in this library, so I can use timer1 for something else in my code
So I want to use this library, that uses timer1 to fetch samples from analog input on pin A0.
It works great, and so after proper detection I'd like to perform all kinds of different tasks. But for those I need timer1 again and I think this library keeps it's timer1 routine continuously running. (Am I right?)
(EDIT: clarification) I think therefore a different library using timer1 won't work as expected. That's why after the first library's task is done, I'd like to free up timer1 for the second library.)
/*
  Original text created by Jacob Rosenthal:

  The Goertzel algorithm is long standing so see
  http://en.wikipedia.org/wiki/Goertzel_algorithm for a full description.
  It is often used in DTMF tone detection as an alternative to the Fast
  Fourier Transform because it is quick with low overheard because it
  is only searching for a single frequency rather than showing the
  occurrence of all frequencies.

  This work is entirely based on the Kevin Banks code found at
  http://www.embedded.com/design/configurable-systems/4024443/The-Goertzel-Algorithm
  so full credit to him for his generic implementation and breakdown. I've
  simply massaged it into an Arduino library. I recommend reading his article
  for a full description of whats going on behind the scenes.

  Created by Jacob Rosenthal, June 20, 2012.
  Released into the public domain.

  Modifications 6v6gt 09.09.2019
  1. Restructure instance variables to permit multiple instances of class.
  2. Make sample array static to share it between instances
  3. Pass in sample array as pointer so it can be reused outside class.
  4. Drive ADC by timer1 instead of polling ADC in loop()
      and reduce resolution to 8 bits.
  5. Separate coeeficient calculation from constructor because it
       now relies on data unknown at invocation (sample rate)
  5. Some consolidation of methods.
  6. Software "as is". No claims made about its suitability for any use.
       Use at your own risk. Special care required if you use other
       analog inputs or an AVR chip other than ATmega328P (Uno etc.).
*/

#include "Arduino.h"
#include "Goertzel.h"

// set by Goertzel::init()
uint8_t * Goertzel::testData;             // static declaration in .h
uint16_t Goertzel::N ;                    // ditto
uint16_t Goertzel::SAMPLING_FREQUENCY ;   // ditto

volatile bool Goertzel::testDataReady = false ; // static declaration in .h

//ADC interrupt service routine
ISR(ADC_vect) {
  // load sample buffer on sample conversion.
  static uint16_t sampleIndex = 0 ;
  if ( ! Goertzel::testDataReady   ) {
    if ( sampleIndex < Goertzel::N  ) {
      *(Goertzel::testData + sampleIndex++ )  = ADCH ; // 8 bits. Direct adressing into byte buffer
    }
    else  {
      Goertzel::testDataReady = true ;    // make buffer available to consumer
      sampleIndex = 0 ;
    }
  }
  TIFR1 = _BV(ICF1); // reset interrupt flag
}

// constructor
Goertzel::Goertzel(float TARGET_FREQUENCY  )
{
  _TARGET_FREQUENCY = TARGET_FREQUENCY; //should be integer of SAMPLING_RATE/N
}

//static method
void Goertzel::init( uint8_t *sampleArray , uint16_t sampleArraySize, uint16_t sampleFrequency ) {
  // set up sample array, number of samples and sample frequency.

  // load class static variables
  testData = sampleArray ;
  N = sampleArraySize ;
  SAMPLING_FREQUENCY = sampleFrequency ;

  // initialise ADC and Timer1. Timer1 triggers ADC at frequency SAMPLING_FREQUENCY.
  // ISR(ADC_vect) called when conversion complete.
  cli() ;

  // Setup Timer1 for chosen sampling frequency.
  TCCR1A = 0;
  TCCR1B = _BV(CS10)  |    // Bit 2:0 – CS12:0: Clock Select =  no prescaler
           _BV(WGM13) |    // WGM 12 = CTC ICR1 Immediate MAX
           _BV(WGM12);     // WGM 12 ditto
  ICR1 = ( (F_CPU ) / SAMPLING_FREQUENCY ) - 1;

  // Setup ADC for triggering by timer1; 8bit resolution; Analog Port PC0 (pin A0) ADMUX
  ADMUX =  _BV(REFS0) ;    // Fixed AVcc reference voltage for ATMega328P
  ADMUX |= _BV(ADLAR) ;    // left adjust conversion result in ADCH (8bit)
  DIDR0 |= _BV(ADC0D);     // DIDR0  Digital Input Disable Register 0
  ADCSRB = _BV(ADTS2) |    // Bit 2:0  ADTS[2:0]: ADC Auto Trigger Source
           _BV(ADTS1) |    // Timer/Counter1 Capture Event
           _BV(ADTS0);     // ditto

  ADCSRA = _BV(ADEN) |      // Bit 7   ADEN: ADC Enable
           _BV(ADSC) |      // Bit 6   ADSC: ADC Start Conversion
           _BV(ADATE) |     // Bit 5   ADATE: ADC Auto Trigger Enable
           _BV(ADIE) |      //
           _BV(ADPS0) |     // Bits 2:0  ADPS[2:0]: ADC Prescaler Select Bits  (div 8 )
           _BV(ADPS1);      // ditto
  sei() ;

}

// instance method
void Goertzel::getCoefficient( void ) {
  // previously in constructor. Now SAMPLING_FREQUENCY unknown at invocation time.
  float omega = (2.0 * PI * _TARGET_FREQUENCY) / SAMPLING_FREQUENCY;
  coeff = 2.0 * cos(omega);
}

// instance method
float Goertzel::detect()
{
  Q2 = 0;
  Q1 = 0;
  for ( uint16_t index = 0; index < N; index++)
  {
    // byte sample is ( *( testData + index ) );
    float Q0;
    Q0 = coeff * Q1 - Q2 + (float) ( *( testData + index ) - 128 ) ; //  128 for 8bit; 512 for 10bit resolution.
    Q2 = Q1;
    Q1 = Q0;
  }

  /* standard Goertzel processing. */
  float magnitude = sqrt(Q1 * Q1 + Q2 * Q2 - coeff * Q1 * Q2);
  return magnitude  ;
}

I'm new to using timers on Arduino, but I want to understand and learn more about it. So I'm reading up on it. Seeing that it's not the easiest subject to wrap my head around I'd like to ask for some directions.
On this splendid page I gathered some examples of stopping / disabling timer1.
  TCCR1B = 0;
  TIMSK1 = 0;    // disable Timer1 Interrupt

Nick Gammons Timer info page
However I don't completely recognise the usage of the library's timer names, registers, variables yet. And so I'm unsure what part of the code is doing what exactly, ie where, how and when the timer starts. And therefore I'm equally unsure how to go about stopping it when the task is done, and to start it again when a new detection is needed. It seems there is TCCR1A, TCCR1B, cli() and sei() that have something to do with it and ISR(ADC_vect). One of you probably knows ;)
EDIT: Reading the suggested ATmega328p datasheet I found out a little bit more about the following abbreviations:
cli // disable interrupts during timed sequence __disable_interrupt();
sei // Set global Interrupt Enable __enable_interrupt();
TCNT1 // Timer/Counter (setting 0 will reset)
TIFR1 // Timer Interrupt Flag Register
TCCR1A // Timer/Counter Control Register 1a (setting 0 will reset)
TCCR1B // Timer/Counter Control Register 1b (setting 0 will reset)
TIMSK1 // Timer Interrupt Mask Register
ICR1 // Input Capture Register
ICF1 // Input Capture Flag
ICP1 // Input Capture Pin
WGM // Waveform Generation Mode
CS // Clock Select Bits (prescaler??)
F_CPU // The CPU speed (What is the default value? 8000000??? 1000000??? 16000000???)
DIDR1/DIDR0 // Digital Input Disable Registers (if left enabled they will use excessive power when Analog input is floating or close to VCC/2)
ADMUX // ADC Multiplexer Selection Register
REFS1 & REFS0 // Voltage Reference Selection
ADLAR // ADC Left Adjust Result
MUX
ADEN // ADC Enable
ADSC // ADC Start Conversion
ADATE // ADC Auto Trigger Enable
ADTS // ADC Trigger Source Select
ADCSRB //
ADIE // ADC Conversion Complete Interrupt Enable
ADPS0 & ADPS0 // ADC Prescaler Select Bits

But hasn't really lightened things up entirely for me. What is _BV? for example.
EDIT: I think I'm starting to make sense of it more. Am I right here(??):
ADMUX = (0b00 << REFS0) | (1 << ADLAR) | (0b00000 << MUX0);
Is the same as:
ADMUX = (0b00 << REFS0); // 0 shift has no effect so can be omitted
ADMUX |= (1 << ADLAR);
ADMUX |= (0b00000 << MUX0); // 0 shift has no effect so can be omitted
Is de same as:
ADMUX = (1 << REFS0); // can be omitted
ADMUX |= (1 << ADLAR);
ADMUX |= (1 << MUX0); // can be omitted
is the same as:
ADMUX = _BV(REFS0); // can be omitted
ADMUX |= _BV(ADLAR);
ADMUX |= _BV(MUX0); // can be omitted
Is the same as:
ADMUX = (1 << ADLAR);
Is the same as:
ADMUX = _BV(ADLAR);

Understanding it all would be great, but may be unnecessary.
If only I'd know how I can stop and free Timer1 usage for other purposes. Starting it all up again would be easier I guess ;)

Did you try looking at the datasheet of the Atmega328p (which is the microcontroller on the Uno/Nano)? The register names (like TCCR1A) are from there. It also describes the function of each bit in each register.

Doing that now.

Re “What is _BV?”: As stated in the documentation:, #define _BV(bit) (1 << (bit))

What is the difference between:
TIFR1 = _BV(ICF1); And
TIFR1 |= bit (OCF1A);
In code comments they both are said to clear the Input Capture Flag or the Interrupt Flag register...

Re _BV() vs bit(): _BV() comes from the avr-libc, whereas bit() is from the Arduino core. Otherwise they are basically the same, except that bit() returns an unsigned long.

Look, guys, comments under a question are for clarifying the question. Not for answering it. See that big "answer" box? That's where answers go. :)

Mine was in the answer field first, bit got moved. Meanwhile, putting it this way, your answer should perhaps have been a comment?

Time hasn't been on my side lately. But here is the code I've come up with so far. Needs testing still to see if it solves all my problems but in regards to my original question this seems to hold the answer I was looking for. Later on I might add some more info/links to register settings, hex/binary/ascii tables, bitwise operations and what they all do. But the manual is your friend pretty much.
Alright then. First of all this print function comes in handy:
// Handy while experimenting with all different bitwise operations and settings
void printRegSettings() {
  const String regNames[8] = {"TCCR1A", "TCCR1B", "ICR1", "ADMUX", "DIDR0", "ADCSRA", "ADCSRB", "TIFR1"}; //other: "TCNT1", "OCR1A", "OCR1B", "TIMSK1"
  uint8_t regVars[8] = {TCCR1A, TCCR1B, ICR1, ADMUX, DIDR0, ADCSRA, ADCSRB, TIFR1}; //other: TCNT1, OCR1A, OCR1B, TIMSK1

    for (uint8_t index = 0; index < sizeof(regVars)/sizeof(regVars[0]); index++) {
      Serial.print(regNames[index]+" = 0b");
      for (uint8_t i = 8; i > 0; i--) {
        Serial.print(bitRead(regVars[index], i-1));
      }
    Serial.write('\n');
    }
}

Next put all library register settings in function, notice the boolean in the end, for emptying the ISR (later described):
void dtmfTimerSetup () {

  TCCR1A = 0;
  TCCR1B = _BV(CS10) | // Bit 2:0 – CS12:0: Clock Select = no prescaler
           _BV(WGM13) | // WGM 12 = CTC ICR1 Immediate MAX
           _BV(WGM12); // WGM 12 ditto
  ICR1 = ( (F_CPU ) / 9600 ) - 1;

  ADMUX = _BV(REFS0) ; // Fixed AVcc reference voltage for ATMega328P
  ADMUX |= _BV(ADLAR) ; // left adjust conversion result in ADCH (8bit)
  DIDR0 |= _BV(ADC0D); // DIDR0 Digital Input Disable Register 0
  ADCSRB = _BV(ADTS2) | // Bit 2:0 ADTS[2:0]: ADC Auto Trigger Source
           _BV(ADTS1) | // Timer/Counter1 Capture Event
           _BV(ADTS0); // ditto
  ADCSRA = _BV(ADEN) | // Bit 7 ADEN: ADC Enable
           _BV(ADSC) | // Bit 6 ADSC: ADC Start Conversion
           _BV(ADATE) | // Bit 5 ADATE: ADC Auto Trigger Enable
           //_BV(ADIE) | //
           _BV(ADPS0) | // Bits 2:0 ADPS[2:0]: ADC Prescaler Select Bits (div 8 )
           _BV(ADPS1); // ditto

  Goertzel::dtmfListenerISR = true;
}

Next add a function to clear all these settings. Initial values of registers is 0 as far as I checked. So setting them zero does the job. Again notice the boolean false this time.
void clearTimerSettings() {
  //Empty Goertzel dtmf interrupt ISR routine
  Goertzel::dtmfListenerISR = false;

  //reset all altered registers to initial value 0
  Serial.println(F("***CLEARING ALL BIT SETTINGS***"));
  TCCR1A = TCCR1B = ICR1 = ADMUX = DIDR0 = ADCSRA = ADCSRB = TIFR1 = 0;

// pauze but don't erase current interrupt settings:
// bitClear(ADCSRA, ADIE); //risk interference when different timer adc library sets bit again
}

In Goertzel.h Add this static bool declaration to class Goertzel public:
static volatile bool Goertzel::dtmfListenerISR;

Add boolean declaration to Goertzel.cpp and add 'if statement' inside ISR(ADC_vect) to only execute interrupt if dtmfListenerISR is true.
volatile bool Goertzel::dtmfListenerISR;

//ADC interrupt service routine

ISR(ADC_vect) {
  //if dtmfListenerISR is false, this code is skipped, freeing timer1 for other purposes
  if (Goertzel::dtmfListenerISR) {

    // load sample buffer on sample conversion.
    static uint16_t sampleIndex = 0 ;
    if ( ! Goertzel::testDataReady  ) {
      if ( sampleIndex < Goertzel::N  ) {
        *(Goertzel::testData + sampleIndex++ )  = ADCH ; // 8 bits. Direct adressing into byte buffer
      }
      else  {
        Goertzel::testDataReady = true ;    // make buffer available to consumer
        sampleIndex = 0 ;
      }
    }
    TIFR1 = _BV(ICF1); // reset interrupt flag
  }
}

Finally use these functions like this in your sketch. The setup can be done in setup but the clearing should take place in your void loop of course, once the library and timer interrupt have finished their job and you want another library / timer routine to take over. Just for testing I put them all inside a setup and a simple sketch now.
void setup() {
  Serial.begin(115200);
  //setup/initialize timer interrupt routine:
  dtmfTimerSetup();
  //FOR TESTING: check and print current settings:
  printRegSettings();
  //clear timer interrupt routine;
  clearTimerSettings();
  printRegSettings(); //only for testing purposes

}

void loop() {
  // put your main code here, to run repeatedly:
}

Ofcourse for the other libraries using timer1 you should do the same: setup functions with register settings / cleanup and declare/set boolean for ISR part. There might be some overkill here, but so far I didn't find a more elegant way of achieving all this.

I'm not sure why you need to stop the timer in the first place. Timers are just things that count "ticks" which can be programmed to arrive at various speeds (usually some division of the processor speed).
Imagine you have a clock in your kitchen. And imagine you are baking a cake. You observe the time that you put the cake into the oven. Then you note at what time the cake will be done. Meanwhile that same clock can be used to time boiling an egg. You don't need to stop or "reset" the clock to achieve this.
Just let the clock run and do its thing, and meanwhile make a note of what time needs to arrive for things to be "done".
Meanwhile, the Uno (and Nano) have other timers. You can use those. It's like owning three clocks, that can run at different speeds — or perhaps more accurately — different levels of precision.

That's because I'd like to use another (more complex) library not written by me, that uses timer1. And it seems their usage collide. Because they both want to use their favourite kitchen clock I guess ;) And I'm not yet the coding diplomat needed to convince them otherwise.

in short: I didn't want to stop the timer (as in clock) but rather the task (interrupt / isr) associated with it. I could've worded my question better perhaps, but I couldn't before because I didn't know the right words. It seems people use 'setup a timer' when they actually mean: 'setup an ISR interrupt routine' or whatever.

I am answering here only a tiny part of the question:

ADMUX = (0b00 << REFS0); // 0 shift has no effect so can be omitted
ADMUX |= (1 << ADLAR);
ADMUX |= (0b00000 << MUX0); // 0 shift has no effect so can be omitted

Is de same as:
ADMUX = (1 << REFS0); // can be omitted
ADMUX |= (1 << ADLAR);
ADMUX |= (1 << MUX0); // can be omitted

No, it is not the same.
Starting from the first line: (0b00 << REFS0) means “zero
left-shifted by REFS0 (i.e. six) bits”. It is not a zero shift, as
stated in the comment: it is a 6-bit shift. The resulting value is zero,
because the number being shifted is zero to start with, and because
vacated bits are zero-filled during a left-shift.
In contrast, (1 << REFS0) means “one left-shifted by REFS0 bits”.
The resulting value is:
2REFS0 = 26 = 0b01000000 = 64
In the first code snippet, ADMUX ends up with only the ADLAR bit being
set. In the second snippet, all three bits (REFS0, ADLAR and MUX0) are
set.
Edit: explaining the notion that “vacated bits are zero-filled
during a left-shift”. Let's assume x = 0bABCDEFGH is a byte, where A…H
are the individual bits (“0b” is a prefix meaning “what follows is in
binary”). Left-shifting this byte gives the following:
x << 0 = 0bABCDEFGH
x << 1 = 0bBCDEFGH0
x << 2 = 0bCDEFGH00
x << 3 = 0bDEFGH000
...

By “vacated bits are zero-filled” I mean that the bits that are beyond
the last original bit (beyond H) are replaced by zeros. Note that a zero
shift “has no effect” in the sense that x<<0 is the same as x. Note
also that shifting the value zero by any amount always yields zero.
In this particular code, the value being written to ADMUX can be
computed as follows:
1 << REFS0 = 1 << 6 = 0b00000001 << 6 = 0b01000000
1 << ADLAR = 1 << 5 = 0b00000001 << 5 = 0b00100000
1 << MUX0  = 1 << 0 = 0b00000001 << 0 = 0b00000001
──────────────────────────────────────────────────
(1<<REFS0) | (1<<ADLAR) | (1<<MUX0)   = 0b01100001

Thanks for taking the time to look at this. I have some more reading to do I suppose. And see if I can find back the source of that comment.

could you elaborate on this: "vacated bits are zero-filled during a left-shift". I'm confused because I thought a shift operation only affects the shifted bit, but now I'm reading the whole row of bits might be shifted left (or right). Then there's also the difference between the logical OR or AND. In case of a zero shift with an OR, does it have an effect at all? And a 1 shift with an OR? Does it have an effect on vacated bits?

@Gaai: What do you mean by “zero shift”? Shifting some number by zero bits or shifting the number zero by some number of bits? What do you mean by “have an effect”? Every expression has the effect or returning some value. Re OR vs AND: please look up the truth tables of these operators yourself. For the rest, see amended answer.

With having an effect I meant: actually setting/changing/writing to the bit. Instead of just reading, which is an effect aswell, as you noted, of course.

I found this line of code with the comment on a forum. I didn't use it right. But I was struggling to understand why I didn't see a bit setting for A0 as the input pin. While when other pins where used (elsewhere by people) they set these with (MUX0, MUX1, MUX2 or other ways even as it seems there are always more ways to do the same in bit settings). Anyway, I tought this might be because A0 was set by some zero setting elsewhere (called a zero shift), which meant it could be left out... I know better now how this is done, thanks to you and some further reading. It's a confusing journey ;)

so I tried ADMUX = _BV(0); //setting 0b00000001
and then ADMUX = _BV(7); //expecting the above to shift left to get 11000000. But bitRead gives me: 01000000. Setting ADMUX to 11111111 first and then doing a _BV(7), still gives me 01000000.

@Gaai: I do not understand your comment.

ADMUX = 0b00000001 followed by: ADMUX = _BV(7); Yields: 0b01000000. While if it was shifted left, I would expect 0b11000000. Reading your explanation.


text:
Question about Buttons and INPUT_PULLUP
I am ok as a developer but have very little experience if it comes to electronics/hardware. I am always too cautious and have the fear that I could wreck something with the wrong wiring. This question may sound silly to you, but I couldn't find the answer anywhere. It's probably very easy to answer.
I'd like to integrate a Push Button into my Arduino Uno Setup. The only other connections are 3 wires leading to an WS2811b Strip, standard setup. From what I have found out online, I should basically connect Digital Pin 2 (or any other) to one side/connector of the Button and GND to the other side, no Resistor, and then set the Pin Mode to INPUT_PULLUP:
pinMode(BUTTON_PIN, INPUT_PULLUP);

This makes sense. But all tutorials I'v seen use these small black Push Buttons looking like the Reset Switch. I needed something bigger, so I bought these:
https://de.aliexpress.com/item/4001095221773.html
Now the question: Should I connect these Buttons to my Arduino in the same way? Or could it be that there is some difference from one type of Push Button to the other that I have not thought about (that could probably ruin things)?
Thanks a lot!

Hello fellow programmer. I suggest you to google word Tinkercad. :) You are welcome.

Aha. Thanks a lot :-)

Yes, just connect them in the same way.
It doesn't matter what type of button you use. You could even use a wire and let it touch ground when you want a "press". That also would work correctly. The only requirement is, that the part has to make a direct connection between the digital input pin and ground when pressed and it has to release that connection when no longer pressed.

I'm sorry to hear you had that experience with that other group. Sometimes people forget that they are there to help people who ask questions, not tell them how stupid the question is.

I am very cautious when it comes to electricity, so I need to ask a lot of things and make sure nothing bad will happen. But a lot of users in technical user groups seem to view beginners as cannon fodder and use them to show off and boast their ego. The question will not be answered, of course.

You can connect them with no external pull up resistors. If those switch wires are more than a few inches long or you are in an electrical noisy environment I would suggest an external pull up as well as the wires will act as an antenna. The internal pull ups are week so electrical noise can easily overpower them. The buttons you selected will probably oxidize over time and fail as the oxide is an insulator. To prevent that use pull up resistors that will force at least 1mA through the contacts (old school). We use to be sure we had some current through the switch when it was not a dry contact switch (those were expensive). Rule of thumb was at least 1mA more was good. This also helped reduce noise in the switch lines. Long term this is much more effective then sealing the switch.

Thanks for this information. What can be done to prevend oxidizing? Will hot glue on the back be a good idea once the soldering is done?

https://en.wikipedia.org/wiki/Wetting_current


text:
Voltage reading problem in Arduino mega based 10 cannel battery capacity tester
I want to make a 10 channels Arduino mega-based battery capacity tester using 4.7 ohms 10w resistors controlling them with IRFZ44n MOSFETs with respected digital pins. An 8.4V battery powers the Arduino (do not consider the buck converter in the picture). I am debugging my project step by step. When I read voltages of individual batteries by corresponding analog pins without turning On 'MOSFET-Gate pins' then Arduino measures the voltages correctly but when I turn on the gate pins then Arduino measures voltage incorrectly. Meaning if I connect
a battery with an analog pin and a multimeter at the same time and the value is pretty much same. Like 3.70 volt for the multimeter and 3.72 for analog pin but when I turn On the gatepin of the MOSFET then Arduino value is like 3.07V and Multimeter value is 3.48V.
Thanks in advance.
Here is the Circuit Diagram of my project:

Simple version to understand:

Code:
long readVcc() {
   // Read 1.1V reference against AVcc
   // set the reference to Vcc and the measurement to the internal 1.1V reference
#if defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
   ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#elif defined (__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
   ADMUX = _BV(MUX5) | _BV(MUX0) ;
#else
   ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);
#endif
   ADCSRB &= ~_BV(MUX5);
   delay(2); // Wait for Vref to settle
   ADCSRA |= _BV(ADSC); // Start conversion
   while (bit_is_set(ADCSRA,ADSC)); // measuring

   uint8_t low  = ADCL; // must read ADCL first - it then locks ADCH
   uint8_t high = ADCH; // unlocks both

   long result = (high<<8) | low;

   result = 1125300L / result; // Calculate Vcc (in mV); 1125300 = 1.1*1023*1000   //1126400L internalRefVolt(1.1) * 1023 * 1000; code can more precse by calculating internalRefVolt(1.1)
   return result; // Vcc in millivolts
}

void setup() {
   Serial.begin(115200);
   delay(3000);
   pinMode(22,OUTPUT);//***Mosfet Gate Pins********
   pinMode(23,OUTPUT);
   pinMode(24,OUTPUT);
   pinMode(25,OUTPUT);
   pinMode(26,OUTPUT);
   pinMode(27,OUTPUT);
   pinMode(28,OUTPUT);
   pinMode(29,OUTPUT);
   pinMode(30,OUTPUT);
   pinMode(31,OUTPUT);

   digitalWrite(22,LOW);//***Initially low the Mosfet Gate Pins********
   digitalWrite(23,LOW);
   digitalWrite(24,LOW);
   digitalWrite(25,LOW);
   digitalWrite(26,LOW);
   digitalWrite(27,LOW);
   digitalWrite(28,LOW);
   digitalWrite(29,LOW);
   digitalWrite(30,LOW);
   digitalWrite(31,LOW);
}

/**********************************Void Loop******************************************************/
void loop() {
   float voltRef = readVcc() / 1000.0;

   digitalWrite(22,HIGH);//*** High the Mosfet Gate Pins********
   digitalWrite(23,HIGH);
   digitalWrite(24,HIGH);
   digitalWrite(25,HIGH);
   digitalWrite(26,HIGH);
   digitalWrite(27,HIGH);
   digitalWrite(28,HIGH);
   digitalWrite(29,HIGH);
   digitalWrite(30,HIGH);
   digitalWrite(31,HIGH);

   float volt0 = analogRead(A0)*(voltRef/1024);
   delay(10);
   volt0 = analogRead(A0)*(voltRef/1024);
   /* if(volt0>3.0){
      digitalWrite(22,HIGH); // High = Mosfet ON
      digitalWrite(36,HIGH); // High = LED Turn OFF

      }*/

   float volt1 = analogRead(A1)*(voltRef/1024);
   delay(10);
   volt1 = analogRead(A1)*(voltRef/1024);

   float volt2 = analogRead(A2)*(voltRef/1024);
   delay(10);
   volt2 = analogRead(A2)*(voltRef/1024);

   float volt3 = analogRead(A3)*(voltRef/1024);
   delay(10);
   volt3 = analogRead(A3)*(voltRef/1024);

   float volt4 = analogRead(A4)*(voltRef/1024);
   delay(10);
   volt4 = analogRead(A4)*(voltRef/1024);

   float volt5 = analogRead(A5)*(voltRef/1024);
   delay(10);
   volt5 = analogRead(A5)*(voltRef/1024);

   float volt6 = analogRead(A6)*(voltRef/1024);
   delay(10);
   volt6 = analogRead(A6)*(voltRef/1024);

   float volt7 = analogRead(A7)*(voltRef/1024);
   delay(10);
   volt7 = analogRead(A7)*(voltRef/1024);

   float volt8 = analogRead(A8)*(voltRef/1024);
   delay(10);
   volt8 = analogRead(A8)*(voltRef/1024);

   float volt9 = analogRead(A9)*(4.95/1024);
   delay(10);
   volt9 = analogRead(A9)*(4.95/1024);

   //*****************************************************************************
   Serial.print("B0= ");
   Serial.println(volt0);

   Serial.print("B1= ");
   Serial.println(volt1);

   Serial.print("B2= ");
   Serial.println(volt2);

   Serial.print("B3= ");
   Serial.println(volt3);

   Serial.print("B4= ");
   Serial.println(volt4);

   Serial.print("B5= ");
   Serial.println(volt5);

   Serial.print("B6= ");
   Serial.println(volt6);

   Serial.print("B7= ");
   Serial.println(volt7);

   Serial.print("B8= ");
   Serial.println(volt8);

   Serial.print("B9= ");
   Serial.println(volt9);

   Serial.println("");
   Serial.println("==========================");
   delay(500);
}

What is the purpose of the resistor and the MOSFET? Why do you need it? When you turn on the MOSFET, more than 500mA will flow through the resistor to the ground, of course your battery voltage will drop!

@hcheung: For estimating battery capacity, the voltage under load is often more relevant that the voltage of the unloaded battery.

I will make a battery capacity tester for that reason discharge the battery current  using the resistor and measure the capacity

Yes i agree with you but if i measure the voltage using multimeter and arduino analog pin at the same time in underload why the value is different so much. Example : Arduino read= 3.07v and Multimeter read=3.48V at the same time.

Where did you connect the negative probe of the multimeter? To the negative terminal of the battery or to the Arduino ground?

Wow! all the time I used the negative probe of the multimeter with the negative terminal of the battery but now I tested with Arduino ground and it gives me accurate value my question is the battery negative terminal is shorted with Arduino GND but why this different result coming out?

The main problem was the battery holder default wire, those wires were have high resistance. After changing those wire the problem was solved. Thank you everyone

Electric wires have resistance. Most of the time this resistance can be ignored, but this is not always the case. Specifically, if the wire is carrying a large amount of current, the voltage drop across it can be significant.
Consider this circuit:

simulate this circuit – Schematic created using CircuitLab
The red wires carry a high current, and experience a significant voltage drop. Wires in black carry almost no current, and are equi-potential. Both voltmeters on the left will measure the same voltage, which is affected by the voltage drops along AB and along DE. The voltmeter on the right measures a lower voltage, because it is also affected by the drops along BC and EF.
In your experiment the problem is compounded by the fact that the ground wire is carrying the current from all the batteries. It is therefore responsible of most of the voltage drop you experience.
The takeaway is that you have to make sure the junction points between the current carrying wires and the measurement wires (points B and E for the voltmeters on the left) are as close as possible to the battery. Otherwise your measurement will be biased.

Love you man!! I am working on this project for 5-6days to find out the problem, I thought I have a problem with the code so I tried to simplify my code to find out where the exact problem coming from but yet don't get any solution. But You actually teach me something that I never knew. Thank you so much, brother. Rally appreciated.

I solve the problem But now  the problem is when I High digital output pin of the arduino to turn on MOSFET-GatePin, Arduino Digital pin voltage drop from 5v to 3v across the gatePin. These thing happening with 7MOSFET and others 3 working perfectly. I changed mosfet and pulldown resistor but no solution.


text:
#define from main (.ino) not considered by comiler in own libaries
I have got the problem, that my #define from main (.ino) is not considered by the comiler in my own libaries. This #define MQTT_MODULE is only considered in the main (.ino) programm, but not in MyRemoteLib.cpp
This example works normally, if I compile it with gcc.
Code in my Test.ino :
#define         MQTT_MODULE             1
#include        "MyRemoteLib.h"
loop() {
  my_test() ;
}

Code in MyRemoteLib.h
#define     MYREMOTELIB_H
#define     MY_TEST         1
#if         MQTT_MODULE
  #define       MQTT_MOD_R              1
#endif

Code in MyRemoteLib.cpp :
#include        "MyRemoteLib.h"
void my_test() {
  #if   MQTT_MOD_R
      test.... > nothing -> ignored by compiler
  #endif
  #if   MQTT_MODULE
      test.... > nothing -> ignored by compiler
  #endif
  #if   MYTEST
      test.... > error-> not ignored by compiler
  #endif
}

Your approach of using #define to selectively include different parts of your library is doomed to fail, because it does not work that way. You might want to learn more how to build a "real" library. In a tiny nutshell, separate all parts in their own source. When the linker resolves references, it will only add the needed modules. However, if this is doable with the Arduino IDE, is another issue.

This is the expected behavior. The library and the main program are two
different compilation units: there are processed by the compiler
separately.
In the main program, the inclusion of the header file yields this:
#define         MQTT_MODULE             1
// Included from MyRemoteLib.h:
#define     MYREMOTELIB_H
#define     MY_TEST         1
#if         MQTT_MODULE
  #define       MQTT_MOD_R              1
#endif
// end of included code
loop() {
  my_test() ;
}

The remaining preprocessor code has no effect at all.
In the library, the same inclusion yields this:
// Included from MyRemoteLib.h:
#define     MYREMOTELIB_H
#define     MY_TEST         1
#if         MQTT_MODULE
  #define       MQTT_MOD_R              1
#endif
// end of included code
void my_test() {
  #if   MQTT_MOD_R
      test.... > nothing -> ignored by compiler
  #endif
  #if   MQTT_MODULE
      test.... > nothing -> ignored by compiler
  #endif
  #if   MYTEST
      test.... > error-> not ignored by compiler
  #endif
}

The conditional compilation gives an empty my_test() (that is, unless
by MYTEST you actually mean MY_TEST).
I do not know what you are trying to achieve, but you may look at ways
to put the code to be conditionally compiled in the header itself. You
may try using inline functions, or maybe templates.
Edit: about removing code using conditional compilation: this is not
always as useful as it may sound, for two reasons.

By default, the Arduino IDE compiles your code with the options
-ffunction-sections and -fdata-sections, and links it with
-Wl,--gc-sections. This means that any function or method that is
never used, or any global variable that is never referenced, is not
included in the final executable.

The code is also compiled with -flto, which enables link-time
(full program) optimizations. This means that code that depends
on a condition that is always false (the conditional expression can
be resolved as a compile-time constant) is also removed from the
final executable.

Thanks for the answer. Well I try to achieve a universal code in my own library's so I can "activate" a "Module" in my main program. And I thought the pre-processer is the best ways, so it even won't be complied (if I don't need it). For example, some sensor functions should only send mqtt msg if I activate my "wifi module"... otherwise the compiler also complains!
That's why I prefer to use #defines. Also if I use the "normal" gcc compiler it works.

@stevo Some of this is probably intended as a comment on Edgar Bonet's answer and some of it may be something that's supposed to be edited into the question. Careful that you don't edit the question out from underneath the existing answer. This is not a forum. The way it's supposed to work is that there are questions with matching answers. Not a forum thread.

@stevo I doubt that your "normal" gcc works differently and "sees" the #define in the source of another translation unit. BTW, the compiler used by the Arduino IDE is a gcc, too.


text:
Can't upload sketch after overheating
I'm using an Arduino nano, after an unfortunate event, The mega chip heat up and when I tried touching it, it burned my finger. After that, I connected to my laptop's USB port and the computer recognized it. But after I hit the upload button, the RX light flash 3 times and stop, no Loader light and it just stop there, and the IDE says this:
Arduino: 1.8.19 (Windows 10), Board: "Arduino Nano, ATmega328P (Old Bootloader)"

Sketch uses 2806 bytes (9%) of program storage space. Maximum is 30720 bytes.

variables use 44 bytes (2%) of dynamic memory, leaving 2004 bytes for local variables.
Maximum is 2048 bytes.

An error occurred while uploading the sketch

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x84

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x84

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x84

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x84

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x84

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x84

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x84

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x84

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x84

avrdude: stk500_recv(): programmer is not responding

avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x84

This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.

Any advice?

Get a new one? It's possible the USB bridge survived, but the actual MCU did not.

"Any advice?¨ I'm not sure what you're going to find as acceptable advice.So, you may want to make that clear. As is the advice is something like: buy a new board..

make an assumption that the issue is just a coincidence and do all necessary troubleshooting ... only it all fails, declare the device to be dead

Right, getta new one then

Not sure what you did but you probably either overvoltage it or connected it backwards. The odds are extremely high you fried the mega chip. Good news, it is not a total waste, you learned something not to do. It is still good for practicing troubleshooting, if you find what failed great or if you cannot fix it,  you will have learned something useful. Atthis point use it for practicing SMD soldering. In the end remove the parts and use the PCB for a template. The recommended solution is to purchase two more, that way if one fails the wate time will be shorter.

Yea, It might be because when I plug it into the board, the Arduino is reversed and d10/d12 is plugged to 5v/gnd instead of gnd and vcc. Or maybe I moved it back a pin so the rst/gnd is plugged to the 5v/gnd. I honestly can't be sure about it as how panicked I was back then.


text:
Controlling the 5V pin on the Arduino nano 33 BLE
Following the guidance on this post  I have enabled the 5V pin.  That same post suggests that I control that pin with D12, though I find it weird since there is already a D12 pin.  When I try and run some code the D12 pin is performing exactly as I expect, but the 5V pin is doing nothing.
Looking through the tech specs it says "the 5V pin does NOT supply voltage but is rather connected, through a jumper, to the USB power input." which I find odd, since if its connected to the power input, should it not be supplying voltage?
Could someone clarify if its possible to use the 5V pin like a digital pin, and if so how?

Following the guidance on this post I have enabled the 5V pin. That same post suggests that I control that pin with D12, though I find it weird since there is already a D12 pin. When I try and run some code the D12 pin is performing exactly as I expect, but the 5V pin is doing nothing.

5 V pin is the the 12th pin of the PCB

Looking through the tech specs it says "the 5V pin does NOT supply voltage but is rather connected, through a jumper, to the USB power input." which I find odd, since if its connected to the power input, should it not be supplying voltage?

it says that the 5V pin is connected to the USB power input through a jumper and the jumper is not connected from factory

the 5V pin does NOT supply voltage but is rather connected, through a jumper, to the USB power input could mean that the pin is not a power input for the arduino

@jsotola it can be both because it is connected to USB power input and to the 5 V to 3.3 V regulator which powers the rest of the board. but the pads are not connected to prevent using the 5 V pin without a solder bridge. https://content.arduino.cc/assets/NANO33BLE_V4.0_sch.pdf

Thank you for the clarification, but it does not answer the question.  Is it possible to use the 5V pin like a digital pin?  If so, how?

@Pablo, the pin is just on a 5 V rail of the board. there is no logic, just 5 V power.