Jump to content

Arduinos, signal transmission and Morse codes


Delay

Recommended Posts

2 hours ago, Delay said:

Are switch statements also called or must they be part of the loop I use them in?

If you mean a conversion 'A'...'Z' into morse code, you probably need not a switch/if, but an array of 0-terminated strings.

Something like:

char const * getMorse(char const chLetter)
{
static char const * const MORSE[] = {".-", "-...", .......};

if ((chLetter < 'A') || (chLetter > 'Z'))
  return 0;

return MORSE[(int)chLetter - (int)'A'];
}

For back conversion you probably have a char array with 26 = 64 or so items.
Then instead of switching/ifing you use the received sequence of dots and dashes as a binary index for the array item.

Edited by kerbiloid
Link to comment
Share on other sites

30 minutes ago, kerbiloid said:

If you mean a conversion 'A'...'Z' into morse code, you probably need not a switch/if, but an array of 0-terminated strings.

It goes to an LED to be interpreted by another machine. I thought of Converting the text to Morse code and then read that Morse code to turn on the LED.
Well, as kindly pointed out by both @razark and @Aperture Science, this first step of string -> Morse code is redundant and I can jump to LED signals immediately. And that's all the sending portion needs to do.
I'll see about the receiving end. I have some own ideas, but they all have the dreaded "LKKL"-style Morse encoding in them.
Encoding is simple (in comparison), decoding is hard. I'm sure that's universally applicable.

And while I already have razark tagged, let me quickly as for reassurance that I understood this aspect of a switch-statement correctly.

/*Some more questions / expected behaviours, just to make sure I understood switches, function calls and how they work*/

String = "Example text"

char MorseEncoder(index){
  switch (String[index]){	//Expected: switch-statement uses 'index' provided by the function to get the corresponding letter to test with
  case 'A':			//('index' gets incremented by 1 after each iteration)
  case 'a':
    send_dit();			//Morse sequence to transmit if character is A or a (I want this to handle both upper and lower case)
    send_dah();
    send_space();
    break;
	}
}

Would this work the way I expect it to?
In this limited example I would expect it to finally send something after reaching String[2], which is 'a'. But even if the entire string was in capslock, String[2] should still produce the Morse code for 'a'.

18 minutes ago, Nivee~ said:

Uuuuh.. umm.. yeah... sure... yeah that loop...if-else, of course...umm..data types..

Hey, I'm also struggling here and I'm afraid these poor guys will need some psychotherapy once I finally understood all vital functions of C.

Edited by Delay
Link to comment
Share on other sites

No worries @Nivee~ ! You'll understand all that and much more.

Just keep in mind, there is always more than one solution to a problem and no solution is the only correct one. If you solve a problem or at that stage successfully do an example, maybe with a few changes from your side, you're perfectly fine. Go step by step.

I just read that your pc is down. If you can afford it, get yourself a dedicated pc for programming. That can be an old used one thrown out of the window elsewhere. Install your programming stuff (i mean Linux, compiler, debugger and libraries, editor/ide, and a browser :-)) and keep the installation in a frozen state, or at least as clean and lean as possible.

Scrub. I am doing too many things at the same time :confused:

 

And, of course, there are a plethora of programming forums and sites. Right now I am trying to wrap my mind around C++17 multithreading. The interesting/funny thing that might happen is that i skip it and go with OpenMP.

Edited by Green Baron
Link to comment
Share on other sites

12 minutes ago, Delay said:

Would this work the way I expect it to?

All I see missing is the loop, otherwise, yes, I think it should do what you think it will do.

 

29 minutes ago, Nivee~ said:

Uuuuh.. umm.. yeah... sure... yeah that loop...if-else, of course...umm..data types..

I've felt that exact same feeling when I look at code I wrote a year before.  

 

7 minutes ago, Green Baron said:

If you can afford it, get yourself a dedicated pc for programming. That can be an old used one thrown out of the window elsewhere. Install your programming stuff (i mean Linux, compiler and libraries, editor/ide, and a browser :-)) and keep the installation in a frozen state, or at least as clean and lean as possible.

Depending on what you're trying to do, a Raspberry Pi could be good.  It's cheap, takes up no room, you can use a small SD card and make multiple different installs and switch them out easily, and make backups in case you break things, so it takes the fear out of trying something you don't quite fully understand.

Link to comment
Share on other sites

11 minutes ago, razark said:

All I see missing is the loop, otherwise, yes, I think it should do what you think it will do.

That would probably be either...

for (i = 0; i = strlen(String) - 1; i++){		//I expect C to work similar to Python in that indices range from 0 to "string length" - 1
}

...or...

int i = 0;
while(i <= strlen(String) - 1){
  i = i++;
}

, right?

Edited by Delay
Link to comment
Share on other sites

Yes :-) It starts with 0, but strlen() omits the trailing \0. That's why it is 1 smaller than sizeof( s ).

You go: for( unsigned int i=0; i<strlen(s); i++ ) { do something useful }

Edit: you have an implicit conversion there from signed to unsigned, that's why i wrote unsigned int to make it clear ;-)

'nother Edit: @razark wrote it correctly, i corrected my post: prefer the post increment i++ over the pre increment ++i, as the latter might introduce a stall in the processor pipeline because of the dependency of incrementing before the operation.

Edited by Green Baron
Link to comment
Share on other sites

3 minutes ago, Delay said:

for (i = 0; i = strlen(String) - 1; i++)

should be 
for (i = 0; i < strlen(String); i++)

which will break out of the loop when i is equal to the length of the string.  The way you have it written, it will assign the length - 1 to the variable i.

And

5 minutes ago, Delay said:

i = i++

This will not do what you want it to.  (Wait.  I'm not sure what it would evaluate to...)

i++;

will suffice.  You don't need the assignment, since it will already increment i.

Link to comment
Share on other sites

11 minutes ago, razark said:

which will break out of the loop when i is equal to the length of the string.  The way you have it written, it will assign the length - 1 to the variable i.

For the function in my previous post, that would be 'index'. So I guess a "complete" (rather: more complete, since send_dit/dah/space aren't defined anywhere) script would look like this:

String = "Example text"

char MorseEncoder(index){		//in the complete version this would assign all characters in the alphabet (maybe even numbers, who knows)
  switch (String[index]){
  case 'A':
  case 'a':
    send_dit();			
    send_dah();
    send_space();
    break;
	}
  case 'B':
  case 'b':
  	sent_dah();
  	sent_dit();
  	sent_dit();
  	sent_dit();
  	sent_space();
  	break;
  //and so on
}

for (int i = 0; i = strlen(String) - 1; i++){
  MorseEncoder(i);			//Call the function. That should take care of literally everything else.
}

 

Edited by Delay
Link to comment
Share on other sites

1 hour ago, Nivee~ said:

<Sees programming conversation going on, tries to join in>

Uuuuh.. umm.. yeah... sure... yeah that loop...if-else, of course...umm..data types..

As someone who only knows Python and JS:

Oh yeah, strings are terrible. So hard to use. How about that pointer arithmetic? And having to write everything yourself instead of just using libraries. I definitely have experience with that. Yep. And uhh... switch voids.

Link to comment
Share on other sites

Two things remain, @Delay.

strlen() returns a size_t, which is an unsigned integer. Try not to compare unsigned and signed values. The compiler will implicitly convert i to unsigned, in this case no problem, but in other cases it can cause a Surprise ! :-) Be explicit with your data types.

Modern compilers are clever enough to do the evaluation of strlen() before entering the loop instead of evaluating it every iteration. Be aware that eventually more complex operations may not be as obvious to the compiler, better write that expression before the loop, as it is only computed once.

:-)

Edited by Green Baron
Link to comment
Share on other sites

12 minutes ago, Delay said:

For the function in my previous post, that would be 'index'. So I guess a "complete" (rather: more complete, since send_dit/dah/space aren't defined anywhere) script would look like this:

A couple of changes.

A: instead of passing the index, you can just pass the character you wish to encode.

void MorseEncoder(char input)  //in the complete version this would assign all characters in the alphabet (maybe even numbers, punctuation, who knows)
{		
  switch (input)
  {
    case 'A':
    case 'a':
    send_dit();			
    send_dah();
    send_space();
    break;

  case 'B':
  case 'b':
  	sent_dah();
    sent_dit();
  	sent_dit();
  	sent_dit();
  	sent_space();
  	break;
  //and so on
  }
}

 

B: Instead of having the strlen() call every loop, do it once, before entering.  (Optimizing compilers probably handle this, but why take the chance.  You never know when you might need to do it yourself, or when you might be working on old systems.  Build good practice into your habits where possible.)

limit = strlen(String);

for (int i = 0; i < limit; i++)
{
  MorseEncoder(String[i]);			//Call the function. That should take care of literally everything else.
}

 

Link to comment
Share on other sites

11 minutes ago, CatastrophicFailure said:

Back in my day, we just programmed “hello world!” in BASIC on monochrome screen loaded from a 5.25” floppy!

Floppy?  You lot had it easy with your floppies and your screens!

I was writing BASIC on cassette tapes hoping I remembered to note down the counter when I hit record on the tape deck!  And wait for dad to stop using the black and white TV so we could switch it to channel three and plug in the computer!

 

*wanders off to shake his cane at those meddlesome kids on his lawn*

Link to comment
Share on other sites

Because it is just pseudocode. Of course C syntax requires a data type for a declaration and definition.

Edit: Advanced: do use const whenever possible, and be aware of implicit conversions.

const size_t i = strlen( string );

Edited by Green Baron
Link to comment
Share on other sites

Spoiler
7 hours ago, CatastrophicFailure said:

I have to go yell at a cloud.

 

7 hours ago, CatastrophicFailure said:

Back in my day

they called "clouds" those bulky white things above.

Happily, now we understand that clouds are network storages.

But it's strange: why did they call the bulky white things after network storages? Did they believe in a sky data center?

 

Link to comment
Share on other sites

5 hours ago, Delay said:

Why is there no "int" in front of "limit" to declare this as an integer?

 

3 hours ago, Green Baron said:

Because it is just pseudocode.

That's why.  It's samples of the working code and such.

The same reason there's no #include <whatever.h> or function definitions or int main(void){ } included.

Link to comment
Share on other sites

It took almost the entire lesson to write the complete switch-statement - for now it's just all letters - but the script works as expected.
Though I did forget some chars and ints and I typed "Text = ... ", rather than "Text[] = ...", but these got kindly pointed out to me and now I have a fully functional encoder that can turn on an LED to send a signal. I just have to be more paranoid about type declarations.
Missed some semicolons and breaks too, but at least I caught all of those. Except for one ; .

Now... about this decoder...
I'd guess that unlike encoding, where you can directly go from text to transmission, for decoding you need a step in between to store the results in a format you can easily work with.

Link to comment
Share on other sites

2 hours ago, Delay said:

It took almost the entire lesson to write the complete switch-statement - for now it's just all letters - but the script works as expected.
Though I did forget some chars and ints and I typed "Text = ... ", rather than "Text[] = ...", but these got kindly pointed out to me and now I have a fully functional encoder that can turn on an LED to send a signal. I just have to be more paranoid about type declarations.
Missed some semicolons and breaks too, but at least I caught all of those. Except for one ; .

Now... about this decoder...
I'd guess that unlike encoding, where you can directly go from text to transmission, for decoding you need a step in between to store the results in a format you can easily work with.

The decoder will basically track the signal's timing, refer to my first post;

You could send one letter at a time back to the computer via Serial.println() (I think that's the arduino function), or you could set a char vector and then output it as a whole phrase.

Link to comment
Share on other sites

Hypothetically you could skip the switch block and use ASCII. Convert the characters to binary, then convert that to a unary encoding scheme. Something like
00 = ··
11 = ··
10 = ·-·
01 = ·-·

Basically you would output a dit for every bit, and a dah for a change in bit-value.

Link to comment
Share on other sites

1 minute ago, razark said:

How would you encode a leading dah?

You, ah, don't? You assume the string is a string of information in a stream of 0x00 NUL. The leading byte is 0x02 STX, so the first bit must be 0 and the byte as a whole 00000010 => ······-·-·.

Link to comment
Share on other sites

8 minutes ago, 0111narwhalz said:

You, ah, don't? You assume the string is a string of information in a stream of 0x00 NUL. The leading byte is 0x02 STX, so the first bit must be 0 and the byte as a whole 00000010 => ······-·-·.

Perhaps I'm not understanding how you are encoding here.

00 = ·· = I
11 = ·· = I
10 = ·-· = R
01 = ·-· = R

So, how do you encode C as -.-.  or K as -.- ?

 

Edit:

Are we talking about encoding the timing?

Edited by razark
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...