-2

I'm programming for Arduino and since I'm a beginner when I get this error message I'm unable to interpret it in order to solve it.

"C:\Users\VITOR~1.NUN\AppData\Local\Temp\ccmmwX2d.ltrans0.ltrans.o: In function setup': ccmmwX2d.ltrans0.o:(.text+0x16a): undefined reference toregistrador_nivel' C:\Users\VITOR~1.NUN\AppData\Local\Temp\ccmmwX2d.ltrans4.ltrans.o: In function AutoCampLib::Registrador::debug(char*)': ccmmwX2d.ltrans4.o:(.text+0xae0): undefined reference toregistrador_nivel' collect2.exe: error: ld returned 1 exit status"

This is my lib :

    #ifndef LIBAC_H
#define LIBAC_H
#define DEBUG
/***************************************************/
/********************Bibliotecas********************/
/***************************************************/
/*           Biblioteca padrão do Arduino          */
#include <Arduino.h>
/* Bibliotecas de data/hora para módulo DS1307 RTC */
#include <Wire.h>
#include <RTClib.h>
#include <Time.h>
#include <TimeLib.h>
#include <TimeAlarms.h>


/* Bibliotecas de leitura e escrita para módulo SD */
#include <SD.h>
#include <SPI.h>
/*    Biblioteca do módulo ultrassônico HC-SR04    */
#include <Ultrasonic.h>
/*    Biblioteca de Lista Encadeada    */
#include <LinkedList.h>
/*    Biblioteca de Threads    */
#include "Thread.h"
#include "ThreadController.h"

/*    Biblioteca de HashMap    */
#include <HashMap.h>

/***************************************************/
/******************Mapa da Pinagem******************/
/***************************************************/

#define PINO_SD_CS 53
#define setor_1   23
#define setor_2   25
#define setor_3   42
#define setor_4   43
#define setor_5   44
#define setor_6   45
#define setor_7   12
#define setor_8   13
#define setor_9   22
#define setor_10  24
#define setor_11  26
#define setor_12  28
#define setor_13  30
#define setor_14  32
#define setor_15  34
#define DesligaBombaCaptacao 31
#define LigaBombaCaptacao 33
#define DesligaBombaInjec   35
#define LigaBombaInjec  37
#define valvulaDescarte 46
#define DesligaPaMistura    39
#define LigaPaMistura   41
#define silo_1  10
#define silo_2  11
#define valvulaL2   29
#define contraLavagem 27
#define segundosUmaSemana 604800
#define TEMPO_OCIOSO 300
#define pinoInterruptTanque 0   // corresponde ao pino 2
#define pinoInterruptSilo 1     // corresponde ao pino 3
#define pinoInterruptInjec 2    // corresponde ao pino 4
#define pinoSensorTanque    6
#define pinoSensorSilo  5
#define pinoSensorInjec 8    
#define boiaInferior 7
#define boiaSuperior 9 
#define VOLUME_PURGA 100  // em Litros


#define ULTIMA_MENSAGEM "Ultima.msg"
#define SILOS_PRODUTOS "Silos.cfg"
#define PROGRAMACAO "Ferti.cal"
#define CONFIGURACAO "Start.cfg"
#define RETROLAVAGEM "Retrolavagem.cal"
#define DADOS "AutoCamp.nfo"
#define LOG "AutoCamp.log"
#define BACKUP "Backup.log"

namespace AutoCampLib {

    class Mensageiro
    {
        public:
            Mensageiro();
            void lerSerial();
            void enviar1099();

        private:
            bool guardarMensagem(char mensagem[]);
            bool tratarMensagem();
            void tratar2001();
            void tratar2002();
            void tratar2003();
            void tratar2101();
            void tratar2901();
            void tratar2902();
            void tratar2903();
            void tratar2904();
            void tratar2905();
            void tratar2999();
            void enviar1001();
            void enviar1002();
            void enviar1003();
            void enviar1004();
            void enviar1005();
            void lerArquivo(String nome);
            void escreverArquivo(String nome, int identificacao);
            bool verificaLetra(char caracter);
    };

    class Registrador
    {
        public:
            static void debug(char mensagem[]);
            static void info(char mensagem[]);
            static void warn(char mensagem[]);
            static void error(char mensagem[]);

        private:
            static void escreverRegistro(char mensagem[],char tipo[]);
            static void verificarTamanho();
            static String buscarDataHora();
    };

    class Fertilizantes
    {
        public :
            void setSilo(char *s);
            void setVol(float volumeFert);
            char *getSilo();
            float getVol();
            void setPortaSilo(int portasilo);
            int getPortaSilo();


        private :
            char _silo[8];
            float volumeF;
            int _portasilo;
    };

    class Eventos
    {
        public :
            Eventos();
            void setSetor(int setor);
            void setDuracao(int duracao);
            void setSequencial(int sequencial);
            void setVolumeH2O(float volumeAgua);
            void setPorta(int porta);
            int getPorta();
            int getSetor();
            int getDuracao();
            int getSequencial();
            float getVolumeH2O();
            //void setFertilizantes(LinkedList<Fertilizantes*>);
            //LinkedList<Fertilizantes*> getFertilizantes();
            Fertilizantes* getFertilizante(int posicao);
            void addFertilizante(Fertilizantes* fertilizante);
            int sizeFertilizantes();



        private :
            int _setor;
            int _porta;
            float _duracao;
            int _sequencial;
            float _volumeH2O;
            LinkedList<Fertilizantes*> _fertilizantes;
    };

    class Agendamentos
    {
        public:
            Agendamentos();
            void setDia(int dia);
            void setHora(int hora);
            void setMinuto(int minuto);
            void setSegundo(int segundo);
            int getDia();
            int getHora();
            int getMinuto();
            int getSegundo();
            //LinkedList<Eventos*> getEventos();
            Eventos* getEvento(int posicao);
            void addEvento(Eventos* evento);
            int sizeEventos();

        private :
            int _dia;
            int _hora;
            int _minuto;
            int _segundo;
            int posicao;
            LinkedList<Eventos*> _eventos;
    };

    class Start 
    {

        public :
            void setPressurizacao (int pressurizacao);
            void setTroca (int troca);
            void setInjecao(int injecao);
            void setAtraso( int atraso);
            void setOrdem(int ordem);
            void setBase(float base);
            void setTopo(float topo);
            void setAltura(float altura);
            void setSiloSTART(char *p);
            void setPino(int pino);
            void openReadStart(Start *start);
            void leCaracter(char c, File file);

            int getPressurizacao();
            int getTroca();
            int getInjecao();
            int getAtraso();
            int getOrdem();
            float getBase();
            float getTopo();
            float getAltura();
            char *getSiloSTART();
            int getPino();

        private :
            Start *start;
            File startcfg;
            int pr;
            int troca;
            int inj;
            int atraso;
            int seq;
            int pino;
            float base;
            float topo;
            float altura;
            char charLido;

            int _pressurizacao;
            int _troca;
            int _injecao;
            int _atraso;
            int _ordem;
            float _base;
            float _topo;
            float _altura;
            char _silostart[8];
            int _pino;
    };


   class Util 
   {

        public :
            static double calculaVolume(byte sensorInterrupt,byte sensorPin, float volumeDesejado);
            static void contadorPulso();

   }; 


   class SensorNivel: public Thread 
    {
        public : bool shouldRun(long time);
                 void run();

        private : int estado;    
    };


    class Programas: public Thread
    {
        public :   bool shouldRun(long time);
                   void run();

        private :  unsigned long tempo;
                   DateTime now ;
    };

    class RecuperaIrriga: public Thread
    {
        public : 
                 bool shouldRun(long time);
                 void run(); 
                 void fecharTodoSetor();
                 void verificarSetores(int numSetor);

        private : long horaFim;
                  long horaAtual;
                  long horaAgendamento;
                  int numeroEvento;
                  DateTime now;
                  Agendamentos *agendamento;

    }; 


    class VolumeAgua: public Thread
    {
        public :
                  bool shouldRun(long time);
                  void run();
                  static void contadorPulso();
                  double calculaVolume(byte sensorInterrupt,byte sensorPin, float volumeDesejado);

        private : volatile byte contaPulso; 
                  int numeroFert;
                  int numeroEvento;
                  float taxaFluxo;
                  float fatorCalibrador;
                  unsigned int fluxoL;
                  unsigned long totalL;
                  unsigned long oldTime;
    };

    class VolumeSilo: public Thread
    {
        public :
                    bool shouldRun(long time);
                    void run();

                    static void contadorPulso();
                    double calculaVolume(byte sensorInterrupt,byte sensorPin, float volumeDesejado);

        private :   float fatorCalibrador;
                    volatile byte contaPulso;
                    int numeroEvento;
                    int numeroFert;    
                    float taxaFluxo;
                    unsigned int fluxoL;
                    unsigned long totalL;
                    unsigned long oldTime;      
    };


    class RecuperaFerti: public Thread
    {
        public : 
                  void verificarSetores(int numSetor);
                  void run();
                  bool shouldRun(long time);


        private : long horaAtual;
                  long inicio;
                  int encherTanque;
                  long horaAgendamento;
                  int encherSilo;
                  int numeroFert;
                  int numeroEvento;
                  DateTime now;
                  Agendamentos *agendamento;


    }; 

    class RecuperaSilos: public Thread
    {

        public :   bool shouldRun(long time);
                   void run(); 

        private :  int numeroFert;
                   int numeroEvento; 

    }; 

    class Injecao: public Thread 
    {

        public : bool shouldRun(long time);
                 void run();   


        private : int numeroFert;
                  int numeroEvento;
                  int estado;
    };                   

    class NivelInjec: public Thread
    {
        private : int estado;

        public : bool shouldRun(long time);
                 void run();   
    };

    class Purga: public Thread
    {
        public :  void run();
                  bool shouldRun(long time);
                  static void contadorPulso();
                  double calculaVolume(byte sensorInterrupt,byte sensorPin, float volumeDesejado);      
    };


    class NivelPurga: public Thread
    {
        private : int estado;
                  DateTime now;
                  int numeroEvento;
                  long horaAtual;
                  long horaAgendamento;
                  Agendamentos *agendamento;

        public : bool shouldRun(long time);
                 void run();
                 fecharTodoSetor();   
    };





}

using namespace AutoCampLib;
#endif
Rezik
  • 31
  • 5
  • 2
    This means `registrador_nivel`'s compiled code was not found. The linker must be able to find the object file (the `.o` file) which is produced when you compile the file that contains the code of `registrador_nivel`. Do you want more explanations? – adentinger Mar 08 '17 at 17:16
  • Yes please !! Do you need any .cpp ? – Rezik Mar 08 '17 at 17:21
  • Well, I can't tell you exactly what you need to do to solve your problem because there is *so much* code. Next time, you should make a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve). But I can write an answer to explain why you get that sort of error. – adentinger Mar 08 '17 at 17:23
  • Ok I get it. Sorry for the huge info, but actually I do not understand your statement, can you give me an small example so I could adapt it to my situation? I dont understand what .o file is. @Anthony D. – Rezik Mar 08 '17 at 17:34
  • Yes, wait a few minutes while I write my answer. – adentinger Mar 08 '17 at 17:35
  • Well I simply added "char registrador_nivel" in the arduino sketch as a global variable and the error has gone. I guess that's the missing link, right? – Rezik Mar 08 '17 at 17:38
  • Yes, that would solve the compilation problem. It doesn't mean your program will work correctly though. – adentinger Mar 08 '17 at 17:39
  • This is way to much code, you should provide a MCVE and add approrpiate tags. – overseas Mar 08 '17 at 19:04

1 Answers1

1

Linker problems

This error means that registrador_nivel is supposed to exist somewhere, but the linker could not find where. I can't tell exactly what your problem is because you have so much code.

Let me show you an example that will produce the error you just got. Let's assume I only have this file:

// main.cpp
extern char registrador_nivel;

int main() {
    registrador_nivel = 2;
}

The line extern char registrador_nivel; tells your compiler that, somewhere, you have a global variable called registrador_nivel. However, main.cpp does not specify where registrador_nivel is. It only says that registrador_nivel exists somewhere.

The line registrador_nivel = 2; tries to change the value of registrador_nivel. You still don't know where registrador_nivel is. You just know you have to change it.

The object file (main.o file) will be produced during the compilation. It is a file that contains the same thing as main.cpp, but it a format that is more understandable to the computer. So main.o still doesn't say where registrador_nivel is.

Now, you want to make the final executable from the main.o file. The linker tries to find where registrador_nivel actually is. To do that, it looks inside static libraries (.lib and .a files) as well as other object files (.o files). If no library or object file says where registrador_nivel is, then the linker will send the error undefined reference to registrador_nivel.


Typical solutions

Once again, I can't tell you exactly what you have to do to solve your problem ; I can only guess.

  1. Are you using static libraries (.lib or .a files)? Since I see in your code that you talk about Bibliotecas, I guess that's your problem. Maybe registrador_nivel is defined in a library. In that case, you should link against these libraries. You're following a tutorial, aren't you? Your tutorial probably says what library to link against, and how.

  2. Are you sure you compiled all the files you should be compiling? If you aren't then you might be missing the .o file where registrador_nivel is, so your linker can't find it.

  3. If you're compiling everything you should be and you're linking against all static libraries you should be, then maybe they require you to declare registrador_nivel. In that case, try declaring a global variable called registrador_nivel.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
adentinger
  • 1,367
  • 1
  • 14
  • 30
  • 1
    Really much thanks, @Anthony D. Your explanation was a charm. Solution number 3 seem to be my case. Thanks a lot – Rezik Mar 16 '17 at 16:50
  • @Rezik Does everything work as expected? The fact that it compiles does not mean that it necessarily works. – adentinger Mar 16 '17 at 16:52
  • Yes indeed. It is compiling right now. Unfortunately this project requires a bigger enviroment to be fully tested. The further I've tested is ok, still need to fix some problems in the eletric painel and also implement THREADS, I've never worked with this before... that's my next challenge haha.. @Anthony D. – Rezik Mar 16 '17 at 17:00
  • @Rezik Good luck on multithreading! This is also on the list of things I would like to learn on my own, along with web programming, artificial intelligence, language theory... and *many* other things that I don't even remember right now. – adentinger Mar 16 '17 at 17:03