text:
Why wont my custom Arduino-Micro-based board connect over USB?
I designed and printed a PCB for my MIDI controller project with a modified Arduino Micro microcontroller essentially built into the design. I swapped out the USB Micro for a USB-C type port (just using the 2.0 protocol). Although I can program the board via ICSP, including getting it to run my Arduino sketches (which I have tested by having it light up the LEDs in a certain pattern, which works as expected), and the fact that it receives power via USB, the problem is that I cannot get the device to connect to my PC over USB - it is not recognized as a USB device, and cannot seem to send or receive data over USB. I'm not sure if I've done something wrong in the design or if I am simply missing something, but could use some advice, as in order to function as intended, the board will need to be able to communicate over USB.
I have tested with various USB-A to USB-C cables and USB-A to Micro cables (tested with other Arduinos) and a Micro to USB-C adapter.
As per various instructions I found online, I connected pull-down resistors of 5.1k Ohms to CC1 and CC2, left SBU1 and SBU2 unconnected as I was planning to use 2.0 protocols to keep things simple (as a related question, can these actually be used to make use of 3.0+ protocols in a design like this with an ATMEGA32U4? Would this be considered better practice in this case and potentially bypass the error?), and wired up D- and D+ as shown in the schematic below; with a EZJZ0V500AA Varistor between each and GND and running through a 4D03WGJ0220T5E Resistor network (which I don't know much about, including whether this type of component has any polarity? I simply tried to follow how the same sort of component was used in the official Arduino Micro schematics) and finally into pins 3 and 4 of the ATMEGA32U4.
This is the original schematic of the board as it was assembled, but as a result of some power issues with this same board which I have since sorted out with help in a separate post Why wont my custom Arduino-Micro-based board receive power via USB?, I had to bypass the 5V regulator and just use VUSB as +5V, so I will put the updated schematic reflecting these changes below the original (I wouldn't think it would affect this issue, but I'm not that experienced and want to err on the side of providing as many details as possible)
Original Schematic:

Revised Schematic:

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              |

Did you try to burn the bootloader over ICSP?

"as a side question" it's probably better than you don't ask that in the same question. I gather you sorted out your power problem and this is now about about data. Or at least I hope that's what's going on. If so, you may want to make that really clear before people start trying to close it as a duplicate. Like before, if you mention that you're testing with a USB-A to USB-C cable, this eliminates any concerns regarding the design or implementation or design surrounding CC1/CC2. They become a non-issue, because they're handled by the cable in that case.

@chrisl Yes, I have successfully burned the bootloader over ICSP prior to testing it over USB

@timemage Appreciate the advice, I am fairly new to this platform so wasn't completely sure the best way to go about asking multiple related questions, etc. I did indeed solve the power issues and thought it might confuse things to mention that again here since this seems to be a mostly unrelated issue, but I'll make a note of it in an edit.

Did you do something like select Arduino Micro and burn the bootloader through ISP? Or did you install use the DFU loader?

@timemage Yeah in the Arduino 1.8.19 IDE I selected Arduino Micro as the board and burned the bootloader using an Arduino Uno as ISP, and then I also successfully uploaded a sketch through Upload Using Programmer through the ICSP as well. I'm not familiar with the DFU loader but can look into that.

Is your board works with blinking LED (that's proof the board generally working) or only the USB port not working?

That was not a recommendation for DFU. Some things to do/measure that you can maybe integrate in the question: Run DRC on the PCB layout if you haven't already.  Measure the UCAP pin to see that 3.3V is there.  Power the board with 5V as though it were connected to USB (don't actually connect it to USB) and measure Measure D+ and D- with a high (15K-50k) valued pulldown after an external reset. See whether or not D+ being pulled up when in the bootloader and that D- is not. If you don't mind the grief involved test with Z1/Z2 removed.

@hcheung Yes, I was able to successfully upload and run an LED blinking sketch to the board (via ICSP programming) so I believe the board is functioning aside from the USB data transfer.

Your USB circuitry looks okay, and you are using a USB-2 port which is the correct choice. Have you installed the USB driver?

@timemage "Not a recommendation for DFU" Understood. Thanks for all the test suggestions. I have been getting a clean read from DRC (though I know from my previous power troubles that that doesn't preclude incorrect footprint selection, so I will double check anything with polarity). Measuring 3.3V at UCAP. As for the final test, do I understand correctly:  remove Z1 and Z2 and effectively replace each with a high value pull-down resistor, burn bootloader to the board, then test (while the board is powered but no sketch running) if D+ is being pulled to a higher voltage while D- is not?

Sort of, but really suggestion for Z1/Z2 is really separate from the pull-down thing. The idea is that Z1/Z2 are for protection that isn't strictly needed to make it work. So at best they are not interfering. The point of the D+/D- measurement is to see that the chip is actually trying to enumerate at full-speed in the bootloader. The point of the pulling down while measuring is that the host that is normally connected (now not connected) usually pulls them weakly toward GND. If you don't do that yourself they may float and give false measurement.

uploading a sketch with programmer deletes the bootloader

@hcheung I tried reinstalling the drivers but it didn't seem to help. Thanks for the suggestion and for looking things over

@timemage Well I was able to do the test today; I added 22k Ohm pulldowns to D+ and D- and measured them while in the bootloader. D+ was reading 3.1V to 3.3V and D- was reading 0V compared to GND. I got the same results with removed Z1 and Z2 and when testing while they were still in place.

Well, then your chip is enabling USB for full-speed, which is what the caterina bootloader (Arduino Micro bootloader)  does. If these voltages are making to the host port, you should, at a minimum get a failure diagnostic in dmesg or device manager or whatever that indicates either a failure to issue USB Set Address or a failure to Get Descriptor, usually the device descriptor. Absence of both would mean something like that's a charge only port, or you have a break in D+ between where you're measuring and the D+ as it goes into the computer/hub.

One thought that came to my mind, you might want to look into Atmel DFU driver.

@hcheung I took "not recognized as a USB device" to mean that it wasn't enumerating on the USB at all as opposed to enumerated as an "unrecognized device."   If that's correct then it won't matter what drivers are installed, since it would need to enumerate to even know which drivers to consider.

Well I finally found the source of the problem, many thanks to everyone here who helped me narrow things down and kept pointing me in the right direction. After figuring out that D+ and D- were getting pulled appropriately by the chip I decided to desolder the USB port on the board, cut a USB-A 2.0 cable and solder the leads directly to the board and, suddenly, it worked. After this I realized the problem must have been with the USB port on the board and upon comparing the datasheet to my pcb file, I realized that the footprint I used and the one in the datasheet had the pins laid out in a different order.
I feel a bit embarrassed for taking up people's time on such a stupid error I made (and admittedly didn't even provide enough information for anyone to be able to figure out for me, despite all of your patience and helpful advice), but at the same time I am both relieved I figured out the problem and grateful for all the help I got on this post, I'm not sure how long it would have taken me to figure out without your suggestions. I learned a lot about the layout of arduino boards, the purposes of various components in said boards, the importance of double checking footprints, and about better practices for asking for assistance.
As a note on "post etiquette" or whatever you would call it, since everyone provided assistance in comments, I didn't see a way to close the post without answering my own question (I am new to posting here), so I hope that is an acceptable way to do so.

It is perfectly fine to answer your own question and mark it as accepted. You might want to read some pages of the [help] to learn more.


text:
Do these bit settings all mean the same?
ADMUX  = ADMUX | _BV(REFS);  // uncompounded bitwise OR
ADMUX |= _BV(REFS0);         // #define _BV(bit) (1 << (bit))
ADMUX |= bit(REFS0);         // #define bit(b) (1UL << (b))
bitSet(ADMUX, REFS0);        // #define bitSet(value, bit) ((value) |= (1UL << (bit)))
sbi(ADMUX, REFS0);           // deprecated assembly?
ADMUX |= (1 << REFS0);       // shift operator
ADMUX |= (1 << 7);           // bit 7 is named REFS0
ADMUX |= 0b10000000;         // bin
ADMUX |= 0x80;               // hex
ADMUX |= 128;                // dec

*under normal 8 bit Arduino circumstances?

Comments are not for extended discussion; this conversation has been moved to chat.

You already got an answer in the comments but, just to make double sure,
I tried compiling all these statements for an Uno, and they got all
translated into the exact same machine code. Well, almost: I had to do
some minor adjustments, which I believe are unrelated to the essence of
your question. Just for completeness, I changed the following:

I replaced REFS0 by REFS1: on an Uno, REFS0 is bit 6, and REFS1
is bit 7.

I replaced REFS by REFS1, as the former is not defined.

I #included <compat/deprecated.h>, otherwise I get the error
“'sbi' was not declared in this scope”.

source: Stack Exchange

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

sort: votes


text:
Do I need to connect a capacitor to AREF if using internal reference? _BV(REFS0)

This is from the Atmega328p datasheet. But I see no mention of it in practical examples.
So when I'm setting up the timer for ADC with:
ADMUX = _BV(REFS0);

Should I add the cap? Or might it be already there on the arduino's hardware? Also what value is advised? 100nF?
Thanks in advance!

According to the datasheet:

The voltage reference may be externally decoupled at the AREF pin by a capacitor for better noise performance.

So you can but you don't have to. It all depends on how good you want your ADC results to be. 99% of the time it's pointless since what you're reading isn't that accurate, but if you want to add a capacitor anyway then sure, go right ahead.
What value capacitor? Well that very much depends on what kind of noise you want to achieve more immunity from. The lower the value the higher the frequency it will help protect you from. You may want to combine multiple capacitors in parallel if you're in a very noisy environment, such as 1nF and 100nF.

Thanks for clearing that up! I'll test it out and see if it improves anything or not.

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


text:
Compile Error Getting when i try to read firebase data using esp32 in Arduino IDE
I am trying to read the firebase data using esp32, when i try to read firebase data statically(string literal) no error is coming.
String board=Firebase.getString(fbdo, F("Device/board")) ? String(fbdo.to()).c_str() : fbdo.errorReason().c_str(); //getting data successfully

But when i try to read data dynamically using String object, i am getting compile error for given code
String string2 = "Device/board";
String board1=Firebase.get(fbdo, F(string2)) ? String(fbdo.to()).c_str() :
    fbdo.errorReason().c_str();

ERROR : #define F(string_literal) (FPSTR(PSTR(string_literal)))

How to solve this problem?

add to the question the exact error message you get

don't use the F macro on esp32

The macro F() can only be used with string literals, not with variables.
A simple solution should be (I cannot test) to provide string2 directly. (I hope that Firebase.get() is overloaded.) Try this:
String board1 = Firebase.get(fbdo, string2) ? String(fbdo.to()).c_str() : fbdo.errorReason().c_str();

To save precious RAM, you might consider to use another data type for string2. To get a similar result, you could try:
const __FlashStringHelper *string2 = F("Device/board");
String board1 = Firebase.get(fbdo, string2) ? String(fbdo.to()).c_str() : fbdo.errorReason().c_str();

To gain some more insight, you might like to read this guide on PROGMEM.

Thank you bro, i will test it and let you know the result


text:
ESP32 WIFI error when trying to initialize WIFI after stopping and deinit WIFI driver
I have a firebeetle ESP32 board and I use VScode with platformIO. My platform is espressif32 v5.0.0 and the framework is arduino.
I am currently implementing a WIFI connection as follows:
bool init_wifi_STA()
{
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED)
    {
        delay(500);
        Serial.print(".");
    }
    return true;
}

When I do not need WIFI anymore, I am calling the following sequence:
esp_wifi_disconnect();
esp_wifi_stop();
esp_wifi_deinit();

When I want to connect to wifi again using my init_wifi_STA() function I get the following error:

[489781][E][WiFiGeneric.cpp:1053] mode(): Could not set mode! 12289
[489781][E][WiFiSTA.cpp:227] begin(): STA enable failed!

I already found this github issue, but checking my library, it looks like the bug was removed (code section from WiFiGeneric.cpp - mentioned by the github issue):
static bool wifiLowLevelDeinit(){
    if(lowLevelInitDone){
        lowLevelInitDone = !(esp_wifi_deinit() == ESP_OK);
    }
    return !lowLevelInitDone;
}

However, I am still getting this error. Any idea where it comes from and how to avoid it?


text:
How to correctly set PWM to control servo angle in AVR?
I've stumbled upon timer configuration to handle my sg-90 servo and my Arduino UNO.
What I did:

Set the prescaler to 64 and mode to fast PWM of 16-bit timer.
The frequency is 50hz so the ICR1 is set to 4999.
And now I don't know what to do next to set the values of OCR1A without guessing them.

From my understanding: If the period is now set to 20ms then for sg-90 servo:
From documentation: http://www.ee.ic.ac.uk/pcheung/teaching/DE1_EE/stores/sg90_datasheet.pdf

Angle 0 should be 1ms (1/20 = 0.05), so OCR1A = 4999 * 0.05 ~= 250
Angle 90 should be 1.5ms (1.5/20 = 0.075), so OCR1A = 4999 * 0.075 ~= 375
Angle 180 should be 2ms (2/20 = 0.1) so OCR1A = 4999 * 0.1 ~= 500

But it doesn't work like that. I've figured out that values are 125, 370, 615 - I've found these numbers in the internet (not in English language) but that guy didn't explain how he got them.
Could someone explain it to me where these numbers come from or where my calculations are incorrect.
It's not a problem with servo because with Arduino servo library everything works fine.
Solution:
The document I've attached is incorrect the pulse range of miliseconds is not 1-2ms but 0.5-2.5ms and everything fits correctly.
Below is my current code:
#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdbool.h>

#define PRESCALER_64 (1 << CS11) | (1 << CS10)
#define FAST_PWM_A (1 << WGM11)
#define FAST_PWM_B (1 << WGM13) | (1 << WGM12)

int main(){

    TCCR1A = FAST_PWM_A | (1 << COM1A1);
    TCCR1B = FAST_PWM_B | PRESCALER_64;
    ICR1 = (F_CPU / 64 / 50) - 1;

    DDRB |= (1 << PB1);

    while(true){
        OCR1A = 125;
        _delay_ms(2000);
         OCR1A = 370;
        _delay_ms(2000);
        OCR1A = 615;
        _delay_ms(2000);
    }

}

research what signals servos expect to receive ... not an Arduino related question

jsotola is right, this is an AVR question, not an Arduino question, it might be better posted on StackOverflow. Anyway, if your timer period is 5000 cycles, your calculations look correct to me. (I haven't checked the timer setup.) Don't you have an oscilloscope to watch the signal? -- Concerning this "other guy": Since any fool can post stuff on "the net", doubt any information, especially if it is not explained. The difficulty today is to filter the 1% of good things from the crap.

why not use a library?

OK, I figured it out. The problem is in the document. The pulse width is not in range 1-2ms but 0,.5-2.5ms.

OK, I figured it out.
The document I've attached is incorrect, the pulse range of milliseconds is not 1-2ms but 0.5-2.5ms and everything fits correctly.


text:
How to improve button turn on/off experience
I have simple circuit turning lights on and off on button click.
It is working quite fine but there is a small issue with button click itself, it is not fully reliable.
Turning lights on is pretty fine but turning them off is tricky.
Basically clicking once almost never works. I need to click in the right moment to turn them off or better keep pressing the button until right moment. If I hold too long it also doesn't work or work wrongly.
Here is the loop code:
void loop() {
    int buttonState = digitalRead(BUTTON_PIN);
    if (buttonState == 1) active = not active;

    if (active) {

       ... led setup

      FastLED.show();
      FastLED.delay(1000 / UPDATES_PER_SECOND);
    } else {
      fill_solid( leds, NUM_LEDS, CRGB::Black);
      FastLED.show();
//      FastLED.clear();
    }
}

What do I need to do to make it working as expected which is:

single click turn light on
another click or hold for a while turns light off for good and they stay off until next click

use the Bounce2 library

It's called "Debouncing" - I think there is even library for it.

I second Juraj. The Bounce2 library handles this very good

I think that you have a couple of things going on here. Debouncing has already been mentioned and I don’t want to discount that at all – there is a ton of information on that subject.
In your case, I think it would be helpful for you to consider 1) how you are defining a button press and 2) how much processing you are doing when you are not checking for a button press.

To demonstrate, I used this simple set up with a switch:
Then I modified an example from the FastLED library to simply toggle one LED (from a 12 LED, generic, neopixel ring [no clock] and ran it on an UNO (I know you are using a nano, but I think it should still work) using this code.
#include <FastLED.h>

#define NUM_LEDS 1

int LEDon = 0;
#define DATA_PIN 6

int switchPin = 8;

CRGB leds[NUM_LEDS];

void setup() {
  // ## Clockless types ##
  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
  pinMode(switchPin, INPUT);
  // start with LED off (not strictly needed)
  leds[0] = CRGB::Black;
  FastLED.show();
}

void loop() {
  if ( digitalRead(switchPin) == HIGH) { // switch is pressed
    if (LEDon == 0) {
      LEDon = 1;
      leds[0] = CRGB::Red;
      FastLED.show();
    }
    else {
      LEDon = 0;
      leds[0] = CRGB::Black;
      FastLED.show();
    }
    while (digitalRead(switchPin) == HIGH); // wait until switch is released
  }
}

I don’t have much experience with this library (it does appear to be very powerful) and don’t know if you can read the state (on/off/color/intensity) of the LEDS – so I just kludged a variable (LEDon) for the example. It works fine. No missed presses and you have to release the button before you can press it again.
Note that I am doing only the minimum amount needed in between looking for a button press.
Libraries are great, but you need to understand a good deal about using them. I think that you are doing time-consuming processing that is causing you to miss presses, which is why you say “I need to click in the right moment to turn them off or better keep pressing the button until right moment”.
I also think that you are ill-defining a press. In the code, I am specifically looking for the button to be released. Because some time is spent processing after the button press is detected, I don’t have to explicitly debounce the switch – for this example. That does not mean that you can always get away with that.
Think about how functionally vague your definition of a press is,
•  single click turn light on
•   another click or hold for a while turns light off for good and they stay off until next click
I would respectfully recommend that you:
Learn as much as you can about the library. Take a look, for example, at this discussion FastLED.delay()  https://github.com/FastLED/FastLED/issues/1206
Do as much as you possibly can in setup().
Do as little as you need to in-between checking for a press (or think about using interrupt).
Hope it helps.


text:
CRC8 code not working properly
I need to send a string followed by its CRC8, 0x31 polynomial (= X^8 + X^5 + X^4 + 1), I've coded this successfully after some troubles, but it doesn't seem to work properly when I check the results.
I used some online CRC calulators so check if my results are fine, but I don't get the same results, no matter what I try.
In fact, differents CRC calculators are not giving me the same results, which troubles me...
Here are my trials on online CRC calculators, always using :
CRC8, polynomial 0x31, data = TEMPS; (beginning of my string)
On http://www.sunshine2k.de/coding/javascript/crc/crc_js.html :

On https://www.lddgo.net/en/encrypt/crc :

On http://zorc.breitbandkatze.de/crc.html :

It doesn't seem normal to get different results when the entry parameters are the same, it confuses me a lot. Am I missing something ?
No matter what I try, I don't get any of these results with my own code.
Here is my code about CRC calculation, using RobTillaart's CRC library (https://github.com/RobTillaart/CRC):
   String crcData = "TEMPS;";
  int crcDataLength = crcData.length();
  char arrayForCrc[crcDataLength+1];
  crcData.toCharArray(arrayForCrc, crcDataLength+1);

  crcTrame = CRC8(0x31,0,0,false,false);
  crcTrame.add((uint8_t *)arrayForCrc, crcDataLength+1);
  String stringCrcNoHex = String(crcTrame.getCRC());
  String stringCrc = String(crcTrame.getCRC(), HEX);

The hex result of this code sample is 0xBA (186 decimal)
I verified every input parameters with gets and prints, they're all correct :
arrayForCrc = "TEMPS;"
polynomial = 0x31
StartXOR = 0
EndXOR=0
ReverseIn=false
ReverseOut=false
Help would be greatly appreciated as I'm stuck and don't know what to try anymore.
Thank you :)

I could explain it if you were getting 0xB5 but not 0xBA. It helps to have completely compilable code.

I just filled out your code with guesses to the point where it compiled with the latest version of that library and I have it is printing 0xB5 and not 0xBA. So either we're both confused or you've got the wrong number in your question.

Check your sunshine screenshot again, because if I put exactly what you have into it and calculate I don't get 0x6E; I get the expected 0x49. Regarding the 'lddgo' screenshot test, it's not really valid. The reverse settings are on. Once you get 0x49 correctly on the sunshine one, turn on both reflect options and you'll see you now get a 0x73 that matches what you have in the lddgo one. So, I'd remove it because this has nothing to do with the problem you're having with the library.

The hex result of this code sample is 0xBA (186 decimal)

Not so far as I can tell; it's 0xB5, which is expected for a simple reason that you'll see. And when modified slightly it matches the 0x49 value. I'm inclined to trust that your code is correct, so far as you've shown it, but your report of what's doing is not correct.

I verified every input parameters with gets and prints, they're all correct

Well, no. As I mentioned in a comments on the question, I get the expected 0x49 on the first site you mentioned with the correct settings. I'm not sure why you're showing 0x6E. But guess what happen if I hit enter after "TEMPS;"? 0x6E. The newline character matters. Also, I do get a 0xBA if I use the correct input but fail to set CRC8 to custom and change 0x07 to a 0x31 in the polynomial. So, maybe that's how you found that value.
If you switch to bytes mode the site expects a sequence of character code values and ignores whitespace (apart from treating it as a delimiter). You can put 0x54 0x45 0x4d 0x50 0x53 into it in bytes mode to see 0x49 result also. You can then add 0x0D (newline) to see it to result in a 0x6E from before.
Regarding the middle site, the settings aren't correct (the reverse setting is on for input and output) and I don't see how to make them correct; they don't seem to have a custom option. However, you can turn on the reflect options on the first site to get the same result as in the 2nd site in order to convince yourself that is what is going on. The third site's output is correct for what you've put into it. It just doesn't match what you're code is actually doing.
Your basic problem is the +1 in this line:
crcTrame.add((uint8_t *)arrayForCrc, crcDataLength+1);

You've included the null terminator in the calculation. This is 7 bytes: 'T', 'E', 'M', 'P', 'S', ';', '\0'. These websites just aren't doing that; they are not automatically adding a null terminator at the end of whatever you type in string mode. Alternately, if you wanted the null terminator in the CRC calculation, your code is fine, but you're going to need to switch to HEX input mode on the website and enter a 0x00 into it after the hex values for the other characters in TEMPS; so as to match. And it will match, I've tested this. You can also: put the first site into bytes mode and put "0x54 0x45 0x4d 0x50 0x53 0x3b 0x00" into it and you will see it now produces a 0xB5, like your current code.
Otherwise, you just need to not enter the null terminator into the calculation:
crcTrame.add((uint8_t *)arrayForCrc, crcDataLength);

This will result in 0x49 coming out of crcTrame.getCRC() instead of 0xB5:
#include "CRC8.h"

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

void loop() {
  String crcData = "TEMPS;";
  int crcDataLength = crcData.length();
  char arrayForCrc[crcDataLength+1];
  crcData.toCharArray(arrayForCrc, crcDataLength+1);

  auto crcTrame = CRC8(0x31,0,0,false,false);
  crcTrame.add((uint8_t *)arrayForCrc, crcDataLength);
  String stringCrcNoHex = String(crcTrame.getCRC());
  String stringCrc = String(crcTrame.getCRC(), HEX);

  Serial.println(stringCrc);
}

If you also want to sanity check what happened with the 0x6E output earlier, you can then change crcData to String crcData = "TEMPS;\n" (adding the newline) and watch it start printing 6E.

There's a .getBytes() function in String that is pretty much what you have without needin the cast:
crcTrame.getBytes(arrayForCrc, crcDataLength);

I'm not sure if you have a good reason for "TEMPS;" to begin life in a String or then to have to get it into an character array. If you're only doing this so you can then call crcTrame.add(), well, you needn't:
#include "CRC8.h"

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

void loop() {
  String crcData = "TEMPS;";
  int crcDataLength = crcData.length();

  auto crcTrame = CRC8(0x31,0,0,false,false);
  crcTrame.add(
    (const uint8_t *)crcData.c_str(),
    crcData.length() // <- Does not count null terminator.
  );
  String stringCrcNoHex = String(crcTrame.getCRC());
  String stringCrc = String(crcTrame.getCRC(), HEX);

  Serial.println(stringCrc);
}

Note: I'm only creating stringCrc to mirror what you were doing. Here, it could just as easily be Serial.println(crcTrame.getCRC(), HEX); and potentially in whatever context you're doing it in. The cast can also be done in a more C++ approved (though uglier way with crcTrame.add(reinterpret_cast<const uint8_t *>(crcData.c_str()), crcData.length());
Any sequence of any number of add() calls that delivers the same data in the same order into calculation will yield the same CRC. There's also an overload of add() that takes an individual character without needing to involve a pointer at all. So your data doesn't need to come from a String, nor be a null-terminated string, or character array, nor fit entirely in memory.


text:
PIR sensor is already high, even though it is not detecting any person
I made codes like this through tinkercad.
const int temperature = A0;

int pir = 7;

void setup()
{
  pinMode(pir, INPUT);

  Serial.begin(115200);
}

void loop()
{
  int pir_state = digitalRead(pir);

  int value_temp = analogRead(temperature);
  float volt = (value_temp * 5.0) / 1024.0;
  float tempC = (volt - 0.5)*100;

  if (tempC >= 22 && pir_state == 1)
  {
    Serial.print(tempC);
    Serial.println("C");
  }

  delay(1000);
}

And following picture is the picture of a circuit I made.

I simulated this circuit. Originally pir_state is gonna be zero when PIR sensor is not detecting any person or object, but pir_state is always high irrespective of detecting. I thought the value of pir went wrong, so I read pir out. Then, I found it out that pir's value is always 7 regardless of detecting.
I know this isn't a big deal to you guys, but actually I'm noob so I can't figure it out what's wrong. Please, could you help finding what's happening to this and tell me what is the problem?
Here, this is a link of the circuit I make.
https://www.tinkercad.com/things/luV81NLkWKo-engineering-designcapstone-design/editel?sharecode=qsYWcgpijodDbgIpsfluJ3yUJwuN-70doPT62QNTv1Q

The value of "pir" is 7 because that is the (pin) number that you assigned to it. You should be interested in the value of "pir_state", which should be the output of the PIR sensor. Your Tinkercad link requires an account, so most people would not bother to see what's there.

You can confirm the code by connecting pin 7 to ground insted of the PIR sensor. If pir_state is zero then the code works correctly. I don't know tinkercad in detail. How is the PIR sensor triggered while simulating? By clicking on it?

Not having (nor likely going to have) a TinkerCad account, I'm unable to sufficiently convince myself that the connection you've made to the output pin of the PIR sensor to the black lead terminating at digital pin 7 is valid according to the simulator. You could eliminate that concern by showing that you still have the problem when doing nothing different except using a more conventional way of inserting it into the board which is also shown to work (without an account).

@user299980 I looked at your TinkerCAD model ... the PIR sensor is not connected to the arduino

Update:
@jsotola commented that Tinkercad does have some capability simulate to the PIR's behavior. So my next step would be to temporarily replace the if(){ ... }' block in your loop() function with a few statements that print your inputs and calculated values once per second and run that while I tweaked the simulated PIR device and the thermo-sensor (if the simulation lets you do that).
The terminal output values should lead you to what ever isn't working the way you expected it to.
You are running your program in simulation, but the PIR sensor is an active device that responds to external physical inputs (changes in infrared illumination on it) modified by sensitivity settings on the device. It's hard to simulate a device's active environment. Unless the simulation offers you a way to simulate that, too, there really isn't a way to simulate the its inputs to your program, so a constant output (as seen by your simulated code) makes sense.
Without the simulator letting you pre-program the PIR's physical environment, the only way to see a its active behavior is to use a real PIR, and monitor it's real output while you change its actual environment - such as waving your hand in front of it - and watch response with an Arduino, an LED (and resistor) to ground, or a DVM.

TnkerCAD does show a PIR field of view when the simulation is running ... clicking a mouse pointer within the field generates a movement event

Thanks for clarifying that!


text:
Permission denied on upload w/ IDE 2
Dealing with this very common issue on IDE v2.0.0., but not sure why.
I should be fine group-wise:
adm tty dialout cdrom sudo dip plugdev lpadmin lxd sambashare docker

I've also seen numerous suggestions to change the device's permissions directly via chmod a+rw /dev/<device>. This is terrible advice, but nothing is working so far, so I tried it anyway. It also doesn't work, as at some point during the upload process, the device is removed and recreated, resetting the permissions.
edit: I've also ensured that ModemManager is not running, and has been purged from the system.
Running the IDE as root always fails, including when the --no-sandbox argument is passed.
I'm using the AppImage download on Ubuntu 22.04, but I tried the zip download, with the same results.
edit: Previously in this spot was a note about this problem not occurring on IDE v. 1.8. That wasn't actually the case - I was just testing with a board that doesn't remove and re-create the device on upload. Using a board where that does occur (Arduino Micro in this case), the error occurs in 1.8 as well.
Using avrdude directly (as my normal user account) also works just fine.
Additional observation - when the device is recreated by the OS after plugging the Arduino board in, it's first created with crw------- 1 root root permissions, and remains in that state for a very short period of time before switching to crw-rw----+ 1 root dialout permissions, at which point uploads work as expected.

You have since rebooted (or at least logged out and in) to be certain that any chances you made to your group membership has been inherited to all processes involved?

@timemage I've been a member of those groups for literally years, so I have extreme confidence that all my groups are correct. This isn't the first time I've head to deal with this, but nothing is working this time around. Again, 1.8 works fine.

Well, I use the 2.0 IDE a little bit, but the system I'm no now is not Ubuntu, nor Debian based. If no new information shows up I may install Ubuntu in a VM may a USB device into it and see what happens when I try there. Given "using avrdude directly... works just fine", what exactly is producing this message? avrdude only as launched by the 2.0 IDE? When you tested avrdude did you test with a system installed one or the avrdude out of the .arduino15 directory? Do you see anything interesting in an strace?

What I'm seeing is that the /dev/ttyACM0 device is being recreated by the OS when I connect the board in programming mode, first with permissions crw------- 1 root root, but a short time later (like within a second or so), those permissions switch over to the expected crw-rw----+ 1 root dialout. Because I am running avrdude directly after that switch has happened, it works, but for whatever reason, IDE 2.0 looks to be sending before the device permissions have settled, leading to the error. I don't know why the device goes through two sets of permissions like it does, though.

I don't know that it does this (I'm not sure why it would), but can you verify that ModemManager is not enabled. It's not something you want running anyway.

Ah forgot to mention that in the original message, but yeah, ModemManager has already been purged from the system.

Installed Ubuntu 22.04 in an VM, disabled ModemManger, added myself to dialout, restarted to take effect, dowloaded non-appimage IDE 2.0.0 zipfile. unpacked, ran, mapped in an UNO on USB, compiled/uploaded a blink sketch twice with different blink rates. No permission errors. Are you running something like selinux, containers, modified posix capabilities, apparmor, etc?

I've not modified anything in this install that I'm aware of. Does your USB device get removed and re-created each upload? That is the core of this problem. I'm watching the file via watch -n 0.1 ls -l /dev/ttyACM0, then starting an upload. It's the short window of crw------- 1 root root permissions immediately upon creation of the device that seems to be the issue here. Everything is fine once the permissions settle, but I do not know what mechanism causes this. I assume it's in the OS, but many searches on this have come up with nothing.

Let us continue this discussion in chat.

I thought you were going to post something. But, sure I can. It'll take a little bit, but I'll put something basic up first.

oh I can make a post. I just wanted to give credit where it was due

The reason why I'm thinking you want to is that you then have more freedom to clean up the question. I'd feel weird editing your question to the degree that I'd be inclined to in order to make the answer match  cleanly with it.

fair enough. i'll take care of it

You can drop all the Edit: stuff. So there's no saga to follow. Just have it be the symptom that people are likely to find with search terms and then move all the answer material into an answer. Offhand the only input I have on the answer is that it's solvable at different levels. One is removing the package entirely another being the specific edit.

After a long debugging session in chat, we've determined that a udev entry installed by the apt package laptop-mode-tools takes a long time to run, leading to the permissions not settling on the USB device until after the IDE has attempted to upload.
This problem happens even when laptop-mode isn't enabled because you're e.g. using AC. You don't need to be actually using a laptop for this problem to occur, as laptop-mode-tools is a generic power-saving package that can be installed anywhere.
The udev rule in question is ACTION=="add", SUBSYSTEM=="usb", RUN+="lmt-udev force" in the file  /lib/udev/rules.d/99-laptop-mode.rules.
Commenting out that udev rule, or changing force to auto resolves the problem for me (without needing to restart udev, or anything else).
Larger hammers that can be used to resolve this include setting ENABLE_LAPTOP_MODE_TOOLS to 0 in /etc/laptop-mode/laptop-mode.conf, or simply removing laptop-mode-tools from the system entirely.
@timemage gets the credit for this fix.

Yeah. An Arduino user stands chance of finding this avoiding some grief with it. I may tack on some comments later that you can integrate (or not). The only one I'll mention now is just that this problem will not be particularly noticeable for a board that with a dedicated serial transceiver, e.g. the UNO, NANO, Mega, ESP8266 boards, because they don't re-enumerate on the USB bus during each reset/upload. Once the permissions become correct (quickly or slowly) the remain correct until disconnected.


text:
I need help with code for my automated garbage bin compressor
Here is my problem, I'm working on an automated garbage bin compressor. When the garbage is near the sensor, the compressor mechanism will trigger. I'm using Arduino Uno as the controller, a 12v AC window motor, an L298N motor driver, a 12v AC battery, an ultrasonic sensor, and 2 led indicators. The flow chart is as follows the sensor will detect if there is garbage in the garbage bin, if there is no garbage then the motor will not spin. If there is garbage then the motor will start spinning for 20-30 seconds and after the motor stops spinning then it will stop for 5 seconds before returning to its original position. There are 2 LED indicators, the green indicator will indicate if the motor doesn't spin and the red LED will indicate if the motor is in use. So far I'm able to program the motor to spin in 1 direction without a command to stop.
const int trigpin = 11;
const int echopin = 10;
int enA = 4;
int SPEED = 250;
int motordirection1 = 3;
int motordirection2 = 2;
int duration = 0;
int distance = 0;

void setup(){
  pinMode (trigpin, OUTPUT);
  pinMode (echopin, OUTPUT);
  pinMode (enA, OUTPUT);
  pinMode (motordirection1, OUTPUT);
  pinMode (motordirection2, OUTPUT);
  pinMode (trigpin, OUTPUT);
  pinMode (echopin, INPUT);

}

void loop(){
  digitalWrite (trigpin, LOW);
  delayMicroseconds (2);
  digitalWrite (trigpin, HIGH);
  delayMicroseconds (10);
  digitalWrite (trigpin, LOW);

  duration = pulseIn (echopin, HIGH);
  distance = duration*0.034/2;

  if (distance < 1){
  digitalWrite (enA, 0);
  digitalWrite (motordirection1, LOW);
  digitalWrite (motordirection2, LOW);
  }
  else if (distance > 2 && distance <25){
  digitalWrite (enA, SPEED);
  digitalWrite (motordirection1, HIGH);
  delay (10);
  digitalWrite (motordirection2, LOW);
  delay (50);
  digitalWrite (motordirection1, LOW);
  digitalWrite (motordirection2, LOW);
  }
  else if (distance > 15){
  digitalWrite (enA, SPEED);
  digitalWrite (motordirection1, LOW);
  delay (10);
  digitalWrite (motordirection2, HIGH);
  delay (50);
  digitalWrite (motordirection1, LOW);
  digitalWrite (motordirection2, LOW);
  }
}

Here is the program that I have. I'm not sure if it's good or not.
EDIT: I made the adjustment in the code and it works but now the problem is the motor only moves in 1 direction when the sensor detects something but after it's out of range the motor doesn't spin back.

We can't do the work for you. Please try yourself and come back when you have a concrete problem, not a whole range of problems.

returning its original position ... how will you know the position?

PMF - so far im able to code 2 separate program. The first program is when the program is started the motor will start spinning until the program is shutdown. The second program is to detect using the ultrasonic sensor. Based on the problem you can see that im incompetent at programming as i only started programming in this August. So yes im not very experienced in this subject

jsotola - from the question that i posted, the motor will start spinning in whatever direction for 20-30 seconds then it will simply turn back for 20-30 seconds in the opposite direction from when it started.

@Atek, are you not aware that a motor slows down when it is doing work?

@jsotola this project is still in its testing phase, that's why i need confirmation if the code i wrote is good to use or not. Im not sure what you mean by the motor slows down, do elaborate

do you not have any experience with machines? ... what about yourself, do you move just as fast when you carry a heavy weight?

the code is irrelevant ... start with some code that runs the motor in one direction ... pauses for 1 second and repeats ... change code that runs in reverse ... ... then combine the two ... etc. etc.

@jsotola I'll try to code what you just said

You wrote:

The flow chart is as follows [...]

Rather than a flow chart, you should think of your system as a finite
state machine, and draw its state diagram.
Superficially, a state diagram may look like a flow chart, but it has
some specific properties:

Within the states represented in the diagram, the machine does nothing
but wait for some event to happen.
Events trigger transitions between states.
Whatever actions the machine may perform can only happen on state
transitions.

Here is a state diagram that may represent your system:

In this diagram, the actions are implicit (because I am lazy), but you
may want to write them down explicitly. For example, on the transition
IDLE → MOVING_FORWARD the motor should be started, and on the next
transition (MOVING_FORWARD → WAITING) it should be stopped.
Note also that this only represents my understanding of your
specifications. You will probably have to amend it in order for it to
reflect what you really want to do.
Once you have the state diagram, the next step is... to debug it! It is
essential that you do this debugging before you start to write any
line of code. At this stage I can already spot a couple of issues:

One transition is conditioned on the “compressor” reaching its home
position. This means that you will need some means to detect this
event, like an endstop.
After compressing some garbage... there is still garbage in the bin.
Then, after the transition MOVING_BACK → IDLE, garbage will be
detected, the system will immediately transition to MOVING_FORWARD,
and it will get stuck in an endless loop.

Once you are done debugging the state diagram, and only then, can
you start writing the code. I suggest you follow the steps of Majenko's
tutorial on finite state machines: translating the diagram to
code should be quite straight forward.

I'll try to understand then try to implement it


text:
How to read and Serial.print the contents (current values) of an 8-bit register?
Currently I'm using:
  ADMUX = 0b01100000; //example
  for (int i = 7; i >= 0; i--) {
    Serial.print(bitRead(ADMUX, i));
  }

This correctly prints:
  01100000

But is there a simpler way?
Before coming up with above for loop I tried using just:
Serial.println(ADMUX);       //converts to integers: 96
Serial.println(ADMUX, BIN);  //leaves out leading zeros: 1100000
Serial.write(ADMUX);         //converts to ASCII char: `

Anything else I don't know of?

Are you asking because you're trying to avoid writing a loop yourself, because you're wondering if it's possible to do with fewer moving parts (whether that's done in your code or someone else's), or are you asking because you're under the impression that without a built-in thing you'd need to write a loop each time you wanted to print a value this way?

I'm not entirely sure what you're asking either ;)

Me being new to using timers and registers, and having done some reading and experimenting recently, I just want to know what is the preferred or most elegant way to do this. I couldn't find an answer here myself. So I tried above ways. Maybe there is something better. If there is I'd like to know it ;)

itoa(n, buffer, 2) is not part of C++, but available in  Arduino, and achieve the same as Serial.println(num, BIN);. It need to define the buffer like char buffer[33] before using, so it is not much simpler.

If you look how print_number is defined which is called by all Serial.print(number, base), and how binary is defined in Arduino Core, there is really no simpler way. Just define your for..loop as a function print_binary() and use it if you need.

"better" (without qualification) and "preferred" are highly contextual and mostly opinion based, which something that questions get closed for on stackexchange.  So, if you have a way to make the question more specific or objectively answerable, it's probably a good idea to do that.

@timemage I did ask 'simpler'.

@hcheung itoa() followed by Serial.print still no leading zeros. So indeed the same. Thanks for your input. Happy with the for loop then for printing. And I guess for other purposes I shouldn't be bothered by the left out leading zeros, as I suppose they don't make a difference when reading or comparing anyway.

@Gaai i noticed. that's part of what prompted my original question. maybe it's just me.

Another option:
#include <LibPrintf.h>
printf("%.8b", ADMUX); //prints: 0110000

The LibPrintf.h library is standard included on ESP boards.
%b stands for binary. .8 for 8 decimal places, which adds leading zero's to all truncated (binary) numbers.
It becomes *simpler if you wanted to print the variable name along with it like:
printf("ADMUX: %.8b", ADMUX);

Results in:
ADMUX: 01100000

*Simpler in the way it now only occupies a single line of code.

Where the question was tagged UNO and NANO the following may be worth knowing for anyone considering this route. A minimal test framework around code in question results in Sketch uses 1542 bytes (4%) of program storage space. Maximum is 32256 bytes.  The same around the code in answer results in Sketch uses 11456 bytes (35%) of program storage space. Maximum is 32256 bytes.

You're right of course. And answer is cheating anyway as it uses a complete library. You could achieve the same one liner with a simple function for multiple calls. But thought it worth a mention especially as the library is standard on esp boards, even though not tagged. Might be good knowledge for people looking to do it on those boards aswell.

Or just that the cost is sort of amortized (through not removed) by more use of LibPrintf. I didn't think so much about whether or not it was cheating. Only that this can be particularly important to be aware of. Any implementation of printf is a beast. However, on a project of any serious size the avr-libc (or whatever) one has often already been paid for, so to speak, by having been used at least once in someone else's code, whether you like it or not.

So if any printf or the like is already been used elsewhere (taking up that costly memory space anyway), you might aswell use it for this? That what you mean? (had to look up amortized, learning everyday ;)

No, it is not that simple. This happens per printf implementation. The cost-per-call for any given individual printf() implementation enormous when you use it once. So the worst case scenario is where you have one usage of avr-libc one and one usage of the libprintf one. Also, the author(s) have documented how you can remove features to trim the library size. There's only so much more I can say about this relevant to your answer.


text:
Odd characters in serial monitor
I have been recently working on a website that takes input from the arduino ie- temperature and humidity. But there is a fatal problem that I've encountered, the serial monitor spews out some garbage with some actual readings. Is there a way to eliminate this?
 ╰─λ cat /dev/ttyACM0
T0°C
Humidity: 39.00%
00%
Temperature: 32.70°C
Humidity: 39.00%
Temperature: 32.70°C
Humidity: 39.00%
Temperature: 32.70°C
Humidity: 39.00%
00%
Temperature: 32.70°C
Humidity: 39.00%
Temperature: 32.70°C
Humidity: 39.00%
Temperature: 32.70°C
Humidity: 39.00%
idit9.00Tempure:70°Humi: 39
emperatu32.7
Huty: 0%
idit9.00Tempure:70°umidity.00%Tratu32.7
idit9.00Tempture.70�Humi: 39
empere: 0°Cmidi39.0
atur°C
Hum9.00

code-
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <DHT_U.h>

#define DHTPIN 4

#define DHTTYPE    DHT11
DHT_Unified dht(DHTPIN, DHTTYPE);

uint32_t delayMS;

void setup() {
  Serial.begin(9600);
  sensor_t sensor;
  dht.begin();
  delayMS = sensor.min_delay / 1000;
}

void loop() {
  delay(delayMS);
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.println(F("Error reading temperature!"));
  }
  else {
    Serial.print(F("Temperature: "));
    Serial.print(event.temperature);
    Serial.println(F("°C"));
  }
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.println(F("Error reading humidity!"));
  }
  else {
    Serial.print(F("Humidity: "));
    Serial.print(event.relative_humidity);
    Serial.println(F("%"));
  }
}

board - Arduino Uno (R3)

Welcome to Arduino:SE.  Without seeing your code and hardware setup, we have no way to answer your question.

@sempaiscuba thanks for correcting me. I have edited it now, let me know if there are some further corrections.

I would print something unique in setup() that makes it evident in the output listing that it is only running once.

What is the actual value of delayMS? The calculation looks fishy, since sensor is not initialized. The value should be around 2500ms.

@PMF It says its 2000ms

Do you have ModemManager installed on your system? Could you check that nobody else is messing with the serial port? Like this: sudo fuser -v /dev/ttyACM0.

Evidently DHT11 sensors need at least 2 seconds to make a new reading.  Consider waiting slightly more than 2 seconds in your loop. Personally I couldn't get a DHTxx to work reliably and switched to, I believe, an si7021.

As has been noted in the comments, you are trying to read the sensor at a rate that is too fast.
Try changing this line:
delayMS = sensor.min_delay / 1000;

to:
delayMS = sensor.min_delay = 1000;

or:
delayMS = sensor.min_delay = 3000;

This will read the sensor at a slower rate and should give you clean output.


text:
Need help with calling an API using an Arduino system
As stated in the title, I need help with calling an API. I'm trying to integrate make a call using the Verkada API but it seems to be using a cURL library that I'm not entirely certain I can get to work with my Arduino Mega2560 and an ethernet shield. The API documentation gives this C/C++ code shown below but with no guidance on how to use it
CURL *hnd = curl_easy_init();

curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "GET");
curl_easy_setopt(hnd, CURLOPT_URL, "https://api.verkada.com/cameras/v1/alerts?org_id=ORGANIZATION_ID&include_image_url=false&page_size=100");

struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "accept: application/json");
headers = curl_slist_append(headers, "x-api-key: API_KEY");
curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, headers);

CURLcode ret = curl_easy_perform(hnd);

This code and the documentation can be found here: https://apidocs.verkada.com/reference/getnotificationsviewv1
If there's any more necessary information I haven't I'm happy to look more and provide it. If I need to be taking a different approach I would also really appreciate some advice on that.
Thank you so much!

you can use the ArduinoHttpClient library

I've been looking at the HTTPClient Library. Is there a  good way to think about translating the above code in a way that would work how it expects it to work? Verkada expects an organization ID and API Key and I don't know if that translates direct into the functions included in the library or works like a standard authorization

use a web browser, such as Chrome to retrieve the data ... use the development tools in Chrome to see what data is passed back and forth between the browser and the server ... your question is not related to Arduino

Do you know whether this API can be accessed through unencrypted HTTP? @Juraj: Seems to me that the HTTPClient library does not support HTTPS.

@EdgarBonet, you are right. then it is not possible with Ethernet shield on Mega. OP has to change to a 32-bit board with SSLClient library with Ethernet library. or instead of Ethernet shield use a WiFi shield or module which provides SSL (WiFi101, esp8266).


text:
Why does "Get Board Info" not work, but I can still program my Arduino Nano?
Dear Stack Exchangers,
I have been working with Arduinos for probably 10 years, and as a habit the first thing I do when I connect a device to the USB port is run the "Tools > Get Board Info" in the Arduino IDE just to make sure I've got the correct port selected, USB cable is good, etc.
Well tonight when I connected a Nano, the "Get Board Info" didn't work at all. So after spending hours rebooting, trying different cables, etc. I eventually just tried uploading a sketch, and that worked fine! But the "Get Board Info" still does not work.
Anybody have any ideas what is going on? Thanks!
Sincerely,
Ramblin' Wreck

By "Nano" you're referring to the ATMega328P based original Nano? Or one of a pile of other board's with that in the name? When it "doesn't work" what does it do instead? Which IDE version?

It has "NANO" printed on the board. Today though, the "Get Board Info" command works fine and I receive the following message:
BN: Unknown board
VID: 1A86
PID: 7523
SN: Upload any sketch to obtain it

I am using Arduino 1.8.13 on a Dell laptop with Windows 10.

To be clear, you were not getting that message before? If so, what were you getting? The content of the message in you are currently getting is in line with Juraj's answer.

Timemage, correct, I was NOT getting that message before. No message window popped up at all. I notice that today the Nano is on COM7 (used Device Manager to determine this), and last night it was on COM5. So perhaps that has something to do with it.

Odd. You should have received one of these messages instead of nothing at all.

The classic Arduino Nano uses an FTDI chip as USB to TTL Serial adapter. Many Nano (and Uno and Mega) clones use the CH340 as USB adapter. These USB chips present themselves with id set by the USB chip manufacturer. This doesn't provide a way to identify the specific board.
Original Uno and Mega Rev 3 and some clones use ATmega16u2 as USB adapter with a firmware by Arduino. Arduino sets the USB id in the firmware so it can identify as specific board type. (People reported Mega clones which presented itself as Uno).
The boards with MCU with native USB like Leonardo, Micro and ARM boards (Zero, MKR, Nano IoT, Nano BLE) provide the USB id set in boards.txt so they can be identified too.


text:
text section exceeds available space in board
When I compile this code it gives the error mentioned above.
I saw online a way to resolve this: Serial.println(F("..."));
For fixed string literal I changed it but still didn't work.
I'm compiling this for ESP32 board.
#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include <DHT.h>
#include <SimpleTimer.h>

const char *service_name = "PROV_SmartHome";
const char *pop = "1234";

// define the Chip Id
uint32_t espChipId = 5;

// define the Node Name
char nodeName[] = "ESP32_Smarthome";

// define the Device Names
char deviceName_1[] = "Switch1";
char deviceName_2[] = "Switch2";
char deviceName_3[] = "Switch3";
char deviceName_4[] = "Switch4";

// define the GPIO connected with Relays and switches
static uint8_t RelayPin1 = 23;  //D23
static uint8_t RelayPin2 = 22;  //D22
static uint8_t RelayPin3 = 21;  //D21
static uint8_t RelayPin4 = 19;  //D19

static uint8_t SwitchPin1 = 13;  //D13
static uint8_t SwitchPin2 = 12;  //D12
static uint8_t SwitchPin3 = 14;  //D14
static uint8_t SwitchPin4 = 27;  //D27

static uint8_t wifiLed      = 2;   //D2
static uint8_t gpio_reset   = 0;
static uint8_t DHTPIN       = 18; // D18  pin connected with DHT
static uint8_t LDR_PIN      = 39; // VN  pin connected with LDR

/* Variable for reading pin status*/
// Relay State
bool toggleState_1 = LOW; //Define integer to remember the toggle state for relay 1
bool toggleState_2 = LOW; //Define integer to remember the toggle state for relay 2
bool toggleState_3 = LOW; //Define integer to remember the toggle state for relay 3
bool toggleState_4 = LOW; //Define integer to remember the toggle state for relay 4

// Switch State
bool SwitchState_1 = LOW;
bool SwitchState_2 = LOW;
bool SwitchState_3 = LOW;
bool SwitchState_4 = LOW;

float temperature1 = 0;
float humidity1   = 0;
float ldrVal  = 0;

DHT dht(DHTPIN, DHT11);  //For DHT 11
//DHT dht(DHTPIN, DHT22);  //For DHT 22

SimpleTimer Timer;

//The framework provides some standard device types like switch, lightbulb, fan, temperature sensor.
static Switch my_switch1(deviceName_1, &RelayPin1);
static Switch my_switch2(deviceName_2, &RelayPin2);
static Switch my_switch3(deviceName_3, &RelayPin3);
static Switch my_switch4(deviceName_4, &RelayPin4);
static TemperatureSensor temperature("Temperature");
static TemperatureSensor humidity("Humidity");
static TemperatureSensor ldr("LDR");

void sysProvEvent(arduino_event_t *sys_event)
{
  switch (sys_event->event_id) {
    case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
      printQR(service_name, pop, "ble");
#else
      Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
      printQR(service_name, pop, "softap");
#endif
      break;
    case ARDUINO_EVENT_WIFI_STA_CONNECTED:
      Serial.printf("\nConnected to Wi-Fi!\n");
      digitalWrite(wifiLed, true);
      break;
  }
}

void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
  const char *device_name = device->getDeviceName();
  const char *param_name = param->getParamName();

  if (strcmp(device_name, deviceName_1) == 0) {

    Serial.printf("Lightbulb = %s\n", val.val.b ? "true" : "false");

    if (strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b ? "true" : "false", device_name, param_name);
      toggleState_1 = val.val.b;
      (toggleState_1 == false) ? digitalWrite(RelayPin1, HIGH) : digitalWrite(RelayPin1, LOW);
      param->updateAndReport(val);
    }

  } else if (strcmp(device_name, deviceName_2) == 0) {

    Serial.printf("Switch value = %s\n", val.val.b ? "true" : "false");

    if (strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b ? "true" : "false", device_name, param_name);
      toggleState_2 = val.val.b;
      (toggleState_2 == false) ? digitalWrite(RelayPin2, HIGH) : digitalWrite(RelayPin2, LOW);
      param->updateAndReport(val);
    }

  } else if (strcmp(device_name, deviceName_3) == 0) {

    Serial.printf("Switch value = %s\n", val.val.b ? "true" : "false");

    if (strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b ? "true" : "false", device_name, param_name);
      toggleState_3 = val.val.b;
      (toggleState_3 == false) ? digitalWrite(RelayPin3, HIGH) : digitalWrite(RelayPin3, LOW);
      param->updateAndReport(val);
    }

  } else if (strcmp(device_name, deviceName_4) == 0) {

    Serial.printf("Switch value = %s\n", val.val.b ? "true" : "false");

    if (strcmp(param_name, "Power") == 0) {
      Serial.printf("Received value = %s for %s - %s\n", val.val.b ? "true" : "false", device_name, param_name);
      toggleState_4 = val.val.b;
      (toggleState_4 == false) ? digitalWrite(RelayPin4, HIGH) : digitalWrite(RelayPin4, LOW);
      param->updateAndReport(val);
    }

  }
}

void readSensor() {

  ldrVal = map(analogRead(LDR_PIN), 400, 4200, 0, 100);
  Serial.print("LDR - "); Serial.println(ldrVal);
  float h = dht.readHumidity();
  float t = dht.readTemperature(); // or dht.readTemperature(true) for Fahrenheit

  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  else {
    humidity1 = h;
    temperature1 = t;
    Serial.print("Temperature - "); Serial.println(t);
    Serial.print("Humidity - "); Serial.println(h);
  }
}

void sendSensor()
{
  readSensor();
  temperature.updateAndReportParam("Temperature", temperature1);
  humidity.updateAndReportParam("Temperature", humidity1);
  ldr.updateAndReportParam("Temperature", ldrVal);
}

void manual_control()
{
  if (digitalRead(SwitchPin1) == LOW && SwitchState_1 == LOW) {
    digitalWrite(RelayPin1, LOW);
    toggleState_1 = 1;
    SwitchState_1 = HIGH;
    my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_1);
    Serial.println("Switch-1 on");
  }
  if (digitalRead(SwitchPin1) == HIGH && SwitchState_1 == HIGH) {
    digitalWrite(RelayPin1, HIGH);
    toggleState_1 = 0;
    SwitchState_1 = LOW;
    my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_1);
    Serial.println("Switch-1 off");
  }
  if (digitalRead(SwitchPin2) == LOW && SwitchState_2 == LOW) {
    digitalWrite(RelayPin2, LOW);
    toggleState_2 = 1;
    SwitchState_2 = HIGH;
    my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_2);
    Serial.println("Switch-2 on");
  }
  if (digitalRead(SwitchPin2) == HIGH && SwitchState_2 == HIGH) {
    digitalWrite(RelayPin2, HIGH);
    toggleState_2 = 0;
    SwitchState_2 = LOW;
    my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_2);
    Serial.println("Switch-2 off");
  }
  if (digitalRead(SwitchPin3) == LOW && SwitchState_3 == LOW) {
    digitalWrite(RelayPin3, LOW);
    toggleState_3 = 1;
    SwitchState_3 = HIGH;
    my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_3);
    Serial.println("Switch-3 on");
  }
  if (digitalRead(SwitchPin3) == HIGH && SwitchState_3 == HIGH) {
    digitalWrite(RelayPin3, HIGH);
    toggleState_3 = 0;
    SwitchState_3 = LOW;
    my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_3);
    Serial.println("Switch-3 off");
  }
  if (digitalRead(SwitchPin4) == LOW && SwitchState_4 == LOW) {
    digitalWrite(RelayPin4, LOW);
    toggleState_4 = 1;
    SwitchState_4 = HIGH;
    my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_4);
    Serial.println("Switch-4 on");
  }
  if (digitalRead(SwitchPin4) == HIGH && SwitchState_4 == HIGH) {
    digitalWrite(RelayPin4, HIGH);
    toggleState_4 = 0;
    SwitchState_4 = LOW;
    my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_4);
    Serial.println("Switch-4 off");
  }
}

void setup()
{

  Serial.begin(115200);

  // Set the Relays GPIOs as output mode
  pinMode(RelayPin1, OUTPUT);
  pinMode(RelayPin2, OUTPUT);
  pinMode(RelayPin3, OUTPUT);
  pinMode(RelayPin4, OUTPUT);
  pinMode(wifiLed, OUTPUT);

  // Configure the input GPIOs
  pinMode(SwitchPin1, INPUT_PULLUP);
  pinMode(SwitchPin2, INPUT_PULLUP);
  pinMode(SwitchPin3, INPUT_PULLUP);
  pinMode(SwitchPin4, INPUT_PULLUP);
  pinMode(gpio_reset, INPUT);

  // Write to the GPIOs the default state on booting
  digitalWrite(RelayPin1, !toggleState_1);
  digitalWrite(RelayPin2, !toggleState_2);
  digitalWrite(RelayPin3, !toggleState_3);
  digitalWrite(RelayPin4, !toggleState_4);
  digitalWrite(wifiLed, LOW);
  dht.begin();    // Enabling DHT sensor

  Node my_node;
  my_node = RMaker.initNode(nodeName);

  //Standard switch device
  my_switch1.addCb(write_callback);
  my_switch2.addCb(write_callback);
  my_switch3.addCb(write_callback);
  my_switch4.addCb(write_callback);

  //Add switch device to the node
  my_node.addDevice(my_switch1);
  my_node.addDevice(my_switch2);
  my_node.addDevice(my_switch3);
  my_node.addDevice(my_switch4);
  my_node.addDevice(temperature);
  my_node.addDevice(humidity);
  my_node.addDevice(ldr);

  Timer.setInterval(2000);

  //This is optional
  RMaker.enableOTA(OTA_USING_PARAMS);
  //If you want to enable scheduling, set time zone for your region using setTimeZone().
  //The list of available values are provided here https://rainmaker.espressif.com/docs/time-service.html
  // RMaker.setTimeZone("Asia/Shanghai");
  // Alternatively, enable the Timezone service and let the phone apps set the appropriate timezone
  RMaker.enableTZService();
  RMaker.enableSchedule();

  //Service Name
  for (int i = 0; i < 17; i = i + 8) {
    espChipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
  }

  Serial.printf("\nChip ID:  %d Service Name: %s\n", espChipId, service_name);

  Serial.printf("\nStarting ESP-RainMaker\n");
  RMaker.start();

  WiFi.onEvent(sysProvEvent);
#if CONFIG_IDF_TARGET_ESP32
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
#else
  WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
#endif

  my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
  my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
  my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
  my_switch4.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
}

void loop()
{
  // Read GPIO0 (external button to reset device
  if (digitalRead(gpio_reset) == LOW) { //Push button pressed
    Serial.printf("Reset Button Pressed!\n");
    // Key debounce handling
    delay(100);
    int startTime = millis();
    while (digitalRead(gpio_reset) == LOW) delay(50);
    int endTime = millis();

    if ((endTime - startTime) > 10000) {
      // If key pressed for more than 10secs, reset all
      Serial.printf("Reset to factory.\n");
      RMakerFactoryReset(2);
    } else if ((endTime - startTime) > 3000) {
      Serial.printf("Reset Wi-Fi.\n");
      // If key pressed for more than 3secs, but less than 10, reset Wi-Fi
      RMakerWiFiReset(2);
    }
  }
  delay(100);

  if (WiFi.status() != WL_CONNECTED)
  {
    //Serial.println("WiFi Not Connected");
    digitalWrite(wifiLed, false);
  }
  else
  {
    //Serial.println("WiFi Connected");
    digitalWrite(wifiLed, true);
    if (Timer.isReady()) {
      //Serial.println("Sending Sensor Data");
      sendSensor();
      Timer.reset();      // Reset a second timer
    }
  }
  manual_control();
}

ESP32 Board details here :

Are you exceeding program space/flash or RAM? By how much? Have you checked how much space the libraries use?

@chrisl I don't know how can I check it. I'll look into it.

When you compile a sketch in the Arduino IDE it will output the amount of used program memory and how much RAM is used by global variables. That gives you a good hint.

Where is all this text you mentioned? This tiny code should easily fit into the ESP's flash (if you're using F(...))... what flash size does your ESP have? Maybe you can get around it using a different partition scheme.

Just how large is the compiled program? Could you include the last lines of the compiler output in your question? The tip from @SimSon is also a good one. If you don't need a file system or OTA, you could select a partition scheme that maximizes available code space, like "Huge APP" or  one of the "No OTA" schemes.

esp32 toolchain uses string literals from flash automatically. the F macro does nothing

Maybe I've missed something, but the flash area is partitioned between usable app (roughly sketch code) space and usable filesystem space. I don't see any indication in your question that you're using a filesystem at all.
Keeping your current settings except for switching the partition setting to "Huge APP (3MB No OTA/1MB SPIFFS)" resulted in:
Sketch uses 1790473 bytes (56%) of program storage space. Maximum is 3145728 bytes.
Global variables use 53260 bytes (16%) of dynamic memory, leaving 274420 bytes for local variables. Maximum is 327680 bytes.

I'm not even sure "Huge APP" makes the most sense. Only that 3MB is larger than 1.2MB and larger than your current 1.8(ish)MB build apparently needs. It says "no-OTA" but you don't seem to be using that either. So, this seems like something you can do irrespective of whatever contributions you can trim from the text segment by tweaking your code.

Partition to Rainmaker I did, its working fine now

You are programming for an embedded processor with limited memory.  Both program space and random access memory (RAM).  Every letter you put in quotes takes up a byte of memory. If you are only over the limit by a little consider abbreviating your text.  For example consider changing strings like:

"Provisioning Started with name"

... to something along the lines of ...

"Prov name"

If by a lot then consider changing your code.  Many times you quote similar text. For example consider changing the following code:
// define the Device Names
char deviceName_1[] = "Switch1";
char deviceName_2[] = "Switch2";
char deviceName_3[] = "Switch3";
char deviceName_4[] = "Switch4";
...
//The framework provides some standard device types like switch, lightbulb, fan, temperature sensor.
static Switch my_switch1(deviceName_1, &RelayPin1);
static Switch my_switch2(deviceName_2, &RelayPin2);
static Switch my_switch3(deviceName_3, &RelayPin3);
static Switch my_switch4(deviceName_4, &RelayPin4);

... to something along the lines of ...
//The framework provides some standard device types like switch, lightbulb, fan, temperature sensor.
String stringOne = "Switch";
String stringTwo = "1"
static Switch my_switch1(stringOne + stringTwo, &RelayPin1);
stringTwo = "2"
static Switch my_switch2(stringOne + stringTwo, &RelayPin2);
stringTwo = "3"
static Switch my_switch3(stringOne + stringTwo, &RelayPin3);
stringTwo = "4"
static Switch my_switch4(stringOne + stringTwo, &RelayPin4);

... the point here is to avoid using up program and random access memory with repeated strings.

If any find a problem in the above code or have insight into a more efficient approach please post.  I'll be more than happy to edit the answer to make it better.

I'll implement these from now on.

You could use enums to replace all the char strings (which take a lot of memory space) into integers behind the scene.
enum deviceNames {Switch1, Switch2, Switch3, Switch4};
deviceNames deviceName; //define variable of type deviceNames

for comparison you can use:
if (deviceName == Switch1); //Switch1 equals 0 for the compiler, Stich2 equals 1 etc etc.

Frist however, you should have a look at the functions getDeviceName() and getParamName(). Could you post them? Would need to see if you can make these changes there aswell.
Since you are getting the variable device_name from there, again as a string. Enums would do no good without additional changes to the functions.
*Also I noticed you still didn't use Serial.print(F());
Read up on storing strings and variables into PROGMEM if you're interested.
*EDIT:
As user Juraj noted in the comments: "the esp32 toolchain uses string literals from flash automatically. the F macro does nothing".
Perhaps you can benefit form newlib nano formatting for printf? I'm not sure as I don't know what difference it makes on your esp32 version. You'll have to check out.

Note that F() is meant to save RAM (data section), not flash (text section).

Yes, as of yet we don't know which of those two memory spaces is exceeded.

esp32 toolchain uses string literals from flash automatically. the F macro does nothing

The title of the question says which of those two memory spaces is exceeded.

@Juraj Aha, that I didn't know. Thanks for noting that.


text:
Read Digital Input from Arduino Pin defined as OUTPUT
I'm working on a Home Automation Project.
I can turn on-off ESP32 pin from Alexa and Google Assistant Successfully now.
What I need help is with a way to read if the AC supply is ON/OFF on the Arduino pin.
Or if possible to save pins I would want to read it on the same pin which id defined as Digital output to control the relay.
Below attached image of what I have in mind.

Normal switch turns On/off supply to load without any requirement of WiFi.
Load is also connected to Relay NO, which is controlled by Arduino Pin D13.

What I want is instead of just reading the status of the D13 pin, I want to read the status of the Mechanical Switch which directly provide to Load.
So I'll actual status of the Load whether it's turned on by Switch or Relay with interrupting directly connected switch from load to supply.

Edited: As others suggested it is not possible to use the Same Pin to control the relay and read AC load status. So is there a way to read the AC supply through the GPIO pin of ESP32 maintaining galvanic isolation, (opposite working of Relay)?

if your manual switch has a second contact, you can read that

Every time I want to answer I stop myself because it's dangerous to connect to the high voltage 110 or 220 VAC side.  I like @edgar's answer.  If your load is resistive (old incandescent lamps) you might look at old X10 schematics to see what they did.  If new (LED lamps) then do what edgar said.

If you want to know the state of the load, I suggest to put the
mechanical switch on the low-voltage side of the relay:

simulate this circuit – Schematic created using CircuitLab
The voltage divider R1/R2 is meant to lower the
voltage at the transistor's collector (up to one diode threshold above
Vcc) to a value suitable for the Arduino digital input.
Note that you still need two separate inputs for controlling and for
sensing the state.

That was my concern, I don't want to use the switch to turn on the load indirectly, as changing the switch in the future will be easier than the relays also any fault in the circuit won't affect the manual system. But if I consider your case why don't I use the Switch in the same place as the Control Pin?

@JustdoinGodswork: If you connect the switch and the control pin together, you will likely short the pin, and possibly destroy its output stage.

What you want to do is not possible, you'll need an extra pin. The reason is that the relay requires a lot of current (works like a very strong pulldown resistor). So, whatever (high impedance) sense signal you apply to the relay, it will just be "consumed" by the relay.
When reading the state of the switch, i.e. the voltage across it, galvanic isolation is absolutely mandatory (mains voltage can be deadly). This can be achieved with an opto coupler and some lines of code or additional hardware - as it's AC voltage, you can't simply read a steady voltage, so you'd either have to sample the AC signal or incorporate some kind of circuitry (software is simpler and cheaper).
Another issue with your circuit is that you must not drive the relay directly with the GPIO. The relay sinks way to much current, it'll fry the GPIO. Use a transistor to switch it.

My bad for the cheap circuit, I couldn't find an online tool to make it. I'll use the proper Opto coupler driver circuit for the relay in actual hardware. Then I'll try to find an increased GPIO pin controller as my priority is not to interfere with the manual system. Is there any device that is opposite to the relay?
Eg. If AC passes through the coil I'd be able to read it at a GPIO pin?


text:
Is there a way to strip a library from all unused parts and defines, automatically?
Say you want to investigate part of the code you use from a rather large library, but it's buried between all kinds of #defines and classes etc, that you're never gonna use in your code.
Is there a tool for stripping those unused/unnecessary parts away (like the (pre-)compiler), without converting it to machine language? That would make it much easier to see what happens in the code, and what code does what. Would be a great learning tool imho.

Not quite an answer to your question but... the command avr-nm can tell you how much flash is being used by each function or method.

Good to know! I'll check the memory list from my code. Does it show unused functions that don't take any space once compiled? Saw a grep reference in there too, nostalgia hits... Man, I was pretty handy with grep and sed once. Could've probably stripped the defines that way.

avr-nm works on the compiler output: it cannot see the stuff that was removed or optimized away by the compiler. Inlined functions won't be shown either, as they become part of the functions that embed them (typically setup() and loop() get inlined into main()). You may get more relevant output if you tweak the compiler options to remove link-time optimization (-flto), as this tends to make the compiler very aggressive at inlining.

you are locking for the -E parameter of the compiler which produces C++ source code after preprocessor?

@Juraj Maybe. That sounds more like it.

Are you looking for a tool that "organizes" all sources for you to quickly navigate through it? Then of course the Arduino IDE is not the right one. You might want to try other IDEs, perhaps augmented with Arduino specific plugins, or specifically designed tools. And of course you need all the source files of the library in question, which is not the usual case.

I'll try Visual Studio Code see what I can find. Got it already for websites and javascript and there is quite a lot of options there.

Yes! I found a cool tool to strip the #ifdef and #define stuff: Coan the C preprocessor chainsaw. Off to investigate ;)

The compiler is called in optimization mode (it is even possible to specify how aggressive it will optimize). It will remove all variables and functions, that are not used in your code. Also it can replace variables that never change with literals to make the code smaller. That's already what is happening and you don't need to worry about that.
About the #defines: Everything with a # at the start is interpreted by the preprocessor. That means, that these things are done even before the compiler gets to see the code. Lets say you define a pin number via #define pin 6, then the preprocessor will replace any mentioning of pin with 6 in the code, before it hands the result over to the compiler. The compiler will never see any defines.
I'm not able to tell you, how the compiler optimizes the code. That's probably very complex. Though the avr-gcc compiler is opensource, so if you really want to learn what it does, you can always analyze its source code.

I thought if a compiler can be smart enough to strip all unused variables and functions away and convert what's left in machine language

While I don't know much about how the optimization works, I don't think that it happens in that order. I find it very unlikely, that the compiler would optimize the C++ code. Though it might do that at the assembler level (since avr-gcc first converts the C++ code to assembler and then compiles to machine code). Searching in the assembler code equivalent of the C++ code isn't a real option either.
You are probably stuck with a full text search function of a program of your choice. Most OSs will also provide that function out of the box. I know, that you can search all files of a directory for a term from the Windows explorer. On systems like Ubuntu/Debian/CentOS and similar you can use the grep command in recursive mode to search for a term. On Mac you can probably also use grep.

Re “post processor”: you mean “preprocessor”.

@EdgarBonet Oh, thanks. Definitely had preprocessor in my head when writing this XD

Thanks for taking the time to answer. I knew the compiler takes care of all that but I'd like to be able to 'quickly' look at a specific code blok (still c++, not compiler code) without it being scattered all around in a library of other functions and methods. I thought if a compiler can be smart enough to strip all unused variables and functions away and convert what's left in machine language, maybe there also is a tool that only strips but doesn't convert. It would be easier to learn how certain parts work that way. Bit of wishful thinking maybe ;)

Ah, ok. Now I understand better. I added to my answer, though my answer to that part is basically just no

I clarified my original question, thanks.

The compiler doesn't quite work like that. It compiles each individual .cpp file into an object file (the .ino file becomes a .cpp file after a bit of pre-processing). I have an answer about the exact process the compiler uses there.
The libraries are also collections of .cpp files which also get turned into object files.
Optimization of unused variables would occur at that point. In other words, the compiler can optimize one compilation unit (one source file) because it can see what parts are used and what are not.
Then the linking phase commences which joins all the object files together, looking for places where a function in a library is called. So for example if you call Serial.begin() somewhere, then the linker will try to find an object file which implements that.
The linker is smart enough to not include code that is not required, so for example, if you never called Serial.begin () then it would not copy in that part of the Serial library.
In the process of doing that it resolves "jumps" and subroutine calls, so that your calls to library functions end up pointing to the place in the program memory where it has put them.
Because this is done at a late stage (after the source has been compiled) you don't really ever have a copy of the source "as linked".
However what you can do is disassemble the object file which gives you the machine code that has actually made it to the final executable. Done properly it will also include the lines of source (C++) code that generated each batch of assembler lines.
If you turn on "verbose compiling" you should see near the end of the compilation output an "ELF" file, and you can then send that to avr-objdump to turn it back into assembler:
avr-objdump -S xxx.elf

It's not great, if you aren't used to assembler, but it gives you a clue as to what made it into the executable file, and where. For a single line of C++ code you might see something like this:
    reg = portModeRegister(port);
 310:   90 e0           ldi r25, 0x00   ; 0
 312:   88 0f           add r24, r24
 314:   99 1f           adc r25, r25
 316:   fc 01           movw    r30, r24
 318:   e8 59           subi    r30, 0x98   ; 152
 31a:   ff 4f           sbci    r31, 0xFF   ; 255
 31c:   a5 91           lpm r26, Z+
 31e:   b4 91           lpm r27, Z+

The -E command for gcc generates preprocessed C and CPP source.
I didn't find a way to integrate it into the Arduino build process. Only thing I could do was edit platform.txt and change the compile command so it generates the preprocessed cpp of a compilation unit instated of .o files. Then linking failed of course.
The produced cpp was I think less readable than the original because it contained many generated comments and original line number instructions.
the changed cpp recipe in platform txt:
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} -E {includes} "{source_file}" -o "{object_file}.cpp"

I added the -E flag and .cpp file extension for the -o option value
You can see the result in the temporary build folder. You can get the location of that folder from the IDE console when you build the sketch with Verify. (you may need to turn on the verbose compile in Preferences).

Thanks, I will need to have a good look at all that to see if I can figure it out. Haven't done it before. Is this all command line? Got a Mac nowadays (pfff, still getting used to it) havent touched a terminal yet.

no command line. it is a command used by the IDE to build the sketch for upload. you have to change it in platform.txt and it will generate the preprocessed cpp instead of creating the hex for upload

Cool. Gonna check it out soon.


text:
MFRC522 board not detected. Red LED lighting
Mega 2560.
I can't get the RFID board detected. The code is as below, and outputs Didn't find MFRC522 board.. I also tested some other library and test code with success.
I triple checked the wires (3,3V pin, GND, and PWM pin 8 and 9).
I have some questions:

All tutorials shows that MOSI, MISO, SCK needs to be hooked up to digital pin 50, 51, 52. But I don't understand why these matter, because they are not referenced in any code I've found? Are they really necessary? And if so, does it have to be 50,51,52? Can't it be any other digital pin?

I accidentally connected it to 5V at first, for maybe 1 minute. Could it be burnt? The LED still lights RED when connected with power.

If the problem was the (correct) library was not loaded, wouldn't I get a compile error?

I'm running this code:
    #include <MFRC522.h>
    #include <SPI.h>

    #define SAD 9
    #define RST 8

    MFRC522 nfc(SAD, RST);

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

      Serial.println("Looking for MFRC522.");
      nfc.begin();

      uint8_t version = nfc.getFirmwareVersion();
      if (! version) {
        Serial.print("Didn't find MFRC522 board.");
        while(1); //halt
      }

      Serial.print("Found chip MFRC522 ");
      Serial.print("Firmware ver. 0x");
      Serial.print(version, HEX);
      Serial.println(".");

      if (nfc.digitalSelfTestPass()) {
          Serial.print("Digital self test by MFRC522 passed.");
      } else {
          Serial.print("Digital self test by MFRC522 failed.");
      }
    }

    void loop() {

    }

I almost tried to answer to this with one giant answer despite that you're really asking about three thing that you know of and in away more things than that.  But then I saw "I also tested some other library and test code with success" What kind of success are we walking about here and did you have that success before or after hooking 5V to the board?  Because if "success" was that you got it reading you should say whether or not you managed to do that after feeding it 5V.  That said, it would be better to pick one question and go with that.

Welcome, hopefully we can help you. You do not have to connect MOSI, MISO, SCK, CS if you do not want to however without them connected properly it will not work. Note you did not mention the CS pin, that is also needed as that is what tells the MFRC522 it has been selected. Those pins are what is used to communicate with the device. The pins may be different for different boards but you need to check the data sheet for that. The numbers appear correct for the Mega.
The LED tells you that there is power there, it in no way tells you if the board is good. Did you fry it, probably probably as the MFRC522 is a 3V3 device but that is not a given as I do not know what pin you connected the 5V to. More than a few nanoseconds on a voltage higher than rated tends to fry things, but you could be lucky I have no way of knowing. The Mega is 5V so that would probably be OK.
You ask: "If the problem was the (correct) library was not loaded, wouldn't I get a compile error?", again no not necessarily. The compiler does not know your design or what you are connecting to. If the library happens to have functions etc appropriately named it will compile with errors but the odds are very slim your code will work.