A list of integer arrays

I have the following:

int S={0,0,0};
int O={1,1,1};

I now want a variable that can hold a list of letters so as to make up a sentence. Something like

Message={S,O,S};

Is this possible and if so what type do I use?

Are you planning some kind of morse code generator?

Your Message array can be an array of pointers but to save memory make the letter arrays bytes not ints.
Try this

const byte S[] = {0, 0, 0};
const byte O[] = {1, 1, 1};
const byte * message[] = {S, O};

void setup()
{
  Serial.begin(115200);
  for (int letter = 0; letter < 2; letter++)
  {
    Serial.print("<");
    for (int aByte = 0; aByte < 3; aByte++)
    {
      Serial.print(message[letter][aByte]);
    }
    Serial.println(">");
  }
}

void loop()
{
}

Note that the example depends on each letter array having the same number of elements.

Many thanks. Just for interest here is the complete programme

//Morse code program.
//Timing periods taken from https://en.wikipedia.org/wiki/Morse_code


#define laser 4
#define sound 13

#define silence 7

const byte S[]={1,1,1};                                   //1 == one time unit i.e. dot
const byte O[]={3,3,3};                                   //3 == three time unit i.e. dash

const byte * message[] = {S, O, S };                      //Array of pointers: Thanks to UKHeliBob for his help here

const int timeUnit=200;

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(laser, OUTPUT);     
  pinMode(sound,OUTPUT);
  pinMode(silence, INPUT_PULLUP);
}

void morse(int duration) {
  digitalWrite(laser,HIGH);                               //Switches on ky-008 laser
  if (digitalRead(silence)==LOW) digitalWrite(sound,LOW); //Checks to see if pin 7 is shorted out and if so sounds active buzzer
  delay(timeUnit*duration);                               //displays/sounds morse signal for a full time unit
  digitalWrite(laser,LOW);  
  digitalWrite(sound,HIGH);
}

void sendLetter(const byte l[]) {                         //Transmts a letter
  for (int i=0; i <= sizeof(l); i++){
    morse(l[i]);
    delay(timeUnit);
  }
}

void sendMessage(const byte * m[]){                      //Transmits a sentance
  for (int i=0; i <= sizeof(m); i++){
    sendLetter(m[i]);
    delay(timeUnit*3);
  }
}

void loop() {
  sendMessage(message); 
  delay(timeUnit*(7));
}

  sendMessage(message);As message is a global variable you do not need to pass it to the function. You can just use it in the function.

I see that you are using delay() in the program. This may cause problems in the future if/when you expand the program. Consider changing to using millis() to manage timing as it will not block the execution of other code.

Do you intend to expand the program to generate other messages ?

A more complete morse example in that it covers ‘sending’ alpha and numeric in messages.

The encoding table is fairly compact as each entry is encoded within a single byte.

The routine ‘signal_element’ must be completed for your type of signaling device.

#include <Arduino.h>

// structure consisting of two bitfields within a single byte
struct morse_encoding_t
{
    // ENCODE MORSE ELEMENT COUNT AND ELEMENT TYPES
    // WITHIN SINGLE UNSIGNED BYTE
    // 3 BITS FOR ELEMENT COUNT
    // 5 BITS FOR ARRAY OF MORSE ELEMENTS ENCODED AS SINGLE BITS IN MSB -> LSB ORDER
    //      0 = DIT, 1 = DAH

    uint8_t count: 3;
    uint8_t elements: 5;
};

struct morse_encoding_t char2encoding(char ch)
{
    const morse_encoding_t em_alpha[] =
    {
          { 2, 0b01    }  // A  .-
        , { 4, 0b1000  }  // B  -...
        , { 4, 0b1010  }  // C  -.-.
        , { 3, 0b100   }  // D  -..
        , { 1, 0b0     }  // E  .
        , { 4, 0b0010  }  // F  ..-.
        , { 3, 0b110   }  // G  --.
        , { 4, 0b0000  }  // H  ....
        , { 2, 0b00    }  // I  ..
        , { 4, 0b0111  }  // J  .---
        , { 3, 0b101   }  // K  -.-
        , { 4, 0b0100  }  // L  .-..
        , { 2, 0b11    }  // M  --
        , { 2, 0b10    }  // N  -.
        , { 3, 0b111   }  // O  ---
        , { 4, 0b0110  }  // P  .--.
        , { 4, 0b1101  }  // Q  --.-
        , { 3, 0b010   }  // R  .-.
        , { 3, 0b000   }  // S  ...
        , { 1, 0b1     }  // T  -
        , { 3, 0b001   }  // U  ..-
        , { 4, 0b0001  }  // V  ...-
        , { 3, 0b011   }  // W  .--
        , { 4, 0b1001  }  // X  -..-
        , { 4, 0b1011  }  // Y  -.--
        , { 4, 0b1100  }  // Z  --..
    };
    
    const morse_encoding_t em_numeric[] =
    {
        // --- NUMERIC
          { 5, 0b11111 }  // 0  -----
        , { 5, 0b01111 }  // 1  .----
        , { 5, 0b00111 }  // 2  ..---
        , { 5, 0b00011 }  // 3  ...--
        , { 5, 0b00001 }  // 4  ....-
        , { 5, 0b00000 }  // 5  .....
        , { 5, 0b10000 }  // 6  -....
        , { 5, 0b11000 }  // 7  --...
        , { 5, 0b11100 }  // 8  ---..
        , { 5, 0b11110 }  // 9  ----.
    };

    switch ( ch )
    {
        case 'a' ... 'z': return em_alpha[ch - 'a'];
        case 'A' ... 'Z': return em_alpha[ch - 'A'];
        case '0' ... '9': return em_numeric[ch - '0'];
        case '/':         return { 5, 0b10010 };
    }

    return { 0, 0 };
}

enum { DIT = 1, DAH = 3, INTRA_CHAR_GAP = 1, CHAR_GAP = 3, WORD_GAP = 7 };

/* Calculating Morse Code Speed
 *
 * The word PARIS is the standard for determing CW code speed. Each DOT is one
 * 'dtUNIT', each DASH is three T-UNITS, intra-character spacing is one 'dtUNIT',
 * inter-character spacing is three T-UNITS and inter-word spacing is seven
 * T-UNITS. The word PARIS is exactly 50 T-UNITS.
 *
 * Note that after each DOT/DASH of the letter P -- one 'dtUNIT' spacing is used
 * except the last one. (Intra-Character).
 *
 * After the last DOT of P is sent, 3 T-UNITS are added (Inter-Character).
 *
 * After the word PARIS - 7 T-UNITS are used.
 *
 * Calculateed as:
 *
 *    P = DOT DASH DASH DOT = 1 1 3 1 3 1 1 (3) = 14 'dtUNITS'
 *    A = DOT DASH      = 1 1 3     (3) =  8 'dtUNITS'
 *    R = DOT DASH DOT    = 1 1 3 1 1   (3) = 10 'dtUNITS'
 *    I = DOT DOT     = 1 1 1     (3) =  6 'dtUNITS'
 *    S = DOT DOT DOT   = 1 1 1 1 1   [7] = 12 'dtUNITS'
 *    --------------------------------------------------------
 *                        = 50 'dtUNITS'
 *
 * () = intercharacter
 * [] = interword
 *
 * If you send PARIS 5 times in a minute (5 WPM) you have sent 250 'dtUNITS'
 * (using correct spacing).
 *
 * 250 'dtUNITS' into 60 seconds per minute = 240 milliseconds per 'dtUNIT'.
 */

const unsigned long     WORDS_PER_MINUTE    = 20;
const unsigned long     UNITS_PER_WORD      = 50;

const unsigned long     tmsSECOND           = 1000UL;
const unsigned long     tmsMINUTE           = 60 * tmsSECOND;
const unsigned long     tmsWPM_SCALER       = tmsMINUTE / (WORDS_PER_MINUTE * UNITS_PER_WORD);

void signal_spacing(unsigned long length)
{
    delay(length * tmsWPM_SCALER);
}

void signal_element(char const signal)
{
    switch ( signal )
    {
        case '.':
          // TURN ON SIGNAL GENERATOR HERE
          // AN LED, BUZZER, TONE-GENERATOR OR WHATEVER

          delay(DIT * tmsWPM_SCALER);

          // TURN OFF SIGNAL GENERATOR HERE
          break;

        case '-':
          // TURN ON SIGNAL GENERATOR HERE
          // AN LED, BUZZER, TONE-GENERATOR OR WHATEVER

          delay(DAH * tmsWPM_SCALER);

          // TURN OFF SIGNAL GENERATOR HERE
          break;

        default:
          // TURN OFF SIGNAL GENERATOR HERE
          break;
    }
}

void signal(struct morse_encoding_t const encoding)
{
    for ( size_t mask = (1 << encoding.count); mask >>= 1; )
    {
        signal_element((encoding.elements & mask) ? '-' : '.');
        if ( 1 != mask )
        {
            signal_spacing(INTRA_CHAR_GAP);
        }
    }
}

void morse(const char* psz)
{
    if ( *psz )
    {
        do
        {
            const morse_encoding_t encoding = char2encoding(*psz++);
            if ( ! encoding.count )
            {
                continue;
            }

            signal(encoding);
            signal_spacing((' ' == *psz) ? WORD_GAP : CHAR_GAP);

        } while ( *psz );
    }
}

void morse(char const ch)
{
    const morse_encoding_t encoding = char2encoding(ch);
    if ( encoding.count )
    {
        signal(encoding);
    }
}

void loop()
{   }

void setup()
{
    morse("THE QUICK BROWN FOX JUMPED OVER THE LAZY DOGS BACK");
}

UKHeliBob:
Do you intend to expand the program to generate other messages ?

Thanks for all the input. I am simply playing with it as an idea for a lesson to some students. But while doing so the idea grew.. not sure where it was going :slight_smile:

I am not sure what you mean by using millis to control timing. Surely I will still need to use delay at some point?

This said, lloyddean seems to have done if for me :slight_smile:

Thanks for all your advice :slight_smile:

abasel:
I am not sure what you mean by using millis to control timing. Surely I will still need to use delay at some point?

Have a look at the Blink Without Delay example in the IDE for an example of non-blocking timing using millis().

No, you should never need a delay ever. Sometimes we use them when we honestly don’t have anything else for the board to do or the time is so short we can live with the code stopping and the board being blind deaf and dumb. But it’s never a must.