Learning Arrays

Alright so I'm trying to learn arrays. This code uses 3 arrays which each color of leds with their own array. Is there a way that I can make it all into one array and each row of the array could be a color. Also, I'm aware of how messy this code is, what would be a better way to write this same sequence?

Board Type: Arduino UNO

P.S. this is just one sequence that I'm wanting to do.
The sequence for light placement is YRGYRGYRG so this code just makes
each light, light up in a row

int rticker = 0;
int yticker = 0;
int gticker = 0;


const int eachColorNum = 3;

int yLed[eachColorNum] = { 2, 5, 8 };
int rLed[eachColorNum] = { 3, 6, 9 };
int gLed[eachColorNum] = { 4, 7, 10 };

void setup() {
  Serial.begin(9600);
  for (byte y = 0; y < 3; y++) {
    pinMode(yLed[y], OUTPUT);
  }
  for (byte r = 0; r < 3; r++) {
    pinMode(rLed[r], OUTPUT);
  }
  for (byte g = 0; g < 2; g++) {
    pinMode(gLed[g], OUTPUT);
  }
}

void loop() {
  Serial.println(rticker);
  // turn on led Lights
  if (yticker < eachColorNum) {  // turn on yellow Lights
    digitalWrite(yLed[yticker], HIGH);
    delay(500);
    yticker++;
  }
  if (rticker < eachColorNum) {  //turn on Red Lights
    digitalWrite(rLed[rticker], HIGH);
    delay(500);
    rticker++;
  }
  if (gticker < eachColorNum) {  // turn on Green lights
    digitalWrite(gLed[gticker], HIGH);
    delay(500);
    gticker++;
  }
  // Turn off led lights
  if (yticker == eachColorNum) {  // turn off Green lights
    for (byte c = 0; c < eachColorNum; c++) {
      digitalWrite(yLed[c], LOW);
    }
    yticker = 0;
  }
  if (rticker == eachColorNum) {  // turn off Green lights
    for (byte c = 0; c < eachColorNum; c++) {
      digitalWrite(rLed[c], LOW);
    }
    rticker = 0;
  }
  if (gticker == eachColorNum) {  // turn off Green lights
    for (byte c = 0; c < eachColorNum; c++) {
      digitalWrite(gLed[c], LOW);
    }
    gticker = 0;
  }
}

Go to the interwebs and use the search term 'two dimensional array c++'.

int led[] = {
  2, 5, 8 // YEL <- I forgot to add the comma after the 8
  3, 6, 9 // RED <- I forgot to add the comma after the 9
  4, 7, 10 // GRN <- I forgot I did not need to add a comma after the 10
}

The LED pins are now led[0] through led[8] with yellow being led[0], led[1], led[2], red being led[3], led[4], led[5] and green being led[6], led[7], led[8]

Why are you using RED, Green and YELLOW?

That won't get you all the colours. Yellow is not a primary colour when using additive colours like light.

It is only a primary colour when using subtractive colours like paint. In subtractive colours, the other two primary colours are cyan and magenta.

Hello eturrentine1

Check and study this small example to gain the knowledge.

//https://forum.arduino.cc/t/learning-arrays/1266982
//https://europe1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
#define ProjectName "Learning Arrays"
#define NotesOnRelease "Arduino MEGA tested"
constexpr uint8_t Leds[][3] =
{
  { 2, 5, 8 },
  { 3, 6, 9 },
  { 4, 7, 10 },
};
void heartBeat(const uint8_t LedPin, uint32_t currentMillis)
{
  static bool setUp = false;
  if (setUp == false) pinMode (LedPin, OUTPUT), setUp = true;
  digitalWrite(LedPin, (currentMillis / 500) % 2);
}
// make application
void setup()
{
  Serial.begin(115200);
  Serial.print("Source: "), Serial.println(__FILE__);
  Serial.print(ProjectName), Serial.print(" - "), Serial.println(NotesOnRelease);


  // https://www.learncpp.com/cpp-tutorial/range-based-for-loops-for-each/
  for (auto &Led : Leds)
  {
    for (auto &a : Led)
    {
      pinMode(a, OUTPUT);
    }
  }
  Serial.println(" =-> and off we go\n");
}
void loop()
{
  uint32_t currentMillis = millis();
  heartBeat(LED_BUILTIN, currentMillis);
  for (auto &Led : Leds)
  {
    for (auto &a : Led)
    {
      digitalWrite(a, HIGH);
      delay(500);
    }
  }
  for (auto &Led : Leds)
  {
    for (auto &a : Led)
    {
      digitalWrite(a, LOW);
      delay(500);
    }
  }
}

Have a nice day and enjoy coding in C++.

Traffic light colors with RGB leds?

My question is why use ints? They should be bytes!

Shift to the left!
Shift to the right!
Pop up!
Pull down!
Byte-byte-byte!

This feels costly and non conventional for newbies. I would recommend to just have in the setup

pinMode (LedPin, OUTPUT);

side note:

I would also write

  digitalWrite(LedPin, (currentMillis / 500) % 2 == 0 ? LOW : HIGH);

but that's another discussion

1 Like

Everyone has the right and the opportunity to learn something new or to ignore it. That's quite simple.
Is your middle name Stefan? :smiley:

1 Like

:wink:

just saying how I see it - of course all options possible.

1 Like

I told you that in your last topic!

so your Object is using 3 pins. As it sounds you are dealing with Traffic lights, group them together and given them a nice name for the group

struct TrafficLight {
  const uint8_t greenPin; 
  const uint8_t yellowPin; 
  const uint8_t redPin; 
};

now you have 3 of those, you can make an array of Traffic Lights

TrafficLight lights[] = {
  {2, 3,  4},
  {5, 6,  7},
  {8, 9, 10}
};

a TrafficLight can perform actions on its lights. For example, configuring the pins as OUTPUT would seem a good way to begin the set-up, so we can expand the structure by adding a function working on the variables inside the struct:

struct TrafficLight {
  const uint8_t greenPin; 
  const uint8_t yellowPin; 
  const uint8_t redPin; 

  void begin() {
    pinMode(greenPin,  OUTPUT);
    pinMode(yellowPin,  OUTPUT);
    pinMode(redPin,  OUTPUT);
  } 
};

and so now in your setup you can just loop through your Traffic Lights and call begin to get ready

void setup() {
  for (TrafficLight& aTrafficLight : lights) aTrafficLight.begin();
}

you can expand the functions a TrafficLight can do, for example light up a specific color or turn everything off. Our structure would become

struct TrafficLight {
  const uint8_t greenPin; 
  const uint8_t yellowPin; 
  const uint8_t redPin; 

  void begin() {
    pinMode(greenPin,  OUTPUT);
    pinMode(yellowPin,  OUTPUT);
    pinMode(redPin,  OUTPUT);
  } 

  void off() {
    digitalWrite(greenPin, LOW);
    digitalWrite(yellowPin, LOW);
    digitalWrite(redPin, LOW);
  }

  void red() {
    off();
    digitalWrite(redPin, HIGH);
  }

  void yellow() {
    off();
    digitalWrite(yellowPin, HIGH);
  }

  void green() {
    off();
    digitalWrite(greenPin, HIGH);
  }
};

so now if you wan to turn all the lights red, it's again a simple for loop calling red() on each traffic light

  for (TrafficLight& aTrafficLight : lights) aTrafficLight.red(); // all lights red

➜ you can see how with this approach we embed into the struct some intelligence about the pins and create well named functions working on the structure.

here is a wokwi (with hidden wires so that it's not too messy) demonstrating the 3 traffic lights blinking with delay

with the traffic light object defined as described above, the main code is easy to read

you define the traffic lights

TrafficLight lights[] = {
  {2, 3,  4},
  {5, 6,  7},
  {8, 9, 10}
};

you get them ready in the setup

void setup() {
  for (TrafficLight& aTrafficLight : lights) aTrafficLight.begin();
}

you cycle through the colors in the loop with a delay here, just like the blink example

void loop() {
  for (TrafficLight& aTrafficLight : lights) aTrafficLight.red();    // all lights red
  delay(300);
  for (TrafficLight& aTrafficLight : lights) aTrafficLight.yellow(); // all lights yellow
  delay(300);
  for (TrafficLight& aTrafficLight : lights) aTrafficLight.green();  // all lights green
  delay(300);
}

if you get that, you are ready for Object Oriented Programming. the TrafficLight structure is an Object and structures are very close to classes.

3 Likes

Just a learning project for me now. It’s not arranged into a matrix, rather just a straight line. I’m just trying to understand switch case functions and arrays to create different outputs.

Example:
click the button: all lights “chase”
Click button again: and all yellow lights up, then all green, then all red.

Did you mean:


int led[] = {
  2, 5, 8, // YEL
  3, 6, 9, // RED
  4, 7, 10 // GRN
}

Yes... sorry.

When you code that you will find that you have to keep your finger on the button for a long time. This is because the button input will only be read at the end of the sequence.

There are ways round this but you will have to use more complex coding techniques than perhaps you are capable of at the moment.

The trick is to use the "blink without delay" technique as shown in the IDE examples. Sometimes referred to as a "State Machine".

We get the question almost every day here and many people have tried to explain it to beginners but still it gets asked.

For starters look at:-
Robin2's several things at once
http://forum.arduino.cc/index.php?topic=223286.0

or

Or Adafruit's

In 2 parts, 1st timing w/o blocking, 2nd reading serial w/o blocking (easier if you did the 1st) that contains state machines;

Nick Gammon's complete commonsense tutorial on non-blocking code.

Nick Gammon -- tutorial containing State Machine Technique.

here is an example

bonus = there is a slider to set the speed of the animation

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.