body:
You are not doing it correctly. In order to perform WiFi scan:

1) It must be in `WIFI_STA` mode;
2) It has to be disconnect from the AP;
3) After you done with the scanned SSID, BSSID and RSSI, you need to called `WiFi.scanDelete()` if you are going to do a scan again, otherwise you will get the same previous scanned result.

So in summary, here is the code:

```
#include <WiFi.h>

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

void loop() {
  Serial.println("Scanning WiFi Networks...");
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  int n = WiFi.scanNetworks();
  for (int i=0; i<n; i++) {
    Serial.printf("- SSID=%-20s RSSI=%d\n", i+1, WiFi.SSID(i).c_str(), WiFi.RSSI(i));
  }
  WiFi.scanDelete();

  delay(10000);
}
```


sender: user

message:
Why use a module rather than sensor directly?

I'm trying to understand when one would use an Arduino module rather than directly a sensor.

Here's an example to contextualize my question: I need to use a Hall sensor to measure the number of rotations per minute of a magnet mounted on a computer fan. I see that I can either buy the Hall sensor and wire it to the Arduino (*[Hall-Effect Sensor Analog 49E][1]*), or alternatively I could buy a sensor module (e.g., *[Digital Hall Effect Sensor Module][2]* or *[Linear Hall Effect Sensor Module][3]*). What is the advantage of buying modules, rather than the sensors directly?

  [1]: https://protosupplies.com/product/analog-hall-effect-sensor-49e/
  [2]: https://protosupplies.com/product/digital-hall-effect-sensor-module/
  [3]: https://protosupplies.com/product/linear-hall-effect-sensor-module/

sender: assistant

body:
The modules are typically easier to work with, particularly for DIY projects. They have standardized connectors, have their connections labeled and can be mounted into wiring boards. The particular sensor you have there does have quite big legs, so this may work fine without the board, but this is often not true. Consider sensors such as the BME/BMP types ([BME680 data sheet][1]). They're far to small to be used directly without a PCB. And they require some external components to work correctly, which are already included on the module. So for experimental purposes, the module is the way to go.

  [1]: https://cdn-reichelt.de/documents/datenblatt/X200/BME680_DB-EN.pdf


body:
It's a question of convenience and application use-case specific. Sometimes a module will give you additional functionality and/or structural stability, just by providing a mini-PCB (maybe with screw holes) for a low price overhead.

For example, compared to the bare element the module you posted has additional components (LED or `A0`,`D0` on the pricier one) is easily mountable and provides standarized connection pins.

If you already have a PCB (or other circuitry) the module could be superfluous, maybe you just need the sensor itself, but often those modules come as neat packages, sometimes with controller chips speaking [I²C](https://en.wikipedia.org/wiki/I²C) and comparable protocols (like the [DHT11/DHT22](https://lastminuteengineers.com/dht11-dht22-arduino-tutorial/) and [others](https://arduino.stackexchange.com/questions/53882/communicating-with-magnetic-sensor-tlv493d-a1b6-over-i2c)).


body:
In your case it only makes sense if you want to put the module on a breadboard and don't have the other components on the board at hand.

Example: for a DS18B20 one wire temperature sensor you need a pullup resistor. If you have this resistor at hand there is no sense to buy a module. But if you have to buy one resistor it is more easy to buy a module.

For experimental setups, it is often easier to use a module. If you want to build the circuit permanently later, the modules are rather annoying. Because the modules are often very bulky. The direct mounting of the components on a perfboard is then more space-saving.


body:
Since nobody else has addressed your example directly, and to use it as an example, in addition to the other observations about these two items, let's also take note of :

#### Hall-Effect Sensor Analog 49E

>The 49E sensor can detect the magnetic N/S pole and relative strength of a magnetic field and **outputs an analog voltage**

 -  Vcc Range   2.3 – 10V
 -  Output : Analog 1.9mV/GS (± 0.2mV/GS)

#### Digital Hall Effect Sensor Module

>3144 sensor detects presence of magnetic field and **outputs logic level**.

 -  Vcc Range   4.5 – 24V
 -  Output :  Open Collector

#### Linear Hall Effect Sensor Module
>Detects N/S poles and relative strength of a magnetic field.

 -   Vcc Range 3.3 – 5V
 -  Output : Analog 2.5mV / G PLUS digital output
 -  Includes 49E sensor plus everything in the schematic below :
 - [![Linear Hall Sensor Module Schematic][1]][1]

So the sensor you've linked provides an analog signal, allowing you measure the magnetic field strength.  The digital module provides only an open-collector output (ie: ON/OFF) which indicates either the absence or presence of a magnetic field above some threshold of intensity. These are entirely different functions which you would use for entirely different applications.  The digital module also works with VCC up to 24V, which makes it handy to integrate with 24V automation systems.  The linear module provides an analog output as well as some indicators and an additional digital output, but is capped at 5V Vcc (whereas the raw module accepts up to 10V).

Why would you choose either?  What do you need to do?  Do you want to check for the presence of a magnetic field only, or do you also want to measure its intensity?  Or both?  The modules do some of the work for you and, in the case of the linear module, actually give you an additional output that the raw sensor does not.  It's up to you to decide which of these serves your needs.

  [1]: https://i.stack.imgur.com/ZU3Ls.jpg


body: It's a tradeoff between convenience and your time, money and expertise. You could design the module's circuitry and function into your circuit board, or, at slightly more expense, you could solder a module to your circuit board, with the designing and functionality already built-in. It might cost a little bit more and maybe be somewhat larger, than if you did it yourself. Ultimately it's up to you, which way works better for you in your particular circumstance.


message:
stop motor instantaneous with hall sensor problem

I have a problem with stopping motor at same spot when magnet pass.. I tried to add interrupt and to make code as clean as possible but no joy so far. Any suggestions? sw will add later, just ignore..

    byte outPin = 12;        // the number of the output pin
    byte inPin = 2;          // the number of the input pin

    byte hallPin = 3;        // hall sensor

    byte sw;
    byte previous;
    int state = LOW;         // the current state of the output pin
    int reading;             // the current reading from the input pin

    void setup()
    {
      pinMode(inPin, INPUT_PULLUP);
      pinMode(outPin, OUTPUT);

      pinMode(hallPin, INPUT_PULLUP);
      attachInterrupt(digitalPinToInterrupt(hallPin), stop, FALLING);   //hall read low when magnet pass
    }

    void loop()
    {
      sw=0;

      reading = digitalRead(inPin);       //read(LOW when press!)
      if (reading == HIGH) previous=0;

      if (previous == 1 && sw == 0) state=LOW;
      else if (reading == HIGH) state=LOW;
      else state=HIGH;

      digitalWrite(outPin, state);
    }

    void stop() {
      if (sw == 0 && reading == LOW) {
        state=LOW;
        previous=1;
      }
    }

body:
You can stop a BDC faster if you short-circuit it. This is possible with an H-Bridge and the appropriate components.

It would be easier to use a [L293D][1], which already provides this mode.

If you want to try it with this component, of course you can also build the h-bridge yourself, pay attention to the D on the component. With the D-version the protection diodes are already built in. You can power two motors from 4.5V to 36V with a maximum current of 600mA.

For up to 2A you can use a L298N.

  [1]: https://www.ti.com/product/L293D


message:
`ConfigTime` daylight saving update

I'm using an ESP8266 to get clock NTP sync in this manner:

    void myIOT2::_startNTP(const int gmtOffset_sec, const int daylightOffset_sec, const char *ntpServer)
    {
     configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); //configuring time offset and an NTP server
     while (now() < 1627735850)          /* while in 2021 */
     {
      delay(20);
     }
     delay(100);
    }

But now, when daylight saving ended on 31/10/2021, what "flags" code that now daylight saving has ended, and 3600 sec have to reduced (or add) ?

in my case `gmtOffset_sec=2*3600` and `daylightOffset_sec=1*3600` `ntpServer="pool.ntp.org"`

body:
Summing @juraj's comments

1) instead of defining UTC+x and Daylight offset, using NTZ instead.

2) While ESP8266 has `TZ.h as part of its core I used relevant TZ as shown.

3) for ESP32: a) replace to `configTzTime` as shown. b) Copy relevant TZ from `TZ.h` for current lib and use as follows.

for ESP8266:
`configTime(TZ_Asia_Jerusalem, ntpServer); `

for ESP32:
`configTzTime(TZ_Asia_Jerusalem, ntpServer);` // Tz value was copied to code


message:
HW-477 Module having VS1838B IR Sensor: Help with Pins

Ordered **Universal IR Receiver** and I got **HW-477 module** with **VS1838B IR Sensor**.

Good thing is datasheet for **VS1838B** is [available][1] but not for HW-477.

**VS1838B** pins as: [Ref][2]
Signal | GND | VCC

while **HW-477** says:
(\- minus) | R | G

Can't understand which one to follow and **R** is for Receiver? **G** is for GND and what is **-** (minus sign) for?

So can anyone help me with ( \- R G ) of **HW-477** ?

Images:
[![HW-477 module][3]][3]
[![VS1838B IR Sensor.][4]][4]

These may help?!
[this][5] & [this][6] one.

**Updates:**

I looked to trace the Foil *(PCB Board Lines)* but it didn't worked because the circuit as whole is coated.

Using **Connectivity** *(Continuity (diode test))* option of Digital Multimeter, found these to play beep:

| **VS1838B** | **HW-477**                |
|-------------|---------------------------|
| Signal      | G & (minus pin of HW-477) |
| GND         | (\- minus pin of HW-477)     |
| VCC         | R                         |

But a person in [this video][5] saying

> \- is of course GND

There is a huge confusion which can only be cleared if I got a reply from seniors. I have two of this and can try one (even to burn) to better understand what is going on.

(Tried contacting the vendor about datasheet but they are not responding)

  [1]: https://www.makerfabs.com/infrared-receiver-vs1838b.html
  [2]: https://circuits-diy.com/how-to-make-ir-infrared-reciever-module-using-vs1838b/
  [3]: https://i.stack.imgur.com/xWfG4l.jpg
  [4]: https://i.stack.imgur.com/YJZJS.jpg
  [5]: https://youtu.be/zwPBItsFBFk?t=255
  [6]: https://youtu.be/GnvHHZTJmv4?t=5

body:
The problem here is that **HW-477** refers not to the module as a whole but a generic PCB that is re-used (in some starter kits for sure) for many different sensors. I think the idea is that whatever device is attached to the board there's a position where the output is always the same (`- = GND`, `R = VCC`, `G = Signal`).
On some variants of the board you can see them labelled as `- + S`.


message:
Why must I detach the Arduino from the computer when making adjustment to the circuit?

I am new to Arduino and am reading [Learn Electronics with Arduino: An Illustrated Beginner's Guide to Physical Computing][1]. On page 118, it says:

> Remember, whenever you make adjustments to a circuit, your Arduino should not be attached to your computer.

To give more context, it means when you make adjustment to the circuit on the breadboard, you should detach the USB cable from the computer.

I am wondering **why**?

Is it because a short circuit can [crash my computer][2] similar to how the [USBKill][3] works? Are there other reasons?

  [1]: https://www.goodreads.com/book/show/36314656-learn-electronics-with-arduino
  [2]: https://arduino.stackexchange.com/q/16022/81119
  [3]: https://usbkill.com/

body:
"Adjustments to a circuit" can mean removing, adding or repositioning components on the breadboard. One can accidentally position a component lead in an incorrect location on the board, creating a circuit that is undesirable and possibly damaging to the assembled project.

If the misplaced lead or leads are in a particularly unsuited location, the circuit can include the USB portion of the system. The probabilities are low that one would accidentally damage that specific set of traces, or send voltage where it should not be, but they are non-zero. Even if one damages the Arduino, the cost is low compared to a damaged USB port or computer.

If you've been creating simple Arduino circuits and have misplaced or mis-routed a lead or component, you've learned how easily that can happen. Disconnecting the USB is comparably a minor inconvenience.


body:
> Is it because a short circuit can crash my computer ...

It is more that you don't want an inadvertent mis-routing of cables to burn out your chips while they are powered.

I wouldn't personally be making changes to a breadboard circuit while it is powered. It is better to do it un-powered, and then check it over, than wonder why there is smoke coming from it.


body:
> Is it because a short circuit can crash my computer

More than crashing it, there is some risk that a short-circuit on your board could cause damage to the computer's USB port that is powering it. Most computers have overload protection on their USB ports but you don't want to test it unnecessarily, risking permanent damage to the port.


message:
My program is using too much memory

I work in a warehouse and I was tasked to make a device which will show the location of any product when Product ID is given. All of our product has 3 things. Product ID, Rack Number and Gap number.

So the basic program is like that When I enter Product ID: 1640
The program will show in display that it is located in RCK 113 GAP 88

For this I used Arduino Mega, 4x3 Keypad and 16x2 LCD Display with I2C adapter.
I found a Arduino Keypad Calculator code on the Internet and modify my code from there.
So currently my code is working fine and everything

What I noticed is Arduino mega has only 2% memory left with all that string value (For that I couldn't use Arduino Uno at first). Now due to new products are added I need more space or ways to store data elsewhere.

I can not use internet or WIFI as Another team has already made a device using ESP8266 Nodemcu which shows data from a Google sheet but since my device stores data in itself it is very fast (almost instant) to show any result on the other hand the device with NODEMCU ESP8266 can be easily updated and doesn't bother about size yet it is very slow to show result and needs good wifi connection so it is not efficient in warehouse environment. So every staff use my device on the go and other device as a backup

Currently I have around 1000 product address stored in my device but a new shipment of almost 3000 product is coming and my mega has only 2% memory left.

So any genius here can you help me to compress my program more ? or any fault I made during my coding ? Also this is my first post and sorry for my bad English.

My Code is given below. It is huge please take your time to understand it.

Even I can't copy my code here

Body is limited to 30000 characters; you entered 132142.

This is a sample of my code for you to understand

Here is full code uploaded. [Download][1]

**What I want to know is, if it is possible to add a Arduino SD card module and keep portion of my string memory in there.**
```
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>

const byte ROWS = 4;
const byte COLS = 4;
unsigned int integerValue=0;
//define the keymap
char keys [ROWS] [COLS] = {
  {'1', '2', '3', 'X'},
  {'4', '5', '6', '*'},
  {'7', '8', '9', '='},
  {'/', '0', '-', '+'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};

//create the keypad
Keypad myKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
LiquidCrystal_I2C lcd(0x27, 16, 2);

//variables declaration
boolean valOnePresent = false;
boolean result = false;
String num1;
int ans;
boolean getvalue = false;

void setup(){
  Serial.begin(9600);
  lcd.init(); // initialize the lcd
  lcd.backlight();
  frstscreen();
  //lcd.clear();

}

void loop(){
  char key = myKeypad.getKey();

  if (key != NO_KEY && (key=='1'||key=='2'||key=='3'||key=='4'||key=='5'||key=='6'||key=='7'||key=='8'||key=='9'||key=='0')){
      num1 = num1 + key;
      int numLength = num1.length();
      lcd.setCursor(15 - numLength, 1);
      lcd.print(num1);
      valOnePresent = true;
  }

  else if (valOnePresent == true && key != NO_KEY && key == '='){

      ans = num1.toInt();

      lcd.clear();
      lcd.setCursor(15,1);
      lcd.autoscroll();
      lcd.print(ans);
      lcd.noAutoscroll();
      result = true;

  }
  else if (key != NO_KEY && key == 'X'){
    lcd.clear();
    valOnePresent = false;
    num1 = "";
    frstscreen();
    getvalue = false;
}

    integerValue = ans;

if (result == true) {

if (integerValue ==  9   ) { IDScrn(); lcd.print("109");lcd.setCursor(12,1);lcd.print("63 "); delayfunc();}
if (integerValue == 15    ) { IDScrn(); lcd.print("107");lcd.setCursor(12,1);lcd.print("60 "); delayfunc();}
if (integerValue == 15    ) { IDScrn(); lcd.print("109");lcd.setCursor(12,1);lcd.print("63 "); delayfunc();}
if (integerValue == 20    ) { IDScrn(); lcd.print("109");lcd.setCursor(12,1);lcd.print("63 "); delayfunc();}
if (integerValue == 22    ) { IDScrn(); lcd.print("110");lcd.setCursor(12,1);lcd.print("68 "); delayfunc();}
if (integerValue == 23    ) { IDScrn(); lcd.print("109");lcd.setCursor(12,1);lcd.print("63 "); delayfunc();}

//TOP and components

if (integerValue ==  1001   ) { IDScrn(); lcd.print("RCK 115 COL A                  "); delayfunc();}
if (integerValue == 1002   ) { IDScrn(); lcd.print("RCK 115 COL A                  "); delayfunc();}
if (integerValue == 1003   ) { IDScrn(); lcd.print("RCK 115 COL A                  "); delayfunc();}

//Stock and CBOX

if (integerValue ==   376    ) { ComScrn(); lcd.print(" Stock Box 1"); delayfunc();}
if (integerValue ==   15     ) { ComScrn(); lcd.print(" Stock Box 1"); delayfunc();}
if (integerValue ==   919    ) { ComScrn(); lcd.print(" Stock Box 1"); delayfunc();}

//CBOX

if (integerValue ==   245    ) { ComScrn(); lcd.print(" 39K COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 10K COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 47k COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 1k  COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 2k  COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 4.7k  COL I "); delayfunc();}
if (integerValue ==   245    ) { ComScrn(); lcd.print(" 27k COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 0 ohm   COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 220 ohm COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 560 ohm COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 470 ohm COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 330 ohm COL I "); delayfunc();}
if (integerValue ==   766    ) { ComScrn(); lcd.print(" 100 ohm COL I "); delayfunc();}
if (integerValue ==   1291     ) { ComScrn(); lcd.print(" Cbox 1  GAP 101 "); delayfunc();}
if (integerValue ==   1314     ) { ComScrn(); lcd.print(" Cbox 1  GAP 101 "); delayfunc();}

if (getvalue == false) { noproduct(); }

}
 }
void frstscreen()
{
  lcd1stline();
  lcd.print("Warehouse Stock");
  lcd.setCursor(0,1);
  lcd.print("Enter ID: ");
}
void pressA(){

  lcd.clear();
  lcd.setCursor(0,1);
  lcd.print("Press A again");
}
void noproduct(){

  lcd1stline();
  lcd.print("Not Found");
  lcd.setCursor(0,1);
  lcd.print("Press A again");
  result= false;
}
void delayfunc(){
  result = false;
  delay (2000);
  pressA();
  getvalue = true;

}
void lcd1stline(){
lcd.clear();
lcd.setCursor(0,0);
}
void IDScrn(){
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ID: ");
  lcd.setCursor(4,0);
  lcd.print(integerValue);
  lcd.setCursor(0,1);
  lcd.print("RCK     GAP");
  lcd.setCursor(4,1);
}

void ComScrn(){
    lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("ID: ");
  lcd.setCursor(4,0);
  lcd.print(integerValue);
  lcd.setCursor(1,1);
}

```

  [1]: https://drive.google.com/file/d/1pZ2t662D5-AdBu6ysvTbfu63l9xxpOkc/view?usp=sharing

body:
Did you try using the (PROGMEM)  `F` macro. It is described in the official Arduino documentation at the end of https://www.arduino.cc/reference/en/language/variables/utilities/progmem/

This forces all strings to be stored in Flash memory instead of the scarce SRAM memory.

You can try with a few strings to see if the memory lowers and calculate if it would be enough (to fit in Flash). If even Flash is not enough, than SD card would be an alternative.

Also some refactorings that might clean up the code (not necessarily reduce the memory used):

- instead of the many `if (integerValue == xxx)` constructs, use  `switch`/`case` statements.
- A possible bug are the identical values within (like 245 and 766 used many times, but for different products)
- Move the function lcd.print("...") inside function `ComScrn` and pass the string (using `F(..)`)
- Similar as above but for `IDScrn`, using two strings and set the cursor inside `IDScrn` as well.
-  `(key != NO_KEY && key == 'X')` ... if `key` is `'X'` it can never be NO_KEY so the first check can be removed.
- `if (result == true)` can be written as `if (result)`.


body:
There are lots of repetitions in your code. This is something you should
generally avoid, not only because of memory usage, but also, and most
importantly, because of maintainability.

The most common way of getting rid of repetitions is to write a loop
that walks through an array. For the first part of your program (the
rack/gap scheme), that array could look like this:

```c++
// Data structure describing a recorded location.
struct Location {
    uint16_t id;
    uint8_t rack;
    uint8_t gap;
};

// List of recorded product locations.
const Location locations[] = {
    {  9, 109, 63 },
    { 15, 109, 63 },
    { 20, 109, 63 },
    { 22, 110, 68 },
    { 23, 109, 63 },
    // etc...
};

// Number of items in the above list.
const size_t nb_locations = sizeof locations / sizeof locations[0];
```

Note that the structure uses the smallest possible integers for each
field, in order to save memory. The main benefit, however, is that the
data is now in a format that is easier to update: a simple list of
numbers.

Then, all the code that handles this data becomes a loop, instead of a
repetition. For example, the following function can print the location
of any item on the LCD. It returns `true` or `false` to let you know
whether it did find the requested item:

```c++
// If the item is found, print its location and return true.
// Otherwise return false.
bool print_location(uint16_t id) {
    for (size_t i = 0; i < nb_locations; i++) {
        if (locations[i].id == id) {
            IDScrn();
            lcd.print(locations[i].rack);
            lcd.setCursor(12,1);
            lcd.print(locations[i].gap);
            delayfunc();
            return true;  // found
        }
    }
    return false;  // not found
}
```

This scheme still has the problem that all the data is copied to RAM at
initialization. If you have 4,000 items, that would require
16,000 bytes of RAM, or about twice the RAM of your Mega. You can
save RAM by keeping all constant data in flash, using [the `PROGMEM`
qualifier][PROGMEM]. You have 32 times more flash than RAM. You
would then need, however, to bring each item back to RAM in order to use
it, which can be done with [the `memcpy_P()` function][memcpy_P]. Here
is a version of the previous code that stores the array in flash:

```c++
// List of recorded product locations.
PROGMEM const Location locations[] = {
    {  9, 109, 63 },
    { 15, 109, 63 },
    { 20, 109, 63 },
    { 22, 110, 68 },
    { 23, 109, 63 },
    // etc...
};

// Number of items in the above list.
const size_t nb_locations = sizeof locations / sizeof locations[0];

// If the item is found, print its location and return true.
// Otherwise return false.
bool print_location(uint16_t id) {
    for (size_t i = 0; i < nb_locations; i++) {
        Location location;  // RAM copy of locations[i]
        memcpy_P(&location, &locations[i], sizeof location);
        if (location.id == id) {
            IDScrn();
            lcd.print(location.rack);
            lcd.setCursor(12,1);
            lcd.print(location.gap);
            delayfunc();
            return true;  // found
        }
    }
    return false;  // not found
}
```

This approach should enable you to store all the database in the flash
of your Mega, and maybe even on an Uno. That being said, I second the
commenters that say that using an SD card should make upgrading the
database a lot more convenient.

[PROGMEM]: https://www.arduino.cc/reference/en/language/variables/utilities/progmem/
[memcpy_P]: https://www.nongnu.org/avr-libc/user-manual/group__avr__pgmspace.html#gad92fa2ebe26e65fa424051047d21a0eb


body:
***What I want to know is, if it is possible to add a Arduino SD card module and keep portion of my string memory in there***

Well, given that two contributors have already gave a handful of advices to both improving your code and the benefits of using an SD card. I find nothing else to say except answering your very specific question.

The answer is simple, and it is a yes.
There is no problem in dividing your data into two parts, one part on your microcontroller/Arduino and the other part on your SD card, you will have to know which part is where so you can access it without any problems and almost instantly as well.

I hope that answers your question fully.


message:
Rp2040 dual core example sketches

So i have a rp2040 board, and i could not find a dual core example codes. The closest i could find is the scheduler library example given to me by the IDE

    /*
     Multiple Blinks

     Demonstrates the use of the Scheduler library for the boards:

     - Arduino Nano 33 BLE, or
     - Arduino Portenta H7, or
     - Arduino Nano RP2040 Connect

     Hardware required :
     * None (LEDs are already conencted to RGB LED)

     ATTENTION: LEDs polarity is reversed (so loop3 will turn the LED off by writing 1)

     created 8 Oct 2012
     by Cristian Maglie
     Modified by
     Scott Fitzgerald 19 Oct 2012

     This example code is in the public domain

     http://www.arduino.cc/en/Tutorial/MultipleBlinks
    */

    // Include Scheduler since we want to manage multiple tasks.
    #include <Scheduler.h>

    // On Nano RP2040 Connect, RGB leds are connected to the wifi module
    // The user APIs are the same, but we can't convert to int, so use defines
    #if defined(ARDUINO_NANO_RP2040_CONNECT)

    #include "WiFiNINA.h"
    #define led1  LEDR
    #define led2  LEDG
    #define led3  LEDB

    // On Nicla Sense ME, RGB leds are connected via an I2C module
    // The user APIs are the same, but we can't convert to int, so use defines
    #elif defined(ARDUINO_NICLA)

    #include "Nicla_System.h"
    #define led1  LEDR
    #define led2  LEDG
    #define led3  LEDB

    #else

    int led1 = LEDR;
    int led2 = LEDG;
    int led3 = LEDB;

    #endif

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

      // Setup the 3 pins as OUTPUT
      pinMode(led1, OUTPUT);
      pinMode(led2, OUTPUT);
      pinMode(led3, OUTPUT);

      // Add "loop2" and "loop3" to scheduling.
      // "loop" is always started by default.
      Scheduler.startLoop(loop2);
      Scheduler.startLoop(loop3);
    }

    // Task no.1: blink LED with 1 second delay.
    void loop() {
      digitalWrite(led1, HIGH);

      // IMPORTANT:
      // When multiple tasks are running 'delay' passes control to
      // other tasks while waiting and guarantees they get executed.
      delay(1000);

      digitalWrite(led1, LOW);
      delay(1000);
    }

    // Task no.2: blink LED with 0.1 second delay.
    void loop2() {
      digitalWrite(led2, HIGH);
      delay(100);
      digitalWrite(led2, LOW);
      delay(100);
    }

    // Task no.3: accept commands from Serial port
    // '0' turns off LED
    // '1' turns on LED
    void loop3() {
      if (Serial.available()) {
        char c = Serial.read();
        if (c == '0') {
          digitalWrite(led3, LOW);
          Serial.println("Led turned off!");
        }
        if (c == '1') {
          digitalWrite(led3, HIGH);
          Serial.println("Led turned on!");
        }
      }

      // IMPORTANT:
      // We must call 'yield' at a regular basis to pass
      // control to other tasks.
      yield();
    }

but i do not think its using the second core of the rp2040. Does anybody have an example codes? because im really lost how to do it

body:
**Note: This information is about the pure "Arduino" core, not the "MBED" core. The MBED core gets in the way of using the RP2040 SDK, so install the pure bare metal core from [here](https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json).**

By default the second core isn't doing anything.

But you can run anything you want on it directly. No need for any libraries.  You use the function `multicore_launch_core1(func)` to start a function on that core. You could make it Arduino-like by writing a wrapper function, such as this code:

```c++

void setup2() {
    pinMode(1, OUTPUT);
}

void loop2() {
    digitalWrite(1, HIGH);
    delay(750);
    digitalWrite(1, LOW);
    delay(750);
}

void main2() {
    setup2();
    while (1) {
        loop2();
    }
}

void setup() {
    multicore_launch_core1(main2);
    pinMode(0, OUTPUT);
}

void loop() {
    digitalWrite(0, HIGH);
    delay(1000);
    digitalWrite(0, LOW);
    delay(1000);
}
```


message:
Why can't I just plug a stepper or gimbal motor (BLDC) into the ground, 5v, and analog pins of my Arduino?

I plugged a BLDC gimbal motor in to my Arduino today, and it made a very small jitter. I tried to set an analog pin for the signal pin of the motor (motor had three pins, I assumed one was power, one was ground, and one was signal/data/position) but the motor barely moved. I wanted to see my motor spin at some constant rate determined by that signal pin, or maybe move to the position specified in the signal pin.

Upon further research, I find many pages advising me to use "controllers" or other complicated setups to manage a motor. I am confused as to why it is so complicated. Can't it be simple to plug a stepper motor into an Arduino and get some constant revolutions based on Arduino control?

body:
Not only is the available current limited, but a stepper motor in particular is not capable of running just by supplying power.

It's drive coils must be energized in sequence to "pull" the rotor around, and sequenced at a rate that drives the rotor at the desired RMP. The circuitry to do that is external to the stepper, usually a combination of logic signals from a micro-controller (typically) and hardware to translate those signals into drive currents sequenced to the stator-coils. This is what makes steppers so flexible - controllable in direction and speed, down to the single-step level (subject to the rotor's interia) - at the cost of more complex drive circuitry. In short, steppers need to be programmed, continuously, to drive them however the mechanical system requires.


body:
It is a power issue. By that I mean `Power = Votage x Current`.

Put simply, the 5V supply regulator IC on the Arduino is only designed to power the microcontroller(s) and a handful of other electronic components.

The Arduino has a little 5V regulator that is capable of delivering 100mA to 500mA depending on your Arduino. Don't forget that the microcontroller itself uses roughly 20mA. The remaining current is capable of runing very low power items such as sensors, switches, LEDs etc but not parts that require more power. Unfortunately motors require a lot more power than what the regulator on the Arduino can provide.

I suggest that you use a second 5V supply. For example you could use:
- Benchtop power supply
- Plugpack or phone charger type power supply
- An old computer power supply
- A DC/DC converter (like [this one][1])

These are just a few. There are many more options.

  [1]: https://www.pololu.com/product/2851


body:
A brushless DC motor consists of three coils of wire wired in a [Y (wye) or Δ (delta) configuration](https://upload.wikimedia.org/wikipedia/commons/c/cb/Wye-delta-2.svg) and a magnetic rotor. The coils are evenly spaced around the 360 degrees of the motor. There can be multiple poles, or "copies" of each coil, so it's not necessarily 120 degrees from a coil A to a coil B - e.g. it could be ABCABCABC to go around the full circle with 40 degrees between coils. There are no power or ground or data wires, just electromagnets.

Anyway, when current goes through one of the coils it forms an electromagnet and attracts the rotor to that position. We say the coil is energized. By repeatedly energizing and de-energizing different coils you make the rotor spin around in circles. If you energize A, then B, then C, then A, then B, then C it spins one way; energize C, then B, then A, then C, then B, then A and it spins the other way. The current direction also matters because an opposite current produces an opposite magnetic field. Of course you also have to get the timing right - so the magnetic force is always pulling the rotor *ahead* of where it currently is. When the rotor catches up with the magnet coil you switch to the next one. I'm oversimplifying.

To use one you can buy a controller which *does* have power and data and ground wires, as well as the 3 wires for the magnets, and you tell the controller to go, and it handles all the switching and timing for you. You could design your own, but good luck.

---

Steppers are the same basic idea but optimized for low speed and precise movements instead of big movements. Because you don't care about timing so much for a stepper - you're moving it one step at a time and not really trying to use its inertia - you *can* write your own control algorithm if you want. Note the Arduino's digital pins still can't output enough current so you still need some circuitry. Or you can buy a stepper motor controller.


message:
Rp2040 How to signal the second core from first core as an indicator to do something

Im new to dual core programming and i do not know the best practices yet. In my current project, i would like the second core to only do something after it is being told by the first core.

The approach i am using somewhat of a brute force is something like this:

    bool indicator = false;
    int a,b;

    void loop () { // core1
      if(indicator == false){  //check if core2 is still processing
         a=random(100);
         b=random(100);
         indicator = true;
      }
    }

    void loop1(){ //core2
      if(indicator == true){
         int sum = a+b;
         Serial.println(sum);
         indicator == false;
      }
    }

this is just a simplified idea of how my code is going to be. Are there better ways of going about this? In general i want to tell core2 from core1 that it needs to start/stop doing something.

body:
What you have created there is called a *semaphore*.

In multi-threaded (or multi-core) programming there are two important signalling concepts:

* **Mutex** - This is an object of some form that is used to allow access to a shared resource by only one core or thread at a time.  A thread tries to "lock" a mutex before using a resource.  A mutex can only be "locked" by one thread at a time, and if the mutex is already locked by another thread it can either block (aka a "spinlock") waiting for the mutex to be unlocked, or it can fail gracefully and try again later.
* **Semaphore** - This is a simple flag that is used for one thread to tell another thread that something has happened or that it should do something. It is typically set by one thread then read and cleared by the other thread.

As I mentioned before, a *semaphore* is what you have created, and a simple boolean value is the most basic semaphore there is. Note, though, that you should really have the variable as `volatile` to prevent the compiler optimizing it away.

The RP2040 SDK has some functions built in for allowing the cores to communicate, including a "[lockout](https://raspberrypi.github.io/pico-sdk-doxygen/group__multicore__lockout.html)" facility allowing one core to tell the other to stall until such time as it should start processing again, and a [FIFO](https://raspberrypi.github.io/pico-sdk-doxygen/group__multicore__fifo.html) to allow the asynchronous passing of data from one core to the other.


message:
Plug in analog sensor into digital pin

If I take an Arduino (samd21, if it matters) and plug in an analog sensor/pot into a digital pin and then set that pin to be an input, would digitalRead(#) trigger HIGH and LOW at some threshold point?  Or does it not work at all?

body:
According to SAMD21 the digital input pin detects **HIGH** if the voltage on pin is higher than 0.55 of supply voltage. So at 3.3 V it is **1.8 V**.

The input pin detects **LOW** if the voltage is lower than 0.3 of supply voltage. It is **0.99 V** at 3.3 V.

For voltages between these values (1 V to 1.8 V) the result can be HIGH or LOW.


body:
Yes. If you read the datasheet you will find a set of voltage specifications. The ones you are interested in are VIH and VIL.

Most MCUs use a "Schmitt Trigger" for the inputs. This means that when the voltage rises above the HIGH threshold (VIH) the input switches to HIGH. When the voltage drops below the LOW threshold (VIL) the input switches to LOW.  This "hysteresis" provides a certain amount of noise rejection to give a clean digital input signal.


message:
What does a delay(0) actually do?

I've seen some code where the developers add `delay(0)`, it doesnt make sense, what does it do? Delay with zero milliseconds, why?

    bool DFRobotDFPlayerMini::waitAvailable(unsigned long duration){
      unsigned long timer = millis();
      if (!duration) {
        duration = _timeOutDuration;
      }
      while (!available()){
        if (millis() - timer > duration) {
          return false;
        }
        delay(0);
      }
      return true;
    }

body:
Delay (traditionally) has two functions that it performs:

1. Wait for a period
2. Yield processing to other threads through the `yield()` weak symbol.

By using a `delay(0)` the author thinks they are saying "I don't want to delay here, but if anything is using the `yield()` function it can run now."

However, that is *not* correct.

The code for `delay()` in the AVR core looks like this:

```c++
void delay(unsigned long ms)
{
    uint32_t start = micros();

    while (ms > 0) {
        yield();
        while ( ms > 0 && (micros() - start) >= 1000) {
            ms--;
            start += 1000;
        }
    }
}
```

You can see that, as well as delaying for a period, `yield()` is regularly called. However that only ever happens if `ms` is greater than 0. If you pass `0` as the delay length then the `delay()` function essentially does nothing at all.

Now it *could* be that an earlier version of the core had `yield()` always being called even with `ms==0`, but the current version doesn't. Maybe this is a hangup from an old coding style.  But for the current core if you want to yield you must explicitly call `yield()` or delay for *at least one millisecond*.


message:
Arduino LiquidCrystal library code prevents ESP32 from running. For 16x2 character display

See bottom for solution.

I am trying to run the Arduino LiquidCrystal library example HelloWorld.ino on an ESP32. It seems like it never even executes the Setup() loop. The ESP resets after eight seconds and then repeats the cycle.

I have used character LCD many times before (with Arduino) but always using I2C. For the current design I am eliminating the I2C to parallel chip and I am instead driving the LCD directly from the ESP32. I am using 4 bit mode to reduce the number of pins required. I have connected Register select, Enable, and D4-D7. These details are not relevant since the ESP32 does not even run with the LiquidCrystal library.

I have looked at the library code and I didn't see anything that I thought would be a problem. But I am a hardware designer (for 36 years) and not a programmer. I use the Arduino IDE because it is quick and easy to test hardware.

The library code can be found here. [https://github.com/arduino-libraries/LiquidCrystal/tree/master/src][1]

This is what I get from the serial monitor.

```
rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1240
load:0x40078000,len:13012
load:0x40080400,len:3648
entry 0x400805f8
ets Jun  8 2016 00:22:57
```

I tried the example code, and when that didn't work so I added a couple of serial print lines to the code. I am listing that below.

```
#include <LiquidCrystal.h>

const int rs = 26, en = 25, d4 = 16, d5 = 17, d6 = 18, d7 = 19;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

void setup() {
  Serial.begin(115200);
  Serial.println("Start");

  lcd.begin(16, 2);
  lcd.print("hello, world!");
}

void loop() {
  delay(1000);

  lcd.setCursor(0, 1);
  lcd.print(millis() / 1000);

  Serial.println(millis() / 1000);
}
```

Details that I didn't list above. I am powering the LCD from 5 volts. The LCD data/control lines are specified as VinLo = 0.55v and VinHi = 2.4 volts. Not that this matters since the code above never executes. I have used a Arduino Nano powered with 3.3 volts, running the above code, to confirm that the display actually works under these conditions. I really want this to work with an ESP32-C3. I tried that originally but switched to the ESP32 because it wasn't working with the code.

I hope someone can provide some guidance here. My other option is not using the library and writing my own code, which ends up being brute force and simplistic.

**EDIT:**

A **big thanks** to **Majenko** who was spot on. After removal of the call the code executed properly.

  [1]: https://github.com/arduino-libraries/LiquidCrystal/tree/master/src

body:
My guess:

* the constructor calls `LiquidCrystal::init()`.
* `LiquidCrystal::init()` calls `LiquidCrystal::begin()`.
* `LiquidCrystal::begin()` uses delays.

Those delays may depend on things that aren't configured yet when the constructors are running, and lock up causing a WDT.

Remove the call to `begin()` in the `LiquidCrystal::init()` function and it should at least get past running the constructor so it gets to run the rest of your code.

Quite why they have that call in there is beyond me.  Rule number one of writing an Arduino library: *never perform any operations more strenuous than assigning variables in the constructor as resources you may rely on may not have been initialized yet.*


message:
ESP32 not detecting PN532 module running in SPI mode

I am trying to get the Pn532 module working on the esp32, first I tried to get it working with i2c and had some "success"(it worked, but as soon as I had another i2c device, in my case a display, 90% of the time it refused to work) and after some research, it's mentioned in the github repo the module doesnt work with multiple devices attached on the i2c bus. Now I am trying to get it working trough spi, but it doesn't get detected.
Code: **readMirafe example from the Adafruit Pn532 Library, but I modified the pins from line 42-45**
```lang-c++
/**************************************************************************/
/*!
    @file     readMifare.pde
    @author   Adafruit Industries
 @license  BSD (see license.txt)
    This example will wait for any ISO14443A card or tag, and
    depending on the size of the UID will attempt to read from it.

    If the card has a 4-byte UID it is probably a Mifare
    Classic card, and the following steps are taken:

    - Authenticate block 4 (the first block of Sector 1) using
      the default KEYA of 0XFF 0XFF 0XFF 0XFF 0XFF 0XFF
    - If authentication succeeds, we can then read any of the
      4 blocks in that sector (though only block 4 is read here)

    If the card has a 7-byte UID it is probably a Mifare
    Ultralight card, and the 4 byte pages can be read directly.
    Page 4 is read by default since this is the first 'general-
    purpose' page on the tags.
This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
This library works with the Adafruit NFC breakout
  ----> https://www.adafruit.com/products/364

Check out the links above for our tutorials and wiring diagrams
These chips use SPI or I2C to communicate.
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
*/
/**************************************************************************/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>

// If using the breakout with SPI, define the pins for SPI communication.
#define PN532_SCK  (18)
#define PN532_MISO (19)
#define PN532_MOSI (23)
#define PN532_SS   (27)

// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines.  Use the values below (2, 3) for the shield!
#define PN532_IRQ   (2)
#define PN532_RESET (3)  // Not connected by default on the NFC Shield

// Uncomment just _one_ line below depending on how your breakout or shield
// is connected to the Arduino:

// Use this line for a breakout with a software SPI connection (recommended):
Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);

// Use this line for a breakout with a hardware SPI connection.  Note that
// the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
// hardware SPI SCK, MOSI, and MISO pins.  On an Arduino Uno these are
// SCK = 13, MOSI = 11, MISO = 12.  The SS line can be any digital IO pin.
//Adafruit_PN532 nfc(PN532_SS);

// Or use this line for a breakout or shield with an I2C connection:
//Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);

void setup(void) {
  Serial.begin(115200);
  while (!Serial) delay(10); // for Leonardo/Micro/Zero

  Serial.println("Hello!");

  nfc.begin();

  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("Didn't find PN53x board");
    while (1); // halt
  }
  // Got ok data, print it out!
  Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
  Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);

  // configure board to read RFID tags
  nfc.SAMConfig();

  Serial.println("Waiting for an ISO14443A Card ...");
}

void loop(void) {
  uint8_t success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer to store the returned UID
  uint8_t uidLength;                        // Length of the UID (4 or 7 bytes depending on ISO14443A card type)

  // Wait for an ISO14443A type cards (Mifare, etc.).  When one is found
  // 'uid' will be populated with the UID, and uidLength will indicate
  // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);

  if (success) {
    // Display some basic information about the card
    Serial.println("Found an ISO14443A card");
    Serial.print("  UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
    Serial.print("  UID Value: ");
    nfc.PrintHex(uid, uidLength);
    Serial.println("");

    if (uidLength == 4)
    {
      // We probably have a Mifare Classic card ...
      Serial.println("Seems to be a Mifare Classic card (4 byte UID)");

      // Now we need to try to authenticate it for read/write access
      // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
      Serial.println("Trying to authenticate block 4 with default KEYA value");
      uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

   // Start with block 4 (the first block of sector 1) since sector 0
   // contains the manufacturer data and it's probably better just
   // to leave it alone unless you know what you're doing
      success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya);

      if (success)
      {
        Serial.println("Sector 1 (Blocks 4..7) has been authenticated");
        uint8_t data[16];

        // If you want to write something to block 4 to test with, uncomment
  // the following line and this text should be read back in a minute
        //memcpy(data, (const uint8_t[]){ 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0 }, sizeof data);
        // success = nfc.mifareclassic_WriteDataBlock (4, data);

        // Try to read the contents of block 4
        success = nfc.mifareclassic_ReadDataBlock(4, data);

        if (success)
        {
          // Data seems to have been read ... spit it out
          Serial.println("Reading Block 4:");
          nfc.PrintHexChar(data, 16);
          Serial.println("");

          // Wait a bit before reading the card again
          delay(1000);
        }
        else
        {
          Serial.println("Ooops ... unable to read the requested block.  Try another key?");
        }
      }
      else
      {
        Serial.println("Ooops ... authentication failed: Try another key?");
      }
    }

    if (uidLength == 7)
    {
      // We probably have a Mifare Ultralight card ...
      Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)");

      // Try to read the first general-purpose user page (#4)
      Serial.println("Reading page 4");
      uint8_t data[32];
      success = nfc.mifareultralight_ReadPage (4, data);
      if (success)
      {
        // Data seems to have been read ... spit it out
        nfc.PrintHexChar(data, 4);
        Serial.println("");

        // Wait a bit before reading the card again
        delay(1000);
      }
      else
      {
        Serial.println("Ooops ... unable to read the requested page!?");
      }
    }
  }
}
```

My wiring is the following
```
(PN523 Module->esp32):
SCK  -> D18;
MSO  -> D19;
MOSI -> D23;
SS   -> D27
```
And yes, the board is in SPI mode(the dip switch). Thank you!

body: Got it working by running the module in VSPI and modifying the library a bit: https://github.com/adafruit/Adafruit-PN532/issues/80#issuecomment-649915457


body: There is a switch on your PN5322 by default it is set to 0, 0. Switch to the mode of communication you are using.


message:
Is there a need to put a delay in the main loop

Im a complete beginner. Generally speaking, is there any need at all to have a delay in the main loop()? Im not used to writing infinite loops

Is it correct to say that the delay() command is simply helpful for tutorials (i.e turn light on, wait, turn light off. wow!) but normally speaking a delay would not be helpful, and instead we are just rapidly infinitely polling our connected devices. Is that correct?

(I get that in some specialized cases it might be helpful to put a delay in the loop. Im not asking about the specialized cases.)

body:
There is no absolute need for any Arduino program to use `delay()`

The *blink without delay* sketch that is included in the standard sketch examples is the canonical illustration of this.

In most cases you don't need to poll your sensors thousands of times a second. It is good discipline to only poll sensors as often as makes sense for the specific application. Sometimes this might be once every five minutes. For example an ambient temperature sensor. In those cases there is nothing to be gained be polling a thousand times a second. To do so wastes resources and is a poor habit that could be troublesome for battery powered applications.

For example, the use of `millis()` for timing allows you to effectively poll several peripherals each at different intervals, perhaps averaging some readings to reduce noise, perhaps also updating a display at other intervals that suit human perception.

For long running battery powered applications it is likely that you will benefit from finding out about putting the microcontroller to sleep using `sleep()` or `deepSleep()` and using interrupts to wake it. A real time clock (RTC) or the watchdog timer interrupt can perhaps be used to schedule your sensor readings and other actions, perhaps in conjunction with `millis()`.

For very simple programs that don't need precise timings. `delay()` can be the simplest and clearest way to manage timings.


body:
No, there is no need to use `delay()` at all. Unlike the `sleep()` or `deepSleep()` commands, delay does not save power or do anything else that's special.

The standard implementation of `delay` is just doing a busy-wait until the time has elapsed, something like:

```cpp
void delay(int ms)
{
    int end = millis() + ms;
    while (millis() < end) {}; // do nothing
}
```
So for the CPU itself, this just wastes CPU cycles, it doesn't save any power.


message:
ATtiny85 giving multiple wake from IDLE if INT0 held low

Desired behaviour:
1. Go to IDLE sleep mode.
2. When PB2 (blue trace) goes low wake up and give a 10 ms HIGH on PB1 pulling a pull-up low (yellow trace on Figure 1).
3. Go to 1.

What I get:

[![Oscilloscope view.][1]][1]

*Figure 1. (1) The input triggers, (2) the CPU wakes from sleep, (3) the CPU goes back to sleep and wakes up repeatedly until (9) the input goes high again.*

I want one 10 ms low pulse and then go back to sleep until the next negative going edge on PB2 regardless of how long PB2 is held low.

Even though I set MCUCR to falling edge of INT0 the device seems to wake repeatedly when PB2 is held low. My code below attempts to solve this by switching to rising edge interrupt if the input is low and falling edge interrupt if the input is high. The result is shown in Figure 1.

``` lang-cpp
void setup(){
  ADCSRA &= ~_BV(ADEN);               // ADC off. ADC not used.
  pinMode(reedPin, INPUT);
}

void loop(){
  system_sleep();                     // Go straigth to sleep.
  // ---- System woken up by interrupt. ---------
  if (!digitalRead(reedPin)) {        // Check that input is low.
    pinMode(outPin, OUTPUT);          // Enable output.
    digitalWrite(outPin, HIGH);       // Pull motor sensor input low by MOSFET.
    delay(pulseTime);                 // Pulse time.
    digitalWrite(outPin, LOW);        // Pulse off.
  }
}

// From http://interface.khm.de/index.php/lab/experiments/sleep_watchdog_battery/
void system_sleep() {
  MCUCR |= _BV(ISC01);                    // Required for both rising and falling edge interrupt.
  if(digitalRead(reedPin)) {              // Input is high so set interrupt for detecting low.
    MCUCR &= ~_BV(ISC00);                 // Clear MCUCR bit 0 for falling edge interrupt.
  } else {                                // Input is low so set interrupt for detecting high.
    MCUCR |= _BV(ISC00);                  // Set MCUCR bit 0 for rising edge interrupt.
  }
  GIMSK |= _BV(INT0);                     // Enable Pin Change Interrupts
  set_sleep_mode(SLEEP_MODE_IDLE);        // Leaves the clock running for elapsedMillis.
  sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
  sei();                                  // Enable interrupts
  sleep_cpu();                            // sleep
  // ZZZZZZZZZZZzzzzzzzzzzz .......
  // ------- CPU is now asleep and awaiting interrupt. ----------------------
  cli();                                  // Disable interrupts on wake up.
  sleep_disable();                        // Clear SE bit.
}

ISR(INT0_vect){                           // Wake up.
  GIMSK = 0;                              // Disable external interrupts. (Only need one to wake up.)
}
```

Can anyone guide me through this?

Many thanks.

  [1]: https://i.stack.imgur.com/uQSsr.png

body:
The Arduino core configures a timer to deliver a periodic interrupt.
This interrupt is used to implement `millis()`, `delay()`, etc. Your
code assumes the external interrupt is the only one the microcontroller
can receive. I guess the timer interrupts may be the cause of the
observed behavior.

I suggest configuring the interrupt for falling edges and leaving it
always on. The ISR can take care of starting the pulse, and setting a
flag to let the main loop know the pulse is active. The main loop can
then stop the pulse when it has been on for long enough:

```c++
volatile bool pulse_active;     // whether the pulse is on
volatile uint32_t pulse_start;  // time when it started

ISR(INT0_vect) {
    // Start the pulse.
    digitalWrite(outPin, HIGH);
    pulse_active = true;
    pulse_start = millis();
}

void loop() {
    // End the pulse if it's time to do so.
    if (pulse_active && millis() - pulse_start >= pulseTime) {
        digitalWrite(outPin, LOW);
        pulse_active = false;
    }

    // Take a little nap.
    sleep_mode();
}
```

Note that the little nap in the code above can be interrupted by either
the external interrupt or the timer interrupt.


message:
Keyboard.h not found on Arduino nano

I am trying to use keyboard on my Arduino nano, but i get this error:
```
'Keyboard' not found. Does your sketch include the line '#include <Keyboard.h>'?
```

As per the answer in https://arduino.stackexchange.com/questions/57581/keyboard-h-not-found, I tried change the board to **Arduino Leonardo**, even though the script gets compiled it doesn't get uploaded (keeps on saying uploading for a long time).

This is the code I use:
```
#include <Keyboard.h>
void setup() {
  Keyboard.begin();
}
void loop() {
}
```

body:
To convert the comments into an answer:

You cannot (!) use the `Keyboard` library on the Arduino Uno/Nano/Mini. It needs a native USB interface to configure it as a HID device, but the Uno/Nano/Mini all use the Atmega328p, which doesn't have a native USB interface. These Arduinos use an additional chip on the board which acts as USB-UART-bridge.

You can compile the code for the Leonardo, because it has a native USB interface. But you cannot (!) upload code, which is compiled for the Leonardo, to an Uno/Nano/Mini. Its a completely different chip.

**What to do now:** Get an Arduino board which has a native USB interface, for example the Leonardo or the Micro.


message:
LCD displays more digits than serial monitor

I am doing a BPM monitoring system. The serial monitor displays accurate BPM values ranging from 60 to 100+. But my LCD display is not accurate. Example, on the serial monitor, my bpm is about 67, but on the LCD it displays 676. What do I need to do to fix it?

    PulseSensorPlayground pulseSensor; // Creates an instance of the PulseSensorPlayground object called "pulseSensor"

    void setup() {
        Serial.begin(9600); // For Serial Monitor
        lcd.begin();
        lcd.backlight();

        // Configure the PulseSensor object, by assigning our variables to it.
        pulseSensor.analogInput(PulseWire);
        pulseSensor.blinkOnPulse(LED13); //auto-magically blink Arduino's LED with heartbeat.
        pulseSensor.setThreshold(Threshold);

        // Double-check the "pulseSensor" object was created and "began" seeing a signal.
        if (pulseSensor.begin()) {
            Serial.println("We created a pulseSensor Object !"); //This prints one time at Arduino power-up, or on Arduino reset.
        }
    }

    void loop() {
        int myBPM = pulseSensor.getBeatsPerMinute(); // Calls function on our pulseSensor object that returns BPM as an "int".
        // "myBPM" hold this BPM value now.
        if (pulseSensor.sawStartOfBeat()) { // Constantly test to see if "a beat happened".
            Serial.println("♥ A HeartBeat Happened ! "); // If test is "true", print a message "a heartbeat happened".
            Serial.print("BPM: "); // Print phrase "BPM: "
            Serial.println(myBPM); // Print the value inside of myBPM.

            lcd.setCursor(0,0);
            lcd.print("BPM: "); // Print phrase "BPM: "
            lcd.print(myBPM);
        }
        delay(50); // considered best practice in a simple sketch.
    }

body:
The additional "6" seems to come from one of the first values. Maybe the first value printed is just a rogue value and all the following values are correct.

The point is that this rogue value may take one more character on the display than the other (correct) values. And when you just move the cursor and print again the previously displayed text is only changed if it is overwritten by the new text. The correct values are shorter, so the last digit of the rogue value is not overwritten. This of course doesn't happen with Serial, since Serial doesn't print to the same space again and again (like a LCD does with its limited space).

**What to do now:** You can use `lcd.clear()` to remove all text from the display before printing new values. Though this can lead to a noticeable flicker on the display. Often it is better to just make sure to overwrite all possible leftover text with spaces via `lcd.print(" ");`. Insert this after the `lcd.print(myBPM)` (since you want to remove all leftover digits after that). In this case you only have 1 leftover digit, so one space is enough. To be sure that this won't happen again when for whatever reason you get more than one leftover digit you can use multiple spaces (`lcd.print("    ");`).


message:
need help for exam please (deadline tomorrow)

what we're required to do on exam [![enter image description here][1]][1]

You don't have to completely give me the answers, I just started learning this yesterday so I'm pressured on learning it properly + the exam, thx

  [1]: https://i.stack.imgur.com/ADTxB.jpg

body:
As written, the exam does not look like you are expected to build
something functional. Rather, that you must show that you understand how
to drive LEDs and a buzzer, how to write conditional code, etc. I would
suggest using a pot to simulate a distance reading, and writing
something along these lines:

```c++
void loop() {
    // Simulate a distance reading between 0 and 4 meters.
    float distance = analogRead(A0) * (4.0/1023);

    // React to the sensor reading.
    if (distance < 3) {
        // ...
    }
    // etc.
}
```


message:
LoRa recieves only 2-4 packets, then stops working

I'm working on LoRa project using [Ai-Thinker RA-01 SX1278 433MHz LoRa][1] with [sandeepmistry/arduino-LoRa][2] library. I modified LoRaReciever example so it looks like this

```
#include <SPI.h>
#include <LoRa.h>

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

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  LoRa.onReceive(onReceive);
}
void onReceive(int packetSize) {

  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");

    // read packet
    while (LoRa.available()) {
      Serial.print((char)LoRa.read());
    }

    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
  }
}
```
I receive 2-4 packets successfully, but then I don't receive any, even though the transmitter is still transmitting. (If I restart my Arduino it receives 2-4 packets again).

I have both LoRa modules really close to each other (about 10 cm) could it cause the problem? - Even when I tried like 15m with walls, problem stayed.

Sometimes, the receiver gets bugged and starts receiving packets all the time (one packet like 50 times), when it's bugged like this, it doesn't stop receiving (unique) packets after any number.

Do you know where the problem could be? Thanks.

I use Arduino Mega

```
#include <SPI.h>
#include <LoRa.h>

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

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(915E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
}

void loop() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();
  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");

    // read packet
    while (LoRa.available()) {
      Serial.print((char)LoRa.read());
    }

    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
  }
}

```
This is original LoRaReciever example, but I don't receive anything using it.
  [1]: https://www.laskarduino.cz/ai-thinker-ra-01-sx1278-433mhz-lora-modul/
  [2]: https://github.com/sandeepmistry/arduino-LoRa

body:
I found the solution.
The problem was with calling `onRecieve` in `loop` not in `setup`
It should have looked like this...
```
#include <SPI.h>
#include <LoRa.h>

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

  Serial.println("LoRa Receiver");

  if (!LoRa.begin(433E6)) {
    Serial.println("Starting LoRa failed!");
    while (1);
  }
  LoRa.onReceive(onReceive);
  LoRa.receive();
}

void loop() {
  //do nothing
}
void onReceive(int packetSize) {

  if (packetSize) {
    // received a packet
    Serial.print("Received packet '");

    // read packet
    while (LoRa.available()) {
      Serial.print((char)LoRa.read());
    }

    // print RSSI of packet
    Serial.print("' with RSSI ");
    Serial.println(LoRa.packetRssi());
  }
}
```


message:
How to Independently run positional and continuous servos using millis()?

I am setting up 3 servos (**2 position servos and 1 '360' continuous rotational servo**) with Arduino. but I failed to run these independently. It runs one after another. I wish to run it in loop independent to each other. Here is the code which I use to run positional servo and CR (360) servo. default servo positions are 90.
*CR 360 servo should be running independently 90-60-120-90 (in loop)
*Pos servo should be running one after another (in loop)

**To run positional servos (tilt/pan):**

    //tilt servo
        for (pos = 90; pos >= 60; pos -= 1)     //90 ~ 60
      {
        tiltservo.write(pos);
        delay(30);
      }

      for (pos = 60; pos <= 120; pos += 1)      //60 ~ 120
      {
        tiltservo.write(pos);
        delay(30);
      }

      for (pos = 120; pos >= 90; pos -= 1)       //120 ~ 90
      {
        tiltservo.write(pos);
        delay(30);
      }

    //pan servo
    for (pos = 90; pos >= 60; pos -= 1)          //90 ~ 60
      {
        panservo.write(pos);
        delay(30);
      }

      for (pos = 60; pos <= 120; pos += 1)       //60 ~ 120
      {
        panservo.write(pos);
        delay(30);
      }

      for (pos = 120; pos >= 90; pos -= 1)       //120 ~ 90
      {
        panservo.write(pos);
        delay(30);
      }

**To run CR 360 servo:**

     legservo.writeMicroseconds(1600);      //CW
     delay(5000);                           //run for 5s
     legservo.writeMicroseconds(1300);      //CCW
     delay(5000);                           //run for 5s

Tried this to independently run CR servos, but how to put some wait (3s-4s) in between FW and RW.

    if (millisNow - lastMillis >= 10000)
    {
    lastMillis = millisNow;
    if (crservoState == 0)
     {
       legservo1.writeMicroseconds(2150); //FW
       crservoState = 1;
     }
      else
     {
       legservo1.writeMicroseconds(850);  //RW
       crservoState = 0;
     }
    }

**Trial code after suggestions:**

    uint32_t milliSNow = millis();

      if (milliSNow - lastTimeServoRotate >= 1000)
      {
        if (crservoState == 0)
        {
          if (milliSNow - lastTimeServoRotate >= 10000)
          {
            legservo1.writeMicroseconds(2150);    //FW run
            crservoState = 2;
            lastTimeServoRotate = milliSNow;
          }
        }

        if (crservoState == 1)
        {
          if (milliSNow - lastTimeServoRotate >= 10000)
          {
            legservo1.writeMicroseconds(850);     //RW run
            crservoState = 3;
            lastTimeServoRotate = milliSNow;
          }
        }

        if (crservoState == 2)
        {
          if (milliSNow - lastTimeServoRotate >= 3000)
          {
            legservo1.writeMicroseconds(1500);    //FW STOP
            crservoState = 1;
            lastTimeServoRotate = milliSNow;
          }
        }

        if (crservoState == 3)
        {
          if (milliSNow - lastTimeServoRotate >= 3000)
          {
            legservo1.writeMicroseconds(1500);     //RW STOP
            crservoState = 0;
            lastTimeServoRotate = milliSNow;
          }
        }
      }

body:
This is covered in the [Blink Without Delay][blink] Arduino tutorial.
Let me paraphrase the main part of the example code here:

```c++
uint8_t ledState = LOW;
uint32_t lastTimeLedChanged = 0;

void loop() {
    uint32_t now = millis();
    if (now - lastTimeLedChanged >= 1000) {

        // Save the last time we updated the LED.
        lastTimeLedChanged = now;

        // Compute the new state of the LED.
        if (ledState == LOW) {
            ledState = HIGH;
        } else {  // ledState is HIGH
            ledState = LOW;
        }

        // Set the LED to the computed state.
        digitalWrite(LED_BUILTIN, ledState);
    }
}
```

This will make the LED cycle between its two possible states at the
desired rate. You can apply this principle as-is to your continuous
rotation servo.

For the positional servos, the same principle can still be applied, but
there is a catch. Whereas both the LED and the CR servo cycle between
two states, the pair of positional servos goes through many states
(<s>92</s> 240 if I counted correctly). You will thus need:

- more variables to store the current state of the servo pair
- more code to compute the new desired state
- more code to update the state

In order to figure out how to represent the state, you have to look at
your current `delay()`-based code, see how many calls to `delay()` are
performed on each full cycle, and figure out how to identify each of
these calls. Each of these delays corresponds to one state of your
system. I would say that you need one variable to know in which of the
`for` loops you are, and another variable to know the last position you
wrote to the servo in that loop. I will call each of the original `for`
loops a “phase”. There are <s>two</s> six such phases:

* phase 0: tilt: 90° → 60°
* phase 1: tilt: 60° → 120°
* phase 2: tilt: 120° → 90°
* phase 3: pan: 90° → 60°
* phase 4: pan: 60° → 120°
* phase 5: pan: 120° → 90°

**Note** there were only two `for` loops in the original question, but
it was then edited to include six loops, thus I edited my answer.

An then you will need to store the time of the last update, thus:

```c++
int phase = 0;  // which of the six phases we are in
int pos = 90;   // last position written to a servo
uint32_t lastTimeServoMoved = 0;
```

Once you have the proper variables to describe the state, updating it is
not hard. If you have reached the end of a phase, move to the next one.
Then update the position by one step. Thus:

```c++
void loop() {
    uint32_t now = millis();
    if (now - lastTimeServoMoved >= 30) {

        // Save the last time we updated a positional servo.
        lastTimeServoMoved = now;

        // Compute the new state.
        if (phase == 0 && pos == 60)
            phase = 1;
        else if (phase == 1 && pos == 120)
            phase = 2;
        else if (phase == 2 && pos == 90)
            phase = 3;
        else if (phase == 3 && pos == 60)
            phase = 4;
        else if (phase == 4 && pos == 120)
            phase = 5;
        else if (phase == 5 && pos == 90)
            phase = 0;
        if (phase == 1 || phase == 4)
            pos += 1;
        else
            pos -= 1;

        // Set the servo to the computed state.
        if (phase < 3)
            tiltservo.write(pos);
        else
            panservo.write(pos);
    }
}
```

I personally do not like this kind of repetitive code. If you are
comfortable with data structures, I would recommend using an array of
structs to store all the information describing the moves that are done
in each phase:

```c++
struct {
    Servo *servo;   // which servo to move
    int step;       // steps by which it moves
    int final_pos;  // final angular position
} moves[] = {
    { &tiltservo, -1, 60 },   // tilt:  90 ->  60
    { &tiltservo, +1, 120 },  // tilt:  60 -> 120
    { &tiltservo, -1, 90 },   // tilt: 120 ->  90
    { &panservo,  -1, 60 },   // pan:   90 ->  60
    { &panservo,  +1, 120 },  // pan:   60 -> 120
    { &panservo,  -1, 90 }    // pan:  120 ->  90
};
```

Then the actual code becomes simpler:

```c++
void loop() {
    uint32_t now = millis();
    if (now - lastTimeServoMoved >= 30) {

        // Save the last time we updated a positional servo.
        lastTimeServoMoved = now;

        // Compute the new state.
        if (pos == moves[phase].final_pos) {
            phase +=1;
            if (phase == 6)
                phase = 0;
        }
        pos += moves[phase].step;

        // Set the servo to the computed state.
        moves[phase].servo->write(pos);
    }
}
```

[blink]: https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay


message:
Procedure for changing frequency of Nano or similar

I need to get interrupts at one of three specific rates: 1920, 2000, and 2400 per sec, at a fairly high precision (~10 ppm). I've asked about this on Electronics but I think here might be more appropriate.

I can't use the standard 16MHz with internal timers, since 16MHz / 2400 (for example) gives 66666.666... counts.

I would use an external standard, but I don't seem to be able to find one that fits the need. Something small and precise at 48KHz / 96KHz etc would be fine.

Alternatively, I could swap the crystal / resonator for one running at 18.432MHz, which divides evenly by those freqs and shouldn't tax a 328p. Can I even do that on a Nano, or some clone / comparable, with the required 10ppm?

-- extra removed --

body:
You could use an internal timer.

You are using interrupts, and you are probably aware that interrupt
handling inevitably incurs some jitter. Thus, if you do not mind an
extra single CPU cycle of jitter, you could reconfigure the timer on
each interrupt in order to control the _average_ interrupt period.

Here is how I would do it, with Timer 1 running in normal mode (CTC mode
would require an extra operation):

```c++
// Interrupt period in units of 1/2^16 CPU cycles.
// For 2.4 kHz, that is 16000/2.4*65536 = 436906666.666...
uint32_t interrupt_period = 436906667;

ISR(TIMER1_COMPA_vect) {
    // Update the timer for the next interrupt.
    static uint32_t accumulator;
    accumulator += interrupt_period;
    OCR1A = accumulator >> 16;

    // The periodic task goes here...
}

void setup() {
    // Configure Timer 1.
    TCCR1A = 0;            // normal mode
    TCCR1B = _BV(CS10);    // clock @ F_CPU
    TIMSK1 = _BV(OCIE1A);  // enable COMPA interrupt
}

void loop(){}
```

Here, `accumulator` is a 32-bit extension of the timer's output compare
register. The upper 16 bits are copied into the actual timer
register, whereas the lower 16 bits ensure that the accumulated
error never exceeds one cycle.

This way of updating the timer should only take about 2 µs per
interrupt. It is a constant time operation, so it doesn't add extra
jitter to your task, other than the single cycle of jitter induced by
rounding to the next edge of the CPU clock.

There are a couple of caveats though:

1. This can only work on an Arduino clocked off a crystal (e.g., a
   Micro). Those clocked off a ceramic resonator (Uno...) would be too
   unstable in frequency to meet your 10 ppm requirement.
2. Even though a crystal is more than stable enough to meet your
   requirement, it is unlikely to be accurate enough. You will then need
   to calibrate it, e.g. by outputting a PWM signal (`analogWrite()`)
   into a frequency meter. Then adjust the variable `interrupt_period`
   according to the measured clock frequency.

------------------------------------------------------------------------

**Edit**: I added the timer configuration to the code, and here comes an
explanation of how this code works.

Think of the timer as a digital alarm clock. It measures time in units
of CPU cycles instead of hours and minutes. It rolls over every
216 cycles instead of every 1440 minutes. But it is
otherwise a regular alarm clock. It has two alarms called “COMPA” and
“COMPB”, but you only need one. In order to perform a periodic task, you
turn the alarm on and, every time it rings, you advance the alarm time
by the required period. That is, you set:

new alarm time = previous alarm time + task period

Note that the addition has to be computed modulo the roll-over period of
your clock : 1440 minutes for a regular alarm clock,
216 cycles for the timer. Thankfully, the arithmetics on
unsigned numbers do this automatically.

Now, lets say the task period is 43 minutes and 35 seconds,
but the alarm can only be set with a resolution of one minute. What you
can do is compute the “ideal” alarm time on paper (this is the
`accumulator` variable), and truncate it to the resolution of the clock
when setting the alarm. If you start at 00:00:00, you will compute the
next ideal time to be 00:43:35 and set the alarm to 00:43. When it
rings, you add the period to the previously computed time, you get
01:27:10, and you set the alarm to 01:27. Etc. Here is the list of the
alarm times as computed and as actually set on the clock:

    computed  set
    ───────────────
    00:00:00  00:00
    00:43:35  00:43
    01:27:10  01:27
    02:10:45  02:10
    ...

Note that, even though the limited resolution of the alarm setting
creates some jitter, the _average_ task period is still exactly
43 minutes and 35 seconds.

The code I wrote above does exactly the same. The “ideal” alarm time is
computed as a fractional number of CPU cycles, written down in binary
fixed point, with 16-bits on each side of the radix point. In hex, it is
1A0A.AAAB CPU cycles. The computed alarm times are multiples of this
period, whereas the times actually written to OCR1A are the same
truncated to an integer:

    computed   set
    ───────────────
    1A0A.AAAB  1A0A
    3415.5556  3415
    4E20.0001  4E20
    682A.AAAC  682A
    ...


message:
How to change variable/sketch through a GUI

Over the past few months, I've been working on a wearable computer mouse using an Arduino and a 9-dof sensor. Most of the sketch is complete, and works as expected.

Recently, I started investigating how to enable a non-technical user to adjust the sensitivity of the device. Currently, I do this by changing a couple of variables in the sketch. My goal is to be able to create a basic GUI, with some buttons (perhaps unsurprisingly), to accomplish the same.

Requirements:
- ability to adjust sensitivity (couple of variables inside sketch) of arduino device through a GUI
- does not slow down sketch (I read that you can use serial, but wouldn't constantly checking for serial slow down the operation of the microcontroller?)
- can be saved as an executable (easy to set up for a nonprogrammer)

It's fine for the solution to upload a new sketch to the microcontroller, or change variables in the EEPROM. Whatever you suggest is best. I came across [this][1], and a few other similar topics, but due to my inexperience was unable to judge whether that's the best way forward.

I'm not looking for a complete solution, of course. Rather, I would really appreciate any guidance on what the basic "structure" of the solution should be. Then I can determine which parts I can do myself, and which I'll need to seek help on.

Thank you very much for looking at this.

  [1]: https://arduino.stackexchange.com/questions/13335/how-do-i-upload-sketch-and-parameters-through-a-user-interface

body:
Reflashing (and with that recompiling) the sketch for every variable change is very over-the-top.

As you already want to write your own program for the PC I would suggest using `Serial`. That will be the easiest to implement. This would work like the following:

- On the Arduino: You regularly check if there is data in the `Serial` buffer, read if in that case. You read until a newline character `\n`, which acts as message delimiter (to distinguish one message from the other). If a full message was received (meaning: you read the newline character) you process the message and write the new values to EEPROM (for saving them permanently).

- On the PC application: Let the user determine each value. You open the Arduinos COM port (the user will have to select the correct one) to communicate via Serial. Then you send each value, that you want to write to the Arduino, in a specific format. For example `<value_name>:<value>`. And don't forget the newline character at the end. Then you can close the COM port and exit the application.

This requires the user to choose the corresponding COM port. With using a custom USB profile (I think a custom HID profile should also be able to receive data) you could eliminate that, but this is a big step in difficulty for you to program.

> I read that you can use serial, but wouldn't constantly checking for serial slow down the operation of the microcontroller?

No, not really. The actual receiving of data is done by the USB hardware. As processing load you only have the placing of data in the buffer (happens inside an ISR), which only is done when actual data is received, and the checking if there is data in the buffer. That also needs very short time. It should not interfere with your sampling rate. The 9-DoF sensor is most likely way slower. The actual processing of the data is also only done when you actually send data. Here the longest will be saving the data in EEPROM.

So all in all you have little to no impact on performance.


message:
String operations printing random character on Serial Monitor

I want to extract the file name `MyFile.txt` out of a path which is stored in a string `"C:\\MyDirectory\\MyFile.txt";`

I found a simple [c code](https://stackoverflow.com/questions/8520560/get-a-file-name-from-a-path?answertab=votes#tab-top?#answer-8520815) which does the job.

```
string filename = "C:\\MyDirectory\\MyFile.bat";

// Remove directory if present.
// Do this before extension removal incase directory has a period character.
const size_t last_slash_idx = filename.find_last_of("\\/");
if (std::string::npos != last_slash_idx)
{
    filename.erase(0, last_slash_idx + 1);
}

// Remove extension if present.
const size_t period_idx = filename.rfind('.');
if (std::string::npos != period_idx)
{
    filename.erase(period_idx);
}
```

I had to alter few things for arduino code
example replace `find_last_of` with `lastIndexOf`, `erase` with `remove` and `rfind` with `lastIndexOf`

Here the `ino` file

```
#include<string>
void setup() {
  Serial.begin(9600);

}

void loop() {
   String filename = "C:\MyDirectory\MyFile.bat";

// Remove directory if present.
// Do this before extension removal incase directory has a period character.
const size_t last_slash_idx = filename.lastIndexOf("\\");
if (std::string::npos != last_slash_idx)
{
    filename.remove(0, last_slash_idx + 1);
}

// Remove extension if present.
const size_t period_idx = filename.lastIndexOf('.');
if (std::string::npos != period_idx)
{
    filename.remove(period_idx);
}
Serial.println(filename);
delay(1000);
}
```
Expected output `MyFile`

When I look into Serial Monitor I get
```
c$$⸮'<;⸮⸮/<⸮⸮$⸮''⸮;,#$$⸮'<;⸮⸮'<⸮⸮$⸮''⸮:$#$$⸮'<;⸮⸮'<⸮⸮$⸮''⸮;$#$$⸮'
```

What am I doing wrong?

body:
> ```c++
> #include<string>
> ```

Remove this. Arduino uses its own `String` class, different from the STL
`string`.

> ```c++
> String filename = "C:\MyDirectory\MyFile.bat";
> ```

There is no `'\M'` escape sequence in C++ strings. You probably mean
`"C:\\MyDirectory\\MyFile.bat"`.

> ```c++
> const size_t last_slash_idx = filename.lastIndexOf("\\");
> ```

`String::lastIndexOf()` returns an `int`, not `size_t`.

> ```c++
> if (std::string::npos != last_slash_idx)
> ```

No `std::string` here. `String::lastIndexOf()` returns `-1` to signify
that the character was not found.

With all these fixes, your sketch should work as intended.


message:
How to debug "No device found on cu.usbserial, An error occurred while uploading the sketch"

I am testing a project on Arduino Nano. I copy-paste the code on the Arduino IDE and click "Upload". I see:

```
No device found on cu.usbserial-<unique id>
An error occurred while uploading the sketch
```

The computer sees the board: when I disconnect the board from the USB socket, the list of ports in `Tools > Port` no longer shows this port.

The error thing happens:
- if I press the reset button first, then click "Upload"
- if I change the USB cable (I tried 5 different ones, one of which worked a few years ago, the last time I used this same board)
- if I use a [simple blink code](https://arduino-tutorials.net/tutorial/blinking-led-on-arduino)
- if I connect to a different USB port
- if I upgrade the Arduino IDE to the latest software from arduino.cc .

The `Get board info` command shows that the computer can read the VID and the PID, but not the serial number or the board type. If I connect an Arduino Uno to the same socket, I can see the serial number and the board type, but I get the same error message (just with a different port ID). Neither boards show signs of degradation.

The Boards Manager shows that the Arduino AVR Boards, which include Arduino Uno and Arduino Nano, are installed.

When I click "Upload", the IDE compiles the program, then the Nano's L LED blinks, then the TX blinks, then a pause, then the L, then the RX, then the L, then the RX, and then the IDE shows the error. So I suspect that the error is not what the IDE says.

Furthermore, the connection between the Arduino and the IDE is working because the Serial Monitor shows the output of the previous program (at 9600 baud).

Some Arduinos can reset by connecting RX to GROUND and uploading code, but this one does not have an RX pin.

How can I debug this error?

body:
It seems that everything is working as it should and the computer and the board can see each other. The only thing left to do is to select the board type so the IDE knows how to send the code in a way that the board can interpret.

Select `Tools > Board > Arduino AVR Boards > Arduino Nano`.

If you have an old or non-Arduino board, try the old bootloader in the processor, as in  https://arduino.stackexchange.com/questions/51729/ch340-nano-avrdude-stk500-getsync-not-in-sync-resp-0xa4 .


message:
Unable to use rising edge interrupt for external clock Arduino 2650

I'm messing about with an Arduino Mega2560r3 and failing to get timer 4 to trigger on the rising edge of an external clock. It only ever triggers on the falling edge.

I've tried

         TCCR4B = (1 << CS42) | (1 << CS41) | (1 << CS40);
and

         TCCR4B = (1 << CS42) | (1 << CS41);
... one of which should do the trick, but now I've pulled all my hair out and I'm turning to the wider community to see what I'm not seeing!

```
void setup() {
  DDRE = (1 << PE5);   //Dig pin 3 as output

  noInterrupts();
// Configure Timer 4 (only ICP4 (pin 49) and ICP5 (pin 48) are connected with Arduino MEGA2560 r3)
  TCCR4A = 0;
  TCCR4B = 0;
  TCCR4B = (1 << CS42) | (1 << CS41) | (1 << CS40);    // CTC mode does not reset when using force
  TIMSK4 = (1 << ICIE4);    // enable capture interrupt
  interrupts();
}

ISR(TIMER4_CAPT_vect)
{
  PORTE ^= (1 << PE5);  // Toggle PE5
}
```

Scope output below - blue is external clock (yes I know it's a sine wave!) and magenta is pin 3 output

[![falling edge trigger output][1]][1]

  [1]: https://i.stack.imgur.com/glqvM.png

body:
You seem to be mixing up two very different things.

1. You can use an external signal to drive the timer. That is, the timer
   will “tick” on the edges of that signal. In this mode, the timer
   behavior could be more accurately described as being a “counter”,
   since it is counting the external signal's edges. The external signal
   has to be fed to pin Tn (for timer _n_). Only the pins T0 (38) and T5
   (47) are routed out on the Arduino Mega2560.

2. You can use a timer to timestamp the edges of an external signal.
   This is called “input capture”. When an edge is detected, the current
   value of the counter register is immediately copied to the input
   capture register ICRn, and an interrupt can be delivered. The
   external signal has to be fed to pin ICPn (ICP4 = 49, ICP5 = 48).

If you want to use input capture, you most likely want to clock the
timer from the system clock, maybe through a prescaler. And you want to
read the ICRn register within the ISR. The edge that triggers the
capture is selected via the bit ICESn (Input Capture Edge Select) of the
control register TCCRnB.


message:
How to add library to Sloeber

Slober has a menu option: *Arduino -> Add a library to the selected project*

HOWEVER, the "Import Arduino libraries" dialog that comes up only shows 18 libraries, and has no obvious way to add more.

I selected *Arduino -> How To*, and selected "Add a library to a sketch", but it told me nothing new. It assumes the library I want to add is in the list, and says nothing about how that list itself is managed, where the libraries in it came from, how to add others, etc.

I theorized that Sloeber's list might be somehow generated from the one maintained by the Arduino IDE... but no, the list of libraries shown in Sketch -> Include library is ENORMOUSLY longer than Sloeber's list.

So... where, exactly, does Sloeber's library list come from, and how does one go about adding a library to it that's NOT in the list? Say...

* From whatever repository the Arduino IDE itself gets libraries from when you go to Library Manager (confession: I don't use Arduino often enough to *know* where those libraries are actually hosted, or who decides what qualifies to be listed. I assume it's something like MavenCentral and hosted by the Arduino organization... but I might be completely wrong)

* From a "zipfile" (containing whatever files, with whatever additional metadata, is required for Arduino's IDE to regard it as a valid library zipfile)

* From a random Github repo, like https://github.com/mrkaleArduinoLib/gbj_htu21 (with library.json, library.properties, and subdirectories for src/ and examples/)

body:
In `Arduino` or in `Window` menu in `Preferences`

[![enter image description here][1]][1]

  [1]: https://i.stack.imgur.com/HKuWe.png


message:
Using 4-digit 7-segment display on Arduino Nano

I want to merge two projects: a ["Don't touch your face" hat for Nano](https://www.hackster.io/elegoo-official/don-t-touch-your-face-hat-337f4e) and a [7-segment 4-digit display for Uno](
https://create.arduino.cc/projecthub/aboda243/how-to-use-4-digit-7-segment-without-library-b8e014). I tested both independently and they work. I added an RGB LED to the first, so I use 6 digital pins: 2 for the ultrasonic sensor, 1 for the buzzer, and 3 the RGB LED.

The Nano project takes 6 digital pins and no analog pins, leaving 4 digital pins and 8 analog pins. The Arduino Uno takes 12 digital pins. So I suppose that it's possible to replace the digital pins of the Uno with analog ones at the right voltage.

Even without the Nano project claiming 6 digital pins, the Nano only has 11 digital pins (D2-D12), not enough for a 7-segment 4-digit display. But I couldn't find a tutorial online on how to do so.

Is it possible to use a 7-segment 4-digit display on Arduino Nano?

body:
There are chips such as the MAX7219 designed to control 7 segment displays from devices such as an Arduino, there are also some well-established libraries such as LEDCONTROL to drive them. In fact the MAX7219 doesn't have to drive 7 seg displays, you can use it to drive any collection of up to 64 LEDs, I use one for a simple illuminated Christmas tree. You'll need some basic soldering skills to connect the chip to an Arduino but it's very simple.

E.g. see: https://www.maximintegrated.com/en/products/power/display-power-control/MAX7219.html


message:
Can't get 1 second on a ATMega168 timer

```
  TCCR1A = 0;
  TCCR1B = 0;
  OCR1B =  0xFF00;
  TCCR1A = (1<<WGM10) ;
  TCCR1B = (1<<CS12) | (1<<CS10);; //set the pre-scalar as 1024
  TIMSK1 = (1 << OCIE1A);
```

This doesn't produce a 1 second timer, it seems to produce a 0.5 second timer? I've calculated it based on the fact that I'm using the internal 8MHz internal clock on the chip.

Where am I going wrong?

EDIT: OK, I truly don't understand anything about timers, this is the first time I've ever tried one. I tried to figure it out using this tutorial: <https://exploreembedded.com/wiki/AVR_Timer_programming>
All the examples are related to 16MHz, and the calculations are confusing to me because of the switch between formats which I don't know. After a lot of googling I figure out what I should be pushing into the calculator is ((8000000/1024)*1)-1) = 7811.5 (Although what I do with this number is a mystery) I think I'm supposed to subtract this from 65536 or perhaps some other randomly generated number. You then take the result of this and turn it into the hexadecimal equivalent of a boy band name, like E17 use lots of arrows to point away from things that look like the names of radio stations, WGM10 (bringing you all the hits of the 80's and 90's)

I apologize for the sarcasm, I couldn't help myself. What I really need to know is:
1. How do you actually calculate a 1-second delay one timer 1 when you are using the 8MHz internal clock of the ATMega168PA ? What are the numbers to type into a calculator?
2. Which switches should I be setting? I thought these were the correct ones.
3. What does OCIE1A stand for, can't find it in the documentation or the tutorial, only in the example code?

I should probably also add all I am doing is incrementing a count and displaying the count in my loop.

```
ISR (TIMER1_COMPA_vect)
{
  count++;
}
```

body:
In normal mode, the timer counts from 0 to 65535 (0xffff), and then
rolls over back to zero. With a prescaler set to 1024, the period is
then 1024 × 65536 = 67108864 CPU cycles.

If you want to control the timer's period, you should not use normal
mode, but rather CTC mode (for “clear timer on compare match”). In this
mode, it counts from 0 to the value stored in OCR1A, and then starts
back at zero. With the same prescaler, the period is then
1024 × (OCR1A + 1) CPU cycles.


message:
how can I delete contents of an SD card in arduino?

I have a datafile, datalog.txt I can open, read and write cool. What is the best way to delete all the file contents?
Should I try rewriting the SD card file with NULL data?
I have been reading the "SD.h" header file. I see a flush() and truncate() function should I use one of these?

or maybe I should just close  and reopen the file, and overwrite the data. But I'm concerned that this might lead to some miss representations if the old data is not completely removed.

I am using a teensy 4.1 with built_in SD card.

body:
To remove a file use `SD.remove("datalog.txt");`

SD library's `FILE_WRITE` is `O_READ | O_WRITE | O_CREAT | O_APPEND` so it would append at the end of the existing file.

<del>to start with an empty file: File file = FS.open("datalog.txt", O_READ | O_WRITE | O_CREAT);</del>

EDIT: opening the file with O_READ | O_WRITE | O_CREAT doesn't clear the content of the file, only starts to overwrite it from the beginning.


message:
Synchronizing an internal frequency to an external one

In this question:
 https://arduino.stackexchange.com/q/86601/4255, @EdgarBonet gave a very nice method of generating timings that don't divide the system clock evenly. He also said that it would require tuning of the exact value by measuring the resulting frequency. I'd like to see if that tuning could be made automatic.

Suppose I had a precise external reference that could interrupt at a a sub-multiple of my frequency, say 60Hz. Is there a way to use that precision to, over time, bring my generated frequency into rough agreement with it?

In other words, for a frequency of 2400 Hz, and a reference of 60 Hz, I would adjust the period of the generator so that there are exactly 80 cycles of the 2400 Hz signal in each 60Hz period, even though there might be variations within the periods of those 80 cycles.

In effect this is a crude phase-locked loop multiplier. I know it can't be highly precise, but even close would be very valuable.

body:
You could use the input capture feature of Timer 1 to timestamp the
edges of the reference input signal. This way you can compute the period
of the input relative to the CPU clock, compare to the expected nominal
period, and use this to adjust the interrupt period.

Combining this idea with the answer to the previous question gives:

```c++
const float input_frequency = 60;
const float interrupt_frequency = 2400;
const uint32_t nominal_input_period = round(F_CPU / input_frequency);
const uint32_t nominal_interrupt_period =
    round(F_CPU / interrupt_frequency) * 65536;

volatile uint32_t interrupt_period = nominal_interrupt_period;

uint16_t last_input_timestamp;

ISR(TIMER1_COMPA_vect) {
    // Update the timer for the next interrupt.
    static uint32_t accumulator;
    accumulator += interrupt_period;
    OCR1A = accumulator >> 16;

    // The periodic task goes here...
}

void setup() {
    // Configure Timer 1.
    TCCR1A = 0;            // normal mode
    TCCR1B = _BV(CS10);    // clock @ F_CPU
    TIMSK1 = _BV(OCIE1A);  // enable COMPA interrupt

    // Capture the first input edge.
    TIFR1 |= _BV(ICF1);  // clear interrupt flag
    loop_until_bit_is_set(TIFR1, ICF1);
    TIFR1 |= _BV(ICF1);  // clear interrupt flag again
    last_input_timestamp = ICR1;
}

void loop() {
    // Detect edges of the input signal.
    if (bit_is_set(TIFR1, ICF1)) {
        TIFR1 |= _BV(ICF1);  // clear interrupt flag

        // Update the interrupt period.
        uint16_t input_timestamp = ICR1;
        uint32_t input_period =
            (int16_t) (input_timestamp - last_input_timestamp
                - (uint16_t) nominal_input_period)
            + nominal_input_period;
        last_input_timestamp = input_timestamp;
        uint32_t new_interrupt_period = round(nominal_interrupt_period
                * ((float) input_period / nominal_input_period));
        noInterrupts();
        interrupt_period = new_interrupt_period;
        interrupts();
    }
}
```

Note that rounding the input period to an integer number of cycles comes
with a rounding error of 1.25 ppm, well within your 10 ppm
requirement. You can do better if needed, by using fixed point or
floating point computations. Note also that the Timer rolls over
multiple times per cycle of the input signal, which is dealt with by
some arithmetic tricks, hence the casts to `uint16_t` and `int16_t` in
the expression of `input_period`.

Strictly speaking, this is not a phase lock loop. It is more like a
frequency lock loop. A real PLL would probably be a bit more involved.
However, if you can tolerate your resulting frequency to be 10 ppm
off, this approach is likely to be good enough.