Community
cancel
Showing results for 
Search instead for 
Did you mean: 
RGarc10
Novice
1,491 Views

Turn my Morse Code Decoder into a server

Hello, all I have two things that I'm trying to bring together. A Morse Code Decoder, ie. an Arduino program that takes the pushes of a momentary push button into a dit if it's a short press or dah if it's a long press, and dynamically decodes the sequence of Morse Code characters into their respective English character representations and displays it on 16x2 LCD screen. I will paste my code here. I've refactored the code but it may still be confusing so feel free to ask me questions. Also I should say that it depends on special hardware from one of Grove's developer kits, but I don't have to change any of their hardware configurations and the code that controls the hardware should be commented on what it's doing in the context of the program:

//Note: this program uses an LCD screen and a momentary pushbutton from the Grove Kit

# include

# include "rgb_lcd.h"

//hardware constants

rgb_lcd lcd;

const int colorR = 66;

const int colorG = 241;

const int colorB = 244;

const int buttonPin = 3;

// Set the timer system for the button presses

long buttonPressTime = 0;

long longPressTime = 1000; //a long button press is one second, in this morse code implementation

unsigned long previousMillis = 0; // will store last time LED was updated

const long interval = 10000; // interval at which to decode a new morse code character (milliseconds)

//variables for the decoding algorithm

String morseVals = String(""); //where I will store each morse character that the user enters, will be passed to the loop statement

char englishChar = ' ';

//Text state of the LCD

int morseColumn = 0;

int englishColumn = 0;

const int MORSE_ROW = 0;

const int ENGLISH_ROW = 1;

// Set the state system of the button presses

boolean isButtonActive = false; // for telling if the button is being pressed so that we only have to use digitalRead() once

boolean isLongPressActive = false;

//helper function for reseting the first row

void resetMorseRow() {

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

lcd.setCursor(i, MORSE_ROW);

lcd.print(" ");

}

morseColumn = 0;

lcd.setCursor(morseColumn, MORSE_ROW);

}

void setup()

{

// set up the LCD

lcd.begin(16, 2);

lcd.setRGB(colorR, colorG, colorB);

//lcd.cursor(); //makes the cursor where the next character will be printed at, but only useful for debugging as it looks too much like a dah

lcd.setCursor(0, 0);

}

void loop()

{

morseDecoder();

}

void morseDecoder() {

if (digitalRead(buttonPin) == HIGH) { // if the button is being pressed ...

if (isButtonActive == false) { // if the last saved state of the button was set to false i.e it's the first run of the program ...

isButtonActive = true; // set it to true

buttonPressTime = millis(); // save the time when the button was pressed

}

if ((millis() - buttonPressTime > longPressTime) && (isLongPressActive == false)) { // if the current time - the time the button was pressed is the long button press time

// AND the last saved state of the Long button press is set to false (to avoid recording two long presses)

isLongPressActive = true; // set the state of isLongPressActive to true

lcd.setCursor(morseColumn++,MORSE_ROW); // specify the next column in the "morse row"

lcd.print('_'); // print a dah

morseVals = morseVals + "_";

}

}

else { // happens if the long press case failed

if (isButtonActive == true) { // if the button is being pressed

if (isLongPressActive == true) { // if the long press state is set to true ...

isLongPressActive = false; // set it to false

}

else {

lcd.setCursor(morseColumn++,MORSE_ROW);

lcd.print('.'); // print a dit

morseVals = morseVals + ".";

}

isButtonActive = false; // set button active to false (we don't check how short a short press is)

}

}

//it is my understanding that the character timer does not depend on whether or not a button was presses, just time so save the time for each interval

unsigned long currentMillis = millis();

if ((currentMillis - previousMillis >= interval) || (morseVals.length() >= 5) ) { //TODO: this if statement works as a delay right now, but I should I should actually reset the timer whenever the user presses the button

// save the last time you printed an english character

previousMillis = currentMillis;

// print the character now and move up one row once you finish

lcd.setCursor(morseColumn, MORSE_ROW);

//declare the big switch case here

if(morseVals.equals("._")){

englishChar = 'A';

}

else if(morseVals.equals("_...")) {

englishChar = 'B';

}

else if(morseVals.equals("_._.")) {

englishChar = 'C';

}

else if(morseVals.equals("_..")) {

englishChar = 'D';

}

else if(morseVals.equals(".")) {

englishChar = 'E';

}

else if(morseVals.equals(".._.")) {

englishChar = 'F';

}

else if(morseVals.equals("__.")) {

englishChar = 'G';

}

else if(morseVals.equals("....")) {

englishChar ...

Tags (1)
0 Kudos
5 Replies
FTinetti
Honored Contributor I
77 Views

Hi RobertoGarcia,

I'm not completely sure I understand your problem/question. Specifically about a web server on the Intel Galileo, I suggest you do not use any code based on the Arduino Ethernet shield, mostly because the Intel Galileo Ethernet I/O does not have any relationship to the SPI port. Take a look at ,

Are you planning to "replace" physical buttons by a web interface?

HTH,

Fernando.

RGarc10
Novice
77 Views

Hello, Fernando,

I am planning to not replace the physical momentary pushbuttons on the web page interface. I want both buttons on the web server and the pushbuttons to do the same functions, send Morse Code characters, either dits or dahs. I just don't know how to write the function that will be used on the web interface.

I'm not using the web ethernet shield, what I'm doing is connecting the ethernet shield straight to the PC computer I'm debugging with from the ethernet port that is built-in to the Intel Galileo board. Because this is the only way I know how to setup a server I would like to do it similarly:

/*--------------------------------------------------------------

Program: eth_websrv_LED

Description: Arduino web server that serves up a web page

allowing the user to control an LED

Hardware: - Arduino Uno and official Arduino Ethernet

shield. Should work with other Arduinos and

compatible Ethernet shields.

- LED and resistor in series connected between

Arduino pin 2 and GND

Software: Developed using Arduino 1.0.3 software

Should be compatible with Arduino 1.0 +

References: - WebServer example by David A. Mellis and

modified by Tom Igoe

- Ethernet library documentation:

http://arduino.cc/en/Reference/Ethernet http://arduino.cc/en/Reference/Ethernet

Date: 11 January 2013

Author: W.A. Smith, http://startingelectronics.org http://startingelectronics.org

--------------------------------------------------------------*/

# include

# include

// MAC address from Ethernet shield sticker under board

byte mac[] = { 0x98, 0x4F, 0xEE, 0x00, 0x2F, 0x0F };

IPAddress ip(); // IP address, may need to change depending on network

EthernetServer server(80); // create a server at port 80

String HTTP_req; // stores the HTTP request

boolean LED_status = 0; // state of LED, off by default

void setup()

{

Ethernet.begin(mac, ip); // initialize Ethernet device

server.begin(); // start to listen for clients

Serial.begin(9600); // for diagnostics

pinMode(LED_BUILTIN, OUTPUT); // On board LED

}

void loop()

{

EthernetClient client = server.available(); // try to get client

if (client) { // got client?

boolean currentLineIsBlank = true;

while (client.connected()) {

if (client.available()) { // client data available to read

char c = client.read(); // read 1 byte (character) from client

HTTP_req += c; // save the HTTP request 1 char at a time

// last line of client request is blank and ends with \n

// respond to client only after last line received

if (c == '\n' && currentLineIsBlank) {

// send a standard http response header

client.println("HTTP/1.1 200 OK");

client.println("Content-Type: text/html");

client.println("Connection: close");

client.println();

// send web page

client.println("<!DOCTYPE html>");

client.println("");

client.println("");

client.println("Arduino LED Control");

client.println("");

client.println("");

client.println("LED");

client.println("

Click to switch LED on and off.

");

client.println("");

ProcessCheckbox(client);

client.println("");

client.println("");

client.println("");

Serial.print(HTTP_req);

HTTP_req = ""; // finished with request, empty string

break;

}

// every line of text received from the client ends with \r\n

if (c == '\n') {

// last character on line of received text

// starting new line with next character read

currentLineIsBlank = true;

}

else if (c != '\r') {

// a text character was received from client

currentLineIsBlank = false;

}

} // end if (client.available())

} // end while (client.connected())

delay(1); // give the web browser time to receive the data

client.stop(); // close the connection

} // end if (client)

}

// switch LED and send back HTML for LED checkbox

void ProcessCheckbox(EthernetClient cl)

{

if (HTTP_req.indexOf("LED2=2") > -1) { // see if checkbox was clicked

// the checkbox was clicked, toggle the LED

if (LED_status) {

LED_status = 0;

}

else {

LED_status = 1;

}

}

if (LED_status) { // switch LED on

digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)

// checkbox is checked

cl.println("

onclick=\"submit();\" checked>LED2");

}

else { // switch LED off

digitalWrite(LED_BUILTIN, LOW);

// checkbox is unchecked

cl.println("

onclick=\"submit();\">LED2");

}

}

FTinetti
Honored Contributor I
77 Views

Hi RobertoGarcia,

Something sounds strange in

I want both buttons on the web server and the pushbuttons to do the same functions, send Morse Code characters, either dits or dahs.

I think it does not make any sense to have both buttons on the web server... who and how send the code characters? and to what other site/application would the web server sent those characters to? Maybe you mean having the buttons in the web interface or web browser where a user may click/select any of them and send it to the web server?

What do you mean by "the function that will be used on the web interface"? Wouldn't be enough to have two web buttons at the web interface? If it is the case, it is not related to Intel Galileo but to web programming/web site design. It's not a problem if that's the case, It's just for making clear the problem/question.

About

I'm not using the web ethernet shield, what I'm doing is connecting the ethernet shield straight to the PC computer

Again I'm lost... if you are using an Intel Galileo then you don't have any Ethernet shield...

Do you know the code you included in your post or you are asking about some explanation on it? Actually, if all you want in the web browser are the two Morse dit and dah, then two submit buttons are all you need... or maybe I misunderstood your post... sorry.

Maybe it would be helpful if you describe the web interface for the user on one side and the web server behavior for that web interface on the other...

HTH,

Fernando.

RGarc10
Novice
77 Views

Hi, sorry about the confusion. My assignment is for the user to be able to decode their morse code with both options, the web page that the intel galileo serves and the physical buttons on the galileo board. By buttons on a web browser I mean such as the following syntax:

Send dit

And once the user sends those buttons the program will decode the characters into their English characters.

RobertoGarcia wrote:

Maybe you mean having the buttons in the web interface or web browser where a user may click/select any of them and send it to the web server?

Yes this is what I mean, the user would "send" the characters to the Intel Galileo server, and then the rest of the server computes the logic of it, which is the part I'm having trouble getting started. Like, how would Iretrieve the characters once the user sends them by pressing the web buttons. This is similar to my LCD server code, where the guide I got it from did this:

// switch LED and send back HTML for LED checkbox

void ProcessCheckbox(EthernetClient cl)

{

if (HTTP_req.indexOf("LED2=2") > -1) { // see if checkbox was clicked

// the checkbox was clicked, toggle the LED

if (LED_status) {

LED_status = 0;

}

else {

LED_status = 1;

}

}

if (LED_status) { // switch LED on

digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)

// checkbox is checked

cl.println("

onclick=\"submit();\" checked>LED2");

}

else { // switch LED off

digitalWrite(LED_BUILTIN, LOW);

// checkbox is unchecked

cl.println("

onclick=\"submit();\">LED2");

}

}

Except instead of a checkbox that turns an LED off or on, how do I get the web buttons to transmit characters back to the server, which it will then process in the form of decoding.

Nextly, sorry I meant to say that I plugged the ethernet port on one end to my PC laptop into the ethernet port on my Galileo. It's the one built-in, not an ethernet shield. I guess my question is about web design/programming and also howto bring it together with Arduino code. I'm new to networking and server programming. Let me know if I may have missed something.

FTinetti
Honored Contributor I
77 Views

Hi RobertoGarcia,

Now I think we are in the same page. I think you may use a web page like this one:

Morse Code

Text:

(you can copy the text and save it to index.html in order to have a quick look at it). The "meta" in the html head would help to see the web page in cell phones and tablets.

Taking this html as a "departure point" you would be able to add the decoded characters after "Text: ". Actually, if you take a look at the link I included in a previous post ( ) you may read in the last post of the thread how to use the .html in a file, read it and send it to the client from the web server running in the Intel Galileo. However, you will have to process each client request in a similar way of what you are doing now with the led, but storing the "." and "-" in a string and decoding it in a way similar to that you included in the code in the first post.

HTH,

Fernando.