[CODE][C] Simple code for atmega328 to control an L298N or L293D based car.

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is some simple code I used to control a cheap two motor (1 drive and 1 turning) R/C car (the kind that uses a simple motor with a stopper for the turning mech) over serial using an ATMega328. It should (obviously) work on the ATMega328p (from an arduino). I set the fuses such that it uses internal 8mhz oscillator. It will work well with serial comm to a raspberrypi for higher level and network based control.

 

You need to connect the enable pin of the drive motor to PD6, c1 and c2 from drive motor to PD5 and PD7, and connect c3 and c4 from the drive motor to PD3 and PD4.

 

Serial communication is described at the top of the file. All commands are 1 character long. SpeedSet command needs to be followed by a char with value between 0-255. I wasn't sure the two varibles need to be volatile, but I made them so just in case.

 

 

UPDATE 1: Fixed critical errors in code. Thanks to clawson

/*
 * Atmega328 Car control
 *
 * Author: Aditya Goturu <aditya3098@gmail.com>
 * 
 * Clock: 8MHz Internal
 * Pinouts:
 *
 * PD6: PWM Speed Control
 * PD5: Drive1
 * PD7: Drive2
 *
 * PD3: Dir1
 * PD4: Dir2
 */
#define F_CPU 8000000UL
#include<avr/io.h>
#include<util/delay.h>

#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU/(USART_BAUDRATE*16UL)))-1)

#define BV(bit) (1 << bit)
#define stb(byte, bit) (byte |= BV(bit))
#define clb(byte, bit) (byte &= ~BV(bit))
#define tgb(byte, bit) (byte ^= BV(bit))

#define CMD_DFW 100 //d
#define CMD_DBW 101 //e
#define CMD_DTG 102 //f
#define CMD_TRI 103 //g
#define CMD_TLE 104 //h
#define CMD_TFW 105 //i
#define CMD_SPU 106 //j
#define CMD_SPD 107 //k
#define CMD_HLT 108 //l
#define CMD_SPS 109 //m
#define CMD_NOP 110 //n

uint8_t speed=0;
uint8_t incmd;

int main(void) {

  /* Initialization */

  // Serial Comm:

  UCSR0B |= (1<<RXEN0)  | (1<<TXEN0);
  UCSR0C |= (1<<UCSZ00) | (1<<UCSZ01);
  UBRR0H  = (BAUD_PRESCALE >> 8);
  UBRR0L  = BAUD_PRESCALE;

  // Pinmodes:

  stb(DDRD,3);
  stb(DDRD,4);
  stb(DDRD,5);
  stb(DDRD,6);
  stb(DDRD,7);

  // Direction and drive init:

  clb(PORTD,3);
  clb(PORTD,4);

  clb(PORTD,5);
  stb(PORTD,7);

  // PWM Initialization:
  
  OCR0A = 0;
  TCCR0A |= (1 << COM0A1);
  TCCR0A |= (1 << WGM01) | (1 << WGM00);
  TCCR0B |= (1 << CS01);
  
  /* Loop */

  while(1) {

    while( ( UCSR0A & ( 1 << RXC0 ) ) == 0 ){}
    incmd = UDR0;
    
    if(incmd != CMD_NOP) {
    
      switch(incmd) {
        
        case CMD_DFW:
          clb(PORTD,5);
          stb(PORTD,7);
          break;
        
        case CMD_DBW:
          stb(PORTD,5);
          clb(PORTD,7);
          break;
        
        case CMD_DTG:
          tgb(PORTD,5);
          tgb(PORTD,7);
          break;
        
        case CMD_TRI:
          clb(PORTD,3);
          stb(PORTD,4);
          break;
        
        case CMD_TLE:
          stb(PORTD,3);
          clb(PORTD,4);
          break;
        
        case CMD_TFW:
          clb(PORTD,3);
          clb(PORTD,4);
          break;
        
        case CMD_SPU:
          speed++;
          OCR0A = speed;
          break;
        
        case CMD_SPD:
          speed--;
          OCR0A = speed;
          break;
        
        case CMD_HLT:
          speed = 0;
          OCR0A = speed;
          break;
        
        case CMD_SPS:
          while( ( UCSR0A & ( 1 << RXC0 ) ) == 0 ){}
          speed = UDR0;
          OCR0A = speed;
          break;
      }

    }

  }

  return 0;

}

 

The day microsoft makes a product that doesn't suck, is the day they make a vacuum cleaner.

Last Edited: Mon. Apr 27, 2015 - 11:52 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is problem??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There is no problem. I just wanted to leave it out there as it was my first avr c program and I spent many hours on it. Hopefully someone will find it useful.

The day microsoft makes a product that doesn't suck, is the day they make a vacuum cleaner.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But it's not really a "Tutorial" is it? The idea of this forum is you write an article to try and teach someone some AVR/programming technique by giving step by step guidance.

 

Your post here is more appropriate to be included in "Projects" linked from the main bar at the top of the page.

 

Moderator.

 

PS Oh and you have made an error. F_CPU *must* be defined before the inclusion of <util/delay.h> not after it.

 

Also that whole program is based on a variable called "incmd" yet nothing ever assigns a value to it - so it will always hold 0

 

And if I'm being completely pedantic the interface to main is "int main(void)" not "int main()".

 

Oh and you use "volatile" yet this code does not have multiple paths of execution.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Holy crap, that was buggy. Sorry. I will debug it and post the better version in a few minutes.

 

 

Edit: Can you please move this thread to the Projects section?

The day microsoft makes a product that doesn't suck, is the day they make a vacuum cleaner.

Last Edited: Mon. Apr 27, 2015 - 11:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Not possible - Projects is not a "forum" as such. You need to visit yourself and [Create New Project]

 

But to be brutally honest this code just isn't fit for publishing as either a project or a tutorial yet anyway.

 

The idea of those areas is to post stuff that you've worked on for some time, tested, honed, re-tested, re-honed until you have something you feel is totally complete and others would enjoy without having any issues about things they still need to fix and so on.

 

Give it a few months, add some features, test it to death. Then post it as a project.

 

If you want to post it as a project now but make it clear "this is still work in development" or even "here's something I'm working on does anyone else want to pitch in and assist me with making this as good as it can possibly be?" then a far better platform for that is:

 

http://spaces.atmel.com

 

When you create a project there one of the many things you get to set is:

 

 

where you can actually tell others how "complete" you think the code is.

 

(actually looking at some of the other projects on Spaces it would appear that not everyone bothers to edit this to set the current state of their projects - shame sad)