NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.
Microcontroller Programming » 4 Shift Registers in Daisy Chain with Atmega168 for RGB PWM
June 16, 2011 by lavared |
Hi, I have been trying to do a PWM on a 8x8 RGB LED matrix using an Atmega168 and 4 74H595 Shift Registers. Is there any code snippet for how to do the spi transfer for the 4 shift registers (each representing red, blue, green and common cathode) when the 4 shift registers are connected in daisy chain and get the input from the Atmega168 set as Master. Thanks |
---|---|
June 16, 2011 by lavared |
the arrangement for it is similar to http://francisshanahan.com/index.php/2009/how-to-build-a-8x8x3-led-matrix-with-pwm-using-an-arduino/ but without the arduino board. I'm using my own nerdkit board and everything seems to be working except that i'm not getting distinct color combinations but see the red, blue, green lights on with some flickering on green leds. I think i'm not doingthe spi transfer correctly. |
June 16, 2011 by Ralphxyz |
lavared, lets have a look at your code. Ralph |
June 16, 2011 by lavared |
Raplh, Here it is..I'm not able to include full code due to formatting issues. Lavared /******** define __spi_clock 13 // SCK - hardware SPIdefine __spi_latch 10define __spi_data 11 // MOSI - hardware SPIdefine __spi_data_in 12 // MISO - hardware SPI (unused)define __display_enable 9define __rows 8define max_row rows-1define __leds_per_row 8define max_led leds_per_row-1define __brightness_levels 32 // 0...15 above 28 is bad for ISR ( move to timer1, lower irq freq ! )define max_brightness brightness_levels-1define __fade_delay 4define __TIMER1_MAX 0xFFFF // 16 bit CTRdefine __TIMER1_CNT 0x0020 // 32 levels --> 0x0130; 38 --> 0x0157 (flicker)define __TIMER2_MAX 0xFF // 8 bit CTRdefine __TIMER2_CNT 0x1D // max 28 levels !include <avr/interrupt.h>include <avr/io.h>include <stdint.h>include <inttypes.h>include "../libnerdkits/delay.h"include "../libnerdkits/uart.h"include <stdio.h>include <stdlib.h>volatile uint8_t brightness_red[leds_per_row][rows]; volatile uint8_t brightness_green[leds_per_row][rows]; volatile uint8_t brightness_blue[leds_per_row][rows]; uint8_t spi_transfer(volatile uint8_t data) { unsigned char datain; // Start transmission (MOSI) SPDR = data; while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission { // Get return Value; datain = SPDR; // Latch the Output using rising pulse to the RCK Pin PORTB |= (1<<PB2); // Hold pulse for 1 micro second delay_ms(1); // Disable Latch PORTB &= ~(1<<PB2); }; // Return Serial In Value (MISO) return SPDR; // return the received byte, we don't need that } Rest all code (expect main() program ) is same as given here... http://blog.spitzenpfeil.org/wordpress/wp-content/uploads/2008/10/matrix_code.pde the main() code is given below: int main(void) { setup(); while(1){ loop(); } return 0; } |
June 16, 2011 by Noter |
That's pretty hard to follow. Maybe you could post again as a code block? |
June 16, 2011 by lavared |
Here it is again. Lavared /** #define spi_clock 13 // SCK - hardware SPI #define spi_latch 10 #define spi_data 11 // MOSI - hardware SPI #define spi_data_in 12 // MISO - hardware SPI (unused) #define display_enable 9 #define rows 8 #define max_row rows-1 #define leds_per_row 8 #define max_led leds_per_row-1 #define brightness_levels 32 // 0...15 above 28 is bad for ISR ( move to timer1, lower irq freq ! ) #define max_brightness brightness_levels-1 #define __fade_delay 4
Rest all code (expect main() program ) is same as given here... http://blog.spitzenpfeil.org/wordpress/wp-content/uploads/2008/10/matrix_code.pde
|
June 16, 2011 by lavared |
|
June 16, 2011 by lavared |
|
June 17, 2011 by Noter |
I haven't looked at all of it yet but I think there is a problem here in the spi_transfer function. The while should loop doing nothing until it's done and then do the latch. Here I have taken the code block out of the while loop. Also, return datain since you already read it from SPDR.
|
June 17, 2011 by lavared |
Thanks Noter, thats what I thought. But how do you latch data to send to 4 shift registers...? If you look at lines 207-213 and 460-466, the spi function is transferring data related to red, blue, green and cathode in the reverse order. I want it to read all the 4 shift register data and then send it once it done reading from all. |
June 17, 2011 by Noter |
I think all you need to do is remove the latch logic from the spi_transfer function so you can send all 4 bytes and then latch only once after the 4th byte is sent. Assuming all your shift registers have the latch lines common and they overflow from one to the next. Have you tried that? |
June 17, 2011 by lavared |
yeah Noter, I have tried that but it did'nt work. Hence i tried it this way. |
June 17, 2011 by Noter |
Ok, it's been a while since I've used 74HC595 so I had to look at the datasheet again but that's the way it works. You can shift data thru them as much as you like and when you latch, the current shifted data is put to the output pins. How about making a test program with minimum code to just work the spi and shift register with a simple pattern that blinks the led's. That should be easier to get working and then you can work it back into your big program. |
June 17, 2011 by Noter |
How are you driving your led's? Max current for the 74HC595 is 70ma which is enough current to drive about 3 led's. When I used the 74HC595 I had it drive transistors which in turn drove the load. |
June 18, 2011 by Rick_S |
In the link he gave above, assuming he copied the circuit design, it looks as if they drove an 8 x 8 RGB matrix directly. I'm guessing they get away with it like the NK guys do on the LED-Array project, due to a low duty cycle. Rick |
June 18, 2011 by lavared |
Yes Noter, i'm driving them directly. I'll try to run a small sample code to test the shift register transfer. |
June 18, 2011 by lavared |
yeah it is the spi transfer function that needs reworking. I'm now trying to figure out how to latch the red, blue and green leds simultaneously on the 4 shift registers. |
June 18, 2011 by lavared |
can somebody point me to a code snippet for latching data on multiple shift registers? |
June 19, 2011 by Noter |
Sorry but I can't find any of my old shift register code. It went away when I changed over to multiple mpu's using I2C. I still have a tube of 74HC595's and can probably wire up a few to duplicate your results if you would post your small test program so I don't have to start from scratch. |
June 19, 2011 by Rick_S |
Here is a link to a grouping of 4 595's I used to drive a 4 digit 7 segment LED display to demonstrate a simple how to for another member who was building a Photography Club rating project. There is sample code and some photo's of the setup. Don't know if it'll help out or not... Rick |
June 19, 2011 by lavared |
Noter, here it is. I'm actually trying to send some bits for red, blue and green leds on different rows and running them. Its similar to Rick's code on 595's.
|
June 19, 2011 by lavared |
my USB-Serial cable stopped working while testing. Is there any other way (any other cable locally available) to get it to work, so that I'll be able to flash my MCU?. Ordering from the Nerkits store might set me back by a week or so depending on the shipment of the cable. |
June 20, 2011 by Noter |
Ok, I'll give it a try later this evening. If you have a serial port you may be able to get the parts for this circuit quicker than a new usb cable. |
June 20, 2011 by Noter |
I made a few minor changes for my setup but otherwise your program works fine. I use the util/delay.h because my F_CPU is 8000000 vs the nerdkit's 14745600 and I don't have any led's connected to the outputs so I changed for a stable pattern that made it easy to test one output pin at a time. See if this blinks your led's in a static pattern. If not maybe a wiring problem?
|
June 21, 2011 by lavared |
thanks Noter. Will try it once I receive my USB-Serial cable this weekend. Unfortunately I don't have have the parts to the wiring diagram you sent earlier. |
June 26, 2011 by lavared |
Noter, I modified the example and its is working for me too with 2 shift registers. I chained the two shift registers in a daisy chain and for each shift register I attached 8 leds (16 in total) and I lit them one after the other sequentially in a chain. It worked for me. Thanks for helping me out. Now I need to figure out my actual problem. |
July 13, 2011 by lavared |
All, I have one question and was hoping somebody would clear it....In my code above, i'm doing the PWM on PB1 pin but it is not connected to any shift registers. The only connections I have for the 4 shift registers is MOSI, SCK, Latch pins of MCU. Is PB1 pin supposed to be empty ? Or does it need to be connected to any pins (since theoretically PWM is happening on it). Thanks |
August 16, 2011 by Ralphxyz |
Hey Paul, I tried your code in two different setups but all I get is led 1, 9, 19 and led 28 to flash (using 4 shift registers with 32 leds). Any idea what might be happening? Ralph |
August 16, 2011 by Ralphxyz |
Duh, darn sorry I've got so many things I am looking at besides the actual code. It is doing exactly what your program says to do. Well now to feed it some patterns to see what happens. Ralph |
Please log in to post a reply.
Did you know that essentially all power supplies' voltages drop when current is drawn from them? Learn more...
|