body:
Just to complement JRobert's answer: yes, the four serial ports are
independent. They can be activated independently, they can be set to
different baud rates if needed, and they do have separate buffers.


sender: user

message:
Arduino Mega's auxiliary serial ports

If I am correct, the first two pins (RX/TX) are connected to the USB, and I cannot use the serial monitor and the first RX/TX serial ports at the same time.

But, what about the other 3 auxiliary serial ports? Are they separated? Do each one of them has it's own buffer?

For example: Is it possible to add, let's say, four Bluetooth modules(Let's say HC-05) and use each of them for a different purpose?

sender: assistant

body:
Serial1, Serial2 and Serial3 are all independent, at 0/5V levels.
You can each one to a bluetooth module, or whatever HC-05 is.
Or FTDI Basic modules if you want more USB ports.
Etc.


message:
How to actually concatenate two Strings?

I'm using the SPISlave library, and I have the following code snippet:
<!-- language-all: lang-cpp -->

    String arg;

    SPISlave.onData([arg](uint8_t *data, size_t len) {
      data[len] = 0;
      arg += String((char *)data);
      // ...
    }

The compiler doesn't like my string concatenation, though:

> /home/lars/sketch_apr01a/sketch_apr01a.ino: In lambda function:
> sketch_apr01a:65:12: error: passing 'const String' as 'this' argument
> of 'String& String::operator+=(const String&)' discards qualifiers
> [-fpermissive]
>        arg += String((char *)data);

I've tried other versions as well, with similar results:

 - `arg.concat((char *)data)`
 - `arg = arg + String((char *)data)`
 - `arg += String((const char *)data)`

So how exactly do I write this unusual operation?

body:
Actually for such string concatenation (which is in a function that may be called a lot), this could result in memory fragmentation, an on most Arduinos the memory will be soon too scattered that no useful memory is left.

Instead, it's better to create beforehand a buffer with the maximum size of the string you want to handle, like:

    static const int MAX_BUFFER_LENGTH = 256;

    char buffer[MAX_BUFFER_LENGTH];

And use the function `strcat` or `strncat` for concatenating two strings; there are generic C functions.


body:
Your lambda is capturing `arg` by copy, which is most certainly not what
you want. And since it doesn't have the `mutable` qualifier, the
captured parameters are not modifiable. Hence the compiler error.

You could get rid of the error by qualifying the capture as `mutable`,
but you would then be modifying the captured copy of `arg`, not the
original one. The correct solution would be to capture the String by
reference instead of capturing by copy. See [Lambda
expressions](https://en.cppreference.com/w/cpp/language/lambda).

But then, I concur with Michel Keijzers that avoiding Strings altogether
is a better option.


body:
    #include <stdio.h>

    static const int MAX_BUFFER_LENGTH = 32;
    char buffer[MAX_BUFFER_LENGTH];

    sprintf(buffer, "%s%s", string1, string2);


message:
How to stop OLED flicker when using SSD1306Ascii.h?

Why does the OLED display flicker when using the SSD1306Ascii.h library? The Adafruit library does not have this issue, but I've been told uses a lot of memory and so I'm trying to use Ascii to conserve memory resources. The problem manifests itself when the void loop() begins. When using similar code with the Adafruit library, the display stays steady as a rock.

Here is my example code. many thanks in advance.

    // Edit AVRI2C_FASTMODE in SSD1306Ascii.h to change the default I2C frequency.

    #include "SSD1306Ascii.h"
    #include "SSD1306AsciiAvrI2c.h"

    #define I2C_ADDRESS 0x3C

    // Define proper RST_PIN if required.
    #define RST_PIN -1

    SSD1306AsciiAvrI2c oled;
    //------------------------------------------------------------------------------
    void setup() {

    #if RST_PIN >= 0
      oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
    #else // RST_PIN >= 0
      oled.begin(&Adafruit128x64, I2C_ADDRESS);
    #endif // RST_PIN >= 0
      // Call oled.setI2cClock(frequency) to change from the default frequency.

      oled.setFont(System5x7);
      oled.clear();
      oled.print("Hello World!");
      delay(2000);
      oled.clear();

    }
    //------------------------------------------------------------------------------
    void loop() {

      oled.setFont(System5x7);
      oled.print("Hello fuuuzzzzyyyy world!");
      delay(1);
      oled.clear();

    }

body:
Your loop is repeatedly writing and clearing the display, nearly as fast as possible (minus the 1ms delay at the bottom), which is the reason for the flicker you're seeing. If instead, you only update the display when something changes, it will look much smoother. Even a clear-and-rewrite the entire display when something changes (assuming the changes are infrequent) will be a major improvement. Of course this assumes you'd eventually be writing dynamic data; your test program, of course, writes and re-writes static data.

Update:

> If I run the same code structure with Adafruit library there is no
> flicker, even with no delay in the loop.

Can you compare the two libraries to see what they do differently?

> The Adafruit library does not have this issue, but I've been told uses
> a lot of memory

There's a likely clue: Adafruit may be buffering the display contents in memory so it can find out which character positions changed and update only those. That would be a classic time/space trade-off.


body: Yes, it's due to rewriting the whole display.  I generally only rewrite portions that have changed or at worst use the ClearToEOL command to make sure everything's obliterated.


message:
typedef function pointer array declaration problem

Thanks for all your feedback. It helped.

I rewrote this yet another time and this time **it works perfectly**. I included three variations: a simple example using an array of function pointers, a Lambda version and a complex version like what I started with.

    #define TASK_COUNT   3

    typedef void ( *taskPointer ) ( );

    // Simple Version:
    void taskS1 () { Serial.println ( ( char* )"SIMPLE TASK 1" ); }
    void taskS2 () { Serial.println ( ( char* )"SIMPLE TASK 2" ); }
    void taskS3 () { Serial.println ( ( char* )"SIMPLE TASK 3" ); }

    // Array of pointers to tasks
    taskPointer callSimpleTask [ ] = {
    taskS1,
    taskS2,
    taskS3,
    };

    // Run the simple test
    void showSimpleVersion () {
     Serial.println ( F ( "\nSimple Version:" ) );
     for (uint8_t i = 0; i < TASK_COUNT; i++) {
      callSimpleTask [ i ] ();
     }

    }

    // Lambda Version: No separate task definitoins
    void ( *callLambdaTask [ ] ) ( ) = {
     [ ] {Serial.println ( ( char* )"LAMBDA TASK 1" ); },
     [ ] {Serial.println ( ( char* )"LAMBDA TASK 2" ); },
     [ ] {Serial.println ( ( char* )"LAMBDA TASK 3" ); },
    };

    // Run the Lambda test
    void showLambdaVersion () {
     Serial.println ( F ( "\nLambda Version:" ) );
     for (uint8_t i = 0; i < TASK_COUNT; i++) {
      callLambdaTask [ i ] ();
     }

    }

    // Complex Version: Each array element is a struct containing a
    // pointer to the corresponding task and related properties
    struct complexTaskDefinition {
     taskPointer task;
     bool repeat;    // Repeat flashing after delay
     int32_t iterations;   // # times to repeat... -1 = forever
     uint32_t delay;    // MS to wait before execution
    };

    // Create a pointer to a task definition
    complexTaskDefinition *task;

    // Prove that called function can call other functions:
    void taskC1 () { showTaskC1(); }
    void taskC2 () { showTaskC1 (); }
    void taskC3 () { showTaskC1 (); }

    void showTaskC1 () {
     Serial.println ( ( char* )"COMPLEX TASK 1" );
    }
    void showTaskC2 () {
     Serial.println ( ( char* )"COMPLEX TASK 2" );
    }
    void showTaskC3 () {
     Serial.println ( ( char* )"COMPLEX TASK 3" );
    }

    complexTaskDefinition tasks [ ] [4] = {
     {taskC1, true, -1, 1000 }, // taskC1 repeats forever every second
     {taskC2, true, 10, 2000 }, // taskC2 runs 10 times pausing for 2 seconds between iterations
     {taskC3, false, 3, 3000 }, // taskC3 runs 3 times with 3 second delays between each, then dies
    };

    void showComplexTaskList () {
     Serial.println ( F ( "\nComplex Task List:" ) );
     for (uint8_t i = 0; i < TASK_COUNT; i++) {
      task = tasks [ i ];
      Serial.print ( '[' );
      Serial.print ( i );
      Serial.print ( F ( "] REPEAT:" ));
      Serial.print ( ( task->repeat ) ? "YES" : "NO" );
      Serial.print ( F ( ", DELAY:" ) );
      Serial.print ( task->delay );
      Serial.print ( F ( ", ITERATIONS:" ) );
      Serial.print ( task->iterations );
      Serial.println ();
     }
    }

    void showComplexVersion () {
     Serial.println ( F ( "\nComplex Version:" ) );
     for (uint8_t i = 0; i < TASK_COUNT; i++) {
      task = tasks [ i ];
      task->task ();
    //  (( *tasks ) [ i ]).task ();
     }
    }

    void setup () {
     Serial.begin ( 115200 );
     while (!Serial.availableForWrite ()) {}

     showSimpleVersion ();

     showLambdaVersion ();

     showComplexVersion ();

     showComplexTaskList ();
    }

    void loop () {
    }

Here is the output:
Simple Version:

    SIMPLE TASK 1
    SIMPLE TASK 2
    SIMPLE TASK 3

    Lambda Version:
    LAMBDA TASK 1
    LAMBDA TASK 2
    LAMBDA TASK 3

    Complex Version:
    COMPLEX TASK 1
    COMPLEX TASK 1
    COMPLEX TASK 1

    Complex Task List:
    [0] REPEAT:YES, DELAY:1000, ITERATIONS:-1
    [1] REPEAT:YES, DELAY:2000, ITERATIONS:10
    [2] REPEAT:NO, DELAY:3000, ITERATIONS:3

I want to run one more experiment, this time with the complex version as a class.

body:
Try replacing

```c++
taskDefinition _tasks [ ] [4] = {
```

by

```c++
taskDefinition _tasks [ ] = {
```

In short, you have defined `_tasks` as a 2D array of objects (an array
of arrays of objects) while you intend to use it as a 1D array.

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

Note that the error message is quite explicit if you take the time to
parse it:

> request for member 'task' in '\_tasks[((int)i)]',

You are requesting `_tasks[i].task`,

> which is of non-class type

but `_tasks[i]` is not an object.

> type 'taskDefinition [4]'

It is instead an array of four `taskDefinition` objects.

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

**Edit**: Fixing the answer to match the latest version of the question.

Your code works, but not quite as you expect it to work. You wrote:

```c++
complexTaskDefinition tasks [ ] [4] = ...;
```

Here you are defining a 2D array of objects, while your intention was to
define a one-dimensional array (why do I feel like I am repeating
myself?).

```c++
complexTaskDefinition tasks [ ] [4] = {
    {taskC1, true, -1, 1000 },
    {taskC2, true, 10, 2000 },
    {taskC3, false, 3, 3000 },
};
```

This definition, although syntactically correct, is awfully wacky. You
are defining `tasks` as an array of 3 items. Each item is itself an
array of 4 objects, where the first object of the array is explicitly
initialized, and the three others are implicitly initialized to
all-bits-zero. So basically your definition is equivalent to this
explicit version:

```c++
complexTaskDefinition tasks [3] [4] = {
    {{taskC1, true, -1, 1000 }, {nullptr, false, 0, 0},
     {nullptr, false, 0, 0},    {nullptr, false, 0, 0}},
    {{taskC2, true, 10, 2000 }, {nullptr, false, 0, 0},
     {nullptr, false, 0, 0},    {nullptr, false, 0, 0}},
    {{taskC3, false, 3, 3000 }, {nullptr, false, 0, 0},
     {nullptr, false, 0, 0},    {nullptr, false, 0, 0}}
};
```

Then you wrote:

```c++
task = tasks [ i ];
```

Here, `tasks[i]` is a row of the 2D array, i.e. a 1D array of 4 objects,
whereas `task` is a pointer to object. The assignment is legit because
here, like in most contexts, the array “decays” to a pointer to its
first element. The above line is equivalent to the explicit version:

```c++
task = &tasks[i][0];
```

Quite fortunately, this happens to point to one of the elements of the
array that has been explicitly initialized!

As an illustration of the above, here is a modified version of
`showComplexTaskList()` that loops over _all_ the tasks in the array:

```c++
void showComplexTaskList () {
    Serial.println ( F ( "\nComplex Task List:" ) );
    Serial.print(F("number of tasks: "));
    Serial.println(sizeof tasks / sizeof(complexTaskDefinition));
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        for (uint8_t j = 0; j < 4; j++) {
            task = &tasks[i][j];
            Serial.print ( '[' );
            Serial.print ( i );
            Serial.print ( F ("]["));
            Serial.print ( j );
            Serial.print ( F ( "] REPEAT:" ));
            Serial.print ( ( task->repeat ) ? "YES" : "NO" );
            Serial.print ( F ( ", DELAY:" ) );
            Serial.print ( task->delay );
            Serial.print ( F ( ", ITERATIONS:" ) );
            Serial.print ( task->iterations );
            Serial.println ();
        }
    }
}
```

Its output is:

```text
Complex Task List:
number of tasks: 12
[0][0] REPEAT:YES, DELAY:1000, ITERATIONS:-1
[0][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[0][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[0][3] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][0] REPEAT:YES, DELAY:2000, ITERATIONS:10
[1][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[1][3] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][0] REPEAT:NO, DELAY:3000, ITERATIONS:3
[2][1] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][2] REPEAT:NO, DELAY:0, ITERATIONS:0
[2][3] REPEAT:NO, DELAY:0, ITERATIONS:0
```

So your program works almost by chance: an error in the way you define
the array cancels an error in the way you use it. This kind of cancelled
error method is very bad programming practice. You are wasting memory in
unused `complexTaskDefinition` objects. More importantly, your code
doesn't express your intent, which makes the program way harder to
understand and to debug.

The fix is to declare a 1D array, as this has always been the intention:

```c++
complexTaskDefinition tasks [ ] = {
    {taskC1, true, -1, 1000 },
    {taskC2, true, 10, 2000 },
    {taskC3, false, 3, 3000 },
};
```

Now, you can check that this array does only have three tasks, as
reported by `sizeof tasks / sizeof(complexTaskDefinition)`. To use the
array, you can use a pointer if you want:

```c++
task = &tasks[i];
// ...
Serial.print ( ( task->repeat ) ? "YES" : "NO" );
```

Or you can directly request a member of `tasks[i]`, as in

```c++
void showComplexVersion () {
    Serial.println ( F ( "\nComplex Version:" ) );
    for (uint8_t i = 0; i < TASK_COUNT; i++) {
        tasks[i].task();
    }
}
```

Now I have a question for you. Since I already explained your 1D vs. 2D
array mistake in the first iteration of my answer, why did you persist
with this in your edited question? If you are going to blatantly ignore
the answers you get, at least say so in the question. This could save
time to those who might consider helping you.


message:
Is the code correct? Nrf24l01

I'm am a beginner, so I'm sorry I have written this wrong.

Is this piece of code correct? If not where?

Transmitter:

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

    int* Msg, mSg, msG;

    RF24 radio(9, 10);
    const uint8_t pipe = 1;

    void setup() {
      // put your setup code here, to run once:
      radio.begin();
      radio.setPALevel(RF24_PA_LOW);
      radio.openWritingPipe(pipe);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      Msg = analogRead(A1);
      radio.write(Msg, sizeof(Msg));
      mSg = analogRead(A2);
      radio.write(mSg, sizeof(mSg));
      msG = analogRead(A3);
      radio.write(msG, sizeof(msG));
      delay(100);
    }

Receiver:

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

    #define in1 2
    #define in2 3
    #define in3 4
    #define in4 5

    #define in5 A2
    #define in6 A3
    #define in7 A4
    #define in8 A5

    const int maxMsgLength = 64;
    char Msg[maxMsgLength];
    const int maxmSgLength = 64;
    char mSg[maxmSgLength];
    const int maxmsGLength = 64;
    char msG[maxmsGLength];

    RF24 radio(9, 10);
    const uint8_t pipe = 1;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      radio.begin();
      radio.setPALevel(RF24_PA_LOW);
      radio.openReadingPipe(1, pipe);
      radio.startListening();
    }

    void loop() {
      // put your main code here, to run repeatedly:
      if (radio.available()) {
        radio.read(Msg, maxMsgLength - 1);
        radio.read(mSg, maxmSgLength - 1);
        radio.read(msG, maxmsGLength - 1);
      }

      int xAxis = Msg;
      int yAxis = mSg;
      int YAxis = msG;

      if (xAxis < 450) {
        // Forward
        digitalWrite(in1, 1);
        digitalWrite(in2, 0);
        digitalWrite(in3, 1);
        digitalWrite(in4, 0);
        Serial.println("Forward");
      }
      else if (xAxis > 550) {
        // Backward
        digitalWrite(in1, 0);
        digitalWrite(in2, 1);
        digitalWrite(in3, 0);
        digitalWrite(in4, 1);
        Serial.println("Backward");
      }
      else {
        // Stop
        digitalWrite(in1, 0);
        digitalWrite(in2, 0);
        digitalWrite(in3, 0);
        digitalWrite(in4, 0);
        Serial.println("Stop");
      }

      if (yAxis < 450) {
        // Left
        digitalWrite(in5, 1);
        digitalWrite(in6, 0);
        Serial.println("Left");
      }
      else if (yAxis > 550) {
        // Right
        digitalWrite(in5, 0);
        digitalWrite(in6, 1);
        Serial.println("Right");
      }
      else {
        // Stop
        digitalWrite(in5, 0);
        digitalWrite(in6, 0);
        Serial.println("Stop");
      }

      if (yAxis < 450) {
        // Flipper Up
        digitalWrite(in7, 1);
        digitalWrite(in8, 0);
        Serial.println("Up");
      }
      else if (yAxis > 550) {
        // Flipper Down
        digitalWrite(in7, 0);
        digitalWrite(in8, 1);
        Serial.println("Down");
      }
      else {
        // Stop
        digitalWrite(in7, 0);
        digitalWrite(in8, 0);
        Serial.println("Mid");
      }
      delay(250);
    }

Edit:

Transmitter:

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

    int x, y, f;

    RF24 radio(9, 10);
    const uint8_t pipe = 1;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      radio.begin();
      radio.setPALevel(RF24_PA_LOW);
      radio.openWritingPipe(pipe);
    }

    void loop() {
      // put your main code here, to run repeatedly:
      x = analogRead(A1);
      radio.write(x, sizeof(x));
      y = analogRead(A2);
      radio.write(y, sizeof(y));
      f = analogRead(A3);
      radio.write(f, sizeof(f));
      delay(100);
    }

Receiver:

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

    #define in1 2
    #define in2 3
    #define in3 4
    #define in4 5

    #define in5 A2
    #define in6 A3
    #define in7 A4
    #define in8 A5

    int x;
    int y;
    int f;

    RF24 radio(9, 10);
    const uint8_t pipe = 1;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      radio.begin();
      radio.setPALevel(RF24_PA_LOW);
      radio.openReadingPipe(1, pipe);
      radio.startListening();
    }

    void loop() {
      // put your main code here, to run repeatedly:
      if (radio.available()) {
        radio.read(&x, sizeof(x));
        radio.read(&y, sizeof(y));
        radio.read(&f, sizeof(f));
      }

      if (x < 450) {
        // Forward
        digitalWrite(in1, 1);
        digitalWrite(in2, 0);
        digitalWrite(in3, 1);
        digitalWrite(in4, 0);
        Serial.println("Forward");
      }
      else if (x > 550) {
        // Backward
        digitalWrite(in1, 0);
        digitalWrite(in2, 1);
        digitalWrite(in3, 0);
        digitalWrite(in4, 1);
        Serial.println("Backward");
      }
      else {
        // Stop
        digitalWrite(in1, 0);
        digitalWrite(in2, 0);
        digitalWrite(in3, 0);
        digitalWrite(in4, 0);
        Serial.println("Stop");
      }
      if(x > 1023)x = 1023;
      if(x < 0)x = 0;

      if (y < 450) {
        // Left
        digitalWrite(in5, 1);
        digitalWrite(in6, 0);
        Serial.println("Left");
      }
      else if (y > 550) {
        // Right
        digitalWrite(in5, 0);
        digitalWrite(in6, 1);
        Serial.println("Right");
      }
      else {
        // Stop
        digitalWrite(in5, 0);
        digitalWrite(in6, 0);
        Serial.println("Stop");
      }
      if(y > 1023)y = 1023;
      if(y < 0)y = 0;

      if (f < 450) {
        // Flipper Up
        digitalWrite(in7, 1);
        digitalWrite(in8, 0);
        Serial.println("Up");
      }
      else if (f > 550) {
        // Flipper Down
        digitalWrite(in7, 0);
        digitalWrite(in8, 1);
        Serial.println("Down");
      }
      else {
        // Stop
        digitalWrite(in7, 0);
        digitalWrite(in8, 0);
        Serial.println("Mid");
      }
      if(f > 1023)f = 1023;
      if(f < 0)f = 0;

      Serial.println(x);
      Serial.println(y);
      Serial.println(f);
      delay(250);
    }

Thank you for your time.

body:
I see (at least one ) problem.

First remove the * from:

    int* Msg, mSg, msG;

Because it should store integers (numbers), not pointers to numbers.

Also, make the variables better. These almost identical names are quite confusing (name them x, y or z or a better name).

What you are doing is sending the 3 integers as integers (meaning that each integer is 2 bytes), so you send 6 bytes.

But in the receiver, you read characters, you have to replace this by:

- Changing `char`  to `int`  for the 3 variables in the receiver side
- Also here, change the names
- Remove the constants for the length (64)
- Instead read the code as you write it:

    int xAxis;
    radio.read(&xAxis, sizeof(int));

& means: address, the read function stores the value in xAxis (so you don't have to copy it afterwards).
Also print out the value after the read so you can check it.


message:
#define above static const int?

I see a lot of people, but also libraries, defining constants (like pin numbers, length of items etc) as #define:

    #define LENGTH 5

While it is recommended to use in this case static const int:

    static const int LENGTH = 5;

I did a test and for memory it does not make a difference.

Is there some specific Arduino reason why #define is (mis)used so often?

body:
For numbers, certainly, `const <type>` is preferred.  This is chiefly because it imposes a type (which would only be optional for a `#define`), which can have a knock-on effect for mathematics.

That's not to say that you should always use `const <type>` instead of `#define`.  `#define` has its place.

One of the benefits of `#define` over `const <type>` is that it is a direct literal text replacement. The replacement is done before the compilation, so *anything* that is valid in your code can be put in a `#define`, whereas only things which evaluate to the correct type at runtime can be placed in a `const <type>`.

Take strings for example.  Yes, you can use:

    const char *foo = "This is text";

And you can use that wherever a `const char *` is expected.  However, if you use:

    #define FOO "This is text"

you can use it anywhere a *string literal* is expected.  That makes for useful things such as C's way of concatenating string literals at compile time:

    Serial.println("I say: " FOO);

The two string literals `"I say: "` and `FOO` (which expands to `"This is text"`) are concatenated into a singe string literal at compile time into:

    Serial.println("I say: This is text");

You can't do that with `const char *`.

Another big difference with `const <type>` compared with `#define` is *when expressions are evaluated*.  Take for example:

    const float sinpi = sinf(3.141592653);

That will calculate the sine of PI once at startup. However:

    #define SINPI sinf(3.141592653);

will calculate the sine of PI *every time it is used*.

So in this instance `const float` not only gives you an imposed type of `float` for all calculations, it also reduces calculation overhead by only running the calculation once and saving the result.

So as you can see there are pros and cons to each.  But in general, for numbers:

* `const <type>` is preferred for storing internal numerical data that doesn't change, and
* `#define` is most often used for user-configurable data, since it doesn't impose the `;` at the end of the line which often gets forgotten by (newer) users.


message:
Arduino resets itself

If I connect more power consuming components to Arduino, it gets reset. What is the cause of this observation?

body:
Branded Arduino boards have overload protection on their voltage regulators. If the voltage regulator overheats it shuts down, and then attempts to restart when the temperature returns to normal. I believe there is also short-circuit protection, although I'm not positive.

When power returns the processor will do a power-on reset.


body:
It depends on **what** is shorted. As stated by Duncan C, shorting the 5V pin to ground will probably not harm the arduino due to the mentioned protection mechanisms.
On the other hand an output port should not be shorted, chances are that the port gets destroyed.

In case of a short circuit the arduino "resets" itself because the voltage drops below the mcu's operating conditions, because the voltage regulator either shuts down completely or is not able to provide enough current.


body:
When powered through USB there is a resettable polymeric ("poly") fuse. If you draw more than about 500mA this fuse will cut out and isolate the power.  When you remove the load the fuse will reset and allow power back to the board.

"Poly" fuses are in fact "Positive Temperature Coefficient" (PTC) thermistors. As they get hot their resistance increases (as opposed to the NTC thermistors you use for temperature sensing where the resistance decreases as they get hotter).  The current flowing through the PTC causes it to warm up. Too much current and it gets too hot, and the resistance gets too high (it's non-linear, so the resistance suddenly increases a lot).


body: Consider this: An Arduino was not designed as a power supply. Connect your loads to an external power supply things will get a lot better.


message:
Multiple WiFi client/server connections

I'm implementing a WiFi HTML web server using the WiFiNINA library, an Adafruit Airlift ESP32 coprocessor, and a Teensy 3.5. It's starting to work, but I have a couple of questions. This simplified code will illustrate the first.

    #include <WiFiNINA.h>
    #include "Wifi_names.h"

    WiFiServer server(80);

    void error (const char *msg) {
       Serial.println(msg);
       while (1) ; }

    void setup(void) {
       Serial.begin(115200);
       while (!Serial) ;
       WiFi.setPins(19, 20, 21, -1, &SPI);
       if (WiFi.status() == WL_NO_SHIELD) error("no Wifi shield");
       Serial.print("ESP32 firmware version: "); Serial.println(WiFi.firmwareVersion());
       WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
       while (WiFi.status() != WL_CONNECTED) ;
       Serial.print("connected, IP address is ");
       server.begin();
       Serial.println(WiFi.localIP()); }

    void show_client(const char *msg, WiFiClient *pclient) {
       Serial.print(msg); Serial.print(":");
       if (*pclient) {
          Serial.print(" IP "); Serial.print(pclient->remoteIP());
          Serial.print(" port "); Serial.print(pclient->remotePort()); }
       else Serial.print("none");
       Serial.println(); }

    void check_for_another_client(const char *msg) {
       WiFiClient newClient;
       newClient = server.available();
       show_client(msg, &newClient); }

    void loop(void) {
       WiFiClient client;
       while (!(client = server.available())) ;
       Serial.print("\n time: "); Serial.println((float)millis()/1000);
       show_client("client 1", &client);
       check_for_another_client("client 2");
       while (client.available() == 0) ;  // wait for data
       check_for_another_client("client 3");
       Serial.print("client 1 data read: "); Serial.println(client.read(), HEX); // read the data
       check_for_another_client("client 4");
       while (client.available()) client.read(); // flush the rest of the input
       delay(1000);
       client.stop(); // abort the connection
    }

The output is:

    ESP32 firmware version: 1.2.2
    connected, IP address is 192.168.86.35

     time: 43.22
    client 1: IP 192.168.86.32 port 62346
    client 2: IP 192.168.86.32 port 62346
    client 3:none
    client 1 data read: 47
    client 4:none

The question is: why does server.available() continue to say that I have new connections until there is some data available on the connection it already gave me? What if a second connection arrives after the 3-way TCP connection establishment handshake (SYN, ACK/SYN, ACK) but before any data arrives? How do I get that second connection?

The second question, which is related, is illustrated by the Sniffer trace of that transaction:

    179 *REF*     192.168.86.32  192.168.86.35  TCP  66  62346 → 80 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
    180 0.000239  192.168.86.32  192.168.86.35  TCP  66  62347 → 80 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 WS=256 SACK_PERM=1
    183 0.039352  192.168.86.35  192.168.86.32  TCP  58  80 → 62346 [SYN, ACK] Seq=0 Ack=1 Win=5744 Len=0 MSS=1436
    184 0.039431  192.168.86.32  192.168.86.35  TCP  54  62346 → 80 [ACK] Seq=1 Ack=1 Win=64240 Len=0
    185 0.039602  192.168.86.32  192.168.86.35  HTTP 488 GET / HTTP/1.1
    195 0.278592  192.168.86.35  192.168.86.32  TCP  54  80 → 62346 [ACK] Seq=1 Ack=435 Win=5310 Len=0
    197 1.053036  192.168.86.35  192.168.86.32  TCP  54  80 → 62346 [FIN, ACK] Seq=1 Ack=435 Win=5310 Len=0
    198 1.053146  192.168.86.32  192.168.86.35  TCP  54  62346 → 80 [ACK] Seq=435 Ack=2 Win=64240 Len=0
    199 1.053600  192.168.86.32  192.168.86.35  TCP  54  62346 → 80 [FIN, ACK] Seq=435 Ack=2 Win=64240 Len=0
    200 1.060248  192.168.86.35  192.168.86.32  TCP  54  80 → 62346 [ACK] Seq=2 Ack=436 Win=5309 Len=0

The request is from the Chrome browser. As you can see, it tries to establish two simultaneous TCP connections from two different source ports, 62346 and 62347, because it will use the second one for embedded images. But WiFiMINA never accepts that connection with the 3-way handshake, and never gives it to me. Chrome will resend the second SYN packet three seconds later, but as long as the first connection is still active, WiFiMINA continues to ignore it.

How can you accept two simultaneous TCP connections on different source ports from the same client? That's required for Chrome.

body:
The server.available() in Arduino networking libraries returns always the first connected client. This is in contrary with ESP8266 and ESP32 WiFi libraries for Arduino. They flag the returned connection as claimed and don't return it again. If the WiFiClient on ESP goes out of scope it is closed. In Arduino libraries you must stop() the Client to close the connection and free the 'socket'.

The Arduino Ethernet library has a new function not adopted yet by the WiFi libraries. It is server.accept(). It marks the connection as accepted and the next call doesn't return the same client. The sketch is still responsible to call stop(). The use of accept() is demonstrated in AdvancedChatServer example of the Ethernet library 2.00.

What you can do? Get the connection (WiFiClient), handle the request, send the response and stop() the connection. Then handle the next Client. Set Expires header to let browser cache the static files.


message:
Micro is not recognised as HID device

Being a completely noob with Arduino (but not with coding though) I'm trying to create a simple buttonbox with a Micro unit.

For now, I can not figure out what should I do to make my Windows 10 recognize the Arduino as a HID device (joystick actually). What did I miss?

body:
Joystick ([github.com/MHeironimus/ArduinoJoystickLibrary][1]) lib did the job. @chrisl, thx for the patience.

  [1]: https://github.com/MHeironimus/ArduinoJoystickLibrary


message:
Why voltage drop cause changes in analog reading of hall-effect sensor?

The sensor is a hall-effect [UGN3503][1] sensor and I'm using a [TL431][2] shunt regulator as voltage reference for analog readings.

I'm using `analogRead()` with setting the analog reference to external `analogReference(EXTERNAL);`.

schematic:

<!-- Begin schematic: In order to preserve an editable schematic, please
     don't edit this section directly.
     Click the "edit" link below the image in the preview instead. -->

![schematic](https://i.stack.imgur.com/sICIL.png)

<!-- End schematic -->

The problem is changes in analog reading of hall-effect sensor. without connecting anything to Arduino but the sensor and TL431 reading is around `~1020`, but for example connecting a single LED to any pins of Arduino causes the reading drop by `~2-3` or connecting the an I2C LCD causes the reading to drop to `~1010` etc...

How can i prevent analog read changes to happen when voltage drops?

  [1]: http://www.bristolwatch.com/hall_effect/ugn3503.pdf
  [2]: https://www.onsemi.com/pub/Collateral/TL431-D.PDF

body:
It sounds like your +5v supply is only barely adequate and sags as you draw even marginally more current. But even given that, your AREF is the TL431's voltage which 1) won't match the supply voltage (slightly redrawn schematic shows why), and 2) the sensor voltage could possibly exceed the AREF which is out of spec for the Arduino's A/D.

A more stable power supply - able to maintain its voltage despite the expected variation in current draw - would help a lot, but your best solution is to use the supply voltage as your AREF, unless you require the TL431 reference to be your AREF for some reason.

[![image][1]][1]

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


body:
I suspect the USB 5v supply is rather noisy and sags slightly with load. A hall effect sensor measures TINY signals, so it's probably quite sensitive to changes in supply voltage.

You might try adding a capacitor to the line, but you'd be better off either feeding 7.5-9-VDC into the barrel connector and using the on-board voltage regulator on the Arduino to generate your 5V and 3.3V, or feeding a regulated 5V supply into a cut USB cable (that way you get the power source switching and fuse protection on Arduino boards, but still can use an externally regulated 5V supply.)


message:
Why is Serial Print causing different behaviour based on where its located

Im trying to test out these two motors I have where I need to call a function from the loop. I only want to call this function once so I made a quick little if statement to have the program only run once. However, it seems that when I run this file, the Variable I have set doesn't continue getting incremented. The code will tell more.

```c
int i = 0;

void loop()
{
    // Serial.print("=====");Serial.print(i);Serial.println("=====");
    if(i == 1)
    {
        Serial.print("+++");Serial.print(i);Serial.print("+++");
        DeclinationMotor(DEC_freq, NULL, HIGH);
    }
    i++;
}
```

The behavior is really odd in that if i just run that code above, the variable **i** will not get incremented and become stuck at 1. However if I were to un-comment the other serial print line above the if statement, i would be incremented properly and that function will be executed only once.

For reference, the function **DeclinationMotor** is

```c
float DeclinationMotor(float freqspeed, float angularDistance, byte direction)
{
    Serial.print(freqspeed); Serial.print("DEfS "); Serial.print(angularDistance); Serial.print("DEaD "); Serial.println(direction);

    int finalLocation = 0;
    if(freqspeed == NULL && angularDistance != NULL)
        freqspeed = DEC_freq;
    if(angularDistance != NULL)
    {
        if(direction == HIGH)
            finalLocation = DEC_degrees_from_home + angularDistance;
        else
            finalLocation = DEC_degrees_from_home - angularDistance;
    }

    SetPinFrequency(DEC_STEP, freqspeed);
    pwmWrite(DEC_STEP, 128);
    digitalWrite(DEC_DIR, direction);
    digitalWrite(DEC_running, HIGH);

    return finalLocation;
}
```

**Full Code Here**
```c
//-----------------------------------------------------------------------------
#include <PWM.h>
void analogJoyStick();
void serialEvent();
void meridianFlipT();
float RightAscensionMotor(float freqspeed, float angularDistance, byte direction);
float DeclinationMotor(float freqspeed, float angularDistance, byte direction);
void StopRAMotor();
void StopDECMotor();

// --------------Todo--------------
// Turn the Variables into motor actions for serial event
// Write program that helps figure out the encoders degrees for its
// angle crap. You might just need to count exactly how many
// times the revolution goes around manually
// set up isrs for optical sensors and joystick
// create stop motors function
//

#define RA_sensor 2
#define DEC_sensor 3

// Sensor limit LEDs
#define RA_limit 27
#define DEC_limit 29

// Telescope Position Status LEDs
#define home_pos 35
#define tracking 37

// Joystick
#define xPin A0      // X axis
#define yPin A1      // Y axis
#define JS_button 26 // Button

// Motor 1
#define RA_STEP 10                // Step for Right Ascension
#define RA_DIR 12                 // Direction for Right Ascension
#define RA_EN 32                  // Enable motor disconnection
#define RA_OUT 36                 // Motor fault output
int RA_freq = 800;                // Frequency for normal movement
int RA_freq_tracking = 400;       // Frequency for tracking objects
int RA_freq_slow = 600;           // Frequency for when close to desired position
volatile byte RA_track_DIR = LOW; // Used to store last direction of RA motor

// Encoder 1
#define RA_A 18
#define RA_B 19
#define RA_I 22
long int RA_Encoder_Count = 0;      // Positive value means net position is in B direction
int RA_Complete_Rotations = 0; // Positive value means net complete rotation is in B direction
int RA_degrees_from_home = 0;  // Used to keep track of how far from home position

// Motor 2
#define DEC_STEP 11                 // Step for Declination
#define DEC_DIR 13                  // Direction for Declination
#define DEC_EN 34                   // Enable motor disconnection
#define DEC_OUT 38                  // Motor fault output
int DEC_freq = 800;                 // Frequency for normal movement
int DEC_freq_slow = 600;            // Frequency when close to desired position
volatile byte DEC_track_DIR = LOW;  // Used to store last direction of DEC motor

// Encoder 2
#define DEC_A 20
#define DEC_B 21
#define DEC_I 24
long int DEC_Encoder_Count = 0;      // Positive value means net position is in B direction
int DEC_Complete_Rotations = 0; // Positive value means net complete rotation is in B direction
int DEC_degrees_from_home = 0;  // Used to keep track of how far from home position

// Communication with ATmega328
#define COMM 39
#define RA_running 23
#define DEC_running 25

int i = 0;

void setup()
{
    // Sensor Inputs
    pinMode(RA_sensor, INPUT);
    pinMode(DEC_sensor, INPUT);

    // Sensor Fault LEDs
    pinMode(RA_limit, OUTPUT);
    pinMode(DEC_limit, OUTPUT);

    // Telescope Position Status LEDs
    pinMode(home_pos, OUTPUT);
    pinMode(tracking, OUTPUT);

    // Interrupts for Sensors
    // attachInterrupt(digitalPinToInterrupt(RA_sensor), RA_sensor_trip, CHANGE);
    // attachInterrupt(digitalPinToInterrupt(DEC_sensor), DEC_sensor_trip, CHANGE);

    // Right Ascension Motor Inputs and Outputs
    pinMode(RA_STEP, OUTPUT);
    pinMode(RA_DIR, OUTPUT);
    pinMode(RA_OUT, INPUT);
    // attachInterrupt(digitalPinToInterrupt(RA_OUT), RA_motor_fault, CHANGE);

    // Right Ascension Encoder Inputs
    pinMode(RA_A, INPUT);
    // attachInterrupt(digitalPinToInterrupt(RA_A), RA_Enc, RISING);
    pinMode(RA_B, INPUT);
    pinMode(RA_I, INPUT);

    // Declination Motor Inputs and Outputs
    pinMode(DEC_STEP, OUTPUT);
    pinMode(DEC_DIR, OUTPUT);
    pinMode(DEC_OUT, INPUT);
    // attachInterrupt(digitalPinToInterrupt(DEC_OUT), DEC_motor_fault, CHANGE);

    // Declination Encoder Inputs
    pinMode(DEC_A, INPUT);
    // attachInterrupt(digitalPinToInterrupt(DEC_A), DEC_Enc, RISING);
    pinMode(DEC_B, INPUT);
    pinMode(DEC_I, INPUT);

    // Joystick inputs
    pinMode(xPin, INPUT);
    pinMode(yPin, INPUT);
    pinMode(JS_button, INPUT);

    // Communication with ATmega328
    pinMode(COMM, OUTPUT);
    pinMode(RA_running, OUTPUT);
    pinMode(DEC_running, OUTPUT);

    // Constant signal to ATmega328 to confirm ATmega2560 is operational
    digitalWrite(COMM, HIGH);

    Serial.begin(9600);
    InitTimersSafe();

}

void loop()
{
    // Serial.print("=====");Serial.print(i);Serial.println("=====");
    if(i == 1)
    {
        Serial.print("+++");Serial.print(i);Serial.print("+++");
        DeclinationMotor(RA_freq, NULL, HIGH);
    }
    i++;
}

void analogJoyStick()
{
    int NumbX, NumbY;

    while(digitalRead(JS_button) == LOW)
    {
        NumbX = analogRead(xPin);
        NumbY = analogRead(yPin);

        // Here we go to to move the motor and the numbers have been created with
        // small numerical buffers to allow deadzones. It was made to be linear response
        // to the users input.

        if(NumbX > 530)
            RightAscensionMotor((RA_freq * (NumbX - 512)/512), NULL, HIGH);
        else if(NumbX < 500)
            RightAscensionMotor((RA_freq * (NumbX - 512)/512), NULL, LOW);
        else
            StopRAMotor();

        if(NumbY > 530)
            DeclinationMotor(800, NULL, HIGH);
        else if(NumbY < 500)
            DeclinationMotor(800, NULL, LOW);
        else
            StopDECMotor();
        delay(50);
    }
    // Track();
}

// this thing seems to be appended onto the end of the loop() so the immediate intersection must be
void serialEvent()
{
    char ident = Serial.read();     // first character will be the identifying character

    if(ident == 'R')
    {
        int number1 = Serial.parseInt();        // these variables should become global afterwards
        Serial.read();
        int number2 = Serial.parseInt();

        // you don't know what origin is yet so..
    }
    else if(ident == 'M')
    {
        int raAngle = Serial.parseInt();
        Serial.read();                              // These serial reads are for the separaters in the transmitted string
        int raDirection = Serial.parseInt();
        Serial.read();
        int dAngle = Serial.parseInt();
        Serial.read();
        int dDirection = Serial.parseInt();

        RightAscensionMotor(RA_freq, raAngle, raDirection);
        DeclinationMotor(DEC_freq, dAngle, dDirection);
    }

    // Serial.readbytes()
    Serial.read();      // this is to read the newline character out of the buffer.
}

// This needs to be called if
// if(Osensor1 || Osensor2)
    // meridianFlip();
void meridianFlipT()
{
    float finalLocationRA, finalLocationD;
    byte RACheck = LOW; byte DCheck = LOW;
    Serial.println("F1");    // newline is already incorporated

    // Right so, RA is normal yea whatever, but Declination is made this way to allow the counter weight
    // to always be pointed away from the tripod. For the latitude is 0 at the pole.
    finalLocationRA = RightAscensionMotor(RA_freq, 180, !RA_track_DIR);
    finalLocationD = DeclinationMotor(DEC_freq, ((180 - DEC_degrees_from_home) * 2), !DEC_track_DIR);

    // This is going to check to see if both the motors have turned to their respective locations theres
    // a little buffer period that is inputted to just to see if the motor gets there. We can replaced this later on
    while(RACheck == LOW || DCheck == LOW)
    {
        if(RACheck == LOW && (finalLocationRA + 2 > RA_degrees_from_home && finalLocationRA - 2 < RA_degrees_from_home))
        {
            digitalWrite(RA_running, LOW);
            RACheck = HIGH;
        }
        if(DCheck == LOW && (finalLocationD + 2 > DEC_degrees_from_home && finalLocationD - 2 < DEC_degrees_from_home))
        {
            digitalWrite(DEC_running, LOW);
            DCheck = HIGH;
        }
        delay(10);
    }

    //Track();            // Resume Tracking
    Serial.println("F0");
}

// These two are just functions to move the motors with. Might have a
// return to tell that its finished or something
float RightAscensionMotor(float freqspeed, float angularDistance, byte direction)
{
    Serial.print(freqspeed); Serial.print("RAfS "); Serial.print(angularDistance); Serial.print("RAaD "); Serial.println(direction);

    int finalLocation = 0;
    if(freqspeed == NULL && angularDistance != NULL)
        freqspeed = RA_freq;
    if(angularDistance != NULL)
    {
        if(direction == HIGH)
            finalLocation = RA_degrees_from_home + angularDistance;
        else
            finalLocation = RA_degrees_from_home - angularDistance;
    }

    SetPinFrequency(RA_STEP, freqspeed);                 // Look at SetPinFrequencySafe()
    pwmWrite(RA_STEP, 128);
    digitalWrite(RA_DIR, direction);
    digitalWrite(RA_running, HIGH);                 // I think this just turns it on?

    return finalLocation;
}

float DeclinationMotor(float freqspeed, float angularDistance, byte direction)
{
    Serial.print(freqspeed); Serial.print("DEfS "); Serial.print(angularDistance); Serial.print("DEaD "); Serial.println(direction);

    int finalLocation = 0;
    if(freqspeed == NULL && angularDistance != NULL)
        freqspeed = DEC_freq;
    if(angularDistance != NULL)
    {
        if(direction == HIGH)
            finalLocation = DEC_degrees_from_home + angularDistance;
        else
            finalLocation = DEC_degrees_from_home - angularDistance;
    }

    SetPinFrequency(DEC_STEP, freqspeed);
    pwmWrite(DEC_STEP, 128);
    digitalWrite(DEC_DIR, direction);
    digitalWrite(DEC_running, HIGH);

    return finalLocation;
}

void StopRAMotor()
{
    Serial.println("-RAMotor Stopped-");
    digitalWrite(RA_STEP, LOW);
    digitalWrite(RA_running, LOW);
}
void StopDECMotor()
{
    Serial.println("-DECMotor Stopped-");
    digitalWrite(DEC_STEP, LOW);
    digitalWrite(DEC_running, LOW);
}
```
[![Output from the Serial monitor after about 10 seconds][1]][1]

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

body:
Here is my guess what happens:

Once the code in the if statement have run, the `loop()` only contains the incrementation of `i`. This will run very fast. After a rather short time (maybe someone here can make the calculation to get the time, that is needed) `i` will overflow, going from it's most positive value to it's most negative value, then incrementing further and finally reaching again `1`. As this happens rather fast, you think, that `i` does not increment, but it is just flowing over again and again. `i` is of type `int`, which means, that it needs 65535 `loop()` iterations, to get to `1` again.

About the version with the extra `Serial.print()` calls: You didn't show us your `setup()`, but you probably have chosen a rather slow baudrate (maybe 9600, as it is used by many examples). At the first iterations the calls are just placing the data in the buffer and returning fast. But after a few iterations the `Serial` buffer is full. In this case the `Serial.print()`/`Serial.write()` functions (and their siblings) are blocking the code execution, until enough space in the buffer is free. So this would considerably slow down the executing of the `loop()`, thus considerably increasing the time between `i` overflows - to a point, where you don't wait long enough to actually see it overflow (but it will happen at some point).

---

To execute a code part only once you can either use the `setup()` function (if the call should happen at the start of the program), or you can use a simple flag. Imagine, that you don't increment `i` in the `loop()`, but that you are setting it's value to zero inside of the if statement. That would prevent the code in the if statement to execute again, until you yourself set `i` to 1 again.

    byte flag = 0;

    void setup(){
        flag = 1; // Set flag to 1 somewhere in your sketch as you like, to execute the if statement
    }

    void loop(){
        if(flag){
            //execute the wanted code here
            flag = 0; // deactivate this code by setting the flag to 0
        }
    }

Notice, that I changed some things here:

1. I changed the name of the variable to `flag`, because that's what it is: A simple flag with only 2 states - zero and non-zero

2. I changed the type of the variable to `byte`, as you don't need a whole `int` (16 bits) for a simple flag. So I used the smallest variable type, a `byte`. (you could also use boolean here, but basically that's the same)

3. The if statement now only checks for the value of `flag` directly. It will evaluate as true, if `flag` is not zero, as false, if it is zero. (So you could set `flag` to any other value than zero to activate the code, but `true` is also defined as 1, so I stayed in line with this).

4. I set the `flag` back to zero inside the if statement, so that it will not be executed another time. It will only execute again, if you yourself set `flag` again to a non-zero value somewhere in your code.


message:
Can I use only Ruby or Crystal Lang with an Arduino?

I am new to Arduino. I have used other SBCs before and ran some ruby script to automate many tasks.

I know Ruby and Crystal programming languages.

Can I use Ruby or Crystal solely on Arduino for creating basic robot?

body: No. You cannot. It is not possible. And some more filler to make the answer long enough.


body:
You could bridging via Firmata: https://playground.arduino.cc/Interfacing/Ruby/

Another resource is https://code.tutsplus.com/articles/using-ruby-to-program-arduino--cms-21893

You will need to Flash your Arduino with Firmata and then program in Ruby.
I'm not sure if that would work with Crystal.


body:
This is for Ruby:
https://playground.arduino.cc/Interfacing/Ruby/

Here are generic info about interfacing:
https://playground.arduino.cc/Main/Interfacing/


message:
Editing a particular position in a file stored in SD card

I am trying to store some variables in a text file which is saved in a SD card, using the SD library. Every time my program runs, it load the values of those variables from the file. After a few minutes, my program will attempt to change the value of some variables (not all).

This is what I would in a C program. I would locate the position (using position()) where the values to be edited is present, and then using the seek() function I would write at the given position thus overwriting the file.

Each variable is stored in a separate row. But for some reason the program only writes at the end of the file, even if I have moved the file pointer elsewhere. **How can I do the above task?**

A simple example of the code is as follows:

    #include <SD.h> //Load SD library

    int chipSelect = 53;
    File file;

    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);
      pinMode(chipSelect, OUTPUT); // chip select pin must be set to OUTPUT mode

      Serial.print("Welcome!");
      Serial.println();

      bool initialization_state = SD.begin(chipSelect);
      delay(400); // SD card needs sometime to intialize

      if (!initialization_state) { // Initialize SD card
        Serial.println("Could not initialize SD card."); // if return value is false, something went wrong
      } else {  // if return value is true
        Serial.println("SD card initialized");
      }

      SD.remove("misc.txt");
      file = SD.open("misc.txt",FILE_WRITE);
      file.print("Once you know the central idea and a rough plan for your paragraphs, you need to arrange them in a certain manner to get your story across.");
      file.println();
      file.print("Following are some possible ways of organizing your paragraphs.");
      file.println();
      file.print("Narration: Tell a story. Go chronologically, from start to finish. Description: Provide specific details about what something looks, smells, tastes, sounds, or feels like.");
      file.println();
      file.print("Organize spatially, in order of appearance, or by topic. Process: Explain how something works, step by step. Perhaps follow a sequence—first, second, third.");
      file.close();
      read_file();
      Serial.print("Read?");
      Serial.println();

      update_file();
      read_file();
    }

    void loop() {
      // put your main code here, to run repeatedly:
    }

    void read_file() {
      Serial.println("--- Reading file ---");
      file = SD.open("misc.txt", FILE_READ);

      char character;
      while( (character = file.read()) != -1) {
        Serial.print(character);
      }
      Serial.println();
      file.close();
    }

    void update_file() {
      file = SD.open("misc.txt", FILE_READ);
      char character;
      while( (character = file.read()) != '\n') {}
      byte pos = file.position();
      file.close();

      file = SD.open("misc.txt", FILE_WRITE);
      file.seek(pos);
      file.print(" Love, love, love.");
      file.close();
    }

In this program I am attempting to overwrite the second line. The while loop breaks at the first newline character. I store the location of the first character in the second line in a variable pos. Then I open the file object for writing, I seek the position where I want to write (using file.seek(pos) ) and then I print into the file. But when I read the file, the text "Love, love, love." is written at the end.

I am using the linux Arduino IDE 1.8.9.

body:
The problem is that you are opening the file with `FILE_WRITE`.  That is a combined macro that is made up of:

    #define FILE_WRITE (O_READ | O_WRITE | O_CREAT | O_APPEND)

The key one there is `O_APPEND`.  In the source code ([SdFile.cpp](https://github.com/arduino-libraries/SD/blob/master/src/utility/SdFile.cpp#L427)) t says:

> **O_APPEND** - If set, the file offset shall be set to the end of the file prior to each write.

So the seek does nothing if `O_APPEND` is set, since it is overridden.

So instead you need to open the file without `O_APPEND`.  In fact you don't need to close and open the file at all, since if opened correctly you can hop around at will reading and writing.  The flag `O_RDWR` is a combination of `O_READ` and `O_WRITE`.

For example:

    void update_file() {
      file = SD.open("misc.txt", O_RDWR);
      char character;
      while( (character = file.read()) != '\n') {}
      file.print(" Love, love, love.");
      file.close();
    }

The `O_CREAT` flag that is part of `FILE_WRITE` will create a new file if you try and open one that doesn't exist. By omitting that `SD.open` will fail if the file you are trying to modify doesn't exist.


message:
Write an array to SD

I'm new to the Arduino and I asked some questions around here and they were really helpful so I'm hoping I will get help once more
```
#define maxLen 800

volatile  unsigned int irBuffer[maxLen]; //stores timings - volatile because changed by ISR
volatile unsigned int x = 0; //Pointer thru irBuffer - volatile because changed by ISR

void setup() {
  Serial.begin(9600); //change BAUD rate as required
  attachInterrupt(0, rxIR_Interrupt_Handler, CHANGE);//set up ISR for receiving IR signal
}

void loop() {

  Serial.println(F("Press the button on the remote now - once only"));
  delay(5000); // pause 5 secs
  if (x) { //if a signal is captured
    Serial.println();
    Serial.print(F("Raw: (")); //dump raw header format - for library
    Serial.print((x - 1));
    Serial.print(F(") "));
    detachInterrupt(0);//stop interrupts & capture until finshed here
    for (int i = 1; i < x; i++) { //now dump the times
      if (!(i & 0x1)) Serial.print(F(" "));
      Serial.print(irBuffer[i] - irBuffer[i - 1]);
      Serial.print(F(", "));
    }
    x = 0;
    Serial.println();
    Serial.println();
    attachInterrupt(0, rxIR_Interrupt_Handler, CHANGE);//re-enable ISR for receiving IR signal
  }

}

void rxIR_Interrupt_Handler() {
  if (x > maxLen) return; //ignore if irBuffer is already full
  irBuffer[x++] = micros(); //just continually record the time-stamp of signal transitions

}
```
I would like to modify the code above to write to an SD file instead of printing it on the serial port. I've tried to use myFile.write or myFile.print but it won't work. Maybe I am just not that aware of how the SD functions work. Any tips?
This is a function to capture IR signals. I require them for a Arduino remote.
The modified code:
```
//you may increase this value on Arduinos with greater than 2k SRAM
#define maxLen 800

#include <SPI.h>
#include <SD.h>

File myFile;

volatile  unsigned int irBuffer[maxLen]; //stores timings - volatile because changed by ISR
volatile unsigned int x = 0; //Pointer thru irBuffer - volatile because changed by ISR

void setup() {
  Serial.begin(9600); //change BAUD rate as required
  attachInterrupt(0, rxIR_Interrupt_Handler, CHANGE);//set up ISR for receiving IR signal
}

void loop() {
  // put your main code here, to run repeatedly:

  Serial.print("Initializing SD card...");

  if (!SD.begin(53)) {
    while (1);
  }
  Serial.println("initialization done.");

  // open the file. note that only one file can be open at a time,
  // so you have to close this one before opening another.
  myFile = SD.open("test.txt", FILE_WRITE);

  Serial.println(F("Press the button on the remote now - once only"));
  delay(5000); // pause 5 secs
  if (x) { //if a signal is captured
    Serial.println();
    myFile.print(F("Raw: (")); //dump raw header format - for library
    myFile.print((x - 1));
    myFile.print(F(") "));
    detachInterrupt(0);//stop interrupts & capture until finshed here
    for (int i = 1; i < x; i++) { //now dump the times
      if (!(i & 0x1)) myFile.write(F(" "));
      myFile.print(irBuffer[i] - irBuffer[i - 1]);
      myFile.print(F(", "));
    }
    x = 0;
    Serial.println();
    Serial.println();
    attachInterrupt(0, rxIR_Interrupt_Handler, CHANGE);//re-enable ISR for receiving IR signal
  }

}

void rxIR_Interrupt_Handler() {
  if (x > maxLen) return; //ignore if irBuffer is already full
  irBuffer[x++] = micros(); //just continually record the time-stamp of signal transitions

}
```

body:
You are never closing the file.  The SD library (owing to how SD cards work) operates around a 512 byte buffer. Only when that buffer is full, or the library is manually instructed, will that buffer ever get written to the SD card.

The two ways of forcing the buffer to be written to the card are:

* Close the file with `myFile.close()` or
* Flush the file with `myFile.flush()`

Unless you do one of those after storing your data, since you are writing less than 512 bytes, the data will be lost when you power off (or reset) or remove the SD card.


message:
Trouble in sensor data reading sequence

I am reading from two MPU6050 sensors using Arduino Uno but it give trouble in squence. The code is perfect and also sensors reading is done.
See image of serial monitor.

>[![Reading of sensors data][1]][1]

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

You can see the above image in which the output data of serial monitor is not lining up. It breaks the lines after some time interval. I want to expect the serial data in lining. Here is the code:

    // I2Cdev and MPU6050 must be installed as libraries, or else the .cpp/.h files
    // for both classes must be in the include path of your project
    #include "I2Cdev.h"

    #include "MPU6050_6Axis_MotionApps20.h"
    //#include "MPU6050.h" // not necessary if using MotionApps include file

    // Arduino Wire library is req1uired if I2Cdev I2CDEV_ARDUINO_WIRE implementation
    // is used in I2Cdev.h
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
    #include "Wire.h"
    #endif

    // class default I2C address is 0x68
    // specific I2C addresses may be passed as a parameter here
    // AD0 low = 0x68 (default for SparkFun breakout and InvenSense evaluation board)
    // AD0 high = 0x69
    //MPU6050 mpu;
    MPU6050 mpu1(0x68);
    MPU6050 mpu2(0x69); // <-- use for AD0 high

    // uncomment "OUTPUT_READABLE_YAWPITCHROLL" if you want to see the yaw/
    // pitch/roll angles (in degrees) calculated from the q1uaternions coming
    // from the FIFO. Note this also req1uires gravity1 vector calculations.
    // Also note that yaw/pitch/roll angles suffer from gimbal lock (for
    // more info, see: http://en.wikipedia.org/wiki/Gimbal_lock)
    #define OUTPUT_READABLE_YAWPITCHROLL

    int pre_count = 0;

    #define LED_PIN 13 // (Arduino is 13, Teensy is 11, Teensy++ is 6)
    bool blinkState = false;

    // MPU control/status vars
    bool dmpReady1 = false;  // set true if DMP init was successful
    uint8_t mpuIntStatus1;   // holds actual interrupt status byte from MPU
    uint8_t devStatus1;      // return status after each device operation (0 = success, !0 = error)
    uint16_t packetSize1;    // expected DMP packet size (default is 42 bytes)
    uint16_t fifoCount1;     // count of all bytes currently in FIFO
    uint8_t fifoBuffer1[64]; // FIFO storage buffer

    // MPU control/status vars
    bool dmpReady2 = false;  // set true if DMP init was successful
    uint8_t mpuIntStatus2;   // holds actual interrupt status byte from MPU
    uint8_t devStatus2;      // return status after each device operation (0 = success, !0 = error)
    uint16_t packetSize2;    // expected DMP packet size (default is 42 bytes)
    uint16_t fifoCount2;     // count of all bytes currently in FIFO
    uint8_t fifoBuffer2[64]; // FIFO storage buffer

    // orientation/motion vars
    Quaternion q1;           // [w, x, y, z]         q1uaternion container
    VectorInt16 aa1;         // [x, y, z]            accel sensor measurements
    VectorInt16 aa1Real1;     // [x, y, z]            gravity1-free accel sensor measurements
    VectorInt16 aa1World1;    // [x, y, z]            world-frame accel sensor measurements
    VectorFloat gravity1;    // [x, y, z]            gravity1 vector
    float euler1[3];         // [psi, theta, phi]    euler1 angle container
    float ypr1[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity1 vector

    // packet structure for InvenSense teapot demo
    uint8_t teapotPacket1[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };

    Quaternion q2;           // [w, x, y, z]         q1uaternion container
    VectorInt16 aa2;         // [x, y, z]            accel sensor measurements
    VectorInt16 aa1Real2;     // [x, y, z]            gravity1-free accel sensor measurements
    VectorInt16 aa1World2;    // [x, y, z]            world-frame accel sensor measurements
    VectorFloat gravity2;    // [x, y, z]            gravity1 vector
    float euler2[3];         // [psi, theta, phi]    euler1 angle container
    float ypr2[3];           // [yaw, pitch, roll]   yaw/pitch/roll container and gravity1 vector

    // packet structure for InvenSense teapot demo
    uint8_t teapotPacket2[14] = { '$', 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0x00, 0x00, '\r', '\n' };

    // ================================================================
    // ===               INTERRUPT DETECTION ROUTINE                ===
    // ================================================================

    volatile bool mpuInterrupt1 = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady1() {
      mpuInterrupt1 = true;
    //  Serial.println("Mpu interrupt true");
    }

    volatile bool mpuInterrupt2 = false;     // indicates whether MPU interrupt pin has gone high
    void dmpDataReady2() {
      mpuInterrupt2 = true;
    }

    // ================================================================
    // ===                      INITIAL SETUP                       ===
    // ================================================================

    void setup() {
      // join I2C bus (I2Cdev library doesn't do this automatically)
    #if I2CDEV_IMPLEMENTATION == I2CDEV_ARDUINO_WIRE
      Wire.begin();
      TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz)
    #elif I2CDEV_IMPLEMENTATION == I2CDEV_BUILTIN_FASTWIRE
      Fastwire::setup(400, true);
    #endif

      // initialize serial communication
      // (115200 chosen because it is req1uired for Teapot Demo output, but it's
      // really up to you depending on your project)
      Serial.begin(115200);
      while (!Serial); // wait for Leonardo enumeration, others continue immediately

      // NOTE: 8MHz or slower host processors, like the Teensy @ 3.3v or Ardunio
      // Pro Mini running at 3.3v, cannot handle this baud rate reliably due to
      // the baud timing being too misaligned with processor ticks. You must use
      // 38400 or slower in these cases, or use some kind of external separate
      // crystal solution for the UART timer.

      // initialize device
      Serial.println(F("Initializing I2C devices 1..."));
      mpu1.initialize();

       // initialize device
      Serial.println(F("Initializing I2C devices 2..."));
      mpu2.initialize();

      // verify connection
      Serial.println(F("Testing device 1 connections..."));
      Serial.println(mpu1.testConnection() ? F("MPU6050 1 connection successful") : F("MPU6050 1 connection failed"));

      // verify connection
      Serial.println(F("Testing device 2 connections..."));
      Serial.println(mpu2.testConnection() ? F("MPU6050 2 connection successful") : F("MPU6050 2 connection failed"));

      // wait for ready
      Serial.println(F("\nSend any character to begin DMP programming and demo: "));
      while (Serial.available() && Serial.read()); // empty buffer
      while (!Serial.available());                 // wait for data
      while (Serial.available() && Serial.read()); // empty buffer again

      // load and configure the DMP
      Serial.println(F("Initializing DMP 1..."));
      devStatus1 = mpu1.dmpInitialize();

      // load and configure the DMP
      Serial.println(F("Initializing DMP 2..."));
      devStatus2 = mpu2.dmpInitialize();

      // supply your own gyro offsets here, scaled for min sensitivity
      mpu1.setXGyroOffset(220);
      mpu1.setYGyroOffset(76);
      mpu1.setZGyroOffset(-85);
      mpu1.setZAccelOffset(1788); // 1688 factory default for my test chip

      // supply your own gyro offsets here, scaled for min sensitivity
      mpu2.setXGyroOffset(74);
      mpu2.setYGyroOffset(14);
      mpu2.setZGyroOffset(-19);
      mpu2.setZAccelOffset(253); // 1688 factory default for my test chip

      // make sure it worked (returns 0 if so)
      if (devStatus1 == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP 1..."));
        mpu1.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady1, RISING);
        mpuIntStatus1 = mpu1.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP 1 ready! Waiting for first interrupt..."));
        dmpReady1 = true;

        // get expected DMP packet size for later comparison
        packetSize1 = mpu1.dmpGetFIFOPacketSize();
      } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP 1 Initialization failed (code "));
        Serial.print(devStatus1);
        Serial.println(F(")"));
      }

      // make sure it worked (returns 0 if so)
      if (devStatus2 == 0) {
        // turn on the DMP, now that it's ready
        Serial.println(F("Enabling DMP 2..."));
        mpu2.setDMPEnabled(true);

        // enable Arduino interrupt detection
        Serial.println(F("Enabling interrupt detection (Arduino external interrupt 0)..."));
        attachInterrupt(0, dmpDataReady2, RISING);
        mpuIntStatus2 = mpu2.getIntStatus();

        // set our DMP Ready flag so the main loop() function knows it's okay to use it
        Serial.println(F("DMP 2 ready! Waiting for first interrupt..."));
        dmpReady2 = true;

        // get expected DMP packet size for later comparison
        packetSize2 = mpu2.dmpGetFIFOPacketSize();
      } else {
        // ERROR!
        // 1 = initial memory load failed
        // 2 = DMP configuration updates failed
        // (if it's going to break, usually the code will be 1)
        Serial.print(F("DMP 2 Initialization failed (code "));
        Serial.print(devStatus2);
        Serial.println(F(")"));
      }

      // configure LED for output
      pinMode(LED_PIN, OUTPUT);
    }

    // ================================================================
    // ===                    MAIN PROGRAM LOOP                     ===
    // ================================================================

    void loop() {

      // if programming failed, don't try to do anything
      if (!dmpReady1) return;

      // if programming failed, don't try to do anything
      if (!dmpReady2) return;

    // Serial.println("code access here 1");
      // wait for MPU interrupt or extra packet(s) available
      while (!mpuInterrupt1 && fifoCount1 < packetSize1) {
        // other program behavior stuff here
        // .
        // .
        // .
        // if you are really paranoid you can freq1uently test in between other
        // stuff to see if mpuInterrupt1 is true, and if so, "break;" from the
        // while() loop to immediately process the MPU data
        // .
        // .
        // .
         break;

    //    Serial.println("code access here 2");
      }

      // wait for MPU interrupt or extra packet(s) available
      while (!mpuInterrupt2 && fifoCount2 < packetSize2) {
        // other program behavior stuff here
        // .
        // .
        // .
        // if you are really paranoid you can freq1uently test in between other
        // stuff to see if mpuInterrupt1 is true, and if so, "break;" from the
        // while() loop to immediately process the MPU data
        // .
        // .
        // .
        break;
      }

      // reset interrupt flag and get INT_STATUS byte
      mpuInterrupt1 = false;
      mpuIntStatus1 = mpu1.getIntStatus();

      // reset interrupt flag and get INT_STATUS byte
      mpuInterrupt2 = false;
      mpuIntStatus2 = mpu2.getIntStatus();

      // get current FIFO count
      fifoCount1 = mpu1.getFIFOCount();

      // get current FIFO count
      fifoCount2 = mpu2.getFIFOCount();

      // check for overflow (this should never happen unless our code is too inefficient)
      if ((mpuIntStatus1 & 0x10) || fifoCount1 == 1024) {
        // reset so we can continue cleanly
        mpu1.resetFIFO();
        Serial.println(F("FIFO overflow!"));

        // otherwise, check for DMP data ready interrupt (this should happen freq1uently)
      } else if (mpuIntStatus1 & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount1 < packetSize1) fifoCount1 = mpu1.getFIFOCount();

        // read a packet from FIFO
        mpu1.getFIFOBytes(fifoBuffer1, packetSize1);

        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount1 -= packetSize1;

    #ifdef OUTPUT_READABLE_YAWPITCHROLL
        // display euler1 angles in degrees
        mpu1.dmpGetQuaternion(&q1, fifoBuffer1);
        mpu1.dmpGetGravity(&gravity1, &q1);
        mpu1.dmpGetYawPitchRoll(ypr1, &q1, &gravity1);
        int count = 0;
        count++;
        pre_count += count;
        Serial.print(pre_count);
        Serial.print("\t");
        Serial.print(ypr1[0] * 180 / M_PI);
        Serial.print("\t");
        Serial.print(ypr1[1] * 180 / M_PI);
        Serial.print("\t");
        Serial.print(ypr1[2] * 180 / M_PI);
        Serial.print("\t");
    #endif

    //    // blink LED to indicate activity
    //    blinkState = !blinkState;
    //    digitalWrite(LED_PIN, blinkState);
      }

       // check for overflow (this should never happen unless our code is too inefficient)
      if ((mpuIntStatus2 & 0x10) || fifoCount2 == 1024) {
        // reset so we can continue cleanly
        mpu2.resetFIFO();
        Serial.println(F("FIFO 2 overflow!"));

        // otherwise, check for DMP data ready interrupt (this should happen freq1uently)
      } else if (mpuIntStatus2 & 0x02) {
        // wait for correct available data length, should be a VERY short wait
        while (fifoCount2 < packetSize2) fifoCount2 = mpu2.getFIFOCount();

        // read a packet from FIFO
        mpu2.getFIFOBytes(fifoBuffer2, packetSize2);

        // track FIFO count here in case there is > 1 packet available
        // (this lets us immediately read more without waiting for an interrupt)
        fifoCount2 -= packetSize2;

    #ifdef OUTPUT_READABLE_YAWPITCHROLL
        // display euler1 angles in degrees
        mpu2.dmpGetQuaternion(&q2, fifoBuffer2);
        mpu2.dmpGetGravity(&gravity2, &q2);
        mpu2.dmpGetYawPitchRoll(ypr2, &q2, &gravity2);
        Serial.print("\t");
        Serial.print(ypr2[0] * 180 / M_PI);
        Serial.print("\t");
        Serial.print(ypr2[1] * 180 / M_PI);
        Serial.print("\t");
        Serial.println(ypr2[2] * 180 / M_PI);
    #endif

    //    // blink LED to indicate activity
    //    blinkState = !blinkState;
    //    digitalWrite(LED_PIN, blinkState);
      }

       // blink LED to indicate activity
        blinkState = !blinkState;
        digitalWrite(LED_PIN, blinkState);
    }

What is the problem?
Thanks in advance!

body:
Both printing codes are inside of different if statements, which involve testing `mpuIntStatus1` and `mpuIntStatus2`. This works good, as long as in one `void loop()` iteration both of these if statements are executed. But that's a timing issue and you cannot assume, that these things happen regularly and always this way. Without completely analyzing your code, the variables `mpuIntStatus1/2` seem to indicate, that new data arrived. There is no reason, why this should be synchronized with the `void loop()` iterations.

To solve this you should rewrite your code to include all these print statements into one single if statement at the end of `void loop()`. In the if statements from above you can set a flag to indicate, that data arrived. This flag will be tested by the if statement at the end of loop. It is up to you to decide, how this should behave, when only data from 1 sensor arrived. You can only print the values from this sensor, or you can print both and using dummy values, that can be distinguished by humans (for example all values zero). Or you can choose to only print out values, if both sensors have given you results.


message:
I2C LCD TFT with UART serial communication for MLX90615 IR thermometer freezing IR output

I have one Ir temperature mlx90615 sensor based of this connection only used for mega2560 RX1&TX1) :

[![enter image description here][1]][1]
Which is connected to one Arduino 2560 mega with one LCD TFT 2.4 like this (Arduino mega2560 RX1 TX2 instead of Uno for mlx90615 connection and UNO 3.5V and Ground used to power supply the MLX90615):
[![enter image description here][2]][2]

So my problem is when i insert some new object in the seen area of Ir sensor the output halt for some second delay and don't show new value  via serial point or LCD output.

it characteristic table via [datasheet of mlx90615][3] sensor is :

[![enter image description here][4]][4]

[![enter image description here][5]][5]

I have use this source code on library for mlx90615 into my codes by this function:
```

or(i=0;i<8;i++){
  i=1;
 serialEvent();
  if(sign)
  {
     sign=0;
     for(i=0;i<8;i++)
      sum+=Re_buf[i];
     if(sum==Re_buf[i] )
     {
           TO=(float)(Re_buf[4]<<8|Re_buf[5])/100;
//           Serial.print("TO:");
//           Serial.println(TO);
//           TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
//           Serial.print("TA:");
//           Serial.println(TA);

             tft.fillScreen(BLACK);
             tft.setTextColor(WHITE);
             tft.setTextSize(3);
             Serial.print("TO:");
             Serial.println(TO);

            tft.setCursor(10, 15);
            tft.print("Temprature :");
            tft.setCursor(10, 50);
            tft.print(TO);
            tft.setCursor(100, 30);tft.print("C");
             TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
             Serial.print("TA:");
             Serial.println(TA);
             delay(100);
   }
  }

 }

void serialEvent(){
  char i;
  Serial1.write(0XA5);
  Serial1.write(0X15);
  Serial1.write(0XBA);
  for (i=0;i<30;i++)
  {
    while (Serial1.available()) {

    Re_buf[counter]=(unsigned char)Serial1.read();
    if(counter==0&&Re_buf[0]!=0x5A) return;
    counter++;
    if(counter==9)
    {
       counter=0;i=600;
       sign=1;
    }
  }
  }
}
```

The total codes are here:

```
#include "LiquidCrystal.h"

 #include <Adafruit_GFX.h>    // Adafruit's core graphics library
#include <Adafruit_TFTLCD.h> // Adafruit's hardware-specific library
#include <TouchScreen.h>     //Touchscreen library
///#include <Fonts/Org_01.h>    //Include a different font
#include <EEPROM.h>         //Include the EEPROM library to score the highscore
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;

#include <TimeLib.h>

bool backsensed = false;
bool resetsensed = false;

// most mcufriend shields use these pins and Portrait mode:
uint8_t YP = A1;  // must be an analog pin, use "An" notation!
uint8_t XM = A2;  // must be an analog pin, use "An" notation!
uint8_t YM = 7;   // can be a digital pin
uint8_t XP = 6;   // can be a digital pin

#define TS_MINX 100
#define TS_MINY 120
#define TS_MAXX 920
#define TS_MAXY 940
//Create the touchscreen object
TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);  //(data,data,data,data,sensitivity);

//Some of the tft pins
#define LCD_CS A3
#define LCD_CD A2
#define LCD_WR A1
#define LCD_RD A0
// Optional, used to reset the display
#define LCD_RESET A4

#define REDBAR_MINX 80
#define GREENBAR_MINX 130
#define BLUEBAR_MINX 180
#define BAR_MINY 30
#define BAR_HEIGHT 250
#define BAR_WIDTH 30

//Create the tft object
//Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);

// Define some TFT readable colour codes to human readable names
#define BLACK   0x0000
int BLUE = tft.color565(50, 50, 255);
#define DARKBLUE 0x0010
#define VIOLET 0x8888
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
int GREY =  tft.color565(64, 64, 64);
#define GOLD 0xFEA0
#define BROWN 0xA145
#define SILVER 0xC618
#define LIME 0x07E0

int currentpcolour;

//Minimum and maximum pressure to sense the touch
#define MINPRESSURE 10
#define MAXPRESSURE 1000

#define DRAW_LOOP_INTERVAL 50  //The interval used instead of delay();

//Define the address used in the eeprom memory to store highscores
#define addr 0
int currentpage;

int currentWing;        //Used to flap the wings
int flX, flY, fallRate; //Used to calculete and store the bird's position
int pillarPos, gapPosition;  //Used tho draw the pillars
int score;              //Store the score
int highScore = 0;      //Store the highscore
bool running = false;   //Store weather flying or not
bool crashed = false;   //Store weather crashed or not
bool scrPress = false;  //Store weather sensed some touch and store
long nextDrawLoopRunTime;
int redval;
int greenval;
int blueval;

int redpos = BAR_MINY + 12;
int greenpos = BAR_MINY + 12;
int bluepos = BAR_MINY + 12;

int oldrpos = redpos;
int oldgpos = greenpos;
int oldbpos = bluepos;
int x, y;

int lastDay = 0;
int lastMonth = 0;
int lastYear = 0;
int lastHour = 0;
int lastMinute = 0;
int lastSecond=0;
int movementTimer = 0;
int menuOptions = 4;
int menuOption = 0;
int alarmHours = 0;
//int Heater_alarmMinutes = 0;
//int Heater_alarmSecond=10;
//int Motor_alarmSecond=10;
//int Motor_alarmMinutes=0;

byte Heater_alarmMinutes_end ;
byte Heater_alarmSecond_end;
byte Motor_alarmSecond_end;
byte Motor_alarmMinutes_end;

bool heater_key = 0;
bool backLightOn = 1;
int fadeValue = 255;

byte address=0;
byte value;

bool state=1;

//#$############# MLX9615 ##################

 unsigned char Re_buf[11],counter=0;
 char sign=0;
float TO=0,TA=0;
void serialEvent();

//########################################
void DrawTriangle() {
 int n, i, cx = tft.width() / 2 - 1, cy = tft.height() / 2 - 1;

 tft.fillScreen(BLACK);
 n = min(cx, cy);

 for (i = 0; i < n; i += 15) {
 tft.drawTriangle(
 cx , cy - i, // peak
 cx - i, cy + i, // bottom left
 cx + i, cy + i, // bottom right
 tft.color565(0, 0, i));
 }
}
void drawHome()
{

  tft.fillScreen(BLACK);
  tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border

  tft.fillRoundRect(60, 180, 200, 40, 8, RED);
  tft.drawRoundRect(60, 180, 200, 40, 8, WHITE);  //Game

  tft.fillRoundRect(60, 130, 200, 40, 8, RED);   //RGB led
  tft.drawRoundRect(60, 130, 200, 40, 8, WHITE);

  tft.fillRoundRect(60, 80, 200, 40, 8, RED);
  tft.drawRoundRect(60, 80, 200, 40, 8, WHITE); //Oscilloscope

  tft.setCursor(60, 20);
  tft.setTextSize(2);
///  tft.setFont();
  tft.setTextColor(WHITE);
  tft.print("Select on Option");
  tft.setCursor(70, 50);
  tft.setTextSize(2);
  tft.setTextColor(LIME);
  tft.print("GSH.ir");
  tft.setTextColor(BLACK);

  tft.setCursor(80, 95);
  tft.print("Heater Setting");

  tft.setCursor(80, 145);
  tft.print("Motor  Setting");

  tft.setCursor(70, 195);
  tft.print("     Start");

  //tft.drawCircle(30, 30, 20, RED);
  //tft.fillCircle(111, 111, 30, WHITE);
  //  delay(500);
  //tft.drawRoundRect(120, 192, 60, 64, 15, YELLOW);
  // tft.fillRoundRect(0, 192, 60, 64, 15, CYAN);

   // tft.drawRect(0, 0, 60, 64, CYAN);

   //  tft.fillRect(180, 192, 60, 64, GREY);
     //DrawTriangle();

}

void drawstart(bool k)
{

  tft.fillScreen(BLACK);
  tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border

//  tft.fillRoundRect(60, 180, 200, 40, 8, RED);
//  tft.drawRoundRect(60, 180, 200, 40, 8, WHITE);  //Game
//
//  tft.fillRoundRect(60, 130, 200, 40, 8, RED);   //RGB led
//  tft.drawRoundRect(60, 130, 200, 40, 8, WHITE);
//
  tft.fillRoundRect(90, 60, 160, 60, 18, RED);
  tft.drawRoundRect(90, 60, 160, 60, 18, WHITE); //Oscilloscope

  tft.setCursor(40, 180);
  tft.setTextSize(3);
///  tft.setFont();
  tft.setTextColor(WHITE);

  if (k) {
    tft.print("Motor on time");
  }else{
    tft.print("Heater on time");
  }

}
void drawMenu(bool k)
{
   tft.fillScreen(BLACK);

  tft.drawRoundRect(0, 0, 319, 240, 8, WHITE);     //Page border

//  tft.fillRoundRect(60, 180, 200, 40, 8, RED);
//  tft.drawRoundRect(60, 180, 200, 40, 8, WHITE);  //Game
//
//  tft.fillRoundRect(60, 130, 200, 40, 8, RED);   //RGB led
//  tft.drawRoundRect(60, 130, 200, 40, 8, WHITE);
//
//  tft.fillRoundRect(75, 80, 160, 60, 18, BLUE);
 // tft.drawRoundRect(700, 60, 160, 80, 18, WHITE); //Oscilloscope

  //tft.fillTriangle(60,60,20,120,180,180,RED);
  tft.fillRoundRect(70, 75, 180, 70, 18, GREEN);
   //tft.fillTriangle(42, 20, 42, 60, 90, 40, RED);
   tft.fillTriangle(260,90, 260, 130, 300, 110, RED);
   tft.fillTriangle(60,90, 60, 130, 20, 110, RED);

  tft.setCursor(45, 180);
  tft.setTextSize(2.95);
///  tft.setFont();
  tft.setTextColor(WHITE);
  if (k) {
    tft.print("Motor Timer Setting");
  }else{
    tft.print("Heater Timer Setting");
  }
//  tft.fillRoundRect(5, 5, 80, 60, 8, WHITE);
//  delay(70);

  tft.setTextSize(4);
  tft.fillRoundRect(5, 5, 80, 60, 8, RED);
  tft.drawRoundRect(5, 5, 80, 60, 8, WHITE);
  tft.setCursor(20,20);
  tft.print("<-");

   tft.fillRoundRect(230, 5, 85, 60, 8, BLUE);
  tft.drawRoundRect(230, 5, 85, 60, 8, WHITE);
  tft.setCursor(250, 20);
  tft.print("OK");

}

void start(){
  tft.fillScreen(BLACK);
   drawstart(0);
   setTime(0, 0, 1, 20, 1, 2013); // hour, min, sec, day, month, year
  lastHour = hour();

          //check for heater key pressed

   heater_key=1;state =1;
 while (state ){

   if ( lastSecond!=second())
   {
       lastMinute = minute();
       lastSecond=second();
       tft.setTextSize(6);
       tft.fillRoundRect(60, 60, 200, 100, 18, RED);
       //tft.fillScreen(BLACK);
       tft.setTextColor(WHITE);
       tft.setCursor(110, 85);
       tft.print(lastMinute);
       tft.setCursor(140,85);
       tft.print(":");
       tft.setCursor(170, 85);
       tft.print(lastSecond);
       //delay(1000);
   }
   if (heater_key)
    {
      // alarm set
      if ((Heater_alarmSecond_end <= lastSecond) && (Heater_alarmMinutes_end == lastMinute))
      {
         state=0;
         digitalWrite(A5, LOW);

      }
       if ((Heater_alarmSecond_end >= lastSecond) || (Heater_alarmMinutes_end >= lastMinute))
         {
          //sound alarm
          digitalWrite(A5, HIGH);
          //setOffAlarm();
         }
     }
   }

    drawstart(1);
    state =1;
   setTime(0, 0, 0, 20, 1, 2013); // hour, min, sec, day, month, year
   while (state){
   if ( lastSecond!=second())
   {
       lastMinute = minute();
       lastSecond=second();
       tft.setTextSize(6);
       tft.fillRoundRect(60, 60, 200, 100, 18, RED);
       //tft.fillScreen(BLACK);
       tft.setTextColor(WHITE);
       tft.setCursor(110, 85);
       tft.print(lastMinute);
       tft.setCursor(140,85);
       tft.print(":");
       tft.setCursor(170, 85);
       tft.print(lastSecond);
       //delay(1000);
   }
   if (1)
    {
      // alarm set
      if ((Motor_alarmSecond_end <= lastSecond) && (Motor_alarmMinutes_end == lastMinute))
      {
         state=0;
         digitalWrite(A6, LOW);

      }
       if ((Motor_alarmSecond_end >= lastSecond) || (Motor_alarmMinutes_end >= lastMinute))
         {
          //sound alarm
          digitalWrite(A6, HIGH);
          //setOffAlarm();
         }
     }
   }

//########### MLX90615 @#############
   char i=0,sum=0;

//  for (i=0;i<100;i++){
   score=1;
    while(score==1){
    serialEvent();
    if(sign)
    {
       sign=0;
       for(i=0;i<8;i++)
        sum+=Re_buf[i];
       if(sum==Re_buf[i] )
       {
             TO=(float)(Re_buf[4]<<8|Re_buf[5])/100;
             if ((int)TO>=30){
              score=0;
             }
             tft.setTextSize(3);
             Serial.print("TO:");
             Serial.println(TO);
            tft.fillScreen(BLACK);
            tft.setCursor(10, 15);
            tft.print("Temprature :");
            tft.setCursor(10, 50);
            tft.print(TO);tft.setCursor(100, 30);tft.print("C");
             TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
             Serial.print("TA:");
             Serial.println(TA);
             delay(100);
     }
    }
  }
//####################
   delay(100);
   drawHome();
   return;

}

void menu(){

// drawMenu();

 TSPoint p = ts.getPoint();     // Read touchscreen
 state =1;
// while(state){
// if (p.z > MINPRESSURE && p.z < MAXPRESSURE)
if (p.z > 10 && p.z < 1000)
    {
     tft.setTextSize(3);
            tft.setTextColor(RED);
            tft.setCursor(10, 10);
            tft.print(p.x);
            delay(500);
      /* if (p.y > 743 && p.x < 247 && p.x > 150 && p.y < 875)
        {
          tft.fillRoundRect(5, 5, 50, 30, 8, WHITE);
          delay(70);
          tft.fillRoundRect(5, 5, 50, 30, 8, BLUE);
          tft.drawRoundRect(5, 5, 50, 30, 8, WHITE);
          tft.setCursor(15, 15);
          tft.print("<-");
          delay(70);
          tft.fillRoundRect(5, 5, 50, 30, 8, BLACK);
          currentpage = 0;
          drawHome();
          p.x = 160;
          p.y = 760;
          return;
        }
      if (p.x > 736 && p.x < 855 && p.y > 255 && p.y < 725  )
      {
        tft.setTextSize(3);
            tft.setTextColor(WHITE);
            tft.setCursor(10, 10);
            tft.print("UP2");
            delay(500);

      }
      x = map(p.x, TS_MINX, TS_MAXX, tft.width(), 0);
      y = map(p.y, TS_MINY, TS_MAXY,  tft.height(), 0) + 30;
//tft.fillTriangle(250,90, 250, 130, 290, 110, RED);
//   tft.fillTriangle(60,90, 60, 130, 20, 110, RED);
    if (y > 70 && y < 130)
      {
        if (x > 20 && x < 120)
        {
            tft.setTextSize(3);
            tft.setTextColor(WHITE);
            tft.setCursor(50, 140);
            tft.print("DOWN");
        }
        if (x > 220 && x < 320)
        {
            tft.setTextSize(3);
            tft.setTextColor(WHITE);
            tft.setCursor(50, 140);
            tft.print("UP");
        }

      }
      */
  }
// }
}
////########## MLX90615    #############
//void serialEvent(){
//  while (Serial1.available()) {
//    Re_buf[counter]=(unsigned char)Serial1.read();
//    if(counter==0&&Re_buf[0]!=0x5A) return;
//    counter++;
//    if(counter==9)
//    {
//       counter=0;
//       sign=1;
//    }
//  }
//}
////########################

// initialize the library by providing the nuber of pins to it
LiquidCrystal lcd(8,9,4,5,6,7);

void setup()
{

  time_t t = now(); // store the current time in time variable t
  pinMode(A5, OUTPUT);pinMode(A6, OUTPUT);

  tft.reset();
  tft.begin(tft.readID());
//  Serial.begin(9600);
//  Serial.println();
//  Serial.print("reading id...");
//  delay(500);
//  Serial.println(tft.readID(), HEX);

  tft.fillScreen(BLACK);
  tft.setRotation(1);

  currentpage = 0;

  tft.setTextSize(3);
  tft.setTextColor(WHITE);
  tft.setCursor(50, 140);
  tft.print("Loading...");

  tft.setTextColor(tft.color565(255, 255, 0));
  tft.setCursor(30, 70);
  tft.print("By:");

  tft.setCursor(30, 100);
  tft.print("NotesPoint.com GSH.IR");

  for (int i; i < 250; i++)
  {
    tft.fillRect(BAR_MINY - 10, BLUEBAR_MINX, i, 10, RED);
    delay(0.000000000000000000000000000000000000000000000000001);
  }

  tft.fillScreen(BLACK);
  score=14;
  if (EEPROM.read(1)==score){
  address=2;
  tft.setCursor(300, 100);
  tft.print("eeprom writed beffor");
  Heater_alarmSecond_end = EEPROM.read(address);
  Heater_alarmMinutes_end= EEPROM.read(address+1);
  Motor_alarmSecond_end = EEPROM.read(address+2);
  Motor_alarmMinutes_end = EEPROM.read(address+3);
  }
  else{
    tft.setCursor(300, 100);
  tft.print("new eeprom");
    address=1;
  EEPROM.write(address,14);
  EEPROM.write(address+1,10);
  EEPROM.write(address+2,4);
  EEPROM.write(address+3,10);
  EEPROM.write(address+4,0);
  address=1;

  Heater_alarmSecond_end = EEPROM.read(address);
  Heater_alarmMinutes_end= EEPROM.read(address+1);
  Motor_alarmSecond_end = EEPROM.read(address+2);
  Motor_alarmMinutes_end = EEPROM.read(address+3);
  }
  delay(100);
  drawHome();
  setTime(0, 0, 0, 20, 1, 2013); // hour, min, sec, day, month, year
  //########### MLX90615 ############

Serial1.begin(115200);Serial.begin(115200);
  delay(1);
//  Serial1.write(0XA5);
//  Serial1.write(0X45);
//  Serial1.write(0XEA);
  Serial.write(0XA5);
  Serial1.write(0XA5);
  Serial1.write(0X15);
  Serial1.write(0XBA);
//buadrate 115200
  Serial1.write(0XA5);
  Serial1.write(0XAF);
  Serial1.write(0X54);

//#############################

}
//void setup() {
//
//lcd.begin(16,2);
//
//// set cursor position to start of first line on the LCD
//lcd.setCursor(0,0);
////text to print
//lcd.print("   16x2 LCD");
//// set cusor position to start of next line
//lcd.setCursor(0,1);
//lcd.print("   DISPLAY");
//   Serial1.begin(115200);
//   Serial.begin(115200);
//  delay(1);
//  Serial1.write(0XA5);
//  Serial1.write(0X45);
//  Serial1.write(0XEA);
//}

void loop() {

//
//
//
   char cc,i=0,sum=0;

   //  digitalWrite(13, HIGH);
  TSPoint p = ts.getPoint();     // Read touchscreen
//  digitalWrite(13, LOW);

  pinMode(XM, OUTPUT);
  pinMode(YP, OUTPUT);

//   score=1;
//   while(score==1){
for(i=0;i<8;i++){
  i=1;
 serialEvent();
  if(sign)
  {
     sign=0;
     for(i=0;i<8;i++)
      sum+=Re_buf[i];
     if(sum==Re_buf[i] )
     {
           TO=(float)(Re_buf[4]<<8|Re_buf[5])/100;
//           Serial.print("TO:");
//           Serial.println(TO);
//           TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
//           Serial.print("TA:");
//           Serial.println(TA);

             tft.fillScreen(BLACK);
             tft.setTextColor(WHITE);
             tft.setTextSize(3);
             Serial.print("TO:");
             Serial.println(TO);

            tft.setCursor(10, 15);
            tft.print("Temprature :");
            tft.setCursor(10, 50);
            tft.print(TO);
            tft.setCursor(100, 30);tft.print("C");
             TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
             Serial.print("TA:");
             Serial.println(TA);
             delay(100);
   }
  }

 }

}
void serialEvent(){
  char i;
  Serial1.write(0XA5);
  Serial1.write(0X15);
  Serial1.write(0XBA);
  for (i=0;i<30;i++)
  {
    while (Serial1.available()) {

    Re_buf[counter]=(unsigned char)Serial1.read();
    if(counter==0&&Re_buf[0]!=0x5A) return;
    counter++;
    if(counter==9)
    {
       counter=0;i=600;
       sign=1;
    }
  }
  }
}
```

 So has anybody this problem with this kind of sensors or other sensors?and why this happened?

***Update:***

Based of [this site][6] i have combined the blinky and mlx90615 uart sample code, and it's working without freeze, the code is shown below:

```

unsigned char Re_buf[11],counter=0;
unsigned char sign=0;
float TO=0,TA=0;
void setup() {
   pinMode(LED_BUILTIN, OUTPUT);
   Serial.begin(115200);
  delay(1);
  Serial.write(0XA5);
  Serial.write(0X45);
  Serial.write(0XEA);
}

void loop() {
  unsigned char i=0,sum=0;
 digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(50);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(50);
  if(sign)
  {
     sign=0;
     for(i=0;i<8;i++)
      sum+=Re_buf[i];
     if(sum==Re_buf[i] )
     {
           TO=(float)(Re_buf[4]<<8|Re_buf[5])/100;
           Serial.print("TO:");
           Serial.println(TO);
           TA=(float)(Re_buf[6]<<8|Re_buf[7])/100;
           Serial.print("TA:");
           Serial.println(TA);
   }
  }

}
void serialEvent() {
  while (Serial.available()) {
    Re_buf[counter]=(unsigned char)Serial.read();
    if(counter==0&&Re_buf[0]!=0x5A) return;
    counter++;
    if(counter==9)
    {
       counter=0;
       sign=1;
    }
  }
}
```

I have read this queston: [Hardware Serial causes hang-up][7] and i think its related to I2C comunication with TFT LCD by this:

> I think I found the solution. As you can see on the photo above, I
> used unscreened wires in comparison with the Breadboard. I2C is
> definitely very sensitive against EMP, which causes the bus freezes. I
> now use screened wires and don´t use the Breadboard anymore. The issue
> now occurs very rarely. Unfortunately I still don´t understand the
> interdependency to the UART interface. I will now improve the
> screening of my wireing. Hopefully, the breakdowns will totaly
> diappear.
>
>
> Re: Hardware Serial causes hang-up
> Summary: My final solution, after weeks of detective work is, to use another sensor board.  :smiley-fat:
> Obviously the ADXL 345 together with connected UART, provoked by EMP
> is the problem. I still don´t know why, but now, using the 10DOF GY-86
> board with the MCU5060 IMU, it runs stable in a longtime test, for
> over 60 hours! No more freeze!!! I hope this will help someone having
> similar problems!

Now it the end of week and i will go to holiday so i wil try newx two days by 16X2 Crystal LCD and printed board to check will it happen again?

Until next two days i will appriciate any sugestion or help.

Thanks a lot.

  [1]: https://i.stack.imgur.com/1uCJS.png
  [2]: https://i.stack.imgur.com/VYnYJ.png
  [3]: https://www.melexis.com/-/media/files/documents/datasheets/mlx90615-datasheet-melexis.pdf
  [4]: https://i.stack.imgur.com/3eruh.png
  [5]: https://i.stack.imgur.com/rZyuZ.png
  [6]: http://epc-project.ir/temp-mlx90615/
  [7]: https://forum.arduino.cc/index.php?topic=159870.0

body:
TBH, I've read your question many times but I still do not understand, what your problem is. What I can see is:

 - You provided picture with wiring for Arduino Uno, not Arduino Mega. If you are using LCD TFT shield intended for I2C and Arduino Uno, it will not work on Mega – this board has I2C on pin 20 (SDA) and 21 (SCL), not like Uno on pin A4 (SDA) and A5 (SCL). But I guess the LCD TFT shield uses SPI, not I2C. Even if it is SPI, it will not work either (again, different pinout).
 - You are using HW Serial #1 for debug and also for communication with the sensor. This may be the source of your problems. Use different HW Serial for debug (#1 is recommended) and different for communication with the sensor (e.g. Serial #2). Arduino Mega has 3 HW Serial interfaces. If you are using Uno and not Mega, use SoftwareSerial (but I recommend using smaller baud rate, if possible).