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.

  • You don't even need the constructor in the first place if it does nothing – Anonymous Penguin Jun 13 '15 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. – Edgar Bonet Jun 13 '15 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. – Mohit Tank Jun 14 '15 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] – Butzke Jun 18 '15 at 14:42
2
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.

  • Thank you for your reply.i will correct my mistakes as you mentioned.and let me see if it works or not. – Mohit Tank Jun 13 '15 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. – Majenko Jun 13 '15 at 14:37
  • is it mandatory to use constructor in class,in my case uart::uart(){ }. – Mohit Tank Jun 13 '15 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() {} – Majenko Jun 13 '15 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 – Mohit Tank Jun 13 '15 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.