Problem With my Morse code Practice Device

Hello. I have been building a device for a class in college but somehow, the LCD display seems to jump a cursor line at random whenever i input a new letter.
Here is the code:

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

int timeStart  = 0;
int buttonMorse = 9;
int buttonEnd = 12;
int buttonMorseState = 0;
int  buttonEndState = 0;
int timeButtonPressed = 0;
int buttonStartEnd = 11;
int  buttonStartEndState = 0;
int cont = 0;
int timeButtonNotPressed_Start = 0;
int  timeButtonNotPressed = 0;
int buzzer = 10;
int lcdPos = 0;

LiquidCrystal_I2C  lcd(0x27, 16, 2);

// morse character
String character = "";
// list  of letters and numbers
String lettersAndNumbers[37] = {" ", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
//  respective morse code for each letter and number
String morseCode[37] = {"-..-.", ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..",
                        "-----", ".----", "..---", "...--", "....-", ".....", "-....", "--...", "---..", "----."
                       };

void  setup() {
  // put your setup code here, to run once:
  pinMode(buttonMorse,  INPUT);
  pinMode(buttonEnd, INPUT);
  pinMode(buttonStartEnd, INPUT);
  pinMode(buzzer, OUTPUT);

  lcd.init(); // Inicialize communication with  the display
  lcd.backlight(); // Turn the display lights on
  lcd.clear();  // Clean the display
  lcd.setCursor(0, 0);
  Serial.begin(9600);
  Serial.println("setup");
}

void  loop() {
  if (digitalRead (buttonStartEnd) == HIGH) {
  //if (lcdPos % 32 == 0) {
    // Everytime all the 32 positions of the  display are being used, clean it up
    lcd.clear();
  }
  buttonStartEndState  = digitalRead(buttonStartEnd);
  // Everytime the button thats start and pauses  the program is pressed, the program increases 'cont' in one
  if (buttonStartEndState) {
    cont++;
    delay(500);
    //Serial.println ("Botão1 press");
    //lcd.print("botão press");
  }
  // If 'cont' is even, the program starts,  if it's odd, the program pauses

    // When the program  is running, the time that the button of the morse code is not pressed is count
    timeButtonNotPressed = millis();
    // If the button is not pressed  for 3 seconds, a space is done
    if (timeButtonNotPressed % 3000 == 0) {
      Serial.print("");
      lcd.print("");
      lcdPos++;
      delay(300);
    }
    buttonMorseState = digitalRead(buttonMorse);
    buttonEndState =  digitalRead(buttonEnd);
    // timeStart restart before press the button
    timeStart  = millis();
    // while the button is pressed the time is count
    Serial.println(buttonMorseState);
    while (buttonMorseState) {
      buttonMorseState = digitalRead(buttonMorse);
      tone(buzzer, 800);
    }
    noTone(buzzer);
    // finalize the time and store in timeButtonPressed
    timeButtonPressed  = millis() - timeStart;
    // if the button is pressed for less than 200 miliseconds  and more than 5 miliseconds, so the character is "."
    if (timeButtonPressed  < 200 and timeButtonPressed > 5) {
      character = character + ".";
      //  the time that the button is not pressed is turned to 0
      timeButtonNotPressed  = timeButtonNotPressed - timeButtonNotPressed;
    }
    // if the button is pressed  for more than 200 seconds, so the character is "-"
    if (timeButtonPressed  > 200) {
      character = character + "-";
      // the time that the button  is not pressed is turned to 0
      timeButtonNotPressed = timeButtonNotPressed  - timeButtonNotPressed;
    }
    // if the button that ends the character is  pressed
    if (buttonEndState) {
      // compare the list of characters with  the list of morse
      for (int i = 0; i < 37; i++) {
        // if the character  made is equal to the respective morse code, print the character that have the same  index
        if (morseCode[i] == character) {
          Serial.print(lettersAndNumbers[i]);
          lcd.print(lettersAndNumbers[i]);
          // Position of the display's  cursor is increased in one
          lcdPos++;
          // If the position  is in the end of the first line, everytime lcdPos is divisible by 16, the cursor  go to the second line, position 0,1
          if (lcdPos % 16 == 0) {
            lcd.setCursor(0, 1);
          }
        }
      }
      // character is restarted
      character  = "";
      delay(500);
    }   
  }

and here is a picture of the connections:

Hi, @pedro_n00
Welcome to the forum.

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.

Do you have pull-up or pull-down resistors on your buttons?
It sounds like you have your digital input pins that are connected to the buttons open circuit when they are not pressed.

If your buttons got HIGH when pressed, you need a 10K resistor between each of the buttons input pins and gnd.
This will make sure the inputs are LOW when the buttins are not pressed.

Tom.. :smiley: :+1: :coffee: :australia:

As a quick try, you can try changing:

pinMode(buttonMorse,  INPUT);

to:

pinMode(buttonMorse,  INPUT_PULLUP);

That turns on an internal (20k?) resistor as a pull up.

I did take a quick look at your code and couldn't find anything. You may have to do some debugging by putting in some Serial.print statements to watch where the cursor position is. There may also be a command with the LCD that will indicate the exact cursor position.

Sir Michael

buttons are typically connected between the pin and ground, the pin configured as INPUT_PULLUP to use the internal pullup resistor which pulls the pin HIGH and when pressed, the button pulls the pin LOW.

a button press can be recognized by detecting a change in state and becoming LOW and may need to be debounced (e.g. delay (20);)

if you're trying to measure the time that the morse button is pressed, shouldn't it be debounced?

I built your project and started to read the code to see whether you buttons are meant to be normally HIGH or LOW and to see what each should do and so forth.

I agree with @gcjr that bouncing may be an issue; it is so far hard to say you haven't got some inadvertent debouncing accruing from the logic, or even something intentional.

I stopped when I read this line whilst making a first high level pass over the code

  timeButtonNotPressed  = timeButtonNotPressed - timeButtonNotPressed;

which is a long way to say

  timeButtonNotPressed  = 0;

Stopped.

Please say how you buttons are wired.

Please describe the function of the three buttons.

Please say what you are working with for the dot period. It might be nice as you fix this to make the dot period adjustable, even better (but harder) would be to make it adjust itself to your fist.

Then perhaps some more attention, from me anyway.

a7

OK I see how it is supposed to work but not yet why it doesn't.

I'll need to practice to put in a valid character.

L8R.

I can send some Morse characters through this hacked up version. I jettisoned code I didn't figure out except that it was unnecessary. For now. Play with it here:

The debouncing is handled just through program flow and delay() and trusting the user not to test the limits, like nice users that wanna show their stuff working.

Most of my changes were excisions and adding feedback. LEDs would be nice at least for development.

Note the cursor handling, and I sped things up by skipping 8 columns each new character.

The entire sketch depends on this section I draw you attention to

    timeStart  = millis();
    // while the button is pressed the time 

    while (buttonMorseState) {
      buttonMorseState = digitalRead(buttonMorse);
      tone(buzzer, 800);
    }
    noTone(buzzer);

    timeButtonPressed  = millis() - timeStart;

a7

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