Don't ad-block us - support your favorite websites. We have safe, unobstrusive, robotics related ads that you actually want to see - see here for more.
0 Members and 1 Guest are viewing this topic.
Cool, both links were really cool. I knew the ATMega8 was limited to 3 PWM outputs. I kinda forgot you could do software PWM. What's the difference anyway? I read somewhere that timers are seperate circuits within mcus. Is this correct? Then assuming that those PWMs are directly controlled by the timers, I can see why the PWM outputs are limited. Software PWM works simply by using a timer, but using the software to turn the light on and off, instead of the timer doing it directly I'm guessing?
However, if you just want to use hardware pwm, you are limited to 3 leds (The atmega8 has only 3 pwm channels).
Hi,That should be enough. If every third LED in the "sky" is connected to the same one, then _which_ one is on can be selected by other outputs.
Can you elaborate? I see what you are saying that I really only NEED 3 outputs.
I think I figured it out. Since I wouldn't be using many of the MCUs outputs, I could simply have two LEDs between each "group" controlled by software PWM. These LEDs would be connected to the MCU output, then to ground (basically.) Then as the lights would get ready to move from one "group" to another, the two LEDs in the middle would be sort of a buffer. When the last LED in the first group turns off, the first LED in the second group turns on.
...Period_begin: Output_AD = Flag_AD ;Where Flag_AD is a Boolean...Period_done: Flag_AD = NOT Flag_AD...
Hi,Here's a solution.Each timer can control more than one output and having 2 outputs from each makes it possible to switch cleanly.
So basically I'm still using only the 3 hardware PWM, except I'm splitting each signal. (Kinda like a Y adapter for RCA cables).
Now... if I just knew how to set up the pins on the MCU... I have yet to find an all inclusive tutorial that says "If you want to do this with a certain pin, you have to look up this bit value in the datasheet and write some code like this..." etc. etc...
Universal "dimming" dial. (Controlled by a potentiometer probably, which regulates the overall PWM, maybe a factor in mathematical equation
Modular. Basically I'd have ports in the back to add more LEDs, then a multiposition switch to tell the micro controller how many LEDs were plugged in. The micro controller would then take into account those extra LEDs in the "moon moving" algorithim. (Meaning the LEDs would be lit for shorter amounts of time, since there are more of them)
Time controlled On/Off switch (Turn on at night, off during day)
Universal Voltage control (Some LEDs are 2.5v, some are 3.7. I don't know if controlling each one individually would be possible, but I think if I was able to just regulate the voltage applied to all LEDs that are used, I'd be good, cause most people would use the same LEDs throughout their lighting. So all LED output would either be 2.5 or 3.7, not a mix of both for example. I thought of doing this with a <1k pot and a variable voltage controller, but I think using the microcontroller would be easier.)
Hi,This (pdf) tutorial may be helpfull if you can live with the poor English and the strange web linking in some places of the background.
About the "features" you want.QuoteTime controlled On/Off switch (Turn on at night, off during day)You could add an RTC or make an equivalent in software, but a much easier approach is to use an LDR mounted so it can sense outside light and let it start when it gets to a certain level of darkness.
QuoteUniversal Voltage control (Some LEDs are 2.5v, some are 3.7. I don't know if controlling each one individually would be possible, but I think if I was able to just regulate the voltage applied to all LEDs that are used, I'd be good, cause most people would use the same LEDs throughout their lighting. So all LED output would either be 2.5 or 3.7, not a mix of both for example. I thought of doing this with a <1k pot and a variable voltage controller, but I think using the microcontroller would be easier.)LEDs are current controlled devices and the simplest way of controlling this current is with a resistor (as you see it in the schematic).If you used LEDs with different voltage drops, you would go with individual constant current devices.
The '1' is there to set bit WGM11 = 0 and WGM10=1these are 2 of the 4 bits that set the waveform generation mode.The other 2 bits are in TCCR1B
My first question, why so many different types of PWM?
Other modes like phase/frequency correct tend to need a 16 bit timer and use an ICR register (along with prescaler) to set top. This gives you precise control over the frequency as well as the duty cycle. The difference between them is quite subtle and, as you've said, only tend to make a difference when controlling (precisely) DC motors.
Why is there 8, 9 and 10 bit PWM? (I think it's to get more accurate (I.E. higher resolution) timings, 10 bit is slower than 8 bit?, since TOP is the number of clock cycles per time period of PWM, as top increases the PWM slows down but gets more accurate?)
Correct me if I'm wrong, but could I use the 5 row down, 0101, for my application?
How do I actually change the dimming of the LED, is it simply changing the duty cycle? Or is it changing the frequency at which it blinks? (Former is easier, correct?)
As for the resistors in Soeren's diagram, I can calculate the value by using this formula... R = (Vs - Vl)/I I did it for mine, and got a value of roughly 100. R=(5-2.5)/.025 I was guessing for the voltage and current, as the LEDs didn't come with a data sheet. (I know the stats for the ones I'm using). Does this sound right?
An 8 bit PWM will give you steps of 78.1µs (12.8 step/ms)An 9 bit PWM will give you steps of 39.1µs (25.6 steps/ms)An 10 bit PWM will give you steps of 19.5µs (51.2 steps/ms) = almost useable (depending on purpose of course)
You also need to Google 'perceived intensity brightness' - ie a linear change to your duty cycle does not result in a linear change in brightness as far as your eye is concerned. This also varies depending on the color of LED you are using.
So if I choose one of those modes, I'm stuck with a certain frequency, but I can change the duty cycle. But if I use the mode where OCR1A is the TOP value, I can change the frequency, but not the duty cycle... (In the datasheet it says that if OCR1A is used as the TOP value, it runs at a 50% duty cycle). So I'm assuming you'd say go with the 10 bit pwm?
QuoteYou also need to Google 'perceived intensity brightness' - ie a linear change to your duty cycle does not result in a linear change in brightness as far as your eye is concerned. This also varies depending on the color of LED you are using.If using PWM doesn't change brightness that we can notice with our eyes, then how do people make the percieved brightness change in videos like this...
What Webbot said was just that your perception of brightness doesn't follow a linear scale.
I've successfully dimmed an LED using a freq of 1000 Hz (actually 977.5 Hz), a 10 bit Phase correct PWM, and a prescaler of 8. I had to take the duty cycle down to 7% to actually "see" some dimming. I'm sure I can configure it some other way so I get more duty cycle to play with, if you know what I mean. (Maybe if I lower the frequency?)
This puzzles me. So basically even though we're linearly adjusting the parameters that affect brightness, the brightness change won't LOOK linear? (I'm guessing it falls off toward the low and high end, so we have to adjust more to get the same amount of brightness "change")
EDIT: Yes webbot I googled, but it's late, and I didn't see any result that jumped out at me, and I didn't feel like reading papers, so I just decided to guess
int main(){ unsigned int i,j; DDRB|=(1<<PORTB1); //Define port B1 as output TCCR1A=0xA1; //Set B1 as PWM and set 2 of 4 registers for PWM type OCR1A=25; //Set duty cycle (OCR1A/TOP)= Duty cycle, which changes brightness TCCR1B=0x01; //Set 2 of 4 registers for PWM type and 3 registers for prescaler for(j=1;j<10;j++) //My infinite loop { for(i=1;i<200;i++) { OCR1A=i; //Loop to increase LED brightness (This doesn't work) pause(); } for(i=200;i>1;i--) { OCR1A=i; //Loop to decrease LED brightness (This doens't work) pause(); } j=j-1; //This keeps my j For loop infinite }}
int main(){ unsigned int i,j; DDRB|=(1<<PORTB1); //Define port B1 as output DDRB|=(1<<PORTB2); //Define port B2 as output TCCR1A=0xA1; //Set B1 and B2 as PWM and set 2 of 4 registers for PWM type OCR1A=200; //Set duty cycle (OCR1A/TOP)= Duty cycle, which changes brightness OCR1B=2; TCCR1B=0x01; //Set 2 of 4 registers for PWM type and 3 registers for prescaler for(i=1;i<50000;i++)//Pauses for a second or so pause(); OCR1A=2; //Switches the brightness of the two LEDs OCR1B=200;}
int main(){ unsigned int i,j; DDRB|=(1<<PORTB1); //Define port B1 as output DDRB|=(1<<PORTB2); //Define port B2 as output TCCR1A=0xA1; //Set B1 as PWM and set 2 of 4 registers for PWM type for(j=1;j<10;j++) //Repeat the brightness switch 9 times { OCR1A=200; //Set duty cycle (OCR1A/TOP)= Duty cycle, which changes brightness OCR1B=2; TCCR1B=0x01; //Set 2 of 4 registers for PWM type and 3 registers for prescaler for(i=1;i<50000;i++)//Pause for a second or so pause(); OCR1A=2; OCR1B=200; //Switch the brightness of the two LEDs }}
int main(){ unsigned int i,j; DDRB|=(1<<PORTB1); //Define port B1 as output DDRB|=(1<<PORTB2); //Define port B2 as output TCCR1A=0xA1; //Set B1 as PWM and set 2 of 4 registers for PWM type OCR1A=200; //Set duty cycle (OCR1A/TOP)= Duty cycle, which changes brightness OCR1B=2; TCCR1B=0x01; //Set 2 of 4 registers for PWM type and 3 registers for prescaler pause2(); OCR1A=2; OCR1B=200; //Switch the brightness of the two LEDs for(i=1;i<200;i++) { OCR1A=i; OCR1B=200-i; //Dim one LED and brighten other LED pause2(); }}
void pause(){ unsigned int k; for(k=1;k<20000;k++) { k++; k--; } for(k=1;k<20000;k++) { k++; k--; } for(k=1;k<20000;k++) { k++; k--; }}
int main(){ unsigned int i; setup_pwm(); for(i=1;i<1000;i++) { if (i<=200) //LED1 brightness up OCR1A++; else if ((i>200) && (i<=400)) //LED1 brightness down OCR1A--; if ((i>100) && (i<=300)) //LED2 brightness up OCR1B++; else if ((i>300) && (i<=500)) //LED2 brightness down OCR1B--; if ((i>200) && (i<=400)) //LED3 brightness up OCR2++; else if ((i>400) && (i<=600)) //LED3 brightness down OCR2--; if (i == 600) //Makes this loop go on forever i = 0; pause2(); //Pause so that I can actually see the dimming }}
The weird thing is, when I step through the program, OCR2 only gets up to 23... I have no idea why, but it works? I know that OCR2 is an 8 bit value, and OCR1A and OCR1B are 16 bit, but why does OCR2 act weird like that?
int main(){ unsigned int i; setup_pwm(); ADMUX= 0x21; ADCSRA= 0xC8; SREG=0x80; for(i=1;i<1000;i++) { if (i<=200) //LED1 brightness up OCR1A++; else if ((i>200) && (i<=400)) //LED1 brightness down OCR1A--; if ((i>100) && (i<=300)) //LED2 brightness up OCR1B++; else if ((i>300) && (i<=500)) //LED2 brightness down OCR1B--;// if ((i>200) && (i<=400)) //LED3 brightness up// OCR2++; // else if ((i>400) && (i<=600)) //LED3 brightness down// OCR2--; if (i == 600) //Makes this loop go on forever i = 0; pause2(); //Pause so that I can actually see the dimming if (i%10==0) ADCSRA |= 0x40; } }ISR(ADC_vect){ int valu; valu = ADCH; OCR2 = valu;}