# Question
Title: Is it advisable to use Serial.write in an ISR when loop() routinely uses Serial.read?
I do not know much electronics.

I have Nano v3 as I2C master, it reads 5-byte packets (of delimtted data) from PC's USB port, processes it and forwards it.

I now need to implement a way to signal PC if something went wrong down the line. I don't want to clutter I2C channel and its just a flag so I think interrupt is best for my purpose.

While writing the ISR function I am not sure if its advisable to write data using Serial, because loop might have read 2-3 bytes of the 5-byte message packet. And I don't know if it will overwrite data coming from PC or what...

**What will happen if I Serial.write(0x1) (suddenly, in an ISR function) while loop() was reading data from same Serial**?

I don't know how to test this myself.

# Answer
Reading and writing of serial data are separate functions. When you `.write()` you just append the data to the TX buffer. When you `.read()` you just take the next character from the RX buffer.

All actual sending and receiving, and filling/emptying of the buffers is done inside the ISRs for the UART module.

That said, you *really* shouldn't use `Serial` inside an ISR. This is because the sending and receiving is done by an ISR, and if you are in *your* ISR then the sending can never happen until you leave your ISR. For the odd occasional byte it's not really a problem, but if the TX buffer fills up `Serial.write()` will block until the TX ISR has sent some data - which won't happen since your ISR is blocking the TX ISR.

So it's best to avoid any `Serial` operations inside an ISR. Instead you would normally set flags and values in an ISR then check for those flags in `loop()` to report anything.
> 2 votes

---
Tags: serial, i2c, interrupt, softwareserial, system-design
---


# Question
Title: Why SSD1306 OLED display get scrambled text when printing messages from separate tasks in RTOS? (revised)
ESP32 with RTOS, test app with 2 independent tasks. Each prints a message to OLED display. Why text gets frequently scrambled? Mutex have been used to share display resource.

```
#define DEBUG_ESP              //comment out to deactivate debug console verbose
#ifdef DEBUG_ESP
  #define pDBGln(x) Serial.println(x)
  #define pDBG(x)   Serial.print(x)
#else
  #define pDBG(...)
  #define pDBGln(...)
#endif

//create handle for the mutex. It will be used to reference mutex
SemaphoreHandle_t  xMutex;

//*********************************SSD1306 OLED Display
#define I2C_SDA              14
#define I2C_SCL              15
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//*****************************************************

void setup() {

  // create mutex and assign it a already create handler
  xMutex = xSemaphoreCreateMutex();

  Wire.begin(I2C_SDA,I2C_SCL);
  Serial.begin(115200);

   // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    pDBGln("SSD1306 allocation failed - Halt");
    for(;;); // Don't proceed, loop forever
  }else{
    // Show initial display buffer contents on the screen --
    // the library initializes this with an Adafruit splash screen.
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(0, 0);
    display.clearDisplay();
  }

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

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

void loop() {}

void task01( void * parameter ){
  while(1){
    printToDisplay("Task01..............");
    vTaskDelay(1500);
  }
}

void task02( void * parameter ){
  while(1){
    printToDisplay("Task02..............");
    vTaskDelay(2500);
  }
}

void printToDisplay(String text){
  bool myMutex;
  while(1){
    // take mutex
    myMutex = xSemaphoreTake(xMutex, portMAX_DELAY);
    if(myMutex){
      static byte   lineCounter = 0;
      static String displayText[8];
      if(lineCounter>7){
        for(int i=0;i<7;i++){
          displayText[i] = displayText[i+1];
        }
        displayText[7] = text;
        display.clearDisplay();
        display.setCursor(0, 0);
        for(int i=0;i<8;i++){
          display.println(displayText[i]);
        }
      }else{
        displayText[lineCounter] = text;
        display.println(displayText[lineCounter]);
        if(lineCounter<8){lineCounter++;}
      }
      display.display();

      // release mutex
      xSemaphoreGive(xMutex);
      break;
    }
  }
}

```

The code below uses no RTOS and works perfectly: (my project requires RTOS)

```
#define DEBUG_ESP              //comment out to deactivate debug console verbose
#ifdef DEBUG_ESP
  #define pDBGln(x) Serial.println(x)
  #define pDBG(x)   Serial.print(x)
#else
  #define pDBG(...)
  #define pDBGln(...)
#endif

byte lineCounter = 0;

//*********************************SSD1306 OLED Display
#define I2C_SDA              14
#define I2C_SCL              15
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
//*****************************************************

void setup() {

  Wire.begin(I2C_SDA,I2C_SCL);
  Serial.begin(115200);

   // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    pDBGln("SSD1306 allocation failed - Halt");
    for(;;); // Don't proceed, loop forever
  }else{
    // Show initial display buffer contents on the screen --
    // the library initializes this with an Adafruit splash screen.
    display.setTextSize(1);
    display.setTextColor(SSD1306_WHITE);
    display.setCursor(0, 0);
    display.clearDisplay();
  }
}

void loop() {
  pDBGln("Start Display Test...");
  task01();
  task02();
}

void task01(){
  printToDisplay("Task01..............");
  delay(500);
}

void task02(){
  printToDisplay("Task02..............");
  delay(500);
}

void printToDisplay(String text){
  static byte   lineCounter = 0;
  static String displayText[8];
  if(lineCounter>7){
    for(int i=0;i<7;i++){
      displayText[i] = displayText[i+1];
    }
    displayText[7] = text;
    display.clearDisplay();
    display.setCursor(0, 0);
    for(int i=0;i<8;i++){
      display.println(displayText[i]);
    }
  }else{
    displayText[lineCounter] = text;
    display.println(displayText[lineCounter]);
    if(lineCounter<8){lineCounter++;}
  }
  display.display();
}

```

# Answer
> 1 votes
This is a formal answer to the question based on the comments between Paulo Borges and Majenko.

---

The ESP32 is dual core, meaning that it comes with 2 Xtensa LX6 32-bit microprocessors: core 0 and core 1.

The issue is not a bug in your code but rather that you are running your threads on Core 0 instead of Core 1.

In the ESP, the Core 0 is used for the RF communications. Even with the mutex protection, it is highly likely that your tasks are having timing issues.

Move Task01 and Task02 into Core 1 and your program will run without any display issues.

---
Tags: esp32, oled
---


# Question
Title: connect USB keyboard to Arduino using clk and data wires
Edit: What I'm looking for is some kind of library which could be used with an arduino to read the HID protocol output from the Data+ and Data- cables of the USB.

========== If I cut the cable of a usb keyboard, plug in power and ground can I use the clk and data wires to read keystrokes into the Arduino? If so any pointers to libraries and schematics?

Simple I instructions? The "for dummies" version?

***EDIT***

Following some of the suggestions below I found this:

https://github.com/julianschuler/USBKeyboard

Which looks like what I want to do, basically hook up the lines into the arduinio and read from the keyboard using the HID protocol in this library.

***EDIT 2***

That doesn't do what I want. Does anyone know how this could be accomplished?

# Answer
USB doesn't have data and clock lines. It has a pair of data lines with inverted polarity (D+ and D-). The USB protocol is considerably more complex than you seem to imagine.

**However** there is a caveat: some keyboards have the ability to work in *IBM PS/2* mode. For this you will need a USB to PS/2 adaptor (pictured below) and then use the PS2Keyboard.h library. Your mileage may vary, though, as not all keyboards will work.
> 3 votes

---
Tags: arduino-mega, arduino-nano, usb
---


title: Calling class member from .h file

text:
# Question
Title: Calling class member from .h file
In `.ino` file I have a class defined (called `IPmonitoring`).Also, inside the same `.ino` file, I call a `.h` file ( which is located "above" class `IPmonotoring`).

When I try to call members of `IPmonitoring` inside .h file - I get an error, which usually I solve using `extern`, but seemingly it is not the same for classes.

What should be done ?

Guy

# Answer
> 2 votes
You need to re-think your layout, and your usage of the .h file.

* You should never have code in a .h file unless it is either `inline` or part of a `template` class.

A .h file should only contain hints about where other things are. Those things should then be in .cpp or .ino files.

For example your IPmonitoring class would be *declared* in a .h file, and *defined* (or *implemented*) in a .cpp file (or .ino file if you prefer). Any place you want to use that class you `#include` the .h file. In one place you may choose to create an instance of that class. It is that instance that you then reference with `extern`.

In the Arduino world it is common to create a single instance of the class in the class's .cpp file and `extern` it in the .h file so everywhere that you include the .h file instantly has access to that single instance of the object.

This is how most libraries are written.

For example:

```
// IPMonitoring.h

class IPMonitoring {
    public:
        void doStuff();
};

extern IPMonitoring ipMon;

```

And:

```
// IPMonitoring.cpp

#include <IPMonitoring.h>

IPMonitoring ipMon;

void IPMonitoring::doStuff() {
    // Do something
}

```

And finally:

```
// mySketch.ino

#include <IPMonitoring.h>

void setup() {
    ipMon.doSomething();
}

void loop() {
}

```

---
Tags: class
---


# Question
Title: In multidimensional arrays, can you use variable arrays or their names instead of the actual data?
Referring to this thread How to declare and use "Variabled arrays" inside arrays

Example

```
byte array[2][4] = { {1,2,3,4}, {5,6,7,8} };
Serial.println(array[0][2]); is equal to '3'.

```

Instead of using {1, 2, 3, 4} and {5, 6, 7, 8} I want to be able to declare separate arrays for each of them and just put the name.

Another big issue is putting arrays of different sizes for each entry and it would be wrong to do so. Is this really not possible? Do I have to use some other concept instead if I want to have an array that contains entries of arrays that have different sizes? I heard about pointers but not familiar with that.

Example,

```
byte arrayX[3] = {1, 2, 3}
byte arrayY[4] = {5, 6, 7, 8}

byte array[2][4] = { arrayX , arrayY };

```

Take note that the code was not taken from the link I mentioned, I just used the same array names. Also I changed arrayX from the link to 3 entries because I want to emphasize the part of my question if it is possible if arrays have different sizes and you would just use the biggest size?

Now I think this is wrong and I haven't tested it currently but I want to ask if there is a solution that makes use of what I have mentioned? The site I linked to gave a solution which feels very redundant in terms of declaration and I would not want that. This is the solution mentioned there.

```
byte arrayZ[2][4] = {
  {arrayX[0],arrayX[1],arrayX[2],arrayX[3]},
  {arrayY[0],arrayY[1],arrayY[2],arrayY[3]}
};

```

The issue I had when searching the internet is the same as the link. "Surfed on the internet to find a bunch of examples but the only difference is that they don't use arrays that have been declared to have a name inside array."

# Answer
> 2 votes
Two-dimensional arrays come in two "flavours". Actually, multi-dimensional arrays are possible in any combination of these.

* All elements in a rectangular grid, at least from the abstract view of the programming language;
* A one-dimensional array of one-dimensional arrays.

If you declare:

```
byte array[n][m];

```

then you have reserved space for "n times m" bytes. From the programmer's view it is a rectangular grid, actually all bytes are in sequence in a one-dimensional array. This is because the memory of our computers are commonly organized as a big one-dimensional array of bytes. The compiler generates the correct calculation for the offset into this array, multiplying one index with the size of the width (or length, depending on your mental model) and adding the other index.

You can initialize such an array with the nested set of curly braces like this:

```
byte array[n][m] = {
    { /* ... */ },
    /* ... */
};

```

But you cannot initialize it as you show.

Otherwise, if you declare

```
byte* array[n];

```

then you have reseved space for "n" pointers to bytes, that is a one-dimensional array of pointers. Each of these pointers can point to a different or the same one-dimensional array of bytes, or to no array at all if it's `nullptr`.

Now you can set up the array as you like:

```
byte arrayX[m1] = { /* ... */ };
byte arrayY[m2] = { /* ... */ };

byte* array[n] = { arrayX, arrayY, /* ... */ };

```

The arrays `arrayX` and `arrayY` (and any further) don't need to have the same length. Each can have its own length. But beware, you need to trace the length somehow to avoid out-of-bounds accesses. And of course, you need to check or be sure that a pointer is not null before dereferencing it.

In both cases you can access a single element with:

```
byte element = array[i][j];
array[k][l] = 23;

```

This is because the syntax with the brackets is equivalent to the dereferencing operator:

```
x[y] == *(x + y)

```

*Note 1: Since Arduinos are programmed in C++, there is another option. You can use references instead of pointers. Because it is really hard to create a null reference, some see it as a safety measure against null pointers.*

*Note 2: Again, since Arduinos are programmed in C++, you can implement an own class that provides the `operator[]`. With this option you can do any magical stuff, but it might break the user's expectation. Be careful if you go that route.*

---
Tags: array
---


# Question
Title: Serial plotter looks different and doesnt print graph
When I open my serial plotter to get the graph for my HC-SR04 sensor it doesn't show anything. My plotter looks different too. I have attached images below as well.

Only those numbers on the **top-most** move with time.(100,200,300) Here's my code:

```
int trigPin = 12;
int echoPin = 11;

int pingTravelTime;
float pingTravelDistance;
float distToTarget;

int baudRate = 9600;

int dT = 10;
int dT2 = 500 ;

String msg1 = "The distance is equal to ";
String msg2 = "cm";

void setup() {
  // put your setup code here, to run once:
  Serial.begin(baudRate);

  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  digitalWrite(trigPin, LOW);
  delayMicroseconds(dT);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(dT);
  digitalWrite(trigPin, LOW);

  pingTravelTime = pulseIn(echoPin, HIGH);

  pingTravelDistance = pingTravelTime * ((765. * 5280. * 12.) / (3600. * 1000000));
  pingTravelDistance = 2.54 * pingTravelDistance;
  distToTarget = (pingTravelDistance / 2);

  Serial.println(msg1 + distToTarget + msg2);

  delay(dT2);
}

```

What do I do??

# Answer
The serial plotter expects you to send numbers, and only numbers. If it reads any other text, like for example

“The distance is equal to 9.88cm”

It assumes these are the names of the columns of data that are to follow. So it chooses one color for each column and prints the color key on top of the graph.

> What do I do??

Just remove the prose and print only the numbers. You may print something like “distance(cm)” in `setup()` if you want to have the key displayed, but that is not required.
> 6 votes

---
Tags: arduino-uno
---


# Question
Title: Obtaining angular velocity from quaternion data (BNO055)
I'm able to get quaternion data from the BNO055 sensor, and would like to convert these to angular velocity for my project. I know you can pull the gyroscope directly for the data, but from what I understand using quaternions and converting those is more robust?

I found a function that does this in a Adafruit repository for the sensor. However, I'm not sure what the Delta time variable should be equal to, in relation to the sample frequency. Could anyone advise?

Here is the function code:

```
  Vector<3> toAngularVelocity(double dt) const {
    Vector<3> ret;
    Quaternion one(1.0, 0.0, 0.0, 0.0);
    Quaternion delta = one - *this;
    Quaternion r = (delta / dt);
    r = r * 2;
    r = r * one;

    ret.x() = r.x();
    ret.y() = r.y();
    ret.z() = r.z();
    return ret;
  }

```

And the link

# Answer
> 1 votes
I do not know how to interpret the data given by that sensor, but from reading the code, the meaning of `dt` is pretty clear.

The function you show assumes that the sensor started in the reference orientation (quaternion `one`), then rotated at a constant angular velocity until it reached the current orientation (quaternion `*this`), and this rotation happened over a time `dt`.

Then `dt` is the time required for moving from the reference orientation to the orientation described by the quaternion `*this`. You should probably check out the sensor's datasheet for more details on how the orientations are provided.

---
Tags: sensors, timing, imu, bno055
---


title: 2 instanced of ESP8266Ping

text:
# Question
Title: 2 instanced of ESP8266Ping
I'm using `ESP8266Ping` lib inside my `iot` lib which hanldes Wifi connectivity and MQTT messages. Since it create its own instance called `Ping` when calling `#include <ESP8266Ping.h>`\- it had to be place in `iot.cpp`.

I writing another library, `IPmonitor` which checks clients on the network (using pings), I wanted to use `ESP8266Ping` again.

My sketch file, create an instance of `iot` and `IPmonitor` for check/ log errors on monitored clients.

But I get error of using the same library twice.

I guess that since `ESP8366Ping.h` library is defined it creates an instance of the class ( see mark below ):

```
class PingClass {
  public:
    PingClass();

    bool ping(IPAddress dest,   byte count = 5);
    bool ping(const char* host, byte count = 5);

    int averageTime();

  protected:
    static void _ping_sent_cb(void *opt, void *pdata);
    static void _ping_recv_cb(void *opt, void *pdata);

    IPAddress _dest;
    ping_option _options;

    static byte _expected_count, _errors, _success;
    static int _avg_time;
};

#include "ESP8266Ping.impl.h"
PingClass Ping;                     // <----- This

#endif

```

How can it be solved ?

# Answer
> 2 votes
With that library... you can't. All the code is in one big monolithic .h file. As you well know by now that is a big no-no. The author should be given a big slap on the wrists.

The closest you could do without re-writing the whole library is to just copy the class definition from the outer .h file and create an `extern` to the existing object - maybe make your own copy of the `ESP8266Ping.h` file without the `#include "ESP8266Ping.impl.h"` and `PingClass Ping;` (the latter of which you change to an `extern`).

---
Tags: class
---


# Question
Title: What does an Arduino do if the serial connection is closed on the other end?
I have a simple method that simply waits for an input, computes a response, and sends it:

```
void loop() {
  if (Serial.available() > 0){
    input = Serial.read();

    if (input == 10){
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2);

      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10);
      digitalWrite(trigPin, LOW);

      duration = PulseDuration(echoPin, HIGH, 6000);
      distance = duration * 0.00034/2;  // 0.00034 m/us is speed of sound

      Serial.println(distance, 4);
      }
  }
}

```

My question: What happens to the arduino if I close the serial connection from the receiving end while it's printing out data (in the last line of the loop)?

Context and motivation:

The program works well most times. I can open a python program that sends the requests and prints out the reply using pyserial. After I close the python side and reopen it, connection is set and I can start listening on the side nicely just like the first time. Sometimes, however, when I try to restart the python program, I get a connection error saying that the port is already opened (I'm running in Windows.. there are tons of posts about this problem, but none of them have been helpful). Some other times, when connecting with the python program (which connects with `connection = serial.Serial(self.arduino_port, 9600, timeout=0)` it just blocks and doesn't connect, it doesn't give the "port already opened" error, and it doesn't advance to the next statement. I am confident I did close the previous python run before attempting a new one (process explorer shows no active python programs running, it also shows no open processes using a serial handler). I'm not here to solve that problem directly, though, just to ask a related question.

I'm also confident running `connection.close()` does not terminate the arduino program, as I have been able to restart my python program without having to reset the arduino or anything, suggesting the arduino kept running its loop after I closed the connection on the python side.

All that to say that my latest hypothesis is that these issues arise when I close the serial connection `connection.close()` while the arduino is printing, but because the port is closed, that Arduino is stuck and cannot do the Serial.println(), as the USB never asks to flush the data in its buffer. Is this possible/does it make sense? What happens to the arduino if I close the serial connection while it's printing out data?

I'm not posting my python program here as it's not directly relevant to the question and I can't seem to make a minimum reproducible program that doesn't expose confidential code.

# Answer
> 0 votes
That's some strange Intel monstrosity. It's impossible to know what it does or how. Intel's foray into the Arduinosphere was brief and somewhat abortive.

In general though (for most cores) the DTR signal (and sometimes the RTS signal too) of the CDC/ACM protocol is used to "gate" the serial data - if it's asserted then serial data gets sent through to the host PC. If it's not asserted then it just gets thrown away.

I have seen cores where if DTR is not asserted the data gets buffered until the TX buffer is full and then blocks, but that is rare.

You might find your answer if you delve into the core's source code, but you may find that big chunks of it are hidden away in closed source pre-compiled libraries, and the fact it seems to run some custom RTOS means it'll be even more obfuscated. YMMV...

---
Tags: serial, print, genuino, 101
---


# Question
Title: How can i call lcd.begin() from several different code files in a proper way?
I have a project split into several files:

```
//Loop.cpp
#include "LiquidCrystal.h"

void setup(){
    LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
    lcd.begin(16, 2);
}

void loop() {
//Code
}

```

```
//Display.cpp
#include "LiquidCrystal.h"

namespace display {
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void displayData(const InputPacket &inputPacket, const DataPacket &dataPacket) {
    lcd.setCursor(0,1);
    lcd.print("Foo");    //This creates display error, unless i call lcd.begin(16, 2) in this function
}

} //namespace display

```

My initial problem is that - without calling lcd.begin() from within displayData() - the characters aren't displayed correctly. In other words, calling lcd.begin() in setup() doesn't help. (It appears to me that setup() has implicit static property, no?)

As an attempted solution, i could create an lcd object in Display.cpp, and call lcd.begin() from within displayData(). Even though characters are displayed properly, this gives me display flickering. (Presumably as a result of calling these functions repeatedly in the loop during runtime).

So, the only solution to this dilemma that i can come up with is to call lcd.begin() from a function written to run only once inside of displayData(). Or is it?

My question is, are there other more elegant solutions/alternatives?

# Answer
> 2 votes
The object called `lcd` that you create inside the `setup` function is a local variable. It only lives as long as that function is executing - so not very long. It doesn't exist outside that function.

The `lcd` object you have in `namespace display` on the other hand is a global variable. That one lives as long as your program, which means until you reset your Arduino here. (It is completely unrelated to the object inside `setup`.)

If you want all your LCD code to be grouped inside the `display` namespace, you could do this in `Display.cpp`:

```
namespace display {
  // This is a global variable, full name `display::lcd`
  LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

  void setup() {
    // this `lcd` refers to the global `display::lcd` defined above
    lcd.begin(16, 2);
  }

  // rest of the display functions
}

```

Create a `Display.h` file to provide prototypes for the display module:

```
#ifndef DISPLAY_H
#define DISPLAY_H

// Include the header that defines InputPacket and DataPacket here

namespace display
{
void setup();
void displayData(const InputPacket &inputPacket, const DataPacket &dataPacket);
}

#endif

```

Then your main file can call the display function. The main file doesn't even have to know that you're using an LCD if you do package all LCD code in the display file.

```
#include "Display.h" // no need to include LiquidCrystal.h if all
                     // LCD handling is done in Display.cpp

void setup(){
  // Initialize display
  display::setup();
}

```

---
Tags: lcd, arduino-due
---


title: What's the time out of Wire.begin()?

text:
# Question
Title: What's the time out of Wire.begin()?
Here's a schematic of my project:

The purpose is to make laptop work as keyboard for desktop PC. Nano uses Serial.read() to get keystrokes from laptop and forwards key press and release data to Leonardo (using I2C) acting as USB-HID keyboard.

Nano's setup looks like:

```
void setup() {
  Wire.begin();
  Serial.begin(14400);
  Serial.write("Hello");  // https://serialport.io/docs/api-stream#serialpor|
  pinMode(LED_BUILTIN, OUTPUT);
}

```

Leonardo's setup looks like:

```
void setup() {
  Keyboard.begin();
  Wire.begin(4);
  Wire.onReceive(cbfunc);
}

```

I have tested both boards individually, but not the whole setup. Whenever either board connects to USB port it powers up due to +5 volt from USB. Now that I have i2c wires in place, I am confused -

if I connect leonardo & desktop first \[and i2c-master (Nano) isn't powered on yet\], what will happen at `Wire.begin(4)`? Will it wait (1s, 5s, forever) until i2c-master comes online?

# Answer
Generally you should not provide power to any pin of a device, which is powered off. That can cause current flowing through clamping diodes to ground and might destroy the pins hardware or the device (also it can lead to weird situations, where the device is somewhat powered through the IO pin, which might lead to instability).

You can either cut the connection between the devices, if only one of them is powered (this should be possible with some extra components), or you can power both devices from one USB port. For the other port you would cut the V+ (positive supply voltage) line of the USB port/cable (this makes sure, that you don't get a bad current between both computers on the USB power line, if they provide a bit different voltage). Since the ground wire still connects both computers and the Arduinos, the communication will still work correctly.

> if I connect leonardo & desktop first \[and i2c-master (Nano) isn't powered on yet\], what will happen at Wire.begin(4)?

The `Wire.begin()` line won't get stuck, since it doesn't do much on the lines and it doesn't know, if something is connected on the other end, until some transaction happens on the bus. But it might be, that any transaction from the powered Arduino (the master) might cause a blocked I2C bus (since at some places the library waits for the lines to get high. The connection through the clamping diodes might hold the line at low. I'm not sure about that). Then you would need to reset both Arduinos, to make sure, that the bus is in a healthy state.

The solution from above (powering both Arduinos from one USB port) will also make sure, that both Arduinos start at the same time and thus won't block the bus through the clamping diodes.
> 0 votes

---
Tags: serial, i2c, softwareserial, system-design
---


title: Calling functions between 2 classes

text:
# Question
Title: Calling functions between 2 classes
Class `myIOT2` contains a function that need to be called from class `IPmonitoring`:

```
bool myIOT2::checkInternet(char *externalSite, byte pings)
{
    return Ping.ping(externalSite, pings);
}

```

This function is needed as a pinger in `IPmonitor`:

```
void IPmonitoring::start(cb_func ping)
{

        _ping_cb = ping;
}

```

and this `cb_func` is defined by (inside `IPmonitor.h`):

```
typedef bool (*cb_func)(char *externalSite, byte pings);
cb_func _ping_cb;

```

inside my sketch (relevant parts only) I fail when `iot.checkInternet` is passed, while using a function `test` that calls `iot.checkInternet` succeeds:

```
myIOT2 iot;
IPmonitoring WiFi_service(ROUTER_IP, "Router");

bool test(char *a, byte b)
{
        bool x = iot.checkInternet(ROUTER_IP);
        return x;
}

void setup()
{
WiFi_service.start(iot.checkInternet); // <---- Trial a)fails
WiFi_service.start(test);              // <-----Trail b)succeeds
}

```

error is :

```
home/guy/Documents/git/Arduino/IPmonitor/IPmonitor.ino: In function 'void setup()':
IPmonitor:436:45: error: no matching function for call to 'IPmonitoring::start(<unresolved overloaded function type>)'
         WiFi_service.start(iot.checkInternet);//
                                             ^
/home/guy/Documents/git/Arduino/IPmonitor/IPmonitor.ino:436:45: note: candidate is:
In file included from /home/guy/Documents/git/Arduino/IPmonitor/IPmonitor.ino:2:0:
/home/guy/Documents/git/Arduino/libraries/myIPmonitor/myIPmonitor.h:42:10: note: void IPmonitoring::start(IPmonitoring::cb_func)
     void start(cb_func ping);
          ^
/home/guy/Documents/git/Arduino/libraries/myIPmonitor/myIPmonitor.h:42:10: note:   no known conversion for argument 1 from '<unresolved overloaded function type>' to 'IPmonitoring::cb_func {aka bool (*)(char*, unsigned char)}'
Multiple libraries were found

```

What is done wrong ? and why `test` succeeds ?

# Answer
There is a fundamental difference between a simple function and a function that is a member of a class. You can't use a function pointer to point to a member function of a class: simply because that member function also includes information about the class instance that it belongs to.

The *proper* C++ way to handle it is to use `std::function`, but the Arduino AVR compiler lacks the full STL (Standard Template Library), so that can't be used on normal Arduinos. Other cores do have it, so you may well be able to use it on the ESP8266.

If you want to make your code portable between systems that may not have the full STL then there's other tricks you have to do:

* Use a wrapper function (which as you have found works), or
* Make a polymorphic class and store a pointer to the instance cast to the parent class - the parent class defines the functions that are allowed to be called from the pointer.
> 1 votes

---
Tags: class
---


# Question
Title: Why AnalogRead shows value (395) when its on HIGH State ? why not shows 1023 when its high State
**I Took a output from ESP8266 and Connected it with Arduino Nano Analog input A0**

i use BLYNK app to on/off D0 pin in ESP8266 , and i connected ESP8266 D0 pin with Arduino Nano A0 analogPin.

when esp8266 D0 in high state , the analogRead value in arduino nano serial monitor it show the value 395.

why not 1023 on high state .

# Answer
There are two problems here - one immediate and one which will be come apparent.

First off, you appear not to have connected the ground pins of the two boards together. This is important. Voltage is not an absolute value, it's a value *relative to some other point in the circuit*. This is why "voltage" is sometimes called "potential *difference*". Normally the point in the circuit that voltages are referenced to is termed "ground". Note: there is nothing special about ground, it's just an arbitrary point in the circuit - usually, but not always, the point where the voltage is lowest. If the ground of the Arduino that it's using to compare incoming voltages against is not the same as the ground that the ESP8266 is using to create its output voltage in relation to, then the Arduino really can't know what the voltage is.

You can think of it as a person standing on the ground. Now I am about 6 feet tall. When I am stood up the top of my head is about 6 feet above the ground. But to someone who is stood on a nearby rise in the ground my head is only maybe 3 feet above the ground. Their ground is not the same as my ground.

The second problem, which will become apparent once you have connected the grounds, is that the Arduino measures voltages between 0 and 5V as values between 0 and 1023. However the ESP8266 doesn't operate at 5V, it operates at 3.3V. The highest voltage it can ever put out is 3.3V. The Arduino can never read that as 1023 because it's not 5V. Instead it will read somewhere around 675. That is, 3.3V is two thirds of 5V, and 675 is two thirds of 1023.
> 2 votes

---
Tags: arduino-nano, analogread
---


# Question
Title: Regarding using I2C with Arduino for Silicon Micro-structure 5852 D 1.5 psi
I am trying to get output from a sensor (micro-structure 5852D), but I only get two outputs: 11 and 255 for even applying pressure.

The following is my code, please show me how to over come this problem.

```
#include "Wire.h"
#define addrs 0x5F // I2C bus address

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

void loop()
{

   byte lobyte;
   byte hibyte;
   int Press;

   Wire.beginTransmission(addrs);
   Wire.write(1);
   int x = Wire.endTransmission();

   Serial.print("endTransmission: ");
   Serial.println(x, DEC);

   Wire.requestFrom(addrs, 2); // contents of your first two registers
   while(Wire.available() < 2 );          // Check for data from slave
   {
      delay(1000);
      lobyte = Wire.read();       // Read press high byte
      Serial.println(lobyte, DEC);
      hibyte = Wire.read();      // Read press low byte
      Serial.println(hibyte, DEC);

      Press = toPressure(hibyte, lobyte);
      Serial.print("Pressure: ");
      Serial.println(Press);

      delay(1000);
   }

}

float toPressure(byte hi, byte lo)
{
  int a = (hi * 256 + lo) & 0x3FFF;  // see pdf, mask 14 bit

  float rv = (a - 116)* 0.8606; // faster //(t - 1638.0) / 30.84 + 600.0
  return rv;

}

```

# Answer
> 2 votes
The issues in your code:

* When communicating with the sensor, the sensor expects a **register address** after the device address. Instead of providing it the register address, you sent the *number of bytes you would like to receive*. Good guess, but unfortunately the device was not designed that way.
* You did not combine the least significant bits and most significant bits of the sensor output correctly. The LSB contains the 6 (**not 8**) least significant bits, while the MSB contains the 6 most significant bits. You first combined them like `00MMMMMM00LLLLLL` (where bits marked L come from the LSB and bits marked M come from the MSB), and then masked off the upper two bits as in `MMMMMM00LLLLLL`. The proper way would have been to only left shift the MSB 6 bits, producing `0000MMMMMMLLLLLL`, and then masking away the upper 4 bits leaving `MMMMMMLLLLLL`.
* You should avoid 32 bit floating point math on 8-bit microcontrollers at all costs unless you have a huge amount of processor cycles to spare.

In order to read data from the sensor you must first select the register you want to read. To select a register you must first send the device address (95 in decimal, 5F in hexadecimal) with the write request bit set, and then the register address of the byte you want to read.
You can then read the contents of the selected register by first sending the device address, this time with the write request bit clear, and then receiving one byte of data immediately followed by a not acknowledge (NACK) to end the transmission.

The internal registers are organized as in the following table:

Here is my take on the code. It compiles fine, but obviously I cannot test if it actually works as I don't have the sensor. I removed the scaling routine, as it would be wise to first get it working to some level before implementing less essential features.

```
#include "Wire.h"
#include <stdint.h>

#define SENSOR_I2C_ADDR 95
#define SENSOR_REG_PRESSURE_LSB 128
#define SENSOR_REG_PRESSURE_MSB 129

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

void loop()
{
    Wire.beginTransmission(SENSOR_I2C_ADDR);        //Send the address of the register where the least
    Wire.write(SENSOR_REG_PRESSURE_LSB);            //..significant bits of the pressure measurement are found
    Wire.endTransmission(false);                    //Send a repeated start
    Wire.requestFrom(SENSOR_I2C_ADDR, 1, false);    //Request 1 byte of data, followed by a repeated start

    Wire.beginTransmission(SENSOR_I2C_ADDR);        //Send the address of the register where the most
    Wire.write(SENSOR_REG_PRESSURE_MSB);            //..significant bits of the pressure measurement are found
    Wire.endTransmission(false);                    //Send a repeated start
    Wire.requestFrom(SENSOR_I2C_ADDR, 1, true);     //Request 1 byte of data, followed by a stop, ending the transaction.

    uint16_t pressureRaw;

    //There should now be two bytes of data in the receive buffer.
    if(Wire.available() == 2)
    {
        uint8_t lsb = Wire.read();                  //The first byte contains the 6 least significant bits
        uint16_t msb = Wire.read();                 //The second byte contains the 6 most significant bits
        pressureRaw = (msb << 6 | lsb) & 0x0FFF;    //The most significant bits are aligned and combined with the
                                                    //..least significant bits. As the resulting value only has
                                                    //..12 bits of precision the upper 4 bits are masked to zero.

        Serial.print("Raw pressure value: ");
        Serial.println(pressureRaw);
    }
    else                                            //If more or less than 2 bytes have been received something isn't right.
    {
        while(Wire.available())                     //Clear the buffer
            Wire.read();
        Serial.println("I2C transaction error");
    }
    delay(1000);
}

```

For some unfathomable reason Silicon Microstructures decided to not include the I2C interface specification in the datasheet itself. The information is instead found in a separate application note.

EDIT:
Apparently Wire.flush() does absolutely nothing. Implementation from Wire.cpp:

```
void TwoWire::flush(void)
{
    // XXX: to be implemented.
}

```

And no, the implementation isn't in the base class either: `virtual void flush() = 0;`. To work around this, I replaced the flush call with a read() loop.

# Answer
> 2 votes
Sorry if I'm late to the party. I solved this years ago. Here's my YT video demo with a google drive link to the code in the video description. It works with the entire SM58XX series of sensors. Just input the parameters for your particular model in the top lines of the code and you'll be off to the races. https://www.youtube.com/watch?v=Xb2J1puSOwk

---
Tags: i2c
---


title: Dht 11 sensors give null value

text:
# Question
Title: Dht 11 sensors give null value
```
void Sensor_value()
{   server.handleClient();
    humidity = dht.readHumidity();
    temperature = dht.readTemperature();
 }

```

I want to make condition if temperature = null and Humidity= null that means the sensor fails to take reading so I want to return and take value again

# Answer
The way to do this is:

```
float h = dht.readHumidity();
float t = dht.readTemperature();
float f = dht.readTemperature(true);

if (isnan(h) || isnan(t) || isnan(f)) {
  Serial.println("Failed to read from DHT sensor!");
  return;
}

```

See https://www.hackster.io/MisterBotBreak/how-to-use-temperature-and-humidity-dht-sensors-9e5975 and https://stackoverflow.com/questions/40874880/getting-nan-readings-from-dht-11-sensor.

`NULL` should only be used with pointers.
> 1 votes

---
Tags: temperature-sensor, dht11
---


# Question
Title: Endurance of Arduino UNO during 24/7 operations and mild power fluctuations
I am designing an automation system for my research project and planning on using Arduino Uno to do the same. The program is to execute simple instructions based on few input parameters and does not need large computational powers. It is estimated it would take 26 minutes to run the program (26-minute cycle\*) and it is expected that it would take anywhere from 3 weeks to 2 months to complete the project (1160 - 3300 cycles before reboot)

My question is as follows:

1. Is the Arduino Uno capable of surviving the extended service expectancy and execute the program correctly?
2. What is the influence of small voltage fluctuations on the endurance of electronics on the board?
3. Is a heat sink needed for this application? How to determine the power draw to choose heat sink size?
4. Is there any fatigue rating for the cyclic running of the program?

I am planning to power the entire system via a regulated 12V 600-watt battery bank and this bank would be periodically recharged.

\*By cycle duration I mean the real word time required for completion of one batch. It is estimated that it's required to complete 1160-3300 cycles/batches for the research

# Answer
> 3 votes
> Is the Arduino Uno capable of surviving the extended service expectancy and execute the program correctly?

Yes, it is. Though your program and wiring needs to be stable and correct.

> What is the influence of small voltage fluctuations on the endurance of electronics on the board?

Depends on what you call small. As long as you don't enter the brown-out region (where the voltage is so low, that the Arduino goes into reset for safety) or giving a too high voltage to it (See the specifications for that), you should be fine.

> Is a heat sink needed for this application? How to determine the power draw to choose heat sink size?

The power draw of the Arduino depends on what you are doing with it. The best way would be to just measure the current of your application. Then you get the power by multiplying current and voltage. Normally you don't need a heatsink with an Arduino. The only part, that can get hot, is the linear voltage regulator. Depending on what you are interfacing with the Arduino, you might need to put a small heat sink on that (12V is a bit on the high side of input voltage for the regulator. It will dissipate the excess 7V as heat, so 7V multiplied by the used current). The microcontroller on the Arduino will not get hot (unless you are doing something terribly wrong).

And you should make sure, that the current for extra peripherals in your project doesn't flow through the Arduino, since that will place an extra burden on the voltage regulator. It should flow past it (means you connect them in parallel to the voltage source).

> Is there any fatigue rating for the cyclic running of the program?

No, not really. I think the flash memory (where the program is stored) has a data retention failure rate of less then 1ppm (parts per million) over 20 years. So the program will not be lost, until you plan to run your application a hundret years. Also there is no read limit on the flash memory, only a write limit.

# Answer
> 0 votes
I see no problems in that. Given the program you write is stable and correct, the Arduino UNO will certainly work without any problems for months. It has an integrated voltage regulator, so you can attach a 12V battery directly and it automatically regulates voltage changes. The CPU and/or flash do not have any "fatigue" problems as long as the program is only read or executed. The program flash has a limited number of write cycles, but that also is far beyond where you'll get problems.

Where I do see a problem is in your use case. You seem to be doing quite complex mathematics with quite a lot of data, when one cycle takes 26 Minutes. You might not have enough RAM on the UNO to do this. It has only 2.5k (that is around 2500 bytes) of RAM. Where do you store the results?

# Answer
> 0 votes
I have Arduino here powered over year long, still working (running the same loop() again and again) without a glitch and it is not even hand-temperature hot in my living room - I expect it to run flawlessly for lot more years, until I will switch it off :)

---
Tags: arduino-uno, home-automation, temperature
---


# Question
Title: Do I need an Microchip ATSAM3X8E Evaluation Kit?
I am intending to use the Arduino Due processors into my own designs. We have a very extensive (dozen of thousands of lines in .c code) sets of Arduino Due functional codes, and now I intend to move into a more solid form shape.

I have the following questions. What i need is some sort of feedback in order to answer those by myself and realize how to proceed.

1. I understand some of the Fast Speed Serial options in the Microchip IC cannot be tried in the Arduino Due (such as USBOTG?)?. What I actually need is some Serial Speed close to 2Mbps and a USB Programming Port.
2. Which are the main differences between the Microchip ATSAM3X8E and the Atmel ATSAM3X8E? R: No, they are the same.
3. I notice there are some functionalities in the Microchip ATSAM3X8E or even in the Atmel ATSAM3X8E not able to be reproduced in the Arduino Due Board?
4. Do The Microchip ATSAM3X8E IC have its own functionalities not present in the Atmel ATSAM3X8E? R: No, they are the same.
5. As note, there is a Keil ARM SAM3X-EK Evaluation Kit (also also here with its brochure), with a ATSAM3X8H, which is not the same IC series, but somehow exposes my concern (if real).
6. If my concern about High Speed Serial is real, how should I evaluate it?

# Answer
> I understand some of the Fast Speed Serial options in the Microchip IC cannot be tried in the Arduino Due (such as USBOTG?)?. What I actually need is some Serial Speed close to 2Mbps and a USB Programming Port.

What would make you think that? The chip is the chip regardless of what board it's soldered to. You have the native USB and you have all the UART connections direct to the chip. The board has no effect on that at all. 2Mbps is nothing. You can go *much* faster than that.

> Which are the main differences between the Microchip ATSAM3X8E and the Atmel ATSAM3X8E?

The label. When Microchip bought Atmel a few years back they bought *everything*. That includes the Malaysian factories where the Atmel chips are made (a friend of mine had the job of inventory combining and spent quite some time in Malaysia sorting it all out). Microchip ATSAM3X8E chips are made in the same factory by the same people to the same designs on the same machines. It's just they are now labelled "Microchip" instead of "Atmel".

> I notice there are some functionalities in the Microchip ATSAM3X8E or even in the Atmel ATSAM3X8E not able to be reproduced in the Arduino Due Board?

Is that a question or a statement. Or aren't you sure? The Due is just a chip on a board with some support circuitry. Everything that is in the chip is there, you can't remove it. There may be the case that a specific pin may not be brought out to a header, but you will have to compare the datasheet with the schematic in that case. The chip is not at fault here.

> Do The Microchip ATSAM3X8E IC have its own functionalities not present in the Atmel ATSAM3X8E?

No. The two are 100% identical.

> As note, there is a Keil ARM SAM3X-EK Evaluation Kit (also also here with its brochure), with a ATSAM3X8H, which is not the same IC series, but somehow exposes my concern (if real).

The ATSAMA3X8H is not commercially available. It was a specific custom chip made only for the SAM3X-EK kit. It is, essentially, a SAM3X8E with more IO pins and the ability to connect to SDRAM.

> If my concern about High Speed Serial is real, how should I evaluate it?

Your concern is not real. Only imagined. The only possibility is that the UART to USB chip used on the Due may not be able to keep up at high baud rates. That has nothing to do with what the SAM3X8E can do, just what the interface to your PC is capable of. You can replace that with an external USB to UART interface if you want, such as an FT232R based interface. That is if it's communication with your PC that you're concerned about, in which case you would be better with the native USB interface as it's not restricted by whatever external hardware is added.
> 2 votes

---
Tags: arduino-due, atsam3x8e
---


# Question
Title: Serial Communication between ESP8266 and Arduino ( Sofware and Hardware )
I wish to connect an Arduino ( any of 328P family ) which its 5v, with ESP8266 (ESP-01, or even NodeMCU or Wemos D1 mini ) which is 3v3 logic. My goal is that ESP8266 will be in-charge of MQTT messages and other remote abilities, while Arduino board will be in charge of UP/Off/Down rocker switch and 2 relays ( For reliability I rather have this setup ). **Both MCU's code is written by me using Arduino**

I Know of 2 main ways: voltage divider and level shifter ( and 3rd will be to use a 3v3 logic as pro-mini - but let's leave for now ).

My questions are:

A) Does `Rx` `Tx` need a voltage to be the same ( some on-line tutorial ignore this at all )? if so, is it needed both ways ?

B) Some Tutorial mention that using a voltage divider create some communication interference. It is true and/ relevant for use as explained ?

C) Does `SofwareSerial` library is recommended (again - reliability ).

# Answer
> 1 votes
> A) Does Rx Tx need a voltage to be the same ( some on-line tutorial ignore this at all )? if so, is it needed both ways ?

The point is, that often 3.3V MCUs cannot tolerate voltages significantly above that. So connecting 5V can hurt it. I've seen quite a bit of discussion online, if ESP boards are 5V tolerant or not, but I haven't seen a real investigation in this. Often you can very well get away with connecting them directly, but nobody will give you any guarantees about this. If you want to be safe, you need to add some kind of voltage transition from Arduino TX to ESP RX. The other line (ESP TX to arduino RX) is driven by the ESP with 3.3V, which is ok for the Arduino (3.3V is enough for the Arduino to see it as HIGH), so you don't need anything on this line.

> B) Some Tutorial mention that using a voltage divider create some communication interference. It is true and/ relevant for use as explained ?

Since a voltage divider is passive, you get extra effects (parasitic capacitance and inductance), which limits the baudrate. Though I still got communication without errors with baudrates up to 115200 (I did not do a thorough investigation, this is just subjective experience). Electronically better would be proper level shifting (which uses transistors), but in most cases a voltage divider also works well. So I would say unless you want to use really high baudrates you are good with a voltage divider. Others can of course also provide their experience on this site.

> Does SofwareSerial library is recommended (again - reliability ).

Generally a Hardware Serial interface is always better, since the communication protocol is completely handled in hardware. The code just needs to read and write the individual bytes from/to hardware registers. `SoftwareSerial` is used, when there is no free to use Hardware Serial interface. And it imposes some extra limits: You can only listen to one `SoftwareSerial` interface at any give time and you cannot use high baudrates with it (I think 115200 is already too high for it, depending on the used Arduino). Also it depends on the rest of your code (depends on your use of ISRs). So, if you have an unused hardware Serial interface on your Arduino board, you should use that. Otherwise you can use `SoftwareSerial`.

# Answer
> 2 votes
Just adding a little flesh to @chrisl's excellent answer with some added technical detail:

> B) Some Tutorial mention that using a voltage divider create some communication interference. It is true and/ relevant for use as explained ?

The problem here is that the resistors and the input pin's capacitance form a low-pass filter. Too high a resistance and you deform the nice clean square wave of the serial data. This limits the baud rate you can reliably use. Reduce the resistor values and you increase the frequency of the filtering, thus allowing higher baud rates, but at the cost of increased current draw from the TX pin.

> Does SofwareSerial library is recommended (again - reliability ).

The problem of SoftwareSerial is twofold: it's very much a "blocking" system, whereby the MCU can't be doing anything else when a byte is being either received or transmitted, and it's very picky about timing, partly because of that blocking. There are two factors that affect the maximum speed you can use: how fast the MCU can process the incoming signal to work out what it is, and how fast the MCU can process that decoded signal to get it stored in the buffer.

While it's possible to receive reliably a byte at 115200 baud the problem comes when receiving multiple bytes rapidly. The Arduino is not always able to take that received byte and store it in the RX ringbuffer fast enough before the start bit of the next byte arrives, so it misses it. This causes corruption in the data stream.

For this reason I never recommend more than 9600 baud (or maybe 38400 at a pinch) to give the Arduino more time to process the bytes as they arrive. However that then means that more time is spent doing the sending or receiving, which blocks the rest of your program during that time for longer.

Also SoftwareSerial is strictly half duplex: when you're receiving you can't send, and when you're sending you can't receive. It's only really of any use in a "call-response" style protocol where switching between sending and receiving is predictable.

---
Tags: serial, softwareserial, voltage-level, voltage-divider
---


# Question
Title: Can I use an accelerometer to measure the velocity of a car in a curve?
I am making an application that is used to measure the velocity, it has an accelerometer that measures the component acceleration in the XYZ-axis. When the car is moving just straight the measurement is ok, as only linear components are involved.

My doubt came when the car is on a curve, I am not sure if the accelerometer can measure correctly in such situation or if it is necessary to apply a gyroscope to measure any missing component.

The code snippet for measure the total acceleration is shown below, I measure the acceleration in each axis and I remove the gravitational to finally calculate the velocity and the speed

```
    float AccTotal_X = ((AcX - grav_X)*9.81);
    float AccTotal_Y = ((AcY - grav_Y)*9.81);
    float AccTotal_Z = ((AcZ - grav_Z)*9.81);

    float Vx = vx_0 + AccTotal_X*dt;
    vx_0 = Vx;
    float Vy = vy_0 + AccTotal_Y*dt;
    vy_0 = Vy;
    float Vz = vz_0 + AccTotal_Z*dt;
    vz_0 = Vz;

    speed_dt = sqrt(pow(Vx,2)+pow(Vy,2)+pow(Vz,2))*3.6;

```

# Answer
> 2 votes
I found out the answer to the question in the following article **SenSpeed: Sensing Driving Conditions to Estimate Vehicle Speed in Urban Environments**

According to the article

> When a vehicle makes a turn, it experiences a centripetal force, which is related to its speed, angular speed and turning radius. Thus, by utilizing the accelerometer and the gyroscope, we can derive the tangential speed of a vehicle.

Therefore, just with the accelerometer is not possible to measure the velocity when an object is making a turn, it is necessary a gyroscope also.

The equation to measure the tangential velocity is:

**v = Rω** (1),

Where **v** is the tangential speed, **R** the radius of the curve and **ω** the angular speed.

As the centripetal acceleration is given by **a = ω²R** (2), reformulating (2) and substituting in (1), it is obtained:

**v = a/ω** (3).

Both **a** and **ω** are given by the accelerometer and the gyroscope respectively.

---
Tags: accelerometer, gyroscope
---


# Question
Title: Send HTTP get request from GSM SIM800c and Arduino
I am trying to send Get request from my GSM Module but after connecting to server it is not responding any thing

```
#include <SoftwareSerial.h>
SoftwareSerial myGsm(2,3);
void setup()
{
myGsm.begin(9600);
Serial.begin(9600);
delay(500);
myGsm.println("AT+CGATT=1");
delay(200);
printSerialData();
myGsm.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"");//setting the SAPBR,connection type is GPRS
delay(1000);
printSerialData();
myGsm.println("AT+SAPBR=3,1,\"APN\",\"wap.mobilinkworld.com\"");//setting the APN,2nd parameter empty works for all networks
delay(5000);
printSerialData();
myGsm.println();
myGsm.println("AT+SAPBR=1,1");
delay(10000);
printSerialData();
myGsm.println();
myGsm.println("AT+SAPBR=2,1");
delay(10000);
printSerialData();
myGsm.println("AT+HTTPINIT");
delay(2000);
printSerialData();
myGsm.println("AT+HTTPPARA=\"URL\",\"http://sensor.somee.com/api/Data/GetData?SensorID=1\"");// setting the httppara,
delay(1000);
printSerialData();
myGsm.println();
delay(10000);//the delay is important if the return datas are very large, the time required longer.
printSerialData();
delay(9000);
printSerialData();
delay(1000);
Serial.println("done ");
printSerialData();
}
void loop()
{
}
void printSerialData()
{
while(myGsm.available()!=0)
Serial.write(myGsm.read());
}

```

and the Out put is

```
AT+CGATT=1

OK
AT+SAPBR=3,1,"CONTYPE","GPRS"

OK
AT+SAPBR=3,1,"APN","wap.mobilinkworld.com"

OK

AT+SAPBR=1,1

OK

AT+SAPBR=2,1

+SAPBR: 1,1,"10.209.122.68"

OK
AT+HTTPINIT

OK
AT+HTTPPARA="URL","http://sensor.somee.com/api/Data/GetData?Sen
done

```

# Answer
> 1 votes
You haven't instructed the module to make a request yet. With the AT+HTTPPARA command, you are just configuring the request you want to make. In your case, you just specified the URL you want to call. Next, you have to send

```
AT+HTTPACTION=1

```

to make the actual request using the HTTP GET method, and then you can read the HTTP response using

```
AT+HTTPREAD

```

Keep in mind that after AT+HTTPACTION you will receive an unsolicited result code in the format

```
+HTTPACTION: <Method>,<StatusCode>,<DataLen>

```

this will happen after the module will actually do the request and will have the response.

# Answer
> -1 votes
You should place the code to communicate (which is a recurring task) into the loop (and do this without blocking delay()s. Using delay stops the CPU so whatever comes to the buffer is probably not processed.
Read about the difference of placing code in the setup and the loop in the Arduino basic documentation.
Never use delay in communiction scenarios (except for intializing hardware in setup) see example blinkwithoutdelay in ArduinoIDE

---
Tags: arduino-uno, gsm, http
---


# Question
Title: Is it possible to compile and upload code witout the IDE?
I just got started with Arduino, and found out that I need the IDE to compile and upload codes, which works perfectly fine. This is my code:

```
# pragma GCC optimize ("Ofast")

char i = 0 ;
unsigned long time, lastTime ;

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

void loop() {
    time = millis() ;

    if (time > lastTime) {
        lastTime = time + 100 ;
        i = ~i ;
        digitalWrite(LED_BUILTIN, i  ? HIGH : LOW) ;
    }
}

```

But the biggest problem is that the IDE is written in Java and it uses 1 GB of system's memory, and it's very heavy.

So is there a way I can use the Linux command line to compile and upload the code to the Arduino UNO?

# Answer
Yes, I haven't used it but on the official page it is mentioned, called Arduino CLI (command line interface), available for Mac and Linux.

https://www.arduino.cc/pro/cli

Excerpt:

> Arduino CLI is a command line tool that contains all you need to easily build applications around the Arduino ecosystem. Parse the JSON output of the CLI or implement it as an always-on service that accepts commands via a gRPC interface using your language of choice.
>
> Arduino CLI is the backbone of the Arduino Create Web Editor serving over a million users.

Also, it's open source and can be found on GitHub at https://github.com/arduino/arduino-cli/releases
> 4 votes

---
Tags: arduino-uno, arduino-ide
---


title: Reset an Arduino Uno in code

text:
# Question
Title: Reset an Arduino Uno in code
Is it possible to reset an Arduino (i.e., to reboot it) from code (i.e from the sketch itself)? I know that is possible with a special circuit but is there a chance to make it just with code?

Below is my code and the comment `//reset` is where I want to force a reset.

```
#include <TrueRandom.h>

int i;
int randSeed;
long randNumber;

void setup(){
  Serial.begin(9600);
  Serial.println("20 pseudo Zufallszahlen:");
  for (i=1;i<=20;i++) Serial.print(random(10));
  Serial.println();
  Serial.println();
  //randomSeed(TrueRandom.random());
  randSeed = analogRead (A0);
  randomSeed(randSeed);
  Serial.print("Der 'seed' Wert: ");
  Serial.println(randSeed);
  Serial.println();
  Serial.println("20 Zufallszahlen mit analogem 'seed' Wert:");
  for (i=1;i<=20;i++) Serial.print(random(10));
  Serial.println();
  Serial.println("---------------------------");
  Serial.println();
  delay(500);
  //reset
}

void loop() {
}

```

I want to reset the micro-controller at the end of the setup function to show the effect of random numbers with and without a seed.

# Answer
> 25 votes
There three ways to accomplish this. (last is my favorite)

1) Jumper an unused IO to the RESET pin. Leave it as INPUT for normal run, As it is externally pulled high. And when desired to reset set it as LOW and Output. (bang its rebooting).

```
setup() {
  ...
  pinMode(PINtoRESET, INPUT);    // Just to be clear, as default is INPUT. Not really needed.
  digitalWrite(PINtoRESET, LOW); // Prime it, but does not actually set output.
  ...                            // Does disable 10K pull Up, but who cares.

```

then when desired...

```
...
  pinMode(PINtoRESET, OUTPUT);   // lights out. Assuming it is jumper-ed correctly.
  while(1);                      // never gets here.

```

2) Jump to beginning of the code.

```
void(* resetFunc) (void) = 0;  // declare reset fuction at address 0
...
resetFunc(); //call reset

```

**But be careful**, this does not perform a true reset, in that all the registers ARE NOT DEFAULTED. Rather they and the IO are left as is. Where somethings from the bootloader and then the heap will be initialized. And reset are not!

3) Use the watchdog. The SoftReset library makes it easy. Although it is not difficult to implement directly. Shown below..

```
#include <avr/wdt.h>
...
setup() {
  ...
  MCUSR = 0;  // clear out any flags of prior resets.
  ...

```

then when desired...

```
...
wdt_enable(WDTO_15MS); // turn on the WatchDog and don't stroke it.
for(;;) {
  // do nothing and wait for the eventual...
}
...

```

# Answer
> 4 votes
In case you have the original Arduino bootloader which you want to execute as a part of the reset, you can do a SW reset by jumping to the bootloader reset address (0x7800 on ATmega328p boards)

```
void reset() { asm volatile ("jmp 0x7800"); }

```

The watchdog reset approach will not work because of a bug in the bootloader. Here's a note from ATmega328P Datasheet page 45:

> Note: If the watchdog is accidentally enabled, for example by a runaway pointer or brown-out condition, the device will be reset and the watchdog timer will stay enabled. If the code is not set up to handle the watchdog, **this might lead to an eternal loop of time-out resets**. To avoid this situation, the application software should always clear the watchdog system reset flag (WDRF) and the WDE control bit in the initialization routine, even if the watchdog is not in use.

This is exactly what will happen after a watchdog reset on a system with Arduino bootloader.

---
Tags: arduino-uno, software, reset
---


# Question
Title: Error Outputting Values Arduino Serial.print
I am experimenting with the following program I found online (with slight modifications):

```
int x;
void setup() {
 Serial.begin(9600);
 Serial.setTimeout(1);
}
void loop() {
 while (!Serial.available());
 x = Serial.readString().toInt();
 int y = x + 1;
 Serial.print(y);
}

```

I am encountering an error in Serial monitor output; if I input `1`, I get `21` printed. I think what's happening is that every digit in a number gets incremented by 1, and then `1` is put at the end for some reason. For example, if I input `234`, my output is `3451`. I think the error lies with the line  `x = Serial.readString().toInt();`, but am unsure how to fix this. Thank you!

# Answer
There's two problems here.

First, you don't enter "234", you enter "2" followed by "3" and finally "4". Your really small timeout doesn't give the digits enough time to arrive.

Second, your line ending is being received and interpreted as "not a number" which is returned as 0 by `.toInt()`.

What you need to do is:

1. Don't set a short timeout - you can remove that line entirely.
2. Use `.readStringUntil('\n')` to read up until your line ending in one go.
> 3 votes

---
Tags: c++
---


title: Slow USB reading operation

text:
# Question
Title: Slow USB reading operation
I got an Arduino UNO today, and I am just writing a basic blink program. I have 3 LEDS on the arduino. Those LEDS are connected to Pin 1, 2, and 3.

Now I can control those LED by writing octal values 0 to 7 to the `/dev/ttyUSB0`.

The code I have written so far is:

```
# pragma GCC optimize ("Ofast")

# define LED1 1
# define LED2 2
# define LED3 3

char buf[4] ;
unsigned char inp, len ;

void setup() {
    pinMode(LED1, OUTPUT) ;
    pinMode(LED2, OUTPUT) ;
    pinMode(LED3, OUTPUT) ;

    Serial.begin(9600) ;
}

void loop() {
    len = Serial.readBytes(buf, 3) ;

    if (len) {
        buf[3] = '\0' ;
        inp = atoi(buf) ;

        // Illuminate LEDs
        digitalWrite(LED1, 1 & inp ? HIGH : LOW) ;
        digitalWrite(LED2, 2 & inp ? HIGH : LOW) ;
        digitalWrite(LED3, 4 & inp ? HIGH : LOW) ;
    }
}

```

So when I write:

* 0 turns off all the LEDS
* 1 turns on LED on pin 1
* 2 turns on LED on pin 2
* 3 turns on LED on pin 1 and 2
* 4 turns on LED on pin 3
* 5 turns on LED on pin 1 and 3
* 6 turns on LED on pin 2 and 3
* 7 turns on all the LEDS.

The problem is that, when I write 7 for example, it takes up to 1 second to turn on the LEDS. If I write 0, it takes another second to turn off the LEDS.

Is there way to control the LEDS in close to real-time?

# Answer
> 2 votes
When sending multiple bytes which together form a single message it is best to use a delimiter character and read the data until there. That way you don't run into timeouts and you can be sure, that the received data represents a full message.

In the cases where the LEDs need 1s to react you are most likely sending less than 3 bytes, which causes the `Serial.readBytes()` function to time out after the default 1s. I guess you are currently always sending only 1 byte (though you are trying to read 3 byte in your code).

To use a delimiter character there are multiple ways. The easiest fix would be using `Serial.readStringUntil('\n')`. The newline character (which I used as a parameter here) is a common delimiter character. You would then need to aways send the newline character at the end of a full message.

Just setting the timeout very low is not a very good solution. With a low baudrate as 9600 that can easily mean, that the message is chopped up into multiple parts, because the transmission takes longer than the timeout.

---

Besides that: I don't really understand, why you need to receive 3 bytes for turning on or off 3 LEDs. One byte (even, when you are just using single digits) has a big enough data space for more than these 3 LEDs. Also you are not really using octal numbers. `atoi()` is expecting a string representation of a decimal number. There is nothing octal in your code. And then you are using the first 3 bits of the resulting number for controlling the LEDs.

All in all this seems quite complicated for a very basic task. Maybe there is some reason for that, which you didn't write about.

# Answer
> 1 votes
You're calling `Serial.readBytes()` when there may or may not be 3 bytes available. If there aren't 3, the call waits for them to arrive or for a timeout. That's the delay you are seeing.

If you really want 3 bytes at a time, check whether there are 3 before you try to read them:

```
if( Serial.available >= 3 )
   len = Serial.readBytes(buf, 3);

```

When the `if` fails - because there aren't three bytes available - you won't waste any time waiting for them.

# Answer
> 0 votes
On the Arduino UNO pins 0 and 1 are used for serial communications. That might not make a difference here, but it's probably a good idea to avoid them unless really needed.

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


title: TTGO TS I²C adress

text:
# Question
Title: TTGO TS I²C adress
I'm working on a project using TTGO TS wich communicate wih arduino via I²C protocole How can I find the adress of TTGO TS board used in I²C communication ?

# Answer
The TTGO TS uses an ST7735 display. This is *not* an I2C device. Instead it uses its own custom serial protocol. Since the DC pin is broken out for you it uses the 4-wire serial interface which is simplest to use with SPI.

It's confusing that they use the terms SCL and SDA, which makes you think it's I2C, but it's not.
> 1 votes

# Answer
Like @romkey said, use a I²C scanner to find the address of the device, for example this one from the Arduino website. Connect the device to the Arduino board, upload the code and look up the I²C address of your device.
> 0 votes

---
Tags: i2c, wifi, esp32, wire-library, espressif
---


# Question
Title: Arduino simulator - generating sine wave from PWD (Oscilloscope read is rectangular)
trying to create this simple circuit where a rectangular voltage input is transferred to a sine wave output.

the process is quite simple, but I couldn't see the actual sine wave when connecting an oscilloscope.

I'm currently working on a simulator online, so I thought it would be best to share the circuit with the c++ code, and perhaps you would have any insights on why I keep seeing rectangular output voltage rather than sine when the data is indeed a sine wave:

here's an image of the circuit for some specific time:

and the code that generates the sine wave is

```
#include <math.h>

const int numSamples = 500;
const float pi = 3.1415;
int f = 2; // signal frequency
float sf = 500.0; // sample frequency > 2*f (Nyquist)
int sineSignal[numSamples];

void setup(){
    pinMode(13, OUTPUT);
    // creating sine signal:
    for (int i = 0; i < numSamples; i++){
        float t = i / sf;
        // +1 shift to get values from 0 to 2
        sineSignal[i] = (int) (127 * (sin(2 * pi * f * t) + 1.0));
    }
}

void loop(){
    int pinToConnect = 9;
    for (int i = 0; i < numSamples; i++){
        analogWrite(pinToConnect, sineSignal[i]);
        delay(2);
    }
}

```

ps. this is all based on this video: How to Generate Sine Wave using Arduino?

# Answer
It's working as intened.

The arduino UNO has no DAC (digital to analog converter) onboard, so all it can produce are digital signals, either 0 or 5v. The analogWrite function uses Pulse Width Modulation to produce an output that, *on average*, has the requested voltage, by quickly alternating between logic low and high with different durations.

This is done at the hardware level using the Atmega's timers, and it's very useful in driving LEDs, servos, steppers and more, but it doesn't produce a steady analog output.

I would suggest either moving to a chip that has an onboard DAC, using an external DAC chip such as this one, or building a simple DAC yourself.

An even simpler solution would be building a RC lowpass filter on the output pin, which would provide a simple, but probably imprecise, way to smooth out the signal and make it look like an analog one
> 3 votes

---
Tags: c++, arduino-uno, pwm
---


# Question
Title: non asssign variable using by for in loop() can remeber last value. what happen here?
I modify this code from my friend and it look strange.

```
void setup() {
    Serial.begin(115200);
    Serial.println("reset");
}
void loop() {
    for (int d; d <= 32767; d++) {
      Serial.println(d);
      delay (1000);
    }
}

```

for some reason when you press reset, the variable will keep counting from last value as shown.

this not gonna happen when you put these block in setup()

I know that not good idea to use varible in for loop without assigned the value, but I belived it must have a interesting reason for this. For my hypothesis, the variable value just allocate with same address in memory. when this code run in setup() some how the complier detect this situation and assign 0 as initial value. but when in the loop() some how the compiler don't assign new value to the memory address and it get old value from last time the program was run before resetted. I still need further explanation.

# Answer
I think you missed a compiler warning (I did, too!) - notice that you are using 'd' uninitialized. On each re-entry to the loop() function, loop()'s stack will be in the same place in memory. The for-loop doesn't initialize 'd', but the boot loader did zero RAM for your first run. 'd' happens to occupy the same memory location on each entry to loop(), so the old value (just before reset) is still in place. Since the for-loop didn't re-initialize it... :)

The fix is:

```
for (int d=0; d <= 32767; d++) {

```

Update:

That begs the question: Why did your run fail as expected, while my run appeared to execute normally? My guess is different bootloaders, one that does, and one that doesn't, initialize SRAM on a reset that doesn't result in an upload.
> 3 votes

---
Tags: variables
---


# Question
Title: Making pushbutton behave as a toggle switch with ezButton - do I have to use ledstate with =! operator
I'm using ezbutton to make a pushbutton act like a toggle switch, first press doing permanent on, second press doing permanent off. I'm just trying to understand the basic coding. This project is just a testbed for what I'm planning to do later - wiring vehicle toggle switches to Arduino and feeding the output signal to mosfet that will control the load state. So I'm trying to get the code as nice and tidy as I possible can. In the code below, I would like to know if ledState will be applicable when this sketch will control a mosfet instead of a test led, and I've seen comments saying "ledState = !ledState;" is not optimal - but being a beginner I'm not sure what this means, and is there a better more sound way to address it. Thanks!

```
#include <ezButton.h>

// ---
// Declaration
// ---

const int button1  = 9;
const int led1     = 4;
int ledState = LOW;

ezButton button(button1);

// ---
// Setup
// ---

void setup()
{

  pinMode(led1, OUTPUT);
  pinMode(button1, INPUT_PULLUP);
  button.setDebounceTime(50);

}

// ***
// Main Loop
// ***
void loop()
{

  button.loop();

  if (button.isPressed()) {
    ledState = !ledState;
    digitalWrite(led1, ledState);
  }

}

```

# Answer
I've been looking through the source code for ezButton.c

The function `isPressed()` is something of a misnomer and is only meaningful for a push-to-make button on the low side of a pull-up resistor. It actually detects falling edges of the signal, so it should be called `isFallingEdge()`, but the code itself is good.

Similarly for `isReleased()` which detects rising edges of the signal, so should be called `isRisingEdge()`.

The constructor defaults to `INPUT_PULLUP` which may (or may not) be what you want for your buttons and toggle switches, so it's something to bear in mind especially for low-side push-to-break buttons or high-side push-to-make buttons which will generate rising edges when pressed and falling edges when released thus reversing the meanings of `isPressed()` and `isReleased()`, hence why they really should be called `isFallingEdge()` and `isRisingEdge()`.

The algorithm in `ezButton::loop()` could be optimised a bit by getting rid of `previousSteadyState` and nesting the final `if` statement within the second `if` statement.

Other than that, it's quite a good algorithm that makes use of hysteresis to reset the debounce timer.

For comparison you could take a look at my algorithm in this simple debouncer for Arduino that simply detects rising edges, falling edges or both edges without regard to whether a button was pressed or released, and can be used in a polling loop or with interrupts. Here's the essence of the algorithm:

```
    bool input_state = digitalRead(INPUT_PIN);
    unsigned long current_ms = millis();

    edge = rise = fall = false;

    // Hysteresis:
    //   If there is no change, reset the debounce timer.
    //   Else, compare the time difference with the debounce delay.
    if (input_state == output_state)
    {
      last_ms = current_ms;
    }
    else if ((current_ms - last_ms) >= DEBOUNCE_DELAY_ms)
    {
      // Successfully debounced, so update the outputs.
      rise = input_state && !output_state;
      fall = !input_state && output_state;
      edge = rise || fall;
      output_state = input_state;
    }

```

And `ledState = !ledState;` simple toggles the value of `ledState` which is what you write to your LED with `digitalWrite(led1, ledState);` each time a falling edge is detected in the input signal.
> 1 votes

---
Tags: arduino-uno, button
---


title: Arduino resets itself

text:
# Question
Title: Arduino resets itself
If I connect more power consuming components to Arduino, it gets reset. What is the cause of this observation?

# Answer
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).
> 3 votes

# Answer
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.
> 1 votes

# Answer
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.
> 1 votes

# Answer
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.
> 0 votes

---
Tags: arduino-uno
---


# Question
Title: Load cell weight distribution on rectangular shape instead of square
I have built a simple scale using 4 so called 50kg load cells.

They are connected in a bridge and mounted on wooden feet of a square shaped box. All as a proof of concept which worked quite ok. The readings are all OK and deviation of +/- 2kg is totally acceptable for my project. I followed this discussion which also explains how the connection should be made properly using 4 cells.

How to get weight data from glass electronic bathroom scale sensors?

Now I want to keep the load cells on the feet but change the shape of the scale and instead of a square use a rectangle with the following sides.

In such a form a weight distribution will not be centered all the time. The object to be weighed can shift to the right or to the left.

* Will this affect the measurements in a negative way or will the HX711 controller still take care of it and show the correct results?
* Will the measurements still be correct using 4 cells? If not what would be the proper way of weighing a rectangular shaped load?
* Would it more appropriate to measure the load with 2 cells on the right and two cells on the left and then sum it up?

# Answer
Newton's second law says that if a force acts on a mass, that mass will accelerate at a rate proportional to the force and inversely proportional to the mass.

All that means for your scale is that if you are not being accelerated up or down, the net vertical force on your body must be 0. Since your body has weight, and the net vertical force on your body is 0 (you aren't accelerating, are you? :) then the downward force must be balanced by an exactly equal upward force. That upward force is the sum of the upward forces exerted by each load cell. Their contributions may individually change depending on where you stand, but *their sum must exactly equal your weight*.

Note that we have said nothing about the placement of the cells! If your platform allows it, you could move one of the cells 6 (or 60 or 600) feet away from the the others, for instance. The total upward force must still be the same.

So the bottom line is:

`F_lc1 + F_lc2 + F_lc3 + F_lc4 == your weight`

no matter where you place the cells.
> 2 votes

---
Tags: sensors
---


# Question
Title: Hexadecimal array does not add up as expected
I have an array of hexadecimal values as given below.

```
byte Hexa_Val[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

```

I want to increase this array from the end. As in, go from {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} all the way to {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, and then increase the value next to it to {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}, and continue. The increment should go as shown below.

```
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}
.
.
.
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00}
.
.
.
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF}
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00}
.
.
.
{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}

```

The code I am came up with is

```
byte Hexa_Val[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

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

void loop() {

  Hexa_Val[7] = Hexa_Val[7] + 1;

  if(Hexa_Val[7] = 0xFF){
    Hexa_Val[6] = Hexa_Val[6] + 1;
    Hexa_Val[7] = 0x00;
  }

  if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF)){
    Hexa_Val[5] = Hexa_Val[5] + 1;
    Hexa_Val[7] = 0x00;
    Hexa_Val[6] = 0x00;
  }

  if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF)){
    Hexa_Val[4] = Hexa_Val[4] + 1;
    Hexa_Val[7] = 0x00;
    Hexa_Val[6] = 0x00;
    Hexa_Val[5] = 0x00;
  }

  if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF)){
    Hexa_Val[3] = Hexa_Val[3] + 1;
    Hexa_Val[7] = 0x00;
    Hexa_Val[6] = 0x00;
    Hexa_Val[5] = 0x00;
    Hexa_Val[4] = 0x00;
  }

  if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF)){
    Hexa_Val[2] = Hexa_Val[2] + 1;
    Hexa_Val[7] = 0x00;
    Hexa_Val[6] = 0x00;
    Hexa_Val[5] = 0x00;
    Hexa_Val[4] = 0x00;
    Hexa_Val[3] = 0x00;
  }

  if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF) && (Hexa_Val[2] = 0xFF)){
    Hexa_Val[1] = Hexa_Val[1] + 1;
    Hexa_Val[7] = 0x00;
    Hexa_Val[6] = 0x00;
    Hexa_Val[5] = 0x00;
    Hexa_Val[4] = 0x00;
    Hexa_Val[3] = 0x00;
    Hexa_Val[2] = 0x00;
  }

  if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF) && (Hexa_Val[2] = 0xFF)  && (Hexa_Val[1] = 0xFF)){
    Hexa_Val[0] = Hexa_Val[0] + 1;
    Hexa_Val[7] = 0x00;
    Hexa_Val[6] = 0x00;
    Hexa_Val[5] = 0x00;
    Hexa_Val[4] = 0x00;
    Hexa_Val[3] = 0x00;
    Hexa_Val[2] = 0x00;
    Hexa_Val[1] = 0x00;
  }

  if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF) && (Hexa_Val[5] = 0xFF) && (Hexa_Val[4] = 0xFF) && (Hexa_Val[3] = 0xFF) && (Hexa_Val[2] = 0xFF) && (Hexa_Val[1] = 0xFF)  && (Hexa_Val[0] = 0xFF)){
    Hexa_Val[7] = 0x00;
    Hexa_Val[6] = 0x00;
    Hexa_Val[5] = 0x00;
    Hexa_Val[4] = 0x00;
    Hexa_Val[3] = 0x00;
    Hexa_Val[2] = 0x00;
    Hexa_Val[1] = 0x00;
    Hexa_Val[0] = 0x00;
  }

  //to find out what I am sending
  for( byte a=0; a<8; a++ ) {
    Serial.print(Hexa_Val[a], HEX);
  }
  Serial.println();

  delay(500);

}

```

But it just gives me zeros in the serial monitor. If I just leave the first two IF statements

```
byte Hexa_Val[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

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

void loop() {

  Hexa_Val[7] = Hexa_Val[7] + 1;

  if(Hexa_Val[7] = 0xFF){
    Hexa_Val[6] = Hexa_Val[6] + 1;
    Hexa_Val[7] = 0x00;
  }

  if((Hexa_Val[7] = 0xFF) && (Hexa_Val[6] = 0xFF)){
    Hexa_Val[5] = Hexa_Val[5] + 1;
    Hexa_Val[7] = 0x00;
    Hexa_Val[6] = 0x00;
  }

  //to find out what I am sending
  for( byte a=0; a<8; a++ ) {
    Serial.print(Hexa_Val[a], HEX);
  }
  Serial.println();

  delay(500);

}

```

The increment will start from the third value on the right. Something like

```
00000200
00000300
00000400
00000500
00000600
00000700

```

How do I get it to increase as I mentioned at the beginning? Why does the code recognize `0xFF` as a zero?

# Answer
> 2 votes
There are multiple problems here:

> `if(Hexa_Val[7] = 0xFF)`

First of all, `=` is the assignment operator. You are setting `Hexa_Val[7]` to `0xFF`. If you want to compare for equality, you should use `==`.

Second problem, The value `0xff` will never be displayed, because you are replacing it by zero. This byte will then count 0xfd, 0xfe, 0x00, skipping 0xff. If you want to count 0xff, the condition should be `Hexa_Val[7] == 0`, i.e. increment `Hexa_Val[6]` only after `Hexa_Val[7]` has overflowed.

Third problem, your second `if` test comes too late. At this point `Hexa_Val[7]` has already been reset. You should test for `Hexa_Val[6]` overflowing only *within* the previous test.

With all that fixed:

```
Hexa_Val[7] = Hexa_Val[7] + 1;
if (Hexa_Val[7] == 0) {
  Hexa_Val[6] = Hexa_Val[6] + 1;
  if (Hexa_Val[6] == 0) {
    Hexa_Val[5] = Hexa_Val[5] + 1;
  }
}

```

If you don't want to write 8 nested conditions (which is kind of cumbersome), you can instead loop over the array backwards, incrementing each element in turn, and break out of the loop as soon as an increment does *not* overflow:

```
for (int i = 7; i >= 0; i--) {
    if (++Hexa_Val[i] != 0) break;
}

```

If you don't mind the array being backwards, you can also handle the whole array as a single 64-bit number, and just increment it like you would increment any integer. But then you have to print the array backwards, starting from the mast element:

```
union {
    uint64_t number;
    byte bytes[8];
} Hexa_Val = { .number = 0 };

void loop() {
    // Increment the array.
    Hexa_Val.number++;

    // Print out.
    for (int i = 7; i >= 0; i--) {
        if (Hexa_Val.bytes[i] < 0x10) Serial.write('0');
        Serial.print(Hexa_Val.bytes[i], HEX);
        Serial.write(' ');
    }
    Serial.println();

    delay(500);
}

```

---
Tags: programming, array, mathematics
---


# Question
Title: Is defining a function improves speed rather computing average for each analog input separately
My Arduino controller reads data coming from four different sensors. After the data is read, I individually compute four input average values. I understood that I am having the same lines of code repeated four times. Instead, I want to define a function with an analog pin as input and compute the average. My code is working fine. The question I have is, will this function improve the speed, reduce memory?

My code:

```
// Samples average
sample_cnt = 1000;

//// Input the pin number and compute average value
float Average_input_value(int analog_pin){
  float avg_val = 0;
  for(int i=0;i<sample_cnt;i++){
    avg_val += analogRead(analog_pin);
  }
  // Divide by Sample count to get the average value
  avg_val = avg_val/sample_cnt;
  return avg_val;
  }

```

# Answer
Writing the code out four times, in line, is a little bit faster than calling a function because the function call and return take some time, and the loop instructions take some time, and neither of those contribute to the average calculation.

Writing a function that you use four times, however, is much more readable, is much easier to fix if you've made a mistake because you can fix it once instead of four times, and is much easier to change or replace for the same reason, if that ever becomes necessary. Besides, a good optimizing compiler can often decide when to rewrite your loop as inline several repetitions of the loop contents (called "unrolling the loop"), so hand optimizing is probably not worthwhile.

Where your function will win over 4 repetitions of the calculation code is in the code-space needed. The function is more compact, but slightly slower.
> 2 votes

# Answer
Just adding some numbers to complement JRobert's answer.

On the Uno, the cost of calling a function and returning from it is about 0.5 µs. In contrast, calling `analogRead()` within a loop costs *at least* 112 µs per iteration. Given that you are computing the sum as a `float` (where a suitably sized integer would suffice), it may well be more that 112 µs in your case.

I do not know how many readings you want to average, but even if it is only a handful, the calls to `analogRead()` will completely dwarf the cost of using a function.
> 1 votes

---
Tags: arduino-uno, arduino-mega, analogread, analog-sampling
---


# Question
Title: Can we use UART COMMUNICATION with MCP23017?
I am using MCP23017 as a GPIO expander with Arduino in my project. I have too many serial devices and no pins left on Arduino for UART communication.

I am wondering if I can use this MCP23017 GPIO expander pins for UART communication or not?

# Answer
> 1 votes
I can think of one way.

In theory you could use the GPIO pins of the mcp23017 to control a couple of 2-way multiplexers. With these multiplexers you could split your Rx/Tx pins to more than one serial bus.

May it be obvious that you cannot used the split busses at the same time. So depending on your specific use-case this may or may not be a solution.

# Answer
> 0 votes
No. No you can't. Serial takes precise timing and fast reactions. Things you can't do with a remote device like that.

Instead there are SPI UART devices specifically for the job, such as the MAX3107.

---
Tags: arduino-uno, pins, uart, serial-data
---


# Question
Title: How detect I2C errors with requestFrom()
I am going to use MCP23017 chips, and some of them will be cabled with a 1 meter max unshielded cable. I am expecting that certain transmissions may toss errors. So I want to tackle this problems by using the built in error detection of I2C, polling the inputs frequently (every 20ms or so) and by debouncing the received data in code by comparing the previous state to the current state of every input pin.

If you write bytes to an I2C slave with the Wire library. You can use the return value of `Wire.endTransmission();` to test if the slave has acknowledged the message.

How does this work when you are requesting bytes using `Wire.requestFrom( address, 3 );` for example. This function does return the amount of received bytes. Can we check this value with the value of the amount of bytes we requested?

I have read the TI document over how I2C works

> The master will continue sending out the clockpulses, but will release the SDA line, so that the slave can transmit data. At the end of every byte of data, the master will send an ACK to the slave, letting the slave know that it is ready for more data. Once the master has received the number of bytes it is expecting, it will send a NACK, signaling to the slave to halt communications and release the bus. The master will follow this up with a STOP condition

So the master either ACKs or NACKs a read-in byte. Does the Wire library automatically make several attempts with reading? Oris there something in the Wire library which we can use to detect a failed read operation?

Is it perhaps so that the `requestFrom()` function may return a different amount of bytes than you requested with which would indicate that atleast 1 read operation failed?

So could I attempt something like

```
doItAllAgain:

for(int i = 0 ; i < 5 ; i ++ )
{
    Wire.beginTransmission( address ) ;
    Wire.write( register ) ;
    if( !Wire.endTransmission() ) break ; // if no error, break out of for loop
    Serial.println(F("write operation failed");
}

Serial.println(F("write operation succes");

byte requestedBytes = 3 ;
byte returnedBytes = Wire.requestFrom( address, requestedBytes ) ;

if( requestedBytes != returnedBytes )
{
    Serial.println(F("read operation failed");
    goto doItAllAgain ;
}
else
{
    Serial.println(F("read operation also succes");
    byte byte1 = Wire.read() ;
    byte byte2 = Wire.read() ;
    byte byte3 = Wire.read() ;
}

```

# Answer
> 3 votes
The `Wire` library does not give you any possibility to get error states, when requesting bytes from a slave. Basically you are stuck with the number of bytes being read.

Though you can read some information from that. If the number of bytes is zero, the slave didn't answer (either because its not there, or because it cannot send any byte currently). This equals a NACK by the slave after the address byte.

Other than that the I2C protocol doesn't give any more information. On requesting the slave is sending data and the master is acknowledging it. That means, that the slave cannot generate a NACK in this process. In fact that also means, that the returned number of bytes can only be zero (on NACK on address) or equal to the number of requested bytes, since after the address ACK from the slave the master will continue to generate clock pulses, until it has read all bytes, that it wanted. If the slave doesn't have any more data to send before that, it cannot stop the transmission. It would just stop driving the data line, resulting in all high data bytes (`0xFF`).

Also I doubt, that it would be really useful in your case. I2C is made for small distances, mostly on the same PCB. It can be used for longer distances, but your mileage may vary. If your setup really can corrupt the communication on the I2C lines, your biggest problem will be a stuck bus. The I2C protocol is generally not prepared for noisy environments and it incorporates states, where the devices on the bus can wait infinitely. This is also reflected in the `Wire` library. That means, that big noise on the lines will often lead to the bus being stuck in the middle of a transaction, needing you to reset the devices (not only the slaves, but also the master) to get the bus free again. I would go so far to say, that is it more likely to get the bus stuck, than to get corrupted data. So any information about errors is not really helping you here, since you won't get out of `requestFrom()` in the first place. Your code can very well get stuck there.

I suggest, that you test your setup thoroughly with the wanted run times. If the bus gets stuck too often for you, then you should make your setup more robust (shielded cables, or using an extra MCU with the I2C slave and using a more robust communication interface between main MCU and extra MCU).

---
Tags: i2c, atmega328, wire-library
---