# Question
Title: Protecting your computer from stupid (arduino) mistakes
I recently ran way to much voltage through my Arduino and back into my computer via the USB connection. I'm looking for a USB hub with a fuse or some sort of protection to protect my laptop from these types of mistakes. Any suggestions as to products that would serve this function or other precautions I might take?

# Answer
Both the arduino and a USB port do have some protection against wrong connections and such. The arduino has a diode to prevent wrong polarity to reach your power supply, it also have a resetable fuse (the kinda big, often green SMD part close by your USB connection on your Arduino) that should protect your USB port pretty good from its side of the cable. Your USB port also have some good protections going on as far as i know, so basically it should be hard to break a USB port by accident.

That was the theoretical part, In real life things aren't always what they claim to be, so I use a cheap powered USB hub, that i always use as a first line of defense.
> 5 votes

# Answer
There are a number of USB Isolator products available all around the world.

Here is a list of just a few:
> 3 votes

# Answer
You get used to what not to do fairly quickly :)

Perhaps what you're after is a ruggeduino - http://www.rugged-circuits.com/ruggeduino/

I get the feeling that this sort of thing encourages bad habits, but then it also encourages more exploration.

You need to think carefully about what you're doing, if you put in any second source of power (e.g. USB + power plug, or USB + a signal from another device).
> 1 votes

# Answer
*Please note, that I have no experience in this field, this is simply what I found after some digging.*

I was concerned about connecting a Raspbery Pi Pico device to my brand new computer and did some digging in the "USB Power Delivery" specification:

> #### 7.1.7.1 Output Over Current Protection
>
> Sources operating in SPR mode ***Shall*** implement over current protection to prevent damage from output current that exceeds the current handling capability of the Source. \[...\]

"Shall" means, that this is a mandatory requirement:

> #### 1.4.2.11 Shall/Normative
>
> ***Shall*** and ***Normative*** are equivalent keywords indicating a mandatory requirement. Designers are mandated to implement all such requirements to ensure interoperability with other compliant Devices.

At this point I am already confident enough to plug the device into my computer, so I'll stop digging into the details here.

My understanding is, that the USB controller will detect the fault, disconnect the device and then upon reset and/or reboot it would start working again.

External protection circuits should not be required, at least that is my takeaway. Maybe for really old computers?

**Edit:**

It doesn't seem quite that simple after all, over-voltage protection may not be covered:

> ##### 6.4.6.1.6 Over-Voltage Protection Event
>
> The Over-Voltage Protection Event bit **May** be set when the Source detects its output Voltage exceeds its limits triggering its protection circuitry.

It seems advisable to use some sort of external device after all. Not sure how realistic this failure case is for devices which are powered from the host, but for devices with external power this seems smart.
> 1 votes

---
Tags: arduino-uno, usb, fuses
---


title: How to use this specific arduino shield

text:
# Question
Title: How to use this specific arduino shield
I am trying to understand how to wire this Arduino Uno shield properly.

**My goal/main questions:** I have 6 servo motors and I am trying to wire them properly to this shield. Do I need an external battery pack? If yes, how do I wire that? I need all the wiring details because I cannot find information about this shield anywhere.

I've provided an actual photo of the shield and I even made a schema for you guys, if somebody wants to draw. I bought this arduino + servos + shield from aliexpress and there wasn't any documentation, explanation, schema or anything like that for that specific shield.

Useful info:

Conclusive question: Do I even need this shield at all? Can I just use a regular UNO to be able to freely operate with 6 servos?

---

CODE UPDATE:

```
#include <Servo.h>

Servo myservo;

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

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

```

# Answer
> Do I even need this shield at all? Can I just use a regular UNO to be able to freely operate with 6 servos?

You don't really need this shield for 6 servos. The standard servo library supports 12 servos on the Uno by using a hardware timer. In your case the shield would mainly help with

* Freeing up the hardware timer (in the case you need it)
* Providing a dedicated power line to the servos (since the current for the servos should not run through the Arduino)

If that is enough for you to still use the shield, you can absolutely do that.

> I need all the wiring details because I cannot find information about this shield anywhere.

If you look at the wiki (whose link you provided) and navigate to the page for this shield you will see this diagram

* The servos are connected to the header names "16 road servo", each having the pins (from top to bottom in the image) PWM signal, positive power and ground.
* At the header marked "insert short circuit module" you can use jumpers to select the handling of the power supply, which you connect left to that to the terminals marked supply power. It is not described clearly there, but I would read the following meaning:

+ The VM terminal is used for the motor voltage. You might choose to provide your motors with a different voltage than 5V. If you set the jumper between VM and Vin you can connect that power input to the Vin input of the Arduino, thus powering it from the same power source as the motors (Vin goes to the Arduinos voltage regulator to get the voltage down to 5V). If your power supply is still just 5V, you should leave the jumper out and connect the power supply directly to the VM input (and of course also its ground).
    + Vs should be the power input for the logic circuit of the shield. If you put a jumper between the pins Vs and +5V, you will connect the power of the logic circuit on the shield to the 5V line of the Arduino. I would suggest doing that, because then you don't need to provide Vs from outside.

The other headers are for DC motors and for different modules, which can be connected.

> Do I need an external battery pack?

Here it is important to know, how you are powering the Arduino and how much current the servos need. This datasheet of the MG996 states a stall current of 2.5A, way too much for the Arduino to handle and also way to much for any normal USB port (which will give you up to 500mA). As stated above, you should never run that much current through the Arduino. Provide the motors with power from a power source capable of providing the needed current (+ some headroom). If that is a battery pack or a power supply connect to mains is up to you.
> 2 votes

---
Tags: arduino-uno, servo, shields, arduino-motor-shield, wires
---


# Question
Title: Arduino Nano 33 BLE - use of flash to store data; how to expand a piece of sample code
I've been looking into how to store data in between restarts. With an Arduino UNO, there are plenty of EEPROM libraries, but I'm not finding something 'off the rack' for the Arduino Nano 33 BLE.

I did manage to find a well documented example by Pete Warden, who recently put on github (https://github.com/petewarden/arduino\_nano\_ble\_write\_flash), and it can be compiled and downloaded, but I'm unclear as to how one would expand on it, to write a simple function that can store and read multiple values (integer, float, string, arrays).

The code is below, I'm a bit rusty on things, but I am thinking that the key is in the part:

```
  // Treat the first four bytes of the copy of our flash array as a 32-bit
  // integer.
  int32_t* counter_address = reinterpret_cast<int32_t*>(ram_buffer);

```

How would one add additional variables (and of different lengths) to this code, so you could write and read more than one variable? Somehow, it would seem a command like:

```
int32_t* another_variable = [modified version of:] reinterpret_cast<int32_t*>(ram_buffer);

```

... would do the trick, but I'm not quite sure about how this is done.

```
   * Copyright 2021 The TensorFlow Authors. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==============================================================================*/

// This sketch demonstrates how to initialize, read, and update flash memory
// on an Arduino Nano BLE Sense 33. It contains a counter that starts at zero
// when the sketch is first uploaded, and is incremented by one every time that
// the board is reset without a re-flash. You can test this by uploading the
// sketch, opening the serial monitor, and seeing "Counter=0" output initially.
// If you then press the reset button, you should see "Counter=1", and so on as
// the board is restarted.

// This Mbed API lets us access flash memory, so we include the header. See
// https://os.mbed.com/docs/mbed-os/v6.9/apis/flashiapblockdevice.html
#include "FlashIAPBlockDevice.h"

// One of the challenges I had with the existing examples I found of using flash
// was that they didn't demonstrate how to set an initial value for the memory
// when the sketch was first uploaded. This was essential for most use cases,
// for example we want the counter to start at zero so the initial contents need
// to be set when the program is flashed. I would typically try to use linker
// scripts to set aside an area of memory and mark it so it's initialized during
// flashing, but that's not very easy with the Arduino IDE. Instead I use a bit of
// a hack, by:
//  - Declaring an array of bytes as const, so I know it will end up in
//    flash.
//  - Forcing it to align with the block size of the flash, so it can be
//    accessed by the API that works with whole pages of flash.
//  - Adding an empty initializer list ({}) tells the compiler to zero out the
//    contents in the binary that's flashed to the device.
// The last point is a bit subtle, because you might think that doing it in a
// constructor or setup() would work, but that would be called every time the
// program is reset. What I needed was a way to create a binary with that area
// already initialized before upload, which this approach offers.
// Some other examples use hard-coded addresses for the flash, usually towards
// the top of the address space so that they won't clash with the loaded program,
// but this approach does have the advantage that your writable area is dealt with
// in the same way as other variables, so you shouldn't have to worry about
// overwriting anything.

// From experimentation I know that the "page size" or "block size" of the flash
// on the board is 4KB, and should match the reported get_erase_size() from the
// block device object. In theory we should be able to use the
// MBED_CONF_FLASHIAP_BLOCK_DEVICE_SIZE macro, but this seems to be set to zero.

    #include "FlashIAPBlockDevice.h"

    constexpr int kFlashBlockSize = 4096;

        // Your flash area needs to be a multiple of the block size. In this case I want
        // 64KB (even though I'm only using the first four bytes). You should make this
        // the smallest multiple of the block size that will hold your data.
        #define ROUND_UP(val, block_size) ((((val) + ((block_size) - 1)) / (block_size)) * (block_size))
        constexpr int kFlashBufferSize = ROUND_UP(64 * 1024, kFlashBlockSize);

        // As mentioned above, alignas ensures we get a valid block-aligned address,
        // const should make sure it's in flash, and the empty brackets mean the array
        // is filled with zeroes when the program is first uploaded.
        alignas(kFlashBlockSize) const uint8_t flash_buffer[kFlashBufferSize] = {};

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

              // Beware! If you copy and paste this code into your own example, and try
              // running it without the serial monitor attached, this line will hang forever.
              // You'll need to remove this in production (and yes I have been caught by this
              // myself far too often).
              while (!Serial);

              // The address of the array will be determined by the compiler, and we need to
              // grab it as a 32-bit integer to use with the Mbed API.
              const uint32_t flash_buffer_address = reinterpret_cast<uint32_t>(flash_buffer);
              Serial.println(String("flash_buffer_address=0x") + String(flash_buffer_address, 16));

              // Create the flash object we'll be using to access the flash memory.
              static FlashIAPBlockDevice bd(flash_buffer_address, kFlashBufferSize);
              bd.init();

              // We'll need to copy the area of flash to RAM to modify it, so allocate an
              // array of the right size.
              uint8_t* ram_buffer = (uint8_t*)(malloc(kFlashBufferSize));

              // Copy the existing flash contents into our ram buffer.
              bd.read(ram_buffer, 0, kFlashBufferSize);

              // We need to erase the flash area before we can write into it again.
              bd.erase(0, kFlashBufferSize);

              // Treat the first four bytes of the copy of our flash array as a 32-bit
              // integer.
              int32_t* counter_address = reinterpret_cast<int32_t*>(ram_buffer);

              // Print out the value before any changes.
              Serial.println(String("Counter=") + String(*counter_address, 16));

              // Update our RAM copy of the counter integer.
              *counter_address += 1;

              // Write the whole copy of our RAM buffer back into flash.
              bd.program(ram_buffer, 0, kFlashBufferSize);

              // Shut down our flash access object.
              bd.deinit();
            }

```

# Answer
> 2 votes
I can't really help with the source code you found, but here is a simpler solution for your original problem: I wrote a library called NanoBLEFlashPrefs. It allows you to store parameters and preferences persistently between program restarts and even reprogramming.

The Arduino boards mentioned above use a nRF52840 microcontroller from Nordic Semiconductor. This chip features a very simple file system for flash storage. This is used in the library to store and retrieve an arbitrary struct of data of your program.

Please take a look at the GitHub repository of NanoBLEFlashPrefs.

# Answer
> 2 votes
You can also try my **FS\_Nano33BLE** Library with simple-to-use LittleFS / FATFS.

The filesystem access uses normal POSIX APIs or mbed FileSystem APIs

# Answer
> 2 votes
I guess a simple solution would be to stick with the original pattern and use only one variable... but have this variable be a container for all the stuff you need:

```
struct StoredData {
    int32_t some_integer_variable;
    float some_float;
    // etc...
};

```

Then you can use the same pattern as the original code:

```
StoredData* my_data = reinterpret_cast<StoredData*>(ram_buffer);

```

and access the individual variables as `my_data->some_integer_variable`, `my_data->some_float`, etc.

---
Tags: programming, flash, arduino-nano-ble
---


title: Assign static IP and set host name

text:
# Question
Title: Assign static IP and set host name
Im trying to assign a static IP to my ESP32 and also set the host name. I am able to get one or the other to work, but not get them to **work together**.

Tried moving around WiFi.hostname & WiFi.config in the code, tried WiFi.begin and then setting hostname & IP

```
#include <WiFi.h>
void setup() {

IPAddress local_IP(192, 168, 1, 100);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(208, 67, 222, 222);
IPAddress secondaryDNS(208, 67, 220, 220);

WiFi.mode(WIFI_STA);
WiFi.hostname("ESP");
WiFi.config(local_IP, gateway, subnet, primaryDNS, secondaryDNS);
WiFi.begin("xxxx", "yyyy");

while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}

```

**question in a question:** The WiFi.config that that gives me a static IP is in the format local\_IP, gateway, subnet, primaryDNS, secondaryDNS but the documentation for WiFi.config 2 (and also looking at the library WiFi.h code) is ip, dns, gateway, subnet.

and according to the documentation this should also work, but doesn't WiFi.config (ip)

# Answer
> 4 votes
There is no such thing as a hostname associated with a specific device.

* When you request an IP from your router using DHCP the ESP32 has the option (which it uses) to tell the router what it'd like to be called. The router may, if it chooses, decide to inject that name into DNS lookups done through the router to resolve that allocated IP address.
* You can manually "advertise" a name through the mDNS protocol which requires the inclusion and use of another library and some more configuration in your sketch, along with mDNS support in the devices and applications doing the name lookup (it is getting more universally implemented but is by no means certain to be available).

Since you're not using either DHCP to obtain your IP, nor using mDNS to advertise your name, there is no mechanism that exists to magically make your device have a "name" on your network.

The simplest method to "get around" the issue is to just use DHCP and let your router do all the work. If you really want a static IP address then configure your router to provide a static IP address to your device.

---
Tags: esp32
---


# Question
Title: Unable to use analog pins as digital inputs
I want to use the analog pin `A7` as a digital input pin. As stated in the Arduino docs the analog pins can be configured in the same way like any other digital pin.

However, when trying to configure an analog pin as a digital input pin, I get unexpected behaviour:

* Using a digital pin (e.g. `D2`) works as expected.
* When using an analog pin (e.g. `A7`) the LED is lit after start-up without pressing the button and does not change/react to any button press.
* Since the docs state, that analog pins can be configured as digital pins and used in the same way, this behavior seems to be kind of confusing.

See my attached snippet to reproduce/examine the issue:

```
// using pin 2 (D2) works as expected (LED is lit on button press only)
// const int buttonPin = 2;

// using analog pin 7 (A7 / pin 21) as a digital input is not working,
// LED is lit directly after start-up & does not react to button press,
// analog pins are generally usabable as digital inputs
// see https://www.arduino.cc/en/Tutorial/Foundations/AnalogInputPins
const int buttonPin = A7;

const int ledPin = 13;

int buttonState = 0;

void setup() {
  // button is connected to GND, so enable internal pull-up resistors
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
};

void loop() {
  // as we use internal pull-up resistors, logic HIGH & LOW are inverted
  buttonState = !digitalRead(buttonPin);
  if (buttonState) {
    digitalWrite(ledPin, HIGH);
  } else {
    digitalWrite(ledPin, LOW);
  }
};

```

# Answer
> 5 votes
A6 and A7 are special on the nano. They are the only pins that *can't* be used for digital. They are only analog inputs.

# Answer
> 0 votes
`const int buttonPin = A7;` //is an invalid statement because A7 is not an integer.
Use a number instead:
`const int buttonPin = 21;` // 21 is the decimal pin number for A7.
Don't use A6 or A7 for `pinMode(21, INPUT);` on Nano, they don't work. You can use `analogRead()` (returns 0..1023) and then convert it to wanted boolean value (eg. \>511 or \<511 for crossing half Vref level)

---
Tags: arduino-nano, pins, digital, input, pull-up
---


# Question
Title: How Much mA dropped in ESP8266-01 Work in LiPo Battery if the WIFI function is continuously on
I working on the system where ESP8266-01 should continuously on because I want to get the Wi-Fi function on. In that case ,I can't use the Sleep mode which is given in the Esp8266-01 . So, My Question is that "How much will current(mA) dropped if the esp8266-01 continuously on in 4.2 LiPo battery??

# Answer
**The short answer** is - we don't know.

**Longer answer**: It depends on such factors as:

1. The board circuit (the BBBL (known as The Big Bright Blue LED) on some boards could drain about 10-20ma only by itself)
2. The voltage regulator efficiency
3. The battery controller circuit / quality / keying efficiency.

**The reasonable value** is about 170-220 mA (taken from the PDF, section 5.2) for continuous data transfer.

**The true solution is**: Take the ammeter, connect it *in series with the battery* and measure.
> 2 votes

# Answer
If you really don't sleep at all you can count with about 70 mA, with some short spikes when transmitting.

Sleep mode disabled:

(100 mA per division)

But you **don't need to disable sleep mode** completely to use Wifi, you can be in Auto Light Sleep, which I think is the default for Arduino, Non-OS and RTOS.

Auto Light Sleep:

(100 mA per division)

The Wifi will automatically wake up to transmit and it will also wake up according to the Access Points DTIM interval to receive (usually every 300 ms). You're looking at about 2 mA baseline consumption plus the Wifi send and receive spikes.

Unfortunately after bootup there is a 10 second interval with full 70 mA consumption before the Auto Light Sleep mode kicks in. That's a significant drain if you have frequent system resets, but it might have been a bug that has been fixed in the meantime. (I took those measurements in 2017 with the Arduino SDK.)

There are other modes, but these were the ones that matter in your case.
> 2 votes

---
Tags: arduino-uno, esp8266, wifi, esp32, espressif
---


# Question
Title: Can I use an arduino as an interface to pass files between a device and a PC?
Or maybe you guys can point me towards another direction...

You may ask, why not connect the device directly to the PC?

Well, the device is designed to recognize only USB sticks, and dump the data into them, so I cannot just plug my PC into it and retrieve the data (as far as I know...), because the PC acts as a USB host (I think).

So I thought about using an arduino and make it act as a USB stick, and then pass the data from the arduino to the PC.

Is this possible? Or maybe what I need is a raspberry pi?

Every suggestion is welcomed. Thank you in advance!

# Answer
> 2 votes
You have a device that saves information to a USB stick, is that right? Like a scanner or some sort of temperature logger?

To emulate a USB stick would be quite a task, because what you would have to do is pretend that you have a file system, as your device will be opening files, writing to them, and closing them.

It sounds like a lot of work - it might be easier to get another device that actually logs to something like a serial port.

Having said that, it seems on the face of it to be a reasonable request. Just as an example, I have a scanner that writes to a USB stick. It would be handy to have it send files directly to my PC without having to move the USB stick around all the time.

See Make a computer act as a virtual USB device for other equipments as an example of a similar question, with answers suggesting that it might be possible, for example USB-USB cables.

Even if you got it to work, it might be tedious to use. For instance, if your gadget appends to some file on what it thinks is a USB stick you would have to emulate that file system, and then check on your PC if the file has got larger, and thus have new data on it.

Plus possibly the expense (and time) involved in getting this working might be more than just getting another gadget that actually logs via some sort of port, like serial or RS485.

---
Tags: arduino-uno, usb
---


title: serial is print twice?

text:
# Question
Title: serial is print twice?
I have a problem , when send 1 or 0 by Bluetooth module the serial monitor print two time **(RECEIVED SMS)** . what's the wrong ?

**This is my code :**

```
   char BluetoothData = 0 ;
void setup() {
  // initialize serial communication:
  Serial.begin(9600);
    for (int pin = 1; pin <= 13; pin++)
     {
       pinMode(pin, OUTPUT); // sets the digitals pin  as outputs
       digitalWrite(pin, LOW); // sets the digitals pin off defult intial states
     }
       Serial.println("ALL LEDs NOW OFF \n ");
       Serial.println("Please, Enter : ( 1 to Turn on All LEDs )  or ( 0 to Turn off LEDs ) \n");
}
void loop() {
  // read the sensor:
  if (Serial.available() > 0) {

        BluetoothData = Serial.read();
            Serial.print("*** RECEIVED SMS *** : ==>> ");
            Serial.println(BluetoothData);

        if (BluetoothData == '1'){
        for (int Pin = 1; Pin <= 13; Pin++) {
          digitalWrite(Pin, HIGH);
          }
          Serial.println("ALL LEDs NOW ON");
         }
        // turn all the LEDs off:
   else if (BluetoothData == '0') {
        for (int Pin = 1; Pin <= 13; Pin++) {
          digitalWrite(Pin, LOW);
          }
          Serial.println("ALL LEDs NOW OFF");
         }
  }
   delay(100);
}

```

**This is photo for serial monitor**

# Answer
> 2 votes
Probably the first time because you received the character '1' or '0'. The second character is probably a '\0' or '\d', an `end-of-string` or `end-of-line` character.

You can easily check this by printing the value of each received character, like

```
Serial.println((int)(BluetoothData));

```

You probably see the value for '0' (48), '1' (49), end of string '0' of end of line '13' or maybe '10' (new line).

# Answer
> 1 votes
In the Arduino IDE you should select "No Line Ending" from the menu, instead of "New line". Otherwise you are sending an extra "\n".

---
Tags: arduino-uno, serial, bluetooth, c, sketch
---


# Question
Title: Alerting the ATMega32u4 that it's plugged into a computer (via USB)
I need help in writing some code that will allow for the ATMega32u4 to be aware of when it's plugged into a USB port. I'm not really familiar with the ATMega32 or with it's function in Arduino, so I'm lost in the dark on this one.

Update: So in my circuit, the uC will be powered by Lithium Ion Batteries. On my PCB, their is a battery charging circuit that is powered through a USB C cable. My goal is to implement some type of firmware that can differentiate when the board is plugged into a wall outlet and a USB port on a computer. The reason for this is because I don't want the batteries to charge when the USB C cable is plugged into a laptop.

Second Update: Added pictures of the ATMega32 along with the charging circuit mentioned. I'll be the 5V voltage from USBC to charge the batteries. I'll have the data lines on the USB C cable connected so I can program the microcontroller through a USB cable. My goal here is for the microcontroller to recognize when it's connected to a computer. When this happens, I'll talk to the battery charging IC and tell it to not charge.

# Answer
> 3 votes
I imagine (haven't really tried it) this would work, with some minor adaptation to match your code structure.

```
//  VBUS or counting frames
//  Any frame counting?
u8 USBConnected()
{
    u8 f = UDFNUML;
    delay(3);
    return f != UDFNUML;
}

```

The method reads the `UDFNUML` \- usb data frame number lower (byte) register, waits 3 milliseconds, which would be sufficient time get at least 1 more USB frame if the device was really connected to a USB host, reads the register again and checks if it some USB activity had happened.

Personally, I am not a big fan of busy wait delays like that because the CPU could be better utilized doing something useful in that period (3 milliseconds on a 16Mhz CPU = 48000 clocks ~= 48000 instructions) I'd probably use 1 millisecond timer to sample the register and keep track of the USB status

An alternative would be to use the `bool USBDevice_::configured()` method which is implemented like so

```
bool USBDevice_::configured()
{
    return _usbConfiguration;
}

//  Endpoint 0 interrupt
ISR(USB_COM_vect)
{
  //    ... snip ...
        else if (SET_CONFIGURATION == r)
        {
            if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
            {
                InitEndpoints();
                _usbConfiguration = setup.wValueL;
            } else
                ok = false;
  // ... snip ....
}

```

Hopefully one of the two approaches work for you...

---
Tags: usb, atmega32u4
---


# Question
Title: ESP32 open "captive portal" on connected
I am using the default example SimpleWiFiServer that comes as an example from the ESP32:

```
#include <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>

#define LED_BUILTIN 2   // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED

// Set these to your desired credentials.
const char *ssid = "MyNetwork";
//const char *password = "YourPassword";

WiFiServer server(80);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);

  Serial.begin(115200);
  Serial.println();
  Serial.println("Configuring access point...");

  // You can remove the password parameter if you want the AP to be open.

  //tcpip_adapter_dns_info_t dns_info;
  //dns_info.ip.u_addr.ip4.addr = IPAddress(192,168,4,1);
  //tcpip_adapter_set_dns_info(TCPIP_ADAPTER_IF_AP, TCPIP_ADAPTER_DNS_MAIN, &dns_info);

  WiFi.softAP(ssid);
  IPAddress myIP = WiFi.softAPIP();
  Serial.print("AP IP address: ");
  Serial.println(myIP);
  server.begin();

  Serial.println("Server started");
}

void loop() {
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {                             // if you get a client,
    Serial.println("New Client.");           // print a message out the serial port
    String currentLine = "";                // make a String to hold incoming data from the client
    while (client.connected()) {            // loop while the client's connected
      if (client.available()) {             // if there's bytes to read from the client,
        char c = client.read();             // read a byte, then
        Serial.write(c);                    // print it out the serial monitor
        if (c == '\n') {                    // if the byte is a newline character

          // if the current line is blank, you got two newline characters in a row.
          // that's the end of the client HTTP request, so send a response:
          if (currentLine.length() == 0) {
            // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
            // and a content-type so the client knows what's coming, then a blank line:
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();

            // the content of the HTTP response follows the header:
            client.print("Click <a href=\"/H\">here</a> to turn ON the LED.<br>");
            client.print("Click <a href=\"/L\">here</a> to turn OFF the LED.<br>");

            // The HTTP response ends with another blank line:
            client.println();
            // break out of the while loop:
            break;
          } else {    // if you got a newline, then clear currentLine:
            currentLine = "";
          }
        } else if (c != '\r') {  // if you got anything else but a carriage return character,
          currentLine += c;      // add it to the end of the currentLine
        }

        // Check to see if the client request was "GET /H" or "GET /L":
        if (currentLine.endsWith("GET /H")) {
          digitalWrite(LED_BUILTIN, HIGH);               // GET /H turns the LED on
        }
        if (currentLine.endsWith("GET /L")) {
          digitalWrite(LED_BUILTIN, LOW);                // GET /L turns the LED off
        }
      }
    }
    // close the connection:
    client.stop();
    Serial.println("Client Disconnected.");
  }
}

```

That initializes the ESP32 as an Access Point. On my phone I am able to see the network MyNetwork. If I connect to it and then open a my browser and go to 192.168.4.1 I am able to see the default page.

**How can I change that code so that when I connect to that network it automatically open my browser going to http://192.168.4.1 ?**

When researching on the internet I found this library that does that WiFiManager . That library helps you connect to an existing WiFi network. I do not want to do that. I only want that when I connect to `MyNetwork` my default page opens up just like when you connect to guest networks on hotels etc.

Other people on the internet have modified WiFiAPP.cpp and added these three lines of code:

```
tcpip_adapter_dns_info_t dns_info;
dns_info.ip.u_addr.ip4.addr = IPAddress(192,168,4,1);
tcpip_adapter_set_dns_info(TCPIP_ADAPTER_IF_AP, TCPIP_ADAPTER_DNS_MAIN, &dns_info);

```

That only makes my esp32 crash and does not work.

Has someone figure out a simple way to open a popup window (captive portal) pointing to http://192.168.4.1 once you connect to the ESP32 access point?

Lastly I found this example but that is using esp8266.

# Answer
> 5 votes
Thanks to @Majenko I was able to find what I was looking for on the internet from this link. When I googled "captive portal" instead of the phrases that I was using I found a lot more examples.

This code opens a "captive portal" once I connect to the esp32 access point.

```
#include <WiFi.h>
#include <DNSServer.h>

const byte DNS_PORT = 53;
IPAddress apIP(192, 168, 1, 1);
DNSServer dnsServer;
WiFiServer server(80);

String responseHTML = ""
  "<!DOCTYPE html><html><head><title>CaptivePortal</title></head><body>"
  "<h1>Hello World!</h1><p>This is a captive portal example. All requests will "
  "be redirected here.</p></body></html>";

void setup() {
  WiFi.disconnect();   //added to start with the wifi off, avoid crashing
  WiFi.mode(WIFI_OFF); //added to start with the wifi off, avoid crashing
  WiFi.mode(WIFI_AP);
  WiFi.softAPConfig(apIP, apIP, IPAddress(255, 255, 255, 0));
  WiFi.softAP("DNSServer CaptivePortal example");

  // if DNSServer is started with "*" for domain name, it will reply with
  // provided IP to all DNS request
  dnsServer.start(DNS_PORT, "*", apIP);

  server.begin();
}

void loop() {
  dnsServer.processNextRequest();
  WiFiClient client = server.available();   // listen for incoming clients

  if (client) {
    String currentLine = "";
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        if (c == '\n') {
          if (currentLine.length() == 0) {
            client.println("HTTP/1.1 200 OK");
            client.println("Content-type:text/html");
            client.println();
            client.print(responseHTML);
            break;
          } else {
            currentLine = "";
          }
        } else if (c != '\r') {
          currentLine += c;
        }
      }
    }
    client.stop();
  }
}

```

# Answer
> 3 votes
When providing HTTP server you generally have two options:

1. Using WebServer class and set handlers for roots. The parsing and handling of HTTP header is done by the library.
2. Use WifiServer and receive the HTTP message with header included and handler everything by your own.

If you are doing number 1 and pretend using by connecting with an Android device I suggest adding a handler for the error case showing the captive portal:

```
server.onNotFound(handleRoot);

```

I noticed that for Android 10, to properly detect the captive portal and make the phone to show "Touch to log in the network" message is necesary. If not you must navigate to any HTTP address and let the DNS do the job for you (not HTTPS).

---
Tags: wifi, esp32, softap
---


title: NRF24 and Arduino Nano Every usage

text:
# Question
Title: NRF24 and Arduino Nano Every usage
Im building an RC car project and using 2 NRF24's for communication. I own an Arduino Uno, Nano and Nano Every. The NRF's work great with the Uno and Nano in any combinations but using a Nano Every either as TX or RX doesn't work.

I have tried the NRF24 and NRFLite and both say "Cannot communicate with radio".

When using the NRFLite library examples Basic\_TX on the Uno/Nano and Basic\_RX on the Nano Every, the Uno/Nano says transmission was successful even though the Every says "Cannot communicate with radio". This lasts about 1 second before the Uno/Nano says the transmission failed again. This happens every time you reset the Every. It is as if the NRF24 gets powered on but then is unable to communicate with the Every.

I am using power adapters for the NRF's and powering them through the 5v pin. No luck with capacitors either. Have swapped out all the wires and also double checked all connections.

Is there something wrong with the Nano Every? Does it work with a NRF24 for anyone?

I have completely ran out of ideas to fix this. Thank you in advance

# Answer
I stucked with the same problem too when use nRF24L01+ and Arduino Nano Every to transmit data to Arduino Uno with nRF24L01+. So I have solved the problem as follows below. I hope it could help you and for somebody else.

1. First of all you should add Arduino megaAVR Boards in the boards manager.

1.1 It is first necessary to add the URL of their Boards Manager JSON file in: File \> Preferences \> Additional Boards Manager URLs and Paste the link: https://raw.githubusercontent.com/amperka/iskra-boards/master/package\_amperka\_index.json

1.2. Then go to Tools\>Boards Manager, search Arduino SAMD Boards and install it

1.3. Choose Arduino Nano Every in Tools\>Board\>Arduino megaAVR Boards\>Arduino Nano Every

2. Upload the library for RF24. It must be compatible for architecture megaavr because Arduino Nano Every uses Microchip ATmega4809. I use the latest version RF24-1.4.1. Here is the link to the library: https://www.arduinolibraries.info/libraries/rf24
3. You should check whether you connected nRF24L01+ and arduino correctly.

The pinout of Arduino Uno is as follows: 5V - VCC if you connect nRF24L01+ via nRF24L01+ adapter (I use adapter) or 3.3V - VCC without adapter

GND - GND

9 pin - CE

10 pin - CSN

11 pin - MOSI

12 pin - MISO

13 pin - SCK

not connected - IRQ

However, I use another pinout for Arduino Nano Every. When I use the same pinout as Arduino Uno it can't find nRF24L01+. You can check it in Serial Monitor by using a sketch below. If you get zeros in the third line, for example, something like this: RX\_ADDR\_P0-1 = 0x0000000070 0x0000000000. It means that Arduino Nano Every isn't connected to nRF24L01+ correctly and Arduino Nano Every doesn't see it. I suppose the problem with the library of RF24 and it should be fixed. Perhaps I'm wrong and the problem with another things.

So I use the following pinouts for Arduino Nano Every: 5V - VCC if you connect nRF24L01+ via nRF24L01+ adapter (I use adapter) or 3.3V - VCC without adapter

GND - GND

10 pin - CE

A3 - CSN (if you will get zeros in the third line RX\_ADDR\_P0-1 in Serial Monitor then change A3 to another one. You can vary pin from A5 and so on until A0). do not use A7 and A6 because on some model dev boards, A6 and A7 are analog input only.

11 pin - MOSI

12 pin - MISO

13 pin - SCK

not connected - IRQ

The sketch for checking:

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

RF24 radio(10,A3);  // for arduino nano every
//RF24 radio(9,10); // for arduino uno

const uint8_t num_channels = 128;
uint8_t values[num_channels];
void setup(void)
{
  Serial.begin(9600);
  printf_begin();
  radio.begin();
  radio.setAutoAck(false);
  radio.startListening();

  radio.printDetails();
  delay(5000);

  radio.stopListening();
  int i = 0;
  while ( i < num_channels )  {
    printf("%x",i>>4);
    ++i;
  }
  printf("\n\r");
  i = 0;
  while ( i < num_channels ) {
    printf("%x",i&0xf);
    ++i;
  }
  printf("\n\r");
}
const int num_reps = 100;

void loop(void)
{
  memset(values,0,sizeof(values));
  int rep_counter = num_reps;
  while (rep_counter--) {
    int i = num_channels;
    while (i--) {
      radio.setChannel(i);
      radio.startListening();
      delayMicroseconds(128);
      radio.stopListening();
      if ( radio.testCarrier() )
        ++values[i];
    }
  }
  int i = 0;
  while ( i < num_channels ) {
    printf("%x",min(0xf,values[i]&0xf));
    ++i;
  }
  printf("\n\r");
}
int serial_putc( char c, FILE * ) {
  Serial.write( c );
  return c;
}

void printf_begin(void) {
  fdevopen( &serial_putc, 0 );
}

```

Here is the correct output in Serial Monitor the third line without zeros: RX\_ADDR\_P0-1 = 0xf0f0f0f0d2 0xc2c2c2c2c2

```
SPI Speedz  = 10 Mhz
STATUS      = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1    = 0xf0f0f0f0d2 0xc2c2c2c2c2
RX_ADDR_P2-5    = 0xc3 0xc4 0xc5 0xc6
TX_ADDR     = 0xf0f0f0f0d2
RX_PW_P0-6  = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA       = 0x00
EN_RXADDR   = 0x02
RF_CH       = 0x00
RF_SETUP    = 0x14
CONFIG      = 0x0f
DYNPD/FEATURE   = 0x38 0x38
Data Rate   = 1 MBPS
Model       = nRF24L01+
CRC Length  = 16 bits
PA Power    = PA_HIGH
ARC     = 15

```

the next two lines are a list of available channels that should be read from top to bottom (i.e. we have 127 channels, еру channels are presented in 16-bit version, the first line is the first digit of each of 127 channels, the second line is the second digit of each of 127 channels).

```
00000000000000001111111111111111222222222222222233333333333333334444444444444444555555555555555566666666666666667777777777777777

0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

```

then the level of noisiness of the channels is displayed. There are noise from the channel 09 to the channel 3f approximately. this noise from my wifi router and some another electronics. you should choose free channels for your purpose.

```
00000010114663444533233300000000001000011233544433221100112223212010000000000000000000000000000000000000000000000000000000000000

00200000035575656777697332111321022125625559643632551111000333012000000000100000010001000000001000000000000011010000000000000000

00000001135a9a767767c89a85646565866555645897434644445200121212122000000000000000000000001000000000000000011000000010000000000000

00101000035567667357878a51123341220322335373542222122000112313112000000001010000000001000000020000000010000000000000100000000010

11000011047587577457694521122232111121243247542232210100002222111000000000100002000002000000000000000000000000000010000000000000

```

Note:

1. Check Tools. There should be: Board:Arduino Nano Every; Registers emulation: "ATMEGA328"; Port:COM#(Arduino Nano Every).
2. some transmission errors can occur due to poor contacts between wires and pins of arduino, so the wires should be soldered.

If everything is ok, then you can use your sketches for the receiver and transmitter respectively. Good luck!
> 3 votes

---
Tags: nrf24l01+, arduino-nano-every
---


# Question
Title: Teensy4.1 with 2x 8MB PSRAM Chips: external_psram_size=0 but EXTMEM char[] works as expected?
So I got 2x PSRAM chips from PJRC with my Teensy4.1 and soldered them on (it's a hideous job as I lost my tips) but it's all tested with a multimeter and the connections are solid.

I ran the memtest sketch from here compiled in both Teensyduino and PlatformIO: https://www.pjrc.com/store/psram.html

Aaaaand external\_psram\_size is reading 0 for both cases. Setting the memory size manually in the program also fails (even with 8MB).

However... EXTMEM vars work as expected. I'm not sure how the mem addressing actually works with the provided memtest program, either - it certainly doesn't seem to use EXTMEM anywhere.

Here's my memory tester (run to crash):

```
EXTMEM char bigBuf[10000000];
//char bigBuf[10000];
int c = 0;
void setup() {
  c = 0;
}

void loop() {
  bigBuf[c] = 'a';
  Serial.println(bigBuf[c]);
  Serial.println(String(c));
  c = c + 1000;
  delay(1);
}

```

Output with EXTMEM char\[\]: (as expected overflowed until 16MB)

```
a
0
a
100
...
a
16777100
a
16777200

```

Output with internal mem char\[\]: (as somewhat expected overflowed at 512K - max of RAM1)

```
a
0
a
100
...
a
488081
a
489081

```

Anyway, I'm glad EXTMEM works.. But can someone explain what's going on with the provided memtest? I admit I didn't read it over very well, but I thought that PSRAM could only be accessed via EXTMEM; how is it addressing otherwise?

# Answer
> 3 votes
I'm afraid your test program doesn't work as you intended. I tested it with a T4.1 without RAM soldered on and it gives the same result as in your question.

1. You didn't declare your array volatile. Thus, the compiler can (and probably will) simply optimize the reading back away.
2. Even if you declare the variable volatile the processor reads back the value from the cache line, i.e. you always get the correct value back, even without any external RAM.

Here a simple test program showing the effect. It always switches the LED on, even without external RAM soldered on the board.

```
EXTMEM volatile int test;

void setup()
{
    pinMode(13, OUTPUT);

    test = 42;
    if(test == 42)
    {
        digitalWriteFast(13, HIGH);
    }
}

void loop(){
}

```

Here the disassembly of the setup function. It clearly shows that the processor tries to store 42 in the (non existing) external RAM and reads it back from there. Obviously the read back value comes from the cache line. (comments added by me)

```
void setup()
{
      7c:   push    {r3, lr}                         // pinMode code
    pinMode(13, OUTPUT);                             //
      7e:   movs    r1, #1                           //
      80:   movs    r0, #13                          //
      82:   bl  160c <pinMode>                       //-------------

    test = 42;
      86:   ldr r3, [pc, #20]   ; (9c <setup+0x20>)  // load r3 with address of 'test' (0x70000000, stored at 0x9C)
      88:   movs    r2, #42 ; 0x2a                   // load r2 with #42
      8a:   str r2, [r3, #0]                         // store content of r2 at address stored in r3. i.e., store #42 0x7000'0000 (EXTRAM)

    if(test == 42)
      8c:   ldr r3, [r3, #0]                         // volatile forces the compiler to read back 'test' (store it in r3)
      8e:   cmp r3, r2                               // check if equals r2 (contains #42)
      90:   bne.n   9a <setup+0x1e>                  // goto 0x9A if not equal

CORE_PIN13_PORTSET = CORE_PIN13_BITMASK;             // digitalwritefast code (next 3 lines)
      92:   ldr r3, [pc, #12]   ; (a0 <setup+0x24>)  // ...
      94:   movs    r2, #8                           // ...
      96:   str.w   r2, [r3, #132]  ; 0x84           // -------

      9a:   pop {r3, pc}                             // return from setup()

      9c:   .word   0x70000000                       // Address of 'test'; EXTRAM starts at 0x7000'000
      a0:   .word   0x42004000                       // Address of GPIO register for LED

```

# Answer
> 4 votes
Paul here. I'm the author of that memtest program, and also the creator of Teensy. While luni64 already answered very well about your test program, hopefully I can add some clarity about the official memtest program.

Regarding "I thought that PSRAM could only be accessed via EXTMEM", indeed use of EXTMEM arrays or variables is the normal way. But it is not the only way. The memtest program uses pointers with the known address range of those memory chips. Because the wires physically connect to the "FlexSPI2" peripheral inside the chip, the memory will always start at address 0x70000000. You can find this detail on page 35 of the chip's reference manual.

https://www.pjrc.com/teensy/IMXRT1060RM\_rev2.pdf

Unfortunately the manual is tough to read and confusing in so many ways. Even on page 35, it describes the memory as "ciphertext", which might be the case if the Bus Encryption Engine (mentioned on page 184) were used in a certain way. No encryption is used, and if you read page 184 you'll see that engine only does decryption, so it really only could be used for read-only memory which is pre-loaded with encrypted data.

The point is we know the RAM always starts at 0x70000000 because of the way the hardware is designed. If you look at the memtest code, you'll see it creates 2 variables called "memory\_begin" and "memory\_end", which are pointers used to directly access the memory within that known address range.

The idea behind the memory test is the entire memory is filled with a known data pattern. This sort of testing is meant to catch any (very unlikely) internal problems inside the memory chips, where writing to one place inside the chip might corrupt data somewhere else in the same chip.

The pointer used is declared with "volatile" which prevents the compiler from trying to optimize away actual memory access.

After the memory is completely filled, you'll see a function called arm\_dcache\_flush\_delete() is used. Even if you use volatile to keep the compiler from optimizing away memory access, the Cortex-M7 hardware has 32K level 1 cache. This function causes the ARM Cortex-M7 processor to completely write any cached data to the actual memory chip, and then delete the data from its cache. Normally these special cache functions are only used by low-level driver code using Direct Memory Access (DMA), where you need to be sure data you've written is actually in memory before instructing a peripheral to use DMA to directly grab it from the memory (generally DMA-based peripherals can't access the cache), or before you read data a peripheral put into memory using DMA. Normally you don't need to mess with the cache, but this sort of hardware testing and special benchmarking are the other sort of application where special attention to the processor's cache is important.

Then the entire memory is read back, using the volatile pointer so the compiler doesn't try to do anything too smart. As the data is read, every 32 bit word is compared to the original pattern written. Again, the idea is to check for the pretty unlikely case where the memory appears to work, but could theoretically have an internal problem where writing to one place causes corruption somewhere else inside the chip.

The entire test is repeated many times. A variety of fixed 32 bit patterns are used. Many of the tests fill the entire memory with a pseudo-random sequence, of course doing the same verification where any change to even just 1 bit within the entire memory range will be detected and reported as a failure. Maybe that's overkill, but I tried to design the memtest program according to best practices described for testing PC memory, and those are the ways experts recommend to test memory (actually they recommend even more sophisticated & complex patterns... maybe someday I'll add those).

Hopefully this helps answer "can someone explain what's going on with the provided memtest?"

Regarding the soldering, a problem other people have seen involves the solder adhering only to the memory chip pin. Even though it looks ok when viewed from above, it's possible for the solder to be a blob resting just slightly above the pad surface on the circuit board. I would recommend re-heating the solder. Allow time for it to fully heat and flow onto the pad. While extra time heating isn't wonderful for the PSRAM chip, those chips are pretty hearty heat-size and if the memory isn't working you really don't have much to lose. Counting to 10 while reheating the solder usually works. If you have any liquid flux chemical, applying that before reheating might also help.

Focus your repair effort first on the chip mounted to the smaller set of pads next to the edge of the PCB. The startup code looks for the first 8MB chip in that location. If won't even look for the other chip if no memory is detected in the first location.

---
Tags: teensy
---


# Question
Title: Mini Arducam module camera shield - 2MP ov2640 interface with Arduino Uno
MINI ARDUCAM MODULE CAMERA SHIELD - 2MP OV2640

Arducam Multi-camera adapter board for Arduino SPI Mini Camera

I have the above two components with me along with ARDUINO UNO R3. I want to stream video using these. ARDUCAM provides library for this.

**ARDUCAM LIBRARY**

**ARDUCAM DATASHEET**

When I have chosen example program **ArduCAM\_Shield\_V2\_Video\_Streaming** and tried uploading it to Arduino it showed no ***ArduCAM.h: No such file or directory***.

I have downloaded the library and kept it in the libraries folder of ARDUINO.

Can someone help me out with this??

# Answer
The Uno which you mention has 2 KB of RAM. 2 MP of data would be 2,000,000 x 3 bytes (red, green, and blue), in other words 6 MB.

The screenshot you showed seems to show that the library is designed to take a still photo and buffer it. As you might imagine, buffering 6 MB would take a while, especially as you can only fit 2 KB at a time.

You simply won't be streaming video using the Uno, so the error message is more-or-less irrelevant.

It might be relevant if you actually wanted to take single photos and send them.

In that case, you probably haven't installed the library properly.
> 1 votes

---
Tags: arduino-uno, arduino-ide, shields, camera
---


# Question
Title: How to control multiple servo motors at the same time with protothreading using an I2C PCA9685 PWM board?
I'm trying to use protothreading to control two (and eventually four) servo motors over I2C using a PCA9685 PWM board.

To start, I am simply trying to sweep the two motors back and fourth at the same time.

Here is the code I am using:

```
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

#include <protothreads.h>

#define SERVOMIN  150
#define SERVOMAX  600
#define USMIN  600
#define USMAX  2400
#define SERVO_FREQ 50

int servo1 = 0;
int servo2 = 4;

////////////////////////     T H R E A D    1     /////////////////////////

pt ptServo1;
int Servo1Thread(struct pt* pt){
  PT_BEGIN(pt);
  for(;;){
    for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
      pwm.writeMicroseconds(servo1, microsec);
    }
    PT_SLEEP(pt, 500);
    for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
      pwm.writeMicroseconds(servo1, microsec);
    }
    PT_SLEEP(pt, 500);
  }
  PT_END(pt);
}

////////////////////////     T H R E A D    2     /////////////////////////

pt ptServo2;
int Servo2Thread(struct pt* pt){
  PT_BEGIN(pt);
  for(;;){
    for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
      pwm.writeMicroseconds(servo2, microsec);
    }
    PT_SLEEP(pt, 500);
    for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
      pwm.writeMicroseconds(servo2, microsec);
    }
    PT_SLEEP(pt, 500);
  }
  PT_END(pt);
}

////////////////////////////////////////////////////////////////////////////

void setup() {
  Serial.begin(9600);
  PT_INIT(&ptServo1);
  PT_INIT(&ptServo2);
  pwm.begin();
  pwm.setOscillatorFrequency(27000000);
  pwm.setPWMFreq(SERVO_FREQ);  // Analog servos run at ~50 Hz updates
}

void loop() {
  PT_SCHEDULE(Servo1Thread(&ptServo1));
  PT_SCHEDULE(Servo2Thread(&ptServo2));
}

```

I am noticing that Servo 1 turns to -90 and stops. While it has stopped, Servo 2 turns to -90 and then stops....then Servo 1 turns to +90 and stops and so on. They are not doing the sweeping at the same time.

Any help would be greatly appreciated!

Thank you,

H

# Answer
> 1 votes
Without knowing Protothread in detail: It is most likely handling the threadchange during `PT_SLEEP()`, which you are only executing after one "sweep" (one of the inner for loops), not giving any opportunity to change to the other thread.

Additionally this way you don't have any delay in the inner for loops, thus they get executed very fast. Faster than the motor really can follow. This means, that the servo just moves to the end position as fast as it can and the for loop is essentially useless. You need a delay inside the inner for loops for slowing the signal down.

Please try something like this:

```
pt ptServo1;
int Servo1Thread(struct pt* pt){
  PT_BEGIN(pt);
  for(;;){
    for (uint16_t microsec = USMIN; microsec < USMAX; microsec++) {
      pwm.writeMicroseconds(servo1, microsec);
      PT_SLEEP(pt, 50);
    }
    PT_SLEEP(pt, 500);
    for (uint16_t microsec = USMAX; microsec > USMIN; microsec--) {
      pwm.writeMicroseconds(servo1, microsec);
      PT_SLEEP(pt, 50);
    }
    PT_SLEEP(pt, 500);
  }
  PT_END(pt);
}

```

Change the sleep time in the inner loop according to your wanted sweep speed.

---
Tags: arduino-uno, i2c, motor, servo
---


title: Mixed SHARP IR Sensor Readings

text:
# Question
Title: Mixed SHARP IR Sensor Readings
I'm using the GP2Y0A21YK Sharp IR Sensor in a ball and beam system where I'm trying to balance the ball in the center of the beam using the IR Sensor as a distance locator and a servo motor to tilt the beam. I'm using a PID Controller for the system. However, something odd happens when I apply the code. When the servo motor is disconnected, I'm getting accurate readings of the location of the ball. However, as soon as I plug in the servo motor, the distance reading is completely off and inaccurate. I've read that powering the Arduino using both the USB port and Plug will make the readings more stable. However, I've tried that and it only improved the readings by a small bit. What can be causing this problem? Since the code and the schematic would take a bit of a space, kindly let me know if they are needed and I'm happy to provide.

# Answer
> 1 votes
It is likely your power source supplies insufficient current to power both the servo and the Arduino reliably.

It is also possible that the motor in the servo is creating noise on the power rails and inducing unexpected behavior in the Arduino. But the former is more likely.

Consider using a power source which can supply more current. For instance, D size cell batteries can supply much more current than a small 9 volt battery.

Also consider using a separate power source for the Arduino and the motor. Many resort to this option for such projects as you describe here.

---
Tags: sensors, servo, ir, pid
---


# Question
Title: Compiler error: final link failed: bad value collect2.exe
I work With VS Code v:1.59.1. With extension vscode-arduino v:0.4.4

befor update of vscode. in version 1.58. all was ok. I can build and upload code for all mucrocontrollers.

but after the update, I can build code for arduino uno. but when i build the code for esp32, i get this error:

```
[Starting] Analyzing sketch 'emptyProjct.ino'
[Warning] Output path is not specified. Unable to reuse previously compiled files. Build will be slower. See README.
Cargando configuración...
Inicializando paquetes...
Preparando tarjetas...
Verficando...
c:/users/hassan daoud/documents/arduino/hardware/espressif/esp32/tools/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.4.0/../../../../xtensa-esp32-elf/bin/ld.exe: final link failed: bad value
collect2.exe: error: ld returned 1 exit status
exit status 1
IntelliSense configuration already up to date. To manually rebuild your IntelliSense configuration run "Ctrl+Alt+I"
[Error] Analyzing sketch 'emptyProjct.ino': Exit with code=1

```

other thing. in the right of status bar. in \[Select Programmer\], I can't show any programmer for ESP32, but when i change board to arduino uno, i can select from a lot of choises.

this screenshot is for adruino uno.

and this is for esp32 wroom

after the update of vscode I try to download another extension like \[Espressif IDF\]. because \[vscode-arduino\] dont fix the error of serial port.

I contact with \[Espressif IDF\] for an error in instalation and him tel me to download the sdk in a path with out spasing. and then its work. but the old library I download from Arduino IDE for ESP32 its work in the prev. ver. with space in the path.

so I dont know if the problem is from the new library or what happen. but I cant build code for ESP32.

please help me thank you a lot to all.

# Answer
OK, I fix the error.

I remove all library for esp32 in my computer

```
c:/users/hassan daoud/documents/arduino/hardware/
c:/users/hassan daoud/appdata/local/arduino15/packages/

```

and install again from board manager.

all work ok
> 1 votes

---
Tags: esp32, compiler
---


title: 3th time blown à Nano every

text:
# Question
Title: 3th time blown à Nano every
Like subject all ready telling you, I blew up my 3th Nano every.

I mounted them on a perf board, soldered with 99% tin 1.0mm and a Flux, cleaned with flux remover, etc... When I then power them up through USB I have a short on pin 29 and 30 (Vin Gnd). And the board is ready to go directly in the poubelle (the garbage thing).

Second and third time, after soldering I scratched the space between both pins to make sure there is no connection. But... Yip again. Is this a common issue? Am I overseeing something?

Did my measurements with multimeter. No shorts.

# Answer
> 2 votes
If i am not wrong you have soldered nano directly to the perf board, which i don't recommend at all. You could try soldering a female strip pin on to the pref board and insert the nano board in the strip pin. This way you could easily remove/install the board easily as you wish.

---
Tags: arduino-nano-every
---


# Question
Title: SIM808 does not support SSL related AT commands
1. I am using a SIM808 module. It's working fine with normal MQTT over TCP, but does not work when trying secured MQTT.
2. I sent `AT+SSLSETROOT="C:\USER\HENRY_SSL.CRT"` to set the root certificate (see this document: "SIM800 Series\_MQTT\_Application Note\_V1.03"). The response I'm getting from the GSM is: `+CME ERROR: unknown`.
3. When I try `AT+SMSSL=1`, I get the same error. I checked with HTTP commands and it's working fine, but the `AT+HTTPSSL=1` command does not work. The SIM808 does not respond to SSL related commands.

But as per the Simcom website, the SIM808 does support SSL. Do I need to upgrade any firmware?

# Answer
I updated the firmware version: 1418B05SIM808M32. Now all commands are working fine.
> 1 votes

---
Tags: gsm, sim808
---


title: Trouble with NRF24L01

text:
# Question
Title: Trouble with NRF24L01
I've been trying on and off to try and get my nrf24l01's working for some time and they never seem to work. Right now I'm just trying to turn a led on and off over the radio and it isn't working.

Here's the code for the transmitter

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define button 5
RF24 radio(7, 8); // CE, CSN
const byte address[6] = "00001";
boolean buttonState = 0;
void setup() {
  pinMode(5, INPUT_PULLUP);
  radio.begin();
  radio.openWritingPipe(address);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();
}
void loop() {

  buttonState = digitalRead(button);
  radio.write(&buttonState, sizeof(buttonState));
}

```

And here's the code for the receiver

```
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

int led = 2;
RF24 radio(7, 8); // CE, CSN
boolean buttonState = 0;
const byte address[6] = "00001";
void setup() {
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();
}
void loop() {
 radio.startListening();
  while (!radio.available());
  radio.read(&buttonState, sizeof(buttonState));
  if (buttonState == HIGH)
  {
    digitalWrite(led, HIGH);
  }
  else
  {
    digitalWrite(led, LOW);
  }
}

```

I have the voltage regulator which steps the 5v arduino to 3.3 to the chip so I don't think not having a capacitor (what others recommended) is a problem. I have both radio chips hooked up to arduino nanos.

For the transmitter and receiver I have CE=7,CSN=8, SCK=13, MO=11, and MI=12

I also know that my led is working and the code for my button is working. Is there a problem with my code or is there a chance that my chips are broken even if im using a voltage regulator

# Answer
Interesting. I have been having an issue with nRF24L01's as well so I tried your code (modified to work toggling the transmitter and printing the output). You are possibly getting the same issue as me (nRF24L01 continuously reading closed pipe) so I modified your code as follows:

```
void loop() {
 uint8_t pipeNum;
 radio.startListening();
  while (!radio.available(&pipeNum));
  radio.read(&buttonState, sizeof(buttonState));
  if (pipeNum < 2) {
    if (buttonState == HIGH)
    {
      digitalWrite(led, HIGH);
      Serial.println("ON");
    }
    else
    {
      digitalWrite(led, LOW);
      Serial.println("OFF");
    }
  }
}

```

and then it worked for me. PS: I normally add a "while (!Serial);" line after Serial.begin to hold off output until the monitor is established.
> 3 votes

# Answer
It is not easy to find the problem remotely. Here is what I would do:

1. My first problem have always been connections. I gave up using breadboards and other connectors. Use soldering instead to be sure your circuit is properly connected.
2. Add some Serial.println() in both codes to see what exactly is going to be sent, and what has been received.
3. On the sender code, add a delay(100) to the loop. That would give the module buffers a chance to process.
4. You can improve it more by checking for the button value you read with the old value, and only send the value if the state has changed.
> 2 votes

# Answer
Pretty sure your issue is you're not using the capacitor. I used a 10uF capacitor and it works great.

You put the capacitor on pins 1 and 2, make sure ground is on pin 1.

The capacitor is to make sure there is enough power being supplied when it needs it. Without the capacitor it causes unreliable communication.

If you have other issues this is a great summary video on using the NRF24L01+ transceivers: https://www.youtube.com/watch?v=kDTJULtFPgE
> 1 votes

# Answer
Check these things first:

* Is your power supply give a constant 3.3V and a minimum of 0.5A(500mA)?
* Are you on the right serial baud rate?
* Is the path from the radio to the Arduino as short as possible?
* Are your MISO and MOSI wires twined into each other?
* Try changing your CE to pin 9 and CSN to pin 10.

If none of these things help then, please tell me what library you are using. I had a lot of issues with the RF24 library so maybe try using the NRFLite library.
> 1 votes

---
Tags: arduino-nano, spi, nrf24l01+
---


title: nRF24L01+ module fried?

text:
# Question
Title: nRF24L01+ module fried?
I have 2 nRF24L01+ modules that were working fine then...stopped. I'm wondering if I accidentally fried one of the modules.

When I run the RF24 library GettingStarted example, this is the output of the module I believe may be fried:

```
RF24/examples/GettingStarted/
ROLE: Pong back
*** PRESS 'T' to begin transmitting to the other node
STATUS        = 0x00 RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=0 TX_FULL=0
RX_ADDR_P0-1  = 0x0000000000 0x0000000000
RX_ADDR_P2-5  = 0x00 0x00 0x00 0x00
TX_ADDR       = 0x0000000000
RX_PW_P0-6    = 0x00 0x00 0x00 0x00 0x00 0x00
EN_AA         = 0x00
EN_RXADDR     = 0x00
RF_CH         = 0x00
RF_SETUP      = 0x00
CONFIG        = 0x00
DYNPD/FEATURE = 0x00 0x00
Data Rate     = 1MBPS
Model         = nRF24L01
CRC Length    = Disabled
PA Power      = PA_MIN

```

I've changed out cables and connections all the way through. I also replaced this module with the other one directly and the other worked fine.

So, my question: Is this output showing definitively that I've killed the module and just need to buy a new one? Or is there some way to "flash" or reset the module?

# Answer
Assuming you have triple checked all your wiring before posting this question you should add a small capacitor between Vcc and GND near the nRF24: anything between 10uF and 100uF will do.

Rationale: these devices draw quite a decent amount of current when bootstrapping and transmitting and if they don't receive enough juice they just reset themselves showing those *all zeroes* settings.

They are pretty robust devices, not that easy to *fry*.
> 1 votes

# Answer
The nRF24L01 modules are very sensitive to electrostatic damage, I have killed three. By bit-banging the SPI lines it appears that the SCK line dies as I can detect MISO change on activating CSN (since status information should be returned whatever command is sent). I surmise the zeros you see in the status report are the first pre-clock bit repeated when there is no clock signal received. I put a 33k pull-down resistor on SCK.
> 0 votes

---
Tags: arduino-uno, nrf24l01+
---


# Question
Title: NRF24L01+ (TMRH20 library): Receiver gets blank data
I am working on sample Arduino project for communication over NRF24L01+ (TMRH20 library), everything is working fine with my example except one issue my Receiver gets message but that message is blank. Now i am not sure how do i debug as per serial monitor data is getting transmitted, as per receiver serial monitor it receives data but its blank.

Transmitter code -

```
// SimpleTx - the master or the transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataToSend[12] = "Msg AKSHAY";
//int dataToSend = 1;
char txNum = '0';

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleTx Starting");

    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress);
}

//====================

void loop() {
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
        prevMillis = millis();
    }
}

//====================

void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    Serial.print(dataToSend);
    if (rslt) {
        Serial.println("  Acknowledge received");
        updateMessage();
    }
    else {
        Serial.println("  Tx failed");
    }
}

//================

void updateMessage() {
        // so you can see that new data is being sent
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[10] = txNum;
}

```

Receiver code -

```
// SimpleRx - the slave or the receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.startListening();
}

//=============

void loop() {
    getData();
    showData();
}

//==============

void getData() {
  if ( radio.available() ) {

       radio.read( &dataReceived, sizeof(dataReceived) );
      Serial.println(dataReceived);
       newData = true;
   } else {
       Serial.println("No radio available");
   }
   delay(100);
}

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        newData = false;
    }
}

```

Below is the output TX1 (Transmitter ) and RX1 is Receiver. You can see that Transmitter even gets acknowledgment also..

Both of my devices are arduino nano and below is wiring diagram between arduino and nrf24l01.

I also saw few post where people suggested using 100uf capacitor in NRF24L01 (GND & VCC), this helped me with accuracy in connection but data is still missing.

# Answer
I have tested your code. There appears to be defective clones of the nRF24L01 around that exhibit an issue I show in post nRF24L01 continuously reading closed pipe You can work around this issue by changing your code as follows (although your process still has to read all those nulls):

```
void getData() {
  uint8_t pipeNum;
  if ( radio.available(&pipeNum) ) {

       radio.read( &dataReceived, sizeof(dataReceived) );
      //Serial.println(dataReceived);
      if (pipeNum < 2) {
       newData = true;
      }
   } else {
       Serial.println("No radio available");
   }
   // delay(100);
}

```
> 3 votes

# Answer
A couple of clarifications first

1. At the time instant 22:38, the receiver isn't detecting any available radio devices but at the transmitter side, an acknowledge is received. How is that possible? How is your tx getting an ack without the rx getting connected.
2. I have not seen slave adresses being set as -
`const byte slaveAddress[5] = {'R','x','A','A','A'};`
For the record, **NRF24L01 adresses are 5 bytes long** by default and not 1 byte long as you have defined. While defining the pipe addresses, the first 4 bytes of the adresses should be same among all the pipe addresses. Only the last byte should be unique.
Pipe addresses can be `0xF0F0F0F0A1, 0XF0F0F0F0B1, 0XF0F0F0F0C1, 0XF0F0F0F0D1, 0XF0F0F0F0E1`
Try setting the pipe addresses as
`uint_64t address[5] = {0xF0F0F0F0A1LL, 0XF0F0F0F0B1LL, 0XF0F0F0F0C1LL, 0XF0F0F0F0D1LL, 0XF0F0F0F0E1LL};`
Do the same declaration at the receiver end too. And btw, you can specify any byte you want in the last byte of the address. Here I have defined the last bytes as `A1`, `B1`, `C1`, `D1`, `E1`.
3. To make sure that communication is successful, set some custom ack byte and compare it with the received ack. If both match, you can be sure that the rx did get the data. Sometimes, the NRF24L01 can pickup garbage values from stray signals present around and it can consider it as data sent by the receiver. So to avoid false triggering, its better to make a fool-proof ACK mechanism.
> -1 votes

---
Tags: serial, arduino-nano, nrf24l01+
---


# Question
Title: Bi-directional UART communication on single data wire, possible?
The nano is inside of the house, and the pro mini is outside of the house. I want to send/receive text between them. The communication will be always nano sending text to mini, and then mini sending text to pro in response. There will be no case where mini sends text on its own first.

The line has three wires, but since I have to power the mini with that line, one is used for VCC and another is used for ground, leaving only one wire free. It this case, can I do UART communication between the two? If so, how should I connect the wire to them (including the ground)? And on the software side, how should I handle the communication? Could you give a simple code example in which nano sends "Hello" to pro mini, and then pro mini, after receiving "hello", sends "World" to nano?

# Answer
> 6 votes
You can have bidirectional communication over a single wire by using open-collector outputs. For this, you could add a circuit like this on each side of the link:

simulate this circuit – Schematic created using CircuitLab

Here, TX is the transmit pin of the Arduino, and DATA is the data wire. The RX pin is connected directly to the data wire and, while writing your sketches, you should account for the fact that anything you send will be received back by the sender as an “echo”.

This scheme will slow down your signal transitions, limiting the maximum achievable baud rate. Start with something conservative, like 9600 bps, and lower further if it doesn't work reliably.

# Answer
> 3 votes
This question likely suffers from the X Y problem. Where the question (about software) and possible answer (centered on hardware) do not approach the solution using the same methods.

The question is essentially asking how to design a 1-wire interface over longer than normal distances. There are 1-wire Arduino libraries and 1-wire Arduino tutorials. But it is likely you will run into problems if your cable is very long.

Guessing at the distance you want to run your 3 wires (power, ground and data), this may be more an electrical engineering than a software problem.

**Power:**

All wires have resistance. Using a voltage drop calculator from here we can calculate, assuming we are trying to send 5V over an 18 AWG copper wire 100 meters long to a 250mA load, an expected voltage drop of slightly over a volt. That may cause unexpected results.

If this might be an issue, consider an alternate power source such as batteries, solar power or a second mains power adapter for the far Arduino. It may even be considered to over drive the power lines several volts and regulate the voltage at the far end Arduino.

**Data:**

Reference to ground type data transmission is more susceptible to error the longer the cable run. Several options to mitigating unexpected behavior can be made. However switching over to a balanced pair is usually the best option.

**Options:**

If you are willing to power the far Arduino independently or add 1 additional data wire (either of these options will make available 2 wires for data) we can run the data portion of the cable for a good distance while mitigating noise problems associated with long communication cable runs.

**Try RS485:**

Consider using an RS485 hardware interface at the near and far Arduino. RS485 interfaces can be source easily for Arduino projects (here and here are two examples) and there are Arduino RS485 software libraries which handle the communications.

The intent of the project was not disclosed in the question. However here is an example RS485 project where connected Arduinos communicate the position of a potentiometer such that the RS485 connected Arduino at the far end can mimic the potentiometer's movements on a motor driven servo.

The keen eye may note that the above project only uses 2 wires between the two Arduinos. This is possible because in the above project the two Arduinos are independently powered (this is not seen in the diagram on the linked to web page). Additionally, RS485 uses a balanced pair of signals (the 2 wires) and does not need to run an additional ground between the two Arduinos as a reference to detect the difference between 1s and 0s.

# Answer
> 1 votes
An example of protocol using a single wire (besides ground, so a total of 2) for both bi-directional communication AND power: Dallas 1-wire

There are few other similar standard protocols and you are free to think about your own as long as you are willing to implement all the internals instead of using a well-written and widely used library.

# Answer
> 1 votes
You could do it by using one wire for ground, one wire for nano-\>mini, and one wire for mini-\>nano. The nano-\>mini wire carries both power and data. You can keep it at some voltage above ground to provide the power and superimpose a data signal that is AC coupled off at the mini end. Alternately, you can rectify the data to provide power if you make sure to send 01010101 whenever you don't have something else to say.

---
Tags: serial, communication, uart
---


# Question
Title: Triple-click reset option to erase existing program
My Adafruit Feather M0 has two reset options I know of:

* single click restarts existing program
* double-click listens for an upload for a few seconds, then restarts existing program

Is there another option to have an existing program erased or replaced with something benign like a blinker, e.g.

* triple-click erases existing program and listens for upload indefinitely

If not, what is the level of difficulty to modify the standard bootloader to implement this option?

**NOTE**

The rationale for this option is to recover a bricked board, e.g. with USB port turned off by a low power mode, so the regular software upload doesn't work any longer, at least without some trickery.

# Answer
> 1 votes
Now that we know the board type (Zero) — which took a couple of questions to elicit — it is possible to give a reasonable answer. Had it been a Uno I would have said that no, it doesn't do that, and it would take too much program space to implement it.

> Is there another option to have an existing program erased or replaced with something benign ...

No, not that I am aware of, unless the documentation for the Zero says otherwise.

> If not, what is the level of difficulty to modify the standard bootloader to implement this option?

Moderate, I would guess.

As for the Zero, with 256 KB of programmable memory it probably could be implemented by changing the bootloader. Any such change will, of course, reduce the amount of memory available for other tasks, but perhaps that isn't as big a deal if you start with 256 KB.

You would have to detect the triple-click somehow, for code running right after reset this could be tricky, but possibly achievable, as you say it has been for double-clicks.

Find the source code for the bootloader, see how it detects double-clicks, make it detect triple clicks, and have your "benign" program stored in the bootloader as a block of data ready to be copied into program memory.

There are a few alternatives you could consider:

* If you have a spare pin in your project, make it so that if (say) pin 13 is grounded at startup, do nothing (other than go into a tight loop). This could be done before anything that might make reprogramming hard, like going into low power mode.
* Reprogram it using SWD programming (rather than the bootloader). I don't know the exact details for the Zero, as I don't own one, but there must be a way, otherwise you wouldn't be able to put the bootloader onto it in the first place. Judging by what I read elsewhere the Atmel ICE is the device you need to reprogram it in that way.
* Judging by what I read here you can access the bootloader by selecting Arduino Zero (programming port) as the board, and Atmel-EDBG as the programmer. Then you could tell the Atmel-EDBG to reprogram the board. My details here are hazy but you could look into that as an option.

# Answer
> 1 votes
All Arduino bootloaders for boards with native USB support double reset as a way to activate the bootloader in case the sketch doesn't respond and fails to handle the USB. (The code linked from the Arduino core to your sketch handles the USB for MCU with native USB).

The M0 Arduino bootloader source code is in Arduino SAMD boards support package. Adafruit may use a modified version. The bootloader is strange because avrdude is used to upload over this bootloader and the board reports as ATmega to avrdude.

The M0 bootloader (and the ATmega 32u4 bootloader for Leonardo and Micro) have timeout after double reset. If no upload occurs some seconds after the double reset, they start the sketch.

You want to add a triple reset to replace the sketch which doesn't respond with a save sketch which will handle the USB and allow upload at any time. This would require to change the bootloader source, build the bootloader and use a SWD programmer to burn it (or create a sketch which replaces the bootloader).

Better option is what Arduino did for the Zero and MKR bootloader. The bootloader activated with double reset doesn't timeout with this bootloader and upload is possible anytime after double reset (until next reset or power-cycle).

The original M0 and Zero are almost the same board. One was sold by arduino.org other by arduino.cc. The most important difference is the bootloader.

It is possible to use M0 board as Zero with the Zero bootloader. By replacing the bootloader, you get the double reset without timeout. Other benefits are faster upload with bossac, the bootloader is half the size of the M0 bootloader and the Zero bootloader doesn't reset the internal RTC as the M0 bootloader does.

---
Tags: bootloader, programming-sequence
---


# Question
Title: Counting to 1000 In Both cores execution time problem in esp32?
**I am trying to count to 1000 with single core and dual core with esp32 but the output(run time) dose not make sense, the time which takes a single core should be doubled compared to dual core in theory right?**

Here is the code

```
TaskHandle_t Task1;
TaskHandle_t Task2;
SemaphoreHandle_t baton;

int i = 0;
long l;

void setup() {

  Serial.begin(115200);
  pinMode(2, OUTPUT);
  pinMode(4, OUTPUT);

  baton = xSemaphoreCreateMutex();
  l = millis();
  xTaskCreatePinnedToCore(
    Task1code, /* Function to implement the task */
    "Task1", /* Name of the task */
    10000,  /* Stack size in words */
    NULL,  /* Task input parameter */
    1,  /* Priority of the task */
    &Task1,  /* Task handle. */
    0); /* Core where the task should run */

//single core or dual core execution

//  xTaskCreatePinnedToCore(
//    Task2code, /* Function to implement the task */
//    "Task2", /* Name of the task */
//    10000,  /* Stack size in words */
//    NULL,  /* Task input parameter */
//    1,  /* Priority of the task */
//    &Task2,  /* Task handle. */
//    1); /* Core where the task should run */

}
void Task1code( void * parameter) {
  while (true) {
    xSemaphoreTake(baton, portMAX_DELAY);
    xSemaphoreGive(baton);
    delay(1);// I don't understand in here without this command output result is worse
    i++;
    if (i == 1000) {
      l = millis()-1;
      Serial.print("Done ");
      Serial.print(xPortGetCoreID());
      Serial.print(" ");
      Serial.println(l);

    }if(i>1000){
      vTaskDelete(Task1);
    }
  }
}
void Task2code( void * parameter) {
  while (true) {
    xSemaphoreTake(baton, portMAX_DELAY);
    xSemaphoreGive(baton);
    delay(1);// I don't understand in here without this command output result is worse
    i++;
    if (i == 1000) {
      l = millis()-1;
      Serial.print("Done ");
      Serial.print(xPortGetCoreID());
      Serial.print(" ");
      Serial.println(l);
    }if(i>1000){
      vTaskDelete(Task2);
    }
  }
}
void loop() {

}

```

The output I get for runtime

```
Single core :- 1033 ms
Dual core :- 701 ms

```

Without `delay(1);` command the result is even more obvious

```
Single core :- 39 ms
Dual core :- 40 ms

```

How can I make my algorithm show that single core takes twice time as dual core execution time I wan't both cores to work parallel not one after the other.

# Answer
> 2 votes
For multiple cores to provide any advantage, they must be able to work independently. If they require shared access to a resource - `i` in your experiment - only one core can actually be contributing to the job at any one time. But because there are multiple, they have the additional bookkeeping to negotiate access to the shared resource. Thus the total job takes longer than it would take one core with complete access to the resource and no overhead to manage access, to do the job by itself.

# Answer
> 2 votes
Your must use the semaphore to protect the read/write access to `i` (Only one task is allowed to modify the variable at a time)

```
xSemaphoreTake(baton, portMAX_DELAY);
i = i + 1;
xSemaphoreGive(baton);

```

Additionally you should combine your `if` clauses. If both tasks increment `i`it could happen, that it will never has the value `1000`for the second task.

---
Tags: esp32
---


title: I want to turn on RGB led gradually

text:
# Question
Title: I want to turn on RGB led gradually
Why I can't use "timeA = delay" to make the lights turn on gradually. The problem is that the delay don´t work, and the led light goes directly to the last color. What I need to do in my code to fix this?

Here is my code ↓

```
// C++ code
//

void setup()
{
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

void loop(){

  static unsigned long timeA = 10;
  const long interval = 10;

  static unsigned long timeB = 10;
  const long interval2 = 10;

  static unsigned long timeC = 10;
  const long interval3 = 10;

  unsigned long delay = millis();
  static unsigned long state = 0;
  int i = 0;

  if(delay - timeA >= interval && state == 0){
    state += 1;
    for(i=0;i<=255;i++){
        analogWrite(3, i);
        analogWrite(5, 0);
        analogWrite(6, 0);
        timeA = delay;
    }
  }
   if(delay - timeB >= interval2 && state == 1){
    state += 1;
    for(i=0;i<=255;i++){
        analogWrite(3, 0);
        analogWrite(5, i);
        analogWrite(6, 0);
        timeB = delay;
    }
  }
  if(delay - timeC >= interval3 && state == 2){
   state += 1;
   for(i=0;i<=255;i++){
        analogWrite(3, 0);
        analogWrite(5, 0);
        analogWrite(6, i);
        timeC = delay;
    }
  }

}

```

# Answer
> 1 votes
You `millis()` code is not structured correctly. Lets look at what happens:

`timeA` and co are all initiated with the value 10. So as soon as the program has run 10ms, the first if statement (the one for state 0) will execute. First you increment `state`, so that the next state can be reached. Then you have a for loop without any timed code. It will execute very very fast, without giving the PWM hardware any chance to actually output the `analogWrite()` values. Then you update `timeA` (which normally wouldn't go into the for loop). We leave the if statement and reach the next one. Nearly no time has passed, since we entered the first if statement. And now we are executing the next if statement, since `state` is now 1 and the program had run for more than 10ms. Here it is the same as above.

So the program is rushing through the `analogWrite()` calls ending in the last one, since `state` is never reset, giving the last `analogWrite()` value the change to be output on the pin.

The whole structure of the code does not really make sense. I guess you wanted to do this non-blocking, thus using `millis()`. For loops are not really fitting to this and the `millis()` value has to be compared to the right values to get the order right.

**What to do now:** With the `state` variable you nearly have something that is called Finite State Machine (FSM). It is a powerful programming concept. Basically the state of the program decides, what block of code should be executed on each `loop()` iteration. This is best done via a switch statement. Then in each case we are using an if statement using the `millis()` value to decide, if it is time to execute the new `analogWrite()`:

```
void setup()
{
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

void loop(){

  static unsigned long timeA = 10;
  const long interval = 10;

  static unsigned long timeB = 10;
  const long interval2 = 10;

  static unsigned long timeC = 10;
  const long interval3 = 10;

  unsigned long delay = millis();
  static unsigned long state = 0;
  static int i = 0;

  switch(state){
    case 0:
      if(delay - timeA >= interval){
        analogWrite(3, i);
        analogWrite(5, 0);
        analogWrite(6, 0);
        i++;
        timeA = delay;
      }
      if(i > 255){
        state = 1;
        i = 0;
      }
      break;
    case 1:
      if(delay - timeB >= interval2){
        analogWrite(3, 0);
        analogWrite(5, i);
        analogWrite(6, 0);
        i++;
        timeB = delay;
      }
      if(i > 255){
        state = 2;
        i = 0;
      }
      break;
    case 2:
      if(delay - timeC >= interval3){
        analogWrite(3, 0);
        analogWrite(5, 0);
        analogWrite(6, i);
        i++;
        timeC = delay;
      }
      if(i > 255){
        state = 0;
        i = 0;
      }
      break;
  }
}

```

By setting the variable `state` we can choose, what should be executed next. The variable `i` is handling the fading of each LED, while the `interval` variables set how fast the fading occurs. This coding principle can be used in many different situations, so learning it is really worth it.

Note:

* I have not tested the above code.
* The code can still be optimized/generalized.

# Answer
> 0 votes
I think below is what you were going for. I removed the for-loop and used a static `i` variable to have each state take 256 intervals. Note that you don't need to have separate timeA/B/C variables. Using a single one would also make sure that the first "delay" actually occurs. It's not that critical for fading an led, but in other cases it might.

void setup()
{
  pinMode(3, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
}

void loop(){

  static unsigned long timeA = 10;
  const long interval = 10;

  static unsigned long timeB = 10;
  const long interval2 = 10;

  static unsigned long timeC = 10;
  const long interval3 = 10;

  static unsigned long state = 0;
  static int i = 0;

  unsigned long delay = millis();

  if(delay - timeA >= interval && state == 0){
    analogWrite(3, i);
    analogWrite(5, 0);
    analogWrite(6, 0);
    timeA = delay;

    i++;
    if( i==256 )
    {
      i=0;
      state++;
    }
  }
   if(delay - timeB >= interval2 && state == 1){
    analogWrite(3, 0);
    analogWrite(5, i);
    analogWrite(6, 0);
    timeB = delay;

    i++;
    if( i==256 )
    {
      i=0;
      state++;
    }
  }
  if(delay - timeC >= interval3 && state == 2){
    analogWrite(3, 0);
    analogWrite(5, 0);
    analogWrite(6, i);
    timeC = delay;

    i++;
    if( i==256 )
    {
      i=0;
      state++; // you probably want to use `state=0;`, so it starts over again
    }
  }

}```

---
Tags: rgb-led
---


# Question
Title: Arduino Sleep to conserve battery - How to intergrade it to existing sketch - HELP pls
My sketch below is simply using a touch sensor to activate a servo motor to go from from initial position 0 to 180 then back to 0. then I want the Adruino NANO to go to sleep to conserve some battery life.

Being a novice to programing and after many attempts to use his code and intergrade it with mine. Was unsuccessful.

so if anyone can help intergrade the gammon's sketch below into mine it would be greatly appreciated. As I'm out of ideas.

**HERE IS MY SKETCH**

```
#include <Servo.h>

// constants won't change
const int SENSOR = 2; // Arduino pin connected to motion sensor's pin 7
const int SERVO = 9; // Arduino pin connected to servo motor's pin 9

Servo servo; // create servo object to control a servo

int pos = 0; // variable to store the servo position

// variables will change:
int lastMotionState; // the previous state of motion sensor
int currentMotionState; // the current state of motion sensor

void setup() {

Serial.begin(9600); // initialize serial
pinMode(SENSOR, INPUT); // set arduino pin 9 to input mode
servo.attach(SERVO); // attaches the servo on pin 12 to the servo object

servo.write(0);
currentMotionState = digitalRead(SENSOR);
}

void loop() {
lastMotionState = currentMotionState; // save the last state
currentMotionState = digitalRead(SENSOR); // read new state

if (currentMotionState == LOW && lastMotionState == HIGH) { // pin state change: LOW -> HIGH
Serial.println("OFF");
servo.write(0);
delay(100); // waits (X)ms for the servo to reach the position
}
else
if (currentMotionState == HIGH && lastMotionState == LOW) { // pin state change: HIGH -> LOW
Serial.println("ACTIVE");
servo.write(180);
delay(2000); // waits (x)ms for the servo to reach the position
}
delay(10); // repeats program - larger delay - trigger is
}

```

**\______________________________________**

****Author:Ab Kurk** SLEEP SKETCH**

This sketch is part of the beginners guide to putting your Arduino to sleep tutorial. It is to demonstrate how to put your arduino into deep sleep and how to wake it up.

\*/

```
#include <avr/sleep.h>//this AVR library contains the methods that controls the sleep modes
#define interruptPin 2 //Pin we are going to use to wake up the Arduino

void setup() {
Serial.begin(115200);//Start Serial Comunication
pinMode(LED_BUILTIN,OUTPUT);//We use the led on pin 13 to indecate when Arduino is A sleep
pinMode(interruptPin,INPUT_PULLUP);//Set pin d2 to input using the buildin pullup resistor
digitalWrite(LED_BUILTIN,HIGH);//turning LED on
}

void loop() {
delay(5000);//wait 5 seconds before going to sleep
Going_To_Sleep();
}

void Going_To_Sleep(){
sleep_enable();//Enabling sleep mode
attachInterrupt(0, wakeUp, LOW);//attaching a interrupt to pin d2
set_sleep_mode(SLEEP_MODE_PWR_DOWN);//Setting the sleep mode, in our case full sleep
digitalWrite(LED_BUILTIN,LOW);//turning LED off
delay(1000); //wait a second to allow the led to be turned off before going to sleep
sleep_cpu();//activating sleep mode
Serial.println("just woke up!");//next line of code executed after the interrupt
digitalWrite(LED_BUILTIN,HIGH);//turning LED on
}

void wakeUp(){
Serial.println("Interrrupt Fired");//Print message to serial monitor
sleep_disable();//Disable sleep mode

detachInterrupt(0); //Removes the interrupt from pin 2;

}

```

# Answer
I'm going to guess that you are doing something like a door or safe lock, which may occasionally be used to activate a motor to unlock something but 99.99% of the time is sitting there doing nothing, and you want to save power in that time.

You need to rework somewhat.

* An interrupt to detect a switch press. Then the processor can sleep, using very little power.
* The interrupt, when it happens, wakes the processor
* You activate the motor to unlock the door or whatever-it-is.
* You put the processor into low power mode, and go back to sleep

Since my name was mentioned in the question, tips for doing low-power stuff are at this link. And here for stuff about interrupts.

Plus a slightly abridged version (due to space limitations) here on this site.

*(You aren't supposed to make answers where the answer is totally in the link, but in this case the link is just supplementary material)*
> 1 votes

---
Tags: programming, arduino-nano, c++, power, servo
---