body:
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;
      }
    }

title: stop motor instantaneous with hall sensor problem

Answers: 2

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

body:
The motor can't stop instantly because it has inertia, plus the inertia of whatever stuff the motor is moving.

So if you want it to stop at a set position, you have to slow it down before it reaches the desired position, so it will come to a stop where you want. It's not possible to do that with only one sensor.

A complicated solution would be to use a position encoder, like a rotary encoder, to know the position at all times, so you could use a control algo like PID on the motor. This offers the most features, as you can then set the desired stop position in software, without needing to move the sensor.

If the stop position never moves then a simpler solution is to use multiple sensors. That's often how it's done with elevators: there is a sensor to accurately align the elevator with the floor it has to stop on, but there are also several others slightly before that on the track to tell the controller that it's time to start slowing down, then slow down to a crawl, then stop.

To keep it simple you can use just two sensors: when it goes past the first, slow down the motor to a crawl. When it activates the second sensor, since it is going slow, it will stop quickly and end up where you want.


body:
I'm trying to get an average from three intervals to get bpm. However, when I use the code below the bpm would slowly decrease when used with the sensor. Can anyone please check for what is wrong with the code and for reference I have to modify the below code from the link for 4 beats to get bpm. https://arduino.stackexchange.com/questions/43956/getting-bpm-from-the-given-code

    #include <LiquidCrystal.h>

    LiquidCrystal lcd(24, 25, 26, 27, 28, 29);

    //global variables

    int  ibeats, iInterval1, iInterval2, iInterval3, iCount = 1;
    unsigned long iFirstPulse, iSecondPulse, iThirdPulse, iFourthPulse;
    bool bIgnoreread = false;
    bool bFirstPulse = false, bSecondPulse = false, bThirdPulse = false, bFourthPulse = false;

    float BPM, fAverage;

    void setup()
    {
      //initialize USB serial port, I2C bus and LCD
      Serial.begin(115200);         //set this comm up in-case you want to troubleshoot

      lcd.begin(20, 4); delay(2);
      lcd.clear(); delay(2);

      lcd.setCursor(0, 0); lcd.print(" Patient Prober");

    }

    void loop()
    {

      ibeats = analogRead(15); delay(5);//  Read the Pulse Sensor's value.

      lcd.setCursor(0, 3); lcd.print("BPM:"); lcd.print(BPM); lcd.print(" ");// displaying bpm value on LCD

      if (ibeats > 780 && bIgnoreread == false)     //once the signal is high and bIgnoread is false inital condition, inside if statment will start
      {
        if (bFirstPulse == false && iCount == 1)
        {
          iFirstPulse = millis();   // time when the pulse is high for the FirstPulse
          bFirstPulse = true;      // to turn off if statement
        }

        if (bSecondPulse == false && iCount == 2)
        {
          iSecondPulse = millis();
          iInterval1 = iSecondPulse - iFirstPulse;   // first interval
          bSecondPulse = true;
        }

        if (bThirdPulse == false && iCount == 3)
        {
          iThirdPulse = millis();
          iInterval2 = iThirdPulse - iSecondPulse;    //Second Interval
          bThirdPulse = true;
        }

        if (bFourthPulse == false && iCount == 4)
        {
          iFourthPulse = millis();
          iInterval3 = iFourthPulse - iThirdPulse;    // third interval
          bFourthPulse = true;
        }

        bIgnoreread = true; // to turn off when millis second is assign to variable Pulse  When the signal is high
      }

      // reseting all the bollean to intial condition
      if (ibeats < 300)
      {
        bIgnoreread = false;
        bFirstPulse = false;
        bSecondPulse = false;
        bThirdPulse = false;
        bFourthPulse = false;
        iCount++;               // incrment to help to diffrent if ststment above
      }

      //if(ibeats==0)iCount++;

      fAverage = ( iInterval1 + iInterval2 + iInterval3) / 3;         // Average for the interval
      BPM = (60000.0 / fAverage);                                    // Bpm calculation

      if (iCount > 4)iCount = 1;                                    // reseting icount to start the cycle again
    }
    //********************************************************************************************

title: How to get Bpm with 4 heart beat pulses

Answers: 0


body:
I need to receive some data from USB and send it to the Android device via Bluetooth. The problem is that multiple SoftwareSerials won't connect at the same time.

Here is my code:

```code
SoftwareSerial bluetooth(2,3);
SoftwareSerial usbConverter(4, 5);

void setup() {
  usbConverter.begin(9600);
  bluetooth.begin(9600);
  checkConnection();
}

void checkConnection() {
  while(true) {
    int areBothDevicesConnected = 0;
    if(bluetooth.available()) {
      areBothDevicesConnected++;
      bluetooth.println("Bluetooth connected");
      if(usbConverter.available()) {
        areBothDevicesConnected++;
        bluetooth.println("USB converter connected");
      } else {
        bluetooth.println("USB converter is not available");
      }
    }
    if(areBothDevicesConnected == 2) {
      bluetooth.println("All devices connected");
      break;
    }
    delay(2000);
  }
}
```

As far as I understand only one SoftwareSerial can listen at the same time but in my case, I can't even connect both devices. On Android device I always receive `USB converter is not available`.

My setup:
- Arduino UNO.
- HC-05 Bluetooth.
- USB to TTL converter.

Any clue?

title: Multiple SoftwareSerial's at the same time?

Answers: 0


body:
I have built a circuit board that includes a BLE module and an oxygen sensor that has a UART.  Writing arbitrary data to the BLE works fine, but for some reason every configuration of SoftwareSerial I can think of will not pick up anything from the oxygen sensor TX.  It simply never has any bytes available.

Here's the code:

```c++
#include <SoftwareSerial.h>

const int HM10_TX = 8;
const int HM10_RX = 9;
const int LOXO2_TX = A6;
const int LOXO2_RX = A7;

SoftwareSerial BLE(HM10_RX, HM10_TX);
SoftwareSerial oxygen(LOXO2_RX, LOXO2_TX);

void setup() {
  BLE.begin(9600);
  oxygen.begin(9600);
  oxygen.listen();
}

void loop() {
  if (oxygen.available() > 0) {
    BLE.write(oxygen.read());
  }
}
```

Meanwhile, I uploaded a short serial passthrough sketch to an Uno, connected probes between it and directly to the pins on the Nano that are used for the O2 sensor TX/RX, and I can see the expected bytes being received in my serial monitor.  So I'm 99% sure the problem isn't with the sensor.  Maybe the circuit, but so far I don't seem to have evidence of that.

I've been under the impression that any pin on the Nano can be used with SoftwareSerial.  All the reading I've done hasn't yielded any useful information as to why nothing is being read when clearly there are voltage changes on the pin that are being picked up by the Uno.

The reason I'm not using hardware serial is I will be using multiple sensors and the hardware serial pins need to be available for USB.

Am I doing something wrong?  The passthrough code I write for the Uno really isn't that different from the above code except it's of course using the hardware serial so I can observe the serial output on my laptop.

title: SoftwareSerial fails to receive on Nano but works with Uno

Answers: 0


body:
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"`

title: `ConfigTime` daylight saving update

Answers: 1

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


body:
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

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

Answers: 1

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`.


body:
Using Arduino Uno and a GUVA-S12SD sensor (https://www.adafruit.com/product/1918).

Here's my circuit. 5V into sensor+, GND into sensor-, A0 to sensor out.

[![circuit][1]][1]

Here's my code:

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

    void loop()
    {
      float sensorVoltage;
      float sensorValue;
      float uvIndex;

      sensorValue = analogRead(A0);
      Serial.print("Analog out: ");
      Serial.println(sensorValue);

      // 5 because 5V
      sensorVoltage = sensorValue * (5.0 / 1023.0);
      Serial.print("Output voltage: ");
      Serial.println(sensorVoltage);

      uvIndex = sensorVoltage / 0.1;
      Serial.print("UV Index: ");
      Serial.println(uvIndex);

      Serial.println();

      delay(1000);
    }

Here's a sample from the serial monitor. The values stay about the same regardless of where I am in my house (in a sunny room, in the dark bathroom, etc.).

    Analog out: 853.00
    Output voltage: 4.17
    UV Index: 41.69

    Analog out: 853.00
    Output voltage: 4.17
    UV Index: 41.69

    Analog out: 853.00
    Output voltage: 4.17
    UV Index: 41.69

    Analog out: 853.00
    Output voltage: 4.17
    UV Index: 41.69

Output voltage is supposed to be very low. The UV index maxes out at around 11 - so 41 is too high. I checked what it is in my city right now, and it's 3. So this is super wrong. I don't have a multimeter to test with right now.

Any ideas about what could be going on? Did I order a bad sensor?

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

title: Analog UV sensor displaying incorrect values in serial monitor (GUVA-S12SD)

Answers: 0


body:
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/

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

Answers: 3

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.


body:
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

title: My program is using too much memory

Answers: 4

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.

body:
The Arduino Uno uses a rather old, weak processor. It is still a perfectly cromulent microcontroller - it does just fine - but much newer ones do exist.

You mentioned the ESP8266. Did you know it has 40kB of RAM compared to the Uno's 2kB? And the successor, the ESP32, has 320kB of RAM.

Since your application is basically a miniature computer, with a keyboard and screen, have you considered using something that's designed as a miniature computer? A Raspberry Pi (any model) has more gigabytes of RAM than you know what to do with. But it does use a lot more power. But you can also write the software in a normal Linux way (if you happen to like Linux programming). Or, you could consider writing an app for your Android cellphone.

If you insist on using the Uno, another option is to add an SPI RAM expansion chip, for example [this 1-euro chip with 32kB](https://www.mouser.com/ProductDetail/Microchip-Technology/23K256-I-ST?qs=WqWCsLCZBkqPXMOuUQE8GA==&gclid=CjwKCAjwiY6MBhBqEiwARFSCPu1Y0PDhywHBH9CxXt8TTOn3cnBaHYdKQesFvi_RB0ZBXY6qVMxEyhoCnYkQAvD_BwE) (they do go bigger). Now, the Uno has *no* built-in RAM expansion ability, so you can't just access it with pointers or something, but you can still use the SPI bus to tell the chip to read or write certain bytes, kinda like you can with an SD card.

After writing this, I realized SPI RAM is not so useful for your application, because you don't want to store the data only while the device is turned on. You could use a SPI FRAM or SPI EEPROM chip instead which can store data while it's powered off. The Arduino IDE doesn't have a way to automatically put data into any of these chips... so to input the data you'd probably have to send it over the serial port, into a separate program you wrote, which writes it to the chip. Or you could make a user interface that allows the user to edit the data directly on the device.

Or you can use an SD card, yes. Honestly that's probably the simplest way.


body:
I have a project to find the pulse oximetry rate. I used MAX30102 and ESP8266 as shown in the first picture.

## Wiring

    GND ------> GND
    VIN ------> 3.3V
    SDA ------> D2
    SCL ------> D1

[![Wiring Diagram][1]][2]
[![Module Picture][2]][2]
[![Wiring Picture][3]][3]

## Code

I also used the following code in esp2866 programming:

    #include <Wire.h>
    #include "MAX30105.h"
    #include "spo2_algorithm.h"

    MAX30105 particleSensor;

    #define MAX_BRIGHTNESS 255

    uint32_t irBuffer[100]; //infrared LED sensor data
    uint32_t redBuffer[100];  //red LED sensor data

    int32_t bufferLength; //data length
    int32_t spo2; //SPO2 value
    int8_t validSPO2; //indicator to show if the SPO2 calculation is valid
    int32_t heartRate; //heart rate value
    int8_t validHeartRate; //indicator to show if the heart rate calculation is valid

    void setup()
    {
      Serial.begin(115200); // initialize serial communication at 115200 bits per second:

      // Initialize sensor
      if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
      {
        Serial.println(F("MAX30102 was not found. Please check wiring/power."));
        while (1);
      }

      Serial.println(F("Attach sensor to finger with rubber band. Press any key to start conversion"));
      while (Serial.available() == 0) ; //wait until user presses a key
      Serial.read();

      byte ledBrightness = 60; //Options: 0=Off to 255=50mA
      byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
      byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
      byte sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
      int pulseWidth = 411; //Options: 69, 118, 215, 411
      int adcRange = 4096; //Options: 2048, 4096, 8192, 16384

      particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings
    }

    void loop()
    {
      bufferLength = 100; //buffer length of 100 stores 4 seconds of samples running at 25sps

      //read the first 100 samples, and determine the signal range
      for (byte i = 0 ; i < bufferLength ; i++)
      {
        while (particleSensor.available() == false) //do we have new data?
          particleSensor.check(); //Check the sensor for new data

        redBuffer[i] = particleSensor.getRed();
        irBuffer[i] = particleSensor.getIR();
        particleSensor.nextSample(); //We're finished with this sample so move to next sample

        Serial.print(F("red="));
        Serial.print(redBuffer[i], DEC);
        Serial.print(F(", ir="));
        Serial.println(irBuffer[i], DEC);
      }

      //calculate heart rate and SpO2 after first 100 samples (first 4 seconds of samples)
      maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

      //Continuously taking samples from MAX30102.  Heart rate and SpO2 are calculated every 1 second
      while (1)
      {
        //dumping the first 25 sets of samples in the memory and shift the last 75 sets of samples to the top
        for (byte i = 25; i < 100; i++)
        {
          redBuffer[i - 25] = redBuffer[i];
          irBuffer[i - 25] = irBuffer[i];
        }

        //take 25 sets of samples before calculating the heart rate.
        for (byte i = 75; i < 100; i++)
        {
          while (particleSensor.available() == false) //do we have new data?
            particleSensor.check(); //Check the sensor for new data

          redBuffer[i] = particleSensor.getRed();
          irBuffer[i] = particleSensor.getIR();
          particleSensor.nextSample(); //We're finished with this sample so move to next sample

          //send samples and calculation result to terminal program through UART
          Serial.print(F("red="));
          Serial.print(redBuffer[i], DEC);
          Serial.print(F(", ir="));
          Serial.print(irBuffer[i], DEC);

          Serial.print(F(", HR="));
          Serial.print(heartRate, DEC);

          Serial.print(F(", HRvalid="));
          Serial.print(validHeartRate, DEC);

          Serial.print(F(", SPO2="));
          Serial.print(spo2, DEC);

          Serial.print(F(", SPO2Valid="));
          Serial.println(validSPO2, DEC);
        }

        //After gathering 25 new samples recalculate HR and SP02
        maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
      }
    }

## Error

When executing, it showed me in the window that:

```
11:48:31.564 -> MAX30102 was not found. Please check wiring/power.
```

I have used two of the max30102, but it shows the same result.
The MAX30102 does not turn on and the light also doesn't work. Are there any solutions?

  [1]: https://i.stack.imgur.com/REfDf.png
  [2]: https://i.stack.imgur.com/Xmc4B.png
  [3]: https://i.stack.imgur.com/4E8nW.jpg

title: MAX30102 not working?

Answers: 0


body:
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

title: Rp2040 dual core example sketches

Answers: 1

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);
}
```


body:
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?

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

Answers: 3

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.


body:
The code that I use:

```
#include <SoftwareSerial.h>

//Create software serial object to communicate with SIM800L
SoftwareSerial mySerial(16, 17);

void setup()
{
  //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
  Serial.begin(9600);

  //Begin serial communication with Arduino and SIM800L
  mySerial.begin(9600);

  Serial.println("Initializing...");
  delay(1000);

  mySerial.println("AT"); //Once the handshake test is successful, it will back to OK
  updateSerial();
  mySerial.println("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
  updateSerial();
  mySerial.println("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
  updateSerial();
  mySerial.println("AT+CREG?"); //Check whether it has registered in the network
  updateSerial();
}

void loop()
{
  updateSerial();
}

void updateSerial()
{
  delay(500);
  while (Serial.available())
  {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
  }
  while(mySerial.available())
  {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
  }
}
```

but if I run it, the GSM doesn't seem to respond or it show me different characters as its output "???".

Connection:

| SIM800L | Nodemcu ESP-32s |
| -------- | -------------- |
| RX| GIOP17|
| TX| GIOP16|

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

[![enter image description here][2]][2]

the expected output:

[![enter image description here][3]][3]

the output I have:
[![enter image description here][4]][4]

  [1]: https://i.stack.imgur.com/1bnGQ.jpg
  [2]: https://i.stack.imgur.com/mHdap.png
  [3]: https://i.stack.imgur.com/pyZ8O.png
  [4]: https://i.stack.imgur.com/9x5DQ.png

title: How to connect Nodemcu ESP-32s and GSM SIM800L

Answers: 0


body:
I have my SIM900 connected to a 12v 2A power source, I have inserted my sim card changed it to 3G/2G(autoconnect) ( I did research it to know wheteher it is possible and it turns out it is, the only problem would be not having the same speed according to them) There are no pin/password on the sim. There is still a remaining balance (should be enough to send a text or two)
Also my SIM900 netlight led blinks every 1 sec.

I also did try AT commands that I found on the internet and this is the results:

I have also posted this on this site: https://forum.arduino.cc/t/sim900-at-ccid-error/922283

CODE

    #include <SoftwareSerial.h>

    //Create software serial object to communicate with SIM900
    SoftwareSerial mySerial(7, 8); //SIM900 Tx & Rx is connected to Arduino #7 & #8

    void setup()
    {
    //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
    Serial.begin(19200);

    //Begin serial communication with Arduino and SIM900
    mySerial.begin(19200);

    Serial.println("Initializing...");
    delay(1000);

    mySerial.println("AT"); //Handshaking with SIM900
    updateSerial();
    mySerial.println("AT+CSQ"); //Signal quality test, value range is 0-31 , 31 is the best
    updateSerial();
    mySerial.println("AT+COPS");
    updateSerial();
    mySerial.println("AT+CCID"); //Read SIM information to confirm whether the SIM is plugged
    updateSerial();
    mySerial.println("AT+CREG?"); //Check whether it has registered in the network
    updateSerial();
    }

    void loop()
    {
    updateSerial();
    }

    void updateSerial()
    {
    delay(500);
    while (Serial.available())
    {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
    }
    while(mySerial.available())
    {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
    }
    }

SERIAL MONITOR

    Initializing...
    AT

    OK
    AT+CSQ

    +CSQ: 17,0

    OK
    AT+COPS?

    +COPS: 0

    OK
    AT+CCID?

    ERROR
    AT+CREG?

    +CREG: 1,0

    OK

title: SIM900 AT+CCID ERROR

Answers: 0


body:
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.

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

Answers: 1

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.


body: 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?

title: Plug in analog sensor into digital pin

Answers: 2

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.


body:
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;
    }

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

Answers: 1

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*.


body:
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

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

Answers: 1

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.*


body:
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!

title: ESP32 not detecting PN532 module running in SPI mode

Answers: 2

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.


body:
I want to update software OTA on multiple of my nodemcu devices that are currently sending data to my firebase database. I found this tutorial (https://medium.com/firebase-developers/over-the-air-arduino-firmware-updates-using-firebase-part-1-3e874ad9f93e) for ESP32 and tried adapting it to work with one of my nodemcu however it writes no binary and "gives up". I am not sure why/how to modify the code further. I am currently running core 2.7.4 as upgrading does not allow me to upload code to my nodemcu.

I have attached part of my code below and output I get in serial monitor. I am able to connect to wifi, change my "updatebit", and send data to firebase so there is no issue there.

[![Serial Monitor Output][1]][1]

    #include <Firebase.h>
    #include <FirebaseArduino.h>
    #include <FirebaseCloudMessaging.h>
    #include <FirebaseError.h>
    #include <FirebaseHttpClient.h>
    #include <FirebaseObject.h>

    //#include <ESP8266WiFi.h>
    #include <FirebaseArduino.h>

    #include "Updater.h"
    #include "ESP8266WiFi.h"
    #include "ESP8266HTTPClient.h"

    #define FIREBASE_HOST "..."
    #define FIREBASE_AUTH "..."

    #define FIRMWARE_URL \
    "http://..."
    HTTPClient http;

    void setup() {
    ....
    }
    void loop() {
      if(updatebit==1){
        updateFirmware();
      } else {
      }
    }

    void updateFirmware() {
      // Start pulling down the firmware binary.

      http.begin(FIRMWARE_URL);
      int httpCode = http.GET();
      if (httpCode <= 0) {
        Serial.printf("HTTP failed, error: %s\n",
           http.errorToString(httpCode).c_str());
        return;
      }
      // Check that we have enough space for the new binary.
      int contentLen = http.getSize();
      Serial.printf("Content-Length: %d\n", contentLen);
      bool canBegin = Update.begin(contentLen);
      if (!canBegin) {
        Serial.println("Not enough space to begin OTA");
        return;
      }
      // Write the HTTP stream to the Update library.
      WiFiClient* client = http.getStreamPtr();
      size_t written = Update.writeStream(*client);
      Serial.printf("OTA: %d/%d bytes written.\n", written, contentLen);
      if (written != contentLen) {
        Serial.println("Wrote partial binary. Giving up."); //content length printed in serial
    monitor is 42 but 0/42 bytes are written and it says "Wrote partial binary. Giving up."
        return;
      }
      if (!Update.end()) {
        Serial.println("Error from Update.end(): " +
          String(Update.getError()));
        return;
      }
      if (Update.isFinished()) {
        Firebase.setInt("updatebit",0);
        Serial.println("Update successfully completed. Rebooting.");
        // This line is specific to the ESP32 platform:
        ESP.restart();
      } else {
        Serial.println("Error from Update.isFinished(): " +
          String(Update.getError()));
        return;
      }
    }

If I add the "s" in http changing from

    #define FIRMWARE_URL \
    "http://..."
to

    #define FIRMWARE_URL \
    "https://..."

I get "HTTP failed, error: connection failed" in serial monitor

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

title: ESP8266 NodeMCU Lolin V3 and using Firebase to update its software OTA

Answers: 0


body:
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.)

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

Answers: 2

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.


body:
I am looking to get some assistance to learn how to program the Bluetooth module for TinyCircuits.

I am currently using the [UARTPassThrough.ino example][3] to try and learn BlueNRG's functions.

I see that in the UARTPassThrough.ino code, the loop() function calls the aci_loop() function in UART.ino. I'm not too sure what are ACI commands. What does the aci_loop() function do for its Bluetooth functionality?
```
void aci_loop() {
  HCI_Process();
  ble_connection_state = connected;
  if (set_connectable) {
    setConnectable();
    set_connectable = 0;
  }
  if (HCI_Queue_Empty()) {
    //Enter_LP_Sleep_Mode();
  }
}
```

Also, when I try to use the aci_gap_start_general_discovery_proc() function, the value returned is 255. What does the value 255 mean?

Main .ino file:
```
void setup() {
  SerialMonitorInterface.begin(9600);
  while (!SerialMonitorInterface); //This line will block until a serial monitor is opened with TinyScreen+!
  BLEsetup();
}

void loop() {
  aci_loop(); //Process any ACI commands or events from the NRF8001- main BLE handler, must run often. Keep main loop short.
  BLEdiscoverymode();
}
```

Added own function to UART.ino file:
```
void BLEdiscoverymode() {
  uint8_t output;
  output = aci_gap_start_general_discovery_proc(0x4000, 0x4000, 0x00, 0x01);
  PRINTF("--Bluetooth function return value: %d--\n", output);
}
```

Output from Serial Monitor
```
03:44:21.572 -> --Bluetooth function return value: 255--
03:44:23.774 -> --Bluetooth function return value: 255--
03:44:25.989 -> --Bluetooth function return value: 255--
03:44:28.208 -> --Bluetooth function return value: 255--
03:44:30.407 -> --Bluetooth function return value: 255--
```

Help would be much appreciated.

My TinyCircuit uses these components:

- [TINYZERO PROCESSOR BOARD][1]

- TINYSCREEN OLED TINYSHIELD

- [BLUETOOTH LOW ENERGY TINYSHIELD][2] (ST)
(Uses the BlueNRG-MS chipset with the SPBTLE-RF module)

- Lithium Ion Polymer battery - 3.7V 150MAH

  [1]: https://tinycircuits.com/collections/processors/products/tinyzero-processor
  [2]: https://tinycircuits.com/collections/communication/products/bluetooth-low-energy-tinyshield
  [3]: https://github.com/TinyCircuits/TinyCircuits-TinyShield-BLE-ASD2116/tree/master/examples/STBLE/examples/UARTPassThrough

title: Need help with Bluetooth component for TinyCircuit

Answers: 0


body:
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

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

Answers: 1

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.


body:
When `analogReference(INTERNAL)` is set (1.1V), can I use the AREF pin to supply a circuit? E.g. like this:

    AREF —— R1 —— button switch —— A4 —— R2 —— GND

where A4 is configured as analog input (forming a resistive voltage divider with R1 and R2).

Is this safe to do? The reference manual talks about having a capacitator on AREF, or only capacitive loads.

You can find the [datasheet here](https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf): see 23.2 (page 205), Figure 23-1 (block circuit diagram, page 206), and section 23.5.2 (Page 211).

title: Can I use AREF to supply a circuit, when in internal mode? (Nano)

Answers: 0


body:
I am getting the Arduino console error "the selected serial port serial.serialutil.SerialTimeoutException: Write timeout
does not exist or your board is not connected". I recently upgraded to esp8266 version 3.0.2 and cannot upload a simple blink led sketch to my board. Does anyone know how to resolve this? I would like to be able to use the latest core although downgrading to version 2.7.4 allows me to upload sometimes.

Arduino Code:

    #define LED_BUILTIN 2

    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
    }

    // the loop function runs over and over again forever
    void loop() {
      digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
                                    // but actually the LED is on; this is because
                                    // it is acive low on the ESP-01)
      delay(1000);                      // Wait for a second
      digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
      delay(2000);                      // Wait for two seconds (to demonstrate the active low LED)
    }

Console output:
Arduino: 1.8.13 (Windows 10), Board: "NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled (new aborts on oom), Disabled, All SSL ciphers (most compatible), 32KB cache + 32KB IRAM (balanced), Use pgm_read macros for IRAM/PROGMEM, 4MB (FS:2MB OTA:~1019KB), 2, v2 Lower Memory, Disabled, None, Only Sketch, 115200"

Executable segment sizes:

ICACHE : 32768           - flash instruction cache

IROM   : 231724          - code in flash         (default or ICACHE_FLASH_ATTR)

IRAM   : 26793   / 32768 - code in IRAM          (IRAM_ATTR, ISRs...)

DATA   : 1496  )         - initialized variables (global, static) in RAM/HEAP

RODATA : 876   ) / 81920 - constants             (global, static) in RAM/HEAP

BSS    : 25608 )         - zeroed variables      (global, static) in RAM/HEAP

Sketch uses 260889 bytes (24%) of program storage space. Maximum is 1044464 bytes.

Global variables use 27980 bytes (34%) of dynamic memory, leaving 53940 bytes for local variables. Maximum is 81920 bytes.

esptool.py v3.0

Serial port COM4

Connecting...

Traceback (most recent call last):

  File "C:\Users\ab\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.0.2/tools/upload.py", line 66, in <module>

    esptool.main(cmdline)

  File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 3552, in main

    esp.connect(args.before, args.connect_attempts)

  File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 519, in connect

    last_error = self._connect_attempt(mode=mode, esp32r0_delay=False)

  File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 499, in _connect_attempt

    self.sync()

  File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 438, in sync

    timeout=SYNC_TIMEOUT)

  File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 376, in command

    self.write(pkt)

  File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/esptool\esptool.py", line 339, in write

    self._port.write(buf)

  File "C:/Users/ab/AppData/Local/Arduino15/packages/esp8266/hardware/esp8266/3.0.2/tools/pyserial\serial\serialwin32.py", line 325, in write

    raise SerialTimeoutException('Write timeout')

serial.serialutil.SerialTimeoutException: Write timeout

the selected serial port serial.serialutil.SerialTimeoutException: Write timeout

 does not exist or your board is not connected

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

title: Nodemcu Lolin v3 Timeout error

Answers: 0


body:
i brought a rfid module which is rc 522 but when i upload the code it is not reading the card  even when i upload example code i have returned it 2 times and got it replaced but the same problem may i know the solution

    #include "SPI.h" // SPI library
    #include "MFRC522.h" // RFID library (https://github.com/miguelbalboa/rfid)

    const int pinRST = 9;
    const int pinSDA = 10;

    MFRC522 mfrc522(pinSDA, pinRST); // Set up mfrc522 on the Arduino

    void setup() {
      SPI.begin(); // open SPI connection
      mfrc522.PCD_Init(); // Initialize Proximity Coupling Device (PCD)
      Serial.begin(9600); // open serial connection
    }

    void loop() {
      if (mfrc522.PICC_IsNewCardPresent()) { // (true, if RFID tag/card is present ) PICC = Proximity Integrated Circuit Card
        if(mfrc522.PICC_ReadCardSerial()) { // true, if RFID tag/card was read
          Serial.print("RFID TAG ID:");
          for (byte i = 0; i < mfrc522.uid.size; ++i) { // read id (in parts)
            Serial.print(mfrc522.uid.uidByte[i], HEX); // print id as hex values
            Serial.print(" "); // add space between hex blocks to increase readability
          }
          Serial.println(); // Print out of id is complete.
        }
      }
    }
this is one of the many codes i used

title: rfid module not working (rc522)

Answers: 0


body:
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() {
}
```

title: Keyboard.h not found on Arduino nano

Answers: 1

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.


body:
I am using ESP32 classic Bluetooth Feature for data transfer. I am using the SerialToSerialBT example. I am able to scan and discover the Bluetooth device from my smartphone. But the pairing is without any security/passcode. It simply pairs immediately. How to make the pairing using PIN/Passkey entry?

**Hardware**: ESP32 DEV Kit V1

**Software** Arduino IDE

**Code:**

    #include "BluetoothSerial.h"

    #if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
    #error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
    #endif

    BluetoothSerial SerialBT;

    void setup() {
      Serial.begin(115200);
      delay(5000);
      Serial.println("Starting..");
      SerialBT.begin("MyESP32"); //Bluetooth device name
      Serial.println("The device started, now you can pair it with bluetooth!");

    }

    void loop() {
      if (Serial.available()) {
        SerialBT.write(Serial.read());
      }
      if (SerialBT.available()) {
        Serial.write(SerialBT.read());
      }
      delay(20);
    }

title: ESP32 Classic Bluetooth Set Password

Answers: 0


body:
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.
    }

title: LCD displays more digits than serial monitor

Answers: 1

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("    ");`).


body:
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

title: need help for exam please (deadline tomorrow)

Answers: 1

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.
}
```


body:
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

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

Answers: 1

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());
  }
}
```


body:
I am working on modifying code to control two DC motors with a joystick using Arduino. The code I have works, but the motor accelerates very rapidly and is difficult to control. I would appreciate any help or pointers to get the motor under control. Here is the code I have so far:

    const int ledPin = 3; //Led to Arduino pin 3 (PWM)

    //Variables
    bool started= false;//True: Message is started
    bool ended  = false;//True: Message is finished
    char incomingByte ; //Variable to store the incoming byte
    char msg[3];    //Message - array from 0 to 2 (3 Drive_Analog_Values -PWM - e.g. 240)
    byte index;     //Index of array
    bool started1= false;//True: Message is started
    bool ended1  = false;//True: Message is finished
    char msg1[3];    //Message - array from 0 to 2 (3 Drive_Analog_Values - PWM - e.g. 240)
    byte index1;     //Index of array
    bool started2= false;//True: Message is started
    bool ended2  = false;//True: Message is finished
    char msg2;
    bool started3= false;//True: Message is started
    bool ended3  = false;//True: Message is finished
    char msg3;
    int Fwd_Drive = 0;
    int Rev_Drive = 0;
    int Left_Turn = 0;
    int Right_Turn = 0;
    char Dump = '0';
    char Retract = '0';

    void setup() {

    //setup interrupts
    cli();//stop interrupts

    //set timer1 interrupt at 1Hz
      TCCR1A = 0;// set entire TCCR1A register to 0
      TCCR1B = 0;// same for TCCR1B
      TCNT1  = 0;//initialize counter value to 0
      // set compare match register for 1hz increments
      OCR1A = 15624;// = (16*10^6) / (1*1024) - 1 (must be <65536)
      // turn on CTC mode
      TCCR1B |= (1 << WGM12);
      // Set CS10 and CS12 bits for 1024 prescaler
      TCCR1B |= (1 << CS12) | (1 << CS10);
      // enable timer compare interrupt
      TIMSK1 |= (1 << OCIE1A);

     sei();//allow interrupts

      //Start the serial communication
      Serial.begin(9600); //Baud rate must be the same as is on xBee module
      pinMode(ledPin, OUTPUT);
      pinMode(13, OUTPUT);
      pinMode(2, OUTPUT);
      pinMode(4, OUTPUT);
      pinMode(10, OUTPUT);
      pinMode(5, OUTPUT);
      pinMode(6, OUTPUT);
    }

    ISR(TIMER1_COMPA_vect){ //timer1 turns off all values every 1 second
       analogWrite(5, 0);
       analogWrite(6, 0);
       analogWrite(9, 0);
       analogWrite(10, 0);
       digitalWrite(2,LOW);
       digitalWrite(4,LOW);
    }

    void loop() {
      //digitalWrite(13, LOW); //Debug LED
      while (Serial.available()>0){
      //Read the incoming byte
      incomingByte = Serial.read();
      //digitalWrite(13, HIGH);//Debug LED
      //Start the message when the '<' symbol is received
      if(incomingByte == '<'){
       started = true;
       index = 0;
       msg[index] = '\0'; // Throw away any incomplete packet
      }

      //End the message when the '>' symbol is received
      else if(incomingByte == '>'){
       ended = true;
       break; // Done reading - exit from while loop!
      }
      //Read the message!
      else{
       if(index < 4){ // Make sure there is room
        msg[index] = incomingByte; // Add char to array
        index++;
        msg[index] = '\0'; // Add NULL to end
       }
      }

      if(incomingByte == '['){
       started2 = true;
       msg2 = '\0';
      }
      else if(incomingByte == ']'){
       ended2 = true;
       break; // Done reading - exit from while loop!
      }
      //Read the message!
      else{
       msg2 = incomingByte;
      }
          if(incomingByte == '{'){
       started3 = true;
       msg3 = '\0';
      }
      else if(incomingByte == '}'){
       ended3 = true;
       break; // Done reading - exit from while loop!
      }
      else{
       msg3 = incomingByte;
      }
     }

     if(started && ended){//Driving Logic
      int Drive_Analog_Value = atoi(msg);
      //analogWrite(ledPin, Drive_Analog_Value);//Only for debugging
      //Serial.println(Drive_Analog_Value); //Only for debugging
      if(Drive_Analog_Value>130){
       Rev_Drive = 0;
       Fwd_Drive = map(Drive_Analog_Value, 131, 255, 0, 70);
      }
      else if(Drive_Analog_Value<124){
       Fwd_Drive = 0;
       Rev_Drive = map(Drive_Analog_Value, 0, 123, 70, 0);
      }
      else{
       Fwd_Drive = 0;
       Rev_Drive = 0;
      }
      analogWrite(5, Fwd_Drive);
      analogWrite(6, Rev_Drive);
      index = 0;
      msg[index] = '\0';
      started = false;
      ended = false;
    }

title: Controlling DC motor with joystick using Arduino

Answers: 0


body:
I use a Robotdyn, uno+wifi r3 atmega328p+esp8266. I need to control motor speed and operate few servos. Since the uno has a single timer, I use the esp8266 pin 2 to control motor speed, while the arduino pins to control servos.

I've used the serial channel for uno to send a list of speeds to operate the motors to the esp.
Now I need to trigger esp to change from one speed to another, and I was considering using one of the uno pins to trigger an interrupt for the esp, for this notification. I need the speed change as instantaneous as possible. I am using I2C 5v to 3.3v logic level converter for raising the interrupt from uno pin to pin 4 of esp.

Now the question, how long should I hold the uno pin high for the interrupt to be detected? A quick filp;
digitalWrite(outGoingIntrPin, HIGH);
digitalWrite(outGoingIntrPin, LOW);

seems to sporadically work. I think I need to introduce a delay between these statements, but I do not know how much should that delay be.

Any suggestions to improvise is welcome.

title: Robotdyn esp8266 interrupt from arduino timing

Answers: 0