text:
Nan values in Egg Incubator
I've recently built my Arduino Incubator, which consists of a DHT22 sensor, an LCD Keypad Shield, some fans, resistors, e.t.c.
I uploaded the sketch, and everything seemed fine. However, when I try to select the temperature and humidity I want, it won't let me change anything, and it says "Temperature: NanC, Humidity: Nan%".
What am I doing wrong? I didn't write the code myself. I copied it from a guy who made his incubator and wrote his code himself. He has the incubator project on github.
As you can see in the pictures he posted, everything appears to be working fine. What would be the problem? I don't have a lot of Arduino knowledge, although I am OK with reading and tinkering with code.
The display below, shows NaN when I try to select my own temperature/humidity. When I see the current temperature/humidity, it works fine. The sensor works with no problems at all, though I didn't connect a pullup resistor. I am going to try adding one. However, to me it seems like the problem isn't that. I get NaN errors when trying to select my own value. The buzzer beeps, the servo turns and the fan works fine. As said above, DHT sensor works and sends the values.

Useful Links:
The code (Github)
The schematic (Github)
The whole incubator project (Github)
Update - 7/1/2019
Thanks to Jot, everything works fine now! He corrected my code, and he adviced me to reset the values in the EEPROM. I would have given up the project, unless he had helped me. I have now fully finished the build, even though I plan to add some features in the future.
I want to add:

A backup power source (lead acid battery)
Bigger ventilation holes
Design improvements
The ability to control everything using the serial monitor, so I can connect to the Arduino via Internet (Using an MFP Storage Server which I have)
A larger box for more eggs
A system which turns the eggs automatically
A pump which pumps water to the sponge automatically as well

However, nothing could be done without Jot's help. Again, thanks a lot to Jot for his help, and the efforts he put in order to help me. I really appreciate that, since I have not any kind of Arduino knowledge (I'm 14 years old), and I found his advices and comments very very useful.
I have now put 5 eggs inside the incubator, and it is right now working. I am counting backwards from today, and in about 21 days I am going to have chickens!
Here are some pictures of the machine for those who are interested (or just curious!):
The incubator working, with the screen turned on:

The "egg hatching" room:
(Inside, there is a wet sponge, all the devices and of course, 5 eggs!)

i think that nan means not a number ..... comment out this line H = dht.readHumidity();  and add H = 0.5; ..... what do you get on the display then?

Please, Post all the code that you are using to.

The code, is given in the link above. However, here is the link: https://github.com/quantenschaum/egg-incubator/blob/master/incubator.ino. I only made a few changes at the beginning, so the lcd screen shows both date and time. Actually, I dodn't think this affects the error, as it has nothing to do with that. In addition to the above, I imported the code to the Arduino (before changing anything), and it seemed like the problem existed.

@jsotola thanks for the reply! However, it seems like the H = dht.readHumidity(); is already included. Take a look at that:     if (!key) {
//    beep(2000, 50);
T = dht.readTemperature() + T_OFFSET;
H = dht.readHumidity();
  if ((isnan(T) || T < 10 || T > 60) || (Hcontrol && (isnan(H) || H < 5 || H > 95))) {
    heater(0);
    lcd.clear();
    lcd.print("SENSOR ERROR!"); It seems like it includes those, and also sets off an alarm if a nan value is displayed. When I add H = 0.5;, it beeps and reboots as the code says. My problem is when I select t/h.

@jsotola Also, the screen says "SENSOR ERROR", and that is something that the code says. As you can see in the previous code, if a nan value is displayed, then it sets off the alarm. For more information you can also see the whole code at the link included. Something to mention, is that I only have trouble selecting values e.g. temperature or humidity. I see the current temperature and humidity displayed with not problems. However, when I go to the selection menu, all the setpoints are NaN values.

Did you lay these eggs yourself?

Hi Lefteris the builder,
StackExchange is about questions and answers.
Arduino is about learning and fast prototyping.
For guidance with your project, the forum at http://forum.arduino.cc/ is more appropriate.
I suppose that a number of us have read the code that you use. We really do read code.
That code is not bad, but there are a few weak spots in that code:

Not enough comments to explain what is going on.
Many conditions with flags. That is okay,
but the flags are sometimes a boolean and
sometimes a byte, and there is no explanation what the flag is
used for.
Many checks for isnan(). Does that indicate that
a floating point "nan" problem might pop up
at any time in the sketch?
Most of the code is in the loop(). I don't mind that, but
others prefer to put large blocks of code in functions.

It seems that your hardware is working okay.
It is hard to confirm that the code for the Holt-Winters algoritme is working.
All this together is too confusing for us at the moment.

I have changed my answer, the hardware seems to be working.

Below is the changed sketch to test it without extra hardware.
I use the serial monitor. The sadw keys (followed by enter) are the cursor keys and the space bar (followed by enter) is select.
#include <avr/wdt.h>
// #include <Servo.h>
// #include <LiquidCrystal.h>
// #include <DHT.h>
#include <EEPROM.h>

// stty -F /dev/ttyACM0 115200 cs8 cread clocal -hupcl time 30 && tee incubator.log </dev/ttyACM0

#define WDT_TIMEOUT WDTO_8S // if defined, enable hardware watchdog
#define DHTPIN 3 // data pin of the DHT T/H sensor
#define T_OFFSET 0.9 // temperature sensor offset
#define FAN_PIN 2 // fan tacho signal pin
#define FAN_THRES 500 // fan alarm threshold
#define BEEPER A2 // pin where beeper is attached
#define BRIGHTNESS 10 // display brightness pin
#define HEATER A1 // heater MOSFET pin
#define DELAY 2000 // loop delay in ms
#define TS_ADDR 0 // temperature set point EEPROM address
#define HS_ADDR 4 // humidity set point EEPROM address
#define HC_ADDR 8 // humiditiy control mode EEPROM address
#define TI_RESET 1 // integral reset threshold, set integral to 0 when T error greater than this
#define HI_RESET 5 // integral reset threshold, set integral to 0 when H error greater than this
#define ALARM_T 2 // temperature alarm threshold, alert if T error greater than this
#define ALARM_H 8 // humidity alarm threshold, alert if H error greater than this
#define H_AUTO_THRES 3 // disable vent control in auto mode if H error < this
#define H_AUTO_COUNT 200 // disable for n cycles
#define HWAT 0.25 // holt winters parameters for temperature smoothing
#define HWBT 0.2
#define HWAH 0.7 // holt winters parameters for humidity smoothing
#define HWBH 0.5
#define A 0.005 // long average parameter
#define VENTCLOSED 80 // consider vent closed if under this angle
#define VENTOPENMS  480000L // open vent if closed longer
#define VENTRESETMS 600000L // reset vent after this time (>VENTOPENMS!)

// Servo vent;
// DHT dht(DHTPIN, DHT22);
// LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#define RIGHT 16
#define UP 8
#define DOWN 4
#define LEFT 2
#define SELECT 1
#define NO_KEY 0

// added define to show messages on serial monitor.
#define lcd Serial

byte getKey() {
//  int key = analogRead(0);
//  if (key < 50) {
//    return RIGHT;
//  } else if (key < 150) {
//    return UP;
//  } else if (key < 300) {
//    return DOWN;
//  } else if (key < 500) {
//    return LEFT;
//  } else if (key < 800) {
//    return SELECT;
//  } else {
//    return NO_KEY;
//  }
  if (Serial.available() > 0) {
    int inChar = Serial.read();
    switch (inChar)
    {
      case 'w': return UP;
      case 'a': return LEFT;
      case 's': return DOWN;
      case 'd': return RIGHT;
      case ' ': return SELECT;
    }
  } else {
    return NO_KEY;
  }
}

void eeread(int address, int length, void* p) {
  byte* b = (byte*)p;
  for (int i = 0; i < length; i++) {
    *b++ = EEPROM.read(address + i);
  }
}

void eewrite(int address, int length, void* p) {
  byte* b = (byte*)p;
  for (int i = 0; i < length; i++) {
    EEPROM.write(address + i, *b++);
  }
}

void write_byte(int address, byte &value) {
  eewrite(address, sizeof(value), &value);
}

byte read_byte(int address) {
  byte value;
  eeread(address, sizeof(value), &value);
  return value;
}

void write_int(int address, int &value) {
  eewrite(address, sizeof(value), &value);
}

int read_int(int address) {
  int value;
  eeread(address, sizeof(value), &value);
  return value;
}

void write_float(int address, float &value) {
  eewrite(address, sizeof(value), &value);
}

float read_float(int address) {
  float value;
  eeread(address, sizeof(value), &value);
  return value;
}

void heater(boolean on) {
//  digitalWrite(HEATER, !on ? LOW : HIGH);
}

boolean heater() {
//  return digitalRead(HEATER) == HIGH;
  return true;
}

volatile int fancount;

void count() {
  ++fancount;
}

void beep(unsigned long f, unsigned long l) {
//  pinMode(BEEPER, OUTPUT);
  byte v = 0;
  f = 500000 / f;
  l = (1000 * l) / f;
  for (int i = 0; i < l; ++i) {
//    digitalWrite(BEEPER, v = !v);
//    delayMicroseconds(f);
  }
//  pinMode(BEEPER, INPUT);
}

float Ts, Hs; // set points
byte Hcontrol; // H control mode
byte Ts_changed, Hs_changed; // setpoint changed flags
float ET, dETdt, IETdt; // prop/diff/integ terms for T
float EH, dEHdt, IEHdt; // prop/diff/integ terms for H
float T, Tavg = NAN, Tvar, Tstd;
float H, Havg = NAN, Hvar, Hstd;
float Hpower, Hduty; // heater current power, average duty cycle
unsigned long t0, Hon, talarm, tventclosed;
byte displayMode;
byte key, bri = 255, alarm;
boolean ventclosed;
int fanrpm;

void setup() {
#if defined(WDT_TIMEOUT)
//  wdt_enable(WDT_TIMEOUT);
#endif
  Serial.begin(9600);
  Serial.println("Egg Incubator");
  Serial.println("Use wsad and space is select");

//  pinMode(HEATER, OUTPUT);
//  heater(0);
//  pinMode(BRIGHTNESS, OUTPUT);
//  analogWrite(BRIGHTNESS, bri = 255);
//  lcd.begin(16, 2);
//  lcd.noCursor();
  lcd.print("Incubator 0.7");
//  lcd.setCursor(0, 1);
  Serial.println();
  lcd.print(__DATE__);
//  dht.begin();
//  vent.setMinimumPulse(800);
//  vent.setMaximumPulse(2600);
//  vent.attach(11);
  //  write_float(TS_ADDR, Ts=37.8);  write_float(HS_ADDR, Hs=55);
  Ts = read_float(TS_ADDR);
  Hs = read_float(HS_ADDR);
  Hcontrol = read_byte(HC_ADDR);
//  pinMode(FAN_PIN, INPUT_PULLUP);
//  attachInterrupt(0, count, FALLING);
//  sei();
//  beep(800, 100);
//  beep(1000, 100);
//  beep(1200, 100);
//  beep(1600, 100);
}

void loop() {
  unsigned long t1 = millis();
  int dt = t1 - t0;

  if (!key) {
    key = getKey();
  }

  if (key) {
//    analogWrite(BRIGHTNESS, bri = 255);
  }

  if (t1 - Hon > Hpower * DELAY) {
//    heater(0);
  }

  if (Hcontrol && Hcontrol < H_AUTO_COUNT) {
//    vent.refresh();
  }

  if (alarm && !(alarm & 8)) {
//    beep(1000, 50);
//    beep(1414, 50);
  }

  if (dt > DELAY || key) {

    if (!key) {
      //    beep(2000, 50);
//      T = dht.readTemperature() + T_OFFSET;
      T = 30.0 + T_OFFSET;             // set to fixed value !
//      H = dht.readHumidity();
      H = 60.0;                        // set to fixed value !

      if ((isnan(T) || T < 10 || T > 60) || (Hcontrol && (isnan(H) || H < 5 || H > 95))) {
//        heater(0);
//        lcd.clear();
        lcd.print("SENSOR ERROR!");
//        lcd.setCursor(0, 1);
        Serial.println();
        lcd.print("T=");
        lcd.print(T);
        lcd.print("C H=");
        lcd.print(H, 1);
        lcd.print("%");
        beep(2000, 1000);
        return;
      }

      float dts = dt * 1e-3;

      if (dt > DELAY) {
        fanrpm = fancount * 60 / dts;
        fancount = 0;
      }

      if (fanrpm < FAN_THRES) {
        alarm |= 4;
      } else {
        alarm &= ~4;
      }

      // temperature Holt-Winters smoothing
      float E0 = ET;
      ET = HWAT * (T - Ts) + (1 - HWAT) * (ET + dETdt * dts); // smoothed T error (deviation from set point)
      dETdt = HWBT * (ET - E0) / dts + (1 - HWBT) * dETdt; // smoothed derivative
      IETdt += ET * dts; // integral of error
      if (abs(ET) > TI_RESET) // reset integral on big deviation
        IETdt = 0;
      float pidT = 1.1765 * (ET + 0.010526 * IETdt + 23.75 * dETdt); // PID value, adjust coefficients to tune
      Hpower = fanrpm > FAN_THRES ? max(0, min(1, -pidT)) : 0;
      heater(Hpower > 0.1);
      Hon = millis();

      if (abs(ET) > ALARM_T) {
        alarm |= 1;
//        vent.write(ET < 0 ? 0 : 180);
        if (Hcontrol > 1) {
          Hcontrol = 2;
        }
      } else {
        alarm &= ~1;
      }

      // humidity Holt-Winters smoothing
      E0 = EH;
      EH = HWAH * (H - Hs) + (1 - HWAH) * (EH + dEHdt * dts); // smoothed H error (deviation from set point)
      dEHdt = HWBH * (EH - E0) / dts + (1 - HWBH) * dEHdt; // smoothed derivative
      IEHdt += EH * dts; // integral of error
      if (abs(EH) > HI_RESET) // reset integral on big deviation
        IEHdt = 0;
      float pidH = 0.1176 * (EH + 0.09091 * IEHdt + 2.75 * dEHdt); // PID value, adjust coefficients to tune
//      vent.write(pidH * 180);

      if (Hcontrol && abs(EH) > ALARM_H) {
        alarm |= 2;
      } else {
        alarm &= ~2;
      }

      boolean ventclosed0 = ventclosed;
//      ventclosed = vent.read() < VENTCLOSED;
      ventclosed = VENTCLOSED;

      if (ventclosed && ventclosed != ventclosed0) {
        tventclosed = millis();
      }

      boolean openvent = ventclosed && millis() - tventclosed > VENTOPENMS;
      if (openvent) {
//        vent.write(180);
        if (millis() - tventclosed > VENTRESETMS) {
          tventclosed = millis();
        }
      }

      if (Hcontrol > 1) {
        if (abs(EH) > H_AUTO_THRES || openvent) {
          Hcontrol = 2;
        } else {
          if (Hcontrol < H_AUTO_COUNT) {
            ++Hcontrol;
          } else {
            IEHdt = 0;
          }
        }
      }

      // long term averages
      Tavg = A * T + (1 - A) * (isnan(Tavg) ? T : Tavg);
      Tvar = A * pow(T - Tavg, 2) + (1 - A) * (isnan(Tvar) ? 0 : Tvar);
      Tstd = sqrt(Tvar);

      Havg = A * H + (1 - A) * (isnan(Havg) ? H : Havg);
      Hvar = A * pow(H - Havg, 2) + (1 - A) * (isnan(Hvar) ? 0 : Hvar);
      Hstd = sqrt(Hvar);

      Hduty = A * Hpower + (1 - A) * Hduty;

      if (Ts_changed) {
        if (Ts_changed-- == 1)
          write_float(TS_ADDR, Ts);
      }

      if (Hs_changed) {
        if (Hs_changed-- == 1)
          write_float(HS_ADDR, Hs);
      }
    }

    if (key & SELECT) {
      displayMode = ++displayMode % 8;
    }

//    lcd.clear();
    Serial.println();
    lcd.print("T=");
    lcd.print(Ts + ET);
    lcd.print("C H=");
    lcd.print(Hs + EH, 1);
    lcd.print("%");

//    lcd.setCursor(0, 1);
    Serial.println();

    float uptime;
    char unit;
    switch (displayMode) {
      case 0: // raw values
        lcd.print("T=");
        lcd.print(T);
        lcd.print("C H=");
        lcd.print(H, 1);
        lcd.print("%");
        break;
      case 1: // temperature setpoint
        if (key & (UP | DOWN | LEFT | RIGHT)) {
          Ts = max(20, min(50, Ts + (key & (UP | RIGHT) ? +1 : -1) * (key & (UP | DOWN) ? 0.1 : 1)));
          Ts_changed = 10;
        }
        lcd.print("Ts=");
        lcd.print(Ts);
        lcd.print("C");
        break;
      case 2: // humidity setpoint
        if (key & (UP | DOWN)) {
          Hs = max(10, min(90, Hs + (key & UP ? +1 : -1)));
          Hs_changed = 10;
        }
        if (key & RIGHT) {
          if (Hcontrol < 2) {
            Hcontrol = ++Hcontrol;
          } else {
            Hcontrol = 0;
          }
          IEHdt = 0;
          write_byte(HC_ADDR, Hcontrol);
        }
        lcd.print("Hs=");
        lcd.print(Hs);
        lcd.print("% ");
        lcd.print(Hcontrol == 1 ? "on" : (Hcontrol > 1 ? "auto" : "off"));
        break;
      case 3: // average temperatur
        lcd.print("Ta=");
        lcd.print(Tavg);
        lcd.print("C (");
        lcd.print(Tstd);
        lcd.print(")");
        break;
      case 4: // average humidity
        lcd.print("Ha=");
        lcd.print(Havg);
        lcd.print("% (");
        lcd.print(Hstd);
        lcd.print(")");
        break;
      case 5: // heater duty cycle
        lcd.print("Hd=");
        lcd.print(Hduty);
        lcd.print(" Hp=");
        lcd.print(Hpower);
        break;
      case 6: // air vent
        lcd.print("V=");
//        lcd.print(vent.read() / 180.0);
        lcd.print(" F=");
        lcd.print(fanrpm);
        break;
      case 7: // average humidity
        uptime = t1 * 1e-3;
        unit = 's';
        if (uptime > 60) {
          uptime /= 60;
          unit = 'm';
          if (uptime > 60) {
            uptime /= 60;
            unit = 'h';
            if (uptime > 24) {
              uptime /= 24;
              unit = 'd';
            }
          }
        }
        lcd.print("Up=");
        lcd.print(uptime, 1);
        lcd.print(unit);
        break;
      default:;
    }

    Serial.println();

    if (alarm & 7) {
      if (!talarm) {
        talarm = millis();
      }
      // sound on persistent alarm and fan failure
      if (millis() - talarm > 300000L || alarm & 4) {
        alarm &= ~8;
      }
//      analogWrite(BRIGHTNESS, bri = 255);
//      lcd.setCursor(0, 0);
      if (alarm & 1)
        lcd.print("T ");
      if (alarm & 2)
        lcd.print("H ");
      if (alarm & 4)
        lcd.print("F ");
      lcd.print("ALARM!          ");
      if (!(alarm & 8) && key) {
        alarm |= 8; // alarm acknowledged
        talarm = millis();
      }
      if (!(alarm & 8)) {
//        lcd.setCursor(0, 1);
        Serial.println();

        lcd.print("T=");
        lcd.print(T);
        lcd.print("C H=");
        lcd.print(H, 1);
        lcd.print("%");
      }
    } else {
      alarm = 0;
      talarm = 0;
    }

    if (key) {
      delay((key & SELECT) ? 500 : 200);
    }

    if (bri) {
//      analogWrite(BRIGHTNESS, --bri);
    }
    key = 0;
    t0 = t1;
  }

#if defined(WDT_TIMEOUT)
  wdt_reset();
#endif
}

@Lefteristhebuilder, you have selected that sketch, but the sketch might not handle problems very well.
Anyone can write code for Arduino and put it online.
At least at Github it is possible that others can write an issue (as you did). The project at Github has 9 stars and the creator showed the project at the Arduino "Project Hub". That is all good, but I'm not very happy with the code itself.

Hi! First of all... I didn't write the code myself! I copied from a guy who did the same thing and it worked for him. The display above, shows NaN when I try to select my own temperature/humidity. When I see the current temperature/humidity, it works fine. The sensor works no problems at all, though I didn't connect a pullup resistor. I am going to try adding one. However, to me it seems like the problem isn't that. I get NaN errors when trying to select my own value. Buzzer, servo and fan work fine. Buzzer, fan and servo work fine. As said above, DHT sensor works and sends the values.

@Lefteristhebuilder please update your question with this extra information. Also add a link to your issue at github to your question. Add to question which DHT library you use. Did you really use a SoftwareServo library?

@Lefteristhebuilder I'm running a simulation of the code. I don't get the "nan" numbers when adjusting the values with up and down. The way the menu works in the sketch is hard to understand. If I had to solve this for myself, I would print a lot of variables to the serial monitor and probably end up rewriting the whole sketch.

thanks for your reply! What kind of simulation did you do? Can I do that as well? I don't know whether the code is hard to understand or not, since as mentioned above, I have not any kind of experience with coding. Unfortunately I can't write the sketch, I haven't done any similar thing before and if you asked me to create just a blink sketch, I would struggle a lot, or I would just copy something posted online. What are the available options? I spent a lot of money for this project and I don't want to throw it away.... Hope you kindly understand. I used DHT.h and SoftwareServo.h.

@Lefteristhebuilder I have added the changed sketch to my answer. There are many libraries with "DHT.h" and no one uses the SoftwareServo anymore because that became the normal Arduino Servo library.

Thank you a lot for your time and the efforts you put! I followed your steps, uploaded the code, but unfortunately I still get the same error.... I don't know what causes it to do so, and since you told me that it worked at the simulation, I think that we are not going to make it work..... sorry for wasting your time, very sorry....

Also, is there any way to make it displayed both in the serial monitor and the screen??

That is good information. I have removed all the hardware from the sketch except the EEPROM. Did you reset the values in EEPROM? Can you uncomment the line with two "write_float" in it (remove the two slashes // in front). This line: https://github.com/quantenschaum/egg-incubator/blob/master/incubator.ino#L164 Run the sketch once, and then put the two slashes // back. You can add code to send data also to the serial monitor.

@Lefteristhebuilder You gave up?

Not only I didn't gave up, but I also finished the build. Right now it is working fine, without problems and that's all thanks to you! Thanks to you, I've got rid of the NaN values, and I finished something that I was about to give up. I'm only 14 years old and I don't have any idea of programming, so your advise was very very helpful. You can also check at the very bottom of that thread, as I've put an update and mentioned the fact that you helped me. I don't even know how to thank you! That was unbelievable!

@Lefteristhebuilder Well done. I'm glad I could help.


text:
WifiNINA WebServer not receiving connections
I use a MKR 1010 (firmware 1.2.1), download WifiNINA library (version 1.3.0) and started to play with it.
I can connect to my Wifi network, and WifiNINA library examples such a WifiPing (which repeatedly pings www.google.com) works fine.
However, I can't get any of the server examples (e.g. WifiWebServer) to work.
I can see that the board connects to the network and gets an IP and the Serial monitor is printing this :
09:11:15.989 -> SSID: OfficeNet
09:11:15.989 -> IP Address: 192.168.1.44
09:11:15.989 -> signal strength (RSSI):-36 dBm
09:11:15.989 -> To see this page in action, open a browser to http://192.168.1.44

But if I browser to http://192.168.1.44, I never get any answer.
The loop code is just from the example :
void loop() {
  WiFiClient client = server.available();   // listen for incoming clients

  if (client)
  {                             // if you get a client,
    Serial.println("new client");           // print a message out the serial port
(...)
  }
  // close the connection:
  client.stop();
  Serial.println("client disonnected");
}

I am never getting inside the if client()loop ("new client" never printed).
Any suggestions?

on what port do you start the server? didn't you forget to call server.begin()?

This is the out-of-the-box example code, so port 80, and server.begin() is on the last line of setup()

is your computer on the same WiFi network?

Yes, same network "OfficeNet". I did some more tests, the arduino can ping google server, but no computer from my network (I tried with 2 of them - and they can ping each other). I forced fixed IP address for all of them, no change...

is the network mask 255.255.255.0 or is it different?

Thanks for your interest Juraj ! Not sure how to check this. In my TCP/IP configuration there is something I would translate by "sub-network" which value is indeed 255.255.255.0. It is now quite late in my time zone. I'll go to sleep and delete/re-install everything tomorrow.

yes I meant sub-network mask. it determines which IP addresses 'see' each other. in case of 255.255.255.0 all addresses with the same first 3 numbers of IP address should be able to communicate

Dawn ! I deleted the whole Arduino IDE and re-installed everything yesterday night, and I got it working without any modification ! I even could ping any machine from my network. Switch off everything, came back this morning, and same problem again. Nothing works...

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Prioritizing one sensor
I want to ask is there a possible code to prioritize a specific part of a code? So I'm doing this project where I want to utilize muscle sensor, servo, and a button on an app over Bluetooth. The problem is since all is running in void() loop, even though I am not using the muscle sensor I can't move the servo with the app, since it reads the muscle sensor first. So is there a possible code to make the muscle sensor stop for a period of time after the button is pressed on the app and the servo is moved?
Here is the code:
void loop()
 {
  if(Serial.available()>0)
   {
    char data = Serial.read();

      if (data == 'a')
       {
        myservo.write(15);
       }
  }

int value = analogRead(EMG_PIN);

 if(value > THRESHOLD)
  {
   myservo.write(15);
  }

  else{
       myservo.write(140);
      }

So the first code is a bluetooth code where the servo is controlled through a button on an app. The second one is a muscle sensor. As stated above the problem is it will always read the muscle sensor even though the button is pressed from the app.
#include <Servo.h>

 int increment = 0;

 Servo myservo;

 void setup() {

   myservo.attach(1);

 }

 void loop()
 {

   Serial.println(increment++);

   if (increment > 9);
    {

     if(Serial.available()>0)
      {
       char data = Serial.read();

       if (data == 'a')
       {
        myservo.write(15);
       }
 }

      else if (increment = 0);

      int value = analogRead(EMG_PIN);

      if(value > THRESHOLD)
       {
        myservo.write(15);
       }

     else{
       myservo.write(140);
      }
  }

Your question is too vague to be answerable. The answer is "Yes, there's a way." Provide your current loop code, and highlight the relevant sections where you read the muscle sensor, and where the servo code doesn't get called. It sounds to me like a simple logic problem with your code but we can't tell without seeing the code.

why do you need code to stop the muscle sensor? .... does it have a "stop" function? ....... why don't you simply read it only every10th iteration of loop()?

@DuncanC Ok guys I already edited my post, and putted in my code, i hope it will give you a better hindsight

@jsotola I'm new to this stuff, so I don't really know how to do it :), can you show me an example code from my code above, it would really help thx

@jsotola is it something like that, second code, im still new to thus so a bit confused

something like that .... it looks like to have mismatched braces {}  ..... your indentation levels are messed up so it is not clear just by looking at your code

Note that the line else if (increment = 0); had 3 fatal flaws:

(1) It should use ==, not = (= is an assignment, so it assigns 0 to increment and then the if statement always fails.

(2) you should never put a semicolon after an if statement. That results in if (condition) {do nothing} since a semicolon marks an empty statement.

(3) You are missing a brace after the if statement. Code like if (condition) statement is legal, but confusing and error-prone. That only executes that one statement if the if is true, and then falls through to the statement after the if. If your indentation is wrong, you might think the if statement will only execute ALL the indented code if the if statement is true, but that is not correct.

Ahh ill look into that thx a lot @DuncanC

You have to think of your program as having two distinc modes of
operation:

The "fixed servo" mode is entered when you press the button on the
app. In this mode the servo is kept at a fixed position. The mode
lasts for a predefined delay.
The normal (not fixed servo) mode is the default mode. In this mode
the servo is positioned according to the reading of the sensor.

So you need a boolean variable to remember whether the "fixed servo"
mode is active or not, and the code in loop() should take care of
providing the correct behavior depending on the mode, and updating that
variable when needed. For example:
void loop()
{
    static bool fixed = false;  // whether we are in "fixed servo" mode
    static uint32_t fixed_started;  // when the mode started
    uint32_t now = millis();

    // On button press, start "fixed servo" mode.
    if (Serial.available() && Serial.read() == 'a') {
        servo.write(SERVO_LEFT);
        fixed = true;
        fixed_started = now;
    }

    // Get out of "fixed" mode after some delay.
    if (fixed && now - fixed_started >= FIXED_DELAY) {
        fixed = false;
    }

    // If not in "fixed" mode, react to the sensor.
    if (!fixed) {
        if (analogRead(EMG_PIN) >= THRESHOLD) {
            servo.write(SERVO_LEFT);
        } else {
            servo.write(SERVO_RIGHT);
        }
    }
}

Ahh I see it worked perfectly thx Edgar

Well done, figuring out the OPs intent from that jumble of code.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Can I design Arduino Mega 2560 circuit without adding ATMega 16?
I want to make Arduino Mega 2560 board.
As the reference files are given on Arduino Site, I don't want to add USB communication on the board.
So can I remove part of ATMega 16?
Will it cause any kind of problem in working of board?
And if It will fine to remove ATMega 16 part, How much part of schematic to be change?

It would be helpful for you to understand what each part does. If you find the Atmega16 useful, you should just add it, if not, your question is answered. :)

When I omit a USB / Serial IC I often put an "FTDI" header, so I can use common USB/Serial converters. Might be useful in your case.

Yes, you can omit the ATmega16U2 and its accompanying parts. That is, the whole right block of schematic in this sheet.
The resulting board will work perfectly fine, it will simply no longer have a built-in programming interface, nor a built-in USB-serial interface. You will likely want to buy an FTDI cable and an AVR programmer, if you do not already have these.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Temperature Sensor not giving proper values
In my current project I am reading temperature through sensor which is having only two wires.

To read sensor values, I have used below schematic which I have found on Arduino Project Hub site.

In my project I am using below Arduino program.
#include <OneWire.h>
#include <DallasTemperature.h>

// Data wire is plugged into pin 2 on the Arduino
#define ONE_WIRE_BUS 2

// Setup a oneWire instance to communicate with any OneWire devices
// (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);

// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);

void setup(void)
{
  // start serial port
  Serial.begin(9600);
  Serial.println("Dallas Temperature IC Control Library Demo");

  // Start up the library
  sensors.begin();
}

void loop(void)
{
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  Serial.print(" Requesting temperatures...");
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println("DONE");

  Serial.print("Temperature is: ");
  Serial.print(sensors.getTempCByIndex(0)); // Why "byIndex"?
    // You can have more than one IC on the same bus.
    // 0 refers to the first IC on the wire
    delay(1000);
}

After doing all this I am getting this output on serial monitor.

At which step I am doing wrong?

Could you make a change to a 'schematic' to show your connection? How do you actually connect 2 wires? (Your current schematic has 3 connections between sensor and Arduino, and sensor on your picture has only 2 wires..)
Are you aware of the fact that you want to use 'parasite power mode'? In this case you must provide strong pull-up for temperature conversion time.
Take a look at https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf page 11, 'Convert T [44h]' paragraph...

What type or name of the model is your temperature sensor.? It looks like you're trying to connect an analog sensor. But you use the connection schema and code for the digital sensor.

Which model temperature sensor you using?
If you using lm35 temperature sensor,
Serial.print(sensors.getTempCByIndex(0)/9,31); you need add /9.31 to your code, sensors not directly measure the temperature sensors just have variable resistor inside, resistor value changes by temperature after then voltage changes the arduino just measure the voltage, the voltage value divide the 9.31 this result gives temperature Celcius type.
Also you have to unplug 4.7 k resistor it needless.

Oh, indeed. karanrp: I have assumed you are using DS18B20. Check your sensor first.

That looks like a cheap thermocouple from a digital thermometer to me. You need a special chip to run it.

The -127 for your temperature reading is actually the error code for DEVICE_DISCONNECTED_C.
In the library's example code, they put an if that checks for this error code before printing the temperature:
if(tempC != DEVICE_DISCONNECTED_C)
{
  Serial.print("Temperature for the device 1 (index 0) is: ");
  Serial.println(tempC);
}

Since your sensor has only 2 wires, according to Wikipedia, you need a capacitor to power the sensor:

One distinctive feature of the bus is the possibility of using only two wires — data and ground. To accomplish this, 1-Wire devices include an 800 pF capacitor to store charge and power the device during periods when the data line is active.

This should hopefully resolve your issues.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Compilation Error - Yellow LED blinking as I have installed & connected Arduino UNO board to Windows XP PC
This is the first time when I have installed Arduino IDE (arduino-1.8.10-windows.exe) in my Win. XP SP-3 OS and it seems that the Arduino IDE software installation is successful without any hitch.
After restarting the PC, connected it  with Arduino Uno board through USB-Printer cable provided with the board and then selected Arduino Uno, Selected Port: COM3 (Arduino/Genuino Uno) - as I have verified in the Device Manager that the Arduino Uno installed in COM3 port.
As soon as I have connected Arduino Uno board to my PC, the yellow LED started blinking slowly. As I have tried uploading the sketch -  File>Examples> 01.Basics>Blink - there is an Error message that says, "Error compiling for board Arduino Uno" - even though the yellow LED still kept blinking without a reasonable act from my side.
So, where have I gone wrong - either in performance or in understanding? And is there any suggestion for making things right?
I thank you.
// the setup function runs once when you press reset or power the board
void setup(){

  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

}

// the loop function runs over and over again forever
void loop(){

  // turn the LED on (HIGH is the voltage level)
  digitalWrite(LED_BUILTIN, HIGH);

  // wait for a second
  delay(1000);

  // turn the LED off by making the voltage LOW
  digitalWrite(LED_BUILTIN, LOW);

  // wait for a second
  delay(1000);

}

Please edit your question to add the sketch or any new information, rather than putting it in comments. Even the "Auto format" feature in the IDE couldn't fix the code mis-alignment. I've formatted your sketch and added it to the question. Using comments before the line of code and proper line spacing make the code easier to read and find problems.

The yellow LED may be flashing because there may be a "Blink" LED program pre-installed on the Arduino.
To diagnose the "Error compiling for board Arduino Uno", we need to see the sketch you are trying to upload, and detailed error messages. If you go to Arduino > Preferences, check the "compilation" and "upload" checkboxes beside Show verbose output during:. Display line numbers is another checkbox you could enable.


text:
Comparing a text string to text output (DHT22)
Lately I've received a DHT22 sensor. I've started to create a small temperature and humidity monitor station. One of the things I noticed was if you pulled out the sensor while in use, it displayed "nan". What I wanted to do was if the variable "temp" (for the temperature) equaled "nan", my LCD would display a message. But I keep getting a scope, conversion, and declaring errors. I've tried every variable and a lot of online forums, documentations, and the official Arduino reference site. My code looks like this:

#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <LiquidCrystal.h>

const int rs = 53, en = 51, d4 = 49, d5 = 52, d6 = 48, d7 = 47;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

#define DHTPIN 27
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

int chk;
float hum;
float temp;

byte bigdot[8] = {
  B00000,
  B00000,
  B00000,
  B01110,
  B01110,
  B01110,
  B00000,
  B00000
};

byte circle[8] = {
  B00110,
  B01001,
  B01001,
  B00110,
  B00000,
  B00000,
  B00000,
  B00000
};

void setup() {
  lcd.createChar(0, bigdot);
  lcd.createChar(1, circle);
  lcd.begin(16, 2);
  dht.begin();
  do {
  lcd.setCursor(5,1);
  lcd.write(byte(2));
  lcd.setCursor(4,0);
  lcd.print("Loading");
  delay(500);
  lcd.clear();
  lcd.setCursor(7,1);
  lcd.write(byte(2));
  lcd.setCursor(4,0);
  lcd.print("Loading");
  delay(500);
  lcd.clear();
  lcd.setCursor(9,1);
  lcd.write(byte(2));
  lcd.setCursor(4,0);
  lcd.print("Loading");
  delay(500);
  lcd.clear();
  dht.readHumidity();
  dht.readTemperature();
  } while (hum > 90 || temp > 50.00);
  Serial.begin(9600);

}

void loop() {
    hum = dht.readHumidity();
    temp = dht.readTemperature();
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Temp: ");
    lcd.print(temp);
    lcd.write(byte(1));
    lcd.print("C");

    lcd.setCursor(0,1);
    lcd.print("RH:   ");
    lcd.print(hum);
    lcd.print("%");

    if (temp == a) {
      lcd.clear();
      lcd.home();
      lcd.print("Whoops! An");
      lcd.setCursor(0,1);
      lcd.print("error occured!");
    };
    Serial.print("Humidity: ");
    Serial.print(hum);
    Serial.print(" %, Temp: ");
    Serial.print(temp);
    Serial.println(" Celsius");
    delay(2000); //Delay 2 sec.
 }

Thanks in advance!

please add the full error message to your post

A "float" number has multiple possible states, besides just being a number (It never, though, can be compared to a string):

A real floating point number
Infinity
Something that isn't a valid number

The latter is what you want - that is, the internal data of the float variable doesn't represent a valid number.
There are two functions in the standard math library that deal with this for you.

Is the number infinity? ininf(x)
Is the number invalid? isnan(x)

To use it:
if (isnan(temp)) {
    lcd.print("Invalid");
}


text:
Analog pins giving off the same value
So recently I made code that used two custom sensors that are connected to the analog pin A0 & A5. Schematic can be seen here (http://inmoov.fr/test-your-finger-sensor/).
const int ono = A0;
const int twe = A5;

int one;
int two;

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

  }

void loop() {
  one = analogRead(ono);
  two = analogRead(twe);

  Serial.print(one);
  Serial.print(" ");
  Serial.println(two);

}

So after I follow the schematic i did the code, but the data value from the Serial Plotter of both sensors are always equal even though I was only pressing down on one sensor. So is this a code problem or the circuit? if so is there any fix for it? Thx.

Try using pinMode(one, INPUT); and pinMode(two, INPUT); in setup()

Ok ill try that, ill get back to you in a bit

Could you show us some of those values?

It sounds like a circuit problem. Care to share your circuit, not a link to some circuit you think you made?

Ok i edited my post

@PurnawanBrillian This connection is wrong. You havecto connect it like resistor voltage divider.

how many Ohms do you recommend? I did try 1K and 10K it still doesnt work, look at image 3

@PurnawanBrillian It's good to use +- similar resistivity as sensor has.

@Matej yup I did try that did a 220 Ohm resistor on both the - and +, still didnt work

I also did try changing my arduino and my breadboard and the problem still occurs, so it should not be any hardware problems

When the sensor isn't a FSR, what is it?


text:
Is not it possible to use more than 3 output pins in ESP8266 at the same time?
I'm trying to make a WiFi controlled Car from my old toy car which will be running on ESP8266. I'm using the L298N motor driver and have one motor for left-right control & other for forward-backward direction control.
Now the problem is I'm unable to use more than 3 pins at once. If I even try, likely my code stops working.
Below is my code :
static const uint8_t enFront   = D0;
static const uint8_t front_in1 = D1;
static const uint8_t front_in2 = D2;
static const uint8_t enBack    = D5;
static const uint8_t back_in1  = D3;
static const uint8_t back_in2  = D4;

#include <ESP8266WebServer.h>

const char* ssid = "espCar <^_^>";
const char* password = "hacksAllowed";

  ESP8266WebServer server(80);

void setup() {
  pinMode(enFront,OUTPUT);
  pinMode(front_in1,OUTPUT);
  pinMode(front_in2,OUTPUT);
 /* pinMode(enBack,OUTPUT);   <--Problem here
  pinMode(back_in1,OUTPUT);   <--Problem here
  pinMode(back_in2,OUTPUT);*/ <--Problem here

   Serial.begin(115200);
  WiFi.softAP(ssid, password);
  WiFi.mode(WIFI_AP);
  delay(500);
  server.on("/REQ",processRequest);
  server.begin();
  Serial.println("Server is UP!");
}

void loop() {
 // server.handleClient();
  analogWrite(enFront,1023);
  digitalWrite(front_in1,HIGH);
  digitalWrite(front_in2,LOW);
  delay(2000);
  digitalWrite(front_in2,HIGH);
  digitalWrite(front_in1,LOW);
  delay(2000);
}

void processRequest() {
 /* if (server.arg("move")!=""){
    if (server.arg("right")!=""){
      analogWrite(enFront,server.arg("right").toInt());
      digitalWrite(front_in1,HIGH);
      digitalWrite(front_in2,LOW);
      /*Debug*/
    /*  server.send(200, "200", server.arg("right"));
    }else if(server.arg("left")!=""){
      analogWrite(enFront,server.arg("left").toInt());
      digitalWrite(front_in1,LOW);
      digitalWrite(front_in2,HIGH);
      /*Debug*/
     /* server.send(200, "200", server.arg("left"));
    }
  }*/
}

All code working fine until I declare pinMode(pin,OUTPUT) for any 4th pin. (Everything is ok for every pin till 3rd one is declared)
I'm not so old with ESP or Arduino. So, please help by giving some clarification on this.

Schematic:

simulate this circuit – Schematic created using CircuitLab
Sorry for the mistake of making both motors tagged 2, → one is M1 & other is M2

scheme? (why did you add tags for other boards? I removed them)

ok. on the scheme you have a NodeMcu with Dx labels, in the code you use io pin numbers. you can use Dx constants in code.

pins io 0 and io 2 must be HIGH at boot. it is possible that wiring them to the driver board pulls them down.

Ok. Actually I used System.println to print out D1 to D5 then used them

Ok. Then I will test by keeping them HIGH at BOOT... I think that's happening here. Because adding those last 3 pinMode lines blocking me up.

on the scheme you have D2 (4), D3 (io 0), D4 (io 2) wired

I'm using other pins. It looks nearly to the sceme but not exact. To simplify wiring and push up everything in a small place I did that. :-(

Why can't you draw a schematic that is what you actually have?  You might as well show nothing as to show something that isn't true.

@Delta_G I didn't know about the scematic maker here. *I assume that you've already seen that the site has told me as new contributor

@jsotola I didn't know about the scematic maker here. I assume that you've already seen that the site has told me as new contributor . I knew the code would be enough to diagnose the problem. Next time I ask a question here I'll keep that in mind and I just updated a exact schema

In my project I have 4 relays, PWM output, tone() output, 2 output pins for LED bar, I2C ADC, temperature sensor on A0 and a button. that all on Wemos D1 R2 which has the same io to Dx mapping as NodeMcu

@Juraj Thanks for the support! I've found out what my mistake was

I almost asked if you did connect the groud, because you don't have it in the schema. I magnified the photo from first version of your question and there were black wires so I thought that was the ground connection. Or are those only shadows?

It was my first time on this site. So, there was mistake asking the question, I agree. I even didn't know about the schematic maker here. So, took one nearly same and placed it on the question.
If I've placed the question correctly it won't take much time to get answered. I'll remember these the next time I ask here. :-D

I found out the problem & it has nothing to deal with ESP8266. It was something like voltage conflict (I don't know the deeper science, I agree).
Actually, I was testing by plugging in the USB to ESP & at the same time I had a 11V lipo connected to L298N.
I tested by using one single voltage source & everything worked fine.
It looked something like this (It → the wrong one here):

simulate this circuit – Schematic created using CircuitLab

It is acceptable to connect two DC voltage sources like this, except that you should connect the GND connections together.

I did the same but didn't make the GND together & likely that was the problem


text:
What would be the best way of dynamically 'change' instances regarding dynamic memory?
Since I'm very used to object oriented programming, I would like to use this into my design.
My application will have 4 led strips and each led strip will have a 'pattern' running on it. For this I like to create a base class and for each pattern a derived class. So this means I have 4 instances to a pattern. However, the pattern can change dynamically (based on music MIDI input). Each pattern has between 10-16 parameters.
I know dynamic memory allocation is mostly not a good idea in an Arduino. I'm using a Mega which has 8 KB. I found several 'solutions' but neither one I'm sure about. The first is not the solution but the way I should do it when I have 'plenty' of SRAM available (and simplified):
class Pattern
{
   public:
      virtual void Process();
}

class PatternA: Pattern
{
   public:
      void Process();

      // In example I only use 2 out of 10-16 parameters
      uint8_t SetColor(uint8_t colorIndex);
      uint8_t SetSpeed(uint8_t speed);

   private:
      uint8_t _colorIndex;
      uint8_t _speed;
}

// In this example I only use 2 out of 24 patterns
class PatternB: Pattern
(like PatternA but with its own implementation)

class LedStrip
{
   public:
       void SetPattern(Pattern* pattern);

   private:
       Pattern* _pattern;
}

Other derived classes may have other (named) parameters.
When changing instances, I would get something like this:
LedStrip::SetPattern(Pattern* pattern)
{
    delete _pattern;
    _pattern = pattern;
}

pattern* pattern = new PatternA(...);
ledStrip1.SetPattern(pattern);

However, since the new pattern may use more memory then the deleted pattern, there will be a memory gap. So this is not suitable for the Arduino to be used I assume.
Solutions:
1. Create all possible patterns beforehand.
Assume I would implement 24 patterns, and create any possible combination, I would have 4 (led strips) * 24 (patterns) * 13.5 (average number of parameters) = 1,296 bytes. This seems a bit much as only 4 are 'active'.
class LedStrip
{
   public:
      enum EPattern {A, B}

      void SetPattern(EPattern pattern);

   private:
      PatternA* _patternA;
      PatternB* _patternB;

      Pattern* _pattern;
}

To change pattern:
void LedStrip::SetPattern(EPatternpattern)
{
case EPatternA: _pattern = _patternA; break;
case EPatternB: _pattern = _patternB; break;
}

ledStrip1.SetPattern(EPattern::A);

Of course I could also pass a pattern where the patterns are created globally but this is does not matter for this example. The idea is to create 4 (led strips) * 24 (patterns) instances beforehand and never use delete. This means out of the 4 * 24 patterns, only 4 are used, 1 per led strip.
Of course this causes a lot of unused memory.
2. New/Delete
I create the 4 correct derived instances and when one pattern (instance) change, I delete the instance and create the new. When I put no (instance) variables in the derived class, this could work, but I have some specific questions regarding this solution:
I make sure all the max. parameters are in the base class and I 'cast' 4 instances of the base class to a derived class. This seems a bit of 'tricky' solution.
class Pattern
{
   public:
      SetParameter(uint8_t parameter, uint8_t parameterValue);
      uint8_t parameter GetParameter(uint8_t parameter);

   private:
      uint8_t _parameters[16];
}

class PatternA: Pattern
... (does not have any variables)

To change pattern:
delete ledStrip1.pattern;
ledStrip1.pattern = new PatternA();

Question: can I assume the deleted memory of the old pattern will be replaced by the new pattern as the memory usage is equal?
The downside of this way is that each pattern will have the worst-case amount of parameters in each instance, but this is not a problem (I only have 4 led strips).

Comments are not for extended discussion; this conversation has been moved to chat.

I don't know what you'll make of this, but:
If you can set aside a properly aligned and sufficiently large memory block you can use the placement form of the new operator.
Placement new is essentially new without the the part that behaves like (and typically is) malloc.  Or put differently, it lets you construct an object inside of already allocated memory.  By "already allocated" I don't mean already allocated on the heap; the memory can come from whereever you want.  This more or less lets you make your own custom allocator with predictable behaviour that you don't get from generic heap allocator like malloc.
So you can set aside memory however you want.  It can be an array of unsigned char in static storage duration (global, static local, static member).  And placement new can put an object into it, or importantly, into part of it.  Basically you're making your own arena for your allocator.
It's up to you to align the memory correctly.  There are compiler keywords that can help with that.  You can also resort to an older technique oversizing the block just large enough so that a properly aligned sub-block exists and can be found within it.  However, on an 8-bit microcontroller like the AVR, there are no alignment requirements to speak of.
When it comes to using delete, well, you don't.  You just call the destructor on the object directly.  There are ways you could try to clean that up also.
If I become awake enough to completely understand your specific usage, I may try to make an example.  But that is the basic technique I'd consider.

Regarding avoiding new/malloc: the case against them it is often slightly overstated.  For example, doing a set of malloc / new at the beginning, and only the beginning, of your program and not thereafter is normally fairly stable and predictable.  For example, you can read a configuration out of eeprom in setup() and use that information to allocate say three "dynamic" "arrays" with malloc, that you know they won't total more than some testable maximum.  Maybe a slightly more accurate warning for them is something like: you will get into trouble if you don't have a reasonable understanding of your maximum heap usage and if your usage pattern requires that you free/delete/remalloc.
I mention this in part also because it's not completely unreasonable to malloc/new once, early in your execution, to acquire an arena to use with placement new calls.

Thanks for all this info ... I also need to go through a few times through it (not heard of placement new before).

If you've ever wondered what something like std::vector is doing when you resize() to larger than current size, size() well, that's basically it.   For the new elements where the vector was extended, it's placement new-ing with T's the default constructor into memory it basically realloc()d.  Where the vector is resized smaller, it is manually calling the destructors of those elements that go away.

If you can tightly nail down what you want to do at runtime, you may find your design approaching something vaguely like a container, only fixed capacity (not necessarily size) and handles containment of two or three types as opposed to just one.

I knew about reallocating/keeping the size for bigger/smaller vector, but not about the placement new. About the container, that's indeed true. I could make it easily workable with a big switch statement, but I'm planning to create more patterns (derived classes) to chose from, and like to keep them isolated (thus using derivation instead of some switches.

Yeah, I read something in your question that indicated an understanding of heap usage patterns.  But it's something I wanted to spell out for anyone reading the answer.  I might have left that part out entirely except for wanting to mention that reserving your own arena through the general heap allocator is not unreasonable, in my opinion anyway.

Regarding "vaguely like a container", I was more speaking of how it manages its own memory.  Not so much what the interface looks like.

Yes I understand ... I will check this evening some ideas to see what works.

I tried the placement new and it works. I use a Max(sizeof(...), sizeof(...), sizeof(...)) for each derived type so I only have the derived classes in one place, which is part of the factory to create the different derived instances.
Tip for others: don't forget to #include <new>

Good deal.  If I understand correctly the way you've chosen to employ this is roughly like what I expect the internals of an std::variant do.  That was the sort of example I'd thought to make for you, but I wasn't quite sure whether or not you were willing to accept the overhead of sizing items to the largest type and therefore would have needed something more complicated but otherwise using placement new.

Let us continue this discussion in chat.

When I need dynamically allocate memory, I generally pre-allocate a pool of memory blocks, each sufficiently large for the maximum size request I'll handle. Then, Whether the app requests 1 byte or MAXSIZE bytes, it gets a pointer to the first available one of those MAXSIZE blocks in the pool. free()ing such a block works just as you'd expect. Since all allocations are the same size, and no more memory is ever taken from the real heap, the pool doesn't have to (and can't, in my implementation) grow.
If this is the only dynamically allocated memory for your application, you can re-write new() and delete() to use your pool-allocator, or, if new() and delete() are implemented as wrappers around malloc() and free(), just replace those more primitive ones with the pool-based malloc() and free().

Thanks for the answer, I used placement new which works great in my case. In my case I only have 4 fixed elements (which will now be 'new'ed all the time and destructed, but not deleted).

Since you only need four objects at any given time, it would be wasteful
to statically allocate 4×24 objects, as you only really need four times
the size of the largest object. You can still use static allocation by
using an array of unions: each cell of the array will then be large
enough to store the largest possible pattern.
There may be more elegant solutions, but the simple approach is to use a
tagged union, i.e. a struct holding both a union and an extra variable
telling you what data type the union is actually holding. Beware that
there are limitations on what type of objects you can put in an
union. You should be safe if the actual classes have trivial
do-nothing constructors.
Below is a simplified example with two classes that each hold only a
number, either an uint8_t or a uint16_t:
class Pattern
{
public:
    virtual void process();
};

class Pattern8 : public Pattern
{
public:
    void process() { Serial.println(8000 + param); }
    void set_param(uint8_t param8) { param = param8; }
private:
    uint8_t param;
};

class Pattern16 : public Pattern
{
public:
    void process() { Serial.println(16000 + param); }
    void set_param(uint8_t param16) { param = param16; }
private:
    uint16_t param;
};

// This is the tagged union.
struct AnyPattern : public Pattern
{
    AnyPattern() {}  // must be explicitly defined
    void process() {
        switch (type) {
            case TYPE8: pattern8.process(); break;
            case TYPE16: pattern16.process(); break;
        }
    }
    enum { TYPE8, TYPE16 } type;
    union {
        Pattern8 pattern8;
        Pattern16 pattern16;
    };
};

void setup() {
    AnyPattern patterns[2];
    patterns[0].type = AnyPattern::TYPE8;
    patterns[0].pattern8.set_param(21);
    patterns[1].type = AnyPattern::TYPE16;
    patterns[1].pattern16.set_param(42);
    Serial.begin(9600);
    patterns[0].process();
    patterns[1].process();
}

void loop(){}

I upvoted, although I don't like the union solution that much to be honest, although it works. I used the placement new method which works great for me.

Pattern classes are code and variables for the current set of parameters. The code doesn't take SRAM it is executed from flash. I would instance all 24 patterns for all 4 LED strips using global two dimensional array.
Advanced version could be a pool of pattern instances allocated with 'new' but never deleted, only reused. You would only create a new pattern class instance of requested type, if there is no free pattern instance of that type in the pool.
The parameters sets could be stored in PROGMEM or in EEPROM and loaded as needed into the variables of the corresponding pattern class instance.

For the advanced version idea, I doubt that will work to be honest. In worst case I need 4 of each (pattern class) instances, running out of memory (or using a lot of it).
Maybe it was not clear, but the parameters are flexible, meaning I could have 20 pattern class instances for a single pattern, with all different parameters. The parameter sets can be stored in EEPROM/PROGMEM, but the parameters need to be copied to memory (to four instances). But maybe my question is not really clear.

@MichelKeijzers, can't you load the parameters in an existing unused pattern class instance? as I understand there are only 4 active patterns. so in worst case the pool would contain 4 x 24 pattern objects

Yes, but that's too much ... 4 * 24 patterns * 16 (parameters) = 1,536 bytes which is quite a bit. Especially since there will be needed some other values to be stored as well.


text:
Start / end events using milis
I want to start a relay, have it run for 3 seconds, stop for 10 seconds, repeat.
I can't use delay, because I have a motor driver starting / stopping every 100 milis.
So I put together this code, but it does not work. Any help appreciated.
There's a 500ms delay to stop too much debugging info.
Also for some reason, tenSecondsBool switches to true as soon as you run the code.
unsigned long threeSeconds=3000; // the time we need to wait
unsigned long threeSecondsMillis=0; // millis() returns an unsigned long.
unsigned long fourSeconds=7000; // the time we need to wait
unsigned long fourSecondsMillis=0; // millis() returns an unsigned long.

unsigned long previousMillis=0; // millis() returns an unsigned long.
bool ledState = false; // state variable for the LED
bool led2State = false; // state variable for the LED
unsigned long tenSecondMilis=0; // millis() returns an unsigned long.
unsigned long tenSeconds=10000; // the time we need to wait

unsigned long paliGasiMilis=0; // millis() returns an unsigned long.
unsigned long paliGasi=1000; // the time we need to wait

unsigned long ventMilis=0; // millis() returns an unsigned long.
unsigned long ventInt=100; // the time we need to wait

bool threeSecondBool = false;
bool tenSecondBool = false;

int Fin1 = D7;

#define enA D1
#define in1 D2
#define in2 D3
#define button 4

int rotDirection = 0;
int pressed = false;

void setup() {
  Serial.begin(9600); // send and receive at 9600 baud
  pinMode(enA, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(button, INPUT);
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  pinMode(Fin1, OUTPUT);
  digitalWrite(Fin1, HIGH);
  threeSecondBool = false;
  tenSecondBool = false;
}

void loop() {

 unsigned long currentMillis = millis(); // grab current time

 if ((unsigned long)(currentMillis - tenSecondMilis) >= tenSeconds) {
    Serial.print("---------------\n");
    Serial.print("10 second end\n");
    Serial.print("---------------\n");
    tenSecondBool = true;
    tenSecondMilis = millis();
}

Serial.print("10 second bool = ");
Serial.print(tenSecondBool);
Serial.print("\n");
Serial.print("3 second bool = ");
Serial.print(threeSecondBool);
Serial.print("\n");

 if (tenSecondBool) {
  if ((unsigned long)(currentMillis - threeSecondsMillis) >= threeSeconds) {
   Serial.print("---------------\n");
   Serial.print("3 second end\n");
   Serial.print("---------------\n");
   threeSecondBool = true;
   threeSecondsMillis = millis();
  }
 }

if (!tenSecondBool && threeSecondBool){
  Serial.print("Both triggered!\n");
  digitalWrite(Fin1, HIGH);
}

if (!tenSecondBool && !threeSecondBool){
  Serial.print("Both triggered!\n");
  digitalWrite(Fin1, HIGH);
}

if (tenSecondBool && threeSecondBool){
  threeSecondBool = false;
  tenSecondBool = false;
  digitalWrite(Fin1, LOW);
}

delay(500);

  if ((unsigned long)(currentMillis - ventMilis) >= ventInt) {
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    ventMilis = millis();
  } else {
    digitalWrite(in1, LOW);
    digitalWrite(in2, HIGH);
  }

}

If you want a timer with millis with different intervals, then you can change the interval.
I use the Blink Without Delay to start with, and I borrow the 'relay_is_on' from the answer by Edgar Bonet.
unsigned long previousMillis;
unsigned long interval;
bool relay_is_on;

void loop() {
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    if (relay_is_on) {
      // Relay was on, now turn it off.
      interval = 10000;
      digitalWrite (relayPin, LOW);
      relay_is_on = false;
    } else {
      // Relay was off, now turn it on.
      interval = 3000;
      digitalWrite (relayPin, HIGH);
      relay_is_on = true;
    }
  }
}

The global variables can be set to a value to start with (for example 3000 for the interval) or they can be set in the setup() function. You have to choose what you want to start with. For example one second or one minute delay before it starts is also possible.

Your code is somewhat confusing, probably because it has too many
variables. For doing what you describe, the program only needs to
remember two things:

is the relay in the ON state or in the OFF state?
when was the last time the relay changed state?

These can be represented as follows:
bool relay_is_on = false;
unsigned long last_relay_change = 0;

Then, I recommend you use descriptive names for your variables and
constants. Calling a constant threeSeconds is not useful. It has no
added value over just typing 3000. Having the constant named
RELAY_ON_TIME makes it a lot clearer what it is intended for. It is a
common convention to name the constants with all caps to make them stand
out relative to variables:
const uint8_t RELAY_PIN = ...;
const unsigned long RELAY_ON_TIME  =  3000;  //  3 s ON
const unsigned long RELAY_OFF_TIME = 10000;  // 10 s OFF

With this in place, periodically switching the relay on and off can be
achieved as follows:
void loop()
{
    unsigned long now = millis();
    if (relay_is_on && now - last_relay_change >= RELAY_ON_TIME) {
        // Turn off.
        digitalWrite(RELAY_PIN, LOW);
        relay_is_on = false;
        last_relay_change = now;
    }
    if (!relay_is_on && now - last_relay_change >= RELAY_OFF_TIME) {
        // Turn on.
        digitalWrite(RELAY_PIN, HIGH);
        relay_is_on = true;
        last_relay_change = now;
    }
}


text:
HC-05 sending data to Android a value but it cracked out of its form
I am totally beginner but I am trying to finish my project as school work :-(
but from the beginning, I am really stuck.
Could anyone help me out?
#include <SoftwareSerial.h>
SoftwareSerial BTserial(10, 11); // RX | TX

void setup() {
  // initialize serial communication at 9600 bits per second:
  BTserial.begin(9600);
}

void loop() {
  // read the input on analog pin 0:
  int sensorValue1 = analogRead(A0);
  int sensorValue2 = analogRead(A1);
  BTserial.print(sensorValue1);
  BTserial.print('|');
  BTserial.println(sensorValue2);
  delay(50);
}

The received value is here
D/BluetoothConnectionSrv: InputStream: 955|108
D/BluetoothConnectionSrv: InputStream: 9
D/BluetoothConnectionSrv: InputStream: 46|51
D/BluetoothConnectionSrv: InputStream: 9
D/BluetoothConnectionSrv: InputStream: 47|57

I need only values from 2 sensors, it seems to be as
    D/BluetoothConnectionSrv: InputStream: 955|108
    D/BluetoothConnectionSrv: InputStream: 946|51
    D/BluetoothConnectionSrv: InputStream: 947|57
I've tried to send "How are you?", then the result in the app was this
D/BF: o
D/BF: u ?Are yo
D/BF: u ?
D/BF: H
D/BF: ow Are you
D/BF:  ?

Source code in my app
        bluetoothSocket = socket;
        InputStream tempIn = null;
        OutputStream tempOut = null;

        try {
            tempIn = bluetoothSocket.getInputStream();
            tempOut = bluetoothSocket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }

        inputStream = tempIn;
        outputStream = tempOut;
    }

    public void run(){
        byte[] buffer = new byte[1024];
        int bytes;

        while(true){
            try {
                bytes = inputStream.read(buffer);
                handler.obtainMessage(STATE_MESSAGE_RECEIVED, bytes, -1, buffer).sendToTarget();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

            case STATE_MESSAGE_RECEIVED:
                byte[] readBuff = (byte[]) msg.obj;
                String tempMsg = new String(readBuff, 0, msg.arg1);
                tvMessage.setText(tempMsg);
                Log.d("BF",tempMsg);
                break;

it could be caused by the android app ....... one thing you could try with your program is to change the BTserial.println command to BTserial.print

That extra number is probably associated to println where it appends a new line character, although CR/LF should be 0x0D/0x0A...


text:
HTTP PUT method on NodeMCU/ESP8266
I've been trying to send a put request from my esp8266 for a while not but I can't figure out why it doesn't work and there are barely any posts about put requests online
I keep getting errors around int httpCode = http.sendRequest("PUT", String(data));
Error log: https://gist.github.com/dkbay/ab3fedf5e89d841d25b24fb829df74ef
#include <ESP8266HTTPClient.h>

#define LED_BUILTIN 2

const char* ssid     = "Some SSDI";
const char* password = "Some wifi password";

int wifiStatus;

void setup() {

  Serial.begin(115200);\
  pinMode(LED_BUILTIN, OUTPUT);
  delay(200);

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Your are connecting to;");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    digitalWrite(LED_BUILTIN, LOW);
    delay(500);
    digitalWrite(LED_BUILTIN, HIGH);
    Serial.print(".");
  }

}

void loop() {
  wifiStatus = WiFi.status();

  if(wifiStatus == WL_CONNECTED){

    HTTPClient http;

    http.begin("http://google.com/");
    http.addHeader("Content-Type", "application/json");
    String data = "{\"on\":false}";
    int httpCode = http.sendRequest("PUT", String(data));
    String payload = http.getString();

    Serial.println(httpCode);
    Serial.println(payload);

    http.end();
     Serial.println("");
     Serial.println("Your ESP is connected!");
     Serial.println("Your IP address is: ");
     Serial.println(WiFi.localIP());
  }
  else{
    Serial.println("");
    Serial.println("WiFi not connected");
  }
  delay(1000); // check for connection every once a second

}

what should it do and what does it? Shouldn't 'false' in json be in ""?

@Juraj It wasn't in quotes when I made it in node... It should send a "PUT" request to my hue lights to update them but instead it htrows this error https://gist.github.com/dkbay/ab3fedf5e89d841d25b24fb829df74ef

it doesn't compile,
not "doesn't work". use  sendRequest("PUT", data.c_str());

HTTPClient http;
http.begin("http://google.com?on=false");
http.addHeader("Content-Type", "application/json");
int httpCode = http.sendRequest("PUT", "");
String payload = http.getString();

try with this code, if server .php,
get data by $_REQUEST


text:
Using an Android bluetooth terminal to change preset states on 8x8 LED matrixes
I'm trying to create eyes for a project, and while I have been able to properly program the different expressions, and have them triggered by commands from the COM3 terminal, I have not been able to make any commands from the Bluetooth Terminal on my phone work.
Details:
Mega2560
2x 8x8 LED Displays - MAX7219
HC-05 Bluetooth Transceiver - default Baud - 9600
Using LEDControl.h, SoftwareSerial.h
This is the loop on my device, when I type the commands A, B, etc. into the COM3 terminal it works just fine, but the same commands on the phone are just interpreted as ASCII, even when I put parentheses around them.
void loop()
{
  // Feed any data from bluetooth to Terminal.
  if (EEBlue.available()){
  Serial.write(EEBlue.read());
  }
  if (Serial.available())  //verifies if there is serial data available
  {
    char cmd = Serial.read();

    if(cmd == 'A') {
      display_eyes(eye_neutral_l, eye_neutral_r);
    }
    if(cmd == 'B') {
      display_eyes(eye_shock_l, eye_shock_r);
    }
    if(cmd == 'C') {
      display_eyes(eye_love_l, eye_love_r);
    }
    if(cmd == 'D') {
      display_eyes(eye_suspicious_l, eye_suspicious_r);
    }
    if(cmd == 'E') {
      display_eyes(eye_happy_l, eye_happy_r);
    }
    if(cmd == 'F') {
      display_eyes(eye_hurt_l, eye_hurt_r);
    }
    if(cmd == '1') {
      display_eyes(eye_mad_l, eye_mad_r);
    }
  // Feed all data from termial to bluetooth
  EEBlue.write(Serial.read());
  }
}

The serial data, that you use in your Arduino program, is checked against ASCII values, so you actually really need to send ASCII. What exactly to you mean by "are interpreted as ASCII" on the phone? What terminal program do you use on the phone? And what data output do you get on the PC terminal, when you send data over bluetooth? You are echoing it there, so you should be able to see, what is actually received on the Arduino.

Oh, I just saw, that you only react to command with eye expressions, when there is something on Serial, which as I assume is connected to the PC. When there is data on the EEBlue interface, you just echoing it to Serial, but you don't process it.

So do I need to add something like char cmd = EEBlue.read(); ?

Your problem is, that you read from the EEBlue serial interface, but you are just echoing it over Serial and don't do anything with it. The display code is only executed, when the commands come through Serial.
The simplest way is to copy the code in the if(Serial.available()) statement into the if(EEBlue.available()) statement and changing the read to use EEBlue. Of course you should delete the existing EEBlue.read() from this statement.
But that way would mean to have double the code to maintain. It is cleaner to first read data from either serial interface and then process it. Something like this:
if(Serial.available()){
    cmd = Serial.read();
} else if(EEBlue.available()){
    cmd = EEBlue.read();
}

// insert the code to check the cmd variable for the expected values and act accordingly

cmd = 0; // Resetting the cmd to prevent multiple executions of one command


text:
How to get more than the 16 Analog INs on a Arduino Mega for using like 24 piezo sensors
i bought an Arduino Mega2560 and flashed it with usbmidi. So now it comes up as a midi device.
I need more than those 16 analog ins to be able to put all my 24 piezo sensors into it to receive midi signals from it. I still have no idea how i have to put the piezo pieces into the arduino but also no clue as how to get more than those 16 analog slots. Any way to use the digital inputs as well or do i need some extension shield or so? I'm a total beginner with arduino...

When you are a total beginner, can you start with 16 piezo sensors? You could buy two arduino leonardo boards: https://www.arduino.cc/en/Main/Arduino_BoardLeonardo or use multiplexers: https://www.gammon.com.au/forum/?id=11976 or external ADC (as Michel Keijzers wrote in his answer). A digital pin for a piezo sensor is possible, but then you can not tune the level in software, so I prefer analog inputs.

I already have an Arduino Mega flashed with hiduino (
https://github.com/ddiakopoulos/hiduino) ... :/
Also it's for a setup with a lot of bells. A friend is making music (bells and chimes) which i want to connect the piezos to and then send midi signals to me to visualize the sounds^^

You can customize a controllino on their page
https://www.controllino.biz/controllino-myplc/
I just looked at it and it seems you can get 24 analog outputs.
Don't know what the cost is though.

You need one (or more) external ADC (analog digital converters).
For example the ADS1115, the link shows an Adafruit model and how to use it.
In a DIP format (to be used on breadboards/prototype boards) it will be hard to find a 16 channel ADC, but you can add multiple I2C (or other) 4 channel ADCs to one Arduino Mega.


text:
How to add numbers to a position when controlling a seven-segment display
I'm recently having a hard time with my Arduino project. I'm trying to control a seven-segment display (it has a microcontroller on it) with an encoder, and I'm trying so that everytime I rotate the encoder it adds 5 to the number on the display. What am I doing wrong here???
P.S: there are some parts that are for controlling relays, they are not related to the issue. I removed them on this thread on purpose.
Code (without any attempts to change the added amount to the display):
#include <RotaryEncoder.h>
#include <TM1637Display.h>

// Module connection pins (Digital Pins)
#define CLK 10
#define DIO 11

// Setup a RoraryEncoder for pins A2 and A3:
RotaryEncoder encoder(A2, A3);

// The amount of time (in milliseconds) between tests
#define TEST_DELAY   1000

TM1637Display display(CLK, DIO);

void setup()
{
    Serial.begin(57600);
    Serial.println("SimplePollRotator example for the RotaryEncoder
    library.");
}

// The Interrupt Service Routine for Pin Change Interrupt 1
// This routine will only be called on any signal change on A2 and A3:
//exactly where we need to check.
ISR(PCINT1_vect) {
    encoder.tick(); // just call tick() to check the state.
}

// Read the current position of the encoder and print out when changed.
void loop()
{
    static int pos = 0;
    int newPos = encoder.getPosition();
    if(newPos > -1)
    {
        if (pos != newPos) {
            Serial.print(newPos);
            Serial.println();
            pos = newPos + 4;
            display.setBrightness(0x0f);
            // All segments on
            // Show decimal numbers with/without leading zeros
            display.showNumberDec(newPos, true); // Expect: 1234
            delay(100);
        }
    } // if
} // loop ()
// The End

You stated what you want it to do, but what does it actually do instead?

It instead just skips by one and not by 5 (the code which I published right here is without the attempt to do this

I'd mutliply the pos by five. So display.showNumberDec(pos*5, true). Then you need only this single like instead of the whole if statement (all 10 lines).

In your code, you call:
newPos = encoder.getPosition();

which grabs the absolute position of the encoder. When you rotate this one step, the value of newPos goes up (or down) by one.
Then, you make pos = newPos + 4, which simply adds 4 to the value that is going up or down by one step at a time.
newPos: 1    pos: 5
newPos: 2    pos: 6
newPos: 3    pos: 7
newPos: 4    pos: 8
newPos: 5    pos: 9

Instead, it sounds like you wish the display to always read 5 times the encoder position. If so, then you should write pos = newPos*5.
newPos: 1    pos: 5
newPos: 2    pos: 10
newPos: 3    pos: 15
newPos: 4    pos: 20
newPos: 5    pos: 25

Then, when you write to the display, you do so as:
display.showNumberDec(newPos, true); // Expect: 1234

But newPos is not the newly calculated value. Instead, call
display.showNumberDec(pos, true); // Expect: 1234

I think I tried that and to no avail, trying again now.
EDIT: Nope, still counts one at a time.

Well, you also need to write the correct value to the display: display.showNumberDec(newPos, true); tries to write newPos, but newPos is the encoder position. pos is the calculated display value. I will update my answer.

Thanks! It woroks like a charm now.

This is a classic debugging problem. You think you wrote your code to do one thing and what you wrote actually does something else. You need to add print statements that display the values you are using and then think through each line of your code, writing down the values of your variables at each step and pretending you're a computer. Look at the code that's written, and calculate the results of each line, not what you expect to happen. It is made much harder on microcontrollers where you don't have a debugger to work with.

Good eye Jose, catching the fact that the OP is displaying the encoder position rather than the calculated value. (Voted)


text:
Reading port register and print
I am playing with port registers directly to improve speed on a Arduino micro. I have no problem writing them, like
PORTF &= B11101111

However, when I try to read and print it, things get funny and I hope to know why.
Observation 0:
byte dat = PORTF;
Serial.print(dat,BIN);

produces a single 0, where I am expecting 8 0's as for a byte. And, even when I check that a digitalRead correctly gets a 1 from PF5 or A2,
Observation 1:
byte dat = PORTF;
Serial.print(dat,BIN);
Serial.print(dat,BIN);

produces a compiler error like
...cores\arduino\Print.cpp: In function 'println.constprop':
...cores\arduino\Print.cpp:143:1: internal compiler error: Segmentation fault
}
^

To reproduce your compiler problem, please post a minimized sketch showing the error. And tell us which PC system (Win, Linux, Mac) you're using. [edit] your question, don't put additional information in a comment, please!

the compiler error is the error of the compiler. use Arduino boards package 1.6.21. this is not the right way to work with registers. and PORTF &= B11101111 is PORTF = PORTF & B11101111. so if PORTF is all zeros, the result is zero

https://arduino.stackexchange.com/questions/70104/adc-register-always-returning-high/70108#70108

The compiler error is a compiler bug. What version of the IDE are you using? If it's not the latest, you may want to upgrade.

@EdgarBonet, it is a problem of avr-gcc used in Arduino AVR core 1.6.22 and 1.6.23. the version in AVR core 1.8.0 and 1.8.1 has the problem of 'over-optimizing'. (1.8.0 was next after 1.6.23. 1.7.x was skipped).

@Juraj: What do you mean by “over-optimizing”? Another compiler bug?

@EdgarBonet, this one https://arduino.stackexchange.com/questions/70597/function-parameter-of-type-int-not-working-as-expected#comment153249_70597 and one more was on Arduino Forum

The function Serial.print() and it's siblings cuts all leading zeros. So 0b00001111 get's displayed as 1111 and 0b00000000 as 0. So you actually get what you expect. It's just printing different.
Also, when reading PORTF, you actually read the output state of the pins, as you have set it before. If you want to read the real input level of the pins, you should read PINF instead.
Though I don't know, where that segmentation fault came from.


text:
WebSocketsServer.h: No such file or directory
I'm trying use the NodeMCU WebSocket.
I downloaded the required libraries from:
https://github.com/Links2004/arduinoWebSockets
and pasted them in my Arduino libraries folder. I uploaded my code but got this error:
WebSocketsServer.h: No such file or directory.
Can you please tell me why my Arduino IDE won't find the WebSocketsServer.h header file when it is physically present in my Arduino libraries folder?   Or if there's an alternative way to use the NodeMCU WebSocket?
Here's the code:

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <WebSocketsServer.h>
#include <Hash.h>

// Replace with your network credentials
const char* ssid = "<WiFi-SSID>";
const char* password = "WiFi-PASSWORD";

WebSocketsServer webSocket = WebSocketsServer(81);
ESP8266WebServer server(80);   //instantiate server at port 80 (http port)

String page = "";
int LEDPin = D5;

void setup(void){
 //the HTML of the web page
 page = "
Simple NodeMCU Web Server

<button>ON</button> <button>OFF</button>
";
 //make the LED pin output and initially turned off
 pinMode(LEDPin, OUTPUT);
 digitalWrite(LEDPin, LOW);

 delay(1000);

 Serial.begin(115200);
 WiFi.begin(ssid, password); //begin WiFi connection
 Serial.println("");

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

 Serial.println("");
 Serial.print("Connected to ");
 Serial.println(ssid);
 Serial.print("IP address: ");
 Serial.println(WiFi.localIP());

 server.on("/", [](){
    server.send(200, "text/html", page);
 });

 server.on("/LEDOn", [](){
    server.send(200, "text/html", page);
    digitalWrite(LEDPin, HIGH);
    delay(1000);
 });

 server.on("/LEDOff", [](){
    server.send(200, "text/html", page);
    digitalWrite(LEDPin, LOW);
    delay(1000);
 });

 server.begin();
 webSocket.begin();
 webSocket.onEvent(webSocketEvent);

 Serial.println("Web server started!");
}

void loop(void){
  webSocket.loop();
  server.handleClient();
  if (Serial.available() > 0){
    char c[] = {(char)Serial.read()};
    webSocket.broadcastTXT(c, sizeof(c));
  }
}

void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length){
  if (type == WStype_TEXT){
   for(int i = 0; i < length; i++) Serial.print((char) payload[i]);
   Serial.println();
  }
}
~~~

What is the exact structure, where you have the file in your libraries folder? Directly in there, or in a subfolder? What name for the subfolder?

I try to change that with #include "WebSocketsServer.h" and WebSocketsServer.h is on actual dir.

the library has formal issues to be detected by Arduino IDE. in library.properties the headers key is missing

after you included the zip file to library you must rename directory like this 'WebSocketsServer'. And then you copy all file in 'src' directory and then paste them to its parent directory (WebSocketsServer)

didn't work with me .. do you mean like this: ..\OneDrive\Documents\Arduino\libraries\WebSocketServer\src ?

The proper way is to add library into your Arduino IDE, it will just work.

Open the Arduino IDE
Go to Sketch > Include Library > Manage Libraries
Search for "WebSockets Sattler' and install the library named "WebSockets by Markus Sattler"
Restart the Arduino IDE.

PS

you will see two results for WebSockets library from the same author
the second "WebSockets_Generic" is a more lightweight library and it only provides support for WebSockets in the client mode (it is designed to be more memory efficient)

proper way would be to add WebSocketsServer.h to list of locations that gcc looks for. see: https://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC6
another way would be to download WebSocketsServer.zip from  https://www.arduinolibraries.info/libraries/web-sockets
to your workdir and unzip it
replace
#include <WebSocketsServer.h>

with explicit location
#include "./WebSockets-2.3.5/src/WebSocketsServer.h"

(note unziped version in this case is WebSockets-2.3.5)

relative paths don't work with Arduino builder. the build is executed in a temporary folder where the path is not valid. with Arduino we don't setup gcc.


text:
Wire SlaveReceiver : will the registered function in onRecieve interrupt/conflict with loop block?
I am currently researching on I2C, and I made a configuration that has MasterWriter that transmits data to a SlaveReceiver that will store the data received from Master, into an SD card, and then transmit the same line of data by GPRS onto my back end.
Now the new requirement needs some kind of a caching system, so that if the GPRS failed to transmit, it'll instead save into the SD card under a different filename (the previous step of saving into SD Card is still done but it's for another purpose), so when the GSM signal needed has recovered it'll read the cached/backed-up data, and then transmit the backed-up data. So that means I'll use the loop block (which currently only has one line of delay function).
My question is, will the triggered function "receiveEvent" registered in setup for Wire Slave :

Wire.onReceive(receiveEvent);

conflict with the ongoing loop block where the system reads the backed-up data and sends the backed-up data?
Here's my SlaveReceiver code :

#define ONLINE_MODE 1 //  turn on for GSM.
#define CACHE_MODE 1 //   turn on for SD-based caching
#define I2C_MODE 1  //    turn on for I2C mode SDA-SCL

#include <Arduino.h>
#include "Slave_GSM_SD.h"

#if ONLINE_MODE
// Sim900
#include "GSM.h"
SIM900 gprs;
#endif

#if I2C_MODE
#include <Wire.h>
#endif

#if CACHE_MODE
//SD Card
#include <SPI.h>
#include <SD.h>
#define DEBUG_SD 1
#define SD_CS_PIN 4
File cacheFile;
#endif

void setup()
{
    console.begin(9600);
    while (!console);

    #if CACHE_MODE
     //SD Card
    Serial.print(F("Initializing SD card..."));

    if (!SD.begin(SD_CS_PIN)) {
      Serial.println(F("initialization failed!"));
      while (1);
    }
    // open the file. note that only one file can be open at a time,
    // so you have to close this one before opening another.
    cacheFile = SD.open("CACHE.txt", FILE_WRITE);
    Serial.println(F("SD Card initialization done."));
    #endif

    #if ONLINE_MODE
    gprsSetup();
    #endif

    #if I2C_MODE
    Wire.begin(8);                // join i2c bus with address #8
    Wire.onReceive(receiveEvent); // register event
    #endif
    console.println(F("SLAVE GSM SD READY"));

}

// function that executes whenever data is received from master
// this function is registered as an event, see setup()
// [Q] : will this interrupt/conflict with loop() if loop is still ongoing?
void receiveEvent(int howMany) {
  #if DEBUG_I2C
  Serial.print(F("available bytes : "));
  Serial.print(howMany);
  Serial.print(F(" or "));
  Serial.println(Wire.available());
  #endif

  #if I2C_MODE
  char jsonData[128]="";
  while (Wire.available()) { // loop through all but the last
    char c = Wire.read(); // receive byte as a character

    int len = strlen(jsonData);
    jsonData[len] = c;
    jsonData[len+1] = '\0';

    #if DEBUG_I2C
    Serial.print(c);         // print the character
    #endif

    if (c == '}'){

      #if CACHE_MODE
      writeToSd(jsonData);
      #endif

      #if ONLINE_MODE
      gprsSequence(jsonData);
      #endif

      #if DEBUG_I2C
      Serial.println(F("SAVING TRIGGERED"));
      Serial.println(jsonData);
      #endif
    }

  }
  #endif
}

void writeToSd(char *jsonToWrite){

  #if CACHE_MODE
  // open the file. note that only one file can be open at a time,
 // so you have to close this one before opening another.
  cacheFile = SD.open("CACHE.txt", FILE_WRITE);
  if (cacheFile) {
    cacheFile.write(jsonToWrite);
    cacheFile.close();
  }

  #if DEBUG_SD
  Serial.println(F(" << "));
  // re-open the file for reading:
    cacheFile = SD.open("CACHE.txt");
    if (cacheFile) {
    Serial.println("CACHE.txt:");

    // read from the file until there's nothing else in it:
    while (cacheFile.available()) {
      Serial.write(cacheFile.read());
    }
      // close the file:
      cacheFile.close();
    } else {
      // if the file didn't open, print an error:
      Serial.println(F("error opening CACHE.txt"));
    }
  #endif
  #endif

}

void loop() {
    // i wanted to code the cached-data sending here
    delay(2000);
}

void gprsSetup() {
  //... cleared for brevity
}

void gprsSequence(char *jsonData) {
    //... cleared for brevity. the point is, this function is to send the jsonData by GPRS
}

Generally the onReceive callback function is called from an ISR in the Wire library. That means, that no other interrupts can be handled during that time. For this reason an ISR always should be as short as possible. Writing to the SD card is a rather long process and it also uses interrupts, so it might block forever, when used in an ISR (though I'm not sure, since I didn't look through the SD library). You should do the SD card stuff outside of the ISR. In the ISR you can receive the I2C message and then set a flag variable, that will tell the code in the loop() function, that new data is available and that it can start processing it. That way your ISR stays short and the other operations will not be blocked by it. Do the same with the direct sending of GPRS data.
Also note, that transmitting Serial data inside of an ISR also does not work for the same reason (Serial relies on interrupts). The calls to Serial.print() or Serial.write() will only fill the libraries internal buffer. The data will get transmitted after the ISR was left. If you try to print/write data to Serial, when the buffer is full, the library will block, until the buffer has again space for sending the data, which will never happen inside the ISR. So you should be cautious with writing Serial inside an ISR. A bit doesn't hurt, but it can get a big problem.

will the triggered function "receiveEvent" registered in setup for
  Wire Slave Wire.onReceive(receiveEvent); conflict with the ongoing
  loop block where the system reads the backed-up data and sends the
  backed-up data?

From the general logic there cannot happen more than 1 specific data operation on the SD card at the same time. If you are currently writing one file, you cannot simply break the transmission through an interrupt and writing another file without breaking things. The transaction has to be completed, or you will fastly corrupt your file system. But, as I wrote above, this isn't really possible either way, because the SD card calls will not work properly inside of an ISR. So just put all the GPRS and SD card code into the loop() function and trigger the corresponding code blocks with a flag from the ISR. That way nothing can conflict here.


text:
Can I connect an Arduino Uno Wifi to Arduino Cloud?
Can I connect an Arduino Uno Wifi to Arduino Cloud? If yes, how? If no, what cloud is compatible?
I have tried to look online but I could not find anything that raises this question.

If you sign in to Arduino Cloud the very first thing it asks you is which board you are using. One of the options is the Arduino WiFi Shield 101. That is a shield that you can attach to any Uno-footprint board (including the Uno) to give it encrypted WiFi.
Another option is the Yun shield which turns your Uno into a kind-of Yun.
There are many many other "clouds*" that support Arduino, and many that if you are a reasonable programmer should be simple enough to make work with Arduino, since 99.99% of them all work through some form of HTML-based interface.

* Cloud: n. An idiotic buzzword used to describe pretty much any website these days.

Voted for just because you clearly defined what cloud means :)

As noted above, if you can comply with the interface you should be able to talk to 'the cloud'.  You should even be able to use a PC based web browser.

I believe the Arduino White Fluffy Insubstantial Thing requires encryption (SSL), so basic shields won't work with it - hence the requirement of the WiFi Shield 101.


text:
Button to not run script
I'm looking to have a button that, when pressed down, will mean that the script loaded on the Arduino doesn't run. So far I have:
void setup() {
  pinMode(3, INPUT_PULLUP);
  if (digitalRead(3) == LOW) {
    while(1);
  }
  // Beginning the Keyboard stream
  Keyboard.begin();
  // then the rest of the code.

I have a push button soldered to the ground and 3 pin. Could you see what is wrong with the code?

Well the while(1); will mean that the code will stop cold. Even if you release the button, the code will not resume.

@AndreCourchesne Since that code is in setup() it will only get called if the button is closed when the Arduino starts up.

@JohnnyMopp true indeed.

aside: compiled code is not a "script"...

Welcome to Arduino SE.  Be sure to take the tour to see how things work here:  https://arduino.stackexchange.com/Tour

I would do it this way:
void setup () {
    pinMode(3, INPUT_PULLUP);
}
void loop () {
    while (digitalRead(3)==LOW) {}; //do nothing, wait for release button
    // do all my stuff
}

or even better I would use some LED to indicate, that the button is pressed (or released) to have some visual state indicator (or another stuff to do while the button is pressed
void setup () {
    pinMode(3, INPUT_PULLUP);
    pinMode(13, OUTPUT);
    digitalWrite(13,LOW);
}
void loop () {
    while (digitalRead(3)==LOW) {
       digitalWrite(13,HIGH); // let it shine
       };
    digitalWrite(13,LOW);
    // do all my stuff
}

eventually
void setup () {
    pinMode(3, INPUT_PULLUP);
    pinMode(13, OUTPUT);
    digitalWrite(13,LOW);
}
void loop () {
    if (digitalRead(3)==LOW) {
       digitalWrite(13,HIGH); // let it shine
       while (digitalRead(3)==LOW) {
          // do some other stuff
       };
    digitalWrite(13,LOW); // switch indicator off
    // do my regular stuff
}

You need to move the code that checks the button into loop(). Put the code that you want to pause in the if block.
void loop() {
    // Only execute if not pressed
    if (digitalRead(3) != LOW) {
        // Do stuff
    }
}


text:
PROGMEM : pgm_read_float_near() equivalent for double? (Arduino Due)
I'm using an Arduino Due where double have a size of 8 bytes. In my software, I use double table const stored in prog memory, I was using an UNO before and used pgm_read_float_near() to retrieve these values. What function should I use?

Arduino Due (ARM Cortex-M3) doesn't need anything like PROGMEM as it has access into the flash memory in the same way as into the RAM. The const qualifier is enough to keep it in program memory only.
The AVR based boards like UNO needs PROGMEM because there are different instructions for fetching data from program memory and g++ is not very advanced in this way (some other compilers supports it directly - for example in gcc you can use __flash and __eeprom instead, but not in g++ as it was rejected for some reasons)
Edit:
Currently there are also AVRs with a new design (they are more like xmegas) and they are having flat address space (emulation) so with single pointer you can fetch RAM, FLASH, EEPROM and so on. But it's limited to the devices with smaller FLASH (all of it must fit into 64kB/16b pointers). In those cases you can just use const for global arrays and it'll be stored in FLASH (and not in FLASH and loaded into RAM upon startup like old AVRs) and string literals doesn't need P_STR / F() macros
For example:

Atmega4809 (nano every, uno wifi r2) and variants: 808, 809, 1608, 1609, 3208, 3209, 4808
Attiny(2/4/8/16/32)(0/1/2)(2,4,6,7) - eg Attiny212 1616 ...
It should be also possible on AVR16/AVR32 devices, but 64kB/128kB ones needs PROGMEM again (compiler can't optimize it into FLASH as you have only snapshot of 32kB in direct address space, but it's possible to change it - however there is also erratum about it not working properly)

“instruntions” ??

Yes, Jmaes, instruntions. They're what you hit microcontrollers with to make them work.

For anyone looking for an equivalent, you can manually copy the bytes into a double like:
double pgm_read_double(const double* address) {
    double result;
    memcpy_P(&result, address, sizeof(double));
    return result;
}

And use memcpy_PF for far addresses. But know that many MCUs have access into the flash memory in the same way as into the RAM, so you don't need to use this at all.

authors: Прохор Макей