Thread: ultrasonic ranger programming

  1. #1
    Registered User
    Join Date
    Jun 2010
    Posts
    2

    ultrasonic ranger programming

    hi, i am building an atmega8 based ultrasonic ranger. i am writing the program in C using winavr. the program is showing some warning and i could not get rid of them. plz help...


    Code:
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include <avr/iom8535.h>
    #include <string.h>
    
    
    /* Defines
     **********************************************************************/
    #define FOSC              16000000L
    #define BAUDRATE          38400L
    #define UBRR              ((FOSC / (16 * BAUDRATE)) - 1)
    
    #define NUM_40KHZ_PULSES  5  /* Always does one less pulse. */
    
    #define TRUE              1
    #define FALSE             0
    
    #define F_CPU             4000000
    #define K_DELAY_100us     F_CPU/61349
    #define K_DELAY_1ms       F_CPU/6013
    #define K_DELAY_10ms      F_CPU/600
    
    
    /* Custom Types
     **********************************************************************/
    typedef unsigned char  U8;
    typedef unsigned int   U16;
    typedef char           S8;
    typedef int            S16;
    typedef unsigned char  BOOL;
    
    
    /* Function Prototypes
     **********************************************************************/
    void usart_init      (void);
    void usart_tx_byte   (U8 tx_reg);
    void usart_tx_str    (char *str);
    
    
    /* Global Variables
     **********************************************************************/
    U8 pulse_count;
    U16 distance;
    volatile BOOL pulses_sent;
    volatile BOOL echo_received;
    volatile BOOL echo_missed;
    
    
    
    /* FUNCTION : usart_init
     *
     * Initialise the USART.
     **********************************************************************/
    void usart_init(void)
    {
        UCSRB = _BV(RXEN) | _BV(TXEN) | _BV(RXCIE);
        UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);
        UBRRH = (U8)UBRR >> 8;
        UBRRL = (U8)UBRR;
    }
    
    
    
    /* FUNCTION : usart_tx_byte
     *
     * Wait for the USART to become available and then send out tx_reg.
     **********************************************************************/
    void usart_tx_byte(U8 tx_reg)
    {    
        while(!(UCSRA & (1 << UDRE)))
        {
            /* Make sure GCC doesn't optimize this while loop out. */
            asm volatile("nop");
        }
        
        UDR = tx_reg;
    }
    
    
    
    /* FUNCTION : usart_tx_str
     *
     * Send the null terminated string pointed to by *str out of the serial
     * port.
     **********************************************************************/
    void usart_tx_str(char *str)
    {
        char *ptr;
        
        for(ptr = str; *ptr != '\0'; *ptr++)
            usart_tx_byte(*ptr);
    }
    
    
    
    /* FUNCTION : 
     *
     * (15 + t*( ((K_DELAY_100us-1)*6)+5 ))
     **********************************************************************/
    void delay_100us(U16 t)
    {
        volatile U16 i;
    
        while(t > 0)
        {
            for(i=0; i < K_DELAY_100us; i++)
            {
            }
            
            --t;
        }
    }
    
    
    
    /* FUNCTION : 
     *
     * (15 + t*( ((K_DELAY_1ms-1)*6)+5 ))
     **********************************************************************/
    void delay_1ms(U16 t)
    {
        volatile U16 i;
    
        while(t > 0)
        {
            for(i=0; i < K_DELAY_1ms; i++)
            {
            }
            
            --t;
        }
    }
    
    
    
    /* FUNCTION : SIGNAL(SIG_UART_RECV)
     *
     * USART RX interrupt.  Just send back whatever is received.
     **********************************************************************/
    SIGNAL(SIG_UART_RECV)
    {
       usart_tx_byte(UDR);
    }
    
    
    
    /* FUNCTION : SIGNAL(SIG_OVERFLOW2)
     *
     * At the end of each PWM pulse this interrupt occurs.  Either get 
     * ready for the next pulse or stop the PWM (the correct number of
     * pulses has been sent).
     **********************************************************************/
    SIGNAL(SIG_OVERFLOW2)
    {    
        if(pulse_count == 0)
        {            
            pulse_count = NUM_40KHZ_PULSES;  /* Get ready for the next set of pulses. */
            TCCR2 = TCCR2 & (~0x07);  /* Stop the PWM generation. */
            
            pulses_sent = TRUE;
        }
        else
        {
            TCNT2 = 130;
            pulse_count--;
        }
    }
    
    
    
    /* FUNCTION : SIGNAL(SIG_OVERFLOW1)
     *
     * The Capture/Compare timer has overflowed, therefore no echo was
     * received in time.
     **********************************************************************/
    SIGNAL(SIG_OVERFLOW1)
    {
        TCNT1 = 0;
        echo_missed = TRUE;
    }
    
    
    
    /* FUNCTION : SIGNAL(SIG_INPUT_CAPTURE1)
     *
     * A rising edge has been detected by the Capture/Compare module.  This
     * is the start of the echo.
     **********************************************************************/
    SIGNAL(SIG_INPUT_CAPTURE1)
    {    
        distance = ICR1;
        echo_received = TRUE;
    }
    
    
    
    /* FUNCTION : main
     *
     * Main implementation.
     **********************************************************************/
    int main(void)
    {    
        char *string;
            
        
        cli();
        usart_init();
        
    
        /* D7(PWM OUT)  D6(CAPTURE IN) */
        DDRD  = 0xBF;
        PORTD = 0x00;
            
    
        while(1)
        {        
            echo_received = FALSE;
            echo_missed   = FALSE;
            pulses_sent   = FALSE;
            pulse_count   = NUM_40KHZ_PULSES;
            
            
            /* PWM Output.
               The overflow interrupt counts the number of PWM pulses
               sent out and disables the PWM channel when the correct
               number have gone. */
            TCCR2 = _BV(WGM20)    /* PWM Waveform. */
                  | _BV(CS20)     /* No Prescaler. */
                  | _BV(COM21);   /* Clear on up counting. */
            OCR2 = 50;            /* 50% Duty Cycle on the PWM signal. */
            
            
            TIMSK = _BV(TOIE2);    /* Overflow Interrupt (PWM Output). */
            sei();
            
            
            /* wait for the pulses to go. */
            while(pulses_sent == FALSE)
            {
            }
            
            
            /* Make sure we don't pick up any cross talk between
               the transmitter and receiver. */
            delay_100us(2);
            
            cli();
                  
                
            /* Counter Input Capture.
               Start a timer and generate an interrupt on the first 
               rising edge of the received ultrasonic echo. */
            TCCR1B = _BV(ICES1)   /* Interrupt on the rising edge. */
                   | _BV(ICNC1)   /* Enable the noise canceller. */ 
                   | _BV(CS11)
                   | _BV(CS10);   /* CS10 and CS11 create a prescaler of 64. */
                   
            TCNT1 = 0;
            TIFR  = _BV(TOV1)     /* Enable an Input Capture Overflow Interrupt. */
                  | _BV(ICF1);    /* Enable an Input Capture Interrupt. */
            
            TIMSK = _BV(TOIE1)    /* Overflow Interrupt (Capture Input). */
                  | _BV(TICIE1);  /* Capture Interrupt. */
        
            sei();
    		        /* Wait for some echo activity. */
            while(echo_received == FALSE && echo_missed == FALSE)
            {
            }
                
            
            /* Convert the echo to a distance and send it out of the
               serial port. */
            if(echo_received == TRUE)
            {
                /* Speed of sound = 1cm every 30us
                   Timer Prescaler = 64
                   External Crystal = 16MHz
                   Timer Updates Every (1/16MHz) * 64 = 4uS
                   
                   distance = (TIMER_VALUE * 4) / 30 / 2 = TIMER_VALUE / 15 */
                distance = distance / 15;
                
                sprintf(string, "%dcm\r", distance);
                usart_tx_str(string);
            }
            
            
            /* Create a long delay before starting again.  This is so 
               we don't detect any double echos. */
            delay_1ms(1000);
        }
        
        
        return 0;
    }
    it is showing these errors:
    c:/winavr-20100110/lib/gcc/../../avr/include/avr/signal.h:36:2: warning: #warning "This header file is obsolete. Use <avr/interrupt.h>."
    In file included from test3.c:4:
    c:/winavr-20100110/lib/gcc/../../avr/include/avr/iom8535.h:47:4: error: #error "Attempt to include more than one <avr/ioXXX.h> file."
    test3.c:19:1: warning: "F_CPU" redefined
    <command-line>: warning: this is the location of the previous definition
    test3.c: In function 'usart_tx_str':
    test3.c:91: warning: value computed is not used
    test3.c: In function 'main':
    test3.c:285: warning: implicit declaration of function 'sprintf'
    test3.c:285: warning: incompatible implicit declaration of built-in function 'sprintf'
    make.exe: *** [test3.o] Error 1

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    > #include <avr/signal.h>
    /avr/signal.h:36:2: warning: #warning "This header file is obsolete. Use <avr/interrupt.h>."
    Since you already include the suggested replacement, maybe you should just delete this line?

    > #include <avr/iom8535.h>
    /avr/include/avr/iom8535.h:47:4: error: #error "Attempt to include more than one <avr/ioXXX.h> file."
    Perhaps io.h itself does all the magic of working out which chip-specific io file to include, so that you don't have to (delete this line as well)
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jun 2010
    Posts
    2
    thanks,
    what about the 'sprintf' function?
    >test3.c:285: warning: implicit declaration of function 'sprintf'
    >test3.c:285: warning: incompatible implicit declaration of built-in function 'sprintf'

    how to overcome these?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    You should #include <stdio.h>
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. SRF02 ultrasonic sensor
    By quachtinh in forum C Programming
    Replies: 1
    Last Post: 11-13-2009, 06:51 AM