Replicating "Old-School" Texting With an Arduino, a 4x4 Numerical Keypad, and a 16x2 LCD

Hello! This is a tutorial to produce a text-composition device using an Arduino with text storage and return capabilities to the serial console. In its current form it is not particularly useful, and is more of an entertaining exercise, but the hardware setup and code may be expanded upon or incorporated into other projects as a relatively cheap way to compose text. With the addition of a GSM or 3G shield, and minor code changes and additions, this setup could actually be used as a simple text-sending phone.


Here is a video demo of most of the functionality, including text entry, line wrapping, screen-clearing, spaces, backspaces, serial output, and the end of composition menu, featuring the re-display of stored text upon backspacing, as well as the capability to output a final message and clear the display and storage.

You will need:
An Arduino (I used an Uno R3)
A 16x2 LCD (with or without backlight, your choice. Different sizes could be used with accommodations made in the code)
A breadboard, male-male and male-female jumpers (depends on how permanent this will be, and what headers are where)
5x 2k ohm resistors
1x 240 ohm resistor

The resistor values are not nessisarily set in stone, the 2k ones could most likely be subbed with anything 1k-5k, and the 240 could be anything 100-500, but I make no guarantees that those will cooperate (they probably will though). One of the 2k's and the 240 are used for creating a voltage divider for the contrast on the LCD. Normally this is accomplished with a potentiometer, so substitute as you feel fit.

Step 1: Hardware Setup

The diagram should explain the majority of the hardware setup, which is essentially an expansion of your typical basic LCD setup. Data output lines, however, are shared between the LCD and the keypad. These outputs go to the rows on the keypad in order to normally write them high. If any press occurs, it is detected by one of the columns going high, as the columns are hooked up to be inputs. A high signal as then cycled through the rows and then the keypress is located based on which column goes high when which row is high. Afterwards all rows are returned to the initial high state. After any commands to the LCD, all rows are written high again to ensure that no odd behavior occurs on the LCD, and keypress detection still functions. The resistors on the right of the diagram are the 2k ohm pulldowns for the column inputs to the Arduino, and the resistors on the left for the voltage divider that (as I mentioned earlier) can be replaced with a potentiometer if one wishes to do so.

Step 2: Code

I've attempted to comment this code extensively, but if anything in it remains unclear, please do ask! I've attached the .ino file to make uploading the code simple.

Note: I wrote this code before I had a handle on Object-Oriented Programming, and so the structure and organization of the code could certainly be better, but it still does function perfectly. I would update the code, but I no longer have the hardware on-hand and so would not be able to test it sufficiently. It is my hope, however, that the lack of OOP will make the code simpler to follow for Arduino beginners.

Step 3: Finished!

I hope that you found all this useful! If you have any questions feel free to ask. Thanks!

Share

    Recommendations

    • Big and Small Contest

      Big and Small Contest
    • Toys Contest

      Toys Contest
    • Make it Glow Contest 2018

      Make it Glow Contest 2018

    15 Discussions

    0
    None
    tistpab

    1 year ago

    hello, I use this code to my project sms text
    messaging with gsm900d and I add some
    code my project need to input the NUMBER
    & MESSAGE , when I input the
    number alone i can receive a message but
    when i input the number and message I can’t receive any message.. how can fix this please help me . here’s the code I add.

    #include
    <LiquidCrystal.h> //include the
    lcd library

    #include <String.h>

    #include <Keypad.h>

    #include
    <SoftwareSerial.h>

    #include
    "SIM900.h"

    #include "sms.h"

    SMSGSM sms;

    const byte row1=3; //keypad row pins, shared with the lcd
    data lines

    const byte row2=4;

    const byte row3=5;

    const byte row4=6;

    const byte col1=7; //keypad column lines

    const byte col2=8;

    const byte col3=9;

    const byte col4=10;

    LiquidCrystal lcd(12, 11,
    row4, row3, row2, row1); //lcd object

    byte numpressed; //latest
    number pressed on the keypad

    byte timespressed; //times
    the number has been pressed

    byte cursorx=0; //cursor x
    position

    byte cursory=0; //cursor y
    position

    byte lastnumpressed; //the
    initial number pressed on the keypad

    char letter; //stores
    letter that needs to be printed to the lcd

    char typedtext[140];
    //stores typed text for printout to the serial console

    char phoneNumber [12];

    const int wait=1000;
    //time to wait for additional presses to same number

    const int
    preventholddelay=150; //time to wait to prevent cycling through things too
    quickly

    unsigned long basetime;
    //base time for while loop

    unsigned long elapsed=0;
    //elapsed time in while loop

    bool
    disablespacedelay=false; //disables the delay in the space function in the case
    that a different number is pressed while in while loop

    bool promptkeypress=false;
    //used for waiting for, and keypress detection, at the end-of composition
    prompt

    const byte
    maxtimespressed[16]={

    1,3,4,4,4,4,4,4,4,4,1,7,1,1,1,1}; //stores
    maximum number of times any given key can be pressed before looping back to its
    first letter (used by incrementtimespressed function)

    int positionintypedtext=0;
    //position in typedtext character array

    int charremaining;
    //remaining characters in message

    int
    positioninphoneNumber=0;

    void setup(){

    //KEYPAD

    Serial.begin(9600); //initiate gizduino witha baud
    rate of 9600

    lcd.begin(20,4); //initialize the lcd

    lcd.setCursor(cursorx,cursory); //set the lcd
    cursor

    lcd.noCursor(); //turn off the cursor

    pinMode(row1,OUTPUT); //set the rows as
    outputs

    pinMode(row2,OUTPUT);

    pinMode(row3,OUTPUT);

    pinMode(row4,OUTPUT);

    pinMode(col1,INPUT); //set the columns as inputs

    pinMode(col2,INPUT);

    pinMode(col3,INPUT);

    pinMode(col4,INPUT);

    delay(wait);

    lcd.cursor(); //turn the cursor on again
    after a delay equivalent to wait

    rowshigh(); //sets all rows high

    mainMenu();

    }

    void loop(){

    numpressed=16; //reset
    "numpressed" (16 doesn't refer to any button on the pad)

    if (findpress()){ //look for presses, if one
    has occurred, identify it and continue

    timespressed=0; //reset
    "timespressed"

    if (numpressed==0){ //if zero on the pad
    was pressed,

    dozero(); //print zero

    letter='0'; //manually seed a zero as the
    character for the text storage

    textstorage(1); //regular character
    storage

    }

    if (numpressed==10){ //if shift on the pad
    was pressed,

    textstorage(2); //perform a space in
    storage

    dospace(); //do a space

    }

    if (numpressed==14){ //if the arrows on the
    pad were pressed,

    textstorage(3); //perform a backspace in
    storage

    dobackspace(); //do a backspace

    }

    if (numpressed==15){ //if enter on the pad
    was pressed,

    if (gsm.begin(9600)) //condition if gsm is initialized


    Serial.println("\nstatus=READY"); //displays "ready" on the serial
    monitor if gsm is ready

    else
    Serial.println("\nstatus=IDLE"); //otherwise displays
    "idle" on the serial monitor if gsm is not found

    delay(1000);

    sendTextMessage();

    lcd.setCursor(3,3);

    lcd.print("Sending..");

    lcd.clear();

    delay(1000);

    mainMenu();

    outputserial(); //output message and
    display remaining characters to serial console

    }

    if
    ((numpressed<10&&numpressed>0)||numpressed==11){ //if
    1,2,3,4,5,6,7,8,9, or 11 was pressed (any one of the keys with multiple
    characters assigned),

    lastnumpressed=numpressed; //record which
    number was pressed,

    basetime=millis(); //and take a base time
    for the while loop

    while (elapsed<wait){ //while below
    the time to wait,

    if(findpress()){ //look for presses, if
    one has occurred, identify it and continue

    if (numpressed==lastnumpressed){ //if
    it was the same as before,

    incrementtimespressed();
    //increment "timespressed"


    basetime=basetime+(wait-(wait-elapsed)); //roll up the base time, to
    allow another wait period until next press of the same button

    definepress(); //use
    "numpressed" and "timespressed" to define
    "letter"

    lcd.print(letter); //print the
    letter that was defined

    lcd.setCursor(cursorx,cursory);
    //maintain cursor position

    rowshigh(); //return all rows high

    delay(preventholddelay); //delay a
    little to prevent continuous cycling through "timespressed" during a
    single press

    }

    else{ //if the number that was pressed
    was different than before,

    disablespacedelay=true; //disable
    the delay in the space function to allow the press to be detected a second
    time, at the beginning of void loop

    break; //break out of the while
    loop

    }

    }

    elapsed=millis()-basetime; //refresh
    the elapsed time for the while loop

    }

    elapsed=0; //reset the elapsed time for
    the while loop

    textstorage(1); //store character

    dospace(); //do a space

    }

    }

    if (positionintypedtext==139){ //if the end
    of the stored text has been reached,

    promptkeypress=false; //reset keypress
    detection

    cursorx=0; //set cursor to the beginning of
    first row

    cursory=0;

    lcd.setCursor(cursorx,cursory);

    lcd.print("Msg end.
    <>=back"); //print this out to the lcd

    cursorx=0; //set cursor to the beginning of
    second row

    cursory=1;

    lcd.setCursor(cursorx,cursory);

    lcd.print("enter=serial out");
    //print this out to the lcd

    rowshigh(); //sets all rows high

    numpressed=16; //reset
    "numpressed" (16 doesn't refer to any button on the pad)

    while(!promptkeypress){ //while no relevant
    keypresses have occurred,

    if (findpress()){ //look for presses, if
    one has occurred, identify it and continue

    timespressed=0; //reset
    "timespressed"

    if (numpressed==14){ //if the arrows on
    the pad were pressed,

    promptkeypress=true; //take note so
    that the while loop can be broken

    textstorage(3); //perform a backspace
    in storage

    for (int i=0;i<16;i++){ //print
    out to the first line on the lcd from the stored text

    cursorx=i;

    cursory=0;

    lcd.setCursor(cursorx,cursory);

    lcd.print(typedtext[108+i]);

    }

    for (int j=0;j<16;j++){ //print out to
    the second line on the lcd from the stored text

    cursorx=j;

    cursory=1;

    lcd.setCursor(cursorx,cursory);

    lcd.print(typedtext[123+j]);

    }

    cursorx=15; //set cursor to the
    beginning of second row

    cursory=1;

    lcd.setCursor(cursorx,cursory);

    rowshigh(); //sets all rows high

    }

    if (numpressed==15){ //if enter on the
    pad was pressed,

    promptkeypress=true; //take note so
    that the while loop can be broken

    Serial.print("Final message:
    "); //print this to the serial console

    Serial.println(typedtext); //print
    out all the text typed so far to the serial console


    Serial.println(); //print a blank line

    for (int i=0;i<140;i++){ //write
    all positions in the stored text to be blank

    typedtext[i]=' ';

    }

    positionintypedtext=0; //reset the
    position in the stored text to the beginning

    doclear();

    rowshigh(); //sets all rows high

    }

    }

    }

    delay(preventholddelay); //delay a little
    to prevent continuous cycling

    }

    }

    void rowshigh(){ //sets
    all rows high

    digitalWrite(row1,HIGH); //write all the rows
    high

    digitalWrite(row2,HIGH);

    digitalWrite(row3,HIGH);

    digitalWrite(row4,HIGH);

    }

    bool findpress(){ //finds
    a press to define "numpressed", if any press occurs, returns true

    bool pressfound=false; //variable for any
    press detection, is returned by this function

    digitalWrite(row1,LOW); //write all rows low

    digitalWrite(row2,LOW);

    digitalWrite(row3,LOW);

    digitalWrite(row4,LOW);

    digitalWrite(row1,HIGH); //write first row
    high

    if (digitalRead(col1)==HIGH){ //if the first
    column is now high, "1" has been pressed

    numpressed = 1;

    pressfound=true;

    }

    if (digitalRead(col2)==HIGH){ //if the second
    column is now high, "2" has been pressed

    numpressed = 2;

    pressfound=true;

    }

    if (digitalRead(col3)==HIGH){ //if the third
    column is now high, "3" has been pressed

    numpressed = 3;

    pressfound=true;

    }

    if (digitalRead(col4)==HIGH){ //if the fourth
    column is now high, "reset" has been pressed

    numpressed = 12;

    pressfound=true;

    }

    digitalWrite(row1,LOW); //return first row
    low

    digitalWrite(row2,HIGH); //write second row
    high

    if (digitalRead(col1)==HIGH){ //if the first
    column is now high, "4" has been pressed

    numpressed = 4;

    pressfound=true;

    }

    if (digitalRead(col2)==HIGH){ //if the second
    column is now high, "5" has been pressed

    numpressed = 5;

    pressfound=true;

    }

    if (digitalRead(col3)==HIGH){ //if the third
    column is now high, "6" has been pressed

    numpressed = 6;

    pressfound=true;

    }

    if (digitalRead(col4)==HIGH){ //if the fourth
    column is now high, "dial" has been pressed

    numpressed = 13;

    pressfound=true;

    }

    digitalWrite(row2,LOW); //return second row
    low

    digitalWrite(row3,HIGH); //write third row
    high

    if (digitalRead(col1)==HIGH){ //if the first
    column is now high, "7" has been pressed

    numpressed = 7;

    pressfound=true;

    }

    if (digitalRead(col2)==HIGH){ //if the second
    column is now high, "8" has been pressed

    numpressed = 8;

    pressfound=true;

    }

    if (digitalRead(col3)==HIGH){ //if the third
    column is now high, "9" has been pressed

    numpressed = 9;

    pressfound=true;

    }

    if (digitalRead(col4)==HIGH){ //if the fourth
    column is now high, the arrows have been pressed

    numpressed = 14;

    pressfound=true;

    }

    digitalWrite(row3,LOW); //return third row
    low

    digitalWrite(row4,HIGH); //write fourth row
    high

    if (digitalRead(col1)==HIGH){ //if the first
    column is now high, "shift" has been pressed

    numpressed = 10;

    pressfound=true;

    }

    if (digitalRead(col2)==HIGH){ //if the second
    column is now high, "0" has been pressed

    numpressed = 0;

    pressfound=true;

    }

    if (digitalRead(col3)==HIGH){ //if the third
    column is now high, "." has been pressed

    numpressed = 11;

    pressfound=true;

    }

    if (digitalRead(col4)==HIGH){ //if the fourth
    column is now high, "enter" has been pressed

    numpressed = 15;

    pressfound=true;

    }

    digitalWrite(row4,LOW); //return fourth row
    low

    rowshigh(); //write all rows high

    return pressfound; //function returns true
    if any press found, otherwise returns false

    }

    void definepress(){ //uses
    "lastnumpressed" and "timespressed" to define
    "letter"

    if (lastnumpressed==1){

    if (timespressed==1){

    letter='1';

    }

    if (timespressed==2){

    letter='Q';

    }

    if (timespressed==3){

    letter='Z';

    }

    }

    if (lastnumpressed==2){

    if (timespressed==1){

    letter='2';

    }

    if (timespressed==2){

    letter='A';

    }

    if (timespressed==3){

    letter='B';

    }

    if (timespressed==4){

    letter='C';

    }

    }

    if (lastnumpressed==3){

    if (timespressed==1){

    letter='3';

    }

    if (timespressed==2){

    letter='D';

    }

    if (timespressed==3){

    letter='E';

    }

    if (timespressed==4){

    letter='F';

    }

    }

    if (lastnumpressed==4){

    if (timespressed==1){

    letter='4';

    }

    if (timespressed==2){

    letter='G';

    }

    if (timespressed==3){

    letter='H';

    }

    if (timespressed==4){

    letter='I';

    }

    }

    if (lastnumpressed==5){

    if (timespressed==1){

    letter='5';

    }

    if (timespressed==2){

    letter='J';

    }

    if (timespressed==3){

    letter='K';

    }

    if (timespressed==4){

    letter='L';

    }

    }

    if (lastnumpressed==6){

    if (timespressed==1){

    letter='6';

    }

    if
    (timespressed==2){

    letter='M';

    }

    if (timespressed==3){

    letter='N';

    }

    if (timespressed==4){

    letter='O';

    }

    }

    if (lastnumpressed==7){

    if (timespressed==1){

    letter='7';

    }

    if (timespressed==2){

    letter='P';

    }

    if (timespressed==3){

    letter='R';

    }

    if (timespressed==4){

    letter='S';

    }

    }

    if (lastnumpressed==8){

    if (timespressed==1){

    letter='8';

    }

    if (timespressed==2){

    letter='T';

    }

    if
    (timespressed==3){

    letter='U';

    }

    if (timespressed==4){

    letter='V';

    }

    }

    if (lastnumpressed==9){

    if (timespressed==1){

    letter='9';

    }

    if (timespressed==2){

    letter='W';

    }

    if (timespressed==3){

    letter='X';

    }

    if (timespressed==4){

    letter='Y';

    }

    }

    if (lastnumpressed==11){

    if (timespressed==1){

    letter='.';

    }

    if (timespressed==2){

    letter='?';

    }

    if (timespressed==3){

    letter='!';

    }

    if
    (timespressed==4){

    letter=',';

    }

    if (timespressed==5){

    letter='\'';

    }

    if (timespressed==6){

    letter='"';

    }

    if (timespressed==7){

    letter='-';

    }

    }

    }

    void
    incrementtimespressed(){ //increment "timespressed" until at max
    value stored in maxtimespressed for that lastnumpressed, then roll over to 1

    if
    (timespressed==maxtimespressed[lastnumpressed]){ //if at the maximum,

    timespressed=1; //roll over timespressed to
    one

    }

    else{ //otherwise,

    timespressed++; //increment timespressed

    }

    }

    void dozero(){ //prints
    zero

    lcd.print('0'); //print 0

    lcd.setCursor(cursorx,cursory); //maintain
    cursor position

    dospace(); //space

    }

    void dospace(){ //moves
    cursor forward once, wraps to next line if necessary, clears and returns to top
    of display if at bottom

    if (cursory==1){ //if on the bottom row,

    if (cursorx==14){ //if at the end of the
    row,

    cursorx=0; //define new cursor position as
    the upper-left corner

    cursory=0;

    lcd.clear();

    }

    else{ //otherwise,

    cursorx++; //increment the cursor to the
    right

    }

    }

    else{ //if on the top row,

    if (cursorx==19){ //if at the end of the
    row,

    cursorx=0; //define new cursor position
    as the bottom-left corner

    cursory=1;

    }

    else{ //otherwise,

    cursorx++; //increment the cursor to the
    right

    }

    }

    lcd.setCursor(cursorx,cursory); //set cursor
    to defined location

    rowshigh(); //sets all rows high

    if (disablespacedelay){ //if the delay has
    been disabled,

    disablespacedelay=false; //reset its being
    disabled

    }

    else{ //otherwise,

    delay(preventholddelay); //delay a bit

    }

    }

    void doclear(){ //clears and
    returns to top-left of display

    cursorx=0;

    cursory=0;

    lcd.clear();

    lcd.setCursor(cursorx,cursory);

    rowshigh(); //sets all rows high

    delay(preventholddelay);

    }

    void dobackspace(){ //does
    a backspace, essentially the opposite of dospace

    if (cursory==1){

    if (cursorx==0){

    cursorx=16;

    cursory=0;

    }

    else{

    cursorx--;

    }

    }

    else{

    if (cursorx==0){

    cursorx=0;

    cursory=0;

    }

    else{

    cursorx--;

    }

    }

    lcd.setCursor(cursorx,cursory);

    lcd.print(" ");

    lcd.setCursor(cursorx,cursory);

    rowshigh(); //sets all rows high

    delay(preventholddelay);

    }

    void textstorage(byte
    mode){ //contains functions for text storage

    if (mode==1){ //regular character storage


    phoneNumber[positioninphoneNumber]=letter;

    positioninphoneNumber++;

    // typedtext[positionintypedtext]=letter;
    //store letter that was printed to LCD in typedtext

    //
    positionintypedtext++; //increment position in typedtext

    }

    if
    (mode==2){ //do a space in stored text

    //typedtext[positionintypedtext]=' '; //set
    current position in typedtext to a space

    //positionintypedtext++; //increment
    position in typedtext

    phoneNumber[positioninphoneNumber]=' ';

    positioninphoneNumber++;

    }

    if (mode==3){ //does a backspace in the
    stored text

    //positionintypedtext--; //decrement
    position in typedtext

    //typedtext[positionintypedtext]=' '; //set
    current position in typedtext to a space

    positioninphoneNumber--;

    phoneNumber[positioninphoneNumber]=' ';

    }

    }

    void outputserial(){ //output message and
    display remaining characters to serial console

    Serial.print("Phonenumber: ");

    Serial.println(phoneNumber);

    Serial.println("Message: ");

    Serial.print(typedtext); //print out all the
    text typed so far to the serial console

    // charremaining=(139-(positionintypedtext));
    //calculate remaining characters

    Serial.print(charremaining); //display
    remaining characters

    if (charremaining==1){ //making sure that the
    plural is only used correctly

    Serial.println(" character
    remaining");

    }

    else{

    Serial.println(" characters
    remaining");

    }

    Serial.println(); //print a blank line

    delay(preventholddelay); //delay a little to
    prevent continuous cycling

    }

    void mainMenu(){

    lcd.clear();

    lcd.setCursor(0,0);

    lcd.print("To:");

    cursorx=3;

    cursory=0;

    lcd.setCursor(0,1);

    lcd.print("Text:");

    lcd.setCursor(0,1);

    lcd.setCursor(cursorx,cursory);

    }

    void sendTextMessage()

    {

    sms.SendSMS(phoneNumber,typedtext);

    delay(100);

    Serial.println("\nSMS sent OK");

    }

    0
    None
    EslamE1

    2 years ago

    if i may ask why didnt you use the keypad.h i am trying to build something and i need to do the same thing to get the users email and address and i am using the keypad.h is it doable?

    1 reply
    0
    None
    Clayton FordEslamE1

    Reply 2 years ago

    I didn't use keypad.h as it obfuscates the use of the keypad, and frankly it's really easy to manually implement, as I did here (basically writing a row high, checking for a high signal on each of the columns (corresponding with a button press), and then writing the next row high, etc.). One major advantage of manual implementation is that it allowed me to share digital pins between the keypad and the LCD. So it's up to you which way to go, the code I developed for this project is dependent on the manual keypad implementation that I did, so if you would like to build off of my code, using keypad.h likely won't work out easily. You should be able to easily change the letters and such in the code as necessary to adjust my code to match your keypad.

    0
    None
    kourpetis

    4 years ago on Introduction

    well first of all weldone for the tutorial.

    i've made it and it was actualy very easy.

    i have a problem conbining another code ( morse code encoder decoder ) to this .ino file.

    this is the libraries :

    https://code.google.com/p/morse-endecoder/download...

    and this is the code :

    #include <avr/pgmspace.h>

    #include <MorseEnDecoder.h>

    // Pin mappings

    const byte morseInPin = 7;

    const byte morseOutPin = 13;

    // Instantiate Morse objects

    morseDecoder morseInput(morseInPin, MORSE_KEYER, MORSE_ACTIVE_LOW);

    morseEncoder morseOutput(morseOutPin);

    // Variables dealing with formatting the output somewhat

    // by inserting CR's (carriage returns)

    long lastTransmissionTime;

    long currentTime;

    boolean transmissionEnded = true; // Flag to mark old transmission is finished

    // Minimum transmission pause time to insert carriage returns (CR)

    // Adjust depending on Morse speed. IE 13 wpm = 646 ms between words (no CR).

    const long transmissionPaused = 1000; // Suitable for 13 wpm?

    void setup()

    {

    Serial.begin(9600);

    Serial.println("Morse EnDecoder demo");

    // Setting Morse speed in wpm - words per minute

    // If not set, 13 wpm is default anyway

    morseInput.setspeed(13);

    morseOutput.setspeed(13);

    lastTransmissionTime = (long)millis();

    }

    void loop()

    {

    currentTime = (long)millis();

    // Needs to call these once per loop

    morseInput.decode();

    morseOutput.encode();

    // SEND MORSE (OUTPUT)

    // Encode and send text received from the serial port (serial monitor)

    if (Serial.available() && morseOutput.available())

    {

    // Get character from serial and send as Morse code

    char sendMorse = Serial.read();

    morseOutput.write(sendMorse);

    // Not strictly needed, but used to get morseSignalString before it is destroyed

    // (E.g. for morse training purposes)

    morseOutput.encode();

    // Also write sent character + Morse code to serial port/monitor

    Serial.write(' ');

    Serial.write(sendMorse);

    Serial.write(morseOutput.morseSignalString);

    }

    // RECEIVE MORSE (INPUT)

    // If a character is decoded from the input, write it to serial port

    if (morseInput.available())

    {

    // Get decoded Morse code character and write it to serial port/monitor

    char receivedMorse = morseInput.read();

    Serial.print(receivedMorse);

    // A little error checking

    if (receivedMorse == '#') Serial.println("< ERROR:too many morse signals! >");

    }

    // Local Morse code feedback from input if not sending Morse simultaneously

    if (morseOutput.available()) digitalWrite(morseOutPin, morseInput.morseSignalState);

    // Check if ongoing transmission (not yet transmission pause)

    if (!morseOutput.available() || morseInput.morseSignalState == true)

    {

    // reset last transmission timer and flag

    lastTransmissionTime = currentTime;

    transmissionEnded = false;

    }

    // Format output with carriage returns after a transmission pause

    if ((currentTime - lastTransmissionTime) > transmissionPaused)

    {

    if (transmissionEnded == false)

    {

    // Separate the transmissions somewhat in the serial monitor with CR's

    for (int cr=0; cr<2; cr++) Serial.println(""); // some carriage returns..

    // Finally set the flag to prevent continous carriage returns

    transmissionEnded = true;

    }

    }

    }

    11 replies
    0
    None
    Clayton Fordkourpetis

    Reply 4 years ago on Introduction

    Well I've taken a look at the barebones example from the library you mentioned and it looks like it should be relatively simple to tack on the Morse code sending functionality (receiving would take some additional coding work, depending on how you wanted to accomplish it). I haven't tested it, but I would make the following additions to my code (line numbers are the current ones, they'll probably change as you add these lines of code in, so be careful)

    //towards the top of the code:
    //additional includes for morse, insert after line #9
    #include <avr/pgmspace.h>
    #include <MorseEnDecoder.h>
    //add object for sending morse, here defined as pin 13, after includes
    morseEncoder morseOutput(13);
    //no additions needed to void setup() assuming the library default of 13wpm is used
    //add the following after lines 140 and 505
    morseOutput.encode();
    morseOutput.write(typedtext);
    0
    None
    kourpetisClayton Ford

    Reply 4 years ago on Introduction

    thank you for your response.

    morseOutput.write(typedtext); will not work.

    char* to char compilation problem

    instead i have used

    for (int i=0; i<(positionintypedtext); i++){

    char sendMorse = typedtext[i];

    morseOutput.write(sendMorse);

    morseOutput.encode();

    Serial.print(i);

    Serial.print(sendMorse);

    Serial.print(morseOutput.morseSignalString);

    }

    everything works in the serial window but no morse code.

    0
    None
    Clayton Fordkourpetis

    Reply 4 years ago on Introduction

    Did you try the for loop with the morseOutput.encode(); before the morseOutput.write(sendMorse); rather than after? That seemed to be the order it had to be in. Also just to make sure, what are you using to check for the Morse output?

    0
    None
    kourpetisClayton Ford

    Reply 4 years ago on Introduction

    this is the code that i am using right now.

    void outputserial(){

    morseInput.setspeed(13);

    morseOutput.setspeed(13);

    lastTransmissionTime = (long)millis();

    for (int i=0; i<(positionintypedtext); i++){

    morseDecoder morseInput(morseInPin, MORSE_KEYER, MORSE_ACTIVE_LOW);

    morseEncoder morseOutput(morseOutPin);

    Serial.println();

    Serial.print(i);

    Serial.print(')' );

    char sendMorse = typedtext[i];

    morseOutput.write(sendMorse);

    morseOutput.encode();

    Serial.write(' ');

    Serial.write(sendMorse);

    Serial.write(' ');

    Serial.write(morseOutput.morseSignalString);

    }

    delay(preventholddelay); //delay a little to prevent continuous cycling

    }

    it needs to be like that :

    morseOutput.write(sendMorse);

    morseOutput.encode();

    otherwise i get nothing.

    0
    None
    Clayton Fordkourpetis

    Reply 4 years ago on Introduction

    Here, I threw together some code to add to mine that should achieve Morse transmission... without the uncooperative library. Tack the variables to the top and the functions at the bottom, and call sendmorse() at lines 140 and 505.

    0
    None
    kourpetisClayton Ford

    Reply 4 years ago on Introduction

    i have just tryed it !

    did you try it on an arduino ?

    it actualy goes inside the for loop for just one time and then it realy freezes.

    it can not pass the for loop at all !

    i had a Serila.println(i);

    and it just comes up with 0.

    never goes again inside the loop at all.

    i will try to convert the ifs in to swich just in case that those are the delays.

    one thing that actualy works as expected is the time from the press of the " Enter " key until the time that goes inside the for loop.

    i excpected 5 seccond and it came up 5000 millis of deference, ech time i tryied it out.

    after that it just freezes.

    0
    None
    kourpetiskourpetis

    Reply 4 years ago on Introduction

    IT DOESN'T FREEZE.

    at the time that i needed to right the previous post i left the Serial Window oppen

    and this is the results that came up :

    0 // i

    8804 // millis that passed throug the loop

    1 // i

    183806 // millis that passed throug the loop

    2 // i

    358810 // millis that passed throug the loop

    3 // i

    533814 // millis that passed throug the loop

    ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????

    175002 millisecond delay between each pass through the for loop.

    0
    None
    Clayton Fordkourpetis

    Reply 4 years ago on Introduction

    You may be right about the if statements causing delays, try changing them to switch/case and see what happens...

    Also another thing to check is that I noticed the code you had before individually was printing the letters to the serial console. If that is in the for loop you used, all those individual serial outputs can cause considerable delays, especially at low baud rates.

    0
    None
    kourpetiskourpetis

    Reply 4 years ago on Introduction

    do you have any idea on how can i use this code to transmit everything in morse code and not to the serial ?