Go Down

Topic: How can I create loops within the void loop!!! (Read 8769 times) previous topic - next topic

Pabs

Mar 16, 2011, 08:00 pm Last Edit: Mar 16, 2011, 09:21 pm by Pabs Reason: 1
Hi everyone, I've built a 5x5x5 mono colour LED cube and bought an Arduino Mega 2560.

The problem is I'm new to C and need some help with the basics.

I want to create the effect of only 4 LEDs in a cube moving around the 5x5x5 LED cube.

Is there a command that I can use to loop 4 LEDs then another 4 LEDs, etc. Giving the effect of it moving around?

eg.
LEDs 1,2,3,4 looped for time 2 seconds, then LEDs 5,6,7,8 looped for time 2 seconds, then LED 9,10,11,12 looped for time 2 seconds,......

Below is a sample of the way I have been writing and understanding C simply. If possible could someone show me how to write the with what I have, thanks.

void setup()
{
 pinMode(1, INPUT);
 pinMode(2, INPUT);
 pinMode(3, INPUT);
 pinMode(4, INPUT);
 pinMode(5, INPUT);
 pinMode(6, INPUT);
 pinMode(7, INPUT);
 pinMode(8, INPUT);
 pinMode(9, INPUT);
 pinMode(10, INPUT);
 pinMode(11, INPUT);
 pinMode(12, INPUT);
 pinMode(13, INPUT);
 pinMode(14, INPUT);
 pinMode(15, INPUT);
 pinMode(16, INPUT);
 pinMode(17, INPUT);
 pinMode(18, INPUT);
 pinMode(19, INPUT);
 pinMode(20, INPUT);
}

void loop()
{
 pinMode(5, OUTPUT); ///////////A5//////////////
 pinMode(19, OUTPUT);
 digitalWrite(5, HIGH);  
 digitalWrite(19, LOW);
 delay(25);
 pinMode(5, INPUT);
 pinMode(19, INPUT);  

 pinMode(19, OUTPUT); ///////////////A10//////////////////
 pinMode(5, OUTPUT);
 digitalWrite(19, HIGH);  
 digitalWrite(5, LOW);
 delay(25);
 pinMode(19, INPUT);
 pinMode(5, INPUT);

 pinMode(5, OUTPUT);  //////////////////A15///////////////
 pinMode(20, OUTPUT);
 digitalWrite(5, HIGH);  
 digitalWrite(20, LOW);
 delay(25);
 pinMode(5, INPUT);
 pinMode(20, INPUT);

 pinMode(20, OUTPUT);  ////////////////////A20/////////////  
 pinMode(5, OUTPUT);
 digitalWrite(20, HIGH);  
 digitalWrite(5, LOW);
 delay(25);
 pinMode(20, INPUT);
 pinMode(5, INPUT);


tomm

#1
Mar 16, 2011, 09:44 pm Last Edit: Mar 16, 2011, 09:55 pm by tomm Reason: 1
Hi.
I'm not really familiar with the hardware, but I can at least point you in the right direction with the software.
What i'd start by doing is making it earier to turn a LED at a particular co-ordinate on/off. If you do this, you'll be able to reduce the amount of code you need to write to turn lots of LEDs on and off, making your code clearer to read.

Code: [Select]
void lightLed(int x, int y, int z)
{
  //turn off all your other LEDs
  //do your digital writes etc here to turn the LED on that you want
}


So to turn a 2x2 square in the bottom corner of the matrix on for 2 seconds you'd have, (assuming a normal x,y,z axis system)

Code: [Select]
for(int count=0, count<100,count++)
{
  lightLed(0,0,0);
  delay(5);
  lightLed(1,0,0);
  delay(5);
  lightLed(0,1,0);
  delay(5);
  lightLed(1,1,0);
  delay(5);
}


in your loop().

Then you can either
i) Control the position manually by setting up multiple for loops one after another
ii) Randomising the position each time the loop() starts. I.e. Choosing a random x,y,z between 0 and 4 and displaying the square at that position.

Hope that helps, or at least points you in the right direction. If you want any of this clarifying or expanding, don't hesitate to ask.

Pabs

Hi, Thanks for the great response Tomm, that sounds exactly what I want to do. How do I address an LED on the x,y,z axis system.

Example:

A5 (the top left LED) = x1, y1, z1

A5 uses Pin 5 HIGH and Pin 19 LOW

Thanks,
Pabs.

tomm

I've done a bit of reading up about LED cubes, but obviously I don't know your exact implementation.
Presuming you have an anode per column and a cathode per horizontal plane you could set up your pins/cube like this:

(This makes the assumption your top-front-left LED is 0,0,0 with x going left to right, y going front to back and z going top to bottom)
Code: [Select]

int anodes[5][5] ={ //starting from the top-front-left and working to the top-back-right
                          {A0,A1,A2,A3,A4},
                          {A5,A6,A7,A8,A9},
                          {A10,A11,A12,A13,A14},
                          {A15,A16,A17,A18,A19},
                          {A20,A21,A22,A23,A24}
                         };
int cathodes[5] = {CA0,CA1,CA2,CA3,CA4}; //from top to bottom


Where A0...A24 and CA0...CA4 are the appropriate pin number on the Arduino.
Then you could do something like this:

Code: [Select]

void lightLed(int x, int y, int z)
{
  //turn off all your other LEDs - loop over them or do it manually
  //...
  //turn on the LED you want
  digitalWrite(anodes[y][x], HIGH);   
  digitalWrite(cathodes[5], LOW);
}


So if you have your arrays set up correctly it'll select the appropriate LED pins (hopefully).
This will need a bit of tweaking to work with your setup, but should be a good starting point for you to continue with.
Tom

Grumpy_Mike

You can get more efficient if you use variables (and also use the # key when posting code). For example the whole of setup() could be written as:-
for(int i = 1; i<21; i++) pinMode(i, INPUT);

Note it is not a good idea to use pins 0 and 1 for LEDs as these are used with serial communications.

tomm

Is it standard to set up pins as input, switch them to output when you want to turn them on and then turn them back to inputs? Seems a little excessive to me.

Grumpy_Mike

No it is not. An output must be a high or low, if you start changing them to inputs you get into tri state logic and things fall apart if you don't know what you are doing

Pabs

Hi guys, thanks again for the replies. I need to use a tri state logic because of the way that I multiplexed. I still can't get the the code to turn on four LEDs using:

void lightLed(int x, int y, int z)
{
  //turn off all your other LEDs - loop over them or do it manually
  //...
  //turn on the LED you want
  digitalWrite(anodes[y]
  • , HIGH);   
      digitalWrite(cathodes[5], LOW);
    }



    When I go to verify it, it never works. would it be possible to write the code for me to show 4 LEDs on please. Maybe when I see that wrote it will be easier to understand.

    I'm using PINs 1-20, the PINs need to be tri-state. Below I'll list the position of an LED and its PIN state.

    ///////////A5//////////////
      digitalWrite(5, HIGH);   
      digitalWrite(19, LOW);

      ///////////////A10//////////////////
      digitalWrite(19, HIGH);   
      digitalWrite(5, LOW);

    //////////////B5/////////////////
      digitalWrite(4, HIGH);   
      digitalWrite(19, LOW);

     
      /////////////B10//////////////////////
      digitalWrite(19, HIGH);   
      digitalWrite(4, LOW);


tomm

#8
Mar 17, 2011, 07:49 pm Last Edit: Mar 17, 2011, 07:53 pm by tomm Reason: 1
I've no idea how you've got your LED cube set up so here's a sample 2x2 setup:


The anodes of the LEDs are all connected in columns and the cathodes in horizontal planes.
The 4 anodes and 2 cathodes are connected to individual pins on the Arduino.

So in the setup i'd have:
Code: [Select]

int anodes[2][2] ={ //starting from the front-left and working to the back-right
                         {2,5},
                         {3,4},
                        };
int cathodes[2] = {7,6}; //from bottom to top

along with all the various code for setting the pins up etc.

Then this code to turn LEDs on and off.
Code: [Select]

void lightLed(int x, int y, int z)
{
 //turn off last LED
 digitalWrite(anodes[lastZ][lastX], LOW);  
 digitalWrite(cathodes[lastY], HIGH);
 //turn on the LED you want
 digitalWrite(anodes[z][x], HIGH);  
 digitalWrite(cathodes[y], LOW);
 //store current LED
 lastX =x;
 lastY =y;
 lastZ =z;
}


Then to light the front four LEDs of this cube I'd do

Code: [Select]

void  loop()
{
 lightLed(0,0,0);
 delay(25);
 lightLed(1,0,0);
 delay(25);
 lightLed(0,1,0);
 delay(25);
 lightLed(1,1,0);
 delay(25);
}


This is just an example, but you should only need to populate the arrays with your pin values and you should be pretty close to having working code. I'm quite tempted to build a small one of these myself as my next project.

Go Up