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]
|
[dependencies]
|
||||||
panic-halt = "0.2.0"
|
panic-halt = "0.2.0"
|
||||||
ufmt = "0.2.0"
|
ufmt = "0.2.0"
|
||||||
nb = "0.1.2"
|
nb = "1"
|
||||||
embedded-hal = "0.2.3"
|
embedded-hal = "1"
|
||||||
|
|
||||||
|
[dependencies.avr-hal-generic]
|
||||||
|
git = "https://github.com/rahix/avr-hal"
|
||||||
|
|
||||||
[dependencies.arduino-hal]
|
[dependencies.arduino-hal]
|
||||||
git = "https://github.com/rahix/avr-hal"
|
git = "https://github.com/rahix/avr-hal"
|
||||||
rev = "3e362624547462928a219c40f9ea8e3a64f21e5f"
|
|
||||||
features = ["arduino-uno"]
|
features = ["arduino-uno"]
|
||||||
|
|
||||||
# The latest releases of `proc-macro2` do not support the rust toolchain that
|
# 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]
|
#![no_main]
|
||||||
|
|
||||||
use panic_halt as _;
|
use panic_halt as _;
|
||||||
|
mod servo;
|
||||||
|
use servo::Servo;
|
||||||
|
|
||||||
#[arduino_hal::entry]
|
#[arduino_hal::entry]
|
||||||
fn main() -> ! {
|
fn main() -> ! {
|
||||||
let dp = arduino_hal::Peripherals::take().unwrap();
|
let dp = arduino_hal::Peripherals::take().unwrap();
|
||||||
let pins = arduino_hal::pins!(dp);
|
let pins = arduino_hal::pins!(dp);
|
||||||
|
|
||||||
/*
|
// configure timer for servos
|
||||||
* For examples (and inspiration), head to
|
pins.d9.into_output();
|
||||||
*
|
pins.d10.into_output();
|
||||||
* https://github.com/Rahix/avr-hal/tree/main/examples
|
let tc1 = dp.TC1; // 250kHz
|
||||||
*
|
tc1.icr1.write(|w| w.bits(4999)); // 250kHz/5000 = 50Hz
|
||||||
* NOTE: Not all examples were ported to all boards! There is a good chance though, that code
|
tc1.tccr1a.write(|w| w.wgm1().bits(0b10).com1a().match_clear());
|
||||||
* for a different board can be adapted for yours. The Arduino Uno currently has the most
|
tc1.tccr1b.write(|w| w.wgm1().bits(0b11).cs1().prescale_64());
|
||||||
* examples available.
|
|
||||||
*/
|
|
||||||
|
|
||||||
let mut led = pins.d13.into_output();
|
let carriage = &tc1.ocr1a; // pin 9
|
||||||
|
let claw = &tc1.ocr1b; // pin 10
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
led.toggle();
|
carriage.set_speed(1.0);
|
||||||
arduino_hal::delay_ms(1000);
|
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