Offline
Newbie
Karma: 0
Posts: 10
|
 |
« on: December 24, 2012, 02:31:04 pm » |
Hi all, I am using Arduino to become more electronicly savy as a mechanical engineer. So I am pretty much a noob. I build a 4x4x4 cube following the example in the link below. http://www.instructables.com/id/4x4x4-LED-Cube-Arduino/#introOne thing i did different, because I dont have the NPN transistors. I used a Darlington transitor array uln2803A. Now I want to write some of my own code. But when I just want to light up one led the whole collum lights up. What am I doing wrong?? The code is below. #include <avr/pgmspace.h> // allows use of PROGMEM to store patterns in flash
#define CUBESIZE 4 #define PLANESIZE CUBESIZE*CUBESIZE #define PLANETIME 500 // time each plane is displayed in us -> 100 Hz refresh #define TIMECONST 20 // multiplies DisplayTime to get ms - why not =100?
// LED Pattern Table in PROGMEM - last column is display time in 100ms units // TODO this could be a lot more compact but not with binary pattern representation prog_uchar PROGMEM PatternTable[] = { // blink on and off
B1000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,100,
B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,10,
// this is a dummy element for end of table (duration=0) aka !!!DO NOT TOUCH!!! B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, 0 };
/* ** Defining pins in array makes it easier to rearrange how cube is wired ** Adjust numbers here until LEDs flash in order - L to R, T to B ** Note that analog inputs 0-5 are also digital outputs 14-19! ** Pin DigitalOut0 (serial RX) and AnalogIn5 are left open for future apps */
int LEDPin[] = {13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 14, 15}; int PlanePin[] = {16, 17, 18, 19};
// initialization void setup() { int pin; // loop counter // set up LED pins as output (active HIGH) for (pin=0; pin<PLANESIZE; pin++) { pinMode( LEDPin[pin], OUTPUT ); } // set up plane pins as outputs (active LOW) for (pin=0; pin<CUBESIZE; pin++) { pinMode( PlanePin[pin], OUTPUT ); } }
// display pattern in table until DisplayTime is zero (then repeat) void loop() { // declare variables byte PatternBuf[PLANESIZE]; // saves current pattern from PatternTable int PatternIdx; byte DisplayTime; // time*100ms to display pattern unsigned long EndTime; int plane; // loop counter for cube refresh int patbufidx; // indexes which byte from pattern buffer int ledrow; // counts LEDs in refresh loop int ledcol; // counts LEDs in refresh loop int ledpin; // counts LEDs in refresh loop
// Initialize PatternIdx to beginning of pattern table PatternIdx = 0; // loop over entries in pattern table - while DisplayTime>0 do { // read pattern from PROGMEM and save in array memcpy_P( PatternBuf, PatternTable+PatternIdx, PLANESIZE ); PatternIdx += PLANESIZE; // read DisplayTime from PROGMEM and increment index DisplayTime = pgm_read_byte_near( PatternTable + PatternIdx++ ); // compute EndTime from current time (ms) and DisplayTime EndTime = millis() + ((unsigned long) DisplayTime) * TIMECONST;
// loop while DisplayTime>0 and current time < EndTime while ( millis() < EndTime ) { patbufidx = 0; // reset index counter to beginning of buffer // loop over planes for (plane=0; plane<CUBESIZE; plane++) { // turn previous plane off if (plane==0) { digitalWrite( PlanePin[CUBESIZE-1], HIGH ); } else { digitalWrite( PlanePin[plane-1], HIGH ); }
// load current plane pattern data into ports ledpin = 0; for (ledrow=0; ledrow<CUBESIZE; ledrow++) { for (ledcol=0; ledcol<CUBESIZE; ledcol++) { digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) ); } patbufidx++; }
// turn current plane on digitalWrite( PlanePin[plane], LOW ); // delay PLANETIME us delayMicroseconds( PLANETIME ); } // for plane } // while <EndTime } while (DisplayTime > 0); // read patterns until time=0 which signals end }
|
|
|
|
« Last Edit: December 24, 2012, 02:56:27 pm by Tomtin »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 10
|
 |
« Reply #1 on: December 24, 2012, 05:16:39 pm » |
nobody?
|
|
|
|
|
Logged
|
|
|
|
|
California
Offline
Edison Member
Karma: 39
Posts: 1852
|
 |
« Reply #2 on: December 24, 2012, 05:27:37 pm » |
nobody?
Use the Arduino IDE's auto format tool (Under tools > Auto format) before posting code; nobody is going to want to help you with code looking like that.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 10
|
 |
« Reply #3 on: December 24, 2012, 05:34:57 pm » |
I only made the part where i light up one led to check if it works. When i run this code a whole column lights up. the code below is my part. the rest I copied of the instructables B1000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,100, #include <avr/pgmspace.h> // allows use of PROGMEM to store patterns in flash
#define CUBESIZE 4 #define PLANESIZE CUBESIZE*CUBESIZE #define PLANETIME 500 // time each plane is displayed in us -> 100 Hz refresh #define TIMECONST 20 // multiplies DisplayTime to get ms - why not =100?
// LED Pattern Table in PROGMEM - last column is display time in 100ms units // TODO this could be a lot more compact but not with binary pattern representation prog_uchar PROGMEM PatternTable[] = { // blink on and off
B1000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,100,
B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,10,
// this is a dummy element for end of table (duration=0) aka !!!DO NOT TOUCH!!! B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, B0000, 0 };
/* ** Defining pins in array makes it easier to rearrange how cube is wired ** Adjust numbers here until LEDs flash in order - L to R, T to B ** Note that analog inputs 0-5 are also digital outputs 14-19! ** Pin DigitalOut0 (serial RX) and AnalogIn5 are left open for future apps */
int LEDPin[] = { 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 14, 15}; int PlanePin[] = { 16, 17, 18, 19};
// initialization void setup() { int pin; // loop counter // set up LED pins as output (active HIGH) for (pin=0; pin<PLANESIZE; pin++) { pinMode( LEDPin[pin], OUTPUT ); } // set up plane pins as outputs (active LOW) for (pin=0; pin<CUBESIZE; pin++) { pinMode( PlanePin[pin], OUTPUT ); } }
// display pattern in table until DisplayTime is zero (then repeat) void loop() { // declare variables byte PatternBuf[PLANESIZE]; // saves current pattern from PatternTable int PatternIdx; byte DisplayTime; // time*100ms to display pattern unsigned long EndTime; int plane; // loop counter for cube refresh int patbufidx; // indexes which byte from pattern buffer int ledrow; // counts LEDs in refresh loop int ledcol; // counts LEDs in refresh loop int ledpin; // counts LEDs in refresh loop
// Initialize PatternIdx to beginning of pattern table PatternIdx = 0; // loop over entries in pattern table - while DisplayTime>0 do { // read pattern from PROGMEM and save in array memcpy_P( PatternBuf, PatternTable+PatternIdx, PLANESIZE ); PatternIdx += PLANESIZE; // read DisplayTime from PROGMEM and increment index DisplayTime = pgm_read_byte_near( PatternTable + PatternIdx++ ); // compute EndTime from current time (ms) and DisplayTime EndTime = millis() + ((unsigned long) DisplayTime) * TIMECONST;
// loop while DisplayTime>0 and current time < EndTime while ( millis() < EndTime ) { patbufidx = 0; // reset index counter to beginning of buffer // loop over planes for (plane=0; plane<CUBESIZE; plane++) { // turn previous plane off if (plane==0) { digitalWrite( PlanePin[CUBESIZE-1], HIGH ); } else { digitalWrite( PlanePin[plane-1], HIGH ); }
// load current plane pattern data into ports ledpin = 0; for (ledrow=0; ledrow<CUBESIZE; ledrow++) { for (ledcol=0; ledcol<CUBESIZE; ledcol++) { digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) ); } patbufidx++; }
// turn current plane on digitalWrite( PlanePin[plane], LOW ); // delay PLANETIME us delayMicroseconds( PLANETIME ); } // for plane } // while <EndTime } while (DisplayTime > 0); // read patterns until time=0 which signals end }
|
|
|
|
|
Logged
|
|
|
|
|
Queens, New York
Offline
Edison Member
Karma: 29
Posts: 1563
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
|
 |
« Reply #4 on: December 24, 2012, 11:40:24 pm » |
I thought it took 3 variables to light a single led, x,y,z, going into an AND gate. You only have x and y, so you can't isolate the led that you want at z. I'm not sure how to actually code it, other than IF statements arranged as AND gates. If x=1, and y=1 and z=1, the bottom corner should only be lit, and so on.
|
|
|
|
|
Logged
|
UNO, MEGA, NANO, 4x4 keypad, micro servos, RF transceivers, bluetooth, ultrasonic sensor, 20x4 I2C LCD, 3.2 TFT touch screen, L298N Dual motor driver, Voice Recognition 15W, Gameduino
Arduino Tutorials, coming soon.
"If your doing nothing, it does not mean your lazy, it just means your open for anything that suits you" - Unknown
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 10
|
 |
« Reply #5 on: December 25, 2012, 05:46:52 am » |
No you only need 2. The idea is you light one column and one plane. This will cause one led to light up. Cause the other leds in the column are not grounded by the plane. To light several leds is to switch very fast between them (called multiplexing).
the code is not mine i just changed a bit. Does anyone see where I can change the number of refresh time?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 10
|
 |
« Reply #6 on: December 27, 2012, 11:15:58 am » |
can no one help me ?
|
|
|
|
|
Logged
|
|
|
|
|
Queens, New York
Offline
Edison Member
Karma: 29
Posts: 1563
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
|
 |
« Reply #7 on: December 27, 2012, 01:09:09 pm » |
It could be a problem with the darlington pair array, you might have it wired incorrectly, or it could be with your LED pins. The plane determines which set of LEDS are on, so that may be correct, but you may be sending out more than 1 output. Im not familiar with (B1000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,B0000,100) as a form of port manipulation. Normally it is B0000xxxx,Bxxxxxxxx or something simular. Look at this site. http://tronixstuff.wordpress.com/2011/10/22/tutorial-arduino-port-manipulation/
|
|
|
|
|
Logged
|
UNO, MEGA, NANO, 4x4 keypad, micro servos, RF transceivers, bluetooth, ultrasonic sensor, 20x4 I2C LCD, 3.2 TFT touch screen, L298N Dual motor driver, Voice Recognition 15W, Gameduino
Arduino Tutorials, coming soon.
"If your doing nothing, it does not mean your lazy, it just means your open for anything that suits you" - Unknown
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 10
|
 |
« Reply #8 on: December 27, 2012, 01:11:28 pm » |
thanks for your reply.
When i control the leds iduvidual by saying turn on layer 3 and led 6 it works.
|
|
|
|
|
Logged
|
|
|
|
|
Queens, New York
Offline
Edison Member
Karma: 29
Posts: 1563
"Of all the things I've ever lost, I miss my mind the most" -Ozzy Osbourne
|
 |
« Reply #9 on: December 27, 2012, 01:40:43 pm » |
ok well what exactly is representing layer 3 and led 6? You said you have 1 column that lights up, well that column should have 4 individual data lines(ledpins) and 1 common(plane). You may have the plane correct but you could be sending out 4 led outputs instead of just the one you need.
Or, it is possible that you just wired it wrong, I don't know. Did you test every LED individually?
|
|
|
|
|
Logged
|
UNO, MEGA, NANO, 4x4 keypad, micro servos, RF transceivers, bluetooth, ultrasonic sensor, 20x4 I2C LCD, 3.2 TFT touch screen, L298N Dual motor driver, Voice Recognition 15W, Gameduino
Arduino Tutorials, coming soon.
"If your doing nothing, it does not mean your lazy, it just means your open for anything that suits you" - Unknown
|
|
|
|
United Kingdom
Offline
Faraday Member
Karma: 131
Posts: 4673
|
 |
« Reply #10 on: December 27, 2012, 01:44:11 pm » |
From the code you posted: // turn previous plane off if (plane==0) { digitalWrite( PlanePin[CUBESIZE-1], HIGH ); } else { digitalWrite( PlanePin[plane-1], HIGH ); }
... // turn current plane on digitalWrite( PlanePin[plane], LOW );
I think that code is wrong. If you are driving the planes through a ULN2803 buffer (or through NPN transistors), then the plane outputs are active high, not active low. So you need to write LOW to switch a plane off and HIGH to switch it on.
|
|
|
|
|
Logged
|
Formal verification of safety-critical software, software development, and electronic design and prototyping. http://www.eschertech.com
|
|
|
|
UK
Offline
Tesla Member
Karma: 89
Posts: 6367
-
|
 |
« Reply #11 on: December 27, 2012, 01:45:08 pm » |
If the whole column lights up that suggests all the planes are being enabled. Looking at that sketch, it expects the plane output pins to be active low. Is that how you have wired them up?
ETA: Looks like dc42 is ahead of me.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 10
|
 |
« Reply #12 on: December 28, 2012, 07:09:28 am » |
From the code you posted: // turn previous plane off if (plane==0) { digitalWrite( PlanePin[CUBESIZE-1], HIGH ); } else { digitalWrite( PlanePin[plane-1], HIGH ); }
... // turn current plane on digitalWrite( PlanePin[plane], LOW );
I think that code is wrong. If you are driving the planes through a ULN2803 buffer (or through NPN transistors), then the plane outputs are active high, not active low. So you need to write LOW to switch a plane off and HIGH to switch it on. Thank you very very much it works now!! The last part of the code should have been as below Thank you again  // loop while DisplayTime>0 and current time < EndTime while ( millis() < EndTime ) { patbufidx = 0; // reset index counter to beginning of buffer // loop over planes for (plane=0; plane<CUBESIZE; plane++) { // turn previous plane off if (plane==0) { digitalWrite( PlanePin[CUBESIZE-1], LOW ); } else { digitalWrite( PlanePin[plane-1], LOW ); }
// load current plane pattern data into ports ledpin = 0; for (ledrow=0; ledrow<CUBESIZE; ledrow++) { for (ledcol=0; ledcol<CUBESIZE; ledcol++) { digitalWrite( LEDPin[ledpin++], PatternBuf[patbufidx] & (1 << ledcol) ); } patbufidx++; }
// turn current plane on digitalWrite( PlanePin[plane], HIGH ); // delay PLANETIME us delayMicroseconds( PLANETIME ); } // for plane } // while <EndTime } while (DisplayTime > 0); // read patterns until time=0 which signals end }
|
|
|
|
|
Logged
|
|
|
|
|
|