text:
Arduino Freezes (probably because of I2C) - Need help to write robust script
Arduino Pro mini 3.3V stucks few hours after startup. After repowered, it begins to stuck within a few seconds. If I wait long enough before turning it on it stucks little later for example now it lasted 45 seconds before stuck. Whenever it is stuck SCL pin is high and SDA pin is low so I suspect somethin about I2C is wrong. There is an 60 seconds countdown at start and the stuck usually happens there, you will see it is an extremely simple for loop. There are SHT31 sensor, 128x64 SH1106 driven OLED screen, DS3231 clock module, hc-sr501PIR sensor, LDR, Encoder and a button on the project. Only first three works with I2C and the code for those devices are very short, they are in "start(), updatescreen(), getTime(), getDew()" functions in the long script below so I hope it is not hard to diagnose the problem. I have done some experiments. I isolated SHT31 and OLED, both caused freeze even though all other devices were disconnected (I added blink code to their example test sketch and the blinking stopped after few seconds which means stuck). OLED screen works when it is connected with jumpers outside the PCB so I even suspected the PCB but it is so simple that it shouldn't cause problems. The weird thing is that this device worked perfectly for 2 days before it crushed for the first time.
Schematic:

PCB (some mistakes were fixed later):

Real images:

Test script (the same freezing problem occurs but easier to read):
#include <U8g2lib.h>
#include <Wire.h>

U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
void setup() {
  u8g2.begin();
  u8g2.setFont(u8g2_font_ncenB14_tr);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  u8g2.firstPage();
  do {
    u8g2.setCursor(0, 20);
    u8g2.print(F("Hello World!"));
  } while (u8g2.nextPage());
  delay(1000);
  digitalWrite(LED_BUILTIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(1000);                      // wait for a second
  digitalWrite(LED_BUILTIN, LOW);
}

Test script 2 (this time for sht31, the same freezing problem occurs but easier to read):
#include <Wire.h>
#include "ClosedCube_SHT31D.h"

ClosedCube_SHT31D sht3xd;
void setup() {
  Wire.begin();
  sht3xd.begin(0x44);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  SHT31D result = sht3xd.readTempAndHumidity(SHT3XD_REPEATABILITY_LOW, SHT3XD_MODE_CLOCK_STRETCH, 50);
  delay(1000);
  digitalWrite(LED_BUILTIN, LOW);
  delay(1000);
}

Full Script:
#include "Wire.h"
#include "ClosedCube_SHT31D.h"
#include <DS3231.h>
#include "LowPower.h"
#include <EEPROM.h>
#include <U8g2lib.h>

#define PIR 2
#define ENCODER_BUTTON 3
#define ENC_A 4
#define ENC_B 5
#define FAN_MAIN_REL 8
#define FAN_SECOND_REL 9
#define BUZZER 10
#define LIGHT_REL 11
#define LDR_PWR 12
#define LDR_READ A0
#define FREE_RUN_BUTTON A2
#define CLOCK_INT A3

volatile bool PIR_flag, TIM1_flag, But_flag, FreeRun_flag, Settings_flag;
uint8_t Weather_flag;  // Weather_flag is special, it is set/reset by a regular function, 0: Dew is under threshold, 1: Dew is over DewThres but less than DewThresExtreme, 2: Dew is over DewThresExtreme
volatile int16_t encVal;

// Variables:
float Temp, Hum, Dew;
bool DewTrigEnabled;
uint8_t FanMotTrigEnabled;  // for fan relay
bool LightRelEnabled;       // for light relay
uint16_t waitDur;           // Setting 1
uint16_t Runtime;           // Setting 2
float DewThres;             // Setting 3
float DewThresExtreme;
uint16_t FreeRunDur;  // Setting 5
bool FreeRunStatus;
bool DNDenabled;
uint8_t DND_SH;  // DND start Hour
uint8_t DND_SM;  // DND start Minute
uint8_t DND_FH;  // DND finish Hour
uint8_t DND_FM;  // DND finish Minute
uint16_t counter;
uint8_t hour, minute;
bool LDRenabled;
uint16_t LDRThres;
bool screen_awake = true;  // screen starts "on"
uint8_t FanRelayStatus;
const uint8_t screenTime = 60;  // Screen On time without motion (seconds)
const float DewUSratio = 0.98;  // Determines the dew point which the FAN turns off if it was triggered by the Dew in the first place
const uint8_t phaseLim = 120;   // Determines LDR check rate if light is off but LDR is enabled, each phase corresponds to 5 seconds.

ClosedCube_SHT31D sht3xd;
RTClib myRTC_1;
DS3231 myRTC_2;
U8G2_SH1106_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);

void swCounter(bool turn_on, uint32_t cnt = 0) {
  if (turn_on) {
    counter = cnt;
    TCNT1 = 0;                            // TIM1 counter value
    TCCR1B |= (1 << CS12) | (1 << CS10);  // Start timer by setting prescaler to 1024
  } else
    TCCR1B &= ~(1 << CS12) | ~(1 << CS10);  // Stop TIM1
}

void setup() {
  LoadPinsAndEEPROM();

  Wire.begin();

  // Temp&Hum Sensor:
  sht3xd.begin(0x44);

  // Clock Module:
  myRTC_2.setA2Time(
    0, 0, 0,
    0b01110000, false, false, false);
  myRTC_2.turnOnAlarm(2);

  myRTC_2.setA1Time(
    0, 0, 0xFF, 0,
    0b00001110, false, false, false);
  myRTC_2.turnOffAlarm(1);
  myRTC_2.checkIfAlarm(1);  // clear Alarm 1 flag

  sht3xd.heaterEnable();
  // OLED Screen:
  u8g2.begin();
  u8g2.setFont(u8g2_font_lubB12_tr);
  for (int i = 60; i > 0; i--) {
    u8g2.firstPage();
    do {
      u8g2.drawStr(6, 25, "by Prince");
      u8g2.setCursor(58, 55);
      u8g2.print(i);
      if (i == 30) sht3xd.heaterDisable();
    } while (u8g2.nextPage());
    delay(1000);
  }
  u8g2.setDrawColor(2);

  //TIM1 Configuration:
  TCCR1A = 0;
  TCCR1B = 0;
  TIMSK1 |= (1 << OCIE1A);  // Output Compare A Match Interrupt Enable
  OCR1A = 39061;            // Output Compare A
  TCCR1B |= (1 << WGM12);   // CRC (auto reset timer when it reaches OCR1A)
  TCNT1 = 0;                // TIM1 counter value

  // Attach interrupts (PinChanges and INTpin)
  attachInterrupt(digitalPinToInterrupt(PIR), ISR_PIR, RISING);
  attachInterrupt(digitalPinToInterrupt(ENCODER_BUTTON), ISR_ENCODER_BUTTON, FALLING);
  PCICR |= (1 << PCIE1);                      // A0-A6 group can create interrupt
  PCMSK1 |= (1 << PCINT10) | (1 << PCINT11);  // A2 and A3 pins can create interrupt
  PCMSK2 |= (1 << PCINT20) | (1 << PCINT21);  // D4 and D5 pins can create interrupt

  Beep(1, 100, 0);
  PIR_flag = false;
  But_flag = false;
}

void loop() {
  checkButtons();  // After execution it will return.
  if (!getDNDstatus()) {
    getDew();  // sets flag accordingly

    if (PIR_flag) {
      if (FanMotTrigEnabled == 1) {
        TIM1_flag = true;  // Update screen initially
        screenPwr(1);

        unsigned long lastMotion;
        uint8_t step = 1;
        if (waitDur <= 5) step = 2;  // PIR_flag is already true at this point
        else swCounter(1, waitDur);

        for (step = step; step <= 2; step++) {  // 1: waiting, 2: armed, 3: Running
          if (step == 2) {
            (waitDur >= 90) ? counter = 60 : counter = 30;  // Deciding how long ahead it will check for motion
            swCounter(1, counter);
            PIR_flag = false;
            updateScreen(step);
          }
          while (counter > 0) {  // Counter Loop
            if (checkButtons()) return;
            if (PIR_flag) {
              PIR_flag = false;
              lastMotion = millis();
              if (step >= 2) {    // if it's armed or Running and Motion is detected
                if (step == 2) {  // if it's armed and Motion is detected
                  if (FanRelayStatus != 2) swFanRelays(1);
                  step = 3;  // Motion..
                  updateScreen(step);
                }
                swCounter(1, Runtime);  // Restart interval
              }
            }
            if (TIM1_flag) {
              TIM1_flag = false;
              if (getDNDstatus()) return;
              if (step == 1 && (millis() - lastMotion) / 1000 >= screenTime) return;
              getDew();
              DewControl(step != 3);  // in case Dew increases while on wait
              updateScreen(step);
            }
          }
        }
      } else if (FanMotTrigEnabled != 1) {  // Mot trig is disabled but there is motion
        PIR_flag = false;
        if (FanMotTrigEnabled == 2) swFanRelays(0);
        RunScreen(false);
      }
    }

    DewControl(true);
    Sleep(true);

  } else {  // if it's DND times:
    if (PIR_flag) {
      PIR_flag = false;
      RunScreen(true);
    }
    if (getDNDstatus()) Sleep(false);  // DnD status is rechecked because it might have been stuck in RunScreen by the user when DND is over.
  }
}

void DewControl(bool cmd1) {  // 0: cannot turn the fan "off" but only "on" 1: can both turn "on" and "off"
  if (Weather_flag == 0 && cmd1) swFanRelays(0);
  else if (Weather_flag == 1) swFanRelays(1);
  else if (Weather_flag == 2) swFanRelays(2);
}

void RunScreen(bool cmd1) {  // 0: dont return based on DND, 1: return if not in DND times anymore (prevents being stuck in DND if screen is on)
  TIM1_flag = true;          // Update screen initially
  screenPwr(1);
  swCounter(1, screenTime);  // Fixed Run screen time
  while (counter > 0) {
    if (checkButtons()) return;
    if (TIM1_flag) {
      if (getDNDstatus()) {
        if (FanRelayStatus) return;
      } else {
        if (cmd1) return;
        DewControl(true);
      }
      getDew();
      updateScreen(0);  // Idle or Dew

      if (PIR_flag) {
        counter = screenTime;
        PIR_flag = false;
      }
      TIM1_flag = false;
    }
  }
  LightRel_IfNeeded(0);
}

void getDew() {
  SHT31D result = sht3xd.readTempAndHumidity(SHT3XD_REPEATABILITY_LOW, SHT3XD_MODE_CLOCK_STRETCH, 50);  // used to be a static var
  Temp = result.t;
  Hum = result.rh;

  float a_func = log(Hum / 100) + 17.625 * Temp / (243.04 + Temp);
  Dew = (243.04 * a_func) / (17.625 - a_func);

  if (!DewTrigEnabled || (Dew <= DewThres * DewUSratio) || (Dew < DewThres && FanRelayStatus == 0)) Weather_flag = 0;
  else if (Dew < DewThresExtreme) Weather_flag = 1;
  else Weather_flag = 2;
}

bool getDNDstatus() {  // check if hours and minutes are in the interval
  if (!DNDenabled) return false;

  updateTime();
  uint16_t currentmin = hour * 60 + minute;

  uint16_t localDNDstart = DND_SH * 60 + DND_SM;
  uint16_t localDNDfinish = DND_FH * 60 + DND_FM;

  if (localDNDstart < localDNDfinish) return (currentmin >= localDNDstart && currentmin < localDNDfinish);
  else return (currentmin >= localDNDstart || currentmin < localDNDfinish);
}

void updateTime() {
  if (myRTC_2.checkIfAlarm(2)) {
    DateTime now;  // used to be a static var
    now = myRTC_1.now();
    hour = now.hour();
    minute = now.minute();
  }
}

void swFanRelays(uint8_t cmd1) {  // 0: turn off, 1: turn on
  if (FanRelayStatus == cmd1) return;
  bool PIR_flag_original = PIR_flag;
  if (cmd1 == 0) {
    digitalWrite(FAN_MAIN_REL, LOW);
    digitalWrite(FAN_SECOND_REL, LOW);
    FanRelayStatus = 0;
  } else if (cmd1 == 1) {
    digitalWrite(FAN_MAIN_REL, HIGH);
    if (FanRelayStatus != 2) {
      digitalWrite(FAN_SECOND_REL, HIGH);
      delay(500);
    }
    digitalWrite(FAN_SECOND_REL, LOW);
    FanRelayStatus = 1;
  } else if (cmd1 == 2) {
    digitalWrite(FAN_MAIN_REL, HIGH);
    digitalWrite(FAN_SECOND_REL, HIGH);
    FanRelayStatus = 2;
  }
  delay(100);
  if (!PIR_flag_original) PIR_flag = false;
  But_flag = false;
  FreeRun_flag = false;
}

void LightRel_IfNeeded(bool cmd1) {  // 0: turn OFF Light Relay, 1: turn ON Light Relay
  static bool LightRelStatus;
  bool LDRresult;
  static uint8_t phase;  // regularly check light level in case brightness changes in the room over time.

  switch (cmd1) {
    case 0:
      if (!LightRelStatus) return;
      LightRelStatus = false;
      phase = 0;
      digitalWrite(LIGHT_REL, LOW);
      delay(100);
      PIR_flag = false;
      But_flag = false;
      FreeRun_flag = false;
      break;

    case 1:
      if (!LightRelStatus && phase == 0) {
        if (LDRenabled) {
          digitalWrite(LDR_PWR, HIGH);
          delay(10);
          LDRresult = (analogRead(LDR_READ) > LDRThres);  // Darkness --> High resistance --> High voltage on LDR --> TRUE              Lit --> Low resistance --> Low voltage on LDR --> FALSE
          digitalWrite(LDR_PWR, LOW);
        } else LDRresult = true;

        if (LDRresult) {
          LightRelStatus = true;
          digitalWrite(LIGHT_REL, HIGH);
          delay(100);
          PIR_flag = false;
          But_flag = false;
          FreeRun_flag = false;
        }
      }
      phase++;
      if (phase > phaseLim) phase = 0;  // default value is 120 which means 10 minutes
      break;
  }
}

void Sleep(bool cmd1) {  // 0: Sleep normal 1: Sleep without turning off the Fan
  if (cmd1 == 0) swFanRelays(0);
  LightRel_IfNeeded(0);
  screenPwr(0);
  updateTime();
  PIR_flag = false;
  But_flag = false;
  FreeRun_flag = false;

  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
}

void updateScreen(uint8_t cmd1) {  // 0: idle or Dew Trig, 1: Detected, 2: Waiting, 3: Armed, 4: Mot Trig, 5: Free run dur
  String info;
  LightRel_IfNeeded(1);  // Regularly called because brigthness of the room info is updated every phase*5/60 minutes
  updateTime();

  switch (cmd1) {
    case 0:
      if (FanRelayStatus == 0) info = "Idle";
      else if (FanRelayStatus == 1) info = "Dew";
      else info = "OverDew";
      break;
    case 1:
      info = "Waiting";
      if (FanRelayStatus == 1) info += "&Dew";
      else if (FanRelayStatus == 2) info += "&OverDew";
      break;
    case 2:
      info = "Armed";
      if (FanRelayStatus == 1) info += "&Dew";
      else if (FanRelayStatus == 2) info += "&OverDew";
      break;
    case 3:
      info = "Motion";
      if (Weather_flag == 1) info += "&Dew";
      else if (Weather_flag == 2) info += "&OverDew";
      break;
    case 4:
      info = "<";
      info += String(counter / 60 + 1);
      info.remove(info.indexOf('.'));
      info += " mins";
      break;
  }

  u8g2.firstPage();
  do {
    u8g2.setFont(u8g2_font_6x10_mr);  // u8g2_font_haxrcorp4089_tn
    u8g2.setCursor(0, 7);
    u8g2.print(info);

    u8g2.setCursor(99, 7);
    if (hour < 10) u8g2.print("0");
    u8g2.print(hour);
    u8g2.print(":");
    if (minute < 10) u8g2.print("0");
    u8g2.print(minute);

    u8g2.drawLine(0, 10, 128, 10);

    u8g2.setFont(u8g2_font_fub20_tn);
    u8g2.setCursor(0, 38);
    if (Temp < 10 && Temp >= 0) u8g2.print("0");
    u8g2.print(Temp, 1);
    u8g2.setCursor(0, 64);
    u8g2.print(Hum, 1);
    u8g2.setCursor(71, 61);
    if (Dew < 10) u8g2.print("0");
    u8g2.print(Dew, 1);
    if (Dew < DewThres) u8g2.drawFrame(70, 38, 58, 26);
    else u8g2.drawBox(71, 39, 56, 24);

    u8g2.setFont(u8g2_font_lubB12_tr);
    u8g2.drawStr(55, 30, "*C");
    u8g2.drawStr(55, 64, "%");

    if (FreeRunStatus == true) u8g2.drawStr(81, 30, "FREE");
    else if (getDNDstatus()) u8g2.drawStr(82, 30, "DND");

  } while (u8g2.nextPage());
}

void screenPwr(bool cmd1) {
  if (cmd1 == screen_awake) return;

  switch (cmd1) {
    case 0:
      u8g2.setPowerSave(1);
      u8g2.clear();
      screen_awake = false;
      break;

    case 1:
      u8g2.setPowerSave(0);
      swCounter(0);
      screen_awake = true;
      break;
  }
}

void FreeRun() {
  Beep(1, 500, 0);
  FreeRun_flag = false;
  FreeRunStatus = true;
  getDew();
  swFanRelays(1);
  swCounter(1, FreeRunDur);
  updateScreen(4);
  screenPwr(1);
  while (counter > 0) {
    if (But_flag) {
      FreeRunStatus = false;
      Settings();
      return;
    }
    if (FreeRun_flag) {
      Beep(1, 100, 0);
      delay(1000);
      if (!digitalRead(FREE_RUN_BUTTON)) {  // if the user holds the button down
        swFanRelays(0);
        Beep(2, 100, 100);
        while (!digitalRead(FREE_RUN_BUTTON)) delay(100);  // For the user to remove hand
        delay(500);                                        // prevent debouncing
        FreeRun_flag = false;
        break;
      } else {
        FreeRun_flag = false;
        if (FanRelayStatus == 1) swFanRelays(2);
        else if (FanRelayStatus == 2) swFanRelays(1);
      }
    }
    if (TIM1_flag) {
      TIM1_flag = false;
      if (getDNDstatus()) break;
      getDew();
      updateScreen(4);
    }
  }
  DewControl(true);
  FreeRunStatus = false;
  PIR_flag = false;  // Ignore the motion while in "Free Run" mode
}

bool checkButtons() {
  if (FreeRun_flag) {
    if (!getDNDstatus()) {
      FreeRun();
      return 1;
    } else {  // if Free Run is pressed during DND, deny Free Run
      Beep(3, 50, 50);
      FreeRun_flag = false;
    }
  } else if (But_flag) {
    Beep(1, 100, 0);
    delay(1000);  // If button is held down
    if (!digitalRead(ENCODER_BUTTON)) {
      Settings();
      return 1;
    }
    But_flag = false;
  }
  return 0;
}

void Beep(uint8_t rep, uint8_t dur_act, uint8_t dur_pass) {  // repetition, duration of beeping, duration of pauses
  for (int i = 0; i < rep; i++) {
    digitalWrite(BUZZER, HIGH);
    delay(dur_act);
    digitalWrite(BUZZER, LOW);
    if (i < (rep - 1)) delay(dur_pass);
  }
}

void LoadPinsAndEEPROM() {

#define FanMotTrigEnabled_Address 0
#define waitDur_Address 1
#define Runtime_Address 3
#define DewTrigEnabled_Address 5
#define DewThres_Address 6
#define DewThresExtreme_Address 10
#define LightRelEnabled_Address 14
#define LDRenabled_Address 15
#define LDRThres_Address 16
#define DND_Enabled_Address 18  // DND enabled
#define DND_SH_Address 19       // DND start Hour
#define DND_SM_Address 20       // DND start Minute
#define DND_FH_Address 21       // DND finish Hour
#define DND_FM_Address 22       // DND finish Minute
#define FreeRunDur_Address 23

  EEPROM.get(FanMotTrigEnabled_Address, FanMotTrigEnabled);
  EEPROM.get(waitDur_Address, waitDur);
  EEPROM.get(Runtime_Address, Runtime);
  EEPROM.get(DewTrigEnabled_Address, DewTrigEnabled);
  EEPROM.get(DewThres_Address, DewThres);
  EEPROM.get(DewThresExtreme_Address, DewThresExtreme);
  EEPROM.get(LightRelEnabled_Address, LightRelEnabled);
  EEPROM.get(LDRenabled_Address, LDRenabled);
  EEPROM.get(LDRThres_Address, LDRThres);
  EEPROM.get(DND_Enabled_Address, DNDenabled);
  EEPROM.get(DND_SH_Address, DND_SH);
  EEPROM.get(DND_SM_Address, DND_SM);
  EEPROM.get(DND_FH_Address, DND_FH);
  EEPROM.get(DND_FM_Address, DND_FM);
  EEPROM.get(FreeRunDur_Address, FreeRunDur);

  // DEBUG:
  /*
  FanMotTrigEnabled = 1;
  waitDur = 10;
  Runtime = 10;
  DewTrigEnabled = true;
  DewThres = 18.0;
  DewThresExtreme = 19.0;
  LightRelEnabled = true;
  LDRenabled = true;
  LDRThres = 512;
  DNDenabled = false;
  DND_SH = 23;
  DND_SM = 45;
  DND_FH = 0;
  DND_FM = 2;
  FreeRunDur = 30;
*/
  pinMode(PIR, INPUT);
  pinMode(LDR_READ, INPUT);
  pinMode(ENC_A, INPUT);
  pinMode(ENC_B, INPUT);

  pinMode(CLOCK_INT, INPUT_PULLUP);  // Datasheet states pullup resistor is necessary
  pinMode(FREE_RUN_BUTTON, INPUT_PULLUP);
  pinMode(ENCODER_BUTTON, INPUT_PULLUP);

  pinMode(FAN_MAIN_REL, OUTPUT);
  pinMode(FAN_SECOND_REL, OUTPUT);
  pinMode(LIGHT_REL, OUTPUT);
  pinMode(BUZZER, OUTPUT);
  pinMode(LDR_PWR, OUTPUT);
}

void ISR_PIR() {
  PIR_flag = true;
}

void ISR_ENCODER_BUTTON() {
  But_flag = true;
}

ISR(PCINT1_vect) {
  if (!digitalRead(FREE_RUN_BUTTON)) FreeRun_flag = true;  // Button has pullup resistor thus "!" is used.
}

ISR(TIMER1_COMPA_vect) {
  TIM1_flag = true;
  counter -= 5;
  if (counter <= 0) swCounter(0);
}

// Horrible Settings Codes xd:
ISR(PCINT2_vect) {  // Rotary Encoder Interrupt
  static bool aLastState;
  bool aState = digitalRead(ENC_A);
  bool bState = digitalRead(ENC_B);

  if (aState != aLastState) {
    if (bState != aState) {
      encVal++;
    } else {
      encVal--;
    }
    aLastState = aState;
  }
}

void ButDebounce(bool cmd1) {  // 0: Encoder But, 1: Free Run
  if (cmd1) {
    while (!digitalRead(FREE_RUN_BUTTON)) delay(100);  // Wait until button is released
    delay(200);
    FreeRun_flag = false;
  } else {
    while (!digitalRead(ENCODER_BUTTON)) delay(100);  // Wait until button is released
    delay(200);
    But_flag = false;
  }
}

String formatTime(int input, bool type = true) {  // type = true means input is seconds, if false it means input is minutes
  int hours = input / 3600;                       // Get the number of hours
  int minutes = (input % 3600) / 60;              // Get the number of minutes
  int remainingSeconds = input % 60;              // Get the number of seconds

  if (!type) {
    hours = minutes;
    minutes = remainingSeconds;
    remainingSeconds = 0;
  }

  // Create a formatted string in the format "hour:minute:second"
  String formattedTime = "";

  if (hours < 10) {
    formattedTime += "0";  // Add leading zero for hours
  }
  formattedTime += String(hours) + ":";

  if (minutes < 10) {
    formattedTime += "0";  // Add leading zero for minutes
  }
  formattedTime += String(minutes) + ":";

  if (remainingSeconds < 10) {
    formattedTime += "0";  // Add leading zero for seconds
  }
  formattedTime += String(remainingSeconds);

  return formattedTime;
}

uint8_t setEncVal(uint16_t target, uint8_t inc1, uint8_t inc2, uint16_t inc3, uint8_t lim1, uint8_t lim2) {
  uint16_t a = 0;
  uint8_t b = 0;
  while (a < target) {
    if (b < lim1) a += inc1;
    else if (b < lim2) a += inc2;
    else a += inc3;
    b++;
  }
  return b;
}

void Settings() {} // removed because of character limit but I don't run this function before stuck anyway

Have you tried adding dedicated pullup resistors to SDA and SCL? Like 4.7kOhm. That might help in this case

No but the modules have pull-ups and it is 2.2k each when I measured

the first three sentences describe a possible overheating problem

Last time I had super weird I2C freezes it was caused by pin change ISR without it's handler.

I have a pin change interrupt which I use to wake the arduino up every minute from sleep by Ds3231 and it is connected to A3 and I have a button which is conected to A2. I didn't need handler for the clock module but since they are both analog pins I have "ISR(PCINT1_vect)" for the button so I guess I can say that I have no unhandled interrupts even though pinwise A3 does nothing except waking up.

jsotola, there is no heating on the regulator or the chip. Are you talking about I2C MOSFETs inside the Arduino? I guess I can't feel them with my fingers. I need to replace the Arduino for a reliable test I guess because the MOSFETs are already damaged. Is there any chance that temperature module or the screen or Ds3231 is also broken? Because they drive the SDA line with their MOSFETs as I guess.

OT: The missing separation between mains and low-level electronic looks dangerous to me. The gaps at K1 and K2 seem to be too small. Did you obey rules to protect humans?

I didn't follow any rules, this is a flaw in my design I admit.

You might want to change this before putting in operation to avoid hurting or killing someone, including yourself.

It sounds like over ambitious pull up resistors. They should total about 3K on each bus. I will take a SWAG and say the I2C driver fet is drawing to much current and heating up. When it does that its resistance increase thereby delivering less current. Get your resistors correct and I believe it will work just fine.
If you have freeze spray chill them and they will probably start working until they warm up.
If it was left on for any period of time it is possible you damaged one of the ICs which is no longer driving the bus properly. If you can check it with a scope. If not swat parts.

This is the first answer that sounded reasonable to me. On an other forum they told me I had cold solder or connectivity problem but they didn't sound realistic. This explains maybe why the device works longer when I wait for a long time before repowering, because FETs cool down. Also it explains why it managed to run 2 days at the first time, because the I2C FETs were healthy but now they are semi broken so it only lasts few hours. It lasts few seconds when I repower without waiting. I just can't believe kiloohms of resistance can still damage FETs. I will remove some resistors form modules.

I've removed the DS3231 because it had 4.7k pull-ups on board thus the total resistance became 5k (10k each on the SHT31 and OLED). Unfortunately the device was stuck few minutes after.

Are you sure you are using the latest I2C library?  Up until halfway through 2020, the 'official' I2C library had a known failure mode that would cause the I2C buss to hang.  See my 'Paynters Palace' post on this subject for additional info.
Frank

There is a comment saying: "Modified 2020 by Greyson Christoforo (grey@christoforo.net) to implement timeouts" I guess there is a default timeout already. Also I installed Arduino IDE 2 on April 2023. Anything I am missing? Thanks.


text:
ESP8266 Wifi connection problem
I have a Feather Huzzah, aka ESP8266, that I am trying to connect to the Wifi.
One major thing is, that my landlord decided to use the worst Wifi SSID and PW.
The SSID contains an ä and a whitespace, and the PW an @.
I scanned successfully the Wifi with the board and the prewritten code and the Wifi shows up.
Now I am using the Wifi client basic, just to check if any connection can established.
I tried to write all special characters in Unicode, but still no change.
Here is my code:
/*
This sketch sends a string to a TCP server, and prints a one-line response.
You must run a TCP server in your local network.
For example, on Linux you can use this command: nc -v -l 3000
*/

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>

#ifndef STASSID
#define STASSID "XXX XXäXX"      //original SSID
#define STASSID "XXX XX\u00e4XX" //Unicode SSID
#define STAPSK "XXX@XXX"        //Orginal PW
#define STAPSK "XXX@XXX"        //Unicode PW
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

const char* host = "192.168.1.1";
const uint16_t port = 3000;

ESP8266WiFiMulti WiFiMulti;

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

  // We start by connecting to a WiFi network
  WiFi.mode(WIFI_STA);
  WiFiMulti.addAP(ssid, password);

  Serial.println();
  Serial.println();
  Serial.print("Wait for WiFi... ");

  while (WiFiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

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

  delay(500);
}

void loop() {
  Serial.print("connecting to ");
  Serial.print(host);
  Serial.print(':');
  Serial.println(port);

  // Use WiFiClient class to create TCP connections
  WiFiClient client;

  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    Serial.println("wait 5 sec...");
    delay(5000);
    return;
  }

  // This will send the request to the server
  client.println("hello from ESP8266");

  // read back one line from server
  Serial.println("receiving from remote server");
  String line = client.readStringUntil('\r');
  Serial.println(line);

  Serial.println("closing connection");
  client.stop();

  Serial.println("wait 5 sec...");
  delay(5000);
}

Thank you for any help, and greetings from Sweden.

I copied ä into notepad++ and viewed the character using the hex editor plugin ... it consists of two bytes c3 a4

Don't get me wrong, but what am I supposed to do with that answer? I am not deep into Arduino programming unfortunatly. Can I convert bytes into chars?

it is just information, not an answer ... an answer would be in the "answer" section ... this site is not a forum

convert the bytes to char and insert them into the SSID   ... I have no idea if the result will work ... I would start with a known SSID that does not include problem characters ... connect the usual way to confirm connectivity ... then replace one of the characters with same character and confirm that connectivity is still good ... that will ensure that the character insertion code is valid

I don't have enough reputation to comment, otherwise this would be a comment, but you could ask your landlord to change the password. If he says no, you could say one of your devices can't type that character.

Yeah, I start to belief that this is the only solution :D

Start with a known simple SSID, and try this:
#define STASSID "mywifi" // For example this is the known SSID that connects
... ... ...
const char ssid[] = "mywifi";

If that works, then you can replace the char with hex.
const char ssid[] = {0x6D, 0x79, 0x77, 0x69, 0x66, 0x69};

If that works then you can replace the hex bytes with your actual SSID. And in the place of ä use those two hex bytes as jsotola mentioned, 0xC3 and 0xA4.

Edit 1:
From the comment, it looks like the receiver never connects to the WiFi. In the receiver hardware, try something simple and see if it gets connected at all or not.
#include <ESP8266WiFi.h>

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

  WiFi.begin("network-name", "pass-to-network");

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

  Serial.print("Connected, IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {}

Check what output you get.

Good hint. I connected the board to the Hotspot of my phone and it worked. So good so far. But when I try my local wifi again, I does not like it.  I replaced the const char ssid[] and password with raw hexadezimals and ran it trough several converters. When I print it out it looks fine.  But when i print out the password it is the correct password + the ssid again?! Like it is one variable, added together? Is that only due to the serial printout?

That doesn't sound right. Can you post the code that you mentioned in the comment where the password prints both password and SSID?

#ifndef STASSID
#define STASSID {0x6D, 0x79, 0x77, 0x69, 0x66, 0x69}
#define STAPSK {0x6D, 0x79, 0x70, 0x61, 0x73, 0x73, 0x77}
#endif
const char ssid[] = STASSID;
const char password[] = STAPSK;
... ... ...
Serial.print("Connecting to ");
Serial.print(ssid);
Serial.print(" ");
Serial.print(password);

Connecting to mywifi mypasswmywifi

Sorry, I cant edit it for better readability. I don't get it how to do that

No worries. Let me check.

Ok, that is happening because you are printing the array. Before when you defined your ssid and password, you used a string like this "mypassword". In that case, after the letter, there is a null-terminated character 0x00. So when tried to print that the print() knew when to stop, whenever it saw 0x00. But in the comment code, you are defining ssid and password as an array. So there is no "extra" null character. So print() doesn't know when to stop. when you printed the password it probably had the SSID in the print buffer from the previous print. You can't print an array like that.

Ok, well, it was just a test anyway. It should not make any difference in the internal handling. So, where else could be the problem? Security of the router?

@DaMusikant I updated the answer.

Finally I had some time again. I have some interesting things discovered. When I tried to connect to my hotspot it worked. But when I translated this name and pw it didin't connect. Instead, I saw my phone toggeling that someones connected and then not, in a half second intervall. It seems the controller itself has issues with hexadecimals. What is going on there?

source: Stack Exchange

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

sort: votes


text:
Trying to resolve invalid conversion from 'byte' {aka 'unsigned char'} to
I'm trying to use an existing Arduino library on the Raspberry Pi Pico.  The library is here:
https://github.com/j-bellavance/EdgeDebounce/tree/master
It's based on some interesting insight at Jack Ganssel's blog:
http://www.ganssle.com/debouncing.htm
The library works great on an ATMega 328, but I got two errors when changing to the Raspberry Pi Pico.
The first one was resolved by editing the last line of EdgeDebounce.h like this:
//#endif;  // Arduino ATMega version
#endif   // Pico version, also works on ATMega

The second is a bit more complex.  Here's the relevant section of code, these are lines 78 - 102 in EdgeDebounce.cpp :
  byte EdgeDebounce::debounce(byte pin) {
  unsigned long pinStatus;
  do {
    pinStatus = 0xffffffff;
    for (byte i = 1; i <= MYsensitivity; i++) pinStatus = (pinStatus << 1) | digitalRead(pin);
  } while ((pinStatus != debounceDontCare) && (pinStatus != 0xffffffff));
  return byte(pinStatus & 0x00000001);
}//debounce------------------------------------------------------------------------------------------------

//updateStatus===================================================================
//After releasing EdgeDebounceLite, I realized that EdgeDebounce could do more
//With this small piece of code, EdgeDebounce can return if a switch is
//  .isclosed();  //Conducting current
//  .isopen();    //Not conducting current
//  .rose();      //Just went from open to closed
//  .fell();      //just went from closed to open
//-------------------------------------------------------------------------------
void EdgeDebounce::update() {
  byte newStatus = debounce();
  if (MYmode == PULLUP) newStatus = !newStatus;
  if (MYstatus == OPEN && newStatus == CLOSED) MYrose = true;
  else                                         MYrose = false;
  if (MYstatus == CLOSED && newStatus == OPEN) MYfell = true;
  else                                         MYfell = false;
  MYstatus = newStatus;
}//update-------------------------------------------------------------------------

When I try to compile, I get this error:
c:\Users\thisuser\Documents\Arduino\libraries\EdgeDebounce\EdgeDebounce.cpp: In member function 'void EdgeDebounce::update()':
c:\Users\thisuser\Documents\Arduino\libraries\EdgeDebounce\EdgeDebounce.cpp:102:14: error: invalid conversion from 'byte' {aka 'unsigned char'} to 'pinStatus' [-fpermissive]
  102 |   MYstatus = newStatus;
      |              ^~~~~~~~~
      |              |
      |              byte {aka unsigned char}

exit status 1

Compilation error: exit status 1

So I see that the byte of "newStatus" doesn't convert to "pinStatus" which is an unsigned long.  I've done a bunch of Google searches but can't quite figure out what the fix is.

Where is pinStatus declared? Not inside EdgeDebounce::debounce - that's a local declaration.

In C and in much pre-standard C++ nothing stops you just assigning an integer value to a variable of enumeration type.  In standard C++ (from 1998 onward) that requires an explicit type conversion (a "cast").
The AVR Arduino core
supplies
the -fpermissive option to the compiler which among other things allows the implicit
conversion they're doing despite not being standards compliant C++.  Whatever you're using (odds are this or this) for RPI Pico Arduino core does not provide the -fpermissive option. A lot of Arduino cores don't and probably shouldn't.
You could modify the RPI Pico core's platform.txt to give the -fpermissive option to g++, but it is probably better to make the code compliant.
Minimal change
There are probably dozens of ways to do this, but a combination of mimimal and pleasing to C++ nerds probably looks like:
MYstatus = static_cast<pinStatus>(newStatus);

Alternative Casts
MYstatus = static_cast<decltype(MYstatus)>(newStatus); // fancier
MYstatus = (pinStatus)newStatus;  // traditional cast
MYstatus = pinStatus(newStatus);  // function-style cast
MYstatus = (decltype(MYstatus))newStatus;  // uhhh
MYstatus = (decltype(MYstatus))(newStatus);  // sure... why not?

The static_cast declares in intent in a way that other types of cast don't. decltype would make that line survive changes to the type of MYstatus better, but decltype is not as widely understood.
Alternately not type-converting at all
You can also observe that return byte(pinStatus & 0x00000001); is the only point of return from
byte EdgeDebounce::debounce(byte pin). So you know this function returns either 0 (false) or 1 (truthy). That's just what's going to happen with applying & 1.
They've defined the enumeration type:
enum pinStatus {OPEN, CLOSED};

The rules of C and C++ (even pre-standard C++) will assign these constants
numeric values 0 and 1, where they weren't explicitly given values and were listed in that order.
So, you could replace MYstatus = newStatus; with:
{
  if (newStatus) {
      MYstatus = CLOSED;
  } else {
      MYstatus = OPEN;
  }
}

Or use the ternary operator if you want don't mind people trying to argue with you:
MYstatus = newStatus ? CLOSED : OPEN;

It's apparently also possible to use braces for the function-style cast without a narrowing conversion diagnostic, which I didn't expect for this case. But, I'm not going to edit it again just to mention that

Thank you for taking the time to write such an in-depth answer!

I am using the Earle Philhower RP2040 core.
I read (and re-read) your comments until I understood them all.
I have tested all your suggested fixes above, and they all work.

I don't mind the ternary operator, but I will go with your first suggested change.
Thanks again.

pinStatus  is an enum:
enum pinStatus {OPEN, CLOSED};

The pinStatus you posted is a local variable, nothing to do with pinStatus in the EdgeDebounce.h file.
The error is pointing out that you can't assign an unsigned char to an enum which can only hold OPEN and CLOSED. The unsigned char might hold various other values.
Whoever coded that has made some confusing code.

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


text:
DS3231 is unable to keep record of time
so i bought a DS3231 clock which i am using with This famous library .
// DS3231_Serial_Easy
// Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
// web: http://www.RinkyDinkElectronics.com/
//
// A quick demo of how to use my DS3231-library to
// quickly send time and date information over a serial link
//
// To use the hardware I2C (TWI) interface of the Arduino you must connect
// the pins as follows:
//
// Arduino Uno/2009:
// ----------------------
// DS3231:  SDA pin   -> Arduino Analog 4 or the dedicated SDA pin
//          SCL pin   -> Arduino Analog 5 or the dedicated SCL pin
//
// Arduino Leonardo:
// ----------------------
// DS3231:  SDA pin   -> Arduino Digital 2 or the dedicated SDA pin
//          SCL pin   -> Arduino Digital 3 or the dedicated SCL pin
//
// Arduino Mega:
// ----------------------
// DS3231:  SDA pin   -> Arduino Digital 20 (SDA) or the dedicated SDA pin
//          SCL pin   -> Arduino Digital 21 (SCL) or the dedicated SCL pin
//
// Arduino Due:
// ----------------------
// DS3231:  SDA pin   -> Arduino Digital 20 (SDA) or the dedicated SDA1 (Digital 70) pin

#include <DS3231.h>

// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);

void setup()
{
  // Setup Serial connection
  Serial.begin(9600);
  // Uncomment the next line if you are using an Arduino Leonardo
  //while (!Serial) {}

  // Initialize the rtc object
  rtc.begin();

  // The following lines can be uncommented to set the date and time
  //rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
  //rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
}

void loop()
{
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");

  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());

  // Wait one second before repeating :)
  delay (1000);
}

Now the problem is, after i set a time it shows the time and date perfectly until i cut the power of the DS3231. while being connected to my PC when i disconnected the power of DS3231, i see the timer getting reset while it should have recorded and continued the timer. It outputs 'Monday 1.1.2021 0.0.0'
Is it the problem of my module? or i am doinng something mistake here? or the module works in this way?
whenever i disconnect arduino power from PC, it still continues to count but whenever i disconnect DS3231 from 5 v pin of Arduino, it resets back. Does that mean that the DS3231 need to use the 16Mhz crystal from Arduino to function properly??

Is the battery on the module connected properly? Maybe you need to remove a piece of plastic that prevents that the battery getting depleted during storage.

There was no plastic which prevent discharge. The RTC works fine while Arduino is powered off but all the pins of ds3231 are connected but, when arduino is off and 5v wire of ds3231 is disconnected, time resets.

You didn't write what exact module you have. Normally, the battery and the RTC chip are on the same breakout board and therefore cannot be separated. Clearly, the RTC chip's 5V battery input voltage must stay connected.

Yup.  Show what you actually have.

@PMF OK now, got it

So you disconnect the 5V to the DS3231, but keep the SDA and SCL pins connected? By doing that, you are working outside of the recommended operating conditions.
If you leave the SDA and SCL pins connected, those pins will be at around 5V. The datasheet specifies that those pins shouldn't be higher that Vcc+0.3V. Where Vcc is 0V, in your case.
Removing power from the Arduino board will also remove the power from the I2C pins, keeping things within specifications.

Ok, understood. But if I separate scl sda and 5v gnd all from Arduino and reconnect them again to the arduino which is already powered on, will the timer still reset?

@SubhaJeetSikdar try and see. Just note that you have to disconnect them in the right order. SDA and SCL first. Then Vcc. GND can stay connected. When re-connecting, go in the reverse order. So connect Vcc before SDA/SCL.

Thanks  i got everything clear now.


text:
Using Arduino UNO as FTDI
so , just bought some pre-bootloaded ATmega328(p/pu) to which I need to upload sketches on a breadboard using uno TX and RX pin as FTDI
Here is what I am to do.

I connected Uno GND and Reset .

Arduino Tx to Standalone Atmega Tx

Arduino Rx to Standalone Atmegaa Rx

Connected Crystal , capacitor to standalone pin 9, 10 (XTAL) then grounded it with 2 coupling capacitor.

Standalone vcc to arduino 5v
Standalone GND to Uno GND

Is it possible to do what I need to or i need to buy some USB to TTL devices from the Amazon again?
Thanks for your precious time...

That sounds about right.
The only problem is that normally, when a serial connection is created, the Arduino's reset pin is briefly pulled LOW. You would have to do that manually on the ATMega on your breadboard. I can be a bit tricky to get the timing right.
There is no easy way to get this signal to your breadboard ATMega, while keeping the reset pin on the UNO's ATMega LOW.
Removing the ATMega from the UNO board would work.

I have got to get the right time to reset after uploading the code so, i am doing it manually without FTDI which saved some of my bucks :)

@SubhaJeetSikdar I changed the firmware on the ATMega8u2 on my UNO to also toggle one of the header pins next to it, when it tries to reset the ATMega328P. That way I could upload to custom ATMage328P based board over serial :-)

Can you please send me a video or article link about how you changed the firmware of the programmer ic ATmega8u2, well , mine one seems to be ATmega16u2

I programmed it via DFU. The firmware can be found at https://github.com/arduino/ArduinoCore-avr/tree/master/firmwares/atmegaxxu2. Change  Arduino-usbserial.c to also change one of the ISP pins where it currently change the reset-out pin. It's been way to long, so I don't have the files anymore. Proceed at own risk.

https://youtu.be/EoHD0m3uUhA. Ig this should do it. There are many more tutorials on YouTube to achieve this.

What if I don't want to remove the factory installed atmega on arduino. Actually I dont want to remove factory installed at mega, is there any other way to do this without removing previously installed atmega

If u don't remove the pre installed at mega then it will try uploading the code to both of them which will be a big problem for you . Then you have only one other option to use a FTDI module

What if i connect the ground and reset of the arduino before uploading sketches on breadboard ATmega?

Sorry I am not able to understand what u are asking

https://images.app.goo.gl/g2gEeuHJ9dKAd6hY6

Open the link above, UNO to TTL converter, will it work for what I want to do

Yeah I saw that but I was not able to find any proper tutorial or anything like that for uploading the code I only found few videos for using it for serial monitor . If u have all the parts give it a try and there is one more tutorial which is some what similiar
https://youtu.be/nGEjpZuPXuo

Hmm that video is about bootloading not uploading sketches on a pre bootloaded breadboard ATmega

he basically add a new bootloader to Arduino to program other Arduino using it so basically its the type of thing you wanted

No, i want to upload sketches using my uno board as a bridge between breadboard atmega and my PC , i don't want to burn bootloader, and I already know how to burn bootloader.


text:
How to call multiple delayed functions using a single millis()
I am working in a project where I need to call more than 1 functions actually 4 functions using a single millis()
Here is the code below.
 unsigned long then = 0;

 void loop(){

     unsigned long now = millis();

     if(now-then >=0){

         Serial.println("Function 1 called");

     }else if(now-then>=2000){

         Serial.println("Function 2 called");

     }else if(now-then>=4000){

         Serial.println("Function 3 called");

     }else if(now-then>=6000){

        Serial.println("Function 4 called");

         Serial.println("The end");

         then = now;
     }
 }

All the functions above gets run successfully but not in a proper sequence.
The running sequence of the functions seem to be very improper and random.
The 'function 1' gets executed in a proper sequence and timing but rest of the others are making a messy output.
How can I fix it please?
Thanks.

How do you want the functions to be called in order? Like "1,2,3,4 ... 1,2,3,4" or like "1...1,2...1,2,3...1,2,3,4...1...1,2..."?

Like '1234' order

why with else? why only one then?

The current structure with multiple if statements and on timestamp variable does only work, if you also check for millis()-then being smaller than the next interval. Otherwise the first if statement will always be executed.
I think it gets easier, when you use only one if statement, but put the intervals in an array. In that if statement you can either use a switch statement to execute the code for the corresponding interval, or use a function pointer. Somewhat like this (untested):
unsigned long then = 0;
unsigned long intervals[4] = {0, 2000, 4000, 6000};
int current_interval_index = 0;

...

void loop(){
    unsigned long now = millis();
    if(now-then >= intervals[current_interval_index]){
        switch(current_interval_index){
            case 0:
                Serial.println("Function 1");
                break;
            case 1:
                Serial.println("Function 2");
                break;
            case 2:
                Serial.println("Function 3");
                break;
            case 3:
                Serial.println("Function 4");
                break;
        }
    then = now;
    current_interval_index = (current_interval_index + 1) % 4; // increment index and wrap it back to zero, if it goes to 4
    }
}

That way you can easily extent for more functions and the intervals are conveniently managed in an array. Note, that the intervals add up here. So function 4 executes after 2s+3s+6s = 11s.

Nah, my bad, missed the scope of the index update.

your else in that set of if's is causing only a single if to be possible to be true at any one time, and once the now-then line up, only the first one in the line-up will ever execute. remove the else from your if block. treat each if as its own thing. i.e.
if(now-then >=0) { /* do thing 1*/ }
if(now-then >=1000) { /* do thing 2*/ }
if(now-then >=2000) { /* do thing 3*/ }
if(now-then >=3000) { /* do thing 4*/ }

that way, even if the conditions line up, all the blocks will be checked, and all the if's that resolve true, will execute.

your code will result in sequence 1, 1, 2, 1, 2, 3, 1, 2, 3, 4

You need a stamp for every thing x because you'll have to reset each of them to the current millis when the thing gets executed.


text:
LCD I2C connection problems
I am hoping there is a simple fix to this problem.
I am playing around with a 16x2 lcd with a I2C connector attached. I wired it up to an elegoo uno R3.
I started with some code I've used before and ended up with one row of the LCD fully lit and the other dark.
After a ton of trouble shooting, I can not get the LCD to show anything but one lit and one dark row.

In this image:
Power: 5V, 1.5A

Pin
LCD
Uno

SCL
SCL
SCL

SCA
SDA
SDA

+
VCC
5V

gnd
gnd
gnd

I've also tried:

putting the SDA to A4 and the SCL to A5
Using different power supplies
Powering from the USB connector

And I've tried several of the libraries available
They are all variations of the following from the Adafruit_LiquidCrystal library:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Set the LCD address to 0x27 for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup()
{
    // initialize the LCD
    lcd.begin();

    // Turn on the blacklight and print a message.
    lcd.backlight();
    lcd.print("Hello, world!");
}

void loop()
{
    // Do nothing here...
}

No matter what I do the display does not change.

There should be a potentiometer for the contrast. Turning it ccw will make the text visible

I've played with that. There is no position where text is visible. The top row is fully lit and the bottom row off. When I turn the pot, the lit crystals dim evenly to nothing.

Maybe try an I2C scanner to verify the I2C address which your code assumes is 0x27

That fixed it. The scanner found the i2c at 0x3f. Everything is working. Thank you!

@6v6gt, if you could create an Answer and Andrew if you could accept it, that would make this Q & A perfect for anyone else in the same predicament.

Some common problems with LCD displays which incorporate an I2C backpack include:

Not using the correct I2C address for the I2C backpack. Use an I2C scanner to discover the correct address.
Mixing voltages without proper level shifting, say using a 5v display with a 3.3v MCU
Failing to adjust the contrast potentiometer
Some I2C backpacks may use a non-standard pin allocation which may be corrected by specifying a pin mapping in the constructor to the display library. Fortunately, this is rare.
Using code samples intended for a different variant of the library supporting the display. Always use a basic test sketch which is packaged with the chosen library to verify the performance of the display.

Apparently I have the same problem. I did what was said over and over again but I couldn't get a display. I found that my problem was due to a manufacturer's defect. The 5th pin (rw) from the left of the I2C package was not soldered at all. However, I had seen this pin unsoldered before and thought it should be like that. I hope it helps someone.


text:
NodeMcu V3 & BMe280 -> Temperature, Humidity, Pressure: value nan
I've just started playing around with a NodeMcu V3 and a BME280 sensor.

wiring
VCC -> 3.3V
GND -> GND
SCL -> D1 (GPIO5)
SDA -> D2 (GPIO4)

I've tried this sketch /  I2C scanner: it finds the BME280 at 0x76
#include <Wire.h>

// Set I2C bus to use: Wire, Wire1, etc.
#define WIRE Wire

void setup() {
  WIRE.begin();

  Serial.begin(9600);
  while (!Serial)
     delay(10);
  Serial.println("\nI2C Scanner");
}

void loop() {
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    WIRE.beginTransmission(address);
    error = WIRE.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");

  delay(5000);           // wait 5 seconds for next scan
}

Then I've tried library BMx280I2C into this sketch:
#include <Wire.h>
#include <BMx280I2C.h>

BMx280I2C bmx280(0x76);

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

  // Setup BMx280
  Wire.begin();
  bmx280.begin();
  bmx280.resetToDefaults();
  bmx280.writeOversamplingPressure(BMx280I2C::OSRS_P_x16);
  bmx280.writeOversamplingTemperature(BMx280I2C::OSRS_T_x16);
  bmx280.writeOversamplingHumidity(BMx280I2C::OSRS_H_x16);

}

void loop() {

  // T,P,H measurements
  bmx280.measure();

  do{
    delay(100);
    Serial.println("No value, yet!");
  } while (!bmx280.hasValue());

  Serial.print("Pressure ");
  Serial.println(bmx280.getPressure());

  Serial.print("Temperature ");
  Serial.println(bmx280.getTemperature());

  Serial.print("Humidity ");
  Serial.println(bmx280.getHumidity());

  delay(1000);

}

the output is always and only:

-> No value, yet!
-> Pressure nan
-> Temperature nan
-> Humidity nan

Why? How can I understand the origin of the problem?Thanks!

Did you run the BMx280_I2C example sketch? Did it function correctly>

For ESP8266, you need to call Wire.begin(D2, D1); or Wire.begin(4, 5); instead of just Wire.begin().

@hcheung set  Wire.begin(D2,D1); but same behaviour

The begin() method on BMx280I2C  returns an indication of whether it succeeds or not. You should check it. Also CSB should be connected to VCC to force the I2C interface.

@StarCat same result
21:31:30.943 -> Pressure: nan
21:31:30.943 -> Pressure (64 bit): nan
21:31:30.977 -> Temperature: nan
21:31:30.977 -> Humidity: nan

With this libary https://github.com/Erriez/ErriezBMX280 (example in the same page) I obtain values! But are always the same... For example always Temperature: -142.46

Do you check for errors when you use that library? The code you posted doesn't.

Solved with Adafruit library
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME280 bme;

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

  if (!bme.begin(0x76)) {
    Serial.println("Could not find a valid BME280 sensor, check wiring!");
    while (1);
  }
}

void loop() {
  Serial.print("Temperature = ");
  Serial.print(bme.readTemperature());
  Serial.println(" *C");

  Serial.print("Humidity = ");
  Serial.print(bme.readHumidity());
  Serial.println(" %");

  Serial.print("Pressure = ");
  Serial.print(bme.readPressure() / 100.0F);
  Serial.println(" hPa");

  Serial.print("Approx. Altitude = ");
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(" m");

  Serial.println();

  delay(2000);
}


text:
MKR 1000 not found in ports when MKR IMU Shield is connected
I am trying to connect my MKR IMU Shield to my MKR1000 by placing the IMU shield in the MKR1000. When I do this, however, the Arduino IDE and Simulink are unable to find the port that my Arduino is connected to.
However, when my IMU shield is not connected to my MKR1000, the port can be found properly, and the code can be uploaded to the board. When I plug my IMU shield into my MKR1000 after the code has uploaded, my project crashes with an error.
Any ideas on how I can correct this so that I can able to connect to my MKR1000 when the IMU shield is plugged in? Thank you for all your help.

a damaged shield?

@Juraj Also, when the shield is plugged into the board, the shield becomes very hot. Could this also be a sign of a damaged shield?

a basic question: the pin labels match on MKR and shield?

@Juraj Yes, the pins match up when I plug the shield into the MKR. Thank you for your help!


text:
How to deal with global variables in a program which has more than 5 functions and every function accesses them without any problem?
I know that using Global Variables in programming may create lots of problems in long term , like , Bugs , Lags and more . I am working on a program which has more than 5 functions which need to access global variables something like this.
int Name;
int Age;
int Weight;
String EyeColour;

void AddValues(int N, int A , int W , String EC){
    Name = N;
    Age = A;
    Weight = W;
    EyeColour = EC;
}

// All the functions below use those Global Variables

void function2(){
    ...
}

void function2(){
    ...
}

void function3(){
    ...
}

void function4(){
    ...
}

 void function5(){
    ...
 }

But according to this article
I should avoid using global variables to avoid future problems so I wrapped them up inside a struct.
Like this.
struct Person{

int Name;
int Age;
int Weight;
String EyeColour;

}

Now my main question is, should I declare the structure variable globally? Will it avoid the problems which could be created by global variables ?
If I declare the struct variable globally will it be equivalent to declaring variables globally instead of the structure?
Or
Should I declare the structure variable inside all the functions instead of declaring globally?
So that all functions can work flawlessly without any global variable problems.

This seems to be a general C/C++ question rather than an Arduino question. To amswer the general question--it depends, looks like a canonical class example.

This is actually relevant to Arduino programming, or any chip with small memory.  The cited article is fine for big systems, but when memory is tight there are other considerations that may make it worth your time keeping track of globals.  In big systems we can expect the automatic stack handling to take care of everything in the background without having to think about stack and/or heap crashing into working memory.  Not so when you only have 2K total... and stack collisions can be pretty mysterious!

Dwelling on this question for academic purposes or extreme cases (where there's lots of data (i.e. audio sampling)) is great.  But most Arduino programs I have seen do not use that many variables.  So making Arduino sketch variables global (notice I'm not including Arduino libraries!) is likely fine.

globals are to be generally avoided when feasible, not 100% banned always.

Create a class from the 4 variables (I don't have a compiler at hand, so forgive any compiler errors):
class Person
{
public:
    void Person(int N, int A , int W , String EC);

private:
    int Name;
    int Age;
    int Weight;
    String EyeColour;
}

Create the implementation of Person in the Person.cpp file.
About the functions, if they only relay (or mostly rely) on the 4 properties (Name, Age, Weight, EyeColor), make the a method (function) inside the class.
Decide if a function should be in a method depends upon  many thing, but the most important question is: does it belong (well enough) to the class or not?
Now in the Arduino.ino you can make one instance (or more if you need more).
Person _person;

Preferably, I add an underscore for global variables (and instance variables).
Also, I would avoid using String as changing it will cause dynamic memory allocation changes, which can be very bad in a 2K SRAM system. Try to make constant string arrays (with a max length).

Better still, eye colour could be an enum...

@Majenko Indeed, if the number of possibilities is fixed (gender used to be a boolean)


text:
What happens if Millis() method variable goes out of it's capacity?
I am now working on a project which is expected to last at least 5 years from the time it is completed. In that project, i can not use delay() for some purposes so I am using millis() method
unsigned long Then = 0;
unsigned long Threshold = 1000;

void setup(){
    // Codes
}

void loop(){
    unsigned long Now = millis();
    if(Now-Then>=Threshold){
        // Execute a function or functions
        Then = Now;
    }
}

Now in this code wee can see the variable 'Then' and 'Now' are getting updated whenever threshold is met.
So now, suppose after a certain period of time (without any switch off), if any one of the two ever-updating variables which are 'Now' or 'Then' gets a value which is out of range for 'unsigned long' type
Will the ic continue to behave normally or will it malfunction?
Thank you!

let say millis() rolled over to 5 and the last count was 12345678: (5-12345678) > 1000; no problem.

In the unsigned arithmetics it results into distance between those two numbers, so it'll be fine. (negative numbers are stored in two's complement)

Well I don't care about rollovers or overflows until my system starts malfunctioning.


text:
Can I run more than 2 servo motors smoothly, connecting their power to regulated limit voltage and signal wires to the digital pins of the arduino?
Now my next project is going to be about Servo Motors and for that, I don't want to buy any shield or motor driver for Servos. So I have designed a circuit, to drive 12 servos at a time without any interruptions. I haven't got any Servos yet, well my order is shipped already...Keeping that aside lets head down to the connection..

The Screenshot was taken from a circuit designed by me at tinkercad.com.
Parts:

HiWatt Battery (Standard 9 volts battery blue and white coloured)

SG90 Servo Motor
(6v 400mah max)
(Resistance of each of them is 1.4kohm, when connected power and ground of multimeter)

Arduino
(Required amp is 40*12)

The circuit Explanation:

The Orange wires of servos are signal wires connected to the pins of Arduino.

A 750 ohm resistor is connected to the positive terminals of each motor, from which, voltage is regulated for the motor.

The motor grounds have been connected to the ground of the battery.

Ground of Arduino has been connected to the ground terminal of the battery. So now, ground of the battery and the Arduino is same.

All the motors are connected in parallel connections with 750 ohm resistors at the positive terminal of each motors

So now my question is, How many servos will I be able to run when I power them parallel-ly using a standard 9 volts battery (HI-WATT, Blue and white one), if no, Which will be the best battery for doing it?
I need to run 12 Servos uninteruptedly.
Thanks for your precious time....

So now my question is, How many servos will I be able to run when I power them parallel-ly using a standard 9 volts battery (HI-WATT, Blue and white one), if no, Which will be the best battery for doing it?

Unfortunately: Zero motors with your current circuit. Maybe one motor with a better circuit and the same battery. Here is the explanation.

You should ditch the standard 9V block battery. These batteries are made for low power applications (like IR remotes or smoke sensors) and cannot provide enough current for driving all those motors. They might be able to drive one servo, but still will be drained very fast. You should use a battery, that can provide much more current. Which battery you choose also depends on your other requirements. A series of AA alkaline batteries can give you enough current. Or you can directly buy a LiIon or LiPo rechargeable battery (including a fitting charger board). They can provide way enough current.

You cannot just use simple resistors as voltage regulators. That just doesn't work for loads, that can draw a changing amount of current (like a motor).

The voltage, that the motor gets, depends on the current, that the motor draws. When the motors stands still, it will draw very little current. Thus the motor is getting the full 9V in that case. As the drawn current rises, the voltage will go down, until the motor gets not enough voltage to operate correctly.
The resistor of 750 Ohm restricts the current draw of the motor. Even when we (for the sake of calculation) treat the motor as a short circuit, the maximum current through the resistor with 9V will be only 12mA, so way way lower than the 400mA, that you stated in your question. You won't be able to move the motor much with that little current.
Even if you used a smaller value, you need to be careful with the current. I guess you are using standard resistors there, which typically have a power limit of about 0.25W. These are meant for rather low current circuits. With the 400mA @ 6V, that your motors need, you are in the region of 2.4W (that is not necessary the power for the resistor, just a value for you to see the relation). You can easily burn away a little resistor that way. When you need a resistor with a higher power limit, you need to buy one, which can handle it (and these are typically multiple times the size of a standard "signal" resistor and still can get very hot, when used in the realm of their power limit).

Instead you should buy a proper voltage regulator. At that current, buy a switching buck regulator, as they are way more efficient than linear regulators. Which regulator you need to buy also depends on the voltage of the battery, that you choose. Be sure to buy a regulator, that can provide significantly more current, than we need in total for your circuit. This is important, because regulators are typically described with a maximum current, at which they already need extra measures for cooling. When you stay well below that, you can avoid thinking about fitting cooling for it.

So , will it control the motors as good as 16 channel servo drivers?

Yes, it can. Though you need to think about how you are controlling the servos on the Arduino. The standard Servo library supports up to 12 servos with one timer. When you can change the library to use 2 Timers for supporting more servos, then you have it. You could also try to search for other libraries, which support more servos, or write your own library. I would say, using the driver would be simpler. The driver does not switch the power for the servos. It has a chip, which can output 16 servo control signals and is controllable over an interface like I2C or SPI.
If you want to use such a driver is up to you. You might find it more important to have as few electronic parts as possible.

So, I just need to divide the current using a Voltage Regulator? So volt will remain constant, then, I guess the 750 ohm resistors won't be useful. Am I right?

Yes, a fitting voltage regulator will give you the correct voltage and will hold it constant (as long as you don't overload it). Voltage regulators are way more complex internally as a simple resistor. And yes, when using a proper voltage regulator, you should ditch the resistor.

The parallel connection of motor terminals should be connected to the voltage regulator output without any 750 resistor , and the battery should input the 9 volt in the regulator. Right? So , will it control the motors as good as 16 channel servo drivers?

I added a short explanation about the controls signals. Your question is mainly about the power supply. It is independent of the decision, if you want to use a driver. The power supply only gives the power to the servos, while the driver has a chip to generate the control signals.

Thanks for your precious time

Only 1 Voltage regulator would be enough right, I shouldn't require voltage regulator for each of the motors right?

Yes, one is enough, as long as it can provide enpugh current for all motors

Thanks again bro


text:
Standalone ATmega clock continuous lifetime
Here I have made a standalone ATmega328p clock without
any RTC module using the breadboard ATmega328p , LCD I2C , and some buttons which I would like to turn on for atleast an year (supposed to be without any reset or power-interrupts).
I am powering my ATmega using an old mobile charger (5v , 500mA) of a old broken Android.
However I am not using any millis() or something alike these in the clock code,
So how long will my clock run if is it supposed to be online 24/7
Should I reset it sometimes?
If yes , when, after how many days should I reset it?
And do I need a coolant system for it? (I guess not)
Thanks for your precious time .

I like to enable the watchdog timer inside the ATMega328, so that, if my code ever hangs, the mcu will reset itself.

@Gerben, can u please give me the board manager link for bootloading 8mhz internal clock in Atmega328p u

You can use the bootloader used for the 8Mhz 3.3V Arduino Pro mini, but alter the fuse settings so it uses the internal oscillator, instead of a crystal. I hope that helped. Otherwise, create a new question so everyone can help you, instead of just me.

So how long will my clock run if is it supposed to be online 24/7

Until you turn it off or a stray neutrino corrupts the flash memory, or the flash memory degrades (20-100 years or so depending on temperature).

Should I reset it sometimes? If yes , when, after how many days should I reset it?

No.

And do I need a coolant system for it? (I guess not)

No. Not unless it's in a sealed container with no ventilation and a hot environment.
However
Your RTC-less "clock" will probably not be particularly accurate, unless you have some external source of time (NTP, GPS, etc) as the Arduino's internal timing is not very accurate, and built on a breadboard it's even less so due to excess stray capacitance.

My standalone ATmega clock runs 1 min slower than original clock (till yet), I have used 5 buttons for fixing them manually. If I don't touch it for 5-7 days, will the time of ATmega run more slowly or will continue this 1 minute difference from RTC in future?

Yes. It will do one of those. That's as accurate as I can be. Only time will tell.

What do u mean by one of those? Please clear it to me

I can't be clear. There is no answer. The clock will either run fast (gain time), run slow (lose time) or run the same (keep time). It is impossible to know what until you actually run the clock and measure the time. It is far more likely to drift over time that be the real time, but will it run fast or slow? That's not possible to know without measuring it.

Thank you for your kind answer :)

Interesting. Atmel's flash-based "ATmega" microcontrollers typically promise retention times of 20 years at 85 °C (185 °F) and 100 years at 25 °C (77 °F). I didn't know that.

Two additional points if I may. First, don't expect two Arduinos to run at the same speed, particularly if they are clocked by a resonator rather than a crystal. Second, avoid all dynamic memory allocation since unless carefully organised you will eventually have a fragmented heap and things will no longer work as you intend.


text:
fixing communication port errors
the communication port (com11) is yellowed with exclamation marks in device manager and I am unable to run arduino on my computer. how to get rid of the yellow exclamation mark on the com 11?

I guess you are using Windows? You might need to install the correct driver. Do you have a genuine Arduino, or one of the cheap clones? (They use different USB to Serial chips)

how do I know if it is genuine or clone in the first place?

It's written on it or on the box it came in.

Provide a link to the actual thing you bought.


text:
Need help with millis () function for two linear actuators
Last week I was grateful to receive help programming the Arduino to control two linear actuators.
I need help re-writing the code using the millis () function. I am more than happy to reimburse for time spent on this project. This is my first experience with Arduino and millis () is too involved for me.
The actuators control a set of barn doors in my house. The actuators are programmed to open and close with the push of a button (z-wave relay programmed as 6 second momentary switch). The actuators do not give feedback, so the program is used to control the speed from 0-255 using the PWM ports to make the actuators appear somewhat in sync. They move at three different speeds so that they don't slam when opening and closing. This is where millis () comes in. Right now I am using a delay to control the speed for various amounts of time, but using a delay creates a safety issue since the Arduino cannot do anything during this time.
The reason I need to utilize the millis () function is that I need to be able to make the doors stop and reverse in the event that there is something blocking their path. To accomplish this I will be using a garage door electric eye wired through a homemade circuit board. The output will go low any time the beam is broken and otherwise it will remain high. I'd like the Arduino program to utilize this signal any time the doors are closing and if the beam is broken - make the actuators reverse direction. I realize that without feedback I cannot make the doors open all the way depending on when the beam is broken. I am really not too concerned about that. As long as they stop and reverse for at least a little bit I will be happy. I don't want to crush my kids or pets.
Again, I am more than happy to reimburse anyone willing to help write the code for this. Here is the code I am using now which utilizes the delay function. I'd like this code to be changed to utilize the millis function and also add in programming for the sensor as described above.
/* Program enables momentary direction control of actuator using push button
 */

int RPWM = 10; //connect Arduino pin 10 to IBT-2 pin RPWM
int LPWM = 11; //connect Arduino pin 11 to IBT-2 pin LPWM
int RPWM2 = 5; //connect Arduino pin 5 to IBT-2 pin RPWM
int LPWM2 = 6; //connect Arduino pin 6 to IBT-2 pin LPWM
int downPin = 12;
int upPin = 13;
int speed1 = 0; // Top speed you can change it between [0-255]
int speed2 = 0; // Low speed you can change it between [0-255]
int speed3 = 0; // Low speed you can change it between [0-255]

void setup() {
  pinMode(RPWM, OUTPUT);
  pinMode(LPWM, OUTPUT);
  pinMode(RPWM2, OUTPUT);
  pinMode(LPWM2, OUTPUT);
  pinMode(downPin, INPUT_PULLUP);
  pinMode(upPin, INPUT_PULLUP);
}

void loop() {
  if(digitalRead(upPin)==LOW){ //check if extension button is pressed
    analogWrite(RPWM, 0);
    analogWrite(RPWM2, 0);
    analogWrite(LPWM, 255); // rotate motor with top speed
    analogWrite(LPWM2, 245); // rotate motor with top speed
    delay(3000);               // wait for x sec
    analogWrite(LPWM, 180); // rotate motor with low speed
    analogWrite(LPWM2, 176); // rotate motor with low speed
    delay(1500);               // wait for x sec
    analogWrite(LPWM, 80); // rotate motor with low speed
    analogWrite(LPWM2, 80); // rotate motor with low speed
    delay(1500);               // wait for x sec
    analogWrite(LPWM, 0);     // uncomment if you want to stop motor now
    analogWrite(LPWM2, 0);     // uncomment if you want to stop motor now
  }

  else if(digitalRead(downPin)==LOW){ //check if retraction button is pressed
    analogWrite(LPWM, 0);
    analogWrite(LPWM2, 0);
    analogWrite(RPWM, 250); // rotate motor with top speed
    analogWrite(RPWM2, 255); // rotate motor with top speed
    delay(3000);               // wait for x sec
    analogWrite(RPWM, 165); // rotate motor with low speed
    analogWrite(RPWM2, 165); // rotate motor with low speed
    delay(1500);               // wait for x sec
    analogWrite(RPWM, 80); // rotate motor with low speed
    analogWrite(RPWM2, 80); // rotate motor with low speed
    delay(1500);               // wait for x sec
    analogWrite(RPWM, 0);     // uncomment if you want to stop motor now
    analogWrite(RPWM2, 0);     // uncomment if you want to stop motor now
  }

  else{ //if no button is pushed, remain stationary
    analogWrite(RPWM, 0);
    analogWrite(LPWM, 0);
    analogWrite(RPWM2, 0);
    analogWrite(LPWM2, 0);
  }
}

You should not rely on Arduino code at all, millis or otherwise, for your safety features.  More broadly you should not rely on software at all when it comes to not crushing your kids or pets.

Definitely open to other suggestions.... The actuators are only rated 20lbs. I’ve let the doors close on me and it is not bad at all... but, still would prefer the doors not close on things.

I'm not sure I'm all that comfortable advising you on this.  But, if your actuators are responsible for different directions, it seems at a minimum the door closing on something should mechanically interrupt the power going to the actuator that closes the door and it should probably latch into this interrupted position such that it manual intervention is required to make it operate again.

Each actuator has adjustable overcurrent protection. It works ok to cut power to the actuators if the doors bump into something, but I’m hoping to actually have the doors reverse before bumping into anything. After-all don’t our garage doors rely on software for the same type of safety function?

Also note - My backup plan if I can’t get this working with the Arduino is to connect the electric eye to a couple of relays that would reverse polarity to the actuators in the event the beam is blocked - causing the doors to reverse direction. This would be one method that avoids using software. Could also cause the doors to close on something if the beam is blocked while the doors are opening... so not ideal!

You've come to the requirement called non-blocking programming. The gist of it is that your loop() function does little other than call a number of "maybe-do" functions - my name for functions that assess the need to act, and act or not, and return, as quickly as possible. So in pseudo-code, your loop might look something like:
void loop(){
   maybeStartMotor1();
   maybeSlowMotor1();
   maybeStartMotor2();
   maybeSlowMotor2();
   maybeStopMotor1();
   maybeStopMotor2();
   // Call maybe-do()s for ... whatever else might need to happen
}

Your maybe functions would probably look like, e.g.:
maybeSlowMotor1(){
if( millis() - millis_at_motor1_start > DECELTIME2 )
set motor1 to slow speed;
else if( millis() - millis_at_motor1_start > DECELTIME1 )
set motor1 to medium speed;
return;
}
Note that my understanding of your mechanical system is limited and the above is meant to describe a software technique, not a solution.
Also note my complete agreement with @timemage's caution against depending on software for your safety interlocks. Your 3rd comment under your question - to directly reverse the doors with photocells and relays - in addition to the software detection and control - provides a necessary redundancy.
I'd also like to refer you to this somewhat more complete description I wrote to answer another, similar, question.

Thank you for your answer. I am just a total noob to Arduino and this is outside my wheelhouse. Perhaps the simplest solution for me would be to use the electric eye to simply cut power to the actuators in the event the beam is blocked. Reversing direction would be nice, but to have it function properly would require software/programming.

Use the electric eye / stop actuators first. Then you can work on the software, a little at a time, and not have to do the "would be nice" parts of it up front. With the worst-case covered, you can experiment with the software a little at a time without being able to leave any glaring safety issues.

That’s what I’ll do. I’d still be more than happy to pay someone to do the programming for me if there are any takers! If I just had something to work with I bet I could get it functioning properly.

@ChrisGroat, get in touch w/me through my profile.


text:
Printing vairable with U8GLib
I have this code that takes temperature and humidity values from a DHT11 sensor and number of faces from an external python code and prints them on an OLED screen but instead of values of variables it keeps printing 0, how can I solve it? (Sorry some parts are not in English but just consider them as random variable names.)
//dht11 kodu için ayarlamalar
#include <dht.h>
dht DHT;
#define DHT11_PIN 7

//ekran için ayarlamalar
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0);
char bufferX [20];
char bufferY [20];
char bufferZ [20];

//fan kodu için ayarlamalar
int mot1 = 8;
int mot2 = 9;
int en1 = 10;
int dir = 6;
bool state = true;
int nob = A0;
int val = 0;
int fan_hizi = 0;
String faces_str;
int faces;
float sicaklik;
float nem;

void draw(void)
{
  u8g.setFont(u8g_font_unifont);
  u8g.drawStr( 0, 15, bufferX);
  u8g.drawStr( 0, 30, bufferX);
  u8g.drawStr( 0, 45, bufferY);
  u8g.drawStr( 0, 60, bufferZ);
}

void setup() {
  Serial.begin(9600); //iletişim ve dht11 verisi

  // pin ayarları
  pinMode(mot1,OUTPUT);
  pinMode(mot2,OUTPUT);
  pinMode(en1,OUTPUT);
  pinMode(dir,INPUT_PULLUP);
}

void loop() {
  //dht11 kodu
  sicaklik = DHT.temperature;
  nem = DHT.humidity;
  delay(1000);

  //iletişim kodu
  if(Serial.available() > 0) {
    faces_str = Serial.readString();
    faces = faces_str.toInt();
  }

  Serial.print(faces);

  //sınırlar
  if(faces == 0 && sicaklik < 25 && nem < 65) {
    fan_hizi = 50;
    digitalWrite(13, HIGH);
    digitalWrite(12, LOW);
  }
  if(faces >= 1 || sicaklik >= 25 || nem >= 65) {
    fan_hizi = 250;
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);
  }

  //ekran
  sprintf(bufferX, "Yuzler: %d", faces);
  sprintf(bufferY, "Sicaklik: %d", sicaklik);
  sprintf(bufferZ, "Nem: %d", nem);
   u8g.firstPage();
  do {
  draw();
    }
  while ( u8g.nextPage() );
  delay(10);

  //fan kodu
  analogWrite(en1, fan_hizi);
  digitalWrite(mot1, HIGH);
  digitalWrite(mot2, LOW);
  delay(1000);
  digitalWrite(mot1, LOW);
  }

maybe it is printing a 0 because it is receiving a 0 ... do some debugging

I do not understand, how you initialize the DHT sensor object.
(I wonder why this compiles at all.)
Your way:
//dht11 kodu için ayarlamalar
#include <dht.h>
dht DHT;
#define DHT11_PIN 7

I would use:
//dht11 kodu için ayarlamalar
#include <DHT.h>
#define DHT11_PIN 7

DHT dht( DHT11_PIN, DHT11 );

Don't forget to start the DHT object with:
void setup() {
  // ... code removed for brevity
  dht.begin();
}

Now use the dht object instad of the DHT class.
sicaklik = dht.readTemperature();
nem = dht.readHumidity();

You did not specify what libraries you have used. But I tried all DHT libs I could find and none of them compiled with your code without errors.
The following code compiles on my IDE for an arduino UNO having olivers ug8lib and adafruits DHT sensor library installed. BTW: You even did not mention the Arduino/ESP you used. So I guess it is an UNO.
//dht11 kodu için ayarlamalar
#include "DHT.h"
#define DHT11_PIN 7
DHT dht( DHT11_PIN, DHT11 );

//ekran için ayarlamalar
#include "U8glib.h"
U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_DEV_0);
char bufferX [20];
char bufferY [20];
char bufferZ [20];

//fan kodu için ayarlamalar
int mot1 = 8;
int m ot2 = 9;
int en1 = 10;
int dir = 6;
bool state = true;
int nob = A0;
int val = 0;
int fan_hizi = 0;
String faces_str;
int faces;
float sicaklik;
float nem;

void draw(void)
{
  u8g.setFont(u8g_font_unifont);
  u8g.drawStr( 0, 15, bufferX);
  u8g.drawStr( 0, 30, bufferX);
  u8g.drawStr( 0, 45, bufferY);
  u8g.drawStr( 0, 60, bufferZ);
}

void setup()
{
  Serial.begin(9600); //iletişim ve dht11 verisi

  // pin ayarları
  pinMode(mot1,OUTPUT);
  pinMode(mot2,OUTPUT);
  pinMode(en1,OUTPUT);
  pinMode(dir,INPUT_PULLUP);
}

void loop()
{
  //dht11 kodu
  sicaklik = dht.readTemperature();
  nem = dht.readHumidity();
  delay(1000);

  //iletişim kodu
  if(Serial.available() > 0)
  {
    faces_str = Serial.readString();
    faces = faces_str.toInt();
  }

  Serial.print(faces);

  //sınırlar
  if(faces == 0 && sicaklik < 25 && nem < 65)
  {
    fan_hizi = 50;
    digitalWrite(13, HIGH);
    digitalWrite(12, LOW);
  }

  if(faces >= 1 || sicaklik >= 25 || nem >= 65)
  {
    fan_hizi = 250;
    digitalWrite(13, LOW);
    digitalWrite(12, HIGH);
  }

  //ekran
  sprintf(bufferX, "Yuzler: %d", faces);
  sprintf(bufferY, "Sicaklik: %d", sicaklik);
  sprintf(bufferZ, "Nem: %d", nem);
  u8g.firstPage();

  do
  {
    draw();
  }  while ( u8g.nextPage() );

  delay(10);

  //fan kodu
  analogWrite(en1, fan_hizi);
  digitalWrite(mot1, HIGH);
  digitalWrite(mot2, LOW);
  delay(1000);
  digitalWrite(mot1, LOW);
}

I do not have the time to assemble the hardware to try it.
So I can say it compiles, but I can not say it works.
EDIT:
Now I found adidax "DHT11 lib". your code compiles with this library. But you forgott to read the values from the sensor, before you read them from the variables.
The following line is missing:
void loop() {
  //dht11 kodu
  DHT.read( DHT11_PIN ); // <-- this line is missing
  sicaklik = DHT.temperature;
  nem = DHT.humidity;
...

thank you for your answer. i'm pretty new in arduino. yes, i used a uno board. and about dht11, i used a code i found online. i don't know how exactly it works.


text:
Ethernet Shield Not Working With TFT Screen
I'm trying to stack up Arduino UNO, Ethernet Shield and Waveshare 2.8" TFT Shield. Since I'm new to this I'm mostly doing basic stuff.
I successfully manage to get ethernet shield and TFT shield to work individually. Then since TFT shield will not be able to use the ICSP interface I connected the jumpers as it says on wiki.

Hardware configuration

When using the Arduino board with ICSP interface, the jumpers SB1,    SB2 and SB3 on the LCD module should be kept open.
When using the Arduino board without ICSP interface, the jumpers SB1,    SB2 and SB3 on the module should be connected with a 0R
  resistor,    respectively.

After this I put everything together and try to get them working with the below code but for some reason I don't know, Ethernet shield stopped working. I get the error Ethernet shield was not found.  Sorry, can't run without hardware. :(. Even though the error, my TFT screen lights up and runs demo. Probably I'm missing something simple. I'll appreciate any help or guidance.
#include <stdint.h>
#include <LCD.h>
#include <SPI.h>
#include <Ethernet.h>

IPAddress server(192, 168, 0, 107);
IPAddress ip(192, 168, 0, 177);
IPAddress myDns(192, 168, 0, 1);
IPAddress gateway(192, 168, 0, 1);
EthernetClient client;
byte mac[] = {0x90, 0xA2, 0xDA, 0x00, 0x23, 0x36};

void setup()
{
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  /*--------- TFT Init -------------*/
  SPI.setDataMode(SPI_MODE3);
  SPI.setBitOrder(MSBFIRST);
  SPI.setClockDivider(SPI_CLOCK_DIV4);
  SPI.begin();
  Tft.lcd_init();
  /*--------- TFT Init End -------------*/

  /*--------- Ethernet Setup -------------*/
  Serial.println("Initialize Ethernet with DHCP:");
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    if (Ethernet.hardwareStatus() == EthernetNoHardware) {
      Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    } else if (Ethernet.linkStatus() == LinkOFF) {
      Serial.println("Ethernet cable is not connected.");
    }
    // no point in carrying on, so do nothing forevermore:
    // while (true) {
    //   delay(1);
    // }
  }
  // print your local IP address:
  Serial.print("My IP address: ");
  Serial.println(Ethernet.localIP());
  /*--------- Ethernet Setup End -------------*/

  /*--------- Ethernet Connection Demo Setup -------------*/
  if (client.connect(server, 3000)) {
    Serial.print("connected to ");
    Serial.println(client.remoteIP());
    // Make a HTTP request:
    client.println("GET / HTTP/1.1");
    client.println("Host: localhost");
    client.println("Connection: close");
    client.println();
  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  beginMicros = micros();
  /*--------- Ethernet Connection Demo Setup End -------------*/
}

void loop()
{
  /*--------- TFT Demo -------------*/
  Tft.lcd_clear_screen(WHITE);
  for (int x = 1; x <= 240; x++) {
    for (int y = 1; y <= 320; y++) {
      Tft.lcd_draw_rect(x, y, 1, 1, RED);
      delay(1);
    }
  }
  /*--------- TFT Demo End -------------*/

  /*--------- Ethernet Check-Up ---------*/
  switch (Ethernet.maintain()) {
    case 1:
      //renewed fail
      Serial.println("Error: renewed fail");
      break;

    case 2:
      //renewed success
      Serial.println("Renewed success");
      //print your local IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      break;

    case 3:
      //rebind fail
      Serial.println("Error: rebind fail");
      break;

    case 4:
      //rebind success
      Serial.println("Rebind success");
      //print your local IP address:
      Serial.print("My IP address: ");
      Serial.println(Ethernet.localIP());
      break;

    default:
      //nothing happened
      break;
  }
  /*--------- Ethernet Check-Up End ---------*/

  /*--------- Ethernet Demo ---------*/
  int len = client.available();
  if (len > 0) {
    byte buffer[80];
    if (len > 80) len = 80;
    client.read(buffer, len);
    if (printWebData) {
      Serial.write(buffer, len); // show in the serial monitor (slows some boards)
    }
    byteCount = byteCount + len;
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    endMicros = micros();
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
    Serial.print("Received ");
    Serial.print(byteCount);
    Serial.print(" bytes in ");
    float seconds = (float)(endMicros - beginMicros) / 1000000.0;
    Serial.print(seconds, 4);
    float rate = (float)byteCount / seconds / 1000.0;
    Serial.print(", rate = ");
    Serial.print(rate);
    Serial.print(" kbytes/second");
    Serial.println();

    // do nothing forevermore:
    // while (true) {
    //   delay(1);
    // }
  }
  /*--------- Ethernet Demo End ---------*/
}

From examining the schematics of the Ethernet shield as well as the TFT shield, it looks like the Chip Select (CS) pin of the Ethernet shield uses the same pin (Arduino pin D4) as the Interrupt pin of the Touch Panel on your TFT shield (TP_IRQ) in the schematic.
I don’t think you can solve this without modifying any hardware. Either the TFT shield or the Ethernet shield should be modified to use a different pin, and these modifications should be reflected in the underlying library.
My guess is the Ethernet shield would be easiest to modify as its PCB can be reached from two sides. You could also cut the D4 pin from the TFT shield and connect its PCB trace to an unused digital pin via a short wire.

The error message is from the ethernet library. As I do not have the sufficient hardware to test this indicates a pin conflict. So the ethernet shield v1 uses/needs one or more pins the LCD shield is using.How to find out dig into the circuit documenation and look at the used pins.Be aware that a lot of tuts/infos on the net are about ethernet shield v2 which is hardware differnt from v1.

Circuit schematics for Waveshare and Ethernet shield v1
Check also for shorts between USB (Arduino) / Ethernet plug and the above shields, I isolate them normaly with a piece of isolation tape (to be safe than sorry).

EDIT
Ethernet shield: Arduino communicates with both the W5100 and SD card using the SPI bus (through the ICSP header).
This is on digital pins 10, 11, 12, and 13 on the Uno.
Pin 10 is used to select the W5100 and pin 4 for the SD card.
These pins cannot be used for general I/O

The wave share uses CS=D10, RS=D7, RST=D9 and the SD CS can be defined on eg SD_CS 5 with this library as the waveshare lib is not usable other than basic playing around.
This lib is Adafruit_GFX compatible so a wide variety of programs and other libs work.
So your chance is

to remap the SD CS by software if the other pins pose no conflict (you have to test it) or
get an other Ethernet connector (not a shield because its more flexible) or
remap manually with dupont wires the LCD shield (because it's the top most) and change the according pins in the libs header file.

Do not cut traces or solder around its not worth the effort and you might break things

Thank you for your answer. First of all I did isolate the USB like you said when I first fit the shield. Secondly, since I can run the code above separately with no error I assume my code is good for my versions. Let's say there is a pin conflict. Do you have any idea/suggestion on how to fix that? Do you think I can set another pin for them just with code? Ethernet library has Ethernet.init(sspin) function. Does this mean I have to do some soldering? Thanks again.

See my edit and test the other TFT lib first without ethernet shield


text:
Arduino stopped showing up in /dev and dmesg without response
Arduino suddenly stopped being recognized.
It is not listed in /dev and
dmesg -w shows no activity at all when un/plugged.
I'm on Fedora 33. The Arduino is MKR-Zero. The cable is ok - other devices work well. I tried it on windows machine - same result - in Arduino IDE the option for port is greyed out.
Very weird thing happened before this issue- when I was trying to flash sketch, audio connected to docking station switched to speakers in laptop and keyboard + mouse connected to the docking station powered down (back light on keyboard went off and could not be turned on) however the Num lock light was on.
I'm afraid that I burned the Arduino - how do I verify if that is the case.
The "ON" LED is lit up when plugged in

Ok, I have no idea what the hell is this, but when I double-press the reset button (while connected/powered on ofc) it works again.
This can be seemingly cycled - press once and it goes wrong, press twice and it's ok again... round and round. Seems more like some retarded "feature"

It's a good feature that lets it stay in the bootloader longer for when you've screwed up the application area (sketch) so badly that it just drop off USB before you can put something else on it.

Dumb bastards put it at the top of the frequently asked questions list on the product page were you certain to never find it. =P

It would be nice to have it in documentation, but why bother, right?


text:
Does Adafruit PowerBoost 1000 Charger support data transfer?
As the title says - Does Adafruit PowerBoost 1000 Charger support data transfer?
I mean that if I connect USB on one side to PC and Arduino on other side - can I still program it and get serial monitor communication?
Are the data lines connected??

No it doesn't.
As you can see from the schematic the incoming data lines aren't connected, and the outgoing are wired through appropriate resistors to set the current availability.


text:
Arduino IDE Serial Monitor - how to send NUMBERs - not charcters of numbers
Serial link send and recieves Bytes. Serial monitor at Arduino IDE reads it's input as character.
So if I type '0' in serial monitor, then FW will read byte 48 - I don't want to implement some silly translation from character value to int - I want to input NUMBER as byte into serial monitor - how do I do that?
byte inByte = Serial.read(); // read the incoming byte
if(inByte == 1) // do stuff

use a serial terminal program, such as PuTTY ... or write a terminal sketch in Processing that does what you want

The Serial monitor of the Arduino IDE handles only characters, there is no way to send any byte you like.

It doesn't really matter what you want. You are under the mistaken impression that when you send a string (for example: 3.14159265358) you are sending a number. But you're wrong. Consequently, you will have to "implement some silly translation from character value to int", or learn how to use your available tools to do this for you.

On Linux you may xxd -r -p > /dev/ttyACM0 and then just type hex in the terminal.

instead of finding out the ascii code 49 you can simply write if(inByte == '1') // do stuff

they are all strings, you don't have strong types over serial.

@DataFiddler what if I want to send code with value 10, or 17 - instead of sending one Byte I have to send two bytes.

I was suggesting to question the task you want to achieve. You don' need "silly translations" if you want to recognize single bytes.  I admit, it's hard (OK. IMPOSSIBLE) with all 256 potential byte values. But it's easy to recognize all bytes SerialMonitor can send, without "silly translations".

@DataFiddler hmm, even in that case you limit the entire communication to single bytes only. No floats, no strings, etc.

Based on comments under question no one seems to really know the answer.
So the short answer is: IT'S IMPOSSIBLE - to use Arduino IDE serial monitor to send raw data.
@Edgar_Bonet submitted hint for linux users
@jsotola suggested to use PuTTY, but no additional info on how to do that. Short glance at settings and I couldn't find the way to achieve raw input.
After some additional googling i found some reading where I found program called RealTerm which does the job.
Simply setup your port on Port card and then hit Change button.
On card Display change Display As From ASCII to your prefered format, such as Hex(space)
Then swich on card Send - type your number into input box left to button Send Numbers and press that button
Thats all
The input box accepts decimal value from 0 to 255, or a hexadecimal value, which are prefixed with either a "0x" or a '$'. Each value is separated by space.
Following line is correctly accepted: "255 0xff 0xFF $ff $FF"
Yet another useful tool is Serial Port Monitor. With this you can observe what is really transmitted on line without relying on the interpretation of you application.
Usage is really simple: click white file icon, or Session > New session or press
Ctrl+N
Choose port and vizualizer and click Start monitoring... that's it.
I found most useful mode "Dump view"

I think the comments on your question are quite clear. The important point: any asynchronuous protocoll must include the info either how many bytes are transmitted or which byte is the last one. In "raw data", where each value (0-255) can be a legit data value, there is no way to use bytes for meta data. That's why typically only encoded data is transmitted: you have a small range of byte values that can contain the actual info (alphabet and digits) and you have a bunch of values that are free to be used as meta data. E.g. the commonly used \n as endbyte has the int value 10. How would you transmit the int value 10 in that case?
"I don't want to implement some silly translation from character value to int" - it's not silly, that's the way to go! What about float, boolean or negative values (8-bit, 16-bit, etc.)? You may even want to transmit structured data like python dictionaries. The only way the achieve this is using some kind of parser which knows the protocol.

Another weird but common "protocol" is a timeout, e.g. used in Arduino's Stream::readString().

I think you completely miss my point - I don't care about character transmission. I am creating my on communication protocol with commands, data transfer, responses and such. And if for any reason I want in some place to interpret the byte value as character there is no problem to implement it in my protocol. I just want to debug part of my protocol and inject the raw command. I store my commands as Enumeration, I just begun and have already more than 10 - so treating them as characters is certainly not the way to go.