Why my arduino code works only when conneted to a pc and IDE with the code is open?

As a school project, I'm making a pot with a soil moisture sensor. Moisture is displayed on an LCD display and when moisture is low the LED diode on the side will start blinking. The backlight of an LCD is controlled by a capacitive touch sensor. I'm using an Arduino Micro and everything is working fine when connected to a PC via micro USB and the IDE program is running with the code opened. But when I connect an Arduino to a power bank via micro USB the moisture is no longer measured and displayed on the LCD. The LED diode isn't working too. The only thing that happens is the LCD will display "soil moisture" with the backlight off. The touch sensor is no longer working too. I'm short on time please help someone.

#include <LiquidCrystal_I2C.h>
#include <Wire.h>

const unsigned long button_time = 500;
unsigned long previousTime_button = 0;
const int ledPin = 9;
int ledState = LOW; 
unsigned long previousMillis_led = 0;
const long interval = 500; 
int soil = A1;
int percentValue = 0;

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
   Serial.begin(9600);
   soil = analogRead(A1);
   lcd.noBacklight();
   lcd.init();
   lcd.begin(16, 2);
   lcd.print("Soil Moisture");
   pinMode(ledPin, OUTPUT);
}

void loop() { // soil and LCD code
   unsigned long currentTime_button = millis();
   soil = analogRead(A1);
   while(!Serial);
   Serial.print("\nValue: ");
   Serial.println(soil);
   percentValue = map(soil, 201, 490, 100, 0);
   Serial.print("\nPercentValue: ");
   Serial.print(percentValue);
   Serial.print("%");
   lcd.setCursor(0, 1);  
   lcd.print("Percent: ");
   lcd.print(percentValue);
   lcd.print("%");  
   delay(400);
   
  //Backlight code
   if (currentTime_button - previousTime_button >= button_time && digitalRead(7) == HIGH){ //The touch sensor is connected to a D7
   lcd.backlight();
   previousTime_button = currentTime_button;
   }else{ 
     if (currentTime_button - previousTime_button >= button_time && digitalRead(7) == LOW){
   lcd.noBacklight();
   previousTime_button = currentTime_button;
  }
 }
  // led blinking code
  soil = analogRead(A1);
  if (soil >= 434){
  unsigned long currentMillis_led = millis();
  if (currentMillis_led - previousMillis_led >= interval) {
    previousMillis_led = currentMillis_led;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
 }else {
   digitalWrite(ledPin, LOW);
 }
}

Welcome to the forum

The problem is this line of code

while(!Serial);

It is waiting for a Serial connection and there isn't one

Why is that line of code there in the first place ?

try this

#include <LiquidCrystal_I2C.h>
#include <Wire.h>

const unsigned long button_time = 500;
unsigned long previousTime_button = 0;
const int ledPin = 9;
int ledState = LOW; 
unsigned long previousMillis_led = 0;
const long interval = 500; 
int soil = A1;
int percentValue = 0;

LiquidCrystal_I2C lcd(0x27, 16, 2);

void setup() {
   Serial.begin(9600);
   soil = analogRead(A1);
   lcd.noBacklight();
   lcd.init();
   lcd.begin(16, 2);
   lcd.print("Soil Moisture");
   pinMode(ledPin, OUTPUT);
}

void loop() { // soil and LCD code
   unsigned long currentTime_button = millis();
   soil = analogRead(A1);
   //while(!Serial);
   Serial.print("\nValue: ");
   Serial.println(soil);
   percentValue = map(soil, 201, 490, 100, 0);
   Serial.print("\nPercentValue: ");
   Serial.print(percentValue);
   Serial.print("%");
   lcd.setCursor(0, 1);  
   lcd.print("Percent: ");
   lcd.print(percentValue);
   lcd.print("%");  
   delay(400);
   
  //Backlight code
   if (currentTime_button - previousTime_button >= button_time && digitalRead(7) == HIGH){ //The touch sensor is connected to a D7
   lcd.backlight();
   previousTime_button = currentTime_button;
   }else{ 
     if (currentTime_button - previousTime_button >= button_time && digitalRead(7) == LOW){
   lcd.noBacklight();
   previousTime_button = currentTime_button;
  }
 }
  // led blinking code
  soil = analogRead(A1);
  if (soil >= 434){
  unsigned long currentMillis_led = millis();
  if (currentMillis_led - previousMillis_led >= interval) {
    previousMillis_led = currentMillis_led;
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    digitalWrite(ledPin, ledState);
  }
 }else {
   digitalWrite(ledPin, LOW);
 }
}

Thank you, it's working without while(!Serial);. When I was studying Arduino programming they said the while command has to be before lcd.print when working with Arduino Micro. As I can see it was disinformation. Thank you for your help.

"They" were wrong

Who are "they" ?

It's working, thank you.

The Micro, like the Leonardo, has native USB hardware so you are supposed to wait in setup() for the USB connection using "while (!Serial) {}". This is a problem if you want to run the sketch without a USB connection because it will wait forever.

My favorite workaround is:

void setup() {
  Serial.begin(9600);
  while (!Serial && millis() < 5000) {}

That will wait for no longer than five seconds.

People on the internet.

so did you invest on hydrogen, get a eternal motion system and a russian wife? :laughing:

You mean to say that there is information on the Internet that is wrong ?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.