Projekte:rennauto

Aus Chaostreff Tübingen
Wechseln zu: Navigation, Suche

Controlling an RC car using microcontrollers.

Inhaltsverzeichnis

The plan

  1. Use a microcontroller to talk to the RC car's servos.
  2. Use something more powerful (Raspberry?) to generate control commands for the microcontroller.

Current stage

Talk to the hardware test
Projekt Source GitHub waynix rennAuto

Stats

  • Motor Controller
    • Atmega48
    • 4KB Flash
    • 256 bytes ROM
    • 512 bytes RAM
    • max 23 Input Output Pins
    • UART
    • PWM servo signal(Up to ten servos)
    • Three (two Free) Timers(One Timer 250KHz used for PWM)
    • I2C
    • SPI
    • Analog Digital Converter
    • Breadboard for fast prototyping
    • 16MHZ Oscillator
    • 38600 Baud PC Communication(1MHZ max)

Knowlege Base

Servos

A normal RC Servo does expect a command every 20ms.

  • This command is a 5 to 7V level Pulse Width Modulation(PWM) Signal.
  • The length of the high voltage levels controls the servo.
  • The length may vary between 1ms and 2ms.
  • It would be nice to control the length of the PWM singal in 256=2^8 States.
  • So one step should be the difference of 1ms/256States~3,9µs

AVR Timers

The Timers on the Atmega platform can be used to measure the Time and generate Interrupts to control the Servo.

The Atmega48 has three timers

Timer 0 and 1 share the same Prescaler wich can divide the CPU clock by 1,8,64,256,1024.
Timer 1 is a 16bit timer, Timer 0 and 2 are 8bit Timers.
Timer 2 has its own Prescaler that can divide the CPU clock by 1, 8, 32, 64, 128, 256, 1024.

Timers have several modes the mode used when controlling the servos is "Clear Timer on Compare Match mode". The main thing every timer does is increasing or decreasing the value of the TCNTn register by one each time it is activated. When the timer is set to "Clear Timer on Compare Match mode" and the value of the TCNTn register is equal to the value of OCR2A, then the counterregister TCNTn is Reset and an Interrupt is generated by the timer. Our Microcontroller runs on 16MHZ
when the Prescaler is set to 64 each Timerstep is 4 milliseconds long. That is as close as one can get to 3.9ms when using only the prescaler.

Clear Timer on Compare Match Mode(CTC)

This mode does count up until it reaches the value in the register OCRA the the ISR(TIMER1_COMPA_vect) is triggerd and the counter is reset

Configuration:

Register Bit Wert Beschreibung
TCCR2A WGM10 0
TCCR2A WGM11 0
TCCR2B WGM12 1
TCCR2B WGM13 0 for "Clear Timer on Compare Match mode" in Timer 1.
TCCR2B CSS10 1
TCCR2B CSS11 1
TCCR2B CSS12 0 timer 2 clock select(system clock divided by 64 = 250kHz)
OCR2A 16bit register 0x0000 - 0xFFFF CTC comparison value
TIMSK2 OCIE2A 1 Output Compare Match A Interrupt Enable
SREC Interrupt_bit 1 enable Interrupt globally

Eventuell hat es auch vorteile den vorteiler auf 64 zu setzen dann braucht man eventuell keinen seperaten counter für die 20 ms wenn man den 16bit Timer1 nimmt.(5000 schritte) der einstellbare bereich läge dann zwischen 1,024 und 2,048ms (1ms+4ms*256Schritte)

Configuration Setup

//WGM10 - 13 ctc
TCCR1A = (0 << WGM10) | (0 << WGM11);
TCCR1B = (0 << WGM13) | (1 << WGM12);
// divide system clock by 64
TCCR1B |= (0 << CS12) | (1 << CS11) | (1 << CS10);
TIMSK1 = (1 << OCIE1A);

UART/RS232

UART(Universal Asynchronous Receiver Transmitter) is a protocol for the bytewise serial transmission of Information. One implementation of this protocol is RS232. The UART implementation on Microcontrollers use the same method for information transmission bus other voltage levels. The main advantage of an uart is that no clock generating data line ist needed. Only three connections are needed a normal full duplex UART connection. One UART package may consist from five to nine bits and optionally one parity bit, it begins with a logic '0' as start bit and one or two logic '1' as end bit.

Possible Bitrates with an 16MHZ Oscillators are[1]:

9600bps
19200bps
38400bps
76800bps
250000bps
500000bps
1Mbps

Konfiguration

//Baud Rate 38400Bit/s (at 16MHZ clock)
UBRR0H = (unsigned char)0;
UBRR0L = (unsigned char)25;
UCSR0A = (0 << U2X0) 	//Double Data Rate
//Multiprocessor Communication Mode
        | (0 << MPCM0);
//State: (1= on 0 =off)
UCSR0B = (1 << RXEN0) //Receiver
       | (1 << TXEN0)//Transmitter
//Interrupts:(1= on 0 =off)
       | (1 << RXCIE0) //Receive
       | (0 << TXCIE0) //Transmit
       | (0 << UDRIE0) //Send buffer free
//Bit Count:8
       | (0 << UCSZ02);
UCSR0C = (1 << UCSZ01)
       | (1 << UCSZ00)
//CRC Mode: even
       | (1 << UPM01)
       | (0 << UPM00)
//Stop Bits: 1bit = 0 2bits = 1
       | (0 << USBS0)
//USART Mode: asynchron
       | (0 << UMSEL01)
       | (0 << UMSEL00);

ADC Analog Digital Converter

  • Analog digital wandler setup:
//       Enable      Start Conversion   Auto Trigger   ADC Interrupt CPU Clock Divider(prescaler)
ADCSRA = (1 << ADEN) | (1 << ADSC)    | (0 << ADATE) | (1 << ADIE) | (0 << ADPS2)| (0 << ADPS1)| (0 << ADPS0);
//            Reference Voltage       left Aligned     Source Pin PORT A 0
ADMUX = (0 << REFS0) | (0 << REFS1)   | (1 << ADLAR) | (0 << MUX3) | (0 << MUX2) | (0 << MUX1) | (0 << MUX0);
  • Start measurement
ADCSRA |= (1 << ADSC);
  • ADC Interrupt
ISR(ADC_Vect)
{
  servo1 = ADCH;
}

Weblinks

Timer im Mikrocontroller wiki
OpenCV
Servos bei den Roboternetzen

Meine Werkzeuge
Namensräume
Varianten
Aktionen
Navigation
Werkzeuge