Go Down

Topic: Morse Code programming (Read 2523 times) previous topic - next topic

Mecatronicsstudent

I have been trying for a little while to come up with a program for a morse code transmitter. It uses an led to flash what is typed into the serial monitor. The problem is that all of the code I have seen on the Internet uses delay and I can't use that because I am eventually going to have to have it send and receive at the same time. Can anyone one provide with something similar to delay that won't stop everything. I have been trying to work with millis, but it is getting complicated.

CrossRoads

. . . - - - . . .

See the blink without delay example in the learning section, or playground.

Basically, you will watch the time going by, and when enough has elapsed you start/stop your action, and watch the time go by some for the next action.
Then you can be doing other stuff while that time is elapsing.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Mecatronicsstudent

Yes. I have seen this. I am just having trouble implementing it into my morse code program. I understand how it works though.

Grumpy_Mike

So post what you have implemented and we can see where you are going wrong.

Mecatronicsstudent

#4
May 07, 2012, 09:44 pm Last Edit: May 07, 2012, 10:18 pm by CrossRoads Reason: 1
What I tried to do was have a millis counter for the period of a dot and dash and letter space. It seems like there must be an easier way then having a millis counter for each one. This program does upload and will light but not blink the led when those letters are typed.

Code: [Select]

#define dotPeriod 250
#define dashPeriod (dotPeriod*3)
#define relaxTime (dotPeriod)
#define letterSpace (dotPeriod*3)
#define wordSpace (dotPeriod*7)
#define flash ( digitalWrite(ledPin,ledState))
const int ledPin =  13;      // the number of the LED pin


int leddotState = LOW;  
int leddashState = LOW;
int ledwordspaceState = HIGH;
long previousdotMillis = 0;  
long previousdashMillis = 0;
long previouswordspaceMillis = 0;

void dot(){
 digitalWrite(ledPin,leddotState);
}
void dash(){

digitalWrite(ledPin,leddashState);
}
void wordspace(){
digitalWrite(ledPin,ledwordspaceState);
}
void setup(){
 Serial.begin(9600);
 // set the digital pin as output:
 pinMode(ledPin, OUTPUT);
}

void loop(){
  unsigned long currentdotMillis = millis();
  unsigned long currentdashMillis = millis();
   unsigned long currentwordspaceMillis = millis();
  if(currentdotMillis - previousdotMillis > dotPeriod) {
   // save the last time you blinked the LED
   previousdotMillis = currentdotMillis;  

   // if the LED is off turn it on and vice-versa:
   if (leddotState == LOW)
     leddotState = HIGH;
   else
     leddotState = LOW;
 
 if(currentdashMillis - previousdashMillis > dashPeriod) {
   // save the last time you blinked the LED
   previousdashMillis = currentdashMillis;  

   // if the LED is off turn it on and vice-versa:
   if (leddashState == LOW)
     leddashState = HIGH;
 }
   else
     leddashState = LOW;
     
     
  if(currentwordspaceMillis - previouswordspaceMillis > letterSpace) {
   // save the last time you blinked the LED
   previouswordspaceMillis = currentwordspaceMillis;  

   // if the LED is off turn it on and vice-versa:
   if (ledwordspaceState == LOW)
     ledwordspaceState = HIGH;
   else
     ledwordspaceState = LOW;
         
     
     
    if (Serial.available() > 0) {
   int inByte = Serial.read();
switch (inByte) {
   case 'a':    
     dot();
     break;
   case 'b':    
     dot;
     dot;
     dash;
     break;
   case 'c':    
     dash;
     dot;
     dot;
     break;
   case 'd':    
    dot;
    dash;
    dot;
    dot;
     break;
   case 'e':    
  dash ;
  dot ;
  dash;
     break;
  case ' ':
  wordspace();
  break;

}
    }
 }
  }
}
     

CrossRoads

#5
May 07, 2012, 10:17 pm Last Edit: May 07, 2012, 10:19 pm by CrossRoads Reason: 1
I think you need to add some flags to these.
Basically, check if a dot, dash, or space is progress, if so and the time is elapsed, Then turn it off, maybe like this:
Code: [Select]

void dot(){
 digitalWrite(ledPin,leddotState);
 dot_in_progress = 1;
 dotEndmillis = millis() + dotPeriod;
 leddotState = HIGH;
 digitalWrite (ledPin, leddotState);
}

then within loop:

Code: [Select]

  if(  (dot_in_progress == 1) && (millis() >=dotEndmillis) ) { //
     dot_in_progress = 0;
     leddotState = LOW;
     digitalWrite (ledPin, leddotState);
  }
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

hscriber

If I'm not mistaken, you need "()" when you call your subroutines.  For instance, when you wish to run void dot(), your code should read: dot();

Grumpy_Mike

Yes I was just going to say that:-
Code: [Select]

  case 'b':   
      dot;
      dot;
      dash;


should be

Code: [Select]

  case 'b':   
      dot();
      dot();
      dash();

Mecatronicsstudent

This is very helpful. Thanks

Grumpy_Mike

The other thing is this:-
Code: [Select]
void dot(){
  digitalWrite(ledPin,leddotState);
}
void dash(){
digitalWrite(ledPin,leddashState);
}


Just sets the LED pin low. I can't see any instruction that puts it high. You have a macro called flash defined but you never use it.

The Clever Monkey


The problem is that all of the code I have seen on the Internet uses delay and I can't use that because I am eventually going to have to have it send and receive at the same time.


I don't have much help to offer, but I think it's funny that you want to communicate with morse asynchronously!  I mean, typically, conversations with morse occur synchronously. I know it isn't a requirement or limitation of the encoding itself, but the practice of code is such that a great number of shortcuts that are basically "I'm done, go ahead, I'll wait" are already there.

Not that a machine has to care about that, assuming the send/recv data isn't a real conversation.
I yield() for co-routines.

liudr

I have some sample code you can look at but you really don't have to care about the asyn receive like The Clever Monkey said. It makes no sense to transmit and receive at the same time.

http://liudr.wordpress.com/libraries/phi_morse/

Mecatronicsstudent

It is a requirement of a school project. I could do this if I only had to send or receive one at a time. But here is mu updated code that still only lights it up, not blinks. As for the digital write ledpin leddotstate, all that is doing it writing whatever state the led is in. I should not automatically set it to low I don't think.
I am new to programming and do not know exactly how everything works yet.

#define dotPeriod 250
#define dashPeriod (dotPeriod*3)
#define relaxTime (dotPeriod)
#define letterSpace (dotPeriod*3)
#define wordSpace (dotPeriod*7)
const int ledPin =  13;      // the number of the LED pin
int dot_in_progress = 0;
int dash_in_progress = 0;

int leddotState = LOW; 
int leddashState = LOW;
int ledwordspaceState = HIGH;
unsigned long dotEndmillis = millis() + dotPeriod;
unsigned long dashEndmillis = millis() + dashPeriod;
void dot(){
  dotEndmillis;
  dot_in_progress = 1;
  leddotState = HIGH;
  digitalWrite (ledPin, leddotState);
}
void dash(){
  dashEndmillis;
  dash_in_progress = 1;
  leddashState = HIGH;
  digitalWrite (ledPin, leddashState);
  digitalWrite(ledPin,leddashState);
}
void wordspace(){
digitalWrite(ledPin,ledwordspaceState);
}
void setup(){
  Serial.begin(9600);
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop(){

    if( (dot_in_progress == 1) && (millis() >=dotEndmillis) ) { //
      dot_in_progress = 0;
      leddotState = LOW;
    }
if(  (dash_in_progress == 1) && (millis() >=dashEndmillis) ) { //
      dash_in_progress = 0;
      leddashState = LOW;
}
   

     
     
     if (Serial.available() > 0) {
    int inByte = Serial.read();
switch (inByte) {
    case 'a':   
      dot();
      break;
    case 'b':   
      dot();
      dot();
      dash();
      break;
    case 'c':   
      dash();
      dot();
      dot();
      break;
    case 'd':   
     dot();
     dash();
     dot();
     dot();
      break;
    case 'e':   
   dash();
   dot();
   dash();
      break;
   case ' ':
   wordspace();
   break;

}
     }
  }

Grumpy_Mike

You forgot the code tags!!

Quote
As for the digital write ledpin leddotstate, all that is doing it writing whatever state the led is in. I should not automatically set it to low I don't think.

If that is all you do then it will never blink like you are seeing.

Mecatronicsstudent

what I have is another piece of code that should change the state according to the interval needed. All that does it write it to that state.

Go Up