Projekte:rennauto
Controlling an RC car using microcontrollers.
Inhaltsverzeichnis |
The plan
- Use a microcontroller to talk to the RC car's servos.
- 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