// HellaSweep // sample code to experiment with the Hella VNT actuator. // by jason pepas (jasonpepas@gmail.com) // released under the GPLv2. // parts of the program taken from Ken Shirriff's excellent article on arduino PWM stuff: // http://arcfn.com/2009/07/secrets-of-arduino-pwm.html // min and max duty cycles which the actuator will respond to. #define DUTY_MIN 15 #define DUTY_MAX 98 uint8_t duty_cycle = DUTY_MIN; // min and max periods which the actuator will respond to. #define PERIOD_MIN 106 #define PERIOD_MAX 115 uint8_t period = 110; void setup() { pinMode(3, OUTPUT); // OC2B // we are using waveform generator mode "7", which is fast pwm with TOP = OCRA. // see the atmega168 datasheet page 157, table 17-8. //TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); // actually, I want "inverting" mode, because I am now driving an n-channel mosfet. TCCR2A = _BV(COM2B1) | _BV(COM2B0) | _BV(WGM21) | _BV(WGM20); TCCR2B = _BV(WGM22) | _BV(CS22) | _BV(CS21) | _BV(CS20); OCR2A = period; // sets TOP (thus, frequency). 111 should be just over 140hz. OCR2B = (uint8_t)(period * (duty_cycle / 100.0)); // sets duty cycle. } boolean walk_duty = true; boolean duty_climbing = true; boolean walk_period = false; boolean period_climbing = false; void loop() { if (walk_duty == true) { if (duty_cycle < DUTY_MIN) duty_cycle = DUTY_MIN; if (duty_cycle > DUTY_MAX) duty_cycle = DUTY_MAX; if (duty_cycle == DUTY_MAX) { duty_climbing = false; } if (duty_cycle == DUTY_MIN) { duty_climbing = true; } if (duty_climbing == true) { duty_cycle++; } else // (duty_climbing == false) { duty_cycle--; } OCR2A = period; OCR2B = (uint8_t)(period * (duty_cycle / 100.0)); // sets duty cycle. } if (walk_period == true) { if (period < PERIOD_MIN) period = PERIOD_MIN; if (period > PERIOD_MAX) period = PERIOD_MAX; if (period == PERIOD_MAX) { period_climbing = false; } if (period == PERIOD_MIN) { period_climbing = true; } if (period_climbing == true) { period++; } else // (period_climbing == false) { period--; } OCR2A = period; OCR2B = (uint8_t)(period * (duty_cycle / 100.0)); // sets duty cycle. } delay(20); }