A note on your LED driver. The base voltage is the sum of LED voltage + voltage drop across resistor + base-emitter voltage. If you're running off a 3V supply that should remain somewhat below the 3V to have some base current. A 2V LED + 0.7V base-emitter will only leave 0.2V for the resistor. At 200\$\Omega\$ that's 1mA, which explains why the LED lights so dim.
It's also possible that the transistor isn't saturated. For 20mA LED current at an \$H_{FE}\$ of 100 you need 200\$\mu\$A base current. If there's only 100mV across the base resistor that will give you only 100\$\mu\$A.
Actually in the current schematic the base resistor is superfluous. The resistance seen from the base is the emitter resistance times \$H_{FE}\$, so with an \$H_{FE}\$ of 100 the Arduino will see the 200\$\Omega\$ as 20k\$\Omega\$!
I would suggest to move at least the 200\$\Omega\$ resistor to the transistor's collector side.
Yes! When you configure the fuses to make the controller run from an external clock, you also need that external clock for reprogramming.
It is important to notice that I tested this with an Arduino configured as ISP (In circuit Serial Programmer), which does not attempt to provide an external clock to the device that is being programmed. Other programmers may do this, but that would depend on the programmer. ISP is most common way of programming these devices, but there are other programmers too. Fact is that the device in itself needs an external clock. Unsure for a parallel programmer. A High Voltage programmer can do without an external clock.
I didn't test this with an ATmega, but rather with an ATtiny45, but both AVR's are very similar in these aspects.
This is what I did:
- I wrote a small program to output a 1kHz square wave output (listing below);
- I selected 2MHz clock and programmed
.low = 0x61
Notice that the fuse settings may be controller specific, so this is the setting for ATtiny45;
- The controller outputs a frequency of 1kHz, as expected;
- I selected 1.8432MHz for clock and programmed
.low = 0xe0
;
- Output frequency dropped to 0Hz until I connected the oscillator, then it jumped up to 1kHz, again as expected;
- I detached the external oscillator (output: 0Hz);
- Tried programming the device, resulting in:
avrdude: Device signature = 0xffffff
avrdude: Yikes! Invalid device signature.
Double check connections and try again, or use -F to override this check.
- I reattached the external oscillator and programed the device for 2MHz the following result:
avrdude done. Thank you.
- and of course the ouput was back at 1kHz.
So in conclusion:
If you program the fuses for using an external clock, then you also need an external clock to program the device.
/*
(c) copyright 2013 by J.P. Hendrix
*/
#include <avr/io.h>
#include <util/delay.h>
#define _BS(bit) ( 1 << ( bit ) )
#define _BC(bit) ( 0 << ( bit ) )
/*
ATtiny45
pin function name ISP SPI XO I2C/TWI comparator ADC pin chg
1 !RESET PB5 ADC0 PCINT5 dW
2 extOscPin PB3 XTAL1 CLKI !OC1B ADC3 PCINT3
3 PB4 XTAL2 CLKO OC1B ADC2 PCINT4
4 GND GND
5 PB0 MOSI DI SDA AIN0 OC0A !OC1A AREF PCINT0
6 outputPin PB1 MISO DO AIN1 OC0B OC1A PCINT1
7 PB2 SCK USCK SCL T0 ADC1 PCINT2 INT0
8 VCC VCC
*/
const uint8_t outputPin = _BS( PB1 );
const uint8_t extOscPin = _BS( PB3 );
#ifdef F_CPU
#if ( F_CPU == 1000000 )
// 1MHz
FUSES = { .low = LFUSE_DEFAULT , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };
#elif ( F_CPU == 1600000 )
// 1.6MHz => ATtiny15 Compatibilty Mode
#warn "ATtiny15 Compatibility Mode changes Timer1 behaviour!"
FUSES = { .low = 0x63 , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };
#elif ( F_CPU == 2000000 )
// 2MHz
FUSES = { .low = 0x61 , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };
#elif ( F_CPU == 6400000 )
// 6.4MHz => ATtiny15 Compatibility Mode
#warn "ATtiny15 Compatibility Mode changes Timer1 behaviour!"
FUSES = { .low = 0xe3 , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };
#elif ( F_CPU == 8000000 )
// 8MHz
FUSES = { .low = 0xe2 , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };
#elif ( F_CPU == 16000000 )
// 16MHz
FUSES = { .low = 0xe1 , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };
#else
// #error "F_CPU setting not recognized."
// External oscillator selected
FUSES = { .low = 0xe0 , .high = HFUSE_DEFAULT , .extended = EFUSE_DEFAULT , };
#endif
#else
#error "F_CPU not defined."
#endif
void setup( void ) { // Initialize all hardware
DDRB = outputPin; // Data Direction Register Port B
}
int main( void ) {
setup(); // Initialize the hardware
while ( 1 ) {
_delay_us( 500 );
PORTB ^= outputPin;
}
}
Best Answer
You might need to slow down the ADC. The analog to digital converter runs at half the system clock frequency by default so at 6MHz the ADC's input clock is at 3MHz. Setting
ADCSRA |= 2
(for the ATmega328, datasheet section 23.9.2, page 265) divides the clock by 4 instead of by 2. 12MHz / 4 = 6MHz / 2 = 3MHz.