2

I have made my custom serial(UART) library. So I made uart.h and uart.cpp files as following.

uart.h

#ifndef UART_H
#define UART_H

#include <avr/io.h>
#include <stdlib.h>

//creating class named uart
class uart{

  public:

    // creating constructor
    uart(void);

    //function to start uart at given baudrate
    void start(int baudrate);

    // function to read uart input
    unsigned char read();

    // function to print data on serial monitor
    void print(unsigned char data);

    // function to print string on serial monitor
    void print(char *string);

    // function to print data with given base
    void print(unsigned char data,unsigned int base);

    //function to print data like printf
    void print(char* str,unsigned char data);

    // function to read data by printing string
    unsigned char read(char* string);

};

#endif

uart.cpp

#include "uart.h"

uart::uart(void);

void uart::start(int baudrate){

    long BAUDRATE = ((F_CPU)/(baudrate*16UL)-1);

    UBRR0H = (BAUDRATE >> 8);

    UBRR0L = BAUDRATE;

    // enable recieve and transmit
    UCSR0B |= 1 << RXEN0 | 1 << TXEN0;

    // data size is equal to 8 bits
    UCSR0C |= 1 << UCSZ00 | 1 << UCSZ01;
}

unsigned char uart::read(){

    //wait until receive complete.
    while(!(UCSR0A & (1 << RXC0)));

    // return received byte
    return UDR0;
}


void uart::print(unsigned char data){

    // wait until UDR is empty
    while(!(UCSR0A & (1 << UDRE0)));

    //place data into UDR
    UDR0 = data;
}

void uart::print(unsigned char* string){

    int index = 0;

    // print string character by character
    while(string[index] != '\0'){

        print(string[index]);

        index++;
    }
}

void uart::print(unsigned char data,unsigned int base){


    //buffer to store converted data
    char buffer[10];

    //convert data to ascii
    itoa(data,buffer,base);

    //print converted data
    print(buffer);
}

// function to print data like printf(%d,data);
void uart::print(char* str,unsigned char data){

    int index = 0;

    // print string character by character
    while(str[index] != '\0'){

        if(str[index] == '%'){

            index++;

            if(str[index]=='d') print(data,10);

            else if(str[index] == 'b') print(data,2);

            else if(str[index] == 'x') print(data,16);

            index++;
        }
        print(str[index]);

        index++;
    }
}


unsigned char uart::read(unsigned char* string){
    // print given string
    print(string);
    // return read char
    return(read());
}

test.cpp

#include "uart.h"
int main(){
    uart.start(9600);
    uart.print("Hello world\n");
}

Now all of above function works if i write all function and declations in single .h file and don't divide my header file in .h and .cpp file. if i compile this given program i get following error.

Error

src/uart.cpp
src/uart.cpp:3:16: error: declaration of 'uart::uart()' outside of class is not definition [-fpermissive]
 uart::uart(void);
                ^
src/uart.cpp:39:6: error: prototype for 'void uart::print(unsigned char*)' does not match any in class 'uart'
 void uart::print(unsigned char* string){
      ^
In file included from src/uart.cpp:1:0:
src/uart.h:31:7: error: candidates are: void uart::print(char*, unsigned char)
  void print(char* str,unsigned char data);
       ^
src/uart.h:28:7: error:                 void uart::print(unsigned char, unsigned int)
  void print(unsigned char data,unsigned int base);
       ^
src/uart.h:25:7: error:                 void uart::print(char*)
  void print(char *string);
       ^
src/uart.cpp:30:6: error:                 void uart::print(unsigned char)
 void uart::print(unsigned char data){
      ^
src/uart.cpp:91:15: error: prototype for 'unsigned char uart::read(unsigned char*)' does not match any in class 'uart'
 unsigned char uart::read(unsigned char* string){
               ^
In file included from src/uart.cpp:1:0:
src/uart.h:34:16: error: candidates are: unsigned char uart::read(char*)
  unsigned char read(char* string);
                ^
src/uart.cpp:20:15: error:                 unsigned char uart::read()
 unsigned char uart::read(){
               ^
.build/uno/Makefile:166: recipe for target '.build/uno/src/uart.o' failed
make: *** [.build/uno/src/uart.o] Error 1
Make failed with code 2

PS: I use inotool to compile and upload my programs to arduino and it works great. So you will find src/ in error.

Please help me. I'm stuck here.

4
  • You don't even need the constructor in the first place if it does nothing Commented Jun 13, 2015 at 14:43
  • 1
    Instead of implementing all the variations of print(), you should just subclass Print and only implement size_t write(uint8_t). This way you avoid code duplication, as there are many classes in the Arduino libraries inheriting Print. Commented Jun 13, 2015 at 16:49
  • I am making these libraries for learning purpose.i have worked with AVR microcontollers but arduino libraries amazed me.i like its code structure its very well managed.but i found one disadvantage is that memory consumption with its libs.any way thanks for suggestion. Commented Jun 14, 2015 at 5:53
  • If you solved the question, please mark the asnwer that asnwer the question or make your own answer. And edit the topic removing the [SOLVED] Commented Jun 18, 2015 at 14:42

1 Answer 1

3
uart::uart(void);

That's a prototype, not a function. It needs a body. Also, using "void" to say "no parameters" is really confusing. Better to leave it out all together.

uart::uart() {
}

uart.start(9600);
uart.print("Hello world\n");

uart is a class, not an instance. You should be using uart::start(9600) if you first set your functions to be static, or create an instance from the uart class:

uart myUart;

int main() {
    myUart.begin(9600);
    myUart.print("Hello world\n");
}

Watch your random unsigned entries...

uart.h:
unsigned char read(char* string);

uart.c:
unsigned char uart::read(unsigned char* string){

... There may be others too.

5
  • Thank you for your reply.i will correct my mistakes as you mentioned.and let me see if it works or not. Commented Jun 13, 2015 at 14:36
  • It may take a few iterations. Can't see the wood for the trees at the moment ;) Get rid of these errors first and we'll see where we can go from there. Commented Jun 13, 2015 at 14:37
  • is it mandatory to use constructor in class,in my case uart::uart(){ }. Commented Jun 13, 2015 at 14:56
  • If you don't specify a constructor a "default" empty constructor will be provided. It's good to be explicit and provide one thought. You could have it all in the header file though for simplicity... uart() {} Commented Jun 13, 2015 at 14:57
  • thank you so much @Majenko ,now my header file is working.thank you so so so much..i was stuck from past two days on this error Commented Jun 13, 2015 at 15:07

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.