Send character on serial monitor with physical push button?

Hello

I have a continuity tester that I have based on code in this forum, however the code I had was set to run when I send something in the serial monitor. I'd like the code to run on a button press ideally as this is a standalone test box.

The thread I referenced is here. Specifically post #7:

open the serial monitor and send something (at least one character)
(CR/LF would be enough, so you can send empty line if sending line ending is enabled)

What I'm trying to do is have an external push button initiate the test (which runs to completion). Upon a second press, clear the screen and run again (I'm using an external OLED).

The full code is below, it has just been slightly changed from the original to skip writing when a line passes, only writing the failed lines, and writing a single "PASS" or "FAIL" at the end.

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SPITFT.h>
#include <Adafruit_SPITFT_Macros.h>
#include <gfxfont.h>
#include <Adafruit_SSD1306.h>
#include <splash.h>

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


// Cable Tester by "jurs" for Arduino forum
enum {PASS, FAIL_NOTCONNECTED, FAIL_WRONGCONNECTED, FAIL_SHORTENED };

// pin numbers for use at begin and end of cable
const byte pinsCableBegin[]= {22,24,26};
const byte pinsCableEnd[]  = {23,25,27};
const byte NUMCABLES=sizeof(pinsCableBegin);

void setup() {

  Serial.begin(9600);

  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
    Serial.println(F("SSD1306 allocation failed"));
    for(;;); // Don't proceed, loop forever
  }

// Show initial display buffer contents on the screen --
  // the library initializes this with an Adafruit splash screen.
  display.display();
  delay(10); // Pause for 0.1 seconds

  // Clear the buffer
  display.clearDisplay();

  delay(200);
  // display.display() is NOT necessary after every single drawing command,
  // unless that's what you want...rather, you can batch up a bunch of
  // drawing operations and then update the screen all at once by calling
  // display.display(). These examples demonstrate both approaches...

  display.setTextSize(1);             // Normal 1:1 pixel scale
  display.setTextColor(WHITE);        // Draw white text
  display.setCursor(0,0);             // Start at top-left corner

  if (sizeof(pinsCableBegin)!=sizeof(pinsCableEnd))
  {
    Serial.println("Wrong cable pin configuration!");
    Serial.println("Fix declaration of pinsCableBegin[] and pinsCableEnd[] arrays!");
    while(1); // error stop with endless loop
  }  
  display.println("#   CAB0074 Iss C   #");
  display.println();
  display.display();
  
}

void allPinsInputHigh()
{ // set all pins to INPUT_PULLUP in a for-loop
  for (byte i=0;i<NUMCABLES;i++)
  {
    pinMode(pinsCableBegin[i],INPUT_PULLUP);
    pinMode(pinsCableEnd[i],INPUT_PULLUP);
  }
}


void DoOneTest()
{
  byte result;
  //display.println();
  //display.println("### TEST ###");
  for (byte i=0;i<NUMCABLES;i++) // test each pin 
  {
    result= PASS; // initially there is no error found, assume PASS
    allPinsInputHigh();
    // first test is for continuity and OUTPUT/HIGH
    pinMode(pinsCableBegin[i], OUTPUT);
    if (digitalRead(pinsCableEnd[i])!=HIGH)
    {
        bitSet(result,FAIL_NOTCONNECTED);
    }
    // then check for continuity and OUTPUT/LOW
    digitalWrite(pinsCableBegin[i], LOW);
    if (digitalRead(pinsCableEnd[i])!=LOW)
    {
        bitSet(result,FAIL_NOTCONNECTED);
    }
    
    // next test: check for wrong connections to other pins
    for (byte j=0;j<NUMCABLES;j++)
    {
      if (j!=i && digitalRead(pinsCableEnd[j])==LOW)
      {
        bitSet(result, FAIL_WRONGCONNECTED);
      }  
    }
    // final test for short circuit against other pins
    for (byte j=0;j<NUMCABLES;j++)
    {
      if (j!=i && digitalRead(pinsCableBegin[j])==LOW)
      {
        bitSet(result, FAIL_SHORTENED);
      }  
    }

if (result==PASS) goto finish;
else
  display.print("Line ");
  display.print(i+1);
    if (bitRead(result,FAIL_NOTCONNECTED)) display.print(" OPEN");
    if (bitRead(result,FAIL_WRONGCONNECTED)) display.print(" CROSS");
    if (bitRead(result,FAIL_SHORTENED)) display.print(" SHORT");
    display.println();

finish:;
  }
  
  display.println();
  if (result== PASS) 
  
  display.print("PASS");
  else display.print("FAIL"); 
  //display.println("Test finished.");
  display.println();
  display.display();
}


void loop() {
  if (Serial.available())
  {
    DoOneTest();
    delay(20);
     while (Serial.available()) Serial.read(); // clear Serial input buffer
  }
}

Thank you

Do you mean that you just want to change this

void loop() {
  if (Serial.available())
  {
    DoOneTest();
    delay(20);
     while (Serial.available()) Serial.read(); // clear Serial input buffer
  }
}

so that it responds to a button press rather than a message to Serial?

If so then something like this

void loop() {
  prevButtonState = buttonState;
  buttonState = digitalRead(buttonPin);
  if (buttonState == LOW and prevButtonState == HIGH) { 
  {
    DoOneTest();
  }
}

...R

Thanks, I've given it a try, I just get that prevButtonState and buttonState are not declared in this scope. Declaring them as a default of 0 at the beginning just causes the test to run continuously.

DarrylUK:
Declaring them as a default of 0 at the beginning just causes the test to run continuously.

You need to post the latest version of your program so I can see exactly what you have done.

And you need pinMode(buttonPin, INPUT_PULLUP); in setup(). I forgot to mention that - sorry.

...R