sudar / Arduino-Makefile

Makefile for Arduino sketches. It defines the workflows for compiling code, flashing it to Arduino and even communicating through Serial.
http://hardwarefun.com/tutorials/compiling-arduino-sketches-using-makefile
GNU Lesser General Public License v2.1
2.02k stars 448 forks source link

#include <Arduino.h> not working #509

Open thalesmaoa opened 7 years ago

thalesmaoa commented 7 years ago

Hi, I've been using Arduino-Makefile for a while with my own libraries. A few days ago I wanted to test Arduino Libs but it is not working.

I have .cpp file.

#include <Arduino.h>

void setup(){
    pinMode(LED_BUILTIN, OUTPUT);
}

void loop(){
      digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);                       // wait for a second
      digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);                       // wait for a second
}

My Makefile

# Detecta se esta no Windows ou Linux
ifeq ($(OS), Windows_NT)
    # Define o diretorio do arduino
    ARDUINO_DIR  = arduino-1.6.7-windows
    # Define o diretorio do makefile
    ARDMK_DIR = Arduino-Makefile-master
    # Define a porta de gravacao do sistema
    ISP_PORT = com3
    MONITOR_PORT = com3
    #get_isp_port = com3
    # Diretorio de saida
    OBJDIR = build
    # Nome do hex de saida
    TARGET = carbotronic
else
    # No Linux e possivel usar o caminho completo
    PROJECT_DIR = $(shell pwd)
    # Define o caminho do arduino no linux
    ARDUINO_DIR  = $(PROJECT_DIR)/arduino-1.8.3-linux
    # Define o caminho do makefile
    ARDMK_DIR = $(PROJECT_DIR)/Arduino-Makefile-master
    # Define a porta para gravar
    ISP_PORT = /dev/ttyACM0
    # Define a pasta de saida
    OBJDIR = $(PROJECT_DIR)/build
    # Define o nome do arquivo de saida
    #TARGET = $(shell date '+%Y%m%d_%H_%M_%S_eDrive')
    TARGET = rotacao
endif

# Informa o processador ao compilador
MCU = atmega2560

# Define Atmega2560
BOARD_TAG    = mega
BOARD_SUB    = atmega2560

include $(ARDMK_DIR)/Arduino.mk

It does compile and Upload, but the Led doesn't blink. I really need help!

sej7278 commented 7 years ago

if you have a .cpp file you have to add a lot more than #include <Arduino.h> you have to have a main() etc.

rename your file to .ino (as its not a valid .cpp file) and remove #include <Arduino.h> and it will work.

also not all boards have LED_BUILTIN defined, try setting it to a pin number.

thalesmaoa commented 7 years ago

@sej7278 Thanks for your help, but renaming it is not an option. I have a huge appliance with lot of cpp and h files with classes definitions. The problem emerged when I couldn't use Arduino Libraries.

I've built a small program to find why but I need help to debug it.

I'm pasting the files again:

main.cpp

#include "Defines.h"
int main(void){
    setup();
    for(;;)
        loop();
    return 0;
}

Defines.h

#ifndef DEFINES_H_
#define DEFINES_H_

#define __AVR_ATmega2560__ 1
#define F_CPU 16000000L
#include "Arduino.h"
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>
#include "rotacao.h"

void setup();
void loop();
#endif /* DEFINES_H_ */

rotacao.h

#ifndef _rotacao_H_
#define _rotacao_H_
#include "Defines.h"
#endif /* _main_H_ */

rotacao.cpp

#include "rotacao.h"

void setup(){
    pinMode(13, OUTPUT);
}

void loop(){
      digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);                       // wait for a second
      digitalWrite(13, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);                       // wait for a secondl
}

It does compile and upload! But there are no blinks.

If I use interruptions and manualy set registers it works.

I wass wondering if I did something wrong either is a bug.

sej7278 commented 7 years ago

if it compiles and uploads its nothing to do with the makefile i'd say, gotta be the code

thalesmaoa commented 7 years ago

Perhaps, but I'm so sure. Same code compile and run on Arduino IDE.

Can you try my code?

thalesmaoa commented 7 years ago

Perhaps, but I'm so sure. Same code compile and run on Arduino IDE.

Can you try my code?

sej7278 commented 7 years ago

are you sure, i didn't think the ide could even handle a cpp file with no ino file?

thalesmaoa commented 7 years ago

Sure, only the main code. The extra include and defines are kept out.

thalesmaoa commented 7 years ago

Ok, just found the problem.

If Arduino.h is included, the pre-processor goes crazy because of two setup() and loop() declarations. A workaround is to use and empty main.cpp file as suggested here:

https://arduino.stackexchange.com/questions/13178/classes-and-objects-how-many-and-which-file-types-do-i-actually-need-to-use-the/13182#13182

and here

http://www.gammon.com.au/forum/?id=12625

Is it possible to makefile detect if Arduino.h header is included and workaround this problem?

I kindly ask you not to lower my question. Some may consider using ino file or Arduino.h file not to be a problem, but for me, it is!

Since Arduino is opensource, I can not use it as a proprietary code to create my AVR programs. Indeed I can use it for debug. That is the point of this issue.

Arduino is a opensource code

sej7278 commented 7 years ago

you want to look into the NO_CORE variable then if you don't want to use Arduino.h, should have said that earlier!

thalesmaoa commented 7 years ago

@sej7278 I thank you again, but I tried NO_CORE but this is not the problem. As I mentioned, the problem is the main.cpp file and multiple setup() and loop() declarations. NO_CORE will only avoid Arduino Libraries to be compiled. The should be a directive to check. If Arduino Libs are requested, ignore main or multiple declarations. Some like #ifdef but for the cpp file.