message:
Connecting LEDs and push buttons 12 feet away from Arduino UNO

I have a PCB (let's call it remote PCB) on which I have 4 LEDs and 4 buttons mounted. The remote PCB is far away from my desk (about 12 feet away). The LEDs are used to indicate the status and the buttons are for various state inputs.

All of them are connected to UNO directly.

 1. I am planning to use a 10 pin IDC connector and IDC ribbon cable for the same.
 2. THe LEDs' current is about 2 mA each (white LEDs)
 3. The push buttons will make a ground connection when pressed, else the internal pull-up of the UNO will keep the GPIO at a high level.
 4. I have put a capacitor of 10 nF across the switch to address denounce.
 5. I have a series resistor of 1-kilo ohm for all four Switches on the remote PCB

I would like to know if this is okay? Will there be any problem due to the length. The LEDs are for indication and won't blink faster than 200 ms at any point in time. They will be used to indicate status which is very slow signals.
Thanks in Advance!

body: That is a big no-no. You are adding extremely long antennas to the Arduino asking for problems. At a minimum on the inputs add a 10K series resistor at the Arduino pins.  My preference would be to put the capacitors at the arduino pins to help decouple noise etc as well as the pull up resistors on the wire side of the 10K resistors. Use a buffer of some type for the LEDs, a transistor would work. This may work but for how long and how many processors can you destroy over time.


sender: user

message:
does EEPROM reset itself when a new code is uploaded?

I have a Nodemcu with which i'm doing a project. So whenever there is a power loss i want values of some of the variables to not be reset, because of that im trying to store the values in EEPROM of the nodemcu. But the problem is i want to know if the EEPROM will get reset when a new code is uploaded and also since the nodemcu stores wifi credentials in the EEPROM i dont want to accedentally select an EEPROM address in which the wifi credentials are stored and cause a problem. Can anyone tell me the safe EEPROM addresses to use and also if EEPROM will get rest if  a new code is uploaded?

sender: assistant

body:
The esp family chips do not have EEPROM. Instead they just dedicate a small section of flash to pretend to be EEPROM.

That flash section, depending on the core version, is either a dedicated EEPROM partition, or a dedicated key in the nvram partition. Either way it's separate to the wi-fi credentials, which are stored in their own key in the nvram partition.

EEPROM can be erased when you upload code if the partition layout changes. It's less likely to be erased if it's a newer version of the core where it's stored in the nvram.

For safety, don't change the partition size, and ideally use ArduinoOTA which will never change the partitions or erase the nvram.


message:
I2C pull up resistors and an I2C MUX

I have a rig with 5 light [sensors][1] on an [I2C mux][2] and I am wondering if I need only 1 pull-up resister set for the whole bus or one on each branch from the mux?

Or should I remove all the pull-ups from the branches and leave the one on the mux?

My issue is that the Arduino softlocks after 5-60 min of running, and it always softlocks on a read lux call.

  [1]: https://www.sparkfun.com/products/15436
  [2]: https://www.sparkfun.com/products/16784

body:
From what I can tell, the I2C bus multiplexer itself receives and re-transmits on what amounts to a completely separate bus.  So, each bus would need its own pull-up resistors.  That said, the board you've linked that breaks out the multiplexer chip [has pull-up resistors][1] on each bus that it's providing:

[![Excerpt of Sparkfun Multiplexer breakout showing bus pull-up resistors on far side of multiplexor.][2]][2]

The breakout also has pull-ups on the bus going to the multiplexor itself:

[![Excerpt of Sparkfun Multiplexer breakout showing bus pull-up resistors on near side of multiplexor.][3]][3]

Beyond that, the ambient light sensor [breakout seems to provide its own 4.7K pull-ups][4]. AVR-based Arduinos (and probably others) also enable their own, admittedly weak, pull-ups in the [guts of the wire library][5].

It seems you should not necessarily need to add any additional pull-up resistors of your own to what is already on the buses.

---

With regard to the O.P. comment given below concerned about too many pull-up resistors.

At some point probably below (perhaps far below) 500 ohms some devices may have trouble sinking enough current to create a LOW. The AVR wouldn't have a problem with 500 ohms for example.

The ATMega328P datasheet (along with most other AVR datasheets) will tell you that the internal pullup value is between 20K-50K.  If you're concerned about too-many-parallel-resistors/too-many-current-paths/too-little-total-resistence, you can take the 20K figure along with multiplexer breakout's 4.7K figure, to [calculate][6] `pow(1 / 20e3 + 1 / 4.7e3, -1)`, for about 3.8K, which should be fine.  If you do the same calculation on the multiplexor's individual bus resistor 4.7k and the ambient light sensor breakout's own 4.7k resistor, you get 2.35 k (half), which is also probably fine.  If anything both of these total figures can be made smaller (by adding yet *another* parallel resistor) for longer buses and at higher frequencies.  If you're worried about these figures you can lower the I2C clock rate.  You can also examine the edges of your signal with a scope.  Also if you really want to dig into this stuff, you read in [the official I2C manual][7].  But, really I think what you have is probably fine.

  [1]: https://cdn.sparkfun.com/assets/7/2/f/c/6/Qwiic_Mux_Schematic.pdf
  [2]: https://i.stack.imgur.com/g0ouG.png
  [3]: https://i.stack.imgur.com/rKrZ4.png
  [4]: https://cdn.sparkfun.com/assets/e/7/0/9/4/SparkFun_Ambient_Light_Sensor_VEML6030_Schem.pdf
  [5]: https://github.com/arduino/ArduinoCore-avr/blob/1.8.3/libraries/Wire/src/utility/twi.c#L87
  [6]: https://www.allaboutcircuits.com/tools/parallel-resistance-calculator/
  [7]: https://www.nxp.com/docs/en/user-guide/UM10204.pdf


message:
Arduino on/off PWM

When I turn on DC motor with a button I get a a fixed PWM value that goes into a loop till button state changes.

What should I change that I could change X value with potentiometer in a loop?

```c++
int X = A0;
int SW = 2;
int Xval=5;
int SWval;
int buttonNew;
int buttonOld = 1;
int buttonState= 1;
int engine = 6;

void setup() { // This executes once
  Serial.begin(9600);
  pinMode(X, INPUT);
  pinMode(SW, INPUT_PULLUP);
}

void loop() { // This loops continuously
  Xval = analogRead(X);
  buttonNew = digitalRead(SW);

  if (buttonOld == 0 && buttonNew == 1) {
    if (buttonState == 0) {
      analogWrite(engine, Xval);
      buttonState = 1;
    }
    else {
      digitalWrite(engine, LOW);
      buttonState = 0;
    }
  }

  buttonOld = buttonNew;
  delay(1);
  Serial.print("button");
  Serial.print(SWval);
  Serial.print("          X=");
  Serial.println(Xval);
}
```

body:
Move the analogWrite out of the button-state-change code, and it will update the PWM continually, instead of only when the button is pressed.

See the code below.

I also change the variable name `buttonState` to `motorState`, as it indicates the state of the motor (On/Off). And I inverted it, so `1` means the motor is ON.

The other thing I did was to increase the delay to 10ms, so you don't get any issues with switch-bounce.

``` lang-cpp
int X = A0;
int SW = 2;
int Xval=5;
int SWval;
int buttonNew;
int buttonOld = 1;
int motorState= 0;//indicates whether the motor is on/off
int engine = 6;

void setup() { // This executes once
  Serial.begin(9600);
  pinMode(X, INPUT);
  pinMode(SW, INPUT_PULLUP);
}

void loop() { // This loops continuously
  buttonNew = digitalRead(SW);
  if (buttonOld == 0 && buttonNew == 1) {
    if (motorState == 0) {
      motorState = 1;
    }
    else {
      motorState = 0;
    }
  }
  buttonOld = buttonNew;

  if (motorState == 1) {
    Xval = analogRead(X);
    analogWrite(engine, Xval);
  }
  else {
    digitalWrite(engine, LOW);
  }

  delay(10);
  Serial.print("button");
  Serial.print(SWval);
  Serial.print("          X=");
  Serial.println(Xval);
}
```


message:
Getting all data of my JSON object from Serial.read() at once

I'm new to Arduino and I'm building a project that fetches data from a website (using ESP8266) and then transfers them to my `Arduino UNO` via serial port.

Data coming from ESP8266 every 20s - `[{"x": 0,"y": 0,"rgb": [255, 200, 174]},{"x": 1,"y": 0,"rgb": [255, 200, 174]},{"x": 2,"y": 0,"rgb": [255, 200, 174]}]`

But when I print the data like this
```

void loop() {

  if (Serial.available()) {
    Serial.write(Serial.read()); // This line prints only one character out of whole string

    data =  Serial.read(); // so this doesn't work

    DeserializationError error = deserializeJson(response, data);
    if (error) {
      Serial.print(F("deserializeJson() failed: "));
      Serial.println(error.f_str());
      return;
    }
    for (JsonObject elem : response.as<JsonArray>()) {
      int x = elem["x"]; // 2, 2, 2
      int y = elem["y"]; // 2, 2, 2
      JsonArray rgb = elem["rgb"];

      int rgb_0 = rgb[0]; // 255, 255, 255
      int rgb_1 = rgb[1]; // 255, 255, 255
      int rgb_2 = rgb[2]; // 255, 255, 255
      //Serial.print(x);
    }
  }
  delay(1000);   //then it waits 1 second and goes from the start
}
```

How can I make it to get the whole string and save it into a variable?

Thanks, much for answering.

body:
I was going to put this as a comment, but maybe it belongs as an answer:

For what it's worth, ArduinoJSON seems to be able to [deserialize directly from a stream](https://arduinojson.org/v6/api/json/deserializejson/), i.e. `Serial`, which may obviate the question *as asked*.  Presumably it knows where to stop deserializing, because it knows when it has received an entire JSON object; being a proper JSON parser, it can probably work this out better than you can without, you know, writing a JSON parser.

The following was just thrown together, now the author is here you should probably just follow their direction, but here's the code anyway:

```c++
#include <ArduinoJson.h>

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  Serial.begin(9600);
  Serial.setTimeout(30000);
}

void print_transmission_counter( {
    static unsigned long received_object_counter;
    Serial.println(F("\n\n\n\n"));
    for (int i = 0; i < 30; ++i) {
        Serial.write('-');
    }
    Serial.write('[');
    Serial.print(received_object_counter++);
    Serial.println(']');
}

void loop() {
    static StaticJsonDocument<256> json_doc;
    static bool led_state;

    print_transmission_counter();

    const auto deser_err = deserializeJson(json_doc, Serial);
    if (deser_err) {
        Serial.print(F("Failed to deserialize, reason: \""));
        Serial.print(deser_err.c_str());
        Serial.println('"');
    } else  {
        Serial.print(F("Recevied valid json document with "));
        Serial.print(json_doc.size());
        Serial.println(F(" elements."));
        Serial.println(F("Pretty printed back at you:"));
        serializeJsonPretty(json_doc, Serial);
        Serial.println();
    }

    // Just give some visual indication that the loop is progressing
    led_state = !led_state;
    digitalWrite(LED_BUILTIN, led_state);
}

//  vim:sw=2:ts=2:et:nowrap:ft=cpp:
```


message:
Serial.println won't format DEC

This is weirding me out. So I wrote to the EEPROM and I would like to read from the address and format it in Base 10, err... Decimal. The normal number thingy that's not ASCII. But it keeps returning ASCII values when I write:

`Serial.println(EEPROM.read(address), DEC)`.

Wait for the weird part, when I format in other bases like, say BIN, or OCT, it outputs in the correct base. Please help. Here's the full snippet of the tiny program.

    #include <EEPROM.h>
    int addr = 0;
    void setup() {
      // put your setup code here, to run once:
      Serial.begin(9600);

    }

    void loop() {
      // put your main code here, to run repeatedly:
      if(Serial.available() > 0){
        int rc = Serial.read();
        EEPROM.write(addr, rc);
        Serial.println(EEPROM.read(addr), DEC);
      }

    }

body:
I finally figured it out. Apparently, when I call Serial.read() and assign it to "int rc", It sort of converts the actual ASCII values into integer. So reading the number 3 from the Serial monitor and assigning it to rc stores 51 in rc. So the trick I found to that was to use

    int rc = Serial.read()-'0'

That way, I am storing 51-48 which is, 3 (Since 48 is the ASCII value for 0).

Thanks.


message:
Arduino Uno R3 stops executing code, when trying to instantiate multiple HX711 objects

This is my first time asking something on this platform, so if form or anything else is off, please feel free to point out things about how I could refine it and ask more concisely in the future.

I'm trying to develop an orthosis, which uses 4 load cells (full-bridge type) and 4 HX711 load cell amplifiers to inform patients via an app when they exceed their prescribed weight limit.

I have test code to calibrate the load cells and the code for the project itself. On the same Arduino, with the same components connected the test code, which only instantiates 4 HX711 objects and reads them after calibration, works fine. The full-blown project code uses exactly the same lines as well as the same hardware setup, but after the 2nd HX711 is instantiated I get no further Serial output and for all I can tell without a debugging jig, it looks like the Arduino stops executing code. If I try running the project code with only two HX711 objects (leaving the others physically connected, but commenting out the respective lines) the code works just fine.

So far I tried measuring RAM consumption, the Arduino should have 2048 bytes available, of which my project code seems to use 1483 bytes. My sensor test code uses 276 bytes, which means that technically I shouldn't be able to run out of memory. I also tried using another Arduino as a power source for the HX711 modules, just in case that the entire setup is asking for too much from a single Arduino - had no luck with that either. I would be really thankful for any pointers in the right direction since I can't figure it out on my own.

I'm using the following library for my HX711 modules: https://github.com/bogde/HX711

Project code (stops working after line 126):
```
#include <SoftwareSerial.h>
#include <SPI.h>
#include <SD.h>
#include "DHT.h"
#include "RTClib.h"
#include "HX711.h"

#define DHTPIN (uint8_t) 8
#define DHTTYPE DHT11
#define LED (uint8_t) 5
#define BUZZER (uint8_t) 9
#define BAUD 9600
#define NUM_CHARS (byte) 32
#define CHIP_SELECT (uint8_t) 10
#define SENSOR1_DATA (uint8_t) A0
#define SENSOR2_DATA (uint8_t) A2
#define SENSOR3_DATA (uint8_t) A4
#define SENSOR4_DATA (uint8_t) 7
#define SENSOR1_SCK (uint8_t) A1
#define SENSOR2_SCK (uint8_t) A3
#define SENSOR3_SCK (uint8_t) A5
#define SENSOR4_SCK (uint8_t) 6
#define TEST_DURATION 3000
#define NOT_CONNECTED 0
#define LIVE_VIEW 1
#define SETTINGS 2

// Constants
const int CHAR_SIZE = sizeof(char);

// Hardware interface settings
SoftwareSerial btSerial(2, 3);
RTC_DS1307 rtc;
DHT dht(DHTPIN, DHTTYPE);

HX711 SENSOR1;
HX711 SENSOR2;
HX711 SENSOR3;
HX711 SENSOR4;

// Hardware status & settings
boolean ledEnabled = true;
boolean isLedOn = false;
boolean buzzerEnabled = true;
boolean isBuzzerOn = false;
boolean error = false;

float threshold1 = 0.0f;
float threshold2 = 0.0f;
float threshold3 = 0.0f;
float threshold4 = 0.0f;

// Hardware testing
boolean ledTestinProgress = false;
unsigned long ledTestStart = 0;
boolean buzzerTestinProgress = false;
unsigned long buzzerTestStart = 0;

// Modes
int8_t mode = 0;

// Bluetooth
char data[NUM_CHARS];
boolean newData = false;

void receive();
void processMessage();
void testLED();
void testBuzzer();
void loadSettings();
void saveSettings();

extern void* __bss_end;
extern void* __brkval;

int get_free_memory()
{
  int free_memory;

  if((int)__brkval == 0)
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  else
    free_memory = ((int)&free_memory) - ((int)__brkval);

  return free_memory;
}

void setup() {
    pinMode(LED, OUTPUT);
    pinMode(BUZZER, OUTPUT);
    Serial.begin(BAUD);
    rtc.begin();
    if (!SD.begin(CHIP_SELECT)) {
        Serial.println(F("ERROR: SD init failed."));
        error = true;
    } else {
        loadSettings();

        Serial.println(F("SD initialized."));
        Serial.println(F("Settings: "));
        Serial.print(F("LED: "));
        Serial.println(ledEnabled);
        Serial.print(F("Buzzer: "));
        Serial.println(buzzerEnabled);
        Serial.print(F("Threshold 1: "));
        Serial.println(threshold1);
        Serial.print(F("Threshold 2: "));
        Serial.println(threshold2);
        Serial.print(F("Threshold 3: "));
        Serial.println(threshold3);
        Serial.print(F("Threshold 4: "));
        Serial.println(threshold4);

    }

    dht.begin();

    SENSOR1.begin(SENSOR1_DATA, SENSOR1_SCK);
    SENSOR1.set_scale(-63.f);
    SENSOR1.tare();
    Serial.println(F("Sensor 1 initialized."));

    SENSOR2.begin(SENSOR2_DATA, SENSOR2_SCK);
    SENSOR2.set_scale(-58.f);
    SENSOR2.tare();
    Serial.println(F("Sensor 2 initialized."));

    SENSOR3.begin(SENSOR3_DATA, SENSOR3_SCK);
    SENSOR3.set_scale(-50.f);
    SENSOR3.tare();
    Serial.println(F("Sensor 3 initialized."));

    SENSOR4.begin(SENSOR4_DATA, SENSOR4_SCK);
    SENSOR4.set_scale(-46.f);
    SENSOR4.tare();
    Serial.println(F("Sensor 4 initialized."));

    btSerial.begin(BAUD);
}

void loop() {
    if (!error) {
        receive();
        processMessage();

        DateTime now = rtc.now();
        float sensor1 = SENSOR1.get_units() / 1000;
        float sensor2 = SENSOR2.get_units() / 1000;
        float sensor3 = SENSOR3.get_units() / 1000;
        float sensor4 = SENSOR4.get_units() / 1000;

        Serial.print(F("Sensor 1: "));
        Serial.println(sensor1);
        Serial.print(F("Sensor 2: "));
        Serial.println(sensor2);
        Serial.print(F("Sensor 3: "));
        Serial.println(sensor3);
        Serial.print(F("Sensor 4: "));
        Serial.println(sensor4);

        if (isnan(sensor1) || isnan(sensor2) || isnan(sensor3) || isnan(sensor4)) return;

        if (!buzzerTestinProgress && !ledTestinProgress) {
            if (threshold1 > 0 && sensor1 > threshold1 ||
                threshold2 > 0 && sensor2 > threshold2 ||
                threshold3 > 0 && sensor3 > threshold3 ||
                threshold4 > 0 && sensor4 > threshold4) {
                if (buzzerEnabled)
                {
                    tone(BUZZER, 1000);
                    isBuzzerOn = true;
                }
                if (ledEnabled) {
                    digitalWrite(LED, HIGH);
                    isLedOn = true;
                }
            } else {
                if (isBuzzerOn) {
                    noTone(BUZZER);
                    isBuzzerOn = false;
                }

                if (isLedOn) {
                    digitalWrite(LED, LOW);
                    isLedOn = false;
                }
            }
        }

        if (mode == LIVE_VIEW) {
            btSerial.print(F("<"));
            btSerial.print(F("M;"));
            btSerial.print(now.unixtime());
            btSerial.print(F(";"));
            if (threshold1 > -1.0f) btSerial.print(sensor1);
            else btSerial.print(-1.0f);
            btSerial.print(F(";"));
            if (threshold2 > -1.0f) btSerial.print(sensor2);
            else btSerial.print(-1.0f);
            btSerial.print(F(";"));
            if (threshold3 > -1.0f) btSerial.print(sensor3);
            else btSerial.print(-1.0f);
            btSerial.print(F(";"));
            if (threshold4 > -1.0f) btSerial.print(sensor4);
            else btSerial.print(-1.0f);
            btSerial.println(F(">"));
        }

        if (ledTestinProgress && ((millis() - ledTestStart >= TEST_DURATION))) {
            ledTestStart = 0;
            ledTestinProgress = false;
            digitalWrite(LED, LOW);
        }

        if (buzzerTestinProgress && ((millis() - buzzerTestStart >= TEST_DURATION))) {
            buzzerTestStart = 0;
            buzzerTestinProgress = false;
            noTone(BUZZER);
        }

        delay(250);
    } else {
        tone(BUZZER, 1000);
        digitalWrite(LED, HIGH);
        delay(1000);
        noTone(BUZZER);
        digitalWrite(LED, LOW);
        delay(1000);
    }

    Serial.print(F("Free RAM: "));
    Serial.println(get_free_memory());
}

// Receive a Bluetooth message from the companion app
// Valid messages are encapsulated within '<' and '>' to ensure that the whole message is received.
void receive() {
    static boolean receiving = false;
    static byte index = 0;
    char startMarker = '<';
    char endMarker = '>';
    char rc;

    while (btSerial.available() > 0 && !newData) {
        rc = btSerial.read();
        delay(10);

        if (receiving) {
            if (rc != endMarker) {
                data[index] = rc;
                index++;

                if (index >= NUM_CHARS) {
                    index = NUM_CHARS - 1;
                }
            } else {
                data[index] = '\0';
                receiving = false;
                index = 0;
                newData = true;
            }
        } else if (rc == startMarker) {
            receiving = true;
        }
    }
}

// Processes a received message based on length and content
void processMessage() {
    if (newData) {
        int dataLength = strlen(data);

        Serial.println(data);

        if (dataLength == 1) {
            switch (data[0]) {
                case 'l': mode = LIVE_VIEW;
                break;
                case 's': {
                    mode = SETTINGS;
                    btSerial.print(F("<S;"));
                    btSerial.print(ledEnabled);
                    btSerial.print(F(";"));
                    btSerial.print(buzzerEnabled);
                    btSerial.print(F(";"));
                    btSerial.print(threshold1);
                    btSerial.print(F(";"));
                    btSerial.print(threshold2);
                    btSerial.print(F(";"));
                    btSerial.print(threshold3);
                    btSerial.print(F(";"));
                    btSerial.print(threshold4);
                    btSerial.println(F(">"));
                }
                break;
                case 'H': btSerial.println(F("<W>"));
            }
        } else if (dataLength == 2) {
            if (strcmp(data, "LT") == 0) testLED();
            if (strcmp(data, "BT") == 0) testBuzzer();
        } else {
            char* token = strtok(data, ";");
            int count = 0;

            if (strcmp(token, "S") == 0) {
                while (token != NULL) {
                    token = strtok(NULL, ";");
                    if (count == 0) ledEnabled = atoi(token);
                    if (count == 1) buzzerEnabled = atoi(token);
                    if (count == 2) threshold1 = atof(token);
                    if (count == 3) threshold2 = atof(token);
                    if (count == 4) threshold3 = atof(token);
                    if (count == 5) threshold4 = atof(token);
                    count++;
                }

                saveSettings();
            }
        }

        newData = false;
    }
}

// Initiate an LED test
void testLED() {
    ledTestStart = millis();
    ledTestinProgress = true;
    digitalWrite(LED, HIGH);
}

// Initiate a buzzer test
void testBuzzer() {
    buzzerTestStart = millis();
    buzzerTestinProgress = true;
    tone(BUZZER, 1000);
}

// Load settings from SD card
void loadSettings() {
    File settingsFile = SD.open("settings.txt", FILE_READ);

    if (settingsFile) {

        char settings[10];
        int index = 0;

        while (settingsFile.available()) {
            settings[index] = settingsFile.read();
            index++;
        }

        settingsFile.close();
        settings[index] = '\0';

        int count = 0;

        char* token = strtok(settings, ";");
        ledEnabled = atoi(token);

        while (token != NULL) {
            token = strtok(NULL, ";");
            if (count == 0) buzzerEnabled = atoi(token);
            if (count == 1) threshold1 = atof(token);
            if (count == 2) threshold2 = atof(token);
            if (count == 3) threshold3 = atof(token);
            if (count == 4) threshold4 = atof(token);
            count++;
        }
    } else {
        Serial.println(F("ERROR: Reading settings failed."));
        error = true;
    }
}

// Save settings to SD card
void saveSettings() {
    SD.remove("settings.txt");

    File settingsFile = SD.open("settings.txt", FILE_WRITE);
    if (settingsFile) {
        settingsFile.print(ledEnabled);
        settingsFile.print(";");
        settingsFile.print(buzzerEnabled);
        settingsFile.print(";");
        settingsFile.print(threshold1);
        settingsFile.print(";");
        settingsFile.print(threshold2);
        settingsFile.print(";");
        settingsFile.print(threshold3);
        settingsFile.print(";");
        settingsFile.print(threshold4);
        settingsFile.println(";");

        settingsFile.close();
    } else {
        Serial.println(F("ERROR: Saving settings failed."));
        error = true;
    }
}
```
Sensor test code (working flawlessly with the same hardware setup):
```
#include "HX711.h"

#define SENSOR1_DATA (uint8_t) A0
#define SENSOR2_DATA (uint8_t) A2
#define SENSOR3_DATA (uint8_t) A4
#define SENSOR4_DATA (uint8_t) 7
#define SENSOR1_SCK (uint8_t) A1
#define SENSOR2_SCK (uint8_t) A3
#define SENSOR3_SCK (uint8_t) A5
#define SENSOR4_SCK (uint8_t) 6

extern void* __bss_end;
extern void* __brkval;

HX711 SENSOR1;
HX711 SENSOR2;
HX711 SENSOR3;
HX711 SENSOR4;

int get_free_memory()
{
  int free_memory;

  if((int) __brkval == 0)
    free_memory = ((int)&free_memory) - ((int)&__bss_end);
  else
    free_memory = ((int)&free_memory) - ((int)__brkval);

  return free_memory;
}

void setup() {
    Serial.begin(9600);
    Serial.println(F("Sensor Test"));

    SENSOR1.begin(SENSOR1_DATA, SENSOR1_SCK);
    SENSOR1.set_scale(-63.f);
    SENSOR1.tare();
    Serial.println(F("Sensor 1 initialized."));

    SENSOR2.begin(SENSOR2_DATA, SENSOR2_SCK);
    SENSOR2.set_scale(-58.f);
    SENSOR2.tare();
    Serial.println(F("Sensor 2 initialized."));

    SENSOR3.begin(SENSOR3_DATA, SENSOR3_SCK);
    SENSOR3.set_scale(-50.f);
    SENSOR3.tare();
    Serial.println(F("Sensor 3 initialized."));

    SENSOR4.begin(SENSOR4_DATA, SENSOR4_SCK);
    SENSOR4.set_scale(-46.f);
    SENSOR4.tare();
    Serial.println(F("Sensor 4 initialized."));
}

void loop() {
  Serial.print(F("S1: "));
  Serial.print(SENSOR1.get_units(), 1);
  Serial.print(F(" | S2: "));
  Serial.print(SENSOR2.get_units(), 1);
  Serial.print(F(" | S3: "));
  Serial.print(SENSOR3.get_units(), 1);
  Serial.print(F(" | S4: "));
  Serial.println(SENSOR4.get_units(), 1);
  Serial.print(F("Free RAM: "));
  Serial.println(get_free_memory());
}
```

Wiring diagram (Fritzing): [![Wiring diagram][1]][1]

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

Changelog:
- Code is now embedded in the question.

body:
You'll need to use a library that support multiple HX711's. The [HX711-multi][1] library by compugician has worked great for me.

> The main difference this library introduces is the ability to sample multiple HX711 units simultaneously. It is optimized for intoducing minimal (effectively zero) overhead.

  [1]: https://github.com/compugician/HX711-multi


body:
If I have seen this correctly, you are currently only measuring the memory requirement in the loop().
To find out how much memory your code is using you should measure the memory consumption in any function which is memory hungry. You should call this line in all functions that are likely to put a heavy load on the heap.

    freeRAM = min(freeRAM, get_free_memory());

freeRAM is a global defined int with an initial value of 2048 (or what the RAM size is).
It is not enough to measure the memory usage only in loop(), because every function uses the heap during a call and frees the memory afterwards if variables not static.


message:
How to get current WiFi signal strength?

I have a LCD display where in I'm displaying a WiFi signal logo. I want to reduce the number of bars on the logo, indicating that the signal strength is dropping. I got the reducing bars on the LCD completed, I still have to find out the actual signal strength.

How do I find the signal strength of the connected network with ESP8266 based NodeMCU?

body:
You use [`WiFi.RSSI()`](https://arduino-esp8266.readthedocs.io/en/latest/esp8266wifi/station-class.html#rssi):

> # RSSI
>
> Return the signal strength of Wi-Fi network, that is formally called Received Signal Strength Indication (RSSI).
>
>     WiFi.RSSI()
>
> Signal strength value is provided in dBm. The type of returned value is int32_t.
>
> Example code:
>
>     Serial.printf("RSSI: %d dBm\n", WiFi.RSSI());
>
> Example output:
>
>     RSSI: -68 dBm


message:
Atmega328p with arduino without the board

Perhaps this is a beginners question and I am not sure. I currently have a custom made circuit with an atmega328p chip connected to an mpu6050. However, when I program in Arduino I am not sure what to do? I can't pick a "board" as the atmega328p doesn't belong to a board? (from what I'm aware at least)

How in Arduino do I choose to program for my atmega328p chip? Without having to pick a board such as Arduino Uno etc. As I don't have any board for this. Or does the atmega328p chip always belong to a certain board?

I have a fully working circuit with a cyrstal (16MHz), battery sources, atmega328p etc. But I don't know how to program it with Arduino? I can program it in C, but would like to use Arduino due to certain libraries.

body:
The board option is actually selecting a variant out of the installed cores (which provide the basic Arduino framework for a group of boards/chips). Each core can support multiple variants/boards/chips and can give each of them individual lists of options. There certainly also is a core, which supports the Atmega328p with all needed config options (like the frequency setting). You just need to install it from the boards manager.

Though, since you use a 16MHz crystal just like the Uno/Nano, you could just select the Uno or Nano as board. Neither the Arduino IDE, nor the Atmega328p can know, that the Atmega is actually a standalone one and not mounted on an Arduino board. So you can just use that board when you keep the config options inherent to an Arduino Uno/Nano (frequency setting and pin mapping mainly).


message:
Pro Micro board not responding to anything

I just got a couple of Arduino Pro Micros for a [custom keyboard](https://github.com/omkbd/ErgoDash) build. Before testing them with the Arduino IDE, I tried to test them with [qmk](https://github.com/qmk/qmk_firmware) by shorting `RST` to `GND` to try and flash it. After a few seconds of holding `RST`, I got a single blink and nothing else, and qmk didn't seem to have detected the reset.

I've tried setting "Board" to "Arduino Micro" and "Arduino Pro or Pro Mini". I'm on Arch Linux and no matter which USB port is plugged in, the IDE only shows `/dev/ttyS0`). I tried uploading the "Blink" example, as well as "Burn Bootloader", but only got `programmer is not responding` like so:

```
avrdude: Version 6.3-20190619
         Copyright (c) 2000-2005 Brian Dean, http://www.bdmicro.com/
         Copyright (c) 2007-2014 Joerg Wunsch

         Using Port                    : /dev/ttyS0
         Using Programmer              : arduino
         Overriding Baud Rate          : 19200
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 2 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 3 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 4 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 5 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 6 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 7 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 8 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 9 of 10: not in sync: resp=0x00
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 10 of 10: not in sync: resp=0x00

avrdude done.  Thank you.

```

body:
It turns out I had to use the port `ttyACM0` (and not `ttyS0`) which wasn't found at the time. The port was there the next day and I have no idea why it wasn't there before.

Also, I thought I had to press and hold `RST` for a couple of seconds to reset the Pro Micro, but I actually have to press it twice in a row.

I've managed to flash the firmware for my keyboard by double-pressing `RST`.


message:
Where is all of the Arduino Documentation?

Aside from the main website, I have noticed that it is hard to find documentation for specific Arduino add-ons, such as (This is just one example):

https://www.amazon.com/gp/product/B00OGYXN8C/ref=ppx_yo_dt_b_asin_title_o04_s01?ie=UTF8&psc=1#descriptionAndDetails

Is this fairly normal or are you just expected to "just know what to do" with every Arduino component after a while? I realize that the IDE does have samples, but they don't always help.

body:
To be fair, you're really talking about non-Arduino (capital-A) parts from a multitude of suppliers. And yes, the documentation varies in its depth, quality of translation if it wasn't originally written in English, and even availability at all. Taking the part you linked (from a retailer that storefronts for sellers (sometimes not in this country), who sell from component builders (often not in this country, who build with of parts from supplied factories definitely not in this country, ..., you get the idea. There may or may not exist any documentation specifically for this LCD/keypad combination shield.

But just by reading Amazon's seller's part description, I found that it consists of (at least) a 1602 LCD module and an HD44780 LCD controller chip, for both of which I can quickly find and download datasheets. The sixth image to the left of the description is a schematic of the board which shows that the left, right, up, down, and select buttons are 'multiplexed onto an output called AD0. I might have confirm that that is - or isn't - the Arduino's Analog-0 pin, but in any case, now I know what I have to write to decode which button was pressed from the board's analog output.

All this, and the part costs under US$7.00. For that price (and an assumption that these shields aren't being made in huge quantities), a maker couldn't possibly be able to create a custom datasheet for the shield as a whole, but they did supply a schematic, and their board's components are identified, and those components do, in fact have datasheets online.

Slightly awkward, perhaps, especially if one is thinking in terms of parts like MCUs such as the Atmega328 family, that *are* made in huge enough quantities that its datasheet runs to nearly 700 pages of engineering-ese. Still, the information is there and accessible, without requiring a way lot of digging.

That's part of being an experimenter.


body:
I'd like to add to what JRobert said of finding the information the "hard way"(i.e. looking into the datasheet of the chip it used, and understand how it works from schematic).

In the Arduino world, a lot of hardware/shields are so called [Open Source Hardware](https://en.wikipedia.org/wiki/Open-source_hardware), meaning that many companies can produce the same hardware with the schematic that is released under Open Source hardware license. China happened to be the country where it has the complete value-chain from components, to manufacturing and cheap labour. They are good in producing such products at large quantity and selling at low price, and they are not necessary good in developing original product, and certainly not in documentation (especially in English). These products are not necessary China "knock-off" as many people call it.

Since it is open hardware products, there are multiple vendors producing it and there are many information available on the internet, and take the example you provide, it is "1602 LCD Keypad Shield", and if your google it with this phase, you will soon find [this pdf](https://media.digikey.com/pdf/Data Sheets/DFRobot PDFs/DFR0009_Web.pdf) which is not exactly from the same company of your shield, but it is remarkably similar that you can try.

This applied to many hardware/shields that are available in the market. I hope this provide a general guidance and an "easy way" to find the information in your tinkering journey. Of course, if you want to learn more, go dig out the datasheet and schematic as JRobert mentioned.


body:
With this particular board, you're quite fortunate in finding a supplier with an actual website and description: [HiLetGo LCD1602 Input/Output expansion board LCD Keypad Shield for Arduino](http://www.hiletgo.com/ProductDetail/2160390.html). The fact that the photos of the HiLetGo site show the [DFRobot](https://www.dfrobot.com/) logo — the company that hcheung already referred to — shows just how radically open Open Hardware can get! In this case, DFRobot has pretty decent documentation: [LCD KeyPad Shield For Arduino: SKU DFR0009 - DFRobot](https://wiki.dfrobot.com/LCD_KeyPad_Shield_For_Arduino_SKU__DFR0009) — but even they don't link to the official [LiquidCrystal](https://www.arduino.cc/en/Reference/LiquidCrystal) documentation, but a much older archived version.

The Arduino team admits that they “… [never entirely got to grips with Arduino documentation](https://blog.arduino.cc/2021/05/17/arduino-docs-has-all-the-info-you-ever-need-about-arduino-boards/)”. Their own "Find in Reference" tool in the IDE will sometimes dead-end to error pages on the arduino.cc site. For example, "find in reference" for *Serial* will take you to a local copy of the documentation that has [broken links](http://www.arduino.cc/en/Guide/ArduinoLeonardo) for the [Arduino Leonardo](https://store.arduino.cc/usa/leonardo) [documentation](https://www.arduino.cc/en/Guide/ArduinoLeonardoMicro).

It's not always the case, but typically if an Arduino shield costs less than $10 on Amazon then the cost of "just know[ing] what to do" is passed on to you, the user.


body:
> **Where is all of the Arduino Documentation?**

Arduino
-------

So far as I know, the Arduino name is owned by the Italian company Arduino AG.

Arduino AG provide documentation on the website arduino.cc for the products they manufacture.

Arduino AG have no responsibilities for documenting products designed and manufactured by other businesses.

Other businesses
----------------

There are many other businesses that design and, in some cases, manufacture products that are designed to be compatible with or to work with products manufactured by Arduino AG. They don't need permission from Arduino AG unless they are using the trademarks or other intellectual property of Arduino AG. In addition, Arduino AG make many designs available under a permissive licence that does not give Arduino AG any control over or responsibility for documentation of cloned or derivative products manufactured or marketed by other businesses.

Examples include Adafruit, Sparkfun and many others.

These businesses provide documentation for the products they manufacture.

Some other businesses might choose to manufacture products without providing documentation or without providing documentation in English. For example a small Chinese manufacturer might only provide documentation in Chinese or provide none at all, expecting users to make use of documentation provided by the community or by the designer whose open-source designs they are using or whose proprietary designs their product is functionally equivalent to.

Open Source Designers
---------------------

Many hobbyists and small-scale makers provide documentation for use of their designs for products.


message:
Using OR with a while loop

I am trying to get two limits to or on the same while statement. Can this be done?

```c++
while (digitalRead (home_limit)) {
```

This works for one(1) limit,
But when I try using two(2) limits  is does not work. I can't find the proper configuration. I tried this.

```c++
while (digitalRead (home_limit1) || (home_limit2)) {
```

I also tried other combinations with no luck.
Does anyone know how to do an or (||) statement with a while digital read?

body:
`digitalRead()` is a function. It takes one parameter (the pin number) and returns the state of that pin.  It's *that* return value that you want to OR with another. Which means you have to read the state of *both* pins, separately, and OR the results together:

```c++
while (digitalRead(home_limit1) || digitalRead(home_limit2)) {
    ....
}
```


message:
Greyed out port for Raspberry pico in Arduino IDE - Ubuntu 20.04

I'm trying to figure out how to program my new Raspberry Pico with Arduino, but don't see a port to select so I can't upload the blink sketch.

Here's what I've done:

- The Pico is working, I can program it with micro Python.
- Just in case, I brought the Pico back to factory settings with the nuke file.
- Installed support for the Pico in Arduino IDE. Version 2.1.0 of Arduino MBed RP2040 is installed.
- While keeping BOOTSEL pressed, I plug in the Pico to my laptop (Ubuntu 20.04)
- The board selected is "Raspberry Pi Pico"
- But the option to select a port is greyed out :-(

It seems that I am omitting some step during the installation, but can't figure out what it is.

Any ideas?

Thanks!

body:
I've come across this and this is how I worked around it (on Windows, but I suspect the problem and solution is the same).

A brand new Pico or one not programmed by the Arduino IDE does not have a serial port, which is why you can't see one. Arduino sketches are compiled with a serial port automatically, so once a serial port exists, it can be used for future uploads.

The Arduino solution is to use the 'Export compiled binary' option (for any sketch) and upload the UF2 file (which should be generated into the sketch folder) using virtual USB drive interface. When the sketch starts, the serial port will be available and can be used for future sketch uploads.

Another solution is to use an [alternative Pico core][1]. This one does not need the port selected, but will find and upload to a Pico in bootloader mode via the virtual USB drive.

  [1]: https://github.com/earlephilhower/arduino-pico


body:
Had this issue and tried everything that was described on forums.

The thing that worked for me was: I held the bootsel button until it opened pico  folder, then port button activated in the IDE and I chose UF2 port and then after upload, pico showed at COM7


message:
How to properly handle the Arduino String

I've read that the Arduino String is bad as it causes memory fragmentation, so I try to avoid them mostly. But I still have some occurences where I'm not quite sure if they are ok after all.

The first is in print statements:
I have a function which prints a success or error message to the serial port, like so: `Serial.println("Success");`. Is this ok or should I (for example) pre define the String using `#define SUCCESS "SUCCESS"`?

Which leads me to the next case, defines:
I'm using MQTT and have the topics defined like above, e.g. `#define TOPIC_COLOR "light/color"`. Is this fine?

A third one is with ArduinoJSON:
I'm using Strings as keys, like so `lights["red"] = redVal;`. This call is made at multiple places so I assume the string would be created multiple times? A workaround/improvement I've thought of is using an enum defining the properties and using that as key.

Thanks for all comments, tips and explanations!

body:
+1 to @majenko's comments. I tend to avoid the `String` class, as I like to know what is actually going on, and I stick to `char *` and `char []` in general (and the `stdlib` functions like `sprintf`, `strlen`, etc).

Couple of notes on your question:

1. `"foo/bar"` is fine. Some characters have special meanings in the C language itself, so you need to escape them with the `\`. For example if `"` was part of your literal string, you'd write `"foo\"bar\""`

2. I tend to use `ArduinoJSON` to _parse_. If my app is just _sending_ JSON payloads, I just build it with `sprintf` or `print` which results in smaller programs. But, I guess it is a matter of choice. It is a great library.


message:
Weight scale with Arduino: calibration step

I'm not an expert about Arduino and I'm studying to create a project related to the bees remote monitoring.

I would like to monitor the internal humidity and temperature and the weight of the beehive boxes.

About the weight parameter my idea is to make a structure with 4 load cells.

I watched some video tutorials related to the creation of a weight scale with Arduino. I saw that it's necessary to calibrate the scale without any weight on the scale every time that Arduino will be started.

I'm not able to understand if there is a way to have this calibration in a different way: I mean,  I will place the beehives on my weight scales only one time and Is not possible to remove and put them back for each calibration step.

Is it really necessary or is there a way to have the calibration with the weight on the scales also?

body:
It may be that in this application (beehive monitoring) it is not required to re-calibrate your load sensors before each use.  When a person is observing a scale to measure their own weight they will be sensitive to the scale reading zero before each use.  Even though being, say, a lb off is likely less than a 1% error when measuring their total body weight.  [This site][1] talks about load cell calibration and "recommends a yearly recalibration interval".  They also talk about temperature compensation.

As temperature and humidity will be monitored.  And nonlinear load sensor response to weight can be compensated in software, consider testing your setup under different conditions to determine what considerations need to be taken into account to provide the desired accuracy.

[![This image is from https://www.futek.com/load-cell-calibration-services][2]][2]

This image is from https://www.futek.com/load-cell-calibration-services

  [1]: https://www.futek.com/load-cell-calibration-services
  [2]: https://i.stack.imgur.com/Ed0Fa.jpg


body:
What I can find about calibrating load cells is that they are subject to "electrical influence, mechanical effects, instrumentation faults and
loose cables etc."

In the case of beehives, I'd add temperature, water, ice, snow, dirt & dust, and debris from the bees. The calibration suggestions I found were to calibrate "periodically", which suggests to me that the suggestion to calibrate at every startup assumes that the calibration will be lost at every power-down. That does not have to be the case - it can be store in a non-volatile memory such as EEPROM.

What I do think you'll need to do is calibrate each cells at 0%, 10%, ..., etc., of its full load, probably to 120% or 130% to allow for wind loading and asymmetric loading within the hive, and at a range of temperatures, make a set of force vs. cell output and temperature, from which to interpolate to get the 4 partial hive-weights.

They probably will need to recalibrated periodically, but for your application, a tare-value, measured at a reproducible hive condition, may be sufficient, if all you need is a differential weight.


message:
Conditional compilation depending on sizeof(double)

Is there a macro (#define ...) somewhere in the bowels of Arduino IDE or core header files which tells me at compile time(!), if the `double` data type for a given platform/board is a true double precision floating point number (64 bit width) or "only" an alias for a single precision float (32 bit width)?

With Arduino, both can be the case. 8-bit AVR boards have `double` equal to `float`, ARM-based boards (like Arduino Zero) support "true" double precision.

I am working on a library which implements some bit-banging of floating point numbers (both single and double precision). Due to the low-level nature of the problem, there must be separate functions for `float` and `double`. I would like to do somthing like that:

```
uint32_t function_for_float(float f) {
    // function body here...
}

#if defined(HAS_64_BIT_DOUBLE)
uint64_t function_for_double(double d) {
    // function body here...
}
#endif
```

That way, a compile time error would be generated if somebody tried to use the "double" version on platforms which do not support the "true" double data type. I *want* the compiler error to be generated, because `function_for_double()` will do silently "the wrong thing" when fed a single precision float, leading potentially to difficult-to-debug problems.

Right now, I am defining a macro constant for every relevant board I own, like this:

    #if defined(ARDUINO_SAMD_ZERO) \
     || defined(SAMD_FEATHER_M0_EXPRESS) \
     || defined(ADAFRUIT_FEATHER_M4_EXPRESS)
        #define HAS_64_BIT_DOUBLE
    #endif

But this is ugly and not future-proof (new boards can/will become available...).

Any suggestions?

body:
The `double` data type is almost universally 8-bytes long, so you could
simply

```c
#if !__AVR__
# define HAS_64_BIT_DOUBLE
#endif
```

Gcc provides a more specific macro though: `__SIZEOF_DOUBLE__`, which
has the same value as `sizeof(double)`. But I do not know whether it is
provided by other compilers.


message:
Customizing system settings with defines?

I have written a library that contains a statically allocated buffer (f.g. `struct taskList proc[TBL_SIZE];`)

TBL_SIZE is a macro currently defined in my .h file.

I have heard that there's a way to set or reset the define statement inside the .ino file to customize this setting for some libraries, but I don't know how to do this myself, and by the time I realized that this was a problem I had forgotten what library allowed this setting.

This would be extremely useful as currently I have to edit my library every time I build a new project (or worse, am working on several at once with different settings).

My guess was a variant on an include guard, like this
```
#ifndef TBL_SIZE
#define TBL_SIZE 16 /*(or whatever)*/
#endif
```
block, but that failed to work. I tried it during a final project, so my memory is fuzzy from lack of sleep (and time, now), but I'm fairly sure I got an "undefined" error.

I don't know what this is called to search for it otherwise, so I'm hoping someone can help.

---

Here is more information about my specific issue:

In my .h (at the top, after the regular include guard):
```
#ifndef TBL_SIZE
#define TBL_SIZE 16
#endif
```
(Note that everything works if I just set this directly without the defines)

Further down the .h, inside my class:
```
struct task processes[TBL_SIZE];
```
In the main .ino file before the library includes:
```
#define TBL_SIZE 6
#include <CoRTOS.h>
```
---

Debug output of the build (I know from experience it built with 16 instead of 6 entries in that table from the memory size. The low memory warning is another big clue.)
```
Linking everything together...
"C:\\Users\\rdrag\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc" -w -Os -g -flto -fuse-linker-plugin -Wl,--gc-sections -mmcu=atmega328p -o "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.elf" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\sketch\\ECE554_ASP.ino.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\CoRTOS\\CoRTOS.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_GFX_Library\\glcdfont.c.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_GFX_Library\\Adafruit_GFX.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_GFX_Library\\Adafruit_GrayOLED.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_GFX_Library\\Adafruit_SPITFT.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_BusIO\\Adafruit_BusIO_Register.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_BusIO\\Adafruit_I2CDevice.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_BusIO\\Adafruit_SPIDevice.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Wire\\Wire.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Wire\\utility\\twi.c.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\Adafruit_SSD1306\\Adafruit_SSD1306.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\SPI\\SPI.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761\\libraries\\SparkFun_BME280_Arduino_Library-master\\SparkFunBME280.cpp.o" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/core\\core.a" "-LC:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761" -lm
C:\Users\rdrag\Documents\Arduino\libraries\CoRTOS\src/CoRTOS.h:38:7: note: array types have different bounds
 class cortos_class {
       ^
"C:\\Users\\rdrag\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy" -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.elf" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.eep"
"C:\\Users\\rdrag\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-objcopy" -O ihex -R .eeprom "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.elf" "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.hex"
Multiple libraries were found for "Adafruit_GFX.h"
 Used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_GFX_Library
 Not used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit-GFX-Library-master
Multiple libraries were found for "Adafruit_I2CDevice.h"
 Used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_BusIO
 Not used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_BusIO-master
Multiple libraries were found for "Adafruit_SSD1306.h"
 Used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_SSD1306
 Not used: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_SSD1306-master
Using library CoRTOS at version 0.2.0 in folder: C:\Users\rdrag\Documents\Arduino\libraries\CoRTOS
Using library Adafruit_GFX_Library at version 1.10.7 in folder: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_GFX_Library
Using library Adafruit_BusIO at version 1.7.3 in folder: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_BusIO
Using library Wire at version 1.0 in folder: C:\Users\rdrag\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.3\libraries\Wire
Using library Adafruit_SSD1306 at version 2.4.5 in folder: C:\Users\rdrag\Documents\Arduino\libraries\Adafruit_SSD1306
Using library SPI at version 1.0 in folder: C:\Users\rdrag\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.8.3\libraries\SPI
Using library SparkFun_BME280_Arduino_Library-master at version 2.0.9 in folder: C:\Users\rdrag\Documents\Arduino\libraries\SparkFun_BME280_Arduino_Library-master
"C:\\Users\\rdrag\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-size" -A "C:\\Users\\rdrag\\AppData\\Local\\Temp\\arduino_build_258761/ECE554_ASP.ino.elf"
Sketch uses 28172 bytes (91%) of program storage space. Maximum is 30720 bytes.
Global variables use 1609 bytes (78%) of dynamic memory, leaving 439 bytes for local variables. Maximum is 2048 bytes.
Low memory available, stability problems may occur.
```

body:
>I have heard that there's a way to set or reset the define statement inside the .ino file to customize this setting for some libraries, but I don't know how to do this myself

There are many ways to achieve what you want, you might not even need the `#ifndef` macro, use your library class construct to allow user to pass in the list size as an argument and but set the argument with a default value.

**YourLibrary.h**
```
class YourLibrary
{
private:
  size_t _userSize;
public:
  YourLibrary::YourLibrary(size_t listSize = 16) {
    _userSize = listSize;
  }
  ...
}
```

**User's sketch .ino**
```
#include <YourLibrary.h>

#define LIST_SIZE 32;

YourLibrary instance(LIST_SIZE);  // instance() would set the _listSize to 16

setup() {

}

loop() {

}
```


message:
connecting a small motor to arduino using a transistor

I want to connect a small motor (water pump) to an arduino, and I am not sure about the circuit.

The pump is small, works with 3.3V, but consumes 0.1A so I decided to use a transistor. The one I have is BF547, an NPN type small transistor. It supports currents up to 100 mA.

I measured the hfe (beta) of the transistor, and it is 370. The Vcc is 3.3V, and the current through the motor is 0.1 A, therefore:

A. the Ib equals to Ic/hfe = 0.1A/370 giving Ib = 0,00027A

B. with the Vb at 3.3V(pin voltage) and Vbe at 0.7 (datasheet) the Rb = (Vb-Vbe)/Ib = 9558 Ohm (10kOhm)

My questions are:
1. Did I calculate the base resistance correctly?
2. Do I need any additional resistor for the collector, next to the pump? Is it possible that more current flows through the collector-emitter?
3. According to the datasheet of BF457 100mA is the max Ic it can take. Should I limit the pump by adding a small (10 Ohm) resistor to it (33 Ohm[motors resitance] + 10 Ohm for 3.3 V gives a current of 76 mA)

I am attaching the schematics (linear voltage regulator is there only to stabilise the Vcc provided by an old dc power source I found)

Thanks a lot for any suggestions!

[![circuit][1]][1]

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

body:
I like your thought process (even though it might not be completely correct), I've seen how little thought were put in for such simple circuit design in the Arduino community, including from some Youtuber celebrity who teaching Arduino and claims to have an EE degree.

BF547 is an RF amplifier transistor, not for switching application, it would be better to use an NPN transistor such as [2N3904](https://media.digikey.com/pdf/Data Sheets/NXP PDFs/2N3904.pdf) which is designed for switching application and has a Ice of 200mA.

Your resistor value is too high. If your motor is designed to operate at 100mA 3.3v condition, you would want your driver to provide AT LEAST that current. Assuming your are driving the transistor with 5V out from an Arduino, a 1k bias resistor would limited the Ibe to (5 - 0.7Vbe)/1000=4.3mA, take a very conservative DC current gain of 30 (it typically in the range of 30 - 80 for switching transistor, and hfe could be in the range of 100 - 300 when frequency go up, but this will not be the case for Arduino even you drive the motor using PWM), which will capable to deliver Ice of 4.3 x 30 = 129mA. This should meet your Motor requirements.

You would need a protection diode connected between 3.3V and collector with its cathode connect to 3.3V and its anode connect to the collector of the transistor. An 1N4148 (max If=200mA) would be okay for this specific motor, or even better, use any Schottky diode with current and voltage limit higher than your application).


body: 4.6V - 1.2V (2 diode drops of 0.7V) = 3.4V, close enough for the motor if you are using a MOSFET as a driver. You can use a UIS rated MOSFET with a Vgs of less than 4 and it will work perfectly. the transistor will give you an additional voltage drop of about 0.7 Volts and needs a base resistor. If you want to guarantee the motor will not start during reset and setup() add a 10K resistor from the port pin to ground.


message:
Read from lux hangs in bright light

I am using VMEL6040 sensors and occasionally under bright light the read can hang, rather than using a wdt to recover I would like to ask some questions about the library.

as for debugging the sensors run stabley (several days at reads every 250 ms) in low light, but over 6k lux they can crash.

I am using wire.h here

in the header

    TwoWire *_i2cPort;

the read value calls the ReadRegister function:

    uint16_t SparkFun_Ambient_Light::_readRegister(uint8_t _reg)
    {

      uint16_t _regValue;

      _i2cPort->beginTransmission(_address);
      _i2cPort->write(_reg); // Moves pointer to register.
      _i2cPort->endTransmission(false); // 'False' here sends a restart message so that bus is not released
      _i2cPort->requestFrom(_address, static_cast<uint8_t>(2)); // Two reads for 16 bit registers
      _regValue = _i2cPort->read(); // LSB
      _regValue |= uint16_t(_i2cPort->read()) << 8; //MSB
      return(_regValue);

    }

is there a reason they are not checking the return of the `_i2cPort->endTransmission(false);`call? I am wondering if I should check that and not call the `requestFrom` if it does, i.e.:

    uint16_t SparkFun_Ambient_Light::_readRegister(uint8_t _reg)
    {

      uint16_t _regValue;

      _i2cPort->beginTransmission(_address);
      _i2cPort->write(_reg); // Moves pointer to register.
      if (_i2cPort->endTransmission(false) == 0) { // 'False' here sends a restart message so that bus is not released
          _i2cPort->requestFrom(_address, static_cast<uint8_t>(2)); // Two reads for 16 bit registers
          _regValue = _i2cPort->read(); // LSB
          _regValue |= uint16_t(_i2cPort->read()) << 8; //MSB
          return(_regValue);
      }
      else
          return 0;
    }

Or could my error be from the static casting do int?

body:
so I think I got it, the problem was that on a fail wire.read() returns an int -1
when that gets converted to a unint16 its a big number then it gets left shifted and overflows

the solution was:

    uint16_t SparkFun_Ambient_Light::_readRegisterLight(uint8_t _reg)
    {
        int lsb;
        int msb;

        _i2cPort->beginTransmission(_address);
        _i2cPort->write(_reg); // Moves pointer to register.
        if (_i2cPort->endTransmission(false) == 0) { // 'False' here sends a restart message so that bus is not released

            unsigned long tstamp = millis();
            while ((_i2cPort->available() < 2) && ((millis() - tstamp) < 10));

            if ((_i2cPort->available() < 2)) {
                _i2cPort->requestFrom(_address, 2); // Two reads for 16 bit registers
                lsb = _i2cPort->read(); // LSB
                msb = _i2cPort->read(); //MSB

                if ((lsb >= 0) && (lsb <= 256) && (msb >= 0) && (msb <= 256)) {
                    _regValue = lsb + msb * 256;
                }
            }

            return(_regValue);
        }
        else
            return _regValue;//last read
    }

This contains some extra error handling I added, but will leave in such as:

 1. timeout on waiting for a response
 2. checking on properly closing the bus in end transmission
 3. checking for errors from the read

I didn't do error handling as I would need to rewrite the whole library, and for my application repeating the last reading is sufficient.


message:
How esp8266 gets response from server..?

#include <SoftwareSerial.h>

    const byte rxPin = 2;
    const byte txPin = 3;

    SoftwareSerial ESP8266 (rxPin, txPin);

    void setup() {
      Serial.begin(115200);
      ESP8266.begin(115200);
      delay(2000);
    }

    void printResponse() {
      String s="";
      while (ESP8266.available()) {
        s+=ESP8266.readStringUntil('\n');
      }

      Serial.println(s);
      // now here you can parse and look for "+IPD" look for another line ending (if there is) and then extract the numeric value.
    }

    void loop() {

      ESP8266.println("AT+CIPMUX=1");
      delay(1000);
      printResponse();

      ESP8266.println("AT+CIPSTART=4,\"TCP\",\"www.tcpss.000webhostapp.com\",80");
      delay(1000);
      printResponse();

      String cmd = "GET /test.html HTTP/1.1";
      ESP8266.println("AT+CIPSEND=4," + String(cmd.length() + 4));
      delay(1000);

      ESP8266.println(cmd);
      delay(1000);
      ESP8266.println();
      delay(1000);
      printResponse();

      delay(5000);
    }

i have run this code and i am able to get this  response from server like "+ipd 4,41".... what does it mean?
here is the response after run the code in arduino......

    WIFI GOT IP
    AT+CIPLUX=1

    OK
    AT+CHPSTART=4,"TCP","www.tcpss.000webhostapp.com",80

    4,CONNEC
    AR)CR5NB⸮b⸮⸮k

    j⸮L⸮⸮
    Recv 27 bytes

    SEND OK

    +IPD,4,41

Thanks in advance.....

body:
There's two things to know here:

1. You're seeing corruption in your output because SoftwareSerial is not capable of working reliably at 115200 baud. You need to reconfigure your ESP8266 to operate at a lower baud rate (such as 9600) to be able to use it with an Arduino that doesn't have enough physical UARTs.
2. The response `+IPD,4,41` is telling you *about* the response. It's not itself the response.

It means "IP Data on channel 4 of length 41". It is then your responsibility to request that data from the ESP8266 using whatever AT command the ESP8266 requires.

Personally I would scrap the AT firmware and program the ESP8266 directly. That way you solve both problems: you can choose what baud rate to communicate at (if you even need to communicate to an Arduino at all), and you have no AT commands to parse or craft. It is a far more efficient way of working with the ESP8266 that trying to fudge things with the AT firmware and an Arduino.


body:
`SoftwareSerial` does not works well for baud rate higher than 9600bps, you need to change your Arduino and ESP8266 to operate at 9600bps.

1) Use the `AT+UART_DEF=9600,8,1,0,0` to set the ESP8266 to 9600Baud, with 8 bit, 1 stop bit and no parity. And also remember to configure the Arduino accordingly. The AT command with _DEF suffix means it will only need to be set once and the configuration will be saved in the ESP8266. [ESP8266 AT Command Set](https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf) would be handy when programming the ESP8266 with AT Commands.

2) Add longer delay after sending `AT+CIPSEND` and `Get` request as those network activities sometime take longer time to establish.

3) The `+IPD,4,41` means that Connect 4 (which you established with `AT+CIPSTART` is connected and there are 41 bytes payload waiting to be read. You can refer to [ESP8266 AT Command Examples](https://www.espressif.com/sites/default/files/documentation/4b-esp8266_at_command_examples_en.pdf) for more information.


message:
Differential voltage measurement using Arduino

I have a electrolysis cell in which the anode is hanging using a Structure in a electrolyte. The cathode is at the bottom of the cell with electrolyte above it and anode being dipped into this electrolyte (not completely, a portion of the anode is dipped). The cell operates at 7  volts DC and 90000 amperes of current flowing through it. This is a typical electrolysis process of producing aluminium from alumina powder in a aluminium smelter. The cell is called a pot.
Now the question is I need to measure a potential drop on the anode rod. We usually take a meter to measure the potential drop on the anode rod and typically the reading are in millivolts. As the readings are in millivolts, it just indicates the drop in rod voltage due to resistance of rod. Now can I measure this millivolts drop using Arduino provided the voltage at one point of anode is 5 volts with respect to ground and the voltage at the other point is 4.95 volts with respect to ground, however the difference between these voltages is 0.5 volts and this is voltage I need to measure using Arduino and some arrangements as add on to it. How can I do this?
Can anyone help.
If you want more details, please comment. I will also provide more details.

So far I have done is tried measuring 1.5 volts on a pencil cell using Arduino by connecting A0 analog pin on Arduino to positive directly to the positive of 1.5 volts battery and ground of Arduino to the negative of Arduino.

Can I do the same for this millivolts measurements? I understand that the ground of Arduino and the 2nd point of anode measurement will not be at same potential, so shouldn't be connected together. I am scared to burn my board, so didn't try practically and wanted to get some opinion.

body:
As you do it with the multimeter: connecting ground to the lower potential (4.95 Volts in your example) and the volt probe to the higher potential (in your case 5.0 V), you can also connect the Arduino between the two potentials: Arduino GND to the lower (!) potential and A0, A1, ... or A7 to the higher (!) potential.

As long as you use the correct polarisation and the difference between the potentials is less than VCC of the ADC (5V Arduino ADCs) you should be save.

The resolution of the Arduino might be a problem. I don't know what resolution you need; 5V divided by 1024 is about 5 mV per step.

You might want to provide a reference Voltage at Vin of -let's say- 1 Volt if you need a better resolution. That would improve the resolution to about 1 mV per step. But then the meassured voltage must no exceed the 1 Volt reference voltage.

**EDIT (Gerben's comment)**

You could use the 1.1V internal reference of the ATMega328P (analogReference(INTERNAL))

And please let me give you a security advice: If the resistence in any part of your meassuring setup is significantly lower than the resistance between the messuring points (e.g you shorten the probe wires), then there is a chance that 90000 A running through this setup. That could burn away your hand, arm or even your life. Amperes kill; not Voltage. I've seen a wrench that was vaporized (ok, melted, ok glowing ;-) ) in a second, when it had fallen between the poles of a car battery (12 V; 300 Amps). An you operate with 90000 Amps. !


body: This is obviously a significant project, not something to economize on. I would recommend you use a separate difference amplifier to get a single-ended output referenced to the Arduino ground and scaled to maximize the 10-bit range use.  The diff amp can use its own supplies (+/-7.5 or +/-15, say) with the ground tied to the Arduino ground.  That way the Arduino only sees the difference, never the full 7 V no matter what.


message:
12V 28BYJ-40 motor is not generating enough torque

I am attempting to use a stepper motor to rotate one of my split-flap displays. However despite the thing the motor is rotating weighing probably half a pound, it struggles to do so. It really can rotate the module at all.

**Why is my motor struggling so much?**

My circuit is an Arduino powered by 5V from a wall outlet, connected to a ULN2003 driver that is powered by a 12V wall outlet. The driver is connected to the stepper motor.

This is my code, it uses the Accel stepper library:
```
#include <MultiStepper.h>
#include <AccelStepper.h>
#include <Stepper.h>

AccelStepper stepper2(AccelStepper::FULL4WIRE, 4, 5, 6, 7);

void setup()
{
    Serial.begin(9600);
    pinMode(0, OUTPUT);
    pinMode(1, OUTPUT);
    pinMode(A0, OUTPUT);
    pinMode(A1, OUTPUT);
    pinMode(A2, OUTPUT);
    pinMode(A3, OUTPUT);
    pinMode(A4, OUTPUT);
    pinMode(A5, OUTPUT);

    stepper2.setMaxSpeed(100);
    stepper2.setAcceleration(10);
    stepper2.moveTo(-24000000);

}
void loop()
{
    // Change direction at the limits
    //printletters();

    if (stepper2.distanceToGo() == 0)
        stepper2.moveTo(-stepper2.currentPosition());

    stepper2.run();
}
```
Edit: Here is the schematic, I'm sorry its terrible but I dont know how to make it better

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

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

<!-- End schematic -->

body: The grounds needed to be shared. The driver board ground needed to be connected to the Arduino ground. Otherwise your putting 17V in and only taking 12V out. Thanks to DaveNewton for this answer. I made this change and the torque was immediately fixed!


message:
Arduino Uno - Raspberry PI - Float Sensors - Water pumps

I am experimenting with Aquaponics and since I am a software developer I found it "smart" to use arduino/raspberry in order to control the water flow and not simply use a water pump with mechanical means.

The advantage is that I am able to expand easier the system. The disadvantage is that I haven't yet met the reliability that I would lie to have.
I am a software engineer with basic knowledge in the hardware field. That is why I thought of starting with Raspberry.

Initially I made a setup with a single raspberry PI a few float sensors like this: https://www.hellasdigital.gr/electronics/sensors/humidity-sensor/tank-pool-water-level-liquid-sensor-float-switch/

and relay like this one: https://wiki.52pi.com/index.php/DockerPi_4_Channel_Relay_SKU:_EP-0099

I saw that sometimes the system was hanging with the relays open! This had the side effect to loose water. This is the most precious in aquaponics!

Thus I thought of creating a cluster. Thus I made a cluster of three Raspberrys. The two had the relays and only one PI had the sensors. In order to open the water pump both PIs should have given the green light. This worked better and when one of the PIs hanged then we lost no water.

But again I am thinking that it was not acceptable that the system was hanging so often (at least several times per week). Thus I thought maybe if I use an Arduino for this purpose then this would be better.

Thus this is what I did. I created a simple program (no cluster and a single Arduino). Unfortunately this had even worst results!!!

For the Arduino I used normal 5 Volt relays like this one: https://www.nettop.gr/index.php/hlektronika/relay/8-channel-5v-relay-module-with-light-coupling-5v.html and the same float sensors.

I do not believe that is software related the issue but it must be hardware.
The problem is that my knowledge in the hardware field is limited!
What should I do in order to prevent this? Do you think that is related with the water pumps and the relays ?

The same erroneous behavior happens at both the Raspberry and Arduino, I mean that the relay stays open and the water overflows. For Raspberry I can tell that the system stop to respond, I am sure about it. But for Arduino I cannot say for sure if the whole system was frozen or if input only for the float did not work.

I paste a link to the quick and dirty Arduino code as well for your reference.
The temperature were the systems were operating could be quite hot (30 ~ 48 degrees Celsius) for several hours.

Here is the code for the Arduino:

```c++
#define POT_1_FLOAT_SENSOR  2
#define POT_1_RELAY_1       11

#define PIPE_1_FLOAT_SENSOR  5
#define PIPE_1_RELAY_1       9

#define PIPE_2_FLOAT_SENSOR       3
#define PIPE_2_RELAY_2      10

#define PIPE_3_RELAY_3       12
#define PIPE_3_FLOAT_SENSOR       4

// pot 1
const unsigned long POT_1_MAX_WATERING_PERIOD = 120000;
const unsigned long POT_1_DRAIN_PERIOD = 70000;

unsigned long pot1StartMillis = 0;
unsigned long pot1DelayStartMillis = 0;

// Pipe 2
const unsigned long PIPE_2_MAX_WATERING_PERIOD = 300000;
const unsigned long PIPE_2_DRAIN_PERIOD = 300000;

unsigned long pipe2DelayStartMillis = 0;
unsigned long pipe2StartMillis = 0;

// Pipe 3
const unsigned long PIPE_3_MAX_WATERING_PERIOD = 760000;
const unsigned long PIPE_3_DRAIN_PERIOD = 300000;
unsigned long pipe3DelayStartMillis = 0;
unsigned long pipe3StartMillis = 0;

// Pipe 1
const unsigned long PIPE_1_MAX_WATERING_PERIOD = 180000;
const unsigned long PIPE_1_DRAIN_PERIOD = 300000;
unsigned long pipe1DelayStartMillis = 0;
unsigned long pipe1StartMillis = 0;

bool pot1RedFlag = false;
bool pot1SetStartTime = false;

bool pipe1RedFlag = false;
bool pipe1SetStartTime = false;

bool pipe2RedFlag = false;
bool pipe2SetStartTime = false;

bool pipe3RedFlag = false;
bool pipe3SetStartTime = false;

void setup()
{
  Serial.begin(9600);
  // initialize the pushbutton pin as an input:
  pinMode(POT_1_FLOAT_SENSOR, INPUT_PULLUP);
  pinMode(POT_1_RELAY_1, OUTPUT);
  digitalWrite(POT_1_RELAY_1, LOW);

  pinMode(PIPE_1_FLOAT_SENSOR, INPUT_PULLUP);
  pinMode(PIPE_1_RELAY_1, OUTPUT);
  digitalWrite(PIPE_1_RELAY_1, LOW);

  pinMode(PIPE_2_FLOAT_SENSOR, INPUT_PULLUP);
  pinMode(PIPE_2_RELAY_2, OUTPUT);
  digitalWrite(PIPE_2_RELAY_2, LOW);

  pinMode(PIPE_3_FLOAT_SENSOR, INPUT_PULLUP);
  pinMode(PIPE_3_RELAY_3, OUTPUT);
  digitalWrite(PIPE_3_RELAY_3, LOW);

  pot1StartMillis = millis();
  pipe1StartMillis = millis();
  pipe2StartMillis = millis();
  pipe3StartMillis = millis();
}

void loop()
{
  checkAbstractWateringTimer(pot1SetStartTime, pot1RedFlag, pot1DelayStartMillis,
                                POT_1_DRAIN_PERIOD, POT_1_MAX_WATERING_PERIOD,
                                pot1StartMillis, POT_1_FLOAT_SENSOR, POT_1_RELAY_1);

  checkAbstractWateringTimer(pipe1SetStartTime, pipe1RedFlag, pipe1DelayStartMillis,
                                PIPE_1_DRAIN_PERIOD, PIPE_1_MAX_WATERING_PERIOD,
                                pipe1StartMillis, PIPE_1_FLOAT_SENSOR, PIPE_1_RELAY_1);

  checkAbstractWateringTimer(pipe2SetStartTime, pipe2RedFlag, pipe2DelayStartMillis,
                                PIPE_2_DRAIN_PERIOD, PIPE_2_MAX_WATERING_PERIOD,
                                pipe2StartMillis, PIPE_2_FLOAT_SENSOR, PIPE_2_RELAY_2);

   checkAbstractWateringTimer(pipe3SetStartTime, pipe3RedFlag, pipe3DelayStartMillis,
                                PIPE_3_DRAIN_PERIOD, PIPE_3_MAX_WATERING_PERIOD,
                                pipe3StartMillis, PIPE_3_FLOAT_SENSOR, PIPE_3_RELAY_3);

  delay(200);
}

void checkAbstractWateringTimer(bool &abstractSetStartTime, bool &abstractRedFlag, unsigned long &abstractDelayStartMillis,
                                unsigned long abstractDrainPeriod, unsigned long abstractMaxWateringPeriod,
                                unsigned long &abstractStartMillis, int abstractFloatSensor, int abstractRelay) {
  if (!abstractSetStartTime || (abstractSetStartTime && millis() - abstractDelayStartMillis >= abstractDrainPeriod)) {

    if(digitalRead(abstractFloatSensor) == LOW && !abstractRedFlag) // Need one more condition in order to emulate the delay...
    {
      digitalWrite(abstractRelay, LOW);
      Serial.println("Pot 1 pump is open");

      // Set it only once at the beginning
      if (pot1SetStartTime) {
        abstractStartMillis = millis();
        abstractSetStartTime = false;
      }

      Serial.print("duration ");
      Serial.println(millis() - abstractStartMillis);

      if (millis() - abstractStartMillis >= abstractMaxWateringPeriod)  //test whether the MAX watering period has elapsed
      {
        // Close pump and do not oopen it again. Red Flag...
        Serial.println("Pot 1 pump is closed and the red flag is ON");
        digitalWrite(abstractRelay, HIGH);
        abstractRedFlag = true;
      }
    }
    else
    {
      Serial.println("Pot 1 Pump is closed");
      digitalWrite(abstractRelay, HIGH);
      abstractSetStartTime = true;
      abstractDelayStartMillis = millis();
    }
  }
}
```

Please any ideas, suggestions or tests that I could do are more than welcome in order to create a reliable system.

-- UPDATE --
Both when I was using Raspberry and Arduino I haven't included any resistors between the float sensor pins and the ground. Are there any chances that this is related with the instabilities that I experienced?

Maybe I should add a resistor (10K) between the float sensor pin and the ground?

Thank you

body:
thank you for your valuable input. I can say that now the system is stabilized.
The source of my issues was a faulty sensor but I have taken into account all advices. For example I separated the signal cables from the power cables that this was one more source of issues, I have introduced the pull up resistors, I have used separate power source for the relay module.

Generally for me ALL the comments from this thread were super important.

Thank you!


body:
As requested, I've collated my comments into an answer.

How long are the cable runs? Is there any electrically noisy equipment near the cable runs? Consider using some form of galvanic isolation to interface the float sensors to the MCU. Texas Instruments has a great series of videos on the subject of [galvanic isolation][1] which discusses inductive, capacitive and optical isolation techniques. Isolate the signals in both directions – both the inputs and the outputs.

For stronger pull-ups you could try 1K resistors, though this will use more current.

Something else to consider is debouncing the float sensor signals either in hardware with a low-pass RC filter or with a [software debouncer][2] (which I've put on GitHub).

The relays require 50 to 60 mA drive current but the Arduino pins can only supply 40 mA, so the external power supply is a good idea.

Redundancy, i.e. having multiple sensors for the same measurement, will guard against the loss of a single sensor causing chaos in a critical system, e.g. loss of precious water in a hot climate. You could have 3 float sensors for each water level at different locations, then use a voting system of >= 2 to take action. The system should also flag when sensors disagree so that someone can investigate the issue. And also route the cables via 3 different paths. This physical separation will guard against a single localised event (e.g. a wayward tractor or lightning strike) damaging all the sensors at the same time.

Also consider the fail-safe mode. For example, this could be to switch off all water valves when sensors disagree and then send an alert to someone and/or sound an alarm.

As your aquaponic farm is outside, consider lightning strike protection such as using TVS diodes on all inputs and outputs.

You could add feedback sensors to the relays to verify whether they have actually responded to the commands from the Arduino to switch on or off, i.e. compare commanded value with FB sensor value. These sensors could be pullup/pulldown resistors.

These additional relay FB sensors and the float sensors could be incorporated into the fail-safe logic. Some examples include:
1. If a relay is on when it's supposed to be off, flag the discrepancy.
2. If it takes 5 minutes to fill a tank and the inlet relay has been on for >5 minutes, it might be overflowing or dodgy sensors.
3. If the float sensors say a tank is empty, but the inlet relay has been on for >5 mins, something is wrong, e.g. leaking tank or dodgy sensors.
4. If it takes 10 mins to drain a tank but the float sensors say it's still full after 11 mins, something is wrong, e.g. blocked drain or dodgy sensors.
5. Are inlet and outlet relays on at the same time? Is this a valid condition?

There are many permutations. Happy coding...

  [1]: https://training.ti.com/ti-precision-labs-isolation-what-galvanic-isolation
  [2]: https://github.com/TimMathias/Arduino-Debouncer


message:
Arduino lcd displays random chracters

I have connected arduino nano every to my lcd display. It works perfect when i put all my code in setup() part. But when i put the code in loop() it does werid things. I have to put my code in loop(), because i am reading from load cell and displaying the values that are constantly changing. The delay can't be more than 250 ms.

This works well.
```
#include <LiquidCrystal.h>
int Contrast=30;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup(){
    analogWrite(6,Contrast);
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);
    lcd.print("testing");
}

void loop(){

 }
```

When I do this next thing it works well for few seconds and then it starts to display random weird characters and stops displaying anything after some time.
```
#include <LiquidCrystal.h>
int Contrast=30;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup(){
    analogWrite(6,Contrast);
    lcd.begin(16, 2);
    lcd.setCursor(0, 0);

}

void loop(){

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(millis()/1000);
  delay(250);
 }
```

I have tried removing lcd.clear() it didn't help.
I thought it was a problem with wiring first, but it's not.
What am I doing wrong?

Any help would be great, thanks.

body:
1. `lcd.setCursor(0, 0);` - you dont really need this funtion. `lcd.clear()` will always bring the cursor into the (0,0) position, automatically.

2. check your wiring. The code seems to be correct

3. Increase the delay to 500 ms or more. You don't have to write faster than 1 seconds to the LCD anyway


message:
Looking for an accurate and fast updating range sensor

I need to purchase a distance sensor that will be fixed in place and used to determine distance to the top of a fairly fast moving piston along the axial direction in line with the sensor. The top of the piston can be covered in whatever material works best for sensor accuracy, and the entire apparatus can operate in the dark if needed. Distance will range from 50mm to 500mm. Position measurement must have an accuracy range below 1.5mm. Update rate must be 1000hz or greater (i.e. update every 1ms or faster).

I see there are many options for me at high cost, but I'm limiting my budget to $500 and below for the next few days while I research more. This does not mean I won't spend whatever is needed however. As of now I've seen nothing acceptable for under that price, but it's hard to tell as many companies won't publish prices for these types of sensors.

I'm happy to explain more about the implementation if needed.

## UPDATE
I wish more people were reading this post, because I have great suggestions for DIYers after researching a lot of options the past few days. Currently I'm looking at offerings from Turck.com relating to reading a magnetized strip. This would read position from the side rather than from above or below as I describe in my original question. Turck calls it their "LM-2 line" and some options look pretty affordable and quite a bit under $500. Here's a brochure they provide - it documents how they read a magnetic strip: https://www.turck.us/attachment/B1027.pdf

## NOTE
There is one answer here related to a different sort of solution involving a device which reads a code every 0.5mm or 1.0mm taped to a rod which is attached to the piston. Device would read in direction perpendicular to direction of motion. This would probably be my 2nd or 3rd choice if I'm unable to find an affordable sensor as described in my question.

## NOTE 2
If I had time I'd implement the following solution which I wish I had thought of a month ago: tape a 300mm strip of reflective material which varies in reflectivity along its length. shine a laser on the tape and detect amount of light which reflects. simple solution, easy to calibrate and (if I knew where to get the tape) should be low cost.

body:
Inside an inkjet printer, I've found a clear plastic strip with photo-engraved (loose approximation) lines perpendicular to the length of the strip. This strip passes through an optical pair, one side illuminates, the other reads. The strip stretches the entire width of the printer and if I recall correctly, the reading module is on the print head carriage. Consider that many printers are described as 600 dots per inch, which would create a resolution on the strip of 1/600" / 0.04 mm.

Additionally, I've discovered circular plastic encoders on which the rings of black/clear alternated the segment counts with each expanding ring. That is to say, the first ring was half black, half clear. The next ring out was 1/4 black/white alternating, the one following was 8 segments, then 16, etc.

This required a reader for each ring, but provided an absolute reference rather than a relative reference as is the case with the linear strip. One could create a linear strip which would work in a similar manner. One level would be half black, half clear, the next layer would be 1/4 black/clear, etc.

[![binary scale image][1]][1]

The requirement for 500 mm fits into a binary 512 value, which would require 9 stripes and provide for the accuracy noted in the post.

The aspect I can't answer is the speed of the encoding, although I suspect that any design based on an optical reader could be optimized to work.

I found an article at [rp-photonics.com][2]

> When light is diffracted at the traveling refractive index grating in
> an acousto-optic modulator, the diffracted light experiences a shift
> of optical frequency which is plus or minus the acoustic (or drive)
> frequency. That effect (which can be interpreted as a Doppler shift)
> is exploited in acousto-optic frequency shifters.
>
> Drive frequencies are typically between some tens and hundreds of
> megahertz, rarely more than 1 GHz. The resulting change of optical
> wavelength is quite small. For larger frequency shifts, or for
> realizing very small frequency shifts (e.g. only a few MHz), one may
> cascade two or more devices. It is also possible to use a double pass
> through a single device in order to obtain twice the frequency shift.

I think from reading that excerpt that the long strip in the inkjet printer is the traveling refractive index grating. I had not considered that a low-power laser could be substituted for a simple optical pair. Doing so would provided even better resolution.

If your project allows for a strip of sufficient length to be attached to the piston, with assurance that it won't buckle under acceleration and jam in the sensor, you'd probably make it work.

But wait, there's more. I can picture the rod on the piston alternately obscuring and uncovering a digital design, which is constantly scanned by a laser. This reduces the number of parts in close contact and possibly the moving mass.

  [1]: https://i.stack.imgur.com/4Q7Me.png
  [2]: https://www.rp-photonics.com/acousto_optic_frequency_shifters.html


message:
Is this circuit damaging my arduino/components?

I'm building a system as follows:

* There are two pumps which lower and raise the level of the water
* There is an ultrasound detector which measures the level of the water
* While the water is too high, water is pumped out
* While it's too low, water is pumped in

There are thresholds to prevent micro-adjustments, the system doesn't flip-flop back and forth.

However after a short while the ultrasound sensor stops working, until I power the system off and on again. My electronics knowledge is *extremely* rudimentary, but I know motors can be nasty to other components?

I've included my circuit diagram, should I be doing anything about that? I'm using reed switches to turn them off and on, but the ground and 5v rails are all tied together, and powering the arduino too via VIN.

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

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

body:
Motors are inductive loads (they contain coils) that generate voltage spikes when switched off. These voltage spikes can indeed be nasty to other components.
You need to add a **[flyback diode][1]** in parallel with the motor, with the cathode connected to Vcc.
It will normally not conduct current, but when the motor is switched off, because the voltage spike is negative, it will provide a path for the current and allow to dissipate it through the coil's internal resistance.

As pointed out in the comments, it's also a good idea to (always) add an electrolytic capacitor (> 100 µF) close to the ultrasonic detector to filter out this kind of spikes.

  [1]: https://en.wikipedia.org/wiki/Flyback_diode


body: Hopefully you are powering the Arduino Vin with at least 7 volts. We know the Arduino a power supply it is NOT so where does the 5V come for the motors? You need to post technical links to the hardware items you are using. Are you calling relays reed switches? D11 and D12 sound like port pins, normally they cannot drive relays unless they are designed appropriately. I would suggest you either buy another set of electronic parts or stop using it until the problems can be determined. As far as a circuit diagram does not show the information needed. A schematic, not a frizzy thing is much better.


message:
Send Request With NODEMCU When A Key Press

Hi there I want to send a request to the server with get method with URL parameters, when a key is pressed with nodemcu. But I Can't Do This Work, I Got the Below Error From Serial Monitor:

I Get This Error From Serial Monitor

     ets Jan  8 2013,rst cause:4, boot mode:(3,7)

    wdt reset
    load 0x4010f000, len 1384, room 16
    tail 8
    chksum 0x2d
    csum 0x2d
    v951aeffa
    ~ld
**My Main Code**
```
#include <ESP8266WiFi.h>
const char* ssid = "MobinNet1365";
//replace with your own wifi ssid
const char* password = "G12229M1Q64"; //replace with your own //wifi ssid password
const char* host = "webhook.site";

const int button = 8;
int temp = 0;

void setup() {

  Serial.begin(115200);
  pinMode(button, INPUT);
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

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

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {

  temp = digitalRead(button);
  if (temp == HIGH) {
    Serial.println(host);
    WiFiClient client;
    const int httpPort = 80;

    String url = "/df35c8cd-0398-4c92-b55f-b9e36629b309";
    url += "?switche=";
    url += "1";

    client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
  }
}
```

my request sending code is below:

```
#include <ESP8266WiFi.h>
const char* ssid = "your-ssid";
const char* password = "your-password";
const char* host = "";

void setup() {
 Serial.begin(115200);
 delay(10);
 Serial.println();
 Serial.print("Connecting to ");
 Serial.println(ssid);
 WiFi.mode(WIFI_STA);
 WiFi.begin(ssid, password);
 while (WiFi.status() != WL_CONNECTED)
 {
  delay(500);
  Serial.print(".");
 }

 Serial.println("");
 Serial.println("WiFi connected");
 Serial.println("IP address: ");
 Serial.println(WiFi.localIP());
}
int value = 0;
void loop() {
 delay(5000);
 ++value;
 Serial.print("connecting to ");
 Serial.println(host);
 WiFiClient client;
 const int httpPort = 80;
 if (!client.connect(host, httpPort)) {
  Serial.println("connection failed");
  return;
 }

 String url = "/";
 /* url += "?param1=";
 url += param1;
 url += "?param2=";
 url += param2;
 */
 Serial.print("Requesting URL: ");
 Serial.println(url);
 client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
 unsigned long timeout = millis();
 while (client.available() == 0) {
  if (millis() - timeout > 5000)
  {
   Serial.println(">>> Client Timeout !");
   client.stop();
   return;
  }
 }

 while (client.available())
 {
  String line = client.readStringUntil('\r'); Serial.print(line);
 }

 Serial.println();
 Serial.println("closing connection");
}
```

And My Key Press Code Detector Is below:

```
const int button = 8;
int temp = 0;

void setup() {
  Serial.begin(9600);
  pinMode(button, INPUT);
}

void loop() {
  temp = digitalRead(button);

   if (temp == HIGH) {
      Serial.println("LED Turned ON");
      delay(1500);
   }
   else {
      Serial.println("LED Turned OFF");
      delay(1500);
   }
}
```

And My Circuit Is:

NodeMcu => MicroSwitch

VIN => C

D0 => NO

G => 10k => NO

How Can I Make It When That Key Pressed It Send Request?

body:
IMHO, some consideration :

1. const int button = 8;
const int button = 5; // CHANGE TO Pin "D1 GPIO5"

GPIO8 is used to connect the flash chip, you may change to Pin "D1" which is GPIO 5.
* Check with your board's pinout.

2. to prevent non-stop keep calling within in the loop, you may use millis();

for example :

```
void GetUrl() {
    temp = digitalRead(button);
  if (temp == HIGH) {
    Serial.println(host);
    WiFiClient client;
    const int httpPort = 80;

    String url = "/df35c8cd-0398-4c92-b55f-b9e36629b309";
    url += "?switche=";
    url += "1";

    String link = String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n";
//    Serial.println( "link : " + link );
    client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
  }
}

unsigned long previousMillis = 0;
const long interval = 1000 * 0.5; // 500ms (0.5 sec)

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    GetUrl();
  }
}
```

Reference :

https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay

https://iotbyhvm.ooo/gpio-pins-esp8266/