Serial monitor problem

Im trying to make a morse code reader with a switch and buzzer, but the serial monitor just keeps writing . over and over, no matter what the input is. Can someone help?

int S = 7;
int B = 8;
String MORSE;
bool hasrun = false;
unsigned long pressStart;
void setup() {
  // put your setup code here, to run once:
  pinMode(S, INPUT);
  pinMode(B, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (digitalRead(S) == HIGH && !hasrun) {
    pressStart = millis();
    while (digitalRead(S) == HIGH)
      ;
    unsigned long pressDuration = millis() - pressStart;

    if (pressDuration < 300) {
      MORSE += ".";
      Serial.println(".");
    }
    if (pressDuration > 300) {
      MORSE += "---";
      Serial.println("---");
    }
    hasrun = true;
    delay(300);
  }
  if (digitalRead(S) == HIGH && hasrun) {
    hasrun = false;
  }
}

EDIT: there were some issues with code, but mostly wiring, i fixed that up and it works!

Welcome to the forum

    while (digitalRead(S) == HIGH);

Is the switch pin HIGH or LOW when the switch is open and what, if anything, is keeping it in a that state until the switch is closed ?

How is the switch wired ?

guessing you need to configure the pin as INPUT_PULLUP so that when the button is not pressed it is pulled HIGH rather than floating and not having a constant state

with the pin pulled HIGH, you should check if the pin is LOW to recognize it as being pressed

This works. The lines with <--- have been changed. I assume your switch is connected between pin 7 and ground.

#define PRESSED LOW // <---
int S = 7;
// not used int B = 8; <---
String MORSE;
bool hasrun = false;
unsigned long pressStart;
void setup() {
  // put your setup code here, to run once:
  pinMode(S, INPUT_PULLUP); // <---
  // not used pinMode(B, OUTPUT); <---
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if (digitalRead(S) == PRESSED && !hasrun) { // <---
    pressStart = millis();
    while (digitalRead(S) == PRESSED); // <---
    unsigned long pressDuration = millis() - pressStart;

    if (pressDuration < 300 && pressDuration > 50) { // <--- The > 50 is debounce
      MORSE += ".";
      Serial.println(".");
    }
    if (pressDuration > 300) {
      MORSE += "---";
      Serial.println("---");
    }
    hasrun = true;
    // delay(300); <---
  }
  if (digitalRead(S) == PRESSED && hasrun) { // <---
    hasrun = false;
  }
}

With the delay(300) included, it was missing some switch presses for dot.
Serial output from the code I posted:

.
.
.
---
---
---
.
.
.

[Edit: I haven't worked out exactly why hasrun is needed. There may be bugs associated with that, but I didn't notice any when I was testing it with 3 dots, 3 dashes, 3 dots.]
[Edit2: A press of exactly 300ms won't work. Change "> 300" into ">=300"]


It looks like this, maybe there is something wrong with the wiring. I am planning to use the buzzer later, but im ignoring it for now. Also, thanks for replying!

I configured it and its still not working, but im making progress!

Its still not working for me, maybe there is something wrong with my wiring? Instead of receiving a bunch of dots from the monitor, it stopped sending anything completely. Thank you for your reply, if you could help out more I would appreciate it. the wiring looks like this if its any help:

the connections to the button need to be the corners: lower left and upper right