NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Project Help and Ideas » Christmas Light Synchronization

November 24, 2012
by Pew446
Pew446's Avatar

Hi everyone!

This year I've decided to take a go at a project I've wanted to make for a while now. I was planning on synchronizing our 8 Christmas trees to music using a microcontroller and my laptop. I plan on sending data to the microcontroller in the form of letters to signal which tree(s) to turn on (When letter 'A' is received, turn on tree 1, 'B' = 2, etc..) at predefined intervals. There's probably a better solution, but this is all I can think of for now.

I've been looking around at some instructables and whatnot, trying to build a circuit for cheap, and I have found this instructable, and figured converting it from Arduino to AVR would be simple enough. The more confusing part is the solid state relay circuit. In this instructable, a MOC3031 is used, however, tayda only carries MOC3041. I'm not sure if substituting a MOC3031 with a MOC3041 would work, because the "Off-State Output Terminal Voltage" is rated at 250V in the MOC3031, and 400V in the MOC3041. Is this important?

I'll be posting more as I progress. Thanks!

November 24, 2012
by sask55
sask55's Avatar

Pew446

The number of pins available to use as output pins from the Microcontroller to control lights will depend on what else you have connected to the chip. For example the serial UART, LCD display may use a number of your available pins.

If you are indenting to control only eight sets of lights and do not want the capability to expand that number then you will require control of only eight output pins. There are eight bits in each byte. If you intend to control your lights with data sent from a computer each byte sent to the micro could carry enough information to control all eight of your light circuits.

Each bit in the received byte would correspond to an output pin state on the micro. So rather then sending an ‘A’ to turn on tree 1, ‘B’ =2 etc. Sending a control code byte where bit 0 is low will be tree 1 off, bit 0 high will be tree 1 on , bit 1 low will be tree 2 off, bit 1 high will be on tree 2 on etc.

On the computer it is just a mater of adding or subtracting a value equal to the bit value of the corresponding light circuits. If tree 1 is set up on bit 0 then add a 1 to the byte to be sent to the mico will turn on that tree. Subtract a 1 will turn off tree 1. By adding or subtracting values of 1,2,4,8,16,32,62,128 you can easily control each individual light circuit on each byte sent. Send 0 all trees are off. send 256 all trees would be on. send a 16 only tree 5 would be on. add 32 to 16 32+16= 48 send 48 trees 5 and 6 are on. Any combination of the eight lights can be sent on each byte.

It will take only one line of code on the micro to set or clear the corresponding output pins according to the bit values received in each incoming byte.

I don’t know how clear this idea may be to you. I may not have explained it very well. I or someone else could explain this idea in much more detail if you are interested.

November 24, 2012
by Pew446
Pew446's Avatar

I can't believe I didn't think of that. Thanks for the help!

November 25, 2012
by pcbolt
pcbolt's Avatar

Pew -

Be very careful with the 120 volt AC. From looking at the Instructable, he's got exposed hot and neutral about .2" apart on his perfboard. That's a little too close for my comfort but maybe that's just me. I'd try to come up with a better way to insulate those wires from each other (and from me!). Good luck on the project...you're cutting it close for X-mas this year. :-)

November 25, 2012
by Pew446
Pew446's Avatar

Good point. I'll make sure to take necessary precautions. Don't want to spark a fire!..or myself. :P

November 25, 2012
by Rick_S
Rick_S's Avatar

First a word of warning. Household power is not something to be taken lightly. You shouldn't even put this on a solderless breadboard technically if you plan to light a 120v light bulb because most will draw more current than the breadboard is designed to handle.

I know you'll probably ignore my warnings... I probably would too, but by all means, be very careful.

Noter wrote up an instruction in the library here on how he set up an attiny micro to control a pump. It is a fairly advanced circuit thought but can be found HERE.

As for that instructable, I would shy away from using the triacs he uses. They are only rated at 1 amp. A better triac choice would be the BTAXX series these are T0220 cased with isolated heat sinks and can handle a lighting load better. I've used the BTA12's before but fused them at a lower current. Triac's get quite warm when pushed to their current rating w/o additional heatsinks.

Also, his breadboard and solder skills are a fire waiting to happen. If you are not more advanced in your skills than he is, be safe and just buy a light controller.

If you want to know how to switch Christmas lighting, go to the experts at Computer Christmas or one of the other Christmas lighting sites. This Link at computer Christmas shows a good method of building the SSR portion of your circuit. The drive side from the micro is just like blinking an LED unless you want to do dimming at which point it gets much more complicated.

Rick

November 25, 2012
by Pew446
Pew446's Avatar

Thanks for the concern and help, Rick! I don't plan on using a solderless breadboard. I was going to etch my own board for use with this project.

I don't intend on ignoring your warnings, this is my first time working with such power, and you know what they say: "With great power comes great risk of electrocution." All jokes aside, I plan on taking this project seriously.

Thanks for the link, I'll take a look at it.

I am planning on using these triads, with these heatsinks. 4A should do it.

I noticed how bad his solders are. I have a lot of experience soldering things, (mostly out of pure boredom) and I'm pretty confident I'll do a better job.

Thanks for the tip. I'll head over and find out what they think. The link is helpful. I'm still confused on whether using a MOC3041 will matter in place of that MOC3010 or the MOC3031 on the instructables, though. Also, what is that yellow component? Doesn't appear to be in the schematics. Thanks again!

November 25, 2012
by Noter
Noter's Avatar

They look like high voltage capacitors. Sometimes a triac needs a snubber to turn off.

I think the MOC3041 will be fine in place of the MOC3031. Higher voltage rating than you need is never a problem, it's when you go lower that you will have a problem. Usually higher ratings mean greater cost of the component.

November 25, 2012
by sask55
sask55's Avatar

Pew

My post earlier was concentrating on the communication and control aspect of your project. For whatever reason I never thought about the inherent dangers TO YOU when using the 120 volt AC side of this project.

There are good sound reasons for the electrical codes, equipment testing and standards concerning the use of 120 Volt AC power.

With regard to the programming on the computer, I don’t know what language you will be using to communicate with the Micro. It would be best if you used bit-wise operations to set up the command bytes to send to the Micro. The use of bitwise NOT, AND ,OR if they are available in the language that you are using will greatly simplify coding the control sequences.

It seams to me that the actual synchronization of the display to music will be a big part of your project. What I mean to say is, controlling the lights and producing a good display that is well synchronized to music are two different problems. You will require a bit of artistic talent and a lot of time to build a display production manually for each musical piece you wish to play, or you will require some sort of set of algorithms to interpret the music and produce a display automatically.Neither of these options seam trivial to me.

As a starting point you could consider producing an interesting display sequence based solely on time intervals. There quit a number of interesting ideas online on various types of displays that are automatically synchronized with music. Searching for “color organ” may give you some ideas.

November 30, 2012
by Pew446
Pew446's Avatar

Thanks for all the help and info guys! I'm pretty sure I've found all the parts I need and I ordered them last Tuesday, I expect them to arrive today or tomorrow. As for the code part of the project, I have found a program called Vixen which allows me to easily sync the lights and the music, and it works very similar to how sask55 suggested when using the included DMX USB Pro output driver. It sends 9 bits of data down the line, 8 for the channels and 1 for the stop bit. I haven't started on the AVR part of this project, but I'll get on it soon. In the meantime I'll be designing a PCB for everything.

December 01, 2012
by Rick_S
Rick_S's Avatar

Vixen is cool software, I built a 16 Channel lighting controller (Renard SS16) and used Vixen to test it. I never have set it up for a real display though so it just sits in my hobby/computer room on a shelf. If it weren't so late in the season, a Renard SS8 would have been my recommendation. They are proven boards with a proven protocol that not only turn lighting on and off, but dim as well.

Rick

December 02, 2012
by Pew446
Pew446's Avatar

I've been working on the board today, here are the pictures:

Top

Bottom

Circuit

There is still one socket I don't have on the board, and the 4 holes near the ATMEGA are for the USB-UART cable. I am going to Lowes tomorrow to buy some outlets, and I'll find some time to write the code for the ATMEGA this week.

December 03, 2012
by Rick_S
Rick_S's Avatar

Looks pretty good other than your power traces (Especially the Feed Trace) seem pretty small. I don't know how many lights you plan to put on each of your 8 trees, but keep in mind that tree lights can pull about .3A for mini incandescent per 100 strand. Here is a webpage describing the current draw for various lighting strands.

Rick

December 04, 2012
by Ralphxyz
Ralphxyz's Avatar

Wow Pew446, nice work, it's so neat.

Ralph

December 05, 2012
by Pew446
Pew446's Avatar

Just an update, I have connected one outlet to the board just to test, and I can successfully turn on and off any wall plug device with a 9-volt and a 7805 regulator. It's super cool! Now to code the chip.

December 05, 2012
by Pew446
Pew446's Avatar

Whoops, I'm stumped. How might I go about reading a byte of data from UART? (Or in my case, 9 bits, unless the stop bit isn't too terribly important.) Thanks!

December 06, 2012
by Pew446
Pew446's Avatar

Sorry for a triple post, this is where an edit button would come in handy. I've found out how to read bytes and separate them to bits, and I have it working so lights turn on based on the bits received, however, now my problem lies with vixen. I had thought the driver was going to do what I wanted it to, however, this is the kind of output I get from vixen: Not binary

Are there any drivers optimized for UART or Arduino that anyone knows of, or does anyone have any ideas? Thanks again.

December 06, 2012
by Rick_S
Rick_S's Avatar

I only played with Vixen with a Renard board so the protocol was already defined and worked correctly.

What output have you selected in Vixen??

Is there a generic serial output??

You aren't using any dimming commands, right?? Because your board will not support dimming. Keep in mind though, even though you may not be using dimming commands, Vixen may be outputting characters for it.

You are going to have to find out what Vixen does and what options you have in it's configuration to determine how you will have to parse it's output. Sounds like you've come quite a way though.

Rick

December 07, 2012
by Pew446
Pew446's Avatar

I switched to the generic serial output plugin, and now I only get "ÿ"

I noticed that ÿ = 11111111 in binary, which I assume is for full brightness. I also noticed that if I have, say, 5 channels on, 5 ÿ's are outputted. This makes me think the data is outputted in bytes with spaces where no data is outputted. For example, if I had this sequence set:

(white is on.)

Then the output in serial would be something like: 11111111 (empty) 11111111 (empty) 11111111 (empty) 11111111 (empty)

So I would have to read the bytes in at a steady rate, and if at some point I search for a byte and I don't receive anything (empty), I'll have to move to the next byte. I hope this is making sense. So the problem is going about doing this. I assume I'll have to start some kind of timer at the rate of bytes received, which is 14,400 bytes per second, right? (115200/8) And then scan for bytes every tick. I'm a little lost. Thanks

December 07, 2012
by Rick_S
Rick_S's Avatar

I would think Vixen would output a byte even if a channel was off just to tell that controller to turn off. You may find that you get an 8 byte sequence for your 8 channels and if a channel goes off the byte for that channel becomes 0x00, and when on it is 0xFF. Timing should be nothing more than using the correct baud rate and reading the bytes flowing in. You may need to set up an interrupt and serial buffer to ensure you don't miss any packets. Again, this is all speculation on my part so YMMV

Rick

December 07, 2012
by Rick_S
Rick_S's Avatar

One other thing, you want to read the data raw as it comes in and not try to interpret printable characters you see. Not every ASCII value is a printable character, so what you see as a blank space in reality could be one of many different ASCII values.

Rick

December 07, 2012
by Pew446
Pew446's Avatar

You were correct about Vixen sending out 0x00 when a channel is off. Thanks! The lights seem to receive pretty random data when I run Vixen though. I think the receiving and transmitting are out of sync. I decided to try a buffer like you suggested, but I'm having trouble finding info about how to create one. I did find this, though, and after changing some variable names, (UDR should be UDR0, etc) I'm stuck with two undeclared variables, "BUFFERSIZE" and "BAUD_CALC". Does the nerdkits lib come with any buffer code? Thanks

December 07, 2012
by Pew446
Pew446's Avatar

Hold the phone, it just occurred to me that I can manually replace those variables with my own numbers. Here is my code now:

// main.c

#include <stdio.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>
#include "Serial.c"

#include "../libnerdkits/delay.h"
#include "../libnerdkits/uart.h"

// PIN DEFINITIONS:
//
// PB1-5 ROW DRIVERS (0-4)
// PC0-5,PD2-7: COLUMN DRIVERS (0-11)
#define F_CPU 14745600

void start(){
    int i = 0;
    unsigned char bytes [8];
    DDRC |= ((1 << PC5) & (1 << PC4) & (1 << PC3) & (1 << PC2) & (1 << PC1) & (1 << PC0));
    DDRB |= ((1 << PB5) & (1 << PB4));
    PORTC &= ~((1 << PC5) & (1 << PC4) & (1 << PC3) & (1 << PC2) & (1 << PC1) & (1 << PC0));
    PORTB &= ~((1 << PB5) & (1 << PB4));
    while(1)
    {
        if(getBufferSize() >= 8)
        {
            for(i=0; i<8; i++){
                bytes[i] = readFromBuffer();
            }
                if(bytes[0] == 0xFF){
                    PORTC |= (1 << PC5);
                    printf_P(PSTR("Byte1 t\n\r"));
                }else{
                    PORTC &= ~(1 << PC5);
                    printf_P(PSTR("Byte1 f\n\r"));
                }
                if(bytes[1] == 0xFF){
                    PORTC |= (1 << PC4);
                    printf_P(PSTR("Byte2 t\n\r"));
                }else{
                    PORTC &= ~(1 << PC4);
                    printf_P(PSTR("Byte2 f\n\r"));
                }
                if(bytes[2] == 0xFF){
                    PORTC |= (1 << PC3);
                    printf_P(PSTR("Byte3 t\n\r"));
                }else{
                    PORTC &= ~(1 << PC3);
                    printf_P(PSTR("Byte3 f\n\r"));
                }
                if(bytes[3] == 0xFF){
                    PORTC |= (1 << PC2);
                    printf_P(PSTR("Byte4 t\n\r"));
                }else{
                    PORTC &= ~(1 << PC2);
                    printf_P(PSTR("Byte4 f\n\r"));
                }
                if(bytes[4] == 0xFF){
                    PORTC |= (1 << PC1);
                    printf_P(PSTR("Byte5 t\n\r"));
                }else{
                    PORTC &= ~(1 << PC1);
                    printf_P(PSTR("Byte5 f\n\r"));
                }
                if(bytes[5] == 0xFF){
                    PORTC |= (1 << PC0);
                    printf_P(PSTR("Byte6 t\n\r"));
                }else{
                    PORTC &= ~(1 << PC0);
                    printf_P(PSTR("Byte6 f\n\r"));
                }
                if(bytes[6] == 0xFF){
                    PORTB |= (1 << PB5);
                    printf_P(PSTR("Byte7 t\n\r"));
                }else{
                    PORTB &= ~(1 << PB5);
                    printf_P(PSTR("Byte7 f\n\r"));
                }
                if(bytes[7] == 0xFF){
                    PORTB |= (1 << PB4);
                    printf_P(PSTR("Byte8 t\n\r"));
                }else{
                    PORTB &= ~(1 << PB4);
                    printf_P(PSTR("Byte8 f\n\r"));
                }
        }
    }
}

int main() {
InitializeSerial();
sei();
// init serial port
//uart_init();
//FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
//stdin = stdout = &uart_stream;
start();
return 0;
}

//Serial.c

volatile char commandBuffer[10];
volatile int bufferStepThrough = 0;
volatile int bytesInBuffer = 0;

/** \fn void InitializeSerial()
 * \brief Initializes the USART0.
 * \param void
 * \return void
 */
void InitializeSerial(void)
{
                UBRR0H = 0;//Set baud rate
                UBRR0L = 7;//Set baud rate
                UCSR0B = _BV(TXEN0) | _BV(RXEN0) | _BV(RXCIE0);
                UCSR0C = (1<<USBS0)|(3<<UCSZ00);//Set frame format
}

/** \fn void serialTx( unsigned char output )
 * \brief Transmits an individual byte over serial.
 * \param unsigned char output
 * \return void
 */
void serialTx( unsigned char output )
{
                while ( !( UCSR0A & (1<<UDRE0)) ){}
                UDR0 = output;//Sends data through buffer
}

/** \fn unsigned char serialRx()
 * \brief Receives an individual byte for serial and echoes it back.
 * \param void
 * \return unsigned char received
 */
unsigned char serialRx( void )
{
                char received = UDR0;
                return received;//Get and return received data
}

/** \fn void serialTxString( char * str)
 * \brief Transmits a string, byte by byte, until it sees a null terminator.
 * \param char * str
 * \return void
 */
void serialTxString(char * str) {
                int i=0;
                while(str[i] != '\0') {
                    serialTx(str[i++]);
                }
                PORTB ^= 0xFF;
}

/** \fn void addToBuffer(char newInput)
 * \brief Given a new element, add it to the end of the buffer
 *  given we have not already filled it. If the buffer is full,
 *  it will OVERWRITE THE RECENT COMMANDS, so BEWARE.
 * \param newInput - a new character byte to add.
 * \return void
 */
void addToBuffer(char newInput){
    bufferStepThrough++;
    bytesInBuffer++;
    if(bufferStepThrough >= 10) bufferStepThrough = 0;
    commandBuffer[bufferStepThrough] = newInput;
}

/** \fn char readFromBuffer(void)
 * \brief returns the most recent command in the buffer.
 * \param void
 * \return void
 */
char readFromBuffer(void){
    while(bytesInBuffer == 0){}; //How can I get around needing this?
    char tmp = commandBuffer[bufferStepThrough];
    if(bufferStepThrough == 0) bufferStepThrough = 10 - 1;
    else bufferStepThrough--;
    bytesInBuffer--;
    return tmp;
}

/** \fn char isBufferEmpty(void)
 * \brief returns 1 if the buffer is empty, 0 if not.
 * \param void
 * \return char
 */
char isBufferEmpty(void){
    if(bytesInBuffer > 0) return 0;
    else return 1;
}

/** \fn char getBufferSize(void)
 * \brief returns the number of bytes in the buffer.
 * \param void
 * \return int
 */
int getBufferSize(void){
    return bytesInBuffer;
}

/** \fn ISR(USART0_RX_vect)
 * \brief Handles serial receive interrupts.
 * \param void
 * \return void
 */
ISR(USART_RX_vect){
    addToBuffer(UDR0); //Add to buffer
}

And it's working!

December 07, 2012
by Pew446
Pew446's Avatar

Ignore the pin definitions. I modified the ledarray.c and forgot to remove those.

December 08, 2012
by Pew446
Pew446's Avatar

I'm going to need to redo my circuit board. The microcontroller only outputs 1 volt, so I'm going to have to switch the positive and negative so that the pins are set low, and the MOC3041's get 5 volts directly from the USB cable, unless there is a way to up the voltage my microcontroller outputs. I need at least 1.25 volts to turn on the MOC3041. :/

December 08, 2012
by Rick_S
Rick_S's Avatar

Unless something is drawing way more current than it should, or the micro is damaged, the micro will put out 5 volts if powered by 5 volts. You aren't trying to drive this circuit from USB power are you?? If so, you are probably attempting to pull more than the USB is delivering. An external supply would better serve a stand alone project like this.

Your current limiting resistor size looks right, it should drop the current pull to about 12mA Well below the 15mA max for the opto-coupler. Also with all ports on, you are within the max for the micro with 72mA Max on PORTC and 24mA Max on PORTB. Totaling way less than both the port or chip max. This tells me you either have a short somewhere, or you are not getting enough current from the USB to keep the voltage up.

Since by default, USB supplies 100mA of current unless the device connected to it requests more (Which I highly doubt the UBS-Serial adapter does) you are most likely trying to draw more than it is putting out.

Just my 2 cents worth, YMMV,

Rick

December 08, 2012
by Pew446
Pew446's Avatar

Thanks again Rick, you've been a huge help. I'm going to attempt to power the chip with a 9-volt/reguator setup to see what happens. I am indeed powering the circuit via USB, so that may be the issue.

December 08, 2012
by Pew446
Pew446's Avatar

It still outputs 1 volt, so I am going to assume it is just a bad chip. Luckly I have 2 brand new 328p's, so I'll program one and see what happens.

December 08, 2012
by Pew446
Pew446's Avatar

Well that wasn't it either. Must be the code, drawing too much power. I'm not sure what would be causing that, though.

December 08, 2012
by Ralphxyz
Ralphxyz's Avatar

Pew446, test your mcu without your board connected to confirm you get 5 volts off an output pin!

Ralph

December 08, 2012
by Pew446
Pew446's Avatar

I have tried that, still only 1 volt. I also measured the voltage on another chip I use in my door, and it too outputs 1 volt. Either I'm making a mistake in all my coding, or maybe the capacitors/crystals I bought from Tayda are the wrong kind. These are the capacitors I use, and these are the crystals. They don't seem incorrect, but I use the same kind in both of the chips I've tested. Thanks

December 08, 2012
by Rick_S
Rick_S's Avatar

What do you get if you measure the power to the chip?? Are the pins steady on or cycling on/off giving you a false reading? Something isn't right somewhere.

December 08, 2012
by Pew446
Pew446's Avatar

I think my regulator must have been bad, I just tried a different one on my breadboard and now the pins output 5 volts! I'll try it on the board and let you guys know.

December 08, 2012
by Pew446
Pew446's Avatar

When connected to my breadboard, the chip outputs 5 volts, but when on the circuit board it only outputs 1. I am going to look over the board a bunch.. I must be missing something

December 08, 2012
by Pew446
Pew446's Avatar

I can't see anything wrong with the board. Everything is connected in the same spots as on the breadboard. I will probably tinker with the design and reprint it, maybe a trace broke somewhere.

December 08, 2012
by Ralphxyz
Ralphxyz's Avatar

Pew446, this sounds more like a short than a broken trace!! What is that blob of solder on the center right of the traces?

Ralph

December 08, 2012
by Pew446
Pew446's Avatar

If you are talking about the line of solder, that is just a bridge for a broken trace. I checked for continuity and the traces aren't touching. If you mean the small bridge from the capacitor to the ground wire, that's supposed to be there. I came up with another idea, instead of ruining another board, I'm just going to use a small breadboard glued to the center with the chip and such, then use wires to connect them to the right spots on the resistor/moc3041.

December 08, 2012
by Noter
Noter's Avatar

Could remove all your moc3041s from their sockets and put in one at a time to see if you can locate the problem that way? If it's a total load issue then at least a smaller number of them will work fine and you can work your way up to discover the maximum.

December 08, 2012
by Pew446
Pew446's Avatar

Noter wins the game. I turned on the pin that controls the first MOC3041, measured voltage, 1 volt. Take out the MOC3041, 4.5 volts. I'm not too sure what to do with this info though. Does this mean my controller can't handle the MOC3041? Or maybe it has been working all along? But that wouldn't make sense, because it won't turn on the lights, yet a 9 volt + regulator will..

December 08, 2012
by Pew446
Pew446's Avatar

4.3 volts actually.

December 08, 2012
by Noter
Noter's Avatar

If you really have 330 ohm resistors to the 4031's then that will be about 10ma each. Even so at 10ma each it may be too much for the power supplied by the USB cable. To run the mcu and all or even several the 4031's it will be better to use a 9v or 12v wall wart with a regulator for your power. With your multi-meter, you could measure the total current drawn with the usb 5v and then again from the 9v+regulator and see what the difference is to determine if the usb is able to provide enough power.

December 08, 2012
by Pew446
Pew446's Avatar

I just tried the USB cable, a 9volt and regulator, a 9 volt wall wart at 800 mA + regulator, and a 5 volt wall wart also at 800 mA. No matter which one I use, the chip only reads as outputting 4.3 volts when the 3041 is disconnected. When connected, it outputs 1 volt. I don't understand why the chip only outputs 4.3 volts and not a full 5 volts... when I connect a 9volt + regulator directly to the 330 ohm and ground, the light turns on just like it should. The chip just wont put out the full 5 volts. :/

December 08, 2012
by Noter
Noter's Avatar

I think it's because a pn junction has a voltage drop of about .7v and the chip uses a transistor to pull up the pin so the pin voltage is vcc less the pn junction drop. But your problem is not 4.3 volts, it's that you only have 1 volt under load and that does not provide enough current to light the led and turn on the lights.

Something is causing the chip to run out of power and that is why the output voltage drops to 1v (assuming you measure 1v at the pin on the mcu, be sure to measure both at the mcu and the 3041). It could be the load is drawing too much current or it could be a problem on the supply side. If you verify the load is drawing 10ma (and it probably is) then the problem must be on the supply side of the mcu.

Maybe the trace from the mcu to the 3041 cannot carry the current. Temporarily bypass it by touching a wire to the pin on the chip and the resistor.

Maybe the trace to vcc on the chip is too small or thin. Or the gnd trace could be the culprit. Try jumping power and gnd directly to the chip to bypass those traces and see if that makes a difference.

December 08, 2012
by Pew446
Pew446's Avatar

The load is drawing about 11ma, and I tried bridging the trace from the pin to the resistor with no luck. I tried bridging both VCC and GND of the wall wart to the mcu, and that also did nothing. I might try using a breadboard for the mcu, and instead of turning the pins high, turn them low, and have 5 volts from the wall wart to the resistors, and the GND of the 3041 to the pins on the mcu.

December 09, 2012
by Pew446
Pew446's Avatar

So I connected the 330 ohm to the 5 volts from the wall wart, then connected the ground of the 3041 to a pin on my mcu which I set low, and it does not work. However, when I move the pin from the mcu to the ground of the wall wart, it does work. I'm pretty confused.

December 09, 2012
by Pew446
Pew446's Avatar

Should pins set low be 0 volts? I'm reading 1 volt, but everything on Google says 0 volts.

December 09, 2012
by Rick_S
Rick_S's Avatar

I'll repeat what I said earlier on and what Noter has repeated a couple of times. The circuit as drawn should not exhibit what you are seeing. Current calculations as I said earlier are below both the port and whole chip limits and if good enough power is supplied should be sufficient to operate the opto-couplers.

  1. Double check your resistors feeding the opto-couplers to make sure they are 330 Ohms (Sometimes wire wound resistors can be tricky to read the color bands). Be sure to use your meter and be sure to pull the opto and power first.
  2. With the MCU, optos, and power all removed, check for continuity between the power and ground lines to make certain you have no shorts anywhere (you may hear a short beep when the filter cap charges and this is OK).
  3. Then check each trace from the MCU to it's designation on the corresponding opto to ground again checking for shorts.
  4. Check continuity for each trace between MCU pin and opto current limiting resistor.
  5. With everything back in place and power on, check the power at pins 7&8 of the micro, does it still read ~5V or is it down to 1V like your opto's?

You have something going on in your circuit, and problems are a common part of this hobby. Developing good, logical, troubleshooting skills is a must and is a learned skill. The thing with troubleshooting is to be methodical and do things one step at a time to eliminate possible causes. That is why I gave you the list above of things to check. If you start jumping around spot checking w/o checking thoroughly you are apt to miss something. Most likely when you do find your problem, it will be an "A-HA" moment and something simple. (At least I hope so)

Good luck,

Rick

December 09, 2012
by Pew446
Pew446's Avatar

I just checked everything you told me to. The resistors were 330 ohm, nothing was shorted, and the voltage at 7/8 reads ~5V. While checking my resistors I remembered the resistors on the instructable being carbon film, and I had ordered metal film resistors. I think the tolerance may be too low.

December 09, 2012
by Noter
Noter's Avatar

Are you saying there was 5V on the mcu power pins 7/8 and at the same time the output port for the lights is on and it has only 1v?

December 09, 2012
by Rick_S
Rick_S's Avatar

The tolerance on your resistors isn't an issue. There is something else going on that we aren't seeing if you are getting 5V into the mcu and only 1v out.

December 09, 2012
by Pew446
Pew446's Avatar

Right, 5 volts at 7/8 and only 1 volt at the output for the lights. Once I take out the 3041, breaking the circuit, I get 4.3 volts at the output for the lights. I have moved the mcu to a breadboard because the copper on the board has gotten pretty beat up, and I'll probably have to re-etch it at some point. I have the output soldered directly to the 330 ohm, and the ground soldered directly to pin 2 on the 3041, so the traces are useless as of now. I still get the same results though.

December 09, 2012
by Noter
Noter's Avatar

If you bypass the 3041 and put a 330 ohm resistor from the output pin to gnd for current of 13ma, does that also drop the pin voltage to 1v? And no other output pins are enabled during this test? And still 5v at 7/8?

Are you running a simple test program for this that does nothing other than set the output pin on?

December 09, 2012
by Pew446
Pew446's Avatar

After taking out the 3041 and using only the resistor, the voltage drops to 0.04V, and 7/8 is still 5V. All the pins are outputs, but I only have one of them connected, and it is the only pin high. I'm using my code above, but I am only sending 0xFF for the pin connected to the resistor, and the rest are 0x00.

December 09, 2012
by Noter
Noter's Avatar

It would be good to run simple test code that for sure turns the port on and nothing else. If for some reason your code is toggling the port that would give you a low voltage reading on your multimeter. For example if your output port is PB1 ... then measure and if you still have the problem it's time to try another chip.

#include <avr/io.h>

int main() {

    DDRB = _BV(PB1);
    PORTB = _BV(PB1);

    for(;;);

}
December 09, 2012
by Pew446
Pew446's Avatar

A-HA! :p I wrote Noter's simple code to my chip, and then nothing happened, so I found out my 9 volt was outputting nothing, and I opened up the connector to find the ground line had popped off. I re soldered that, and poof, the light lit up! So either I have faulty code, which seems more than likely, or my 9 volt connector has been on and off the whole time which is a lot less likely, especially since I have also tried wall warts and such with the same results.... so where did I go wrong in my code?

December 09, 2012
by Pew446
Pew446's Avatar

Oh, by the way, thanks very much guys!

December 09, 2012
by Pew446
Pew446's Avatar

I can verify it was my code, I just rewrote it to the chip and now it won't work!

December 09, 2012
by Pew446
Pew446's Avatar

A-HA! Again!

See, these lines:

DDRC |= ((1 << PC5) & (1 << PC4) & (1 << PC3) & (1 << PC2) & (1 << PC1) & (1 << PC0));
DDRB |= ((1 << PB5) & (1 << PB4));
PORTC &= ~((1 << PC5) & (1 << PC4) & (1 << PC3) & (1 << PC2) & (1 << PC1) & (1 << PC0));
PORTB &= ~((1 << PB5) & (1 << PB4));

All have & symbols where there should have been | symbols. Here is the correct code:

DDRC |= ((1 << PC5) | (1 << PC4) | (1 << PC3) | (1 << PC2) | (1 << PC1) | (1 << PC0));
DDRB |= ((1 << PB5) | (1 << PB4));
PORTC &= ~((1 << PC5) | (1 << PC4) | (1 << PC3) | (1 << PC2) | (1 << PC1) | (1 << PC0));
PORTB &= ~((1 << PB5) | (1 << PB4));

And it works perfectly. Thank you all for being so patient with me and helping out a TON! I'll try to get a video of my trees dancing to music sometime soon. :)

December 10, 2012
by Ralphxyz
Ralphxyz's Avatar

Definitely I want to see your dancing trees :-)

Ralph

December 22, 2012
by Pew446
Pew446's Avatar

Sorry it took so long. Here is the video.

It is a bit off sync, and a bit shaky, (my cousin was recording .-.) but it is very cool nonetheless, and I'm really glad it works. All the trees can be turned on at full brightness with no trouble at all. I love it! Now I need another project.. Oh, by the way, I will be entering this project into my school's Science Fair (as an Engineering project) Hopefully I will win a scholarship or something to help out in the future :)

December 22, 2012
by Rick_S
Rick_S's Avatar

Very EXCELLENT! Great job. What more can I say, but you did good man. Way to take a project from start to finish.Thumbs Up Cheers Drool Christmas_Tree

Rick

December 22, 2012
by Noter
Noter's Avatar

Totally COOL!

New project? I came across this the other day and maybe it will give you some ideas.

M4SONIC

Lauchpad How To

December 22, 2012
by Ralphxyz
Ralphxyz's Avatar

Pew446, Great, fabulous, neat, cool etc.

I love it!!

Now how about contributing an article to the Nerdkits Community Library.

I'd like to know more about the whole project like where did you start what did you base the PC code on? Of course I'd like to see the PC code and the mcu code.

How many trees do you have? Is each each tree a note?

Could you apply what you are doing on multiple trees to a single tree, you could vary the light intensity and do different strings.

I imagine you could also add strobe lights, that'd be cool.

Good job.

Ralph

December 22, 2012
by Pew446
Pew446's Avatar

I will definitely try to post an article. I don't feel like I have gone over what I am doing in this thread as much as asked for help, and it's the least I can do to give back to the community. :)

December 22, 2012
by Rick_S
Rick_S's Avatar

Ralph, he used Vixen software on the PC end. It's designed for synchronizing lights to music. You simply listen to the music and tag on/off times for each channel to create the show. The cool part I think about his project is the complete building of the serial driven lighting controller board which takes the serial output from vixen and drives the SSR's to turn on /off his tree lights.

Again great job.

Rick

December 22, 2012
by Ralphxyz
Ralphxyz's Avatar

Makes me want to do some Holiday decorations.

A deeper explanation would be appreciated.

Ralph

December 22, 2012
by pcbolt
pcbolt's Avatar

Well done, Pew!

Glad to see you got it all done before Christmas. Concept to completion in under a month? Wow. That would beat the pants off any science project I ever came up with. Hope you win and really hope you get the scholarship. Have a great holiday.

December 22, 2012
by Pew446
Pew446's Avatar

I wrote up an entry in the Library>Projects section. I don't know how clear it is, so if you find it hard to follow, feel free to edit it to better word it, or ask me and I'll help clear it up and modify the entry so others may understand it better. Let me know what you think :)

December 22, 2012
by Pew446
Pew446's Avatar

Thank you all for being so kind and supportive, by the way!

Post a Reply

Please log in to post a reply.

Did you know that hobby servos are controlled through a particular kind of PWM (Pulse Width Modulation) signal? Learn more...