NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Servo code execution

February 11, 2011
by missle3944
missle3944's Avatar

Hi all, I am working on the servo code and everything works great but I cannot figure out how I could type a character and have the mcu to automaticly run the servo in a loop. What I mean is that I want to type "scan" and then the servo will keep rotating until I enter another command. So far this is what my code is.

    // servosquirter.c
// for NerdKits with ATmega168
// mrobbins@mit.edu

#define F_CPU 14745600

#include <stdio.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"

// PIN DEFINITIONS:
//
// PB3 - pump control
// PB2 - servo signal (OC1B)

void pwm_set(uint16_t x) {
  OCR1B = x;
}

#define PWM_MIN 1300
#define PWM_MAX 4450
#define PWM_START 2765
void pwm_init() {
  // setup Timer1 for Fast PWM mode, 16-bit
  // COM1B1 -- for non-inverting output
  // WGM13, WGM12, WGM11, WGM10 -- for Fast PWM with OCR1A as TOP value
  // CS11 -- for CLK/8 prescaling

  OCR1A = 36864;    // sets PWM to repeat pulse every 20.0ms
  pwm_set(PWM_START);
  TCCR1A = (1<<COM1B1) | (1<<WGM11) | (1<<WGM10);
  TCCR1B = (1<<WGM13) | (1<<WGM12) | (1<<CS11);

  // each count is 8/14745600 = 0.5425us.
  // so 1.0ms = 1843.2
  //    1.5ms = 2764.8
  //    2.0ms = 3686.4
  //   20.0ms = 36864
}

int main() {
  // init LCD
  lcd_init();
  FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
  lcd_write_string(PSTR("*******Servo********"));
  lcd_line_four();
  lcd_write_string(PSTR(" Type c for instru."));

  // init serial port
  uart_init();
  FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
  stdin = stdout = &uart_stream;

  // set PB2,PB3 as output
  DDRB |= (1<<PB2) | (1<<PB3);

  // init PWM
  pwm_init();

  uint16_t pos = PWM_START;
  char tc;
  while(1) {
    pwm_set(pos);
    // Print the current servo position to the LCD.
    lcd_line_two();
    fprintf_P(&lcd_stream, PSTR("servo position: %d "), pos);

    // Wait for a character to be sent to the serial port.
    tc = uart_read();
    if(tc=='d') {pos+= 25;
            DDRC |= (1<<PC3);
  // turn on LED
    PORTC |= (1<<PC3);

    // turn off LED
    PORTC &= ~(1<<PC5);

    // turn of green Led
     PORTC &= ~(1<<PC5);

     PORTC &= ~(1<<PC4);
            }
    if(tc=='a') {pos-= 25;
    DDRC |= (1<<PC5);
    // turn on LED
    PORTC |= (1<<PC5);

     PORTC &= ~(1<<PC3);

        PORTC &= ~(1<<PC4);
        }

    // bounds checking

    if (tc=='c'){
    printf_P(PSTR("COMMAND LIST: \n Type K for fastest \n Type A for slow \n Type B for normal \n \n \n \n \n  "), pos);
        scanf;

        }

    if(pos > PWM_MAX) {pos = PWM_MAX;
    DDRC |= (1<<PC4);
    // turn on LED
    PORTC |= (1<<PC4);

        }

    if (tc=='k') pos+=1000;
    if (tc=='j') pos-=1000;
    if (tc=='b') pos+=100;
    if (tc=='v') pos-=100;

    if(pos < PWM_MIN) {pos = PWM_MIN;

    DDRC |= (1<<PC4);
    // turn on LED
    PORTC |= (1<<PC4);
        }

 // Print the current servo position to the serial port.
    printf_P(PSTR("The position %d\r\n"), pos);
  }

  return 0;
}

Post a Reply

Please log in to post a reply.

Did you know that the printf format string "%.3f" will show three digits after the decimal point? Learn more...