# Question
Title: Error saving SPIFFS on ESP8266 - only after 3rd entry
**EDIT1** \- This phenomena occurs only after reboot using button or `ESP.reboot()`

I'll try to make my question more focused:

1. I have library that saved log events to SPIFFS.
2. From 3rd entry (in the following example - epoch clock entries), it saves wrongly somehow (jump to **Take-4** below).
3. Following code is an example using only relevant functions from that library.

Quick explanation:

`T` is holding epoch clock, that stores it right after boot.

`write(const char *message, bool NOW)` function - gets a message to store, and a boolean `NOW` if it has to be saved immediately rather than delayed save (delayed saved is implemented only in library, while here it gets saved instantly.)

`void _write2file()` writes the buffer to SPIFFS.

`int getnumlines()` returns number of entries saved (seeking for `_EOL` chars). In code below it acts as information only that serves displaying the problem, while when used in real library code, it limits the number of entries of the log.

`void rawPrintfile()` prints in human readable manner log's contents.

And last, the only function which does not belong to the library, `void insert_log_entry()`, simply enter a log entry (always the same one, after reboot).

**Take 1**-After uploading the sketch, you get this result on:

```
19:58:00.125 -> add buffer #0: 1234567890

19:58:00.191 -> total Lines before: 0
19:58:00.191 -> entries in buffer: 1
19:58:00.257 -> ~~~ Saved in /logfile.txt ~~~
19:58:00.257 -> row #0 {1234567890}
19:58:00.257 -> ~~~ EOF ~~~

```

Explanation: there was 1 entry to buffer, no- entries before, and a printout of file contents. So far- OK!

**Take 2** \- Pressing reboot button, and results are:

```
19:58:07.747 -> Start!
19:58:07.814 -> add buffer #0: 1234567890

19:58:07.814 -> total Lines before: 1
19:58:07.814 -> entries in buffer: 1
19:58:07.814 -> ~~~ Saved in /logfile.txt ~~~
19:58:07.814 -> row #0 {1234567890}
19:58:07.814 -> row #1 {1234567890}
19:58:07.814 -> ~~~ EOF ~~~

```

Explanation:again 1 entry in buffer, 1 entry in log, and a printout of 2 entries.

**Take 3** Pressing reboot button again, and results are:

```
19:58:10.167 -> Start!
19:58:10.200 -> add buffer #0: 1234567890

19:58:10.200 -> total Lines before: 2
19:58:10.233 -> entries in buffer: 1
19:58:10.233 -> ~~~ Saved in /logfile.txt ~~~
19:58:10.233 -> row #0 {1234567890}
19:58:10.233 -> row #1 {1234567890}
19:58:10.233 -> row #2 {1234567890}
19:58:10.233 -> ~~~ EOF ~~~

```

Explanation: same, but now 3 entries are saved.

**Take 4!!!**

```
19:58:11.194 -> Start!
19:58:11.227 -> add buffer #0: 1234567890

19:58:11.227 -> total Lines before: 2
19:58:11.260 -> entries in buffer: 1
19:58:11.260 -> ~~~ Saved in /logfile.txt ~~~
19:58:11.260 -> row #0 {1234567890}
19:58:11.260 -> row #1 {1234567890}
19:58:11.260 -> row #2 {12345678⸮⸮⸮1234567890}
19:58:11.260 -> ~~~ EOF ~~~

```

Explanation: Now here is the unsolved error- 4th entry gets mixed up with 3rd, causing it to count only 2 entries (where it had to be 3), and row #2 is now mixed.

In purpose - I simplified the code to focus on the problem itself, which I can't find it root cause for this error (rather that showing entire library , consisting delayed save and delete line function, when log gets full).

\`

```
#include <FS.h>
unsigned long T = 1234567890;

char *_logfilename = "/logfile.txt";
int _buff_i = 0;
#define TEMP_LOG_SIZE 10
#define TEMP_LOG_LEN 150
int _logSize = TEMP_LOG_SIZE;                 // entries
int _logLength = TEMP_LOG_LEN;                // chars in each entry
char _logBuffer[TEMP_LOG_SIZE][TEMP_LOG_LEN]; // Temp buffer for delayed write
const char _EOL = '\r';
unsigned long lastUpdate = 0;

void insert_log_entry()
{
  char a[25];
  sprintf(a, "%d", T);
  write(a, true);
}
void rawPrintfile()
{
  int row_counter = 0;
  bool new_line = true;

  File file = SPIFFS.open(_logfilename, "r");
  if (!file)
  {

    Serial.println("Failed to open file for reading");
  }
  Serial.print("~~~ Saved in ");
  Serial.print(_logfilename);
  Serial.println(" ~~~");
  while (file.available())
  {
    if (new_line)
    {
      Serial.print("row #");
      Serial.print(row_counter++);
      Serial.print(" {");
      new_line = false;
    }
    char tt = file.read();
    if (tt == _EOL)
    {
      new_line = true;
      Serial.println("}");
    }
    else
    {
      Serial.print(tt);
    }
  }
  file.close();
  Serial.println("~~~ EOF ~~~");
}
int getnumlines()
{
  int row_counter = 0;

  File file = SPIFFS.open(_logfilename, "r");
  if (file)
  {
    while (file.available())
    {
      char tt = file.read();
      if (tt == _EOL)
      {
        row_counter++;
      }
    }
  }
  file.close();
  return row_counter;
}
void write(const char *message, bool NOW)
{
  sprintf(_logBuffer[_buff_i], "%s%c", message, _EOL);

  Serial.print("add buffer #");
  Serial.print(_buff_i);
  Serial.print(": ");
  Serial.println(_logBuffer[_buff_i]);
  _buff_i++;
  lastUpdate = millis();

  if (NOW == true)
  {
    _write2file();
  }
}
void _write2file()
{
  int num_lines = getnumlines();
  Serial.print("total Lines before: ");
  Serial.println(num_lines);
  Serial.print("entries in buffer: ");
  Serial.println(_buff_i);

  File file1 = SPIFFS.open(_logfilename, "a");
  if (!file1)
  {
    Serial.println("Failed to open file for appending");
  }
  else
  {
    for (int x = 0; x < _buff_i; x++)
    {
      file1.print(_logBuffer[x]);
    }
    _buff_i = 0;
    lastUpdate = 0;
  }
  file1.close();
}

void setup()
{
  Serial.begin(115200);
  Serial.println("\n\nStart!");
  SPIFFS.begin();
  insert_log_entry();
  rawPrintfile();
}

void loop()
{
  delay(50);
}

```

# Answer
Well , getting to answer was complicated.

1. It happens only after reboot ( button, or `ESP.reset()` ), somehow after 2nd attempt, every time - getting this ( see `THIS`):

> ```
> 19:58:11.194 -> Start!
> 19:58:11.227 -> add buffer #0: 1234567890
>
> 19:58:11.227 -> total Lines before: 2
> 19:58:11.260 -> entries in buffer: 1
> 19:58:11.260 -> ~~~ Saved in /logfile.txt ~~~
> 19:58:11.260 -> row #0 {1234567890}
> 19:58:11.260 -> row #1 {1234567890}
> 19:58:11.260 -> row #2 {12345678⸮⸮⸮1234567890}   <----- THIS ----
> 19:58:11.260 -> ~~~ EOF ~~~
>
> ```

2. @Peter, in comments referred for github issue , that pointed out that there is a known problem regarding reboots and validity of data stored. Issue was solved by using `file.flush()` \- but this solution **did not solve the problem**
3. When searching ESP8266 core, it pointed out an erros SPIFFS\- regarding data saved and it validity
4. only after updating `LittleFS` for all instances in code (somehow when checked as part of Peter's suggestion, only few instances were changed from `SPIFFS` ), solved that problem. no `file.flush()` or `delay()` is required.
> 0 votes

---
Tags: esp8266, spiffs
---


# Question
Title: Arduino UNO voltage supply reduces when I add more sensors
I have an Arduino UNO. When I connect an MQ-9 sensor or an ESP8266MOD WiFi chip, the LCD backlight drops that it doesn't display anything, the red LEDs on the Arduino board dims, and the voltage regulator begins to get hot.

I am using a 12V -- 1.5A DC supply to power the Arduino as the USB port only works for uploading sketches, it doesn't even power the Arduino when nothing is connected. What could be wrong?

NOTE: When I unplug the gas sensor, the Arduino board LEDs get brighter and the LCD too, it works fine with some other sensors like an LM35 or a flame sensor.

# Answer
You are overloading the Arduinos voltage regulator.

The Arduino uses a linear voltage regulator, which dissipates the excess voltages as heat.The higher the provided voltage, the lesser current you can draw from it (since it can only handle a specific power dissipation without a heatsink and power is voltage * current). If you have a genuine Arduino, the voltage regulator will go into thermal emergency shutdown, if you completely overload it. Most Arduino clones use a cheaper regulator, which will just burn out and possibly destroy the Arduino.

So if you require quite an amount of current (like the MQ-9 due to its heating element), you should buy an extra voltage regulator, in best case a switching "buck" regulator (since they are way more efficient than linear regulators). For example there are many rather cheap boards with a switching regulator, which take 12V and output a variable voltage controlled via a small potentiometer (which you can trim for 5V output).

> the USB port only works for uploading sketches, it doesn't even power the arduino when nothing is connected.

Then most likely you have already overloaded the diode, that is in the USB power path (for protecting the PCs USB port and helping with supply voltage selection). If the diode were fried and failed open, then the connection from USB positive power to 5V rail on the Arduino is no longer there. A genuine Arduino Uno should also have a polyfuse in the USB line, which can save you from drawing too much current. It should connect again, after you removed the devices, that draw too much power.
> 5 votes

# Answer
The MQ-9 has a heating preparation cycle that draws more than a third of a watt which is more power than the Arduino can supply via a pin if I remember correctly. Have you taken that into allowance? You can design the heater power to be triggered by the Arduino without overloading the pin (e.g, using a transistor).

See https://electronics.stackexchange.com/questions/67092/how-much-current-can-i-draw-from-the-arduinos-pins

If your circuit already allows for the above it could also be a bad/shorted sensor? You could test it’s resistance with a multimeter and compare it to the data sheet.
> 0 votes

# Answer
You are using a lot more power than an arduino pin can supply. The gas sensor takes a lot of power which the arduino's pin supply of 5v and 200mA MAX cannot tolerate. So I would suggest you power the gas sensor using ur 12v Powersupply by creating a simple potential divider, using a buck converter or simply one of those cheap 7805 regulators. For any other power related queries you can refer this excellent article by BILL from Dronebot Workshop. Good Luck!!
> 0 votes

---
Tags: arduino-uno, sensors
---


title: Ethernet Shield not connecting

text:
# Question
Title: Ethernet Shield not connecting
I've mounted an Ethernet Shield on top of an Arduino UNO. The Arduino is connected via usb to my pc and to the network via ethernet through a switch. I'm running a simplified verison of the WebServer example and the function to Ethernet.begin() always returns EthernetNoHardware.

I've tried different setups changing the ethernet cables and connecting directly to the router. I also tried adding specific ip, gateway and subnet parameters to Ethernet.begin() however the output doesn't change and the server can't be reached:

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

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0F, 0xCC, 0x1E }; //mac address on the sticker
IPAddress ip(192, 168, 1, 134);
IPAddress gateway(192,168,1,1);
IPAddress subnet(255,255,255,0);
IPAddress DNSserver(192,168,1,1);
EthernetServer server(80);

void setup() {
  Ethernet.init(10);
  Serial.begin(9600);
  while (!Serial) {
    ;
  }

  Ethernet.begin(mac, ip, gateway, subnet);

  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield not found.");
  }

  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

```

output:

```
Ethernet shield not found.
server is at 192.168.1.134

```

Any idea on what the issue might be?

# Answer
> 1 votes
In your sketch DNS IP parameter is missing in `Ethernet.begin`.

It should be `Ethernet.begin(mac, ip, dns, gateway, subnet);`

---
Tags: arduino-uno, ethernet, web-server, ethernet-shield
---


# Question
Title: How to wire a three-pin on-off-on switch for reading input?
I would like to read the output of an on-off-on switch with my Leonardo board, but I have very little knowledge of electronics and don't know how to wire it up.

This is the switch in question: E-Switch 200MSP4T1B1M1QE

The switch has three pins. Generic three-pin SPDT wiring diagrams I've found suggest that the two outer pins should be connected to separate lights and the middle pin should be connected to the power source. Those lights also have a ground connection.

I don't want to power anything in a literal sense, I only want to have the Leonardo read the output of the switch. The end goal is to have the two ON positions read as separate button presses (eventually using a joystick library, in case that changes how the switch needs to be wired).

My questions are:

1. Is the above wiring example correct for my use case?
2. Is the output of the switch considered digital or analog?
3. Is a wire from the switch to GND not required?

One final note - I'm not using a breadboard, but connecting the wires directly from the switch to the board.

# Answer
> 5 votes
You talk about wiring a switch to control lights directly. Instead, you want to use your switch to send information to your Arduino.

You link to an SPDT (single pole, double throw) switch. When flipped one way, it connects the center pin to one of the outside pins, and when flipped the other way, it connects the center pin to the other outside pin.

If you want the Leonardo to read the state of the switch as 2 separate switches/button presses, wire the 2 outer pins of the switch to 2 separate digital inputs on the Arduino.

You need to force each input to either ground or +5V when it's not connected to anything, or it will "float" and you'll get semi-random high and low readings.

I suggest setting the Arduino input pins to INPUT\_PULLUP mode. That connects the inputs internally through a resistor to +5V. If you don't connect anything to the pin, it reads as HIGH. When the button is pressed/switch is closed, it reads LOW. That might seem a little confusing, but it means you don't need external resistors.

You'd then attach those to pins to the two outer pins of your switch, and attach the center pin to ground (GND).

If you flip the switch one way, it would connect one outer pin to the center pin. That would connect that Arduino pin to ground, and the reading on the pin would drop from HIGH to LOW. Flip the switch the other way and it would connect the other pin to ground, at that other pin would drop from HIGH to LOW.

It is also possible to wire your switches using INPUT mode, not INPUT\_PULLUP, and have them read LOW when the switch is open, and HIGH when closed, but to do that you'll need external pull-down resistors. (And wiring it will be a little painful without a breadboard or PC board.)

To answer your questions:

1. Is the above wiring example correct for my use case?

You don't show a wiring example. You talk about how to wire a switch to switch power to a pair of lights directly, without using a microcontroller. That's not relevant here.

2. Is the output of the switch considered digital or analog?

It would make sense to use it as a digital input, since you need it to give you 2 states, open and closed.

3. Is a wire from the switch to GND not required?

You need to connect the center pin to either ground +5V, as discussed above.

# Answer
> 4 votes
I suggest this simple circuit:

simulate this circuit – Schematic created using CircuitLab

Set both inputs to `INPUT_PULLUP`. If the input reads `LOW`, that means it has been grounded by the switch.

---

**Edit**: Per Duncan’s request, here is the alternative circuit with the polarities inverted. With the switch’s common connected to Vcc, the inputs should be set to `INPUT_PULLDOWN`. However, most Arduinos do not support this mode, for lack of internal pull-downs. Then one has to use external pull-downs instead, and set the pins to `INPUT`.

simulate this circuit

With this circuit, a pin reads `HIGH` when it is connected to +5V by the switch.

# Answer
> -1 votes
# Alternative Circuit

For the on-off-on switch, the MSP-3 and MSP-4 operate as follows:

*Figure 1 – Operation of MSP-3 and MSP-4 switches.*

| POS | Connection | MSP-3 | MSP-4 |
| --- | --- | --- | --- |
| 1 | Terminal 2 to Terminal 3 | ON | (ON) |
| 2 | Terminal 2 to open circuit | OFF | OFF |
| 3 | Terminal 2 to Terminal 1 | ON | (ON) |

Here is an alternative way to connect the SPDT to the MCU which is useful when running out of pins because it only requires one input pin. It does however require more complicated software to interpret the input e.g., hysteresis and debounce could be implemented with thresholds such as:

* \> 90% Vcc for \> 50 ms means high.
* \< 10% Vcc for \> 50 ms means low.
* \> 45% Vcc and \< 55% Vcc for \> 50 ms means OFF.
* anywhere in between means no change.

*Figure 2 – Connecting SPDT switch to MCU.*

# Throw vs Stop vs Contact

In normal parlance, a throw describes a physical action that moves a mechanism to a new mechanical stop; and throws are distinct from stops and contacts. As such, a switch is a transducer that converts physical movements (throws) to an electrical signal via a system of mechanical stops and electrical contacts.

From Figure 1, the totals are 2 throws, 3 positions, 2 contacts and 1 pole.

However, matters have been confused by a minority of people erroneously metamorphosing the term “throw” to mean “mechanical stop” or “electrical contact.” As you can see in this example—as is often the case—the number of throws equals the number of contacts, but that is not *always* the case. For example, if there were a centre contact for the centre stop, there would be three contacts, but still only two throws. Perhaps the fact that throws and contacts are often equal in number has led some people to conflate and confuse the separate entities. And perhaps that the number of stops can sometimes equal the number of contacts has led some people to conflate and confuse them too. For this kind of switch, the number of throws is always one less than the number of stops.

Matters are not helped by the E-Switch 200MSP4T1B1M1QE datasheet showing an incorrect schematic for the MSP-3, 4 and 5 that omits the centre mechanical stop that should be labelled OFF.

I’ve re-annotated the datasheet, Figure 3, and modified the following prose to comply with the common-sense approach of Figure 1, being mindful that a minority of people use “throw” to mean “contact,” and added the correct schematic for MSP-3, 4 and 5. (The original annotated version and prose was an attempt to use the datasheet’s own erroneous nomenclature and schematic.)

*Figure 3 – Annotated datasheet.*

MSP-1, 2 and 6 are actually single-throw switches despite what the datasheet implies which conflates its description of its SPST with its SPDT switches (which caused some confusion in the comments about the intent and variety of the switch).

The switch required for the above example is the MSP-3 on-off-on. Or to simulate momentary button presses, the MSP-4 (on)-off-(on). Both of these are single-pole double-throw switches (SPDT), not because they have 2 electrical contacts, but because they have 2 physical throws.

In the context of the erroneous datasheet, throws and contacts are erroneously synonymous. In normal parlance, neither throws nor positions are electrical contacts/terminals/pins (though the datasheet has conflated them as well). However, each mechanical stop does have an associated electrical connection/disconnection that should be explained in the datasheet. Unfortunately, in this case, the table in the datasheet has conflated SPST with SPDT and used the term “NONE” to indicate that a position doesn’t exist for the SPST types (MSP-1, MSP-2, and MSP-6). For MSP-3, 4, and 5, notice how POS 2 doesn’t have an associated contact/terminal/pin in the green schematic, Figure 3.

From experience, the only way to be sure is to buzz out the switch with a multimeter (continuity test). So, keep Figure 1 in your mind and a multimeter in your hand, and you won’t go far wrong.

# Conclusions

1. Throws are physical.
2. Stops are mechanical.
3. Contacts are electrical.
4. Claims such as, “My contact is a throw.” are delusional.
5. Conclusions can be lyrical.

# Phantom Scroll-By Downvoter

This answer has a attracted a phantom downvote with no comment expressing why this is warranted.

Does the phantom think:

1. the alternative circuit is wrong?
2. the thresholds are wrong?
3. the errant use of the English language and dodgy schematics in the datasheet are acceptable?

Bear in mind that the terms “throw,” “stop,” and “contact” (their meanings and usage) are taught by schoolteachers to millions of school children every year; and used by billions of English speakers every day. Is the global education system (which isn’t perfect) wrong on this particular point? On what grounds and exceptional circumstances is a datasheet allowed to use such terms in an inappropriate manner?

---
Tags: wires, switch, input
---


# Question
Title: Using MAX30100 SpO2 value to turn on LED
max30100 i2c sensor gives heartrate and spo2 reading in serial and also can show values in lcd display. I want to show it's indication via LED.

If SpO2 value \<94 , it will turn on Red led in digital pin 4

If SpO2 value \>=94, it will urn on Green led in digital pin 5

Here **pox.getSpO2()** gives the SpO2 value.

How can I use this value to toggle between two digital pin. I understand it's easier to read analog pin value for toggling but I am searching for guidelines how I2C values can be use for this condition.

Thank you.

Here is the minimalistic code of SpO2

```
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#define REPORTING_PERIOD_MS     1000

PulseOximeter pox;
uint32_t tsLastReport = 0;

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

    Serial.print("Initializing pulse oximeter..");

    if (!pox.begin()) {
        Serial.println("FAILED");
        for(;;);
    } else {
        Serial.println("SUCCESS");
    }
}

void loop()
{

    pox.update();

    if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
        Serial.print("SpO2:");
        Serial.print(pox.getSpO2());
        Serial.println("%");

        tsLastReport = millis();
    }
}

```

# Answer
> 2 votes
You've done all the hard work already by setting the sensor up and managing to read from it.

I'd define a constant for the SpO2 threshold near the top, and convenient names for the pins:

```
const uint8_t SpO2_threshold = 94;  // percent
const uint8_t red_pin = 4;
const uint8_t green_pin = 5;

```

Then set the pins to output mode in the `setup()` as usual. (Maybe set them both HIGH (or LOW) too in there, to indicate that no reading has been done yet.)

In the loop, inside the reporting section, simply grab the value and toggle the pins:

```
...
uint8_t spo2 = pox.getSpO2();
// Print it out to serial if needed, then:
if (spo2 < SpO2_threshold) {
  digitalWrite(green_pin, LOW);
  digitalWrite(red_pin, HIGH);
} else {
  digitalWrite(red_pin, LOW);
  digitalWrite(green_pin, HIGH);
}

```

---

A more involved version that pulses one LED (short on time, variable off time) depending on the value read from the sensor. It uses the same technique as the sensor reading timing (the one used in the "blink without delay" example).

Sensor readings are clamped (any value at or below `spo2_min` will result in the fasted blink time, over `spo2_max` the slowest). Then that range is mapped to a range of led off times. Don't use the values in this example, I'm not a medical doctor :-)

```
// pin mapping
const uint8_t led_pin = LED_BUILTIN;

// sensor readings (%)
const int spo2_min = 85;
const int spo2_max = 100;

// led timings (ms)
const unsigned long led_off_min = 50;
const unsigned long led_off_max = 5000;

unsigned long led_off_time = led_off_max; // variable off time
const unsigned long led_on_time = 50;     // fixed, short on time

// sensor reading timing (ms)
const unsigned long sensor_interval = 1000;

// led state
uint8_t led_state = LOW;

// "timer" state
unsigned long last_reading = 0;
unsigned long last_led_toggle = 0;

void setup() {
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, led_state);

  Serial.begin(9600);

  Serial.print("Initializing pulse oximeter..");
  if (!pox.begin()) {
    Serial.println("FAILED");
    for (;;);
  } else {
    Serial.println("SUCCESS");
  }
}

void loop() {
  pox.update();
  unsigned long current_millis = millis();

  /* sensor reading "timer" */
  if (current_millis - last_reading >= sensor_interval)
  {
    last_reading = current_millis;

    int spo2 = pox.getSpO2();

    // clamp reading to expected range
    int clamped = constrain(spo2, spo2_min, spo2_max);
    // map to off time range
    led_off_time = map(clamped,
                       spo2_min, spo2_max,
                       led_off_min, led_off_max);

    char buff[128];
    sprintf_P(buff, PSTR("reading: %d (%%) -> interval: %lu (ms)"),
              spo2, led_off_time);
    Serial.println(buff);
  }

  /* led toggling "timers" */
  unsigned long led_elapsed = current_millis - last_led_toggle;

  if ((led_state == LOW) && (led_elapsed >= led_off_time))
  {
    last_led_toggle = current_millis;
    led_state = HIGH;
    digitalWrite(led_pin, led_state);
  }
  else if ((led_state == HIGH) && (led_elapsed >= led_on_time))
  {
    last_led_toggle = current_millis;
    led_state = LOW;
    digitalWrite(led_pin, led_state);
  }

}

```

---
Tags: arduino-uno, programming, arduino-ide, sensors, relay
---


# Question
Title: Connecting an LCD when Pins A4 and A5 are Occupied
Recently I've been working on an automatic dog feeder dispenser (that dispenses by turning a screw attached to a stepper motor). Currently I have a Nema 17 connected to an L298N stepper driver which is connected to Arduino pins 9-12 and a DS1307 RTC connected to analog pins A4 and A5 (I would have a picture but the wiring is all over the place). I would like to connect a 16x2 LCD screen (with a potentiometer already on the back and 4 connecting pins) but from everything I've seen online, it also uses analog pins A4 and A5 which are occupied by the RTC. How would I go about connecting the LCD?

```
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <RTClib.h>
#include <SoftwareSerial.h>
#include <Stepper.h>

RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x3F , 16 , 2);
Stepper myStepper(200 , 9 , 10 , 11 , 12);

void setup() {
  lcd.init();
  lcd.print("yes");
  Wire.begin();
  Serial.begin(9600);
  rtc.adjust(DateTime(2021 , 7 , 15 , 3 , 23 , 0));
  myStepper.setSpeed(100);
}

void loop() {
  DateTime now = rtc.now();
  Serial.print(now.hour());
  Serial.print(":");
  Serial.print(now.minute());
  Serial.print(":");
  Serial.print(now.second());
  Serial.println(" ");

  lcd.print(now.hour());
  lcd.print(":");
  lcd.print(now.minute());
  lcd.print(":");
  lcd.print(now.second());
  lcd.println(" ");

  if ((now.hour() == 7 and now.minute() == 0 and now.second() == 0)) {
    myStepper.step(1000);

}
  delay(1000);

}

```

# Answer
As mentioned in the comments: Your LCD and the RTC both use the I2C bus for communication. That bus is designed to have many devices simultaneously connected. For this to work every slave device on the bus (the Arduino is the master device, which has no address) has to have a unique address. In your code you write, that the LCD is on address `0x3F`. The RTC DS1307 is `0b1101000` or `0x68` (same value in binary or hexadecimal representation) (see the DS1307 datasheet, page 12).

So you can connect both devices to the same pins, as the communication interface there already supports that. The pins A4 and A5 are the I2C pins of the Arduino, so you need to connect them there for using the Arduinos I2C hardware.
> 1 votes

# Answer
Here are my 2 cents. As the other answer suggests, you can always use the same I2C lines for devices. The devices will be differentiated via an I2C address. I have compiled one example based on your code. Here is the link to the simulation

**The code is below**

```
#include <Wire.h>
#include "LiquidCrystal_I2C.h"
#include <RTClib.h>

RTC_DS1307 rtc;

LiquidCrystal_I2C lcd(0x27, 16, 2);

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

  if (! rtc.begin())
  {
    Serial.println("Couldn't find RTC");
    Serial.flush();
    abort();
  }

  lcd.init();
  lcd.backlight();
  lcd.print("yes");
}

void loop() {
  DateTime now = rtc.now();
  Serial.print(now.hour());
  Serial.print(":");
  Serial.print(now.minute());
  Serial.print(":");
  Serial.print(now.second());
  Serial.println(" ");

  lcd.setCursor( 0,0);
  lcd.print(now.hour());
  lcd.print(":");
  lcd.print(now.minute());
  lcd.print(":");
  lcd.print(now.second());

  if ((now.hour() == 7 and now.minute() == 0 and now.second() == 0)) {
    // myStepper.step(1000);
  }

  delay(1000);
}

```

As you can see, I2C lines are shared between the RTC module and the LC display module.
> 1 votes

---
Tags: arduino-uno, lcd
---


title: Arduino UNO won't move servo

text:
# Question
Title: Arduino UNO won't move servo
I have a simple MG996 servo motor and I am trying to make it move with my Arduino Uno. I tried different ways of wiring but nothing seems to work as fully expected.

For the wiring I followed this video: https://www.youtube.com/watch?v=b\_xvu6wWafA and at 9:02 min the guy is showing how the wiring is done. As you can see in my photo, I have done the same thing (as you can see in the "my wiring" picture), with an external battery pack and everything but my code still does not work. No errors or anything, compiles and uploads perfectly. The code I was trying to execute is:

```
#include <Servo.h>

Servo myservo;

void setup() {
  myservo.attach(8);
}

void loop() {
  myservo.write(0);
  delay(1000);
  myservo.write(90);
  delay(1000);
}

```

This code is essentially trying to move the servo from 0 to 90 degrees back and forth. The pin is the correct one (#8). The arduino is receiving the right code (because I tried it with exemplary ones).

Important note: One thing I tried, however, was to not even have an external battery pack. Just connect the wires like so but instead of the 2 GNDs, only 1 GND and 1 +5V pin. That way I was able to move the servo only forward but never backwards! And every time I wanted to move it I had to write a higher degree value.

So the question is, is my wiring bad? I must be missing something.

Photos:

# Answer
You have not connected the supply pin properly. here is the connection diagram for the standard basic Arduino example I also verified this on the video you have linked. Connect the 5V and you should be good to go.

https://wokwi.com/arduino/projects/306894988845777472
> 5 votes

---
Tags: arduino-uno, servo, pins, wires
---


title: How to switch 12V with esp32?

text:
# Question
Title: How to switch 12V with esp32?
Hello i want to switch electric door lock (12V, 170mA) with esp32(3.3V). If is it possible I want use tranzistor. I tried to use IRF520, but it only worked with 5V. My sugestion is use 2 tranzistors one would switch 5V to IRF520 which would switch 12V. Can someone pro provide me some schematic, how to solve it? Thanks.

# Answer
BC549 provides strong pull-down for IRFR5305, which is provides up to +12V at 16A with less than 0.09 Ohm channel resistance.

This circuit works well with ESP8266, I use it in some of my devices.

Don't forget about placing the flyback diode (EEV Blog, Wiki) in reverse polarity, parallel to the magnet. Place it as close as possible to the magnet!
> 6 votes

# Answer
A single, reasonably tough general purpose BJT is all you need here if you really want a simple solution. The 2N4401 supports up to 600mA of current and has a 40V Vce max. As long as the solenoid on the door lock has a snubber it doesn't need to be any more complicated than this unless you need isolation or have other constraints.

Note that below I've drawn a relay because it was easy, but you can just as well put your door lock's solenoid coil where the relay is drawn below (they're effectively the same type of device).

I have exactly this setup on an ESP8266 controlling a 24V relay and it works great. I'm using an old 2N2222, which are long since obsolete, but the 2N4401 would do just the same.
> 3 votes

---
Tags: esp32, switch
---


# Question
Title: How to send data from one Arduino to another isolated?
I have no experience about serial communications, with that being said; I have two circuits isolated from each other and each have a ATMEGA8 reading a voltage on their ADC.

I want one of them to send ADC data to another without having a common ground. I know that I can do it with a Bluetooth or Wi-Fi "module" but I'm looking for an easier way, like maybe with an optocoupler but again I'm not aware of the limits.

* What's the cheapest and simplest way to do this? and basically how it's done?

There's a lot of information about making two Arduinos talk to each other but I couldn't find much information/documentation on isolated communications.

# Answer
> 2 votes
\[Consolidating an answer from the comments\]

A wired connection using Optical isolation (aka Optocouplers) is the recommended way to solve this problem.

There are tutorials available online regarding optical isolation (e.g., https://www.electronics-tutorials.ws/blog/optocoupler.html; https://bestengineeringprojects.com/interfacing-optocoupler-with-arduino/).

One (of many) possible example circuit was noted as:

---
Tags: adc, serial-data, data
---


title: ESP32 powered for atleast a year

text:
# Question
Title: ESP32 powered for atleast a year
How to power esp32 board this one with soil humidity sensor that sends data to server via wifi every 30 minutes for something around a year on battery? What battery type and capacity should I use for that? Or is there any better board you would recommend for this pourpouse? The setup will be indoors.

# Answer
> 1 votes
Okay, let's do some calculations.

Assume that device sends data for 5 seconds (turn on, connect to the Wi-Fi, and so on) and drains (according to the docs) about 0.2A.

So, it works for 5 (secs) * 48 (turn-on's) / 60 minutes per day for 365 days.

So, it works for 5 * 48 / 3600 hours per day for 365 days.

So, it works about 24 hours per year.

0.2A for 24 hours is 4.8A for 1 hour.

Assume that efficiency of the power regulator is 80%

4.8 - 80 % X - 100%

X = 6 A\*h

So, take three (to compensate self discharge and have some headroom) standard Li-Ion cells, or mid-size (about 8000 mAh) power bank, and you well be fine.

But you shall add some external clock (powered by own CR2032 cell), that will be turn power regulator and esp-device ON every 30 minutes.

---
Tags: power, wifi, esp32, battery
---


# Question
Title: DFPlayer Mini with its standard library does not being initialized
I have a DFPlayer Mini bought from AliExpress. The player works correctly in standalone mode, but I am having troubles while using it with the following components:

* Seeduino v4.0;
* 2GB Smartbuy MicroSD card.

When I try to use this standard sketch for Arduino to connect my Seeeduino V4 to the player:

* if I set the serial like `mySoftwareSerial(11, 10)`, the player's tiny LED turns on for 2 seconds, then it switches off, and after that, the board tells me the error message below (video here);
* if I set the serial like `mySoftwareSerial(10, 11)`, the player\`s tiny LED switches on and remains being switched on, while the board tells me the error message below (video here):

```
DFRobot DFPlayer Mini Demo
Initializing DFPlayer ... (May take 3~5 seconds)
Unable to begin:
1.Please recheck the connection!
2.Please insert the SD card!

```

This module's image:

The circuit diagram:

simulate this circuit – Schematic created using CircuitLab

I have tried almost everything I could. I changed the filenames on my SD card, tried to use different pins, tried to use different wires..! I even tried to disconnect the speaker from the player!

I also had seen this message on the manufacturer\`s forum:

> I found that the solder joint on the TX pin was bridged to the SD card holder, effectively bridging the pin to the ground. Try a continuity test between the TX and ground. If they are connected you have a bad joint. I was able to remove the excess solder and it worked fine after that. It's a medium difficulty soldering task.

Maybe, it\`s my case?

# Answer
Please check if the `RX`/`TX` pins are messed up. In my case, simply `RX` and `TX` wires' places' switching did help!
> 1 votes

# Answer
I simply removed the test for the return value of the constructor and assumed it initialised correctly. It then ran properly every time I started it. I have no explanation for this, but it worked.
> 1 votes

---
Tags: debug
---


title: GPS module not working with sensor

text:
# Question
Title: GPS module not working with sensor
I am connecting my Soil Moisture Temperature Sensor SHT10 with GSM Module SIM900A and GPS GY-GPS6MV2. Individually, all components work properly and give proper values. But when I interface all three components with Arduino, only Temperature sensor seems to work and GPS does not give any values. Even If I connect only SHT10 and GPS with Arduino Uno (without GSM), only SHT10 gives values but GPS doesn't.

My code is:

```
#include <AltSoftSerial.h>
#include <TinyGPS++.h>
#include <SHT1x.h>

AltSoftSerial gpsSerial (11,12);

TinyGPSPlus gps;

#define dataPin 6
#define clockPin 7
SHT1x sht1x(dataPin, clockPin);
float TEMP, HUMID;

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

void loop()
{
TEMP = sht1x.readTemperatureC();
HUMID = sht1x.readHumidity();
Serial.println(TEMP);
Serial.println(HUMID);
gps_value();
}

void gps_value()
{
while(gpsSerial.available())
{
gps.encode(gpsSerial.read());
}

if(gps.location.isUpdated())
{
Serial.println("Latitude: ");
Serial.println(gps.location.lat());
Serial.println("Longitude: ");
Serial.println(gps.location.lng());
Serial.println("Altitude Feet: ");
Serial.println(gps.altitude.feet());
Serial.println("Horizontal Dilution of Precision: ");  //lower the better
Serial.println(gps.hdop.value());
Serial.println("");
}
}

```

What is happening here ?

Datasheet of SHT10

# Answer
> 1 votes
As already mentioned this seems to be a current related problem. You are powering your Arduino over Usb. The sensors themselves do work fine. Yet connecting all of them seems to draw too much current so they won’t work properly. (See this post for more information on current.

# Answer
> 0 votes
You could have used SoftwareSerial instead of AltSoftSerial.Since you are using AltSoftSerial please go through its library file to check how you need to deal with it. For Software Serial you need to use predefined Rx , Tx pins of Arduino rather than defining any other pins of it for Rx,Tx for connecting those to Rx Tx of tempterature sensor. For GPS try to define any 2 pins of Arduino as Rx Tx so that you can connect them to Rx Tx of GPS.Hope this helps you.

---
Tags: arduino-uno, gps, temperature-sensor, tinygps
---


# Question
Title: How do I use a 3 legged phototransistor?
I have searched the Internet and found the following circuit to use with my phototransistor but it is not working, I can say so because all analog input i get is 1023 even if i have covered it totally, I have include the phototransistor and the diagram can anyone tell why is it not working! I used this webpage to check my sensor and it works-I used this page

I have used 10kohm resistor.

This is my phototransistor

# Answer
> 1 votes
A reasonably generic data sheet is **HERE**
That is for an AT156 but yours may be an AT138/HT138 based on an ad some years ago from the same seller when they said they had 10,000 for sale.

Basic information here and more in the data sheet.

# Answer
> 1 votes
First that is not even a photo resistor 2nd you have to put one wire positive and the other negitive and the last one plug it into any other gpio pin

---
Tags: arduino-uno, sensors, transistor
---


# Question
Title: Arduino Hanging Not sure if software or hardware issue
I am trying to run a very simple program to glow LEDs in a certain fashion, I connected 9 LEDs to the GPIOs or digital pins, 2 To 10, via 220 Ohm resistors; when I am running the program it is hanging the Arduino after some time interval and LEDs stops glowing, not sure if it is a hardware issue or some bug in the software/code.

Here is the code:

```
int outGPIOsarr[9] = {2,3,4,5,6,7,8,9,10};

void setup() {

  for(int i=0; i<10; i++)
pinMode(outGPIOsarr[i], OUTPUT);
}

void loop() {

for(int i=0; i<10; i++)
 {
digitalWrite(outGPIOsarr[i],HIGH);
delay(10);
 }

for(int i=0; i<10; i++)
 {
digitalWrite(outGPIOsarr[i],LOW);
delay(10);
 }

}

```

# Answer
This is the UB!

The indexes in array in `C++` counts from `0`;

So, the last index in your array of `9` elements is **`8`**.

All cycles must stop at **`8`**. Yours are stops at `9`.

Access beyond the existing element in the array is the Undefined Behavior - it hangs the MCU.
> 3 votes

---
Tags: arduino-uno, led, debug
---


title: Nodemcu POST Response "-1"

text:
# Question
Title: Nodemcu POST Response "-1"
**Nodemcu** device is returning **HTTP response -1** for a **POST** request on django rest api.

I tried the below http request to **Postman**, and it works perfectly fine.

http://localhost:8000/api/datalogs/?plant=http://localhost:8000/api/plants/1/&light=23&temperature=24&humidity=75&soil=Dry&moisture=787&remarks=/

This is my arduino post request:

```
if(WiFi.status() == WL_CONNECTED) {
    HTTPClient http;

    http.begin(host_url);

    http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    httpCode = http.POST(postData);

    payload = http.getString();
    http.end();
}

```

The expected result is **200**, but I get **-1**. Can someone please explain?

# Answer
So, I found the solution. It was a very simple mistake. The **NodeMCU IP** is not the same as the **Computer IP** that the server was running on.

I changed the **localhost** string with the IP of my pc, and it worked perfectly fine.
> 1 votes

---
Tags: nodemcu, web-server
---


# Question
Title: İs that possible to a function return String OR Int depends on address
Well, I'm trying to use a HMI display and this HMI storing datas in separeta addreses. Such as integers addr. is between 0x80000 to 0x9ffff and also for string's addr is between 0 to 0x1ffff.

**At this point I want to make function which is return integer if addr is a integer addr OR it will return string if addr is String addr. is that possible to make two kind of return type for a method.**

I will detect integer or string from addr value like this:

```
????    HMT_SendCMD_ReadVPN16(INT32U Addr)

if((Addr > 0x00080000) || (Addr < 0x0009FFFF))
    {
        return int (); // at here it call a fonction and it will return integer
    }

else if(Addr < 0x0001FFFF)
    {
         return String (); // at here it call a fonction and it will return String
    }

```

# Answer
> 3 votes
> is that possible to make two kind of return type for a method

No. Functions are *declared* with a single return type. What is the point anyway of returning a blank string?

You need to redesign.

# Answer
> 0 votes
If the task were to store something different at the given address,

or if you would want to return a String representation of the integer,

you might be able to do so, but Majenko's comment and Nick's response, suggesting a different approach, are better.

---
Tags: arduino-uno, c++, string, functions
---


title: Swap Serial pins of ESP8266?

text:
# Question
Title: Swap Serial pins of ESP8266?
I have designed and manufactured a PCB which contains an ESP8266 (ESP-WROOM-02D) chip with the serial uart pins connected to a 30pin connector. I made a mistake on the layout (first time designing a PCB), and have the RX (Pin 3) and TX (pin 1) pins connected incorrectly (swapped).

Is there a way to switch these pins in software? There's no nice way to physically modify and I was hoping to not have to have the boards manufactured again if I can avoid it.

Thanks!

# Answer
> 1 votes
You could potentially still fix this by using `SoftwareSerial`.
Instead of using the hard-wired serial, you can create one in software and use any pins you'd like... Have a look at this github project.
This work-around however requires you to have two unused pins to assign to SoftwareSerial.

---
Tags: serial, esp8266, espressif
---


# Question
Title: Getting constant PWM value based on user input from serial monitor
I am trying to get a constant PWM value from the PWM pin based on the user input. For example: the user hits 1, the output PWM value is 100, if it is 2 the output would be 200. This will continue till the user enters a new number. The issue I am having with my code is when I enter a number, the output of the PWM goes to that value for about a second and then goes back to 0. Can you please let me know what I am missing?

// Sketch: Blinking two LEDs by user
int test_pin=2; // declare pin10 as ledpin
int PWMvalue; // variable to store the number of blinks
void setup()
{
  Serial.begin(9600);
}
void loop()
{
  Serial.println("What is the new speed?"); //Prompt User for Input
 while (Serial.available() == 0) {
    // Wait for User to Input Data
  }
  PWMvalue = Serial.parseInt(); //Read the data the user has input

  if (PWMvalue==0)
  {
    analogWrite(test_pin,0);
    }
    else if (PWMvalue==1)
    {
      analogWrite(test_pin,100);
      }
      else if (PWMvalue==2)
    {
      analogWrite(test_pin,200);
      }
      else if (PWMvalue==3)
    {
      analogWrite(test_pin,300);
      }
      else if (PWMvalue==4)
    {
      analogWrite(test_pin,400);
      }
      else if (PWMvalue==5)
    {
      analogWrite(test_pin,500);
      }
      else if (PWMvalue==6)
    {
      analogWrite(test_pin,600);
      }
      else if (PWMvalue==7)
    {
      analogWrite(test_pin,700);
      }
      else if (PWMvalue==8)
    {
      analogWrite(test_pin,800);
      }
      else if (PWMvalue==9)
    {
      analogWrite(test_pin,900);
      }
      else
    {
      analogWrite(test_pin,1023);
      }

  Serial.print("The user has choosen the number:");
  Serial.println(PWMvalue);
  Serial.println(" ");
}
```

# Answer
You wait for user input with a `while (Serial.available() == 0)`, the you read the input with `Serial.parseInt()`. parseInt will wait a second for digits. It will end on a non digit character or timeout and return the number corresponding to received digits. If no digits were received a 0 is returned.

Serial Monitor has Line end setting. If there is some line ending selected, it will send line ending character(s).

Your waiting loop `while (Serial.available() == 0)` will end on line ending character which followed the number processed in previous loop. `parseInt` will not find a digit so it times out after a second and returns a 0, which causes setting the PWM to 0.
> 3 votes

---
Tags: serial, analogwrite
---


# Question
Title: ESP32 OTA update over MQTT using "update.h"
I am trying to do OTA over MQTT using update.h library. I am publishing firmware file over MQTT in a specified chunk size. The file is receiving at ESP32 end. I am supplying the received data to `update.write`. In start ~150 packet are written successfully. But after that update.write started to give error **Wrong Magic Byte**.

Here is the code snippet which I am using inside ESP32

```
#include "mqtt_handler.h"
StaticJsonDocument <256> root;
uint8_t temp[100] = {0};
size_t length ;
void otaHandler(byte *msg, unsigned int len)
{
deserializeJson(root,msg);
String command = root["command"];
if (command.equals("ota.start"))
{
    Serial.println("OTA.START via MQTT");
    if (!Update.begin(UPDATE_SIZE_UNKNOWN))
    {
        Update.printError(Serial);
    }
}
else if (command.equals("ota.write"))
{
    Serial.println("OTA.WRITE via MQTT");
    memset(temp, 0, 100);
    length = root["length"];
    String data = root["data"];
    for (int i = 0; i < length; i++)
    {
        temp[i] = data[i];
    }

    Serial.println(data);
    if (Update.write(temp, length) != length)
    {
        Update.printError(Serial);
    }
}
else if (command.equals("ota.end"))
{
    Serial.println("OTA.END via MQTT");
    if (Update.end(true))
    {
        Serial.printf("Update Success \nRebooting...\n");
    }
    else
    {
        Update.printError(Serial);
    }
}
else
{
    Serial.println("Something went worng");
}
}
void callback(char* topic, byte* message, unsigned int length) {
otaHandler(message,length);
}

```

In this code `callback` is the method which is called when an MQTT message arrived.This is the relevant code, if required I can share the complete code.

Message send by python application looks like as below:

```
{"command" : "ota.start"}
{"command": "ota.write", "length": length, "data": data})
{"command" : "ota.end"}

```

Below is the snapshot of `data` send by Python application in above ota.write message:

Below is the snapshot how my firmware file looks like:

I am sharing this snapshot to show the data format in which I am publishing firmware file.

Below is the snapshot of serial monitor:

Please suggest me if I am missing something on this.

Thanks

# Answer
> 2 votes
You are just throwing an unparseable stream of ASCII decimal representations of the binary data at your code, then writing that ASCII data verbatim to the flash. That can never work.

Instead you need to pick an ASCII representation of your data that is actually parseable (I would suggest sticking to HEX representation and always 2 digits, so represent 0x6 as "06"), then when you receive a packet you must convert the content back into binary before sending it to the Update library.

As it is you take a byte (for example 0xE9) and convert that to ASCII decimal, which is 223. Then you write the 2, 2 and 3 as individual bytes to the flash as ASCII, resulting in 0x32,0x32,0x33 - or printing as decimal in an unparseable stream, 505051.

---
Tags: esp32, ota
---


title: "Stand-alone" serial monitor

text:
# Question
Title: "Stand-alone" serial monitor
I usually use Platformio as IDE for my Arduino projects. I like it as an editor, but I don't like its serial monitor feature. So I often open the Arduino IDE in background to use its serial monitor, but this has some drawbacks (including a significant increase in my computer's CPU usage and battery consumption).

Is there an Arduino-compatible serial monitor application that just works as a serial monitor (and not also as an IDE)? I'm most interested in a MacOS application, but if you know a Windows one please tell me as well.

# Answer
> 2 votes
I use CoolTerm, which is available for Mac, Windows and Linux. It is a great serial app, and you can have several windows open at the same, for each serial pipe you may be using (Bluetooth, Arduino Serial, etc).

# Answer
> 3 votes
Consider building your own monitor in Python. This gives you flexibility since Python is cross platform and you can tailor the monitor to your needs.

1. Install Python.
2. Install pySerial (`pip install pyserial`).
3. Write a Python script to read and/or write to the Arduino across the serial port. There are some great examples out there such as this example and other Stack Overflow answers.

# Answer
> 3 votes
On macOS, you can use the built-in `screen` command, e.g.:

```
screen /dev/cu.usbmodem14201 9600

```

To exit, `control`-`A` followed by `control`-`\`

# Answer
> 1 votes
There's a list of serial port sniffers here, if you want to view raw data

softwarerecs.stackexchange serial-port-logging

And a list here of programs which plot graphs from serial data:

softwarerecs.stackexchange serial-data-plotting-programs

---
Tags: serial, ide
---


# Question
Title: What is the REF pin for -- pin 9 on ATSAMD21G18-QFN48?
32-bit ARM-Based microcontroller SAM D21E / SAM D21G /SAM D21J

I have a Seeeduino XIAO PDF to schematic which uses a ATSAMD21G18-QFN48 chip. Pin D1 on the Seeeduino is pin 9 on the chip; which is labeled as `PA4/EIC/REF/AIN4/SCOM0PAD0/TC0`.

What would the `REF` pin be used for; and how would the pin be addressed in the code?

Based on this post is sound like it is ADC related.

There is no indication about this on the https://wiki.seeedstudio.com/Seeeduino-XIAO/ website. Only this image:

# Answer
PA04 pin can be a normal GPIO or a voltage reference pin (similar to VDDANA). So, the ADC input will be compared to this VREF pin in the application if needed. If you have configured it as GPIO, then it will behave as a normal IO pin. It depends on how you configure it.
> 1 votes

---
Tags: samd21g
---


title: Prevent flash cloning

text:
# Question
Title: Prevent flash cloning
I need a way to prevent someone from cloning code from arduino. Without protection it can be cloned with advdudees in 2 min. I'm using atmega328p chip on nano. In this state arduino acts as a handshake for windows program i need to protect. There is nothing special or of value on arduino, but the custom handshake. One arduino for one .exe file. All arduino code is uploaded from arduino ide.

I did research and here it is.

1. Lock fuse bits. As i understood once locked flash and eeprom cant be read. When they are unlocked flash and eeprom are erased. I need one more arduino to act as programator.
2. Use some other unique hard to copy module like rfid card or bluetooth/wifi mac address. This is bad because it takes too much pins on nano.
3. Subtly solder 2 digital pins and set one to output and other to input. If not connected break loop.
4. Usb hardware dongle licence. I have no idea how to create one and it seems like some relic of the past. Custom file system or something...

I'd like to keep arduino nano for deployment.

There is no internet involved. If program had access to internet i'd just use db.

Thanks in advance.

# Answer
Using the lock fuse bits is definitely the correct step here. Unlocking is not a problem, since the memory will be erased in that step and you cannot prevent reflashing anyway.

---

Very important note from Gerben in the comments:

> Note that setting the lock bits is pointless, while the Arduino bootloader is installed. The bootloader can still read out the program, even with the lock bits set. You'd have to remove the bootloader and upload the code using the ISP interface (ArduinoAsISP).

The lock bits only work for the ISP interface, which can be used to program the Arduino. The bootloader (which is part of the program on the Arduino) still can read the program memory (it has to, since it is executed from there). Thus to prevent someone from reading out the program through the bootloader, you need to remove the bootloader. Programming is then done just like you are setting the fuses: Through ISP (for example via a second Arduino).

---

You didn't include details on the handshake. An important attack route would be to just sniff on the Arduinos Serial interface. Unless your handshake itself is encrypted locking the Arduino will not prevent attackers from getting it.

There are encryption libraries for Arduino (like this one on github). Based on your thread model and the needed resources (since the Uno is rather constrained especially in RAM) you can choose a fitting library and a fitting encryption algorithm. One important attack route would be a replay attack, where the attacker just resends the serial data, that he recorded in the last successfull transmission. One way to prevent that would be a rolling code (like modern garage door openers often use). Or you can create One-Time-Passwords (for example by combining the handshake secret with a timestamp and encrypting/hashing that; you need synchronized time for that).
> 3 votes

---
Tags: arduino-nano, fuses
---


# Question
Title: Will the noise from a voltage regulator interfere with IR LEDs and receivers on an Atmega328? (Arduino Uno sketch)
I have a project which uses an IR LED and receiver to communicate with other Arduinos. I am using the Atmega328 out of the Uno, rather than the whole Arduino board and I need it to be battery-powered, so I need to use a voltage regulator to maintain 5V to the chip.

I want to avoid a linear regulator if I can, as they are inefficient, but I'm worried that the other types will cause too much noise on the output and it will interfere with the IR communication.

Should I be concerned about this or am I making a fuss about nothing, I can always use a linear one if I need to.

Thanks in advance.

# Answer
> 1 votes
I bought a switching mode voltage regulator (buck-boost) to test it and it works fine, I put a 10uF capacitor across the output to reduce noise but that was just a precaution - I don't know if it was necessary.

---
Tags: arduino-uno, atmega328, voltage-level, ir
---


# Question
Title: Digispark Rev.3 Kickstarter ATTiny85 using all 6 pins
i have some trouble to use i2c and the other pins at the same time.

im tring to control the attiny over i2c with a arduino and the attiny should control a 28byj-48 stepmotor.

i started to setup the i2c connection pin 0 and pin 2 is use for that. it is working fine but then i connected the stepmotor driver on pin 1,3,4,5 after connecting the 5 pin i lose my i2c connection.

here is the code from the attiny, nothing special

```
#include <TinyWireS.h>                // wrapper class for I2C slave routines

#define I2C_SLAVE_ADDR  0x29            // i2c slave address (38)
#define A 1
#define B 3
#define C 4
#define D 5
#define NUMBER_OF_STEPS_PER_REV 512

void setup(){
  pinMode(1,OUTPUT);
  pinMode(3,OUTPUT);
  pinMode(4,OUTPUT);
  pinMode(5,OUTPUT);
  TinyWireS.begin(I2C_SLAVE_ADDR);      // init I2C Slave mode
}

void loop(){
  byte byteRcvd = 0;
  if (TinyWireS.available()){           // got I2C input!
    byteRcvd = TinyWireS.receive();     // get the byte from master
    //Blink(byteRcvd);           // master must wait for this to finish before calling Wire.requestFrom
    //byteRcvd += 10;                                                    // add 10 to what's received
    //TinyWireS.send(byteRcvd);           // send it back to master

    //             Blink(1);                  // show we transmitted
  }
}

```

# Answer
> 3 votes
There is no such Digispark board as the Rev 3. There was going to be, but there was a mistake, so they went straight from Rev 2 to Rev 4. However unscrupulous Chinese counterfeiters are making "Rev 3" boards.

So... your mileage may vary since the components used on there could be of *any* dubious quality.

But to your problem: P5 is also the RESET pin. If the fuses on that chip are set correctly then it can be used as an IO port. But being a counterfeit, who knows what they set the fuses to?

But if you *do* change the fuses you will have to rely on the power-on reset (plugging it in) to trigger uploads.

# Answer
> 3 votes
As an addition to Majenko's answer I can report having used many of the "Rev.3" counterfeits, every single one came with *chip default fuses* thereby **reset enabled**.

You can set the RSTDISBL fuse with your Arduino, plus update the micronucleus bootloader in the process (freeing 0.4k).

Keep in mind setting this fuse will **disable ISP programming**, so you will need a working bootloader to reprogram the chip unless you revert it via HV programming.

---
Tags: i2c, attiny, attiny85, stepper-motor
---


# Question
Title: What is the best technique to design a 20 push button circuit
I will be controlling a robot with more than 10 motors which means I'll need 2 buttons each to control moving forward and backward. My controller is an Arduino mega. Is 1 pin = 1 button the best solution here? Or should I use another IC for this?

# Answer
For 20 buttons you can use a Keypad Matrix arrangement (plenty of examples online) where you would use only 9 pins (5 columns of 4 rows is 5+4 pins). It's slightly more involved that simple 1:1 buttons to pins, but thankfully there is a Keypad.h library that takes the hard work out of it for you.

If you want to be able to press multiple buttons at once you need to include diodes in your matrix to prevent "ghosting".

Nick Gammon has a great writeup on it here.
> 15 votes

# Answer
The example project below can control 16 switches. If you have a membrane keypad with 5 x 4 or 5 x 5 then you can meet your requirement.

I will shortly add an example of using shift registers to have multiple inputs (the main use case of shift registers is the same)

Link

---

Below is the example using **shift registers.** You need three shift registers as @Michael mentioned in his answer. Here is one example where you can control 32 switches maximum. You are only using 3 data pins and two power pins. This is the main application of the shift register. You don't have to do any selection, whenever you read the serial input data, you will automatically get the status of all the 32 switches in one Go.

Here is the **code**

```
// File : Cascade165.ino
//
// Version 1, 5 August 2021, by Koepel
//     Initial version.
// Version 2, 5 August 2021, by Koepel
//     Layout of the wiring made better.
// Version 3, 13 August 2021, by Koepel
//     Changed 'SCK' to 'clockPin'.
//
// Cascade of four 74HC165 shift-in registers.
// Only three pins are used on the Arduino board, to read 32 switches.
//
// Using the 74HC165 is safe, because a pulse to the Latch pin
// ('PL' on the 74HC165) will make a new start every time.
// In case of an error or a wrong clock pulse by noise,
// it synchronizes the data when inputs are read the next time.
//
// Based on:
//   (1)
//     Demo sketch to read from a 74HC165 input shift register
//     by Nick Gammon, https://www.gammon.com.au/forum/?id=11979
//   (2)
//     74HC165 Shift register input example
//     by Uri Shaked, https://wokwi.com/arduino/projects/306031380875182657
//
//

const byte latchPin = 9;        // to latch the inputs into the registers
const byte clockPin = 13;       // I choose the SCK pin
const byte dataPin = 12;        // I choose the MISO pin
uint32_t oldOptionSwitch = 0;   // previous state of all the inputs

const int pulseWidth = 10;      // pulse width in microseconds

void setup ()
{
  Serial.begin( 115200);
  Serial.println( "Turn on and off the switches");
  Serial.println( "Top row is switch 0 (right) to switch 7 (left)");
  Serial.println( "Second row is 8 to 15, and so on");

  pinMode( clockPin, OUTPUT);   // clock signal, idle LOW
  pinMode( latchPin, OUTPUT);   // latch (copy input into registers), idle HIGH
  digitalWrite( latchPin, HIGH);
}

void loop ()
{
  // Give a pulse to the parallel load latch of all 74HC165
  digitalWrite( latchPin, LOW);
  delayMicroseconds( pulseWidth);
  digitalWrite( latchPin, HIGH);

  // Reading one 74HC165 at a time and combining them into a 32 bit variable
  // The last 74HC165 is at the bottom, but the switches start numbering
  // at the top. So the first byte has to be shifted into the highest place.
  uint32_t optionSwitch = 0;
  for( int i=24; i>=0; i-=8)
  {
    optionSwitch |= ((uint32_t) ReadOne165()) << i;
  }

  for( int i = 0; i<32; i++)
  {
    if( bitRead( optionSwitch, i) != bitRead( oldOptionSwitch,i))
    {
      Serial.print( "Switch ");
      if( i < 10)
        Serial.print( " ");
      Serial.print( i);
      Serial.print( " is now ");
      Serial.println( bitRead( optionSwitch, i) == 0 ? "down ↓" : "up   ↑");
    }
  }

  oldOptionSwitch = optionSwitch;
  delay( 25);      // slow down the sketch to avoid switch bounce
}

// The ReadOne165() function reads only 8 bits,
// because of the similar functions shiftIn() and SPI.transfer()
// which both use 8 bits.
//
// The shiftIn() can not be used here, because the clock is set idle low
// and the shiftIn() makes the clock high to read a bit.
// The 74HC165 require to read the bit first and then give a clock pulse.
//
byte ReadOne165()
{
  byte ret = 0x00;

  // The first one that is read is the highest bit (input D7 of the 74HC165).
  for( int i=7; i>=0; i--)
  {
    if( digitalRead( dataPin) == HIGH)
      bitSet( ret, i);

    digitalWrite( clockPin, HIGH);
    delayMicroseconds( pulseWidth);
    digitalWrite( clockPin, LOW);
  }

  return( ret);
}

```

Link to the shift register project: https://wokwi.com/arduino/projects/306024460940476993
> 4 votes

# Answer
you can use a so called shift register. One very common one is a 74HC165 shift register (https://playground.arduino.cc/Code/ShiftRegSN74HC165N/).

With one of such IC you can connect 8 buttons, however you can daisy chain max 4 to get 4 * 8 = 32 button inputs, only using 4 digital pins of the Arduino. In your case you would need 3 ICs to get 24 (thus 20) button inputs.
> 2 votes

# Answer
## Max buttons for min pins (via electrical engineering and busy wait in interupt)

Hook up each button to an interrupt **and** an analog pin. You can use **the same** interrupt and analog pins for all buttons, if you use resistors to discern between the buttons.

Use the interrupt pin to get notified, when a button is pushed. Use the resistors to have a different target voltage for each button in a voltage divider. Then in the interrupt handler use the analog pin to measure the voltage.
The main problem is that the voltage will take some time to stabilize after the interrupt already fired. I'd check for at least 3 consecutive identical readings (~30ms delay after the voltage stabilized).

Make sure you have some tolerance, e.g. by shifting at least the two least significant bits out (value = AnalogRead(PIN) \>\> TOLERANCE\_BIT\_COUNT;). With the analog pins' 10 bit resolution (1024 values, AFAIR), 2 bits lost for tolerance and an additional bit lost for difference between HI and LO (needed to trigger the interrupt), there are at least 7 bits left, which could suffice for up to 127 buttons.

Yes, you can hook up a keyboard with 2 pins, if you implement part of the logic in hardware (127 carefully designed voltage dividers) and part in software (detecting stabilized voltage). However the identification which button is pressed can be susceptible to deviations in voltage as small as 4.8 mV (a difference of 1 in the value of AnalogRead, which might carry over the tolerance). Also you can not detect multiple buttons being pushed at the same time. However if the electrical design has been carefully engineered, no failure detection may be needed for multiple buttons being pushed, because the interrupt would not fire, depending on how the target voltages stack up.

Electrical engineering problems to be solved:

* Designing the voltage dividers is left to the reader, because you can crank up the tolerance, if you need less buttons. This may mitigate the susceptibility to small deviations in voltage. My proposal would be to get X identical resistors of R Ohm for X buttons. Connect the resistors in series and fork the voltage between the resistors via the buttons. Connect all forks after their respective button to the analog pin and another resistor (of X times R Ohm) to either ground or Vcc (depending on the choice of interrupt HI vs. LO). Add a pull-up/down resistor to the end of the resistors in series as necessary.
* You might need to make sure not to lose too many bits too early, because otherwise there might be consecutive "identical" values without the voltage having stabilized.
* Check, if the interrupt should fire for HI-\>LO or LO-\>HI, as one might offer more distinct target voltages than the other. I just assumed that the first AnalogRead will return a value of about 512 either way.
* I remember that you can remap the values of AnalogRead to regain the 1 bit lost to HI-LO vs. LO-HI transition. This is not recommended as it might interfere with the behaviour of other analog pins. However in a pinch this may either double the number of buttons possible or add another bit for tolerance.
* A small capacitor might help to filter bumping out of the buttons' switching action, so you don't get multiple interrupts for a single button push. However this may increase the time needed for the voltage divider to stabilize at the target voltage. So choose the smallest capacitor and resistors, you can get away with.
> 0 votes

# Answer
## A different take

Use an app to make on-screen virtual controls instead of using physical buttons, and send press events over bluetooth or wifi or ESPNOW.

### Advantages

* no parts needed if you have a phone/laptop already
* no soldering
* no flaky parts wearing out
* complete control over button layout
* easy to upgrade/modify control layout based on field experience
* one less part to carry
* trivial to have extra backup remotes
* opens the door to macros (eg. auto-land), test routines, etc
* lets you log data from the robot for debugging
* EASILY add cool control hardware like gamepads, voice, or camera
* much easier to code buttons in, eg. HTML+JS than C++
* separates programming concerns and allows detached evolution
* allows possibility of internet/remote control
* can be developed on laptop, moved to portable raspPi or phone
* can control more than one (or a new) robot from the remote control

### Disdvantages

* needs code in two languages
* extra part (eg. ESP8266), though buttons are expensive too
* slightly increased latency (but buttons should be debounced anyway)
* might not be as satisfying as a 80+ hour hand-built controller
* requires a bit of security consideration (maybe)

All in all, I think the advantages FAR outweigh the drawbacks. If you need soldering practice and human-held hardware design experience, a physical remote is a decent project, but you can always do that later once you get the robot working with abstract commands; you don't have to build and debug both at the same time, which is huge to me...

### If you NEED a physical remote

You can still get many of the above benefits in a physical remote if you put an MCU/SBC in the remote. Then talk to the robot with uart/wifi/bt/etc. Uart lets you run just 4 wires to the remote instead of dozens. There's lots of existing 4+wire connectors (USB-B, RJ-45, XLR, DIN, etc) that you can use for this; thin, light, cheap, replaceable. Such a config allows serial debugging, logging, etc. It frees the robot CPU from having to deal with interrupts and library footprints.

All in all, it will make making faster for the small cost of a cheap MCU like a nano/bluepill/esp32...
> 0 votes

---
Tags: arduino-mega, button, robotics
---


# Question
Title: Comparison of a string received from MQTT/Cloud/Arduino
I am trying to compare the string of data which I am receiving from the MQTT broker. If I receive the keyword faster I want to print "increase motor speed" and when I get slower keyword or any other keyword, I want to print "decrease motor speed". I am not sure how to store the data I receive from mqttClient.read()and then store it in string to then compare it Below is the snippet of the code where I have added it and it seems not to work correctly in my case. can you look at it and let me know what is the mistake?

```
while (mqttClient.available()) {
Serial.print((char)mqttClient.read());
String ipstring= String("(char)mqttClient.read()");
String fast ="faster";
if((char)mqttClient.read()==fast)
{
Serial.println("increase motor speed");}
else
{
Serial.println("decrease motor speed");
}*
}

```

I have also attached the code for reference. Thank you!

```
/*
  Azure IoT Hub NB

  This sketch securely connects to an Azure IoT Hub using MQTT over NB IoT/LTE Cat M1.
  It uses a private key stored in the ATECC508A and a self signed public
  certificate for SSL/TLS authetication.

  It publishes a message every 5 seconds to "devices/{deviceId}/messages/events/" topic
  and subscribes to messages on the "devices/{deviceId}/messages/devicebound/#"
  topic.

  The circuit:
  - MKR NB 1500 board
  - Antenna
  - SIM card with a data plan
  - LiPo battery

  The following tutorial on Arduino Project Hub can be used
  to setup your Azure account and the MKR board:

  https://create.arduino.cc/projecthub/Arduino_Genuino/securely-connecting-an-arduino-nb-1500-to-azure-iot-hub-af6470

  This example code is in the public domain.
*/

#include <ArduinoBearSSL.h>
#include <ArduinoECCX08.h>
#include <utility/ECCX08SelfSignedCert.h>
#include <ArduinoMqttClient.h>
#include <MKRNB.h>

#include "arduino_secrets.h"
int sensorValue;

/////// Enter your sensitive data in arduino_secrets.h
const char pinnumber[]   = SECRET_PINNUMBER;
const char broker[]      = SECRET_BROKER;
String     deviceId      = SECRET_DEVICE_ID;

NB nbAccess;
GPRS gprs;

NBClient      nbClient;            // Used for the TCP socket connection
BearSSLClient sslClient(nbClient); // Used for SSL/TLS connection, integrates with ECC508
MqttClient    mqttClient(sslClient);

unsigned long lastMillis = 0;

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

  if (!ECCX08.begin()) {
    Serial.println("No ECCX08 present!");
    while (1);
  }

  // reconstruct the self signed cert
  ECCX08SelfSignedCert.beginReconstruction(0, 8);
  ECCX08SelfSignedCert.setCommonName(ECCX08.serialNumber());
  ECCX08SelfSignedCert.endReconstruction();

  // Set a callback to get the current time
  // used to validate the servers certificate
  ArduinoBearSSL.onGetTime(getTime);

  // Set the ECCX08 slot to use for the private key
  // and the accompanying public certificate for it
  sslClient.setEccSlot(0, ECCX08SelfSignedCert.bytes(), ECCX08SelfSignedCert.length());

  // Set the client id used for MQTT as the device id
  mqttClient.setId(deviceId);

  // Set the username to "<broker>/<device id>/api-version=2018-06-30" and empty password
  String username;

  username += broker;
  username += "/";
  username += deviceId;
  username += "/api-version=2018-06-30";

  mqttClient.setUsernamePassword(username, "");

  // Set the message callback, this function is
  // called when the MQTTClient receives a message
  mqttClient.onMessage(onMessageReceived);
}

void loop() {
  if (nbAccess.status() != NB_READY || gprs.status() != GPRS_READY) {
    connectNB();
  }

  if (!mqttClient.connected()) {
    // MQTT client is disconnected, connect
    connectMQTT();
  }

  // poll for new MQTT messages and send keep alives
  mqttClient.poll();

  // publish a message roughly every 5 seconds.
  if (millis() - lastMillis > 5000) {
    lastMillis = millis();

    publishMessage();
  }
}

unsigned long getTime() {
  // get the current time from the cellular module
  return nbAccess.getTime();
}

void connectNB() {
  Serial.println("Attempting to connect to the cellular network");

  while ((nbAccess.begin(pinnumber) != NB_READY) ||
         (gprs.attachGPRS() != GPRS_READY)) {
    // failed, retry
    Serial.print(".");
    delay(1000);
  }

  Serial.println("You're connected to the cellular network");
  Serial.println();
}

void connectMQTT() {
  Serial.print("Attempting to MQTT broker: ");
  Serial.print(broker);
  Serial.println(" ");

  while (!mqttClient.connect(broker, 8883)) {
    // failed, retry
    Serial.print(".");
    Serial.println(mqttClient.connectError());
    delay(5000);
  }
  Serial.println();

  Serial.println("You're connected to the MQTT broker");
  Serial.println();

  // subscribe to a topic
  mqttClient.subscribe("devices/" + deviceId + "/messages/devicebound/#");
}

void publishMessage() {
  Serial.println("Publishing message");

  // send message, the Print interface can be used to set the message contents
  mqttClient.beginMessage("devices/" + deviceId + "/messages/events/");
  mqttClient.print("hello ");
  sensorValue = analogRead(A0);
  mqttClient.println(sensorValue);
  //mqttClient.print(millis());

  mqttClient.endMessage();
}

void onMessageReceived(int messageSize) {
  // we received a message, print out the topic and contents
  Serial.print("Received a message with topic '");
  Serial.print(mqttClient.messageTopic());
  Serial.print("', length ");
  Serial.print(messageSize);
  Serial.println(" bytes:");

  // use the Stream interface to print the contents
  while (mqttClient.available()) {
    Serial.print((char)mqttClient.read());
    String ipstring= String("(char)mqttClient.read()");
    String fast ="faster";
    if((char)mqttClient.read()==fast)
    {
      Serial.println("increase motor speed");}
      else
      {
        Serial.println("decrease motor speed");
        }
  }
  Serial.println();

  Serial.println();
}

```

# Answer
As I read the comments, I see the project requirements are evolving. The `0 = Off` command structure will severely limit what you can do, but it is a good starting point.

Regarding the first block of code starting with `while (mqttClient.available()) {`, then adding your one digit / char commands idea, I have this test sketch for you to try.

You don't need the `String` object to accomplish your goal. You may have to do something like this though `input = (char)mqttClient.read()` where the test sketch uses this `input = Serial.read();`.

```
char input;

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

void loop(){

  if(Serial.available() > 0){

    input = Serial.read();

    if(input == '0'){
      Serial.println("Turn Off");
    }

    else if(input == '1'){
      Serial.println("Turn On");
    }

    else if(input == '2'){
      Serial.println("Decrease Speed");
    }

    else if(input == '3'){
      Serial.println("Increase Speed");
    }
  }
}

```

To take it a step further, let's say you want to send commands that start with a single letter, then after the letter, the remaining digits, or chars have a purpose, if you want them to. For example, lets say you send the following command `d50`. The `d` could mean decrease speed, and the `50` could mean 50%, 50 steps, etc.

The following test sketch illustrates my point.

```
char inputBuffer[64 + 1];

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

void loop(){

  while(Serial.available() > 0){

    Serial.readBytesUntil('\n', inputBuffer, sizeof(inputBuffer));

    if(inputBuffer[0] == 'f'){
      Serial.println("Letter 'f' entered");
    }

    // Letter "r". Everything after the "r" should be digits.
    else if(inputBuffer[0] == 'r'){
      Serial.print("Letter 'r' entered\t");
      // Change the letter "r" to the digit 0 to keep atol() happy.
      inputBuffer[0] = B110000;
      Serial.print("Number entered = ");
      Serial.println(atol(inputBuffer));

      // Your code here that uses the number parsed using atol().

    }

    // Letter "s". Everything after the "s" should have a max
    // length of up to 64 chars long for a 64 + 1 char buffer.
    else if(inputBuffer[0] == 's'){

      // MAX CHARS example with a 64 byte buffer:
      // s123456789a123456789b123456789c123456789d123456789e123456789f + CR + NL
      Serial.print("Letter 's' entered\tText entered = ");

      // Print out the chars in the buffer.
      for(int i = 1; i < strlen(inputBuffer); i++){
        Serial.print(inputBuffer[i]);
      }
      Serial.println();

      // Your code here that uses the char data after the letter "s" is entered.

    }
    memset(inputBuffer, 0, sizeof(inputBuffer));
  }
}

```
> 1 votes

---
Tags: mkr1000
---


# Question
Title: Parallel I/O - maybe use Machine code function call
I'm a newbie to arduino but been programming lots. I have a project where I would like to output 4 bits to adjacent pins and read 4 bits from another (4) adjacent pins. (Imagine a matrix keyboard application). To do it in C-C++ would take lots of instructions (and time) but machine code

OUTPUT: OR (mask) -\> output port ; this clears bits target bits while leaving other bits as they were AND (newdata) -\> output port ; this sets new data into target bits

INPUT: port -\> register AND (register) (mask) -\> register

Is there a way of implementing this as a call from IDE for instance. I have come across many systems where multi language components can be compiled into one executable.

If it is not normally done, why not? Is it something that I should avoid for some reason?

Thanks Dave

# Answer
You can manipulate the I/O ports directly from C++ without having to resort to assembly code.

The AVR micro in your Arduino (ATmega328P) has three ports (PORTB, PORTC and PORTD) with eight pins each (Px0, Px1, ... Px7). You control the ports using three 8-bit registers. Each bit in a register represents one physical pin (LSB is pin 0, MSB pin 7):

* DDRx: data direction register. A bit set to "1" corresponds to output mode, "0" to input.
* PORTx: data register. In output mode, "1" sets the port HIGH, "0" sets it LOW. In input mode, controls whether pull-ups are enabled ("1") or not ("0").
* PINx: input and toggle register. Read it to get the status of all eight pins of the port at once. Writing to it toggles (LOW -\> HIGH or HIGH -\> LOW) the selected pins (e.g. `PINC = 0b00100001;` toggles pins PC0 and PC5).

With an Arduino, you don't have access to all the pins of all the ports. To get the mapping between Arduino pin names and ports, look at any good Arduino pinout reference (e.g. on the Arduino Uno page in the "Documentation" tab). You can see for example that all pins of port D are available as Arduino digital pins D0 to D7 on an Uno for example. The analog pins are from PORTC.

Macros are provided (by the AVR toolchain) for port and pin names to make things easier. For example, `PORTB` is an alias for the PORTB register, you can assign to it as if it was a regular C++ variable. `PB5` is the index of pin 5 in port B. So setting port B pin 5 to output without affecting the others can be written as:

```
DDRB |= (1 << PB5);

```

If you wanted to set the 4 lower pins of port D to output, and the 4 others to input, you could:

```
DDRD = 0b00001111; // or 0x0f

```

Here's an example of a minimal blink sketch:

```
void setup() {
  // Set PB5 (D13 - builtin led) LOW
  PORTB &= ~(1 << PB5);
  // Set PB5 mode to OUTPUT
  DDRB |= (1 << PB5);
}

void loop() {
  delay(1000);
  // toggle PB5
  PINB |= (1 << PB5);
}

```

The assembly generated is optimal, single instructions to set or clear a bit in I/O memory: (See See compiled assembly output (Visual Micro) for how to get it)

```
// setup
  PORTB &= ~(1 << PB5);
 1f4:   2d 98           cbi     0x05, 5 ; 5
  DDRB |= (1 << PB5);
 1f6:   25 9a           sbi     0x04, 5 ; 4

// loop
  PINB |= (1 << PB5);
 246:   1d 9a           sbi     0x03, 5 ; 3

```

Another example, that blinks a led connected to A3 only when A2 is high:

```
void setup() {
  // Set PC2 and PC3 LOW (A2 and A3)
  PORTC &= ~((1 << PC2) | (1 << PC3));
  // Set PC2 to input, PC3 mode to output
  DDRC = (DDRC & ~(1 << PC2)) | (1 << PC3);
}

void loop() {
  delay(1000);
  // toggle PC3 only if PC2 is high
  if (PINC & (1 << PC2)) {
    PINC = (1 << PC3);
  }
}

```

Again, assembly generated is quite terse:

```
  if (PINC & (1 << PC2)) {
    PINC = (1 << PC3);
 202:   18 e0           ldi     r17, 0x08       ; 8
 252:   32 99           sbic    0x06, 2 ; 6
 254:   16 b9           out     0x06, r17       ; 6

```

(The SBIC instruction is fun: skip the next instruction if a bit in I/O memory is clear.)

You can even save the use of that register `r17` by using `PINC |= ...` in this case:

```
  // toggle PC3 only if PC2 is high
  if (PINC & (1 << PC2)) {
    PINC |= (1 << PC3);
 250:   32 99           sbic    0x06, 2 ; 6
 252:   33 9a           sbi     0x06, 3 ; 6

```

Of course you can also resort to inline assembly, but that is an art in and of itself, and the syntax a bit peculiar. But for simple things, it is straightforward:

```
asm("sbi 0x03, 5;"); // toggle PB5

```

Some references:
> 1 votes

---
Tags: arduino-uno, code-optimization, functions, assembly
---


# Question
Title: What are SerialNina and SerialHCI supposed to be used for? (Arduino Nano RP2040 Connect)
Essentially, I'm trying to figure out how I can use Bluetooth Classic using the on-board U-blox w102 Wifi/Bluetooth module. I'm assuming that SerialNina and SerialHCI are somehow connected to it and maybe the way to use Bluetooth Classic on the Nano RP2040.

The ArduinoBLE library uses SerialHCI in HCIUartTransport.cpp. It also messes with NINA\_RESETN and SPIWIFI\_SS a bit in BLELocalDevice.cpp, but I'm not too worried about those.

The WiFiNINA library uses SerialNina to update the wifi firmware in SerialNINAPassthrough.ino and ESP32BootROM.cpp.

From this, I'm assuming that SerialHCI can be used to control BLE and SerialNina updates the Wifi's firmware. Am I right about this? If so, what part of the Nina-w102 module is SerialHCI connected to?

# Answer
> what part of the Nina-w102 module is SerialHCI connected to?

from ArduinoCore-mbed/variants/NANO\_RP2040\_CONNECT/pins\_arduino.h

```
#define SerialNina      Serial3
#define SerialHCI       Serial2

```

```
#define SERIAL2_TX          (digitalPinToPinName(25))
#define SERIAL2_RX          (digitalPinToPinName(26))
#define SERIAL2_CTS         (digitalPinToPinName(27))
#define SERIAL2_RTS         (digitalPinToPinName(28))
#define SERIAL3_TX          (digitalPinToPinName(25))
#define SERIAL3_RX          (digitalPinToPinName(26))

```

Serial2 is configured with flow control pins, but both Serial2 and Serial3 use the same RX/TX pins wired to ESP32 NINA RX/TX.

---

> the way to use Bluetooth Classic on the Nano RP2040:

To use classic Bluetooth on Arduino boards with esp32 NINA module you have to replace the Arduino nina-fw in the esp32 with the SerialToSerialBT.ino sketch for esp32 Arduino core.

You can flash NINA over the host MCU (rp2040) with SerialNINAPassthrough.ino sketch of WifiNINA library. More details about that are in this Arduino forum thread. (Ignore the part before my first comment there).

But with this modification there is no nina firmware, so no WiFi, no cloud. The esp32 is then like a HC-05.
> 0 votes

---
Tags: arduino-nano-rp2040
---


# Question
Title: Digispark ATtiny85 not recognized (bootloader problem)
I recently bought an ATtiny85 based development board. (picture below)

I managed to install it correctly following the official guides, without a problem. Drivers are installed correctly, and I used the Arduino IDE to actually upload a few sketches and tested them in two computers.

*SUDDENLY*

It has stopped working, based on my research, it seems that the bootloader got damaged. Any idea on how to fix this? I thought about burning the bootloader using Arduino, but I have barely got an idea on how to begin.

Backside of the Attiny85

# Answer
> 1 votes
The 3 default ways to re-program your tiny on that board are:

* micronucleus bootloader (sketches only)
* ISP prog. (sketches & set-fuses, InSystemProgramming)
* HV prog. (re-set fuses, HighVoltage = 12V don't worry)

The bootloader in itself is like a sketch on the chip (at the beginning, taking up flash space) and talks through the software USB port on that board. It then rewrites parts of its own flash from the data the host sends, when you upload new sketches.

If that part gets damaged it won't get recognized by the host anymore and you can't use the board to reprogram itself. Unless the chip/parts died to ESD or other reasons, **you still can use ISP/HV programming on the chip, which is the solution to your problem.**

Read up on fuses, they are the init settings of your chip (like a BIOS) defining its behaviour. There are some fuses which can only be set once, after which they can only be changed by the HV method. Depending their setting on your chip, this could also be done with normal ISP programming.

This instructables shows how to build a HV programmer, but also demonstrates using an Arduino as normal ISP programmer (Step 4).

The original Digispark comes with the RSTDISBL fuse set, meaning you can't directly use ISP (which requires the reset pin). Thats why HV programming is neccessary, to regain the reset pin, after that you can reflash the bootloader via ISP. From then on you can use the bootloader again, to reprogram (upload) your sketches.

---
Tags: arduino-uno, programming, bootloader, attiny85, digispark
---


# Question
Title: Arduino Nano Every: get board name in the code
I would like to identify the target where I'm downloading my Arduino code. Following this example:

How to get board type

I'm able to recognize for example Arduino Mini, etc.. but Arduino Every, quite new board is not in the list and I don't understand where to find the correct "define" name to add in the list. Can someone help me? Thanks Andrea.

# Answer
According to documentation the macro to identify the Arduino board is generated as as `ARDUINO_{build.board}` where `{build.board}` is from boards.txt file of the 'platform'.

Nano Every has in boards.txt `nona4809.build.board=AVR_NANO_EVERY`.

So the macro to identify Nano Every is `ARDUINO_AVR_NANO_EVERY`.
> 2 votes

---
Tags: arduino-builder, arduino-nano-every
---