servo control
This commit is contained in:
parent
54ab1ba86d
commit
bc920907bd
3 changed files with 77 additions and 16 deletions
|
@ -12,12 +12,14 @@ bench = false
|
|||
[dependencies]
|
||||
panic-halt = "0.2.0"
|
||||
ufmt = "0.2.0"
|
||||
nb = "0.1.2"
|
||||
embedded-hal = "0.2.3"
|
||||
nb = "1"
|
||||
embedded-hal = "1"
|
||||
|
||||
[dependencies.avr-hal-generic]
|
||||
git = "https://github.com/rahix/avr-hal"
|
||||
|
||||
[dependencies.arduino-hal]
|
||||
git = "https://github.com/rahix/avr-hal"
|
||||
rev = "3e362624547462928a219c40f9ea8e3a64f21e5f"
|
||||
features = ["arduino-uno"]
|
||||
|
||||
# The latest releases of `proc-macro2` do not support the rust toolchain that
|
||||
|
|
27
src/main.rs
27
src/main.rs
|
@ -1,27 +1,28 @@
|
|||
#![no_std]
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
#![no_main]
|
||||
|
||||
use panic_halt as _;
|
||||
mod servo;
|
||||
use servo::Servo;
|
||||
|
||||
#[arduino_hal::entry]
|
||||
fn main() -> ! {
|
||||
let dp = arduino_hal::Peripherals::take().unwrap();
|
||||
let pins = arduino_hal::pins!(dp);
|
||||
|
||||
/*
|
||||
* For examples (and inspiration), head to
|
||||
*
|
||||
* https://github.com/Rahix/avr-hal/tree/main/examples
|
||||
*
|
||||
* NOTE: Not all examples were ported to all boards! There is a good chance though, that code
|
||||
* for a different board can be adapted for yours. The Arduino Uno currently has the most
|
||||
* examples available.
|
||||
*/
|
||||
// configure timer for servos
|
||||
pins.d9.into_output();
|
||||
pins.d10.into_output();
|
||||
let tc1 = dp.TC1; // 250kHz
|
||||
tc1.icr1.write(|w| w.bits(4999)); // 250kHz/5000 = 50Hz
|
||||
tc1.tccr1a.write(|w| w.wgm1().bits(0b10).com1a().match_clear());
|
||||
tc1.tccr1b.write(|w| w.wgm1().bits(0b11).cs1().prescale_64());
|
||||
|
||||
let mut led = pins.d13.into_output();
|
||||
let carriage = &tc1.ocr1a; // pin 9
|
||||
let claw = &tc1.ocr1b; // pin 10
|
||||
|
||||
loop {
|
||||
led.toggle();
|
||||
arduino_hal::delay_ms(1000);
|
||||
carriage.set_speed(1.0);
|
||||
arduino_hal::delay_ms(20);
|
||||
}
|
||||
}
|
||||
|
|
58
src/servo.rs
Normal file
58
src/servo.rs
Normal file
|
@ -0,0 +1,58 @@
|
|||
use arduino_hal::pac::tc1::OCR1B;
|
||||
use arduino_hal::pac::tc1::OCR1A;
|
||||
|
||||
const MIN: u16 = 100; // *4us = .4ms
|
||||
const MAX: u16 = 700; // *4us = 2.8ms
|
||||
const RANGE: u16 = MAX-MIN;
|
||||
|
||||
pub(crate) trait Servo {
|
||||
/// -1.0 full reverse, 1.0 full forward
|
||||
fn set_speed(&self, speed: f32) {
|
||||
self.set_duty(calculate_duty(speed));
|
||||
}
|
||||
|
||||
fn set_duty(&self, duty: u16);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
/// -1.0 full reverse, 1.0 full forward
|
||||
fn calculate_duty(speed: f32) -> u16 {
|
||||
let speed = speed / 2.0 + 0.5;
|
||||
let duty = speed * RANGE as f32 + MIN as f32;
|
||||
duty as u16
|
||||
}
|
||||
|
||||
impl Servo for OCR1A { // pin 9
|
||||
fn set_duty(&self, duty: u16) {
|
||||
self.write(|w| w.bits(duty));
|
||||
}
|
||||
}
|
||||
|
||||
impl Servo for OCR1B { // pin 10
|
||||
fn set_duty(&self, duty: u16) {
|
||||
self.write(|w| w.bits(duty));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
// unit tests don't run on avr-hal-template projects, could be due to target rules, could be
|
||||
// no_std. to troubleshoot later
|
||||
extern crate std;
|
||||
use crate::servo::calculate_duty;
|
||||
|
||||
#[test]
|
||||
fn forward() {
|
||||
assert_eq!(MAX, calculate_duty(1.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reverse() {
|
||||
assert_eq!(MIN, calculate_duty(-1.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stopped() {
|
||||
assert_eq!(MIN+RANGE/2, calculate_duty(0.0));
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue