Pages: [1] 2   Go Down
Author Topic: Needs help in programming logic on a simple idea.  (Read 1261 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 0
Posts: 228
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am trying to build a Morse code beep time announcer. Already have problems trying different tone generate library.
my questions are:

1, how can I generate a tone without using delay()?

2, how can I make tones corresponds to the Morse code? ie, dit, dot,dot,dot,dot for 1

3, how can I make it beeps every minutes? ie, when it's 12:44, it should beep like this: .---- ..---  ....-  ....-

any help will be highly appreciated!! thanks in advance



Here is what I got so far. Using softtimer library, I get compiling errors. I have no idea what went wrong.

Code:
#include <SoftTimer.h>
#include <TonePlayer.h>
#include <LiquidCrystal.h>
#define beep 7
LiquidCrystal lcd(8,9,10,11,12,13);

int sec=0;
int minu=0;
int hr=0;
unsigned long pstimer=0;

int pbutton3=1;
int pbutton5=1;
int count=0;

TonePlayer tonePlayer(beep, 500);

void setup(){

lcd.begin(16,2); 

pinMode (A3, INPUT_PULLUP);
pinMode (A5, INPUT_PULLUP);   
}

void loop(){
 
 
int button3= digitalRead(A3);

if(button3!=pbutton3){
  if(button3==0){
    minu++;
  }
  pbutton3=button3;
}

int button5= digitalRead(A5);
if(button5!=pbutton5){
  if(button5==0){
    hr++;
  }
  pbutton5=button5; 

 
unsigned long timer= millis();

 if(timer-pstimer > 1000){
   sec++;
   pstimer = timer;   
   count++;
 }   

if(count==3){
  tonePlayer.play("c1g1c1g1j2j2c1g1c1g1j2j2o1n1l1j1h2l2_2j1h1g1e1c2c2");
}

if(count==6){
count=0;
  tonePlayer.play("c1g1c1g1j2j2c1g1c1g1j2j2o1n1l1j1h2l2_2j1h1g1e1c2c2");
}

 
if(sec==60){
 sec=0;
 minu++;
}

if(minu==60){
 minu=0;
 hr++;

 


char szTime[16];
sprintf( szTime, "Time:%02d:%02d:%02d", hr, minu, sec );
lcd.setCursor(0,1);
lcd.print( szTime );

lcd.setCursor(0,0);
lcd.print( "Morse Code Clock" );

}



Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18767
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is what I got so far. Using softtimer library, I get compiling errors.

Which are?
Logged


Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 626
Posts: 34122
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

A dot is a tone for one unit of time a dash fr three units of time with a gap of one unit of time between them,

Quote
3, how can I make it beeps every minutes
Use the technique in the blink without delay example in the IDE.
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 228
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A dot is a tone for one unit of time a dash fr three units of time with a gap of one unit of time between them,

Quote
3, how can I make it beeps every minutes
Use the technique in the blink without delay example in the IDE.

that example will repeatedly blink a led, which is not the cause here. I need to beep a tone in a complicated morse code pattern.
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 228
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Here is what I got so far. Using softtimer library, I get compiling errors.

Which are?

that library is complicated, and with little documentation. I decided not to use it right now.
Logged

Global Moderator
Offline Offline
Brattain Member
*****
Karma: 484
Posts: 18767
Lua rocks!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

1, how can I generate a tone without using delay()?

Have a "state machine". Remember how far through the current sequence you are, and when the desired time is up (one dot length or one dash length) start (or stop) the next tone.

http://www.gammon.com.au/blink
Logged


Offline Offline
Full Member
***
Karma: 0
Posts: 228
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks
1, how can I generate a tone without using delay()?

Have a "state machine". Remember how far through the current sequence you are, and when the desired time is up (one dot length or one dash length) start (or stop) the next tone.

http://www.gammon.com.au/blink

Logged

UK
Offline Offline
Shannon Member
****
Karma: 223
Posts: 12631
-
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Given that you are generating these sequences on a timed basis there are two approaches you can take.

The blocking approach is to wait until it is time to send a sequence and then carry out a blocking sequence of beep/wait actions until the sequence is complete, then go back to waiting until it is time to send the next sequence. This approach means your sketch can only control one thing at a time and is a very limited approach, but it could be made to work. This would be using the delay() function that you mentioned in point (1) and say you want to get away from - IMO you're right to want to get away from it.

The non-blocking approach needs two activities to be performed on a timed basis. The first activity decides whether it is time to send out a morse code sequence. The second activity sends the timed beeps that comprise the requested sequence. The two activities need to communicate with each other. The way I'd implement this is with a circular buffer containing a queue of morse characters which need to be sent and haven't been sent yet. Your clock processing would just write morse characters to this queue. The sending function would use the timing logic demonstrated in the blink without delay example sketch to manage the sending of the sequence of beeps and gaps that constitute a given character, then pull the next morse character off the queue. It's up to you whether you want the queue to hold ascii characters or dot/dash/gap tokens. Having it hold dot/dash/gap tokens would simplify the sending code but means the queue would take up more space.
Logged

I only provide help via the forum - please do not contact me for private consultancy.

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 538
Posts: 27069
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I would give it a try like this, using some arrays and making your own tone.
Have to declare all the variables, add setup, etc.
Sorry about the lack of indenting
Code:
byte timeArray [] = {0,0,0,0,};
byte dotdash [] = {0b00000000, 0b00010000, 0b00011000, 0b00011100, 0b00011110, 0b00011111, 0b00001111, 0b00000111, 0b00000011, 0b00000001,};
//http://en.wikipedia.org/wiki/Morse_code

void loop(){
currentTime = micros(); // capture the 'time'
if ( (currentTime – nextTime) >= oneSecond){ // one second gone by?
nextTime = nextTime + oneSecond; // update for next time check
minutesOnes = minutesOnes + 1;
timeUpdate = 1; // set flag to make some noise on 1 minute updates
if (minutesOnes == 10){ // rollover
minutesOnes = 0;
minutesTens = minutesTens +1;
if (minutesTens == 6){ // rollover
minutesTens = 0;
hoursOnes = hoursOnes + 1;
if (hoursOnes == 10){  // rollover
hoursOnes = 0;
hoursTens = hoursTens +1;
if ( (hoursTens == 2) && (hoursOnes== 4){ // rollover at 24:00 - or set to 1 & 2 for 12 hour
hoursTens = 0;
hoursOnes = 0;
} // hoursTens check
} // hoursOnes check
} // minutesTens check
} // minutesOnes check
timeArray[0] = hoursTens;
timeArray[1] = hoursMinutes;
timeArray[2] = minutesTens;
timeArray[3] = minutesOnes;
} // end 1 second check
// or replace all that with reading the 4 variables from an RTC such as DS1307 using I2C commands

if (timeUpdate == 1){  // check the time update flag for 1 minute -> make noise!
timeUpdate = 0; // clear the flag
for (timeDigit = 0 ; timeDigit <4; timeDigit = timeDigit+1){ // cycle thru the digits
for (ditDa = 0b00010000; ditDa >0; ditDa >>1){  // masking bit
if ( (dotDash[timeArray[timeDigit]] & ditDa) > 0){ // play a dot if the bit is a  1 (one &? two &&?? I think just 1)
for (noise = 0; noise <100; noise = noise+1){ //  burst of tone for a dot- play with how long
digitalWrite (noisePin, HIGH);
delayMicroseconds (1132); // ~ Concert A
digitalWrite (noisePin, LOW);
delayMicroseconds (1132);
} // end dot
else { // play a burst of tone for a dash
for (noise = 0; noise <300; noise = noise+1){ //  burst of tone for a dot - 3x as long here, play with how long
digitalWrite (noisePin, HIGH);
delayMicroseconds (1132); // ~ Concert A
digitalWrite (noisePin, LOW);
delayMicroseconds (1132);
} // end dash
delay (innerDelay); // how fast the dots/dashes come out
} // end 5 bits of dot/dash
delay(digitDelay); // how fast the 4 digits come out
} // end 4 digits

// write code here for time setting, alarm setting, etc.

} // end loop
« Last Edit: August 19, 2013, 01:39:14 pm by CrossRoads » Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Full Member
***
Karma: 0
Posts: 228
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Given that you are generating these sequences on a timed basis there are two approaches you can take.

The blocking approach is to wait until it is time to send a sequence and then carry out a blocking sequence of beep/wait actions until the sequence is complete, then go back to waiting until it is time to send the next sequence. This approach means your sketch can only control one thing at a time and is a very limited approach, but it could be made to work. This would be using the delay() function that you mentioned in point (1) and say you want to get away from - IMO you're right to want to get away from it.

The non-blocking approach needs two activities to be performed on a timed basis. The first activity decides whether it is time to send out a morse code sequence. The second activity sends the timed beeps that comprise the requested sequence. The two activities need to communicate with each other. The way I'd implement this is with a circular buffer containing a queue of morse characters which need to be sent and haven't been sent yet. Your clock processing would just write morse characters to this queue. The sending function would use the timing logic demonstrated in the blink without delay example sketch to manage the sending of the sequence of beeps and gaps that constitute a given character, then pull the next morse character off the queue. It's up to you whether you want the queue to hold ascii characters or dot/dash/gap tokens. Having it hold dot/dash/gap tokens would simplify the sending code but means the queue would take up more space.

thanks a lot. this explanation is clear. I don't want the blocking approach, as later I would want to add a button to this and have it announce the time after pressed.

I can trigger the first activity using this, am I correct?
Code:
if(sec==60){
 sec=0;
 minu++;
}

and the communication between these 2 activities are time based?

I want to queue the number, ie 12:13  to 1213 instead of dot/dash, but how can I do that? and since first one number takes time, how can I set the time for the second number? and how can the program see that 1213 number and does the sequence? thank you for your time.
Logged

Offline Offline
Full Member
***
Karma: 0
Posts: 228
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thanks a lot, I will try to read and understand your codes.
 smiley-cry I don't think it works... I saw a lot of simple errors....

I would give it a try like this, using some arrays and making your own tone.
Have to declare all the variables, add setup, etc.
Sorry about the lack of indenting
Code:
byte timeArray [] = {0,0,0,0,};
byte dotdash [] = {0b00000000, 0b00010000, 0b00011000, 0b00011100, 0b00011110, 0b00011111, 0b00001111, 0b00000111, 0b00000011, 0b00000001,};
//http://en.wikipedia.org/wiki/Morse_code

void loop(){
currentTime = micros(); // capture the 'time'
if ( (currentTime – nextTime) >= oneSecond){ // one second gone by?
nextTime = nextTime + oneSecond; // update for next time check
minutesOnes = minutesOnes + 1;
timeUpdate = 1; // set flag to make some noise on 1 minute updates
if (minutesOnes == 10){ // rollover
minutesOnes = 0;
minutesTens = minutesTens +1;
if (minutesTens == 6){ // rollover
minutesTens = 0;
hoursOnes = hoursOnes + 1;
if (hoursOnes == 10){  // rollover
hoursOnes = 0;
hoursTens = hoursTens +1;
if ( (hoursTens == 2) && (hoursOnes== 4){ // rollover at 24:00 - or set to 1 & 2 for 12 hour
hoursTens = 0;
hoursOnes = 0;
} // hoursTens check
} // hoursOnes check
} // minutesTens check
} // minutesOnes check
timeArray[0] = hoursTens;
timeArray[1] = hoursMinutes;
timeArray[2] = minutesTens;
timeArray[3] = minutesOnes;
} // end 1 second check
// or replace all that with reading the 4 variables from an RTC such as DS1307 using I2C commands

if (timeUpdate == 1){  // check the time update flag for 1 minute -> make noise!
timeUpdate = 0; // clear the flag
for (timeDigit = 0 ; timeDigit <4; timeDigit = timeDigit+1){ // cycle thru the digits
for (ditDa = 0b00010000; ditDa >0; ditDa >>1){  // masking bit
if ( (dotDash[timeArray[timeDigit]] & ditDa) > 0){ // play a dot if the bit is a  1 (one &? two &&?? I think just 1)
for (noise = 0; noise <100; noise = noise+1){ //  burst of tone for a dot- play with how long
digitalWrite (noisePin, HIGH);
delayMicroseconds (1132); // ~ Concert A
digitalWrite (noisePin, LOW);
delayMicroseconds (1132);
} // end dot
else { // play a burst of tone for a dash
for (noise = 0; noise <300; noise = noise+1){ //  burst of tone for a dot - 3x as long here, play with how long
digitalWrite (noisePin, HIGH);
delayMicroseconds (1132); // ~ Concert A
digitalWrite (noisePin, LOW);
delayMicroseconds (1132);
} // end dash
delay (innerDelay); // how fast the dots/dashes come out
} // end 5 bits of dot/dash
delay(digitDelay); // how fast the 4 digits come out
} // end 4 digits

// write code here for time setting, alarm setting, etc.

} // end loop
« Last Edit: August 19, 2013, 01:49:04 pm by arduinomagbit » Logged

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 538
Posts: 27069
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, I am not somewhere where I can compile, and as noted the variable declarations and void setup() need to be written.
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Sr. Member
****
Karma: 9
Posts: 272
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've recently written a morse code generator.
It does use delay, but the delay is short enough that you could check a button in there somewhere too. Or convert it from using delay to something else.

And of course, instead of connecting an LED, connect a buzzer...

Code:
/*
 * The duration (in milliseconds) of one tick.
 * A tick can be a morse code "dot" or a pause.
 */
#define TICK_DURATION        200

/*
 * The basic morse elements "DOT" and "DASH".
 * These constants define how many ticks each are in length.
 */
#define DOT                  1
#define DASH                 3

/*
 * Parameters for the pulse() function.
 * Specify wheter to output a "mark" or a pause (gap).
 */
#define MARK                 0x08  /* Digital port 3 */
#define GAP                  0

/*
 * The default gap duration as measured in ticks.
 */
#define GAP_BETWEEN_MARKS    1
#define GAP_BETWEEN_LETTERS  2 // It's 3 - GAP_BETWEEN_MARKS
#define GAP_BETWEEN_WORDS    7

/*
 * Some pre-compiler magic to encode a morse
 * code character into a 2-byte unsigned integer.
 */
#define ENC1(n0)                     (n0)
#define ENC2(n0, n1)                 (n0 + (n1 << 2))
#define ENC3(n0, n1, n2)             (n0 + (n1 << 2) + (n2 << 4))
#define ENC4(n0, n1, n2, n3)         (n0 + (n1 << 2) + (n2 << 4) + (n3 << 6))
#define ENC5(n0, n1, n2, n3, n4)     (n0 + (n1 << 2) + (n2 << 4) + (n3 << 6) + (n4 << 8))

/*
 * The international morse code representatino of
 * the letters of the alphabet.
 */
PROGMEM const prog_uint16_t MORSE_ALPHA[] = {
    ENC2( DOT,  DASH ),                     /* A */
    ENC4( DASH, DOT,  DOT,  DOT ),          /* B */
    ENC4( DASH, DOT,  DASH, DOT ),          /* C */
    ENC3( DASH, DOT,  DOT ),                /* D */
    ENC1( DOT ),                            /* E */
    ENC4( DOT,  DOT,  DASH, DOT ),          /* F */
    ENC3( DASH, DASH, DOT ),                /* G */
    ENC4( DOT,  DOT,  DOT,  DOT ),          /* H */
    ENC2( DOT,  DOT ),                      /* I */
    ENC4( DOT,  DASH, DASH, DASH ),         /* J */
    ENC3( DASH, DOT,  DASH ),               /* K */
    ENC4( DOT,  DASH, DOT,  DOT ),          /* L */
    ENC2( DASH, DASH ),                     /* M */
    ENC2( DASH, DOT ),                      /* N */
    ENC3( DASH, DASH, DASH ),               /* O */
    ENC4( DOT,  DASH, DASH, DOT ),          /* P */
    ENC4( DASH, DASH, DOT,  DASH ),         /* Q */
    ENC3( DOT,  DASH, DOT ),                /* R */
    ENC3( DOT,  DOT,  DOT ),                /* S */
    ENC1( DASH ),                           /* T */
    ENC3( DOT,  DOT,  DASH ),               /* U */
    ENC4( DOT,  DOT,  DOT,  DASH ),         /* V */
    ENC3( DOT,  DASH, DASH ),               /* W */
    ENC4( DASH, DOT,  DOT,  DASH ),         /* X */
    ENC4( DASH, DOT,  DASH, DASH ),         /* Y */
    ENC4( DASH, DASH, DOT,  DOT )           /* Z */
};

/*
 * Same thing, but digits this time...
 */
PROGMEM const prog_uint16_t MORSE_NUM[] = {
    ENC5( DASH, DASH, DASH, DASH, DASH ),   /* 0 */
    ENC5( DOT,  DASH, DASH, DASH, DASH ),   /* 1 */
    ENC5( DOT,  DOT,  DASH, DASH, DASH ),   /* 2 */
    ENC5( DOT,  DOT,  DOT,  DASH, DASH ),   /* 3 */
    ENC5( DOT,  DOT,  DOT,  DOT,  DASH ),   /* 4 */
    ENC5( DOT,  DOT,  DOT,  DOT,  DOT ),    /* 5 */
    ENC5( DASH, DOT,  DOT,  DOT,  DOT ),    /* 6 */
    ENC5( DASH, DASH, DOT,  DOT,  DOT ),    /* 7 */
    ENC5( DASH, DASH, DASH, DOT,  DOT ),    /* 8 */
    ENC5( DASH, DASH, DASH, DASH, DOT )     /* 9 */
};

/*
 * Outputs either a MARK or GAP for the given number of ticks.
 */
static void pulse(char ticks, const char mark)
{
    PORTD = mark;
    while (ticks-- > 0)
        delay(TICK_DURATION);
    PORTD = 0;
}

/*
 * Outputs a morse code sequence, including any required
 * gaps between marks.
 */
static void pulseChar(prog_uint16_t seq)
{
    while ((seq & DASH) != 0)
    {
        pulse((seq & DASH), MARK);
        pulse(GAP_BETWEEN_MARKS, GAP);
        seq >>= 2;
    }
}

/*
 * Converts a message to morse code and sends the resulting pulses.
 */
static void morseMessage(const char* ch)
{
    /* Iterate over all characters in the message and convert letters to upper-case */
    while (*ch)
    {
        if (*ch >= 'A' && *ch <= 'Z')
            pulseChar(pgm_read_word(&MORSE_ALPHA[*ch - 'A']));

        else if (*ch >= '0' && *ch <= '9')
            pulseChar(pgm_read_word(&MORSE_ALPHA[*ch - '0']));

        if (*ch++ == ' ')
            pulse(GAP_BETWEEN_WORDS, GAP);
        else
            pulse(GAP_BETWEEN_LETTERS, GAP);
    }
}

void setup()
{
    /* Direct port access, setting the port associcated with "MARK" to OUTPUT */
    DDRD = MARK;
}

void loop()
{
    morseMessage("SOS 123\0"); /* !!! WARNING: LETTERS MUST BE CAPITALIZED !!! */
    delay(5000);
}
Logged

Global Moderator
Boston area, metrowest
Online Online
Brattain Member
*****
Karma: 538
Posts: 27069
Author of "Arduino for Teens". Available for Design & Build services. Now with Unlimited Eagle board sizes!
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, this is working.
Take out the serial prints, watch the LED on 13, replace with a speaker and adjust the tone frequency, burst, length, time between dots & dashes, and time between digits as needed.
Code:
byte timeArray [] = {
  0,0,0,0,};
byte dotDash [] = {
  0b00000000, 0b00010000, 0b00011000, 0b00011100, 0b00011110, 0b00011111, 0b00001111, 0b00000111, 0b00000011, 0b00000001,};
//http://en.wikipedia.org/wiki/Morse_code

unsigned long currentTime = 0;
unsigned long nextTime = 0;
unsigned long elapsed = 0;
unsigned long oneSecond = 1000000UL;  // sped up for testing
byte seconds;
byte minutesOnes;
byte minutesTens;
byte hoursOnes;
byte hoursTens;
byte timeUpdate;
byte timeDigit;
byte ditDa;
byte noise;
byte noisePin = 13;
int innerDelay = 50;
int digitDelay = 100;
byte maskBit;

void setup(){
  Serial.begin (115200);
  pinMode (noisePin, OUTPUT);
}
void loop(){
  currentTime = micros(); // capture the time
  elapsed = currentTime - nextTime;
  if ( elapsed >= oneSecond ){ // one second gone by?
    nextTime = nextTime + oneSecond; // update for next time check
    seconds = seconds +1; //
    if (seconds == 60){
      seconds = 0;
      minutesOnes = minutesOnes + 1;
      timeUpdate = 1; // set flag to make some noise on 1 minute updates
      if (minutesOnes == 10){ // rollover
        minutesOnes = 0;
        minutesTens = minutesTens +1;
        if (minutesTens == 6){ // rollover
          minutesTens = 0;
          hoursOnes = hoursOnes + 1;
          if (hoursOnes == 10){  // rollover
            hoursOnes = 0;
            hoursTens = hoursTens +1;
            if ( (hoursTens == 2) && (hoursOnes== 4)){ // rollover at 24:00 - or set to 1 & 2 for 12 hour
              hoursTens = 0;
              hoursOnes = 0;
            } // hoursTens check
          } // hoursOnes check
        } // minutesTens check
      } // minutesOnes check
      timeArray[0] = hoursTens;
      timeArray[1] = hoursOnes;
      timeArray[2] = minutesTens;
      timeArray[3] = minutesOnes;

    }
    Serial.print (".");
    if ((seconds == 0) || (seconds == 30) ){
      Serial.print ("Time ");
      Serial.print (timeArray[0]);
      Serial.print (" ");
      Serial.print (timeArray[1]);
      Serial.print (" : ");
      Serial.print (timeArray[2]);
      Serial.print (" ");
      Serial.print (timeArray[3]);
      Serial.print (" : ");
      Serial.println (seconds);
      //Serial.print (" time update flag ");
      //Serial.println (timeUpdate);
    }

  } // end 1 second check
  // or replace all that with reading the 4 variables from an RTC such as DS1307 using I2C commands

    if (timeUpdate == 1){  // check the time update flag for 1 minute -> make noise!
    timeUpdate = 0; // clear the flag
    for (timeDigit = 0 ; timeDigit <4; timeDigit = timeDigit+1){ // cycle thru the digits
      for (ditDa = 0b00010000; ditDa >0; ditDa = ditDa >> 1){  // masking bit
        //Serial.print ("ditDa ");
        //Serial.print (ditDa, BIN);
        //Serial.print (" maskBit ");
        maskBit = dotDash[timeArray[timeDigit]] & ditDa;
        //Serial.println (maskBit, BIN);

        if (maskBit == 0){
          // play a burst of tone for a dash
          Serial.print ("dash ");
          for (noise = 0; noise <30; noise = noise+1){ //  burst of tone for a dot - 3x as long here, play with how long
            digitalWrite (noisePin, HIGH);
            delayMicroseconds (1132); // ~ Concert A
            digitalWrite (noisePin, LOW);
            delayMicroseconds (1132);
          } // end inner dash
        }

        else {
          // play a dot if the bit is a 1
          Serial.print ("dot ");
          for (noise = 0; noise <10; noise = noise+1){ //  burst of tone for a dot- play with how long
            digitalWrite (noisePin, HIGH);
            delayMicroseconds (1132); // ~ Concert A
            digitalWrite (noisePin, LOW);
            delayMicroseconds (1132);
          } // end inner dot
        }
        // end dot
        // Serial.println ("inner ");
        delay (innerDelay); // how fast the dots/dashes come out
      }
      //Serial.println ("digit ");
      Serial.println(" ");
      delay(digitDelay); // how fast the 4 digits come out
    } // end 5 bits of dot/dash

  } // end 4 digits
  // write code here for time setting, alarm setting, etc.

} // end loop
Logged

Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

Offline Offline
Full Member
***
Karma: 0
Posts: 228
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, this is working.
Take out the serial prints, watch the LED on 13, replace with a speaker and adjust the tone frequency, burst, length, time between dots & dashes, and time between digits as needed.
Code:
byte timeArray [] = {
  0,0,0,0,};
byte dotDash [] = {
  0b00000000, 0b00010000, 0b00011000, 0b00011100, 0b00011110, 0b00011111, 0b00001111, 0b00000111, 0b00000011, 0b00000001,};
//http://en.wikipedia.org/wiki/Morse_code

unsigned long currentTime = 0;
unsigned long nextTime = 0;
unsigned long elapsed = 0;
unsigned long oneSecond = 1000000UL;  // sped up for testing
byte seconds;
byte minutesOnes;
byte minutesTens;
byte hoursOnes;
byte hoursTens;
byte timeUpdate;
byte timeDigit;
byte ditDa;
byte noise;
byte noisePin = 13;
int innerDelay = 50;
int digitDelay = 100;
byte maskBit;

void setup(){
  Serial.begin (115200);
  pinMode (noisePin, OUTPUT);
}
void loop(){
  currentTime = micros(); // capture the time
  elapsed = currentTime - nextTime;
  if ( elapsed >= oneSecond ){ // one second gone by?
    nextTime = nextTime + oneSecond; // update for next time check
    seconds = seconds +1; //
    if (seconds == 60){
      seconds = 0;
      minutesOnes = minutesOnes + 1;
      timeUpdate = 1; // set flag to make some noise on 1 minute updates
      if (minutesOnes == 10){ // rollover
        minutesOnes = 0;
        minutesTens = minutesTens +1;
        if (minutesTens == 6){ // rollover
          minutesTens = 0;
          hoursOnes = hoursOnes + 1;
          if (hoursOnes == 10){  // rollover
            hoursOnes = 0;
            hoursTens = hoursTens +1;
            if ( (hoursTens == 2) && (hoursOnes== 4)){ // rollover at 24:00 - or set to 1 & 2 for 12 hour
              hoursTens = 0;
              hoursOnes = 0;
            } // hoursTens check
          } // hoursOnes check
        } // minutesTens check
      } // minutesOnes check
      timeArray[0] = hoursTens;
      timeArray[1] = hoursOnes;
      timeArray[2] = minutesTens;
      timeArray[3] = minutesOnes;

    }
    Serial.print (".");
    if ((seconds == 0) || (seconds == 30) ){
      Serial.print ("Time ");
      Serial.print (timeArray[0]);
      Serial.print (" ");
      Serial.print (timeArray[1]);
      Serial.print (" : ");
      Serial.print (timeArray[2]);
      Serial.print (" ");
      Serial.print (timeArray[3]);
      Serial.print (" : ");
      Serial.println (seconds);
      //Serial.print (" time update flag ");
      //Serial.println (timeUpdate);
    }

  } // end 1 second check
  // or replace all that with reading the 4 variables from an RTC such as DS1307 using I2C commands

    if (timeUpdate == 1){  // check the time update flag for 1 minute -> make noise!
    timeUpdate = 0; // clear the flag
    for (timeDigit = 0 ; timeDigit <4; timeDigit = timeDigit+1){ // cycle thru the digits
      for (ditDa = 0b00010000; ditDa >0; ditDa = ditDa >> 1){  // masking bit
        //Serial.print ("ditDa ");
        //Serial.print (ditDa, BIN);
        //Serial.print (" maskBit ");
        maskBit = dotDash[timeArray[timeDigit]] & ditDa;
        //Serial.println (maskBit, BIN);

        if (maskBit == 0){
          // play a burst of tone for a dash
          Serial.print ("dash ");
          for (noise = 0; noise <30; noise = noise+1){ //  burst of tone for a dot - 3x as long here, play with how long
            digitalWrite (noisePin, HIGH);
            delayMicroseconds (1132); // ~ Concert A
            digitalWrite (noisePin, LOW);
            delayMicroseconds (1132);
          } // end inner dash
        }

        else {
          // play a dot if the bit is a 1
          Serial.print ("dot ");
          for (noise = 0; noise <10; noise = noise+1){ //  burst of tone for a dot- play with how long
            digitalWrite (noisePin, HIGH);
            delayMicroseconds (1132); // ~ Concert A
            digitalWrite (noisePin, LOW);
            delayMicroseconds (1132);
          } // end inner dot
        }
        // end dot
        // Serial.println ("inner ");
        delay (innerDelay); // how fast the dots/dashes come out
      }
      //Serial.println ("digit ");
      Serial.println(" ");
      delay(digitDelay); // how fast the 4 digits come out
    } // end 5 bits of dot/dash

  } // end 4 digits
  // write code here for time setting, alarm setting, etc.

} // end loop


It works. thank you a lot. I thought it won't work because you use delay here. won't this block the system?
Logged

Pages: [1] 2   Go Up
Jump to: