Hi,
i'm trying to create a rc esc/servo controller:
- visualize setting via LED brightness via P0
- output an RC servo signal on P1: PWM, 20ms period, ratio 5-10% = 1ms-2ms pulse
- on/off signal input on P2
- rpm up/down button on P3/P5
- on/off button on P4
i want to use the avr pwm. to archieve the above pwm parameters, i've to set up timer1 manually (2048 prescale, OCR1C for period, OCR1A for ratio)
pwm generation works as expected for led (although perceived brightness isn't optimal) and servo control.
on/off input works as expected.
up/down buttons work as expected.
the on/off button on P4 doesn't work.
using P3 or P5 for this functionality works as expected.
i think i configured P4 properly as input, disabled pwm1b etc
what am i missing?
-------------------------------------------------------------------------------------------
#include
#include
#define DEBOUNCE_TICKS 5
#define SERVO_PERIOD 160
#define SERVO_MIN 7
#define SERVO_MAX 15
#define SERVO_SCALE 29
int rpm;
boolean forceOff;
boolean forceBtn;
int forceCnt;
boolean upBtn;
boolean dnBtn;
int upCnt;
int dnCnt;
void setup( void) {
rpm = 90;
forceOff = false;
forceBtn = false;
forceCnt = 0;
upBtn = false;
dnBtn = false;
upCnt = 0;
dnCnt = 0;
// use to
pinMode( 0, OUTPUT);
pinMode( 1, OUTPUT);
// configure pwm1a, prescale 2048, period @ocr1c, high @zero, low @ocr1a
TCCR1 = (1<< PWM1A) | (1<< COM1A1) | (0<< COM1A0) | (1<< CS13) | (1<< CS12) | (0<< CS11) | (0<< CS10);
// trying to disable pwm1b, this should free pb4
GTCCR = (0<< PWM1B) | (0<< COM1B1) | (0<< COM1B0);
// set period / 5%
OCR1C = SERVO_PERIOD;
OCR1A = SERVO_MIN;
// configure pwm0a, no prescale
TCCR0A = (1<< COM0A1) | (0<< COM0A0) | (1<< WGM01) | (1<< WGM00);
TCCR0B = (0<< WGM02) | (0<< CS02) | (0<< CS01) | (1<< CS00);
pinMode( 2, INPUT);
pinMode( 3, INPUT);
pinMode( 4, INPUT);
pinMode( 5, INPUT);
// enable pullups
digitalWrite( 2, HIGH);
digitalWrite( 3, HIGH);
digitalWrite( 4, HIGH);
digitalWrite( 5, HIGH);
}
// val range is 0-255, scaled down to timers
// -pwm0A with 0-100% and timer1
// -pwm1A with 5-10%/20ms
void setPos( int val) {
OCR1A = 7 + val / SERVO_SCALE;
// OCR1B = 7 + val / 28;
OCR0A = val;
}
boolean debounce( int pin, boolean* state, int* count) {
boolean temp = ( digitalRead( pin) == LOW);
if ( temp != *state) {
*count = DEBOUNCE_TICKS;
*state = temp;
} else {
if ( *count >= 0) (*count)--;
if ( *count == 0) {
return true;
}
}
return false;
}
void loop( void) {
while( true) {
// toggle on/off
// this doesn't work
// if ( debounce( 4, &forceBtn, &forceCnt) && forceBtn) forceOff = ! forceOff;
// rpm up
// pin 3 works, pin4 down't
if ( debounce( 3, &upBtn, &upCnt) && upBtn) {
if ( rpm < 226) rpm += SERVO_SCALE;
else rpm = 255;
}
// rpm down
if ( debounce( 5, &dnBtn, &dnCnt) && dnBtn) {
if ( rpm > SERVO_SCALE) rpm -= SERVO_SCALE;
else rpm = 0;
}
// use pin as external on/off
if ( forceOff || digitalRead( 2) == LOW) {
setPos( 0);
} else {
setPos( rpm);
}
_delay_ms( 50);
}
}