How to access one array - from an array of arrays(!) as a whole ?

Am trying to optimise some code for a "programmable IR remote".

It is probably quite inefficient in it's usage of variables for the 'mark and space' sequences (pulse trains) but for now, i'm interested in the basic theory of manipulating multi-dimensional arrays.

I had previously been using a global variable for each 'button sequence' and then calling them in a function repeatedly for each button - this ended up eating up a lot of memory.

So; i am now trying to localise the variables to save memory space.

PRESENT setup:

const int remoteONE[] = {4200, 500, 1200, 3400, 200};
const int remoteTWO[] = {4200, 1500, 200, 3400, 300};
const int remoteTHREE[] = {4200, 500, 1200, 1400, 200};
const int remoteFOUR[] = {4200, 500, 1200, 3400, 1200};

and then called by;
(for a particular sequence)

sendCode(remoteTHREE);
sendCode(remoteONE);
sendCode(remoteTWO);
sendCode(remoteONE);

my idea is to place the remoteXXX variables into ONE array within the sendCode() function which can then be called by a parameter of its index;

IMPROVED (in my mind) setup:

void sendCode(int idx) {
const int remoteALLNUM[4][5] = {(4200, 500, 1200, 3400, 200),
                                          (4200, 1500, 200, 3400, 300),
                                          (4200, 500, 1200, 1400, 200),
                                          (4200, 500, 1200, 3400, 1200)};


code2send=remoteALLNUM[idx]; // or something of this sort - obviously this is wrong.

}

the issue is; if i declare as remoteALLNUM[4][5] = {.... etc....
then i can call x = remoteALLNUM[2][1]
but this only gives a single int, whereas i want the whole array.

if i don't initialize the array explicitly and just use; remoteALLNUM[] = {.... etc....
calling x = remoteALLNUM[2] gives only the last member - same problem.

how should i be using this array setup ?

i'm sure the whole variable usage and code structure for the Remote Program could be much better, but for now - am just concentrating on the array manipulation.

Thanks.

Seems your data is always multiple of 100 so you could halve the memory by using bytes and doing the x100 when you send the data only

A 2D array will just layout the data in sequential bytes as you typed it in. The challenge when you pass a 2D array is that you don’t know the width and length of the array and so don’t kow how far in memory you need to go for the second row for exemple (imagine you know you have 12 elements in memory, is it a 4x3, a 3x4, à 6x2 or a 2x6 array?) —> passing size information to your function will let you know how deep in the array you need to go for accessing next rows

J-M-L:
Seems your data is always multiple of 100 so you could halve the memory by using bytes and doing the x100 when you send the data only

hmm, good point - i could definitely implement that.
Thanks !

Delta_G:
The secret is pointers.

...

yes, that seems to be a key to understanding arrays properly.
i don't think i'm fully there yet.

anyway, i tried your method but am getting an error;
" invalid conversion from 'const int*' to 'int* [-fpermissive] "

here's the actual code i ran;

const int remoteALLNUM[6][78] = {(1, 4300, 4600, 350, 600, 400, 600, 400, 600, 400, 600, 350, 600, 400, 1600, 400, 600, 400, 550, 400, 600, 400, 600, 400, 600, 350, 650, 350, 600, 400, 600, 400, 600, 350, 600, 400, 4550, 400, 1600, 350, 600, 400, 600, 400, 600, 400, 1550, 400, 600, 400, 600, 350, 650, 400, 600, 350, 600, 400, 600, 400, 600, 400, 600, 350, 1600, 400, 1600, 350, 1600, 400, 1600, 400, 1550, 400, 1600, 350, 1600, 400),
                         (2, 4300, 4550, 400, 600, 400, 600, 400, 600, 400, 550, 400, 600, 400, 1600, 400, 600, 350, 600, 400, 600, 400, 600, 400, 600, 350, 600, 400, 600, 350, 650, 400, 600, 350, 600, 400, 4550, 400, 1550, 400, 600, 400, 600, 350, 650, 400, 600, 350, 1600, 400, 600, 400, 600, 350, 600, 400, 600, 350, 650, 350, 650, 350, 1600, 400, 600, 400, 1550, 400, 1600, 400, 1550, 400, 1600, 400, 1600, 350, 1600, 400),
                         (3, 4300, 4600, 350, 650, 300, 650, 350, 650, 350, 650, 350, 650, 300, 1650, 350, 650, 350, 650, 300, 650, 350, 650, 350, 650, 350, 650, 300, 650, 350, 650, 350, 650, 350, 650, 350, 4550, 350, 1650, 350, 650, 300, 650, 350, 650, 350, 1650, 300, 650, 350, 650, 350, 1650, 300, 700, 300, 650, 350, 650, 350, 650, 350, 650, 300, 1650, 350, 1650, 300, 650, 350, 1650, 350, 1600, 350, 1650, 350, 1600, 350),
                         (4, 4250, 4600, 350, 650, 300, 650, 400, 600, 350, 650, 350, 650, 300, 1650, 400, 600, 350, 650, 350, 650, 300, 650, 350, 650, 350, 650, 350, 650, 300, 650, 350, 650, 350, 650, 350, 4550, 400, 1600, 350, 650, 300, 650, 350, 650, 350, 650, 350, 650, 350, 1600, 400, 600, 350, 650, 350, 650, 300, 650, 350, 650, 350, 1650, 300, 1650, 350, 650, 350, 1600, 400, 1600, 350, 1600, 400, 1600, 350, 1650, 350),
                         (5, 4350, 4550, 400, 600, 350, 600, 400, 600, 450, 550, 400, 600, 400, 1550, 450, 550, 450, 550, 400, 600, 350, 600, 450, 550, 450, 550, 400, 600, 400, 550, 400, 600, 450, 550, 450, 4500, 400, 1550, 450, 550, 400, 600, 400, 600, 350, 600, 450, 550, 450, 550, 400, 600, 400, 550, 400, 600, 400, 600, 400, 600, 400, 1550, 400, 1600, 400, 1550, 400, 1600, 450, 1550, 350, 1600, 450, 1550, 400, 1550, 400),
                         (6, 4350, 4550, 400, 600, 400, 550, 400, 600, 450, 550, 400, 600, 400, 1550, 450, 550, 450, 550, 400, 600, 350, 600, 450, 550, 450, 550, 400, 600, 400, 600, 350, 600, 450, 550, 450, 4500, 400, 1550, 400, 600, 450, 550, 400, 600, 400, 1550, 450, 550, 400, 1550, 400, 600, 450, 550, 400, 600, 400, 600, 400, 550, 450, 550, 450, 1550, 400, 550, 450, 1550, 450, 1550, 350, 1600, 450, 1550, 400, 1550, 400)
                        };


void setup() {

Serial.begin(9600);

int * code2send = remoteALLNUM[3];

Serial.println(code2send);

}

void loop() {
  // put your main code here, to run repeatedly:

}

have i done something wrong in the implementation ?

Here is some explanation:

Assume you want to represent this array in code
concept.png

this would be the code definition for it
arrayCode.png

and the data would be organized like this (on a UNO)

if you run this small code

const byte a2DArray[][5] = {
  {1, 2, 3, 4, 5},
  {6, 7, 8, 9, 10},
  {11, 12, 13, 14, 15},
};

const int numberOfRows = sizeof(a2DArray) / sizeof(a2DArray[0]);
const int numberOfCols = sizeof(a2DArray[0]) / sizeof(a2DArray[0][0]);


void setup() {
  Serial.begin(115200);
  Serial.print(F("The array has "));  Serial.print(numberOfRows);  Serial.println(F(" rows."));
  Serial.print(F("The array has "));  Serial.print(numberOfCols);  Serial.println(F(" Columns."));

  Serial.print(F("The array starts in memory at address 0x"));  Serial.println((uint16_t) (a2DArray), HEX);
  Serial.print(F("a2DArray[0] starts in memory at address 0x"));  Serial.println((uint16_t) (a2DArray[0]), HEX);
  Serial.print(F("a2DArray[1] starts in memory at address 0x"));  Serial.println((uint16_t) (a2DArray[1]), HEX);
  Serial.print(F("a2DArray[2] starts in memory at address 0x"));  Serial.println((uint16_t) (a2DArray[2]), HEX);
}

void loop() {}

you will see in the console indeed

[sub][color=purple]The array has 3 rows.
The array has 5 Columns.
The array starts in memory at address 0x112
a2DArray[0] starts in memory at address 0x112
a2DArray[1] starts in memory at address 0x117
a2DArray[2] starts in memory at address 0x11C
[/color][/sub]

So consider this code, it should help

const byte a2DArray[][5] = {
  {1, 2, 3, 4, 5},
  {6, 7, 8, 9, 10},
  {11, 12, 13, 14, 15},
  {16, 17, 18, 19, 20},
};

const int numberOfRows = sizeof(a2DArray) / sizeof(a2DArray[0]);

void printSubArray(const byte a1DArray[], int nbCols)
{
  for (int i = 0; i < nbCols; i++) {
    Serial.print(a1DArray[i]);
    if (i != nbCols - 1) Serial.print(F(" , "));
  }
}

void print2DArray(const byte a1DArray[][5], int nbRows)
{
  for (int i = 0; i < nbRows; i++) {
    printSubArray(a1DArray[i], 5);
    Serial.println();
  }
}


void setup() {
  Serial.begin(115200);
  Serial.print(F("The array has "));
  Serial.print(numberOfRows);
  Serial.println(F(" rows."));
  print2DArray(a2DArray, numberOfRows);
}

void loop() {}

the console will show

[sub][color=purple]
The array has 4 rows.
1 , 2 , 3 , 4 , 5
6 , 7 , 8 , 9 , 10
11 , 12 , 13 , 14 , 15
16 , 17 , 18 , 19 , 20
[/color][/sub]

so it works :slight_smile:

if you want to compute at compile time the number of columns in your array (so that you don't hardwire the 5 as I did) you could add at the beginning

const int numberOfCols = sizeof(a2DArray[0]) / sizeof(a2DArray[0][0]);

and use numberOfCols where I used 5.

the code would become

const byte a2DArray[][5] = {
  {1, 2, 3, 4, 5},
  {6, 7, 8, 9, 10},
  {11, 12, 13, 14, 15},
  {16, 17, 18, 19, 20},
};

const int numberOfRows = sizeof(a2DArray) / sizeof(a2DArray[0]);
const int numberOfCols = sizeof(a2DArray[0]) / sizeof(a2DArray[0][0]);


void printSubArray(const byte a1DArray[], int nbCols)
{
  for (int i = 0; i < nbCols; i++) {
    Serial.print(a1DArray[i]);
    if (i != nbCols - 1) Serial.print(F(" , "));
  }
}

void print2DArray(const byte a1DArray[][numberOfCols], int nbRows)
{
  for (int i = 0; i < nbRows; i++) {
    printSubArray(a1DArray[i], numberOfCols);
    Serial.println();
  }
}


void setup() {
  Serial.begin(115200);
  Serial.print(F("The array has "));  Serial.print(numberOfRows);  Serial.println(F(" rows."));
  Serial.print(F("The array has "));  Serial.print(numberOfCols);  Serial.println(F(" Columns."));
  print2DArray(a2DArray, numberOfRows);
}

void loop() {}

and the console would show

[sub][color=purple]The array has 4 rows.
The array has 5 Columns.
1 , 2 , 3 , 4 , 5
6 , 7 , 8 , 9 , 10
11 , 12 , 13 , 14 , 15
16 , 17 , 18 , 19 , 20
[/color][/sub]

Your array is not what you think it is:

const int remoteALLNUM[6][78] = {(1, ..., 400),
                         (2, ..., 400),
                         (3, ..., 350),
                         (4, ..., 350),
                         (5, ..., 400),
                         (6, ..., 400)
                        };

is equivalent to

const int remoteALLNUM[6][78] = {400, 400, 350, 350, 400, 400}; // rest filled with 0

Change (...) to {...}.

" invalid conversion from 'const int*' to 'int* [-fpermissive] "

Pay attention to the red word.

J-M-L:
Here is some explanation:

...

thanks for the tutorial - but i need to "call(?)" the (row) array in one variable, not individually.

oqibidipo:
Your array is not what you think it is:

const int remoteALLNUM[6][78] = {(1, ..., 400),

(2, ..., 400),
                        (3, ..., 350),
                        (4, ..., 350),
                        (5, ..., 400),
                        (6, ..., 400)
                        };



is equivalent to


const int remoteALLNUM[6][78] = {400, 400, 350, 350, 400, 400}; // rest filled with 0

i see, why is that though ?
the pointer for each row ends up only referencing to the last one - what/which syntax determines this ?

oqibidipo:
Change (...) to {...}.

i did - it still gave the same error.

oqibidipo:
Pay attention to the red word.

and what do i do with it ?

remove the const ?

i changed const int remoteALLNUM... to int remoteALLNUM... and now the error is " call of overloaded 'println(int*&) is ambiguous' "

Delta_G:
That's an issue on another line. If you want help understanding how a 2D array works then you've got it.

i see - okay, it's a matter of still fully grasping pointers then.
(the Arduino Reference page on pointers is rather sparse, i'll have to look elsewhere to try and get it under my belt.)

Delta_G:
...It looks like you tried to pass one of those int pointers directly to print,

yes, that was actually the whole code - i was just trying to keep it simple;

Delta_G:
but print doesn't take a pointer to int as an argument.

so i guess that's not possible.

Delta_G:
You have to dereference the pointer when you pass it to print. I can't show you what that looks like in your code because you aren't sharing your code.

so code2send is now a pointer, and to dereference it i'd use a '&' right ?

is it possible to manipulate that so that i can println it ?

i tried

Serial.println(&code2send);

but now the error is;
" cannot convert 'int*' to 'int**' in initialization "

what i need, is to understand the initialization syntax properly;

what is the difference between;

int remoteALLNUM[6][78] = {400.... ..... .....

and;

int remoteALLNUM[] = {400.... ..... .....

the latter won't throw any error, but of course it's not giving the data that i expect.

Delta_G:

Serial.println(&code2send);

You were so close...

ha - some would say i couldn't be further away - because it's the exact opposite ! :0)

Delta_G:
The & is the "address of". It is how you get a pointer to something. That's why it was complaining that you gave it a pointer to a pointer to int (int**).

This is what you want:

Serial.println(*code2send);

The * in front "de-references" the pointer and gets the thing pointed to.

ahh... these things take a while to sink in my brain !...

  • is the pointer !

ok - i think i'm getting there - so code2send is the pointer to the array, and Serial.println-ing it will only give the first member, but if i pass it to a function expecting an array, then the whole row will get read.

which is what you said in your original reply with "sendCodeOldWay".

back to the main code now and am expecting it should work.

Thanks !

when you define a variable in memory, say

int value = 1000;

then the compiler allocates (on a UNO) 2 bytes of memory (SRAM) to store the integer, and put in those 2 bytes the value (1000) you have defined.

SRAM Memory in your arduino is just a bunch of bytes next to each other, each having an address. every time you define a new global variable, the compiler would basically remember that this variable will be stored at a given location and remember that location as being "used" so that it does not allocate anything else there.

if you want to know where (the address) is the first byte in memory of your storage, this is when you use the & operator, this is the "address of" operator and you would obtain a pointer to an int type. Where it becomes possibly confusing is that the notion of "pointer to" for a type is denoted with a * sign
int * ptrToValue = &value; //ptrToValue is a pointer to an int, pointing at the first byte of the memory allocated for value and if you want to access the content (an int) that is "pointed" you also use the * operator (dereference operator). For example, if you want to copy to content in another variable you would do
int copyOfValue = * ptrToValue; . copyOfValue will be initialize with the content of the memory pointed by ptrToValue (basically duplicates the 2 bytes that are there into the memory allocated for copyOfValue)

you can read this to find out more (plenty of on line info)

J-M-L:
...
you can read this to find out more (plenty of on line info)

thanks for that further info - i will have a look at that link to help my comprehension on pointers.

BabyGeezer:
...
back to the main code now and am expecting it should work.

okay - the code itself worked, but the intended purpose did not.

i thought changing the variable from global to inside the function would reduce the memory usage, but it in fact increased - i must not have the variable scope understanding correct.

here is the full code;

/*
 * IRrecord: record and play back IR signals
 * Version 0.11 September, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */
// {only using playback section here)

#include <IRremote.h>
const byte RECV_PIN = 4;
const byte BUTTON_PIN = 17;
const byte STATUS_PIN = 13;
IRrecv irrecv(RECV_PIN);
IRsend irsend;
decode_results results;
byte lastButtonState;

/*
** Example Arduino sketch for SainSmart I2C LCD Screen 16x2
** by Edward Comer uses F Malpartida's NewLiquidCrystal library.
 */
#include <Wire.h>
// #include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x20 //
#define BACKLIGHT_PIN     7
// using MJKDZ board
#define En_pin  4
#define Rw_pin  5
#define Rs_pin  6
#define D4_pin  0
#define D5_pin  1
#define D6_pin  2
#define D7_pin  3
LiquidCrystal_I2C  lcd(I2C_ADDR, En_pin, Rw_pin, Rs_pin, D4_pin, D5_pin, D6_pin, D7_pin);

// pin assignment and variables for Rotary Encoder
const byte encoderBTN = 2;
const byte pinA = 12;  // Connected to CLK on KY-040
const byte pinB = 11;  // Connected to DT on KY-040
int encoderPosCount = 0;
byte pinALast;
byte aVal;
boolean bCW;

// pre-recorded raw codes for the remote being cloned
unsigned int HaierPOWER[] = {4350, 4500, 500, 650, 450, 650, 500, 600, 450, 1750, 500, 1700, 500, 650, 450, 650, 500, 650, 450, 650, 450, 650, 500, 650, 450, 1750, 450, 1750, 500, 650, 450, 650, 500, 600, 500, 1750, 450, 1750, 450, 650, 500, 1750, ...truncated to fit...

unsigned int HaierSOURCE[] = {4350, 4500, 500, 600, 500, 650, 500, 600, 500, 1700, 500, 1750, 400, 700, 500, 600, 500, 650, 500, 600, 500, 600, 500, 650, 450, 1750, ...truncated to fit...

unsigned int HaierCURSup[] = {4350, 4500, 500, 600, 500, 650, 450, 650, 500, 1700, 500, 1750, 450, 650, 500, 600, 500, 650, 500, 600, 500, 600, 500, 600, 500, 1750, ...truncated to fit...

unsigned int HaierCURSdn[] = {4350, 4500, 500, 600, 500, 600, 500, 650, 500, 1700, 500, 1700, 500, 650, 500, 600, 500, 650, 450, 650, 500, 600, 500, 600, 500, 1700, 550, 1700, 500, 600, 500, 650, 500, 600, 500, 600, 500, 1750, 500, 1700, 500, 600, ...truncated to fit...


char * menuList[] = {
  "Switch ALL off",
  "PowerDevicesON",
  "230",
  "252",
  "251",
  "250",
  "261",
  "232"
};
boolean CMDselected = false;
byte chosen = 2;

void setup()
{
  lcd.begin (16, 2);
  //Switch on the backlight
  lcd.setBacklightPin(BACKLIGHT_PIN, NEGATIVE);
  lcd.setBacklight(HIGH);
  lcd.home ();
  lcd.print("LCD connected");
  delay(1000);

  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(STATUS_PIN, OUTPUT);

  pinMode(encoderBTN, INPUT_PULLUP);
  pinMode (pinA, INPUT);
  pinMode (pinB, INPUT);
  /* Read Pin A
  Whatever state it's in will reflect the last position
  */
  pinALast = digitalRead(pinA);
}


void loop() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.write("=CUSTOM REMOTE=");
  if (CMDselected) {
    lcd.setCursor(0, 1);
    lcd.write("                ");
  } else {
    lcd.setCursor(0, 1);
    lcd.write("CLICK knob2begin");
  }
  // If rotary-encoder pressed, ENTER MENU routine.
  while (digitalRead(encoderBTN))  {  // while NOT - run original program

    // If button pressed, send the code.
    byte buttonState = !(digitalRead(BUTTON_PIN));
    if (lastButtonState == HIGH && buttonState == LOW) {
      Serial.println("\tReleased");
      irrecv.enableIRIn(); // Re-enable receiver
    }

    if (buttonState) {
      Serial.println("\tPressed, sending");
      lcd.setCursor(0, 1);
      lcd.write("Pressed, sending");
      digitalWrite(STATUS_PIN, HIGH);
      switch (chosen) {
        case 1:
          lcd.setCursor(0, 1);
          lcd.write("switching on ...");
          break;
        case 2:
          lcd.setCursor(0, 1);
          lcd.write("switching OFF...");
          break;
        case 3:
          lcd.setCursor(0, 1);
          lcd.write("changing to 230 ");
          sendSAMSUNG(2);
          sendSAMSUNG(3);
          sendSAMSUNG(0);
          break;
        case 4:
          lcd.setCursor(0, 1);
          lcd.write("changing to 252 ");
          break;
        case 5:
          lcd.setCursor(0, 1);
          lcd.write("changing to 251 ");
          break;
        case 6:
          lcd.setCursor(0, 1);
          lcd.write("changing to 250 ");
          break;
        case 7:
          lcd.setCursor(0, 1);
          lcd.write("changing to 261 ");
          break;
        default:  // ORIGINAL function - NOT menuSelected
          ;
      }
      // chosen=0;  RESET channel-command to enable RECORD.version

      digitalWrite(STATUS_PIN, LOW);
      delay(50); // Wait a bit between retransmissions
    }

    lastButtonState = buttonState;
  }
  // OUTofWHiLE-loop
  lcd.setCursor(0, 1);
  lcd.write("encoder pressed");
  delay(1000);
  lcd.setCursor(14, 0);
  lcd.write("<=");
  lcd.setCursor(5, 1);
  lcd.write("           ");
  // LOCKinsideMENUroutineUNTILpressAGAIN
  while (digitalRead(encoderBTN))  {
    // FULL EXAMPLE CODE on using KY-040
    aVal = digitalRead(pinA);
    if (aVal != pinALast) { // Means the knob is rotating
      // Need to determine direction
      if (digitalRead(pinB) != aVal) {  // Means pin A Changed first -> Rotating Clockwise
        encoderPosCount ++;
        bCW = true;
      } else {// Otherwise B changed first -> moving CCW
        bCW = false;
        encoderPosCount--;
      }

      byte menuIdx = constrain(encoderPosCount, 0, 7);
      lcd.setCursor(0, 0);
      lcd.write(menuList[menuIdx]);
      lcd.setCursor(0, 1);
      lcd.write(menuList[(menuIdx + 1)]);
      chosen = menuIdx + 1; // not the 2nd1abv.BUT IndexFORswitchCase
    }
    pinALast = aVal;
  }
  lcd.setCursor(0, 0);
  lcd.write("command selected");
  lcd.setCursor(0, 1);
  lcd.write("pressBTN2execute");
  delay(1250);
  CMDselected = true;
}

void sendSAMSUNG(byte idx) {
  // SamsungNUMn[] - ALLcombinedNOW : inSEQ.0,1,2,3,6,5 : **NO'4'use'6'instead
  unsigned int SamsungNUMS[6][77] = {{4300, 4600, 350, 650, 300, 650, 350, 650, ...truncated to fit...
350, 1650, 350, 1600, 350},
    {4350, 4550, 400, 600, 400, 550, 400, 600, 450, 550, 400, 600, 400, 1550, 450, ...truncated to fit...
    {4250, 4600, 350, 650, 300, 650, 400, 600, 350, 650, 350, 650, 300, 1650, 400, ...truncated to fit...
  };
  //    Serial.println("Pressed, sending");
  digitalWrite(STATUS_PIN, HIGH);
  //   sendCode(lastButtonState == buttonState);  ORIG.code
  unsigned int * code2send = SamsungNUMS[idx];
  irsend.sendRaw(code2send, 77, 38);    // Haier length = 67  Samsung = 77
  //  Serial.println("Sent raw");
  digitalWrite(STATUS_PIN, LOW);
  delay(50);
}

and again, just highlighting the difference;

this is the "improved" version;

void loop() {

...

...

...

    if (buttonState) {
      Serial.println("\tPressed, sending");
      lcd.setCursor(0, 1);
      lcd.write("Pressed, sending");
      digitalWrite(STATUS_PIN, HIGH);
      switch (chosen) {
        case 1:
          lcd.setCursor(0, 1);
          lcd.write("switching on ...");
          // code pending
          break;
        case 2:
          lcd.setCursor(0, 1);
          lcd.write("switching OFF...");
          // code pending
          break;
        case 3:
          lcd.setCursor(0, 1);
          lcd.write("changing to 230 ");
          sendSAMSUNG(2);
          sendSAMSUNG(3);
          sendSAMSUNG(0);
          break;
        case 4:
          lcd.setCursor(0, 1);
          lcd.write("changing to 251 ");
          sendSAMSUNG(2);
          sendSAMSUNG(5);
          sendSAMSUNG(1);
          break;
        case 5:
          lcd.setCursor(0, 1);
          lcd.write("changing to 232 ");
          sendSAMSUNG(2);
          sendSAMSUNG(3);
          sendSAMSUNG(2);
          break;
...

...

...

}

void sendSAMSUNG(byte idx) {
  // SamsungNUMn[] - ALLcombinedNOW : inSEQ.0,1,2,3,6,5 : **NO'4'use'6'instead
  unsigned int SamsungNUMS[6][77] = {{4300, 4600, 350, 650, 300, 650, 350, 650, 350, 650, 350, 650, 300, 1650, 350, 650, 350, 650, 300, 650, 350, 650, 350, 650, ...truncated to fit...
350, 1650, 350, 1600, 350},
    {4350, 4550, 400, 600, 350, 600, 400, 600, 450, 550, 400, 600, 400, 1550, 450, ...truncated to fit...
400, 1550, 400, 1600, 450, 1550, 350, 1600, 450, 1550, 400, 1550, 400},
    {4300, 4600, 350, 600, 400, 600, 400, 600, 400, 600, 350, 600, 400, 1600, 400, 600, 400, 550, 400, 600, 400, 600, 400, 600, 350, 650, 350, 600, 400, 600, 400, 600, ...truncated to fit...
400, 1600, 350, 1600, 400, 1600, 400, 1550, 400, 1600, 350, 1600, 400},
    {4300, 4550, 400, 600, 400, 600, 400, 600, 400, 550, 400, 600, 400, 1600, 400, ...truncated to fit...
    {4350, 4550, 400, 600, 400, 550, 400, 600, 450, 550, 400, 600, 400, 1550, 450, ...truncated to fit...
    {4250, 4600, 350, 650, 300, 650, 400, 600, 350, 650, 350, 650, 300, 1650, 400, ...truncated to fit...
350, 650, 350, 1600, 400, 1600, 350, 1600, 400, 1600, 350, 1650, 350}
  };
  //    Serial.println("Pressed, sending");
  digitalWrite(STATUS_PIN, HIGH);
  //   sendCode(lastButtonState == buttonState);  ORIG.code
  unsigned int * code2send = SamsungNUMS[idx];
  irsend.sendRaw(code2send, 77, 38);    // Haier length = 67  Samsung = 77
  //  Serial.println("Sent raw");
  digitalWrite(STATUS_PIN, LOW);
  delay(50);
}

and this was how it was previously - the remote digits code as a global variable;

  unsigned int SamsungNUM2[] = {4300, 4600, 350, 650, 300, 650, 350, 650, 350, 650, 350, 650, 300, 1650, 350, 650, 350, 650, 300, 650, 350, 650, 350, 650, 350, ...truncated to fit...
1650, 350, 1600, 350};

  unsigned int SamsungNUM3[] = {4350, 4550, 400, 600, 350, 600, 400, 600, 450, 550, 400, 600, 400, 1550, 450, 550, 450, 550, 400, 600, 350, 600, 450, 550, 450, ...truncated to fit...

  unsigned int SamsungNUM0[] = {4300, 4600, 350, 600, 400, 600, 400, 600, 400, ...truncated to fit...

  unsigned int SamsungNUM5[] = {4300, 4550, 400, 600, 400, 600, 400, 600, 400, 550, 400, 600, 400, 1600, 400, 600, 350, 600, 400, 600, 400, 600, 400, 600, 350, ...truncated to fit...

  unsigned int SamsungNUM1[] = {4350, 4550, 400, 600, 400, 550, 400, 600, 450, ...truncated to fit...

  unsigned int SamsungNUM6[] = {4250, 4600, 350, 650, 300, 650, 400, 600, 350, 650, 350, 650, 300, 1650, 400, 600, 350, 650, 350, 650, 300, 650, 350, 650, 350, ...truncated to fit...


void loop() {

...

...

...


    if (buttonState) {
      Serial.println("\tPressed, sending");
      lcd.setCursor(0, 1);
      lcd.write("Pressed, sending");
      digitalWrite(STATUS_PIN, HIGH);
      switch (chosen) {
        case 1:
          lcd.setCursor(0, 1);
          lcd.write("switching on ...");
          break;
        case 2:
          lcd.setCursor(0, 1);
          lcd.write("switching OFF...");
          break;
        case 3:
          lcd.setCursor(0, 1);
          lcd.write("changing to 230 ");
          JUSTsendRAW(SamsungNUM2);
          JUSTsendRAW(SamsungNUM3);
          JUSTsendRAW(SamsungNUM0);
          break;
        case 4:
...

...

...



void JUSTsendRAW(unsigned int * hardcode, int codelength) {  
//    Serial.println("Pressed, sending");
    digitalWrite(STATUS_PIN, HIGH);
 //   sendCode(lastButtonState == buttonState);  ORIG.code
       irsend.sendRaw(hardcode, codelength, 38);    // Haier length = 67  Samsung = 77
  //  Serial.println("Sent raw");
    digitalWrite(STATUS_PIN, LOW);
delay(50);
}