Loop very slow

Hi all, hope I’m in the right place:
As part of a larger project I wanted to test some things. After some problems, I got this code to run …

At first I thought, how can ‘loopMon’ not go low. But it does, for about 16 uS. It was hard to see on my old
B & K 30 Mhz scope because it’s approximately 9 mS between pulses of ‘loopMon’ going low.

How can it run that slow? It’s running on a Nano. I thought they ran @ 16 Mhz. I think the timing shouldn’t
be a problem but I don’t see what I’m doing that’s causing the loop to run so slow?

Anybody see why?

Thanks

gTst-Rsel-read-logic_3.txt (4.28 KB)

Please, attach Your code the way recommended in the advicing topis at the top.
Your .txt does not download here.

/* 
 * test if statement(input) and read(logic)
 *
 * the condition that any 2 of the inputs are 0 is not tested for here and should not be
 * allowed, if so the statements following 2 of the if statements will be executed 
 * 
 * 
 */


#define Input1 9               // test input 1 pin 9
#define Input2 10              // test input 2 pin 10
#define Input3 14              // pin A0 (14), test this analog pin as an input
#define loopMon 13             // output to monitor loop with oscilliscope

int SelInp1;                   // variable to hold the value of Input1
int SelInp2;                   // variable to hold the value of Input2
int SelInp3;                   // variable to hold the value of Input3  


#include <LiquidCrystal.h>

LiquidCrystal lcd(6,7,2,3,4,5);    //  wire  arduino >> (6-RS), (7-E), (5-D7), (4-D6), (3-D5), (2,D4)
                                   //  wire display >>  Gnd  [1, 5(RW), 16(LED-)] ..... pot wpr [3(Cont)] .... +5 [15(LED+)] 
                                                        
void setup()
 {
    pinMode(Input1, INPUT_PULLUP);  
    pinMode(Input2, INPUT_PULLUP);  
    pinMode(Input3, INPUT_PULLUP);
    pinMode(loopMon, OUTPUT);  
    
    lcd.begin(16,2);                      // setup lcd
 }

void loop()
 {
  /* ............................  test Input 1 = 0, read next input if !true ..................................*/
     
    digitalWrite(loopMon, HIGH);          // write pin 13 high
    SelInp1 = digitalRead(Input1);        // read the state of input 1 and store it in SelInp1
  
    if (SelInp1 == 0)                     // this will return 'true' if input1 is low (switch made, pin 9)
      {      
        lcd.clear();                      // clear display and put cursor at 0,0 ... 1st column, 1st row
        lcd.print("Input 1");
        lcd.setCursor(0,1);               // put cursor at 0,1 .... 1st column 2nd row
        lcd.print("delay 10 uS");
        digitalWrite(loopMon, LOW);           // write pin 13 low 
        delayMicroseconds(10);                // delay 10 uS                        
      }
    
  /* .............................  test Input 2 = 0, read the next input if !true  .............................*/
   
    SelInp2 = digitalRead(Input2);        // read the state of input 2 and store it in SelInp2 
  
    if (SelInp2 == 0)                     // this will return 'true' if input2 is low (switch made, pin 10)
      {
        lcd.clear();                      // clear display and put cursor at 0,0 ... 1st column, 1st row
        lcd.print("Input 2");
        lcd.setCursor(0,1);               // put cursor at 0,1 .... 1st column 2nd row
        lcd.print("delay 10 uS");
        digitalWrite(loopMon, LOW);           // write pin 13 low 
        delayMicroseconds(10);                // delay 10 uS    
      }
      
   /* ....................   read input 3 & test Input 3 = 0, compare inputs 1, 2 and 3 if !true  ................*/ 
    
    SelInp3 = digitalRead(Input3);         // read the state of input 3 and store it in SelInp3
         
    if (SelInp3 == 0)                      // this will return 'true' if input3 is low (switch made, pin 14)
      {
        lcd.clear();                       // clear display and put cursor at 0,0 ... 1st column, 1st row
        lcd.print("Input 3");
        lcd.setCursor(0,1);                // put cursor at 0,1 .... 1st column 2nd row
        lcd.print("delay 10 uS");
        digitalWrite(loopMon, LOW);           // write pin 13 low 
        delayMicroseconds(10);                // delay 10 uS                                      
      }
      
    
  /* ........................   comprare inputs 1, 2 and 3    ...................................................*/ 
    
  
    if (SelInp1 == SelInp2 == SelInp3)   // this will return 'true' if Input 1,2 and 3 are all high
      {
        lcd.clear();                     // clear display and put cursor at 0,0 ... 1st column, 1st row
        lcd.print("Input 1-2-3 High");
        lcd.setCursor(0,1);              // put cursor at 0,1 .... 1st column 2nd row
        lcd.print("delay 10 uS");
        digitalWrite(loopMon, LOW);           // write pin 13 low 
        delayMicroseconds(10);                // delay 10 uS                                
      }
 }

Got it now.
I can't find any mistakes slowing down the code. What kind of stuff is producing the input signals 1, 2 ,3?
Note that the LCD.writes takes some time to execute.

lcd.clear() is quite slow.

LiquidCrystal lcd(6,7,2,3,4,5);

Four bit LCD writes are sloooow.
sp. “9ms”, 16 MHz"

hd44780.h library has a pinIO class which is much faster than LiquidCrystal.h.

Available through the library manager.

Remove any use of lcd.clear() and use hd44780.h for optimal speed with the lcd.

Try printing static text in setup(), and overwrite old variables, not use clear().
Untested mod.
Leo…

/*
   test if statement(input) and read(logic)

   the condition that any 2 of the inputs are 0 is not tested for here and should not be
   allowed, if so the statements following 2 of the if statements will be executed


*/


#define Input1 9  // test input 1 pin 9
#define Input2 10 // test input 2 pin 10
#define Input3 14 // pin A0 (14), test this analog pin as an input
#define loopMon 13 // output to monitor loop with oscilliscope

int SelInp1; // variable to hold the value of Input1
int SelInp2; // variable to hold the value of Input2
int SelInp3; // variable to hold the value of Input3


#include <LiquidCrystal.h>

LiquidCrystal lcd(6, 7, 2, 3, 4, 5); //  wire  arduino >> (6-RS), (7-E), (5-D7), (4-D6), (3-D5), (2,D4)
//  wire display >>  Gnd  [1, 5(RW), 16(LED-)] ..... pot wpr [3(Cont)] .... +5 [15(LED+)]

void setup()
{
  pinMode(Input1, INPUT_PULLUP);
  pinMode(Input2, INPUT_PULLUP);
  pinMode(Input3, INPUT_PULLUP);
  pinMode(loopMon, OUTPUT);

  lcd.begin(16, 2); // setup lcd
  lcd.print("Input "); // print static text
  lcd.setCursor(0, 1);
  lcd.print("delay 10 uS");
}

void loop()
{
  /* ............................  test Input 1 = 0, read next input if !true ..................................*/

  digitalWrite(loopMon, HIGH); // write pin 13 high
  SelInp1 = digitalRead(Input1); // read the state of input 1 and store it in SelInp1

  if (SelInp1 == 0) // this will return 'true' if input1 is low (switch made, pin 9)
  {
    lcd.setCursor(6, 0); // put cursor at 6,0 .... 6th position 1st row
    lcd.print("1         "); // print and overwrite old text
    digitalWrite(loopMon, LOW); // write pin 13 low
    delayMicroseconds(10); // delay 10 uS
  }

  /* .............................  test Input 2 = 0, read the next input if !true  .............................*/

  SelInp2 = digitalRead(Input2); // read the state of input 2 and store it in SelInp2

  if (SelInp2 == 0) // this will return 'true' if input2 is low (switch made, pin 10)
  {
    lcd.setCursor(6, 0); // put cursor at 6,0 .... 6th position 1st row
    lcd.print("2         "); // print and overwrite old text
    digitalWrite(loopMon, LOW); // write pin 13 low
    delayMicroseconds(10); // delay 10 uS
  }

  /* ....................   read input 3 & test Input 3 = 0, compare inputs 1, 2 and 3 if !true  ................*/

  SelInp3 = digitalRead(Input3); // read the state of input 3 and store it in SelInp3

  if (SelInp3 == 0) // this will return 'true' if input3 is low (switch made, pin 14)
  {
    lcd.setCursor(6, 0); // put cursor at 6,0 .... 6th position 1st row
    lcd.print("3         "); // print and overwrite old text
    digitalWrite(loopMon, LOW); // write pin 13 low
    delayMicroseconds(10); // delay 10 uS
  }


  /* ........................   comprare inputs 1, 2 and 3    ...................................................*/


  if (SelInp1 == SelInp2 == SelInp3)   // this will return 'true' if Input 1,2 and 3 are all high
  {
    lcd.setCursor(6, 0);     // put cursor at 6,0 .... 6th position 1st row
    lcd.print("1-2-3 High"); // print and overwrite old text
    digitalWrite(loopMon, LOW); // write pin 13 low
    delayMicroseconds(10); // delay 10 uS
  }
}

@Wava
Tested mod and approved….

In case all Selinput are Active LOW there will be a hell lot of LCD writes… Maybe use a timer, only writing to the LCD a few times per second? No human eye will catch several 100 writings per second.

Railroader:
No human eye will catch several 100 writings per second.

And it will blur the display.

Wow! 10 answers already for a "one hit wonder"! :astonished:

Rules:

  • Do not update display unless something actually changes.
  • Do not update display more than five times per second, and only if something has changed (and not changed back!) in the meantime.

@Paul__B

Haha. The usual party for the experts?

Paul__B:
Wow! 10 answers already for a "one hit wonder"! :astonished:

@OP
Being new to this Your work is impressive.

  if (SelInp1 == SelInp2 == SelInp3)   // this will return 'true' if Input 1,2 and 3 are all high

This does not what the comment suggests.

Somewhere\TripleEqual\TripleEqual.ino:12:21: warning: suggest parentheses around comparison in operand of '==' [-Wparentheses]

         if (SelInp1 == SelInp2 == SelInp3) {

             ~~~~~~~~^~~~~~~~~~

Parentheses will not work.

See the evaluation of the current expression for all possible values:

void setup() {
  Serial.begin(250000);
  for (int SelInp1 = 0; SelInp1 < 2; SelInp1++) {
    for (int SelInp2 = 0; SelInp2 < 2; SelInp2++) {
      for (int SelInp3 = 0; SelInp3 < 2; SelInp3++) {
        Serial.print(SelInp1);
        Serial.write(' ');
        Serial.print(SelInp2);
        Serial.write(' ');
        Serial.print(SelInp3);
        Serial.print(F(" -> "));
        if (SelInp1 == SelInp2 == SelInp3) {
          Serial.println(F("true"));
        } else {
          Serial.println(F("false"));
        }
      }
    }
  }
}
void loop() {}
0 0 0 -> false
0 0 1 -> true
0 1 0 -> true
0 1 1 -> false
1 0 0 -> true
1 0 1 -> false
1 1 0 -> false
1 1 1 -> true

Whandall:

  if (SelInp1 == SelInp2 == SelInp3 == HIGH)   // this will return 'true' if Input 1,2 and 3 are all high

Might be better?

Railroader:
Might be better?

No, one warning more and still a flawed result.

Somewhere\TripleEqual\TripleEqual.ino:12:21: warning: suggest parentheses around comparison in operand of '==' [-Wparentheses]
         if (SelInp1 == SelInp2 == SelInp3 == HIGH) {
             ~~~~~~~~^~~~~~~~~~
Somewhere\TripleEqual\TripleEqual.ino:12:32: warning: suggest parentheses around comparison in operand of '==' [-Wparentheses]
         if (SelInp1 == SelInp2 == SelInp3 == HIGH) {
             ~~~~~~~~~~~~~~~~~~~^~~~~~~~~~
void setup() {
  Serial.begin(250000);
  for (int SelInp1 = 0; SelInp1 < 2; SelInp1++) {
    for (int SelInp2 = 0; SelInp2 < 2; SelInp2++) {
      for (int SelInp3 = 0; SelInp3 < 2; SelInp3++) {
        Serial.print(SelInp1);
        Serial.write(' ');
        Serial.print(SelInp2);
        Serial.write(' ');
        Serial.print(SelInp3);
        Serial.print(F(" -> "));
        if (SelInp1 == SelInp2 == SelInp3 == HIGH) {
          Serial.println(F("true"));
        } else {
          Serial.println(F("false"));
        }
      }
    }
  }
}
void loop() {}
0 0 0 -> false
0 0 1 -> true
0 1 0 -> true
0 1 1 -> false
1 0 0 -> true
1 0 1 -> false
1 1 0 -> false
1 1 1 -> true

sam_1951:
At first I thought, how can 'loopMon' not go low. But it does, for about 16 uS. It was hard to see on my old
B & K 30 Mhz scope because it's approximately 9 mS between pulses of 'loopMon' going low.

When I want to monitor something like that I invert the output I am using once on each event, rather then making it high (or low) then shortly afterwards making it low (or high). If you invert it then you get a low to high then next time high to low transition each time round, and it is dead obvious on an oscilloscope.

Railroader:
if (SelInp1 == SelInp2 == SelInp3 == HIGH) // this will return ‘true’ if Input 1,2 and 3 are all high

Might be better?

if (SelInp1 && SelInp2 && SelInp3) // this will return ‘true’ if Input 1,2 and 3 are all high

That's the way to do it.

... or use AND (&&)

lastchancename:
... or use AND (&&)

An interesting shorthand. Not sure whether I like it or not.

So we are up to 19 replies and 27 hours for the "one hit wonder"! :roll_eyes: