dhenry:
A 1k resistor is likely too small. I would go with 10k or 100k if possible.
10k or higher is not possible without additional buffering of the output signal, because of the impedance of the load (see circuit)
I use this sketch:
//generate multiple ppm output
//pin configuration
#define PWM_PORT1 PORTB
#define PWM_DDR1 DDRB
#define PWM_PORT2 PORTD
#define PWM_DDR2 DDRD
#define PWM0 (1<<0)
#define PWM1 (1<<1)
#define PWM2 (1<<2)
#define PWM3 (1<<3)
#define PWM4 (1<<4)
#define PWM5 (1<<5)
#define PWM6 (1<<2)
#define PWM7 (1<<3)
#define PWM8 (1<<4)
#define PWM9 (1<<5)
#define PWM10 (1<<6)
#define PWM11 (1<<7)
//set pwm duration for each bit
#define PWM_Bit (PWM_50us) //duration of 1 bit
//pin configuration
//defining timing constants
#define PWM_ms (F_CPU / 64 / 1000) //milli seconds, 64:1 prescaler
#define PWM_1ms (PWM_ms)
#define PWM_500us (PWM_1ms / 2)
#define PWM_250us (PWM_500us / 2)
#define PWM_100us (PWM_500us / 5)
#define PWM_50us (PWM_500us / 10)
#define PWM_2ms (PWM_1ms * 2)
#define PWM_5ms (PWM_1ms * 5)
#define PWM_10ms (PWM_1ms * 10)
//duration examples for 12 channels
unsigned char duration[]={
0, //expected output: 0 / 31 * 5v
5, //expected output: 5 / 31 * 5v
10, //expected output: 10 / 31 * 5v
14, //expected output: 14 / 31 * 5v
18, //expected output: 18 / 31 * 5v
23, //expected output: 23 / 31 * 5v
31, //expected output: 31 / 31 * 5v
5, //expected output: 5 / 31 * 5v
10, //expected output: 10 / 31 * 5v
14, //expected output: 14 / 31 * 5v
18, //expected output: 18 / 31 * 5v
23}; //expected output: 23 / 31 * 5v
//tmr1 ctc isr
ISR(TIMER1_COMPA_vect) {
static unsigned char index = 0; //index
//update the period
if (index) OCR1A = OCR1A * 2;
else OCR1A = PWM_Bit;
//change the pins
if (duration[0] & (1<<index)) PWM_PORT1 |= PWM0; //set pwm0
else PWM_PORT1 &=~PWM0; //clear pwm0
if (duration[1] & (1<<index)) PWM_PORT1 |= PWM1; //set pwm1
else PWM_PORT1 &=~PWM1; //clear pwm1
if (duration[2] & (1<<index)) PWM_PORT1 |= PWM2; //set pwm2
else PWM_PORT1 &=~PWM2; //clear pwm2
if (duration[3] & (1<<index)) PWM_PORT1 |= PWM3; //set pwm3
else PWM_PORT1 &=~PWM3; //clear pwm3
if (duration[4] & (1<<index)) PWM_PORT1 |= PWM4; //set pwm4
else PWM_PORT1 &=~PWM4; //clear pwm4
if (duration[5] & (1<<index)) PWM_PORT1 |= PWM5; //set pwm5
else PWM_PORT1 &=~PWM5; //clear pwm5
if (duration[6] & (1<<index)) PWM_PORT2 |= PWM6; //set pwm6
else PWM_PORT2 &=~PWM6; //clear pwm6
if (duration[7] & (1<<index)) PWM_PORT2 |= PWM7; //set pwm7
else PWM_PORT2 &=~PWM7; //clear pwm7
if (duration[8] & (1<<index)) PWM_PORT2 |= PWM8; //set pwm8
else PWM_PORT2 &=~PWM8; //clear pwm8
if (duration[9] & (1<<index)) PWM_PORT2 |= PWM9; //set pwm9
else PWM_PORT2 &=~PWM9; //clear pwm9
if (duration[10] & (1<<index)) PWM_PORT2 |= PWM10; //set pwm10
else PWM_PORT2 &=~PWM10; //clear pwm10
if (duration[11] & (1<<index)) PWM_PORT2 |= PWM11; //set pwm11
else PWM_PORT2 &=~PWM11; //clear pwm11
//update index
index += 1; // incrment index
if (index == 5) index = 0; //wrap around index
}
//set up the timer1, 64:1 prescaler
void tmr1_init(unsigned short period) {
TCCR1B &=~0x07; //stop tmr1
//set up tccr1a
TCCR1A = (0<<COM1A1) | (0<<COM1A0) | //com1a10 = 0b00, normal operations
(0<<COM1B1) | (0<<COM1B0) | //com1b10 = 0b00, normal operations
(0<<WGM11) | (0<<WGM10); //wgm2..0 = 0b0100, top at OCR1A
TCCR1B = (0<<ICNC1) | (0<<ICES1) | //disable input capture noise canceller and input capture edge select
(0<<WGM13) | (1<<WGM12) | //wgm3..0 = 0b0100, top at OCR1A
(0<<CS12) | (1<<CS11) | (1<<CS10); //cs2..0 = 0b0011, 64:1 prescaler
TCCR1C = 0x00;
//reset the timer/counter
TCNT1 = 0x0000; //reset the timer
//load the period
OCR1A = period;
//reset the flag
TIFR1 |= (1<<OCF1A);
//enable the interrupt
TIMSK1 |= (1<<OCIE1A);
}
void setup(void) {
//initialize the output pins
PWM_PORT1 |= PWM0 | PWM1 | PWM2 | PWM3 | PWM4 | PWM5 ; //set the pins
PWM_DDR1 |= PWM0 | PWM1 | PWM2 | PWM3 | PWM4 | PWM5 ; //set up the pins for output
PWM_PORT2 |= PWM6 | PWM7 | PWM8 | PWM9 | PWM10 | PWM11 ; //set the pins
PWM_DDR2 |= PWM6 | PWM7 | PWM8 | PWM9 | PWM10 | PWM11 ; //set up the pins for output
//set up the timer
tmr1_init(PWM_Bit);
//enable interrupt
sei();
}
void loop(void) {
}
