message:
Can I check if a message has been sent successfully using Radiohead_ASK?

I'm new to Arduino programming and I'm trying to get a simple 433 MHz transmitter and receiver module working on an Arduino Uno board. Unsurprisingly, it's not working as expected and I'm trying to debug the problem.

I'm using RadioHead and read in the [documentation](https://www.airspayce.com/mikem/arduino/RadioHead/classRH__ASK.html) that the send() and waitPacketSent() methods return a boolean to indicate success. However, I disconnected the data wire and the send() method still returns true. As the module is no longer connected to the arduino I would have expected it to return false.

I understand that the messages are sent as unreliable datagrams, but I'm just trying to work out whether the transmitter has actually sent something. Is there some way I can do this?

The code I'm using is relatively short, so I've included it in full below, for what it's worth

```c
#include <RH_ASK.h>
#include <RadioHead.h>

#ifdef RH_HAVE_HARDWARE_SPI
#include <SPI.h> // Not actually used but needed to compile
#endif

RH_ASK driver;

bool sent;

void setup()
{
#ifdef RH_HAVE_SERIAL
    Serial.begin(9600);    // Debugging only
#endif
    if (!driver.init())
#ifdef RH_HAVE_SERIAL
      Serial.println("init failed");
#else
  ;
#endif
  sent = false;
}

void loop()
{
    uint8_t buf[RH_ASK_MAX_MESSAGE_LEN];
    uint8_t buflen = sizeof(buf);

    const char *msg = "hello";
    bool sendSuccess;
    bool waitSuccess;

    if (!sent) {
      Serial.println("sending");
      sendSuccess = driver.send((uint8_t *)msg, strlen(msg));
      if (sendSuccess) {
        Serial.println("Send completed successfully");
      } else {
        Serial.println("Send Error");
      }
      Serial.println("Waiting");

      waitSuccess = driver.waitPacketSent();
      if (waitSuccess) {
        Serial.println("Wait Sent Success");
      } else {
        Serial.println("Wait Sent Error");
      }
      Serial.println("Done Sending");
      sent = true;
      delay(1000);
    }

    if (driver.recv(buf, &buflen)) // Non-blocking
    {
      Serial.println("driver.recv");

      // Message with a good checksum received, dump it.
      driver.printBuffer("Got:", buf, buflen);
    }
}
```

The output on the serial monitor is as follows
>22:22:30.647 -> sending
>
>22:22:30.647 -> Send completed successfully
>
>22:22:30.684 -> Waiting
>
>22:22:30.753 -> Wait Sent Success
>
>22:22:30.753 -> Done Sending

Thanks in advance!

body:
There is no concept of "did the packet arrive", only "did it get sent" - and by "sent" I mean the data squirted out of the data pin for the attached module to send.

These 433MHz modules are dumb. Very dumb. You toggle the transmitter's pin high and low and the receiver sees that toggling, if it is in range, and toggles its output pin to mirror the signal.

The only way you can know if the packet arrived is if the receiver also has a transmitter and the transmitter also has a receiver. When a message arrives at the receiving node it sends a message back to the transmitting node to say "I got it". That takes a lot of work to get right, though. Especially since the original message may have arrived fine, but the acknowledgement didn't, and all sorts of horrible things can happen if you don't handle packet sequencing right.

Better is to pick a better module that does all these things for you, such as the nRF24L01+ with Auto-ACK turned on.


sender: user

message:
Can I get around extremely long time to setup WIFI connection WPA2 Personal?

I'm using the [Arduino Wifi Nina Library][1] to connect an [Arduino Uno Wifi Rev2][2] to wifi and then using the [Arduino HTTP Client library][3] to make HTTP post calls to the internet.

To connect the Arduino to my home Wifi Network (WPA2 Personal), I use the `WiFi.begin()` method. This method takes an excruciatingly long 4 seconds to connect to the Wifi. This seems to be a [known issue][3]. Since this methods is synchronous/blocking, my sketch is completely unresponsive during this time to any user input such as button-presses etc. I'm trying to create a proof-of-concept for a commercial-grade product. So having it go unresponsive to user-input for several seconds is unacceptable.

Is there any workaround to this? Is there a asynchronous library to achieve the same goal? Is there some other workaround? How do other people deal with this situation?

  [1]: https://www.arduino.cc/en/Reference/WiFiNINA
  [2]: https://store.arduino.cc/usa/arduino-uno-wifi-rev2
  [3]: https://github.com/espressif/arduino-esp32/issues/1675

sender: assistant

body:
4 even 5 seconds is normal for connecting to WiFi. How long takes your phone or other devices to connect?

You can connect a little faster with static IP address.

EDIT: With WiFiNINA library for Uno WiFi Rev.2, you can change the connection timeout with [`WiFi.setTimeout()`][1]. The default is 5 seconds. WiFi.begin() can end with WL_CONNECT_FAILED but if you later check the status of the connection it will eventually be connected.

----------

With esp8266 or esp32 you can make the connection persistent and it is build up immediately after boot and asynchronously. WiFiNINA library doesn't make this possible yet. Some future version will offer WiFi provisioning.

  [1]: https://www.arduino.cc/en/Reference/WiFiNINAsetTimeout


body:
For a proof-of-concept, use two Arduinos, one for WiFi and one for everything else.
The everything-else Arduino can keep your system responsive (minus the WiFi, of course, during connection time) and poll the WiFi Arduino periodically (without blocking) to find out when WiFi becomes available.


body:
I think better solution is to use ESP8266 WiFi module and Connect if needed another Arduino through GPIO pins of ESP8266.

This video will be helpful,
[https://www.youtube.com/watch?v=dWM4p_KaTHY][1]

  [1]: https://www.youtube.com/watch?v=dWM4p_KaTHY


message:
Formatting variables from a variadic function

I have a function that concatenates a print line, however I am having trouble getting some of the strings to format correctly.

Using Serial.print formats the output from **keypad.getKey()** correctly, however when I try to output the same format using **printConcatLine()** it does not give me the same output. I've tried casting it as both a char and an int...
<!-- language-all: lang-cpp -->

    void printConcatLine(const char* mask, ...) {
        va_list params;
        va_start(params, mask);

        while(*mask != '\0') {
          if (*mask == 'i') {
              Serial.print(va_arg(params, int));
          } else if(*mask == 'c') {
              Serial.print(va_arg(params, const char *));
          } else if (*mask == 'f' || *mask == 'd') {
              Serial.print(va_arg(params, double));
          }
          ++mask;
        }

        va_end(params);
        Serial.println();
    }

    char btnPressed = keypad.getKey();
      if (btnPressed) {
        Serial.print("BtnPressed: ");
        Serial.println(btnPressed);
        // Output: "BtnPressed: 1"

        printConcatLine("ci", "BtnPressed: ", btnPressed);
        // Output: "BtnPressed: 49"

        printConcatLine("cc", "BtnPressed: ", btnPressed);
        // Output: "BtnPressed: "
      }

I also tried changing:
> va_arg(params, const char *)

to

> va_arg(params, char)

which also did nothing.

How can I modify the call to **va_arg()** to properly output the same output as **Serial.print()**?

body:
With the format `"ci"`, the argument is interpreted as an integer, and
the output is correct: 49 is the ASCII code of `'1'`.

With the format `"cc"`, the argument is interpreted as a string (pointer to an
array of chars), which is incorrect.

One (bad) solution is to use the `"cc"` format and pass `&btnPressed` as
an argument. The problem with this approach is that the byte in memory
right after `btnPressed` may not be a zero, and the format expects a
NUL-terminated string.

A better approach would be to have one format for a `char` and a
different one for a string. I suggest `"c"` and `"s"` respectively. But
then you should be aware that there are special promotion rules
associated with variadic functions. When playing with your code, the
compiler reminded me of this one:

> warning: **‘char’** is promoted to **‘int’** when passed
> through **‘...’**

So the function should expect an `int`, and cast it to `char` in order
to call the correct overload of `Serial.print()`:

```c++
void printConcatLine(const char* mask, ...) {
    va_list params;
    va_start(params, mask);

    while(*mask != '\0') {
      if (*mask == 'i') {
          Serial.print(va_arg(params, int));
      } else if(*mask == 's') {
          Serial.print(va_arg(params, const char *));
      } else if(*mask == 'c') {
          Serial.print((char) va_arg(params, int));
      } else if (*mask == 'f' || *mask == 'd') {
          Serial.print(va_arg(params, double));
      }
      ++mask;
    }

    va_end(params);
    Serial.println();
}
```

Used like this:

```c++
printConcatLine("sc", "BtnPressed: ", btnPressed);
// Output: "BtnPressed: 1"
```


body:
Edgar beat me to it by a few seconds, but my answer is pretty much the same as his, so read that first.

I will however add a few extra notes and pointers:

* It's better to assign the va_args to an actual variable. That makes it both easier to read and understand what's going on, and more certain for the overloading of the print function to know what is supposed to happen (at least from the reader's perspective) that mere casting.
* Bytes and chars are promoted to integer when being passed to a variadic function, so you have to treat them as such
* `float` and `double` happen to be the same on the AVR based Arduinos, so your code will be OK there, but the same can't be said for other chips. If you want your code to be portable then you should split `float` and `double` into separate handlers since they use different sizes.
* It can be good to "pass through" unknown characters in the format string so that you can add extra formatting in there. See my example below.

Here's my variant of the same code. Note the colon and space in the format that is used to add more formatting to the output (this could be enhanced by adding a `%` before any format characters as `printf` does). I also like to use a separate pointer to iterate over the format string instead so that the original start pointer is still available if I should ever want it.

Also note the difference between `c` and `i`: use `c` to print a letter from a char, and `i` to print the number in a char instead.

```
void printConcatLine(const char *mask, ...) {
 va_list params;
 va_start(params, mask);

    char *ptr = (char *)mask;
 while (*ptr != '\0') {
  if (*ptr == 'c') {
   int c = va_arg(params, int);
   Serial.write(c);
  } else if (*ptr == 'i') {
   int i = va_arg(params, int);
   Serial.print(i);
  } else if (*ptr == 's') {
   const char *s = va_arg(params, const char *);
   Serial.print(s);
  } else if (*ptr == 'f' || *ptr == 'd') {
   // Be careful with this. It's not portable. On AVR float
   // and double are the same, but that's not the case on other
   // microcontrollers. It would be better to split them.
   double d = va_arg(params, double);
   Serial.print(d);
  } else {
            Serial.write(*ptr);
  }
  ptr++;
 }

 va_end(params);
 Serial.println();
}

void setup() {
 Serial.begin(115200);
 char btnPressed = 1;
    float flt = 3.141592653;

 if (btnPressed) {
  printConcatLine("c: sisd", 'Q', "BtnPressed: ", btnPressed, " done ", flt);
 }
}

void loop() {
}
```


body:
I recommend to use printf if you don't need float support in printf. This code produces a little smaller compiled code then the one in Majenko's answer and has the full power of the printf except of float.

    #include <StreamLib.h>

    void setup() {
        Serial.begin(115200);
        char btnPressed = 1;
        float flt = 3.141592653;

        byte b;
        BufferedPrint bp(Serial, &b, 1);

        if (btnPressed) {
            bp.printf("%c: %s %i %s", 'Q', "BtnPressed: ", btnPressed, " done ");
            bp.println(flt, 4);
        }
    }

    void loop() {
    }

With StreamLib you can of course print float with normal single print function for floats, the same as for Serial or network Client, with second parameter for the number of decimal places.

If you want to create a formatted C-string you can use the CStringBuilder of the StreamLib. It too builds the string with `print` functions and has 'printf' too.


message:
ESP32 runtime error in 2d array

I am trying to serial print the value of ```b[0][0]```.

Has to be zero but it dose not work!

**Here is the code**
```
void setup() {
  Serial.begin(115200);
  byte b[321][241];
  Serial.println(b[0][0]);
}

void loop() {

}
```
If the array is small like ```b[2][2]``` it dose work

In theory esp32 has ram of  520 KiB SRAM so can this be a problem?

**Here is the error code**
```
rst:0x8 (TG1WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:9720
ho 0 tail 12 room 4
load:0x40080400,len:6352
entry 0x400806b8
```
The code complies fine but the error gets when esp32 is running

esp32 version for arduino is 1.0.4

body:
The ESP32 uses FreeRTOS to run everything, and that includes the Arduino API. Your code is running in a thread of its own ("loopTask"), and that task by default has 8192 bytes of stack allocated to it.

```
xTaskCreateUniversal(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, CONFIG_ARDUINO_RUNNING_CORE);
```

You cannot create local variables and other stack data that totals more than 8192 bytes.

Instead you will either have to have the variable as a global variable (or static local) so it gets allocated in the global data segment, or use `new` or `malloc` to create it on the heap (and don't forget the corresponding `delete` or `free` call when you're done with it).


message:
Assigning an element of a multidimensional array to a second array

I have two arrays. The first array is a multidimensional array holding color values.

The 2nd array stores an **active** color from the 1st array.
How can I assign an element from the multidimensional **colors** array to the 2nd **EXCLUSIVE_COLOR** array?

    int colors[][3] = {
      { 255, 0, 0 },
      { 0, 255, 0 },
      { 0, 0, 255 },
      { 253, 7, 210 }
    };
    int EXCLUSIVE_COLOR[3] = {0};

I tried the following but neither seemed to work:

        EXCLUSIVE_COLOR = {
          colors[0][0],
          colors[0][1],
          colors[0][2]
        };
        // error: assigning to an array from an initializer list

        EXCLUSIVE_COLOR = colors[0];
        // error: invalid array assignment

body:
You can copy the array:

```c++
EXCLUSIVE_COLOR[0] = colors[0][0];
EXCLUSIVE_COLOR[1] = colors[0][1];
EXCLUSIVE_COLOR[2] = colors[0][2];
```

but this doesn't work in an initialization.

Alternatively, you can declare `EXCLUSIVE_COLOR` as a pointer to an
array of 3 integers:

```c++
int (*EXCLUSIVE_COLOR)[3]; // pointer to array 3 of int
```

Then you can have this point to a row of the 2D array, either by
assigning the pointer or in the initialization:

```c++
int (*EXCLUSIVE_COLOR)[3] = &colors[0];  // initialization

// Later in the program:
EXCLUSIVE_COLOR = &colors[1];
```

Note that when using this pointer, you will have to explicitly
dereference it:

```c++
for (int i = 0; i < 3; i++)
    Serial.println((*EXCLUSIVE_COLOR)[i]);
```

**Edit**: As pointed out by Juraj in a comment, you can instead make
`EXCLUSIVE_COLOR` a pointer to int. In this case you will make it point
to the first element in the row you want:

```c++
int* EXCLUSIVE_COLOR = &colors[0][0];
```

One nice thing of this approach is that you can use the “decay to
pointer” feature of the language to simplify the syntax:

```c++
int* EXCLUSIVE_COLOR = colors[0];

// Later
Serial.println(EXCLUSIVE_COLOR[i]);
```


body:
Use arrays only where appropriate:

    struct Color {byte r, g, b;};
    const Color colors[] = {
      {0,255,0},
      {255,0,0}
    };
    const Color red = colors[1];

This works without `const` as well. But you should consider using `const` wherever possible.


message:
How can I list only files that begin with "/LOG?"

Trying to list root directory of LittleFS; but only files beginging with "/LOG."

    String str;

                         if (!LittleFS.begin())
                         {
                              Serial.println("LittleFS failed to mount !");
                         }
                         Dir dir = LittleFS.openDir("/");
                         while (dir.next())
                         {

                            if(strncmp(dir.fileName().c_str(), "/LOG", 4) == 0)
                            {

                                str += "";
                                str += dir.fileName();
                                str += "";
                                str += "    ";
                                str += dir.fileSize();
                                str += "
\r\n";
                            }
                         }

                         client.print(str);

If I comment out "if(strncmp(dir.fileName().c_str(), "/LOG", 4) == 0)" and associated braces; all files list.  Code with "if(strncmp(dir.fileName().c_str(), "/LOG", 4) == 0)" no files are listed.

How can I list only files that begin with "/LOG?"

William

body:
Give a filename String to text...
```
String text = "/LOGsdfsdf";
if(text.startsWith("/LOG")){
//wee file begins with /LOG
}else{
// wops wrong file.
}
```
Look in here

https://www.arduino.cc/reference/en/language/variables/data-types/stringobject/

Method url ```startsWith("");```

https://www.arduino.cc/reference/en/language/variables/data-types/string/functions/startswith


message:
How to write to the second line of a display?

I got this 4 line display from Mouser: https://www.gravitech.us/20chbllcd.html, and I get it to work fine for lines 1 and 3 (as line 3 is just the 21st character of line 1). But I am struggling to get lines 2 and 4 working. If I understand correctly, these are "line 2" for the HD44780 controller, and I should set the DDRAM address to `0x40` before I write there.

But, when I try that, nothing happens.

I tried writing `0x04` to the DDRAM address counter, and I can see the cursor jumping there, but when I write to that address, no text shows up. If I omit the command, text pops up correctly.

Also, when changing the contrast of the display (using the potentiometer on the Vdd and Vo pins), only lines 1 and 3 change contrast.

My code:

This method I use for convenience:

    void set(int _rs, int _rw, int _d7, int _d6, int _d5, int _d4, int _d3, int _d2, int _d1, int _d0) { ... }

To set the DDRAM address to `0x40`:

    set(0,0,1,1,0,0,0,0,0,0);

The general timing and control is correct, as I can get text on the display, and also a function like "shift" works fine.

body:
 - Line 1 starts at address 0x00 | 0x80 `0b10000000` and ends at 0x13 | 0x80 `0b10010011`
 - Line 2 starts at address 0x40 | 0x80 `0b11000000` and ends at 0x53 | 0x80 `0b11010011`
 - Line 3 starts at address 0x14 | 0x80 `0b10010100` and ends at 0x27 | 0x80 `0b10100111`
 - Line 4 starts at address 0x54 | 0x80 `0b11010100` and ends at 0x67 | 0x80 `0b11100111`

That 0x80 `0b10000000`  is the HD44780 command for set DDRAM address. The other bits `0b1xxxxxx` define the address.

[![20x4 HD44780 addressing][1]][1]

You'll find more details at [Arduino with HD44780 based Character LCDs][2]

  [1]: https://i.stack.imgur.com/InxsJ.jpg
  [2]: http://www.martyncurrey.com/arduino-with-hd44780-based-lcds/


body:
You need to setup the HD44780 in 2-line mode. The command is `| 0 | 0 | 1 | DL | N | F | X | X |` with:

- DL: 0 = 4-bit / 1 = 8-bit interface
- N: 0 = 1 line / 1 = 2 lines **(this is the bit to set)**
- F: 0 = 5x7 / 1 = 5x10 font size

Most probably you have that command already in your program to set the width of the interface, but with N = 0.

*Note: The common algorithm is to send the command `0x33` three times to make sure to be in 8-bit mode. The first can be the second part of a half-done 4-bit command, possibly not changing the interface width. Then the second and third will switch into 8-bit mode. If the device is already in 8-bit mode, or gets into it in the course, it makes no harm to repeat.*

Since in 4-bit mode only D7 to D4 are used, you can change `0x33` into `0x38` to enable the 2-lines mode.


message:
SIM800L and DTH22

I am very new to arduino. I am build a model that will require SIM800L and DTH22. I want to know if I can power both from my arduino. DTH22 has a wide range of input voltage but I doubt of SIM800L. It says 3.4V-4.4V but one arduino forum said that it requires 2Amps of current. But many people simply connect it to arduino 3.3V. Can anyone with experience tell me about this? (I am asking as I fried the microcontroller in my previous project.) Should I get externel power supply or go forward with arduino?

body:
**Do not connect any GSM module to an Arduino board 3.3v**

This SimCom GSM modules like sim800L or sim800C can take burst current of 2Amp in low network area to provide proper network and another thing is that below 3.4v and above 4.4v it will shut down automatically and you will get an Undervoltage & overvoltage warning AT response on UART before shutdown.

Another thing is that the 3.3v voltage regulator on the Arduino board can only handle up to 1Amp max and above 500ma consumption its temperature will rise and near 1A even more.

So the conclusion don't provide supply to sim800l from Arduino.


message:
Assigning an empty array row to reference

int colors[][3] = {
      { 255, 0, 0 },
      { 0, 255, 0 },
      { 0, 0, 255 },
      { 253, 7, 210 }
    };
    int (*EXCLUSIVE_COLOR)[3];

I have a two-dimensional array to store some color values.
I have a 2nd array, which I am using to assign an **"EXCLUSIVE_COLOR"** from the first colors array.

What is the best method to assign a null or empty value to the **"EXCLUSIVE_COLOR"** array to be used upon initialization and when the **"EXCLUSIVE_COLOR"** is unset?

Initially I tried just assigning a default value to the array upon initialization:

    int (*EXCLUSIVE_COLOR)[3] = {0,0,0};
    //Produces an error: scalar object ‘EXCLUSIVE_COLOR’ requires one element in initializer

    int (*EXCLUSIVE_COLOR)[3] = {0};
    //assigns non-zero values to all three elements

I know that I can add a "dummy" record to the colors array to reference, when there isn't an **"EXCLUSIVE_COLOR"** set.

    int colors[][3] = {
      { 255, 0, 0 },
      { 0, 255, 0 },
      { 0, 0, 255 },
      { 253, 7, 210 },

      { 0, 0, 0, }   //dummy record
    };
    int (*EXCLUSIVE_COLOR)[3] = &colors[4];

However I wanted to know if there was a cleaner way to be able to assign an empty value to reference when a color is not set, and when the array is initialized.

body:
If you're using a pointer then there's no limit to what that pointer can point to.

The way I see it you have two sensible choices:

1. Point to a default value

This doesn't have to be in your array. It can be anything that is an `int[3]`, since that is what your array consists of.

```
int[3] nothing = {0, 0, 0};

EXCLUSIVE_COLOR = nothing;
```

This means that it's actually pointing to something valid, in this case it's actually (I assume) the colour black.  That can make it easy to deal with, since `EXCLUSIVE_COLOR[0]` will be a valid value.

2. Point to nothing

You can point your pointer to `NULL` and it will be pointing to "nothing". This means that `EXCLUSIVE_COLOR[0]` is no longer valid, which can make handling it somewhat harder. However it does allow you to distinguish between "nothing" and "black", unlike option 1.

For example:

```
EXCLUSIVE_COLOR = colors[2]; // {0, 0, 255}
...
EXCLUSIVE_COLOR = NULL; // Not pointing anywhere
```

To test if it's pointing somewhere you can simply use `if`:

```
if (EXCLUSIVE_COLOR) {
   // you have a valid entry
}
```


message:
How many LED displays can be hooked to one Arduino board?

I am new to Arduino development. I need to connect multiple led displays(between 20 and 100), such as [this one](https://www.aliexpress.com/item/32798439084.html?spm=2114.search0302.3.16.684d2ca7hUQpw6&ws_ab_test=searchweb0_0,searchweb201602_0,searchweb201603_0,ppcSwitch_0&algo_pvid=15340b91-2b67-4083-81c2-8a9077740719&algo_expid=15340b91-2b67-4083-81c2-8a9077740719-2) to an Arduino board. The led displays will be pretty far out from each other.

How can this be achieved? How can i uniquely identify the LCD displays? At this point i need some 101 orientation.

body:
> The led displays will be pretty far out from each other.

Those are I2C connected displays. I2C is not designed (though there are technologies to allow it) to operate over long distances. It's designed primarily for communication between chips within a circuit board.

> How can i uniquely identify the LCD displays?

Since you can't change the I2C address of the displays you would either need a separate I2C bus for each one or employ some form of I2C multiplexer.

All of this is getting too complicated. The more accepted way of doing this would be to have a small microcontroller directly connected to each display (one display per microcontroller) and then make the microcontrollers communicate with each other (or with a single master) over some suitable communication medium (some wireless system, or a serial bus like RS485 or CAN, for example).

You're then just rubber-stamping the units as many times as you want, and connecting them all together.


message:
Setting an array pointer to null on declaration

How can I set an array pointer to **null**?

I have a pointer to a 3 int array that I am trying to set to **null**.

> int (*EXCLUSIVE_COLOR)[3];

[Per this link][1] I was trying to set it to null upon initialization.
However this does not assign a null value to it. It assigns three 'random' integers to the array elements:

> {128, 447, 451}

How can I make it point to a **null** or **empty** value?

  [1]: https://arduino.stackexchange.com/questions/76201/assigning-an-empty-array-row-to-reference

body:
Here is a full example that shows you all thing things you have been asking over the past few days:

```
int colors[][3] = {
    {255, 0, 0},
    {0, 255, 0},
    {0, 0, 255}
};

#define NCOLOR (sizeof(colors) / sizeof(colors[0]))

int *EXCLUSIVE_COLOR = NULL;

void setup() {
    Serial.begin(115200);
    Serial.print("You have ");
    Serial.print(NCOLOR);
    Serial.println(" colors defined.");
    reportColor();
    EXCLUSIVE_COLOR = colors[2];
    reportColor();
    EXCLUSIVE_COLOR = NULL;
    reportColor();
}

void loop() {

}

void reportColor() {
    if (!EXCLUSIVE_COLOR) {
        Serial.println("Color is not set");
    } else {
        Serial.print("Color is set to ");
        Serial.print(EXCLUSIVE_COLOR[0]);
        Serial.print(",");
        Serial.print(EXCLUSIVE_COLOR[1]);
        Serial.print(",");
        Serial.println(EXCLUSIVE_COLOR[2]);
    }
}
```

You have an array of colours. You have a pointer that can point at a colour or at nothing. It starts off pointing at nothing. The code recognises that it's pointing at nothing and reports it. It gets assigned to a specific colour in your colours array. The code recognises that it's now a valid value and reports it. The pointer then gets pointed to nothing again. Again the code recognises that and tells you.

The result:

```
You have 3 colors defined.
Color is not set
Color is set to 0,0,255
Color is not set
```


message:
How To Activate H-Bridge?

My understanding of the H-bridge is, that activating in1 or in2 will direct the 12V current to the motor, so it either spins right/left. Not that in1 or in2 is the actual current passing through to the 12V motor.

These are the schematics.

I am trying to activate the H-bridge and the 12V motor by powering In1 with digital 2 from my Arduino.

The power outlet is an universal adapter connected to my wall outlet, which then goes to a breadboard power supply.

I don't have a functioning multimeter, so I cannot measure the exact current going through, but I do know, that if I place in1 in the power outlet's Vout the 12V motor spins.

Other than that, I do not have much information, and I would like to ask you guys for help as to why, the 12V motor doesn't spin when I power in1?

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

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

body:
There was no common GND between the H-Bridge and the Arduino.

The question has been solved.


message:
Efficient way to store array with repeating values?

So I have about 2000+ X and Y values where I will look up the Y value for a given X value. If I store the values naively they won’t fit in memory, however there are a lot of repeating values and the X values are arranged in numerical order so I don’t really need to store them explicitly.

So my plan is to use the 3 most common Y values and have an array for all the Y values with only 4 possible values (So using only 2 bits with a bitfield), where 0,1 and 2 corresponds to the most common Y values and 3 tells the program to go fetch the value somewhere else, and here I am thinking a hash table/tree.

Before implementing all this stuff I thought I would ask here if anyone has a better way of doing this, such as if it’s possible/recommended to use the flash memory on the arduino for this or if there’s some better way to store the data. The Y data consists of analog read values which hover around a specific value (say 800) and vary +- 20 or so. I think a histogram of the Y data follows a normal distribution, but I currently do not have enough data to tell.

body:
Without a better understanding of what the data is or how you intend to use it it's impossible to give you real recommendations.

However it is simple enough to store your data in flash memory.

Since X is just a sequential value it can, as you have noted, be ignored.

For the rest, a simple array in flash which you then read with `pgm_read_<X>()` where `<X>` is the data size that you are using.

All this can be read on the [Arduino PROGMEM Reference Page](https://www.arduino.cc/reference/en/language/variables/utilities/progmem/) although the documentation is not great.

So here's a little example:

```
const int values[] PROGMEM = {
   100, 399, 2847, 1, -497, 32, 4370
};

void setup() {
    Serial.begin(115200);
    for (int i = 0; i < 7; i++) {
        Serial.println((int)pgm_read_word(&values[i]));
    }
}

void loop() {
}
```

The casting of the return from `pgm_read_word` as an `int` is needed to interpret the sign bit properly (it returns unsigned by default).


message:
Antenna for ESP32-pico-d4

I am currently playing a bit around with the esp32-pico-4d, it does not have an onboard antenna, so an external antenna is needed, tho I don't know a lot about it so a little help would be appreciated.

I found this:

https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf

here one says that he literally just connected the antenna to ground and LNA_IN would that work?

and which antennas would you recommend? (as small as possible is only gonna be used for BLE and)

(datasheet: https://www.espressif.com/sites/default/files/documentation/esp32-pico-d4_datasheet_en.pdf)

body:
> here one says that he literally just connected the antenna to ground and LNA_IN would that work?

Yes. LNA_IN is the input to the Low Noise Amplifier - the input stage of the receiver / output stage of the transmitter.

> and which antennas would you recommend? (as small as possible is only gonna be used for BLE and)

You want one tuned for 2.4GHz. The simplest is a quarter wave dipole at 3.125cm in length. Better would be a proper 2.4GHz antenna of the kind you get on a WiFi router or some USB WiFi dongles.


body:
In my experience, an LNA connection typically implies that an antenna with a [Low Noise Amplifier](https://en.wikipedia.org/wiki/Low-noise_amplifier) is required to meet the specifications - typically for signal strength. That's not to say it absolutely won't work without it, but rather it's *typically* used.

You'll need to select an antenna first, [do some calculations](https://en.wikipedia.org/wiki/Friis_Transmission_Equation) and determine if you have enough signal to make your ESP32's receiver "happy". If your antenna doesn't deliver enough power, you'll have to add an LNA.

Wrt antennas, many boards are made today with the antennas etched from the copper. Some are quite good, and last I checked there were Gerber files available that could be used to replicate them on your PCB (assuming you use a board that meets the specs - dielectric constant is important). Another, maybe easier approach is to buy one of the miniature ceramic antennas - for example [Johanson Technology makes them](https://www.johansontechnology.com/antennas), and they're available from other mfrs through distributors - [Mouser, for example](https://www.mouser.com/Passive-Components/Antennas/_/N-8w0fa?Keyword=ceramic+antennas&FS=True). You may be able to wangle free samples - perhaps even some applications engineering support if they believe that will help them sell product!

Another source for antenna recommendations would be the [Bluetooth Consortium website](https://www.bluetooth.com/). They maintain a list of ["prequalified" vendors](https://www.bluetooth.com/develop-with-bluetooth/build/service-providers/prequalified-components-subsystems/) - including some who make antennas. There may be other resources that would be useful. And don't overlook the usual open source repositories for help... there may be some out there who are hacking the same chip.

Anyway - got carried away - hope this helps.


message:
Using HC-SRO4 sensor and looking for obstacle

I am working in TinkerCAD, I want to design and simulate a circuit in which there are following components: 1.)An Arduino board. 2.)A potentiometer 3.)An HC-SRO4 sensor 4.)An LED.
So, the sensor should be able to tell if the range that has been set via the potentiometer has any objects in it or not. And if there are one or more objects in that range then the LED should also light up. Also, the user should be able to change the range using potentiometer during simulation.
I have attached the code here, but for some reason, I don't feel satisfied. Here is a list of the possible reasons. 1.) For LED lightening up, I had to use another ```if else``` , since it was showing an error ```else used without a previous if``` if I used LED in the same ```if else```2.) The theoretical range for the sensor I have used is ```2cm-400cm``` but in my circuit, it was not showing the upper range as ```400cm```.
Please tell the possible solutions. Also, can I improve my code and circuit

Here is the code which I used.
```
const int echoPin = 6;
const int pingPin = 7;

void setup()
{
 Serial.begin(9600);//Starting serial terminal
}

void loop()
{
  int sensorValue = 0;//Setting variable
  int mappedValue = 0;
  const int potentiometerRange = 0;//setting the buttons to variables to avoid confusion.
  long distance;//declaring a varible in loop because we can change the range during runtime.
  long actualDuration;//...
  long duration;
  pinMode(A0,INPUT);
  pinMode(11,OUTPUT);
  digitalWrite(11,LOW);//
  sensorValue = analogRead(potentiometerRange);//reading the potentiometer value.
  mappedValue = map(sensorValue,0,1023,2,400);//mapping the value accordingly for ultrasonic sensor.
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);//to ensure a clean high pulse later
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);//to trigger the ping.
  delayMicroseconds(10);
  digitalWrite(pingPin, LOW);
  pinMode(echoPin,INPUT);//noe echo which tuns low in the time when waves return back.
  duration =  pulseIn(echoPin,HIGH);//time calculated by sensor
  //calculation of distance from any object
  actualDuration = duration/2;//reducing the time in half for the distance is half only.
  distance = 0.0343*actualDuration;//keeping in mid that speed of sound is 343 m/s and pulseIn returns time in microseonds.
  if(mappedValue>=distance)//checking if the object is in range
    Serial.println("YES");
  else
    Serial.println("NO");
  if(mappedValue>=distance)
    digitalWrite(11,HIGH);
  else
    digitalWrite(11,LOW);
   delay(500); // Delay a little bit to improve simulation performance
}
```
I'm also attaching the picture of my circuit.

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

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

body:
There's not much code there, so not much to optimize. I will however show you how to combine your two `if`s.

You have:
```
if(mappedValue>=distance)//checking if the object is in range
    Serial.println("YES");
  else
    Serial.println("NO");
  if(mappedValue>=distance)
    digitalWrite(11,HIGH);
  else
    digitalWrite(11,LOW);
```

and I guess you tried this:

```
if(mappedValue>=distance)//checking if the object is in range
    Serial.println("YES");
    digitalWrite(11,HIGH);
  else
    Serial.println("NO");
    digitalWrite(11,LOW);
```

That would be correct in Python where the indenting matters (oh how that brings back the PTSD of having to work with COBOL...) but not in C.  In C indenting is ignored completely. It's only there for our benefit in reading the flow of code.

Instead to group statements together within an `if` or an `else` (or any other conditional or loop structure) you wrap those statements in a *block*. That is, place `{` before it and `}` after it.  Thus:

```
if(mappedValue>=distance)//checking if the object is in range
{
    Serial.println("YES");
    digitalWrite(11,HIGH);
}
  else
{
    Serial.println("NO");
    digitalWrite(11,LOW);
}
```

Or with my preferred formatting:

```
if(mappedValue>=distance) { //checking if the object is in range
    Serial.println("YES");
    digitalWrite(11,HIGH);
} else {
    Serial.println("NO");
    digitalWrite(11,LOW);
}
```


message:
Running hardware interrupt function on NodeMCU ESP8266, Exception(0) after four iterations, can't disarm interupt function

I've been trying to test the stability and consistency of hardware interrupts on my NodeMCU ESP8266. I'm using the Arduino IDE. This sketch should not require any external circuitry and I think, but am not certain that the problem is a value overflowing somewhere. **QUESTION 1: Can anyone point out where the problem that's causing Exception(0)?**

The hw_timer_* functions are documented in the [ESP8266 NONOS SDK reference pdf](https://www.espressif.com/sites/default/files/documentation/2c-esp8266_non_os_sdk_api_reference_en.pdf). The hw_timer_* declarations where not found by the Arduino IDE after I set it up with the [board manager url here](https://arduino.esp8266.com/stable/package_esp8266com_index.json), so I copied [hw_timer.h](https://raw.githubusercontent.com/espressif/ESP8266_NONOS_SDK/master/driver_lib/include/driver/hw_timer.h) and [hw_timer.c](https://raw.githubusercontent.com/espressif/ESP8266_NONOS_SDK/master/driver_lib/driver/hw_timer.c) from the Expressif github repo into the same folder as my .ino file. The interrupt functions run now, but after four iterations, I get the exception & a stack dump and then the board reboots with this rst message:
```
 ets Jan  8 2013,rst cause:4, boot mode:(3,6)
```
The code of my sketch is here. You shouldn't need any pins or anything.
**EDIT:** I added `volatile` before the 3 vars referenced in interrupt and in the other fns.
```
#include "user_interface.h";
#include "hw_timer.h";
#include "hw_timer.c";

// interrupt interval used for my hw_timer
#define timerInterval 100

// the number of cycle count samples we collect before analyzing
#define totalSamples 500

volatile uint32_t cycleSamples[totalSamples];
volatile uint16_t cycleSampleCount = 0;

// calculate min/max/mean
uint32_t elapsedCycles; // the number of cycles elapsing between two samples
float elapsedSum = 0; // cycles are large numbers...just in case we exceed 2^32 we use a float
uint32_t elapsedMax = 0;
uint32_t elapsedMin = 0xFFFFFFFF;
uint32_t elapsedCount = 0;
float elapsedMean;

// for std dev calculation
float diffSumSquared = 0;
float variance = 0;
float stdDev = 0;

// set to true by the timer fn when it has gathered the samples
volatile bool analyzeSamples = false;

// The hardware timer callback function must NOT be defined with ICACHE_FLASH_ATTR.
// Interrupt callback functions must be in IRAM, because the flash may be in the middle
// of other operations when they occur. Do this by adding the ICACHE_RAM_ATTR attribute
// on the function definition
// @see https://arduino-esp8266.readthedocs.io/en/latest/reference.html#interrupts
ICACHE_RAM_ATTR void my_timer_callback(void) {

  if (analyzeSamples) {
    // if this fn has collected all the samples, we have to skip this until it’s finished analyzing them
    // and resets this
    return;
  }

  if (cycleSampleCount >= totalSamples) {
    // we can't disable this timer
    analyzeSamples = true;
    return;
  }

  // take a peek at the cycles counter to check timing accuracy
  cycleSamples[cycleSampleCount] = ESP.getCycleCount();
  cycleSampleCount++;

}

void setup() {

  Serial.begin(115200);

  for(uint8_t i=5; i>0; i--) {
    Serial.printf("counting %d\n", i);
    delay(1000);
  }

  // START THE SAMPLE TIMER USING HARDWARE INTERRUPTS
  // use NMI_SOURCE for highest priority and quickest/most accurate timing
  hw_timer_init(NMI_SOURCE, 1);
  hw_timer_set_func(my_timer_callback);

  // If NM is used as the ISR source for auto-loading the timer, parameter val of hw_timer_arm can not be less than 100
  hw_timer_arm(timerInterval);

}

void loop() {
  // TODO we need to do something nondeterministic here to see if it fucks up timing of interrupts

  if (analyzeSamples) {

    // this doesn’t work to try and disable the interrupt fn
    // hw_timer_set_func(0);
    // nor does this
    //hw_timer_arm(0);

    Serial.println("Sampling complete, analyzing...");

    elapsedSum = 0; // cycles are large numbers...just in case we exceed 2^32 we use a float
    elapsedMax = 0;
    elapsedMin = 0xFFFFFFFF;
    elapsedCount = 0;

    // we loop from the 1th (i.e, the second) item
    for(uint32_t i = 1; i<totalSamples; i++) {
      elapsedCycles = cycleSamples[i] - cycleSamples[i-1];
      Serial.printf("%d %d\n", i, elapsedCycles);
      elapsedSum += (float)elapsedCycles;
      elapsedMax = max(elapsedMax, elapsedCycles);
      elapsedMin = min(elapsedMin, elapsedCycles);

      elapsedCount++;
    }
    // calculate mean
    elapsedMean = elapsedSum / (float)elapsedCount;
    Serial.print("Average elapsed cycles: ");
    Serial.println(elapsedMean);
    // report min/max
    Serial.print("Elapsed cycles max: ");
    Serial.println(elapsedMax);
    Serial.print("Elapsed cycles min: ");
    Serial.println(elapsedMin);

    // calculate the variance/std dev
    diffSumSquared = 0;
    for(uint32_t i = 1; i<totalSamples; i++) {
      elapsedCycles = cycleSamples[i] - cycleSamples[i-1];
      diffSumSquared +=  sq(elapsedCycles - elapsedMean);
    }
    variance = diffSumSquared / elapsedCount;
    Serial.print("Variance: ");
    Serial.println(variance);
    stdDev = sqrt(variance);
    Serial.print("Std Dev: ");
    Serial.println(stdDev);

    // reset the samples to zero and let's try again
    Serial.println("Gonna reset...");

    ets_intr_lock( ); //close interrupt
    for(uint32_t i = 0; i<totalSamples; i++) {
      cycleSamples[i] = 0;
    }
    cycleSampleCount = 0;
    analyzeSamples = false;
    interrupts();
    ets_intr_unlock(); //open interrupt
    system_soft_wdt_restart();

    Serial.println("Reset complete.");

//    stopStopStop = true;

  } else {
    Serial.println("not yet!");
  }
  Serial.println("sleeping 1...");
  delay(1000); // sleep 1000ms

}
```

This brings me to **QUESTION 2: How do you disarm/cancel a hw_timer?** As you can see in this code, I've tried setting the FN to zero and/or null and I've also tried setting hw_timer_arm(0).

The exception and stack dump seem to consistently happen after the `sleep 1...` debug message which corresponds to the end of the loop() function. Some typical debug output:

```
// useful and happy output above right up to this point
497 8000
498 8000
499 8000
Average elapsed cycles: 8000.00
Elapsed cycles max: 8263
Elapsed cycles min: 7738
Variance: 396.13
Std Dev: 19.90
Gonna reset...
Reset complete.
sleeping 1...

Exception (0):
epc1=0x40201030 epc2=0x00000000 epc3=0x400043a3 excvaddr=0x00000000 depc=0x00000000

>>>stack>>>

ctx: sys
sp: 3ffedf20 end: 3fffffb0 offset: 0190
3ffee0b0:  00000000 00000000 00000000 4010480d
3ffee0c0:  40105513 00000000 00000000 00000000
3ffee0d0:  00000010 00000000 00000000 40000f68
3ffee0e0:  00000004 00000000 40000f58 00000000
3ffee0f0:  60000200 3fffeed0 00000002 7c097c08
// giant stack dump continues....

```

Any help would be much appreciated.

body:
So these [docs](https://arduino-esp8266.readthedocs.io/en/latest/boards.html#rst-cause) say that RST cause 4 is **watchdog reset**. Evidently arduino has a [watchdog timer](https://create.arduino.cc/projecthub/rafitc/what-is-watchdog-timer-fffe20) to check and make sure that your program isn't stuck in an infinite loop. Therea are some tips in that link on how to avoid this reset. Generally speaking, you need to make sure your loop doesn't spend too much time doing any one thing or handling too many interrupts or it might start to get overwhelmed and then the arduino code can't get around to all the housekeeping it has to do.

Regarding the disabling of a hardware timer function, I [posted an issue](https://github.com/espressif/ESP8266_NONOS_SDK/issues/318) on the ESP8266 github repo and someone offered what looks like a helpful response, which I have not tested. They suggest:

>Call hw_timer_init with second argument = 0; then in your ISR call hw_timer_arm() if you want to keep it going and do not call it if you want to "disarm."


message:
Power MPU 6050 module through pin AD0

**TL;DR**: is it safe to power a MPU 6050 module through its AD0 pin instead of VCC?

We managed to have two MPU 6050 modules on the same I2C buffer by changing the address of one of them by connecting its AD0 pin to the same current origin used for VCC.

We found out that we can get the same result if we just switch the power cable which goes to the VCC pin to the AD0 pin: the module changes its address and we are able to read its data normally.

This would be a better configuration for us because, if the AD0 cable ever got disconnected, we wouldn't get anything from the second module but we would still get uncorrupted data from the first one. In the other case (cable to both VCC and AD0), if the AD0 cable got disconnected, we would get corrupted data.

So the final configuration would be: GND, SCL, SDA pins connected normally, power to AD0, pin VCC left unconnected.

The question is: is this a safe configuration or is it better to just leave the VCC pin connected normally and get another cable to the AD0?

From empirical tests it looks like it works fine, but we couldn't find any confirmation and are not experts on the matter.

body:
Theoretically that should be OK.

According to the [datasheet](https://invensense.tdk.com/wp-content/uploads/2015/02/MPU-6000-Datasheet1.pdf) the MPU6050 consumes no more than 3.9mA with all the internal options turned on. That is below the limit of 25mA sustained current from a single IO pin for the ATMega chips. Just be aware of the total limit of the ATMega's power pins of 200mA, but it would take a lot of modules to reach that limit.

Since the MPU6050 is a 3.3V device your modules most likely have a voltage regulator on them to allow powering from 5V. That should mitigate any voltage droop caused by the higher impedance of using an IO pin as a voltage source.


message:
Send data before raising edge of a Clock

I'm trying to control a LED strip that has a custom protocol (developed above of I2C).

But in my tests i was successful figuring out how it works :

You set Clk to zero , you send a bit in the data line , then you set Clk to high. Based on the pixels number , i should send 16bits for each color (Red Green Blue).

I was able to generate a Clock signal at 8MHz with this code :

    const byte Clock = 9;
    const byte Data = 10;

    void setup ()
    {
     pinMode (Clock, OUTPUT);
     pinMode (Data, OUTPUT);
     digitalWrite(Data, HIGH);
     TCCR1A = bit (COM1A0);
     TCCR1B = bit (WGM12) | bit (CS10);
     OCR1A =  0;
     }

     void loop ()
     {
     ...
     }

**My questions :**
How could i send data at that specific time when the clock is at zero ?

Note that using digitalWrite() function was not working due to the frequency limitation of that function.

Thanks for any helpful information.
[![enter image description here][1]][1]

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

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

  [1]: https://i.stack.imgur.com/1nNuR.jpg
  [2]: https://i.stack.imgur.com/XtzXG.jpg
  [3]: https://i.stack.imgur.com/wul5y.jpg

body:
It sounds like you have some misconceptions.

In order to work with clocked signals like in SPI, you set your data line(s) to the desired value, and then raise the clock signal from low to high. The receiving device detects the low to high transition and reads the state of the data lines.

If you did it in the other order (switch the clock signal from low to high, then set the data pin(s).) then the receiver would detect the clock rising edge and try to read the data value before it was set correctly.

With a clock line like in your setup, the communication doesn't rely on fixed timing. The clock line tells the receiver when the data is available, and you can use whatever clock timing you want (up to the max speed supported by the hardware.)


body:
After a night of continuous tests i figure out how to control correctly the LED strip using the following :

1- To apply any RGB value (a pixel) you have to send a compete frame of data to all the pixels. In my strip i have 12 pixels ,so to turn for example the first pixel into red , i have to send 11 zero pixels then the red pixel.

2- The delay and timing as mentioned above by @Majenko was the key, you just set the data and pulse the clk , that easy.

3- the protocol used isn't SPI or I2C , it's a custom protocol based on a custom driver developed by a private company (not a driver for general use or market , it was dev for a big wall lighting project).

    #define setPin(b) ( (b)<8 ? PORTD |=(1<<(b)) : PORTB |=(1<<(b-8)) )
    #define clrPin(b) ( (b)<8 ? PORTD &=~(1<<(b)) : PORTB &=~(1<<(b-8)) )
    #define Data 7
    #define Clk 9

    void setup() {
    pinMode(Data,OUTPUT);
    pinMode(Clk, OUTPUT);
    Serial.begin(9600);
    }

    void loop() {
    int i, j, k, q, r, lim_j, lim_i;
    int red, green, blue;
    for(k=0; k<12; k++)
    {
    r= k%3;
    lim_j = 2 - r;
    q = k/3;
    lim_i = 3 - q;
    Serial.print(lim_i); Serial.println(lim_j);
    clrPin(Clk);
    delayMicroseconds(5);
    setPin(Clk);
    delayMicroseconds(5);

    for(i=0; i<4; i++)
    {
      for(j=0; j<3; j++)
      {
        if(i==lim_i && j==lim_j)
          one_pixel(1200, 0, 0);
        else
          one_pixel(0, 0, 0);
      }
    }
    clrPin(Clk);
    delay(1000);
    }
    }

    int one_pixel(int red, int green, int blue)
    {
    rapid_serialize(red);
    delayMicroseconds(5);
    rapid_serialize(green);
    delayMicroseconds(5);
    rapid_serialize(blue);
    delayMicroseconds(5);
    clrPin(Clk);
    }

    inline void rapid_serialize (uint16_t color) //just a copy for now , not a pointer
    {
    uint16_t bit_shift = 32768;
    while (bit_shift)
    {
     clrPin(Clk);
     bit_shift = bit_shift>>1;
      if ((bit_shift & color) == 0)
          clrPin(Data);
      else
          setPin(Data);
     delayMicroseconds(5);
     setPin(Clk);
     delayMicroseconds(5);
      }
     }


message:
ESP01 and Arduino - Serial port confusion

I'm trying to understand how to think about ESP01 devices and arduino connectivity

I purchased one of the [USB programmers][1] from Ebay to program the ESP01 - this works nicely, I can see the ESP doing things (I have it pinging a server sending data back and forth)

Obviously, the ESP01 has very few GPIO pins, so I'm interested in connecting to an arduino so I can combine the Arduino's IO with the Wifi on the ESP, and this is where I'm getting a little stuck. I'm assuming I have to connect the RX pin on the Uno to the TX on the ESP and the TX on the Uno to the ESP RX to set up the connection, but I'm confused as to which serial port to use on the Uno.

Specifically:

- are the TX/RX pins on the arduino actually the same serial port as the USB connector - i.e if my intent is to plug the arduino into a computer to talk to it over USB, should I not then re-use the TX/RX pins to talk to the ESP

- if so, should I look to software serial or something similar and use other IO pins on the arduino to connect to the ESP01

... Also, as an aside, if I get this all working, do I still need the USB programmer, or can I then program directly from the arduino?

  [1]: https://www.ebay.co.uk/itm/ESP-01-ESP8266-Switchable-USB-Adaptor-Programmer-CH340G-UK-Seller/322466871464?ssPageName=STRK:MEBIDX:IT&_trksid=p2057872.m2749.l2649

body:
The Arduino UNO only has one serial port. That is pins 0/1 (RX and TX), which is mapped to the `Serial` object.

Those pins and that object are also used for communication with the PC through the USB connection. That means you can't easily use them for both PC communication and ESP8266 communication. It's possible, but it gets messy.

That is why many people use `SoftwareSerial` because that can work on any combination of pins on the Arduino that you like.

> ... Also, as an aside, if I get this all working, do I still need the USB programmer, or can I then program directly from the arduino?

Again, that is possible, but very messy. You could possibly get things to pass through from `Serial` to a `SoftwareSerial` instance, but it's not reliable (`SoftwareSerial` in general is not reliable for sustained transfers of data), and using the Arduino as a dumb UART interface would entail changing the wiring to pins 0/1 when you wanted to program.

So it's far simple to just use your USB interface for programming. Either that or set up OTA programming for the ESP8266 so you don't even have to use wires.


message:
How can I use multiple 7-segment displays in Tinkercad

I need to connect five 7-segment displays using Tinkercad.

We know that Tinkercad doesn't have an Arduino Mega to use its pins.

How can I do this without the Arduino Mega?

body:
It sounds like you will need to multiplex them.

Assuming common cathode LEDs:

Set up a transistor for each digit that activates the ground for that digit. (Lighting all the segments of a digit will probably exceed the max current sink of one of your digital pins.) You may be able to drive a single segment directly from an output pin, assuming it's current draw is ≤20 mA. If the segments draw > 20 mA then you will likely need transistors for the segment drivers as well. (The max output of a pin on most Arduinos is actually 40 mA, and if the average current when multiplexed across 5 digits is < 20 mA, you might get away with drawing up to 40 mA per segment. I'd ask somebody with more electronics experience than me to confirm this.)

Write your code to switch one digit's ground on at a time, after turning on the desired anode (segment) pins. Cycle through the digits rapidly and they will all appear to be on at the same time.

The pseudo-code:

    setup {
       digit index = 0
       turn all pins (segment anodes and digit cathodes) to open state
    }

    loop {
       set up segments pins for digit[index]
       Turn on cathode for that digit
       short delay to allow segments of current digit to glow
       turn off cathode (ground) of current digit
       digit index = (digit index + 1) % num_digits
    }

The above would require a digital pin for each segment, and a pin for the ground of each digit. (7 + 5 = 12 digital pins total.) Without multiplexing, you'd need 7x5 = 35 digital pins, and would still have to make sure you didn't exceed the total current output limits of the Arduino. (35 segments x 20 mA/segment would be 700 mA total.) Most Arduinos have a total current output of no more than 200 mA across all pins, so you could not light up all the segments of more than 2 digits at once, assuming 20 mA/segment.)

Note that it might be easier to ignore all of the above and get a serial LED display driver like a MAX7219. You just need 2 digital lines to drive that, and it will control 8  8-segment digits (7 segments plus a decimal point at each position)


message:
Writing and Reading data from RTC module EEPROM_Arduino

i have took below code from https://lastminuteengineers.com/ds1307-rtc-arduino-tutorial/. i am not understand what these codes are doing. please help me to understand.

    Wire.write((int)(eeaddress >> 8)); // MSB
    Wire.write((int)(eeaddress & 0xFF)); // LSB

Thanks

body:
These two lines write a 16 bit (2 8-bit) value, which is signed -32768..32767 or unsigned 0..65535.

Assume a value in bits: 10101010 11001100

Statement 1:

    Wire.write((int)(eeaddress >> 8)); // MSB

The first statement shifts the value 8 bits (positions) to the right; this is called the MSB (Most Significant Byte, the left 8 bits). Bits on the right are clipped / fall off. Thus

    10101010 11001100

will become

    00000000 10101010

When casted to an 8 bit value you get:

    10101010

Statement 2:

    Wire.write((int)(eeaddress & 0xFF)); // LSB

The second statement will get the LSB (Least Significant Byte). This used the AND operator, meaning a bit is only 1 if both values are 1. 0xFF is the 'mask'

    Original value: 10101010 11001100
    Mask:           00000000 11111111
                    ----------------- AND (&) operator
    Result:         00000000 11001100

As you can see only the right 8 bits are kept. When casting this to an 8 bit value:

    11001100


message:
Sine wave using arduino uno

I am an adruino hobbyist, i want to make sine wave using arduino uno,
for that i using timer0 as interrupt, OCR0A set to 17 for 3.6khz interrupt(16000000/(100hz*36 interval)/256-1),
If i am using only one pwm pin i am getting correct frequency but when i enable two pwm pin i am getting only half if the frequency, kindly advise what is wrong and how to correct it.
.................................
This code i am getting correct frequency at PWM pin 9.

//

    ISR(TIMER0_COMPA_vect)
    {
    OCR1A=(256+((((sin(num*3.14/180))*256))))/2;
    //OCR1B=(256+((((sin(num*3.14/180))*256))))/2;
         num=num+10;
        if(num >= 360)
    {
           num = 0;
        }
    }

//
............................
This code i am getting only half of the previous frequency at PWM pin 9,10

//

    ISR(TIMER0_COMPA_vect)
    {
    OCR1A=(256+((((sin(num*3.14/180))*256))))/2;
    OCR1B=(256+((((sin(num*3.14/180))*256))))/2;
         num=num+10;
        if(num >= 360)
    {
           num = 0;
        }
    }

//

body:
You are doing complex calculations inside an Interrupt Service Routine. This is not a good idea. Computing sines takes a large amount of time as this consists of multiple, complex floating point operations. Interrupt Service Routines should be short and as simple as possible.

This is probably the reason you can't have two PWM signals active at the same time at the same frequency. The ISRs simply take too long.

The solution would be to pre-calculate the desired waveforms or greatly simplify the waveform calculations (preferably without floating point). If you decide to pre-calculate, take care to stay within the limited amount of memory you have available on your Arduino. You can minimize the memory used by calculating and storing just 1/4 of a complete waveform and constructing the remaining 3/4 from these values.

This leaves the conversion of your PWM output to a real sine wave. How are you planning to do that?


message:
Come out of loop and execute Setup again

I want to end loop at a specific time and start setup again. Is this possible? (I can explain reason in case you require).

body: Not directly, no. You can reboot the Arduino though so everything starts from scratch (either through the watchdog timer or wiring a GPIO pin to RESET and pulling it LOW), but if you find you need to do this sort of thing then you should rethink your methodology so that you don't need to do this sort of thing.


body:
You could just call `setup()` yourself:

```c++
void loop() {
    if (some_condition) {
        setup();  // reinitialize everything
        return;
    }
    // etc.
}
```

But, as Majenko puts it, if you nee to do that it looks like there is
something wrong with your methodology.

That being said, it would be less suspicious if you only need to
reinitialize some specific part of your program. In this case you can
make a separate function for these initializations, and call it both
from `setup()` and, when needed, from `loop()`:

```c++
void init_foo() {
    // ...
}

void setup() {
    init_foo();
    // other initializations...
}

void loop() {
    if (some_condition) {
        init_foo();  // reinitialize foo
        return;
    }
    // etc.
}
```


message:
Make a code loop 100 times with a text on Serial Monitor

Ok, this is my code:

    int rosso = 13;
    int verde = 12;
    int blu = 11;
    int count = 0;
    String command_on, command_off;
    String s;
    String enough = "stop";

    void setup(){
      pinMode(rosso, OUTPUT);
      pinMode(verde, OUTPUT);
      pinMode(blu, OUTPUT);
      Serial.begin(9600);
      command_on = String("on");
      command_off = String("off");
    }

    void redToBlue(){
      if(count < 100) {
      rgb(0,255,0);
      delay(100);
      rgb(0,0,0);
      delay(100);
      rgb(255,0,0);
      delay(100);
      rgb(0,0,0);
      count = count+1;
      }
    }

    void switchOff(){
      rgb(0,0,0);
      delay(100);
    }

    boolean wait_command(){
      if(s == command_on){
        redToBlue();
      }
      if(s == command_off){
      switchOff();
      }
    }

    void accendi(){
      if(s == command_on){
      redToBlue();
      }

      if(s == command_off){
      switchOff();
      }
    }

    void rgb(int r, int g, int b){
      analogWrite(rosso, r);
      analogWrite(blu, b);
      analogWrite(verde, g);
    }

    void loop(){
     s = Serial.readString();
     Serial.println("What I have to do? ");
     wait_command();
    }

When I open the Serial Monitor and type "on" there, the redToblue() function must loop 100 times. But in my case loops only one time then it stops. I think I have to change something inside loop() function and on redToBlue()...

body:
I'm not sure exactly what you want, but if you expect after a single command `on` to have it looped 100 times, you need to call the `redToBlue` function in every loop (within `wait_command`, that checks for a boolean if the `on` command has been requested, and when so, call the `redToBlue` function. When the `off` command is set, you reset the boolean.

Also `wait_command` is not a good name, as it does not wait for a command, but processes it.


body:
You `loop()` function is the one that will be called when the program runs and it will keep looping around until you stop it.  So at the moment you have `loop()` doing the following:

 1. Reading a string from the serial connection
 2. Displaying a message to the serial connection
 3. Parsing the string that was read and acting upon it.

So when your code runs you see it print the message and maybe do something with the light and then it stops/freezes.  Its not really frozen, its waiting for you to enter an answer.

So if you really want it to ask what to do and then then loop 100 times you need to do this:

 1. Display the message.
 2. Read the data.
 3. Call `wait_command()` (after you have modified it)

   void redToBlue(){
      for (int count = 0; count < 100; ++count) {
    rgb(0,255,0);
    delay(100);
    rgb(0,0,0);
    delay(100);
    rgb(255,0,0);
    delay(100);
    rgb(0,0,0);
    }
    } ***// Sorry I can't get the code to format.***

I think you could also refactor the function to loop over an array of 4 rgb values.  I don't now if that would be better for the processor, it would look nicer :)


message:
Problem on color mixing lamp on Proteus Arduino starter kit

I set the circuit and couldn't illuminate, where is the problem?

[![my circuit on proteus][1]][1]

[![original arduino circuit][2]][2]

Fritzing: https://fritzing.org/media/fritzing-repo/projects/c/color-mixing-lamp/images/Arduino Lamp Project.png

  [1]: https://i.stack.imgur.com/DuDbY.png
  [2]: https://i.stack.imgur.com/jMi94.png

body: just fixed by using TORCH LDR instead of normal LDR. FULLY WORKS.


message:
Relative position using Accelerometer

I have a simple scenario please:

Two Arduino Nano 33 IoT devices started moving randomly from the same exact origin(Point = [X0, Y0, Z0]);

Can I use the coordinates queried from each device Accelerometer to get the Euclidean Distance between them?

In other words, Is the relative coordinate/position retrieved from the Accelerometer reliable?

Because I read that getting the relative position every time requires double integrations which leads to big accumulated error over time. Though I might be totally wrong.

Your help is very much appreciated.

body:
What you heard (about double integration and accumulating errors) is correct. Mathematically, you can do this, by integrating each device's acceleration to get its current speed, and integrating the speed to get it's current position, then taking the vector difference in the their positions to get the distance between them.

*If* you had highly accurate accelerometers in a very noise-free environment (both mechanical and electrical noise), you could do it for a (short) while before the inevitable tiny errors (which are also being integrated!) begin to dominate the data and make the results useless. But as a practical matter - especially for us experimenters using inexpensive equipment and subject to a lot of mechanical and electrical noises on the experimental platform, plus environmental electrical noise - this will happen even more quickly.


message:
Boolean Logic With Chars For Motor Input Selection

Context of the code:

I am trying to control 2 DC motors through an H-gate, this means there are 4 inputs in total:
For DC motor 1: Input 1 (VCC) and Input 2 (GND).
For DC motor 2: Input 3(VCC) and Input 2 (GND).

Summary of the code:

The global variables are motinpN which are the pins connected to the different inputs.

An array, which is where the different PWM for the motor speeds are stored.

Char x, which is the variable used for the boolean logic.

Then comes the actual loop which consists of 4 similar functions, the "input selector" function and then the statements that turn the integers stored in the inpSpeedS[] arrays into motor speeds.

The issue:

The code won't enter the first loop, i.e it won't advance past

 Serial.println("X equals:");
  Serial.print(x);"

I would like to know then, what I am doing wrong in order for this not to work?

       int Speed = 0;
    const int motinp1 = 2;
    const int motinp2 = 3;
    const int motinp3 = 4;
    const int motinp4 = 5;

    char  x = '0';

    int inpSpeedS[4]; // An array to determine the speed of each individual input

    void setup()
    {
      Serial.begin(9600);
      pinMode(motinp1, OUTPUT);
    }

    void loop() {
      Serial.println("X equals:");
      Serial.print(x);

      if (Serial.available () && (x == '0')) {
        Serial.print("Which input?");
        x = Serial.read();
        Serial.println(x);
      }
      if (Serial.available () && (x == 'a'))
      {
        Serial.println("Input 1 selected");
        inpSpeedS[0] = Serial.parseInt();
        Serial.print("Input 1: ");
        Serial.println(inpSpeedS[0]);
       x = '0'; //reset x, goes back to input selection
      } if (Serial.available () && (x == 'b'))
      {
        Serial.println("Input 2 selected");
        inpSpeedS[1] = Serial.parseInt();
        Serial.print("Input 2: ");
        Serial.println(inpSpeedS[1]);
       x = '0';
      }
      if (Serial.available () && (x == 'c'))
      {
        Serial.println("Input 3 selected");
        inpSpeedS[2] = Serial.parseInt();
        Serial.println("Input 3: ");
        Serial.print(inpSpeedS[2]);
       x = '0';
      }
      if (Serial.available () && (x == 'd'))
      {
        Serial.println("Input 4 selected");
        inpSpeedS[3] = Serial.parseInt();
        Serial.print("Input 4: ");
        Serial.println(inpSpeedS[3]);
       x = '0';
      }
      analogWrite(motinp1, inpSpeedS[0]);
      analogWrite(motinp2, inpSpeedS[1]);
      analogWrite(motinp3, inpSpeedS[2]);
      analogWrite(motinp4, inpSpeedS[3]);
    }
EDIT - I have turned the char 0 from a string literal null to an ASCII code for 0, and same for the other chars. It is still stuck outside of the function loops.

body:
It's screaming on you:

    sketch_jun13a.ino:7:11: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

     char  x = "0";

               ^~~

    sketch_jun13a.ino: In function 'void loop()':

    sketch_jun13a.ino:21:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

       if (Serial.available () && (x == "0")) {

                                        ^~~

    sketch_jun13a.ino:21:36: warning: ISO C++ forbids comparison between pointer and integer [-fpermissive]

    sketch_jun13a.ino:26:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

       if (Serial.available () && (x == "a"))

                                        ^~~

    sketch_jun13a.ino:33:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

         x = "0"; //reset x, goes back to input selection

             ^~~

    sketch_jun13a.ino:34:38: warning: comparison with string literal results in unspecified behavior [-Waddress]

       } if (Serial.available () && (x == "b"))

                                          ^~~

    sketch_jun13a.ino:41:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

         x = "0";

             ^~~

    sketch_jun13a.ino:43:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

       if (Serial.available () && (x == "c"))

                                        ^~~

    sketch_jun13a.ino:50:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

         x = "0";

             ^~~

    sketch_jun13a.ino:52:36: warning: comparison with string literal results in unspecified behavior [-Waddress]

       if (Serial.available () && (x == "d"))

                                        ^~~

    sketch_jun13a.ino:52:36: warning: ISO C++ forbids comparison between pointer and integer [-fpermissive]

    sketch_jun13a.ino:58:9: warning: invalid conversion from 'const char*' to 'char' [-fpermissive]

         x = "0";

             ^~~

Basically this is char variable with assigned character literal: `char x = '0';`

And this is C string: `char str[] = "0";` or its equivalent: `char str[] = {'0', '\0'};`. Where `'\0'` is so called `NUL` Terminal character.

[Everything about C strings you need to know](https://www.cs.uic.edu/~jbell/CourseNotes/C_Programming/CharacterStrings.html)

EDIT:

Simple demo for the "parser" - it's not perfect but should be enough:

    char  x = '0';

    int inpSpeedS[4]; // An array to determine the speed of each individual input

    void setup() {
      Serial.begin(9600);
      Serial.println("Select channel [a..d] and speed [0..255]: ");
    }

    void loop() {

      if (Serial.available() > 1) { // wait for more characters in buffer
        switch (Serial.read()) {
          case 'a': inpSpeedS[0] = Serial.parseInt(); break;
          case 'b': inpSpeedS[1] = Serial.parseInt(); break;
          case 'c': inpSpeedS[2] = Serial.parseInt(); break;
          case 'd': inpSpeedS[3] = Serial.parseInt(); break;
          default : return; // skip invalid characters like line endings
        }

        Serial.print("Speeds: ");
        for (auto spd : inpSpeedS) {
          Serial.print(' ');
          Serial.print(spd);
        }
        Serial.println();
        Serial.println("Select channel [a..d] and speed [0..255]: ");

        /*
          analogWrite(motinp1, inpSpeedS[0]);
          analogWrite(motinp2, inpSpeedS[1]);
          analogWrite(motinp3, inpSpeedS[2]);
          analogWrite(motinp4, inpSpeedS[3]);
        */

      }
    }

And the result:

    -> Select channel [a..d] and speed [0..255]:
    <- a547
    -> Speeds:  547 0 0 0
    -> Select channel [a..d] and speed [0..255]:


message:
Mac OS X Catalina Serial Monitor Problem

I have some problems on MacBook Pro running with Catalina. I bought new nodemcu LoLin board. Its clone. It has ch340 adapter to communicate. And writing on bottom side wemos.cc and use ch340g driver.

I succesfully installed drivers and I can see my lolin boards on port list

I upload a code that doing only print hello to serial port. I tried with 9600 and 115200 baud rates. My serial monitor show garbage data. I am using platform io with VSCode to upload code and upload time is too much.When I am uploading code I got this warning :

"Detected crystal freq 156.04MHz is quite different to normalized freq 40MHz. Unsupported crystal in use?"

I am using cheap thundeIrbolt usb converter too. But I connect with this converter to Windows pc, everything looks fine. I can see hello world on serial monitor. But on my Mac, I can see garbage only. I tried some serial monitors, Arduino IDE and platform io ide but still same.

Are there any solution about this problem?

EDIT :

I fixed issue last night. Catalina has ch340 drivers already and I setup oem driver from GitHub. Apples driver and oem drivers conflicting. If you use Mojave and higher os, you dont need any driver for ch340. So if you installed ch340 oem  driver you should delete it.

I am adding the post:
[Platformio post][1]

  [1]: https://community.platformio.org/t/troubleshooting-ch340g-issues-on-macos/9522

body:
I fixed issue last night. Catalina has ch340 drivers already and I setup oem driver from GitHub. Apples driver and oem drivers conflicting. If you use Mojave and higher os, you dont need any driver for ch340. So if you installed ch340 oem driver you should delete it.
I am adding the post: Platformio post


message:
Powering a system using batteries

I made an arduino nano IR sensor based auto liquid dispenser. Currently it is being powered by a 12V 2 amps adapter. The 12v adapter is connected to a LM2596 DC to DC buck converter which converts the 12V to 5V and powers the arduino, IR sensor and a regular green LED. Also I am using a RO valve solenoid (rated upto 24V DC) which is being powered by the 12V adapter. So whenever the IR sensor is triggered, the DC motor (5V 200mA) and solenoid (12V 300-500mA) are turned on for 3 seconds.

Now, I intend to power this system via batteries. I am considering the following 3 options.

a.) Lithium batteries in series (4 of 3.7V batteries). But again here I believe things would be complex as I have to make a BMS and charger for this. Is anything available off the shelf so that I can directly integrate the battery and charger with my existing system ?

b.) Connect 8 AAA batteries in series to get 12V. But how long would these batteries last for my application ?

c.) Connect 2 9V batteries in series. Again, can you guys please tell me how long these may last in the system.

Arduino nano I believe consumes 20mA and the IR sensor probably around another 10- 20mA.
If it wasnt for the solenoid, I was considering connecting a mobile power bank to power the system.

body:
I think you should go with 3 lithium batteries in series and for proper balance charging of batteries, you can use an off the shell 3s lithium charging circuit like this [here][1].So you will get 4.2*3 = 12.6V on full charge and on full discharge you will get 3.7*3=11.1v out of the battery.

So still I think your pump motor would work on 11v and ther are chances that your solanoid also work on 11v it will just draw more current then usual.

  [1]: https://robu.in/product/3s-12v-18650-lithium-battery-protection-board-12v-10a-overcharge-overcurrent-protection/?gclid=CjwKCAjwlZf3BRABEiwA8Q0qq9as1ergawrXgdhpC2R4g2RkCU830LG1Fb6Cxtejf4sBEsifmbmioxoCZfIQAvD_BwE


body:
Consider using a 12V sealed cell lead-acid battery. Those are fairly cheap and easy to find in a wide variety of capacities, and chargers are also simple and easy to find.

A car battery would power your system approximately forever, since they have such huge capacity.

Figuring out how long a given type of battery will last is a simple question of math. Figure out the average current draw of your entire project, in milliamps. (You need to include the power consumed by your voltage regulator. The linear regulators built into Arduinos are quite inefficient, and work by dissipating excess voltage as heat.)

The total power of a battery is expressed in milliamp/hours. (where 1 milliamp/hour is a milliamp of power drawn for a full hour.) If you your system draws 2 amps, or 2000 milliamps average current, and your battery is rated for 2000 mAh, or 2 amp/hours, the battery will last 1 hour.

For battery-powered systems you should think about skipping the built-in linear regulator in your Arduino and instead using a switching regulator and providing regulated 5V directly to the board. Switching regulators can run at 90%+ efficiency, compared to something like 40% - 50% efficiency for linear regulators (I don't have a specific efficiency figure for linear regulators on hand, and it depends on input voltage compared to output voltage. The 40% - 50% number is an educated guess.)


message:
Error passing a `time_t` and `struct tm`, ESP32

I need to create a converter from epoch time stored in a `time_t` variable, to a `struct tm` variable, in order to check / create a certain task every hour or a day. This function should get also a past `time_t` for other uses.

Converting function, inside a library, works OK ( last two lines are for verification purposes, meaning conversion was done as expected ):

    void myIOT32::convEpoch(time_t in_time, struct tm *convTime)
    {
      convTime = gmtime(&in_time);
      char time_char[40];
      sprintf(time_char, "d-d-d d:d:d", convTime->tm_year + 1900, convTime->tm_mon+1, convTime->tm_mday,
                convTime->tm_hour, convTime->tm_min, convTime->tm_sec);

      Serial.print(" from funct: ");
      Serial.println(time_char);

Now, when calling it from my code and try to use time `tm` var, it causes the code to crash. In code below, I just try to print it to console:

    void sendnewNotif()
    {
      struct tm *newtime;
      time_t t=182423032;
      iot.convEpoch(t, newtime); // <--- Using the conversion
      char timeStamp[50];
      // Serial.print(newtime->tm_year);

    }

What may be the problem ?

Guy

body:
```c++
void myIOT32::convEpoch(time_t in_time, struct tm *convTime)
{
  convTime = gmtime(&in_time);
```

Here you are overwriting the parameter `convTime`. There is no point in
passing such a parameter if you are not going to use the value provided.

```c++
void sendnewNotif()
{
  struct tm *newtime;
  time_t t=182423032;
  iot.convEpoch(t, newtime); // <--- Using the conversion
```

`newtime` is initially uninitialized. The call to `iot.convEpoch()`
doesn't change that (the parameter is passed by value, not by
reference).

```c++
  Serial.print(newtime->tm_year);
```

This is dereferencing an uninitialized pointer, which is undefined
behavior and can crash the program.

The simplest solution I see is to have `myIOT32::convEpoch()` return the
pointer it got from `gmtime()`. Note that this points to static storage,
which makes the method not reentrant.

Example (not tested):

```c++
struct tm *myIOT32::convEpoch(time_t in_time)
{
  struct tm *convTime = gmtime(&in_time);
  // ...
  return convTime;
}

void sendnewNotif()
{
  time_t t = 182423032;
  struct tm *newtime = iot.convEpoch(t);
  Serial.print(newtime->tm_year);
}
```


message:
Voltage issue on an esp32 wvroom 32D development board

I have an esp32 wroom 32 dev board. I'm running into power issues and I'm not sure what's going on.

When I try to upload sketches the uploads fail if I have any jumpers running to the 5v or 3.3v pins which is weird.

Also, when I have nothing plugged into the board other than the usb cable and try to measure voltage across the ground and power pins I get 1.5v from the 5v pin and 0 from the 3.3 pin

[![5v pin reading][1]][1]

[![3.3 pin reading][2]][2]

This is a brand new out-of-the-static-bag board and I'm having the same issue with another board of the same type.

I feel like there's something I'm missing. Any ideas?

  [1]: https://i.stack.imgur.com/WHwxR.jpg
  [2]: https://i.stack.imgur.com/dvyEP.jpg

body: Try measuring the voltage against a different ground pin? I had a similar problem and discovered the pin next to the 5v input pin wasn't actually ground. Not sure why this would affect sketch uploading though..


message:
How to keep track of millis during sleep mode

In my application, I need to keep track of the time the application has been running as well as use sleep modes. However, when using the sleep modes, Timer0 is disabled, and therefore millis stop counting.

**Is there a way to measure/count how long the Arduino was in sleep mode for?**

To give you some more background info, this is what I'm trying to achieve:
I am using a pressure sensor which sends an interrupt to the Arduino every 80ms and wakes it up.
The program does various routines to process the data which can take anywhere from 2ms to 60ms.
It then goes into sleep mode until another external interrupt occurs, approx 20-78ms later.
The application has many processes based on time, such as a stopwatch, timer and alarm, so I need to be able to keep track of this, preferably using millis().
The device is running on a single cell 250mah LiPo battery which at present only lasts about 4 hours.
I'm using an ATMega1284.

In most of the sleep modes Timer0 is disabled. Which means that millis() stops counting. Is there a way, without using an RTC (Both Space and weight are at a premium), to keep millis counting whilst in sleep mode?

I notice that SLEEP_MODE_IDLE keeps Timer0 running, but that means that for every millisecond an interrupt wakes up the device. Please correct me if I'm wrong, but given that my loop can take about 60ms to execute, I don't see much advantage to sleeping for 1ms.

**Possible solutions:**

 - Use Timer2 for the millis function?
 - Use the Watchdog Timer to count how much time has passed whilst in
   sleep mode and add this to millis() when waking up?
 - If there was a VERY small SMD RTC which didn't need any external
   components such as oscilators etc then this might be feasible.

body:
The only way to keep `millis()` running is sleep mode is to sleep in
SLEEP\_MODE\_IDLE. Switching to Timer 2 would make no difference, as
all timers but the watchdog are stopped in other sleep modes. The
watchdog is horribly inaccurate, so you do not want to rely on it for
any kind of timekeeping.

> I don't see much advantage to sleeping for 1 ms.

Sleeping for 1 ms saves a little bit of power. But if you do that
60 times every 80 ms you will save a lot of power. I suggest
you do just that: sleep when you are done with your calculations. When
you wake up, if you see that the waking up came from the external
interrupt, the you process it. Otherwise you just go back to sleep.

Note that if the 80 ms period of the external interrupt is
consistent enough, you could use _that_ as time source.


body:
I found a RealTimeClock that I could use: [RV-8803][1].
It's only 3.2mm x 1.5mm x 0.8mm, has an internal XTAL, and can provide time in 100th of a second.
Sparkfun do a breakout board ([BOB-16281][2]), and accompanying [library][3].

Given that I've already got a bunch of decoupling capacitors in my circuit and can use the internal pullups of the ATMega1284, I think I can probably integrate the RV-8803 without the need for any additional components.

On the breadboard, interrupts are working well and I can now use EXTENDED_STANDBY sleep mode instead. The only downside is that the RTC records time in 100ths of a second, whereas my program was using milliseconds previously. I'll need to see if 100ths is accurate enough for my needs.

Failing that, I'll have a look at @Gerben's suggestion above.

  [1]: https://www.microcrystal.com/en/products/real-time-clock-rtc/rv-8803-c7/
  [2]: https://www.sparkfun.com/products/16281
  [3]: https://github.com/sparkfun/SparkFun_RV-8803_Arduino_Library


message:
How to supply more than 500mA while powered by USB

I'm about to build myself a new BrewPi and I have some Arduino power/USB questions.

Something smiliar to a combination of these projects:

https://i.stack.imgur.com/gZHZt.jpg

https://www.homebrewtalk.com/threads/how-to-brewpi-lcd-add-on.510036/

The device will have a Raspberry Pi Zero W, an Arduino UNO (clone?), a LCD screen with backlight, and some relays and probes. The Pi must be connected to the Arduino via USB. The Arduino will drive the screen and some relays/probes. For simplicity's sake, I would like to power everything from the same regulated 5V power supply, and for ease of wiring I would prefer to power the Pi only and have it power the Arduino via USB, with the Arduino then supplying power to the rest.

My preference:
5V ----> Pi Zero --(USB)--> Arduino --(5V)--> Screen/etc.

However, according to this datasheet the max draw of the screen might exceed 1000mA:
https://www.vishay.com/docs/37314/lcd020n004l.pdf

This obviously exceeds the 500mA limit from the Arduino's 5V pin while being powered via USB. However, a Pi Zero has few safety features and does not limit outgoing current from it's USB port:
https://www.reddit.com/r/raspberry_pi/comments/3zyhuq/pi_zero_usb_power_outputmilliamps/

Given this, is it feasible to short/bypass the Arduino's polyfuse and then draw more than 500ma from the 5V pin of the Arduino without too many problems?

If not, can I 'add' the power supply's 5V to the Arduino's 5V (either from the Pi's 5V pin, or direct from the power supply) at the same time as maintaining the USB connection (which uses the same 5V source)? I'm stretching the limit of my circuit understanding here. If not how should I power the other components?

Would it instead be better to have a 12V supply and power the Arduino directly, then attempt to power everything else from its 5V pin (remembering that there is still a USB connection from the Pi back to the Arduino). What I'd really like to avoid in this situation is having to provide a second 12V->5V conversion.

Any help or advice would be greatly appreciated.

body:
Do not bypass the fuse. Drive your external components directly from the external 5V power supply. Do not pass everything through the Arduino.

You say you have a regulated 5V power supply. Assuming it provides enough current you should use it to drive your external components directly.

You might need to add a filter capacitor near the feed for the Pi/Arduino, to filter out fluctuations in the 5V supply as your high current components switch on and off. You should be able to google "Power supply filter capacitor" to learn more.


message:
NodeMCU wiring for Serial1?

I'm trying to get telemetry data to be sent out Serial1 on the NodeMCU board.  I read that TX is (by default) mapped to pin D4.

Ultimately, there will be a Raspberry that will be listening for these messages, but I don't have it yet.  So to quickly test this, I connected an oscilloscope with Serial decoding to D4 and the GND of the probe to GND on the NodeMCU.  The problem is I'm not getting any indication of activity out D4 when I run the following code:

    Serial1.begin(9600);
    Serial1.printf("some text");

Am I wiring the probe correctly?  Am I missing another serial command in the sketch?

When I move to the rPI, do I GND both boards together, then write TX (D4) to RX on the rPI?

body:
You can do Serial.swap() in setup() to swap Serial away from RX/TX pin. Serial is then on D7 as RX and D8 as TX (and you can wire some serial module there).

Bridge with jumper wire D4 pin with TX pin. the Serial1 output will go over the USB chip to Serial Monitor and you will see the prints to Serial1.

This will not disturb the flashing mode, because bootloader will still listen on standard Serial pins.


body:
## This code worked for me as Modbus slave

Required this library [<ModbusRtu.h>][1]

    #include <ModbusRtu.h>
    unsigned long TIME = 0;
    unsigned long LASTTIME = 0;
    unsigned long INTERVAL = 5000;

    int i = 0;
    // data array for modbus network sharing
    uint16_t au16data[16] = {
      3, 1415, 9265, 4, 2, 7182, 28182, 8, 0, 0, 0, 0, 0, 0, 1, 11 };

    /**
     *  Modbus object declaration
     *  u8id : node id = 0 for master, = 1..247 for slave
     *  port : serial port
     *  u8txenpin : 0 for RS-232 and USB-FTDI
     *               or any pin number > 1 for RS-485
     */
    Modbus slave(1,Serial,0); // this is slave @1 and RS-232 or USB-FTDI

    void setup() {
      Serial.swap();
      Serial.begin( 19200 ); // baud-rate at 19200
      Serial1.begin( 19200 );
      slave.start();
    }

    void loop() {

      if ((millis() - TIME) > INTERVAL) {
        i++;

        if(i == 16){
          i = 0;

          for (int ii = 0; ii < 16; ii++)
          {
            au16data[ii] = 0;
          }
        }

        au16data[i] = 1;

        TIME = millis();
      }

      slave.poll( au16data, 16 );
    }

  [1]: https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino


message:
Need help with EEPROM not storing array values on ESP8266 after restart

I am struggling through a program. I am trying to store my uploaded string into an array then write that array to EEPROM. I run the program, upload the new array and store it in the EEPROM. all values display correctly until I reset or power off the device. I am sure I am overwriting or something obvious, but i am breaking down and asking for help.

The read and write EEPROM subroutines are at the bottom of the code. I call the EEPROM_Write() in server.on after parsing the http get.

*EDIT: per feedback, removed all but the function, with the EEPROM.commit(); suggestion included... still not working*
<!-- language-all: lang-cpp -->

    void EEPROM_Write(){
    Serial.begin(115200);
    EEPROM.begin(280);
      // store values in EEPROM
      for (int i = 0; i < pwmarray1Size; i++)
      {
        Serial.println(pwmarray1[i]);
        EEPROM.put( EEPROMStartAdress + (i * sizeof pwmarray1[0]), pwmarray1[i]);
      }
      Serial.println();
      EEPROM.commit();
     // EEPROM.end();
    }

body:
The ESP has no real EEPROM. Instead the `EEPROM` class for ESPs uses the flash memory. There is a difference in the implementations of this class between Arduinos and ESPs:

On an ESP every data, that you write, will first be placed in a buffer in RAM. You  need to call `EEPROM.commit()` to actually write that data to the underlying flash memory.

So you need to add

    EEPROM.commit();

to the end of your `EEPROM_Write()` function, or the data will stay in RAM and thus be lost on power cycle or reset.

---

I think your problem (besides the commit) lies not in your `EEPROM_Write()` function, but in the `EEPROM_Read()` function. If it doesn't work correctly, you are just not able to see, if the data gets written correctly. In your code (which can be seen in the edit history), you have this function:

    void EEPROM_Read(){
       //load array pwmarray1 with stored values in EPROM
      for (int x = 0; x < pwmarray1Size; x++){
        EEPROM.get(EEPROMStartAdress + (x * sizeof pwmarray1[0]), pwmarray1[x]);
            Serial.print("loading program from EPROM: ");
        Serial.println(pwmarray1[x]);
        }
    }

While in `EEPROM_Write()` you are calling `EEPROM.begin(280)` every time, you don't `EEPROM.end()` it there and you are also not begin the EEPROM in the `EEPROM_Read()` function. I'm not sure about the underlying implementation, but it started to work for me, when I began and ended the `EEPROM` object in both functions.

I've written a test code, that I composed party of your code and that for me correctly saves and reads an array via the `EEPROM` object into the flash memory. It keeps the data over resets and power cycles just correctly. You can control it via Serial Monitor. Just type `c` (for clearing the array to zero), `r` (for reading the array from EEPROM/flash) or `i` (for incrementing all array elements and save them to EEPROM/flash).

    #include <EEPROM.h>

    #define EEPROM_SIZE 280

    int array[60] = {0};
    const unsigned arraySize = sizeof array / sizeof array[0];

    #define EEPROMStartAdress 0

    void setup(){
      Serial.begin(115200);
      Serial.println("///////////////////////////////////////");
      delay(2000);
    }

    void loop(){
      if(Serial.available()){
        char c = Serial.read();
        switch(c){
          case 'c':
            for(uint8_t i=0;i<arraySize;i++) array[i] = 0;
            EEPROM_Write();
            Serial.println("EEPROM RESET");
            break;
          case 'r':
            EEPROM_Read();
            break;
          case 'i':
            for(uint8_t i=0;i<arraySize;i++) array[i] += 1;
            EEPROM_Write();
            break;
        }
      }
    }

    void EEPROM_Write(){
      EEPROM.begin(EEPROM_SIZE);
      // store values in EEPROM
      for (int i = 0; i < arraySize; i++)
      {
        EEPROM.put( EEPROMStartAdress + (i * sizeof array[0]), array[i]);
      }
      EEPROM.commit();
      EEPROM.end();
    }

    void EEPROM_Read(){
      EEPROM.begin(EEPROM_SIZE);
      for (int x = 0; x < arraySize; x++){
        EEPROM.get(EEPROMStartAdress + (x * sizeof array[0]), array[x]);
        Serial.print(" ");
        Serial.print(array[x]);
        }
      Serial.println();
      EEPROM.end();
    }

Removing `begin()` and `end()` from `EEPROM_Read()` and also `end()` from `EEPROM_Write()` gives me the same results, that you described as your problem.


message:
Arduino Micro 5V Vin and 3v3 pins

I am very confused with the pins on the [arduino micro][1]. What are the 3v3, 5v, and Vin pins used for? Are they for power input, or power output, or both?

  [1]: https://store.arduino.cc/usa/arduino-micro

body:
VIN is power input. IN means INput.

Generally 5V and 3.3V are used for power output, but the 5V one can also be used for power input if you want to power the board from 5V.

But since they are just power they have no "direction" as such, only a voltage level.


body:
Vin is a power INPUT. It is connected to the input of the voltage regulator, which enables you to power the Arduino with voltages between 6V and 12V, while the Arduino itself is running on 5V.

The 5V pin can be both an power INPUT and OUTPUT. It is connected to the general 5V power rail inside the Arduino and thus to the power inputs of the microcontroller. This rail/pin needs to be provided with 5V power to let the Arduino work. Where this power comes from (from the voltage regulator, from USB or from your own external 5V power supply connected to the 5V pin) is irrelevant for the Arduino. The 5V pin can even be used to provide power to other components in your circuit (though with certain limitations, see below).

The 3V3 (meaning 3.3V) pin is a power OUTPUT. It is connected to the output of another voltage regulator, which brings the 5V from the 5V rail down to 3.3V. It can be used to power external parts, that need 3.3V to work.

---

Up to this point I only wrote about voltage. But depending on your circuit you also need to consider the current. The different electrical parts on the Arduino can only handle a specific power (measured in Watts). Thus with a given voltage you can only draw up to a specific amount of current through them, before you destroy them.

As an example, let's assume you provide the Arduino with 9V through Vin and you want to drive a middle sized motor. Motors in general can draw a lot of current. When you now drive the motor from the 5V pin of the Arduino, the motors current will flow through the Arduinos voltage regulator. Thus the regulator will go into emergency shutdown and cut the power (applies for a genuine Arduino) or it will get destroyed (applies for most cheap Arduino clones). To prevent that, you need to connect the motor directly with the power supply (or through an extra voltage regulator, suitable for the needed current), so that the current for it is no longer flowing through the Arduino.

This explanation is only to prevent you from destroying your board. That is always very annoying, when it happens.