├── .gitignore ├── LEGO_Power_Functions_RC_v120.pdf ├── examples ├── power_functions │ └── power_functions.ino ├── auto-brake │ ├── keywords.txt │ ├── Makefile │ ├── auto-brake.ino │ ├── NewPing.h │ └── NewPing.cpp ├── tracked_racer_42065 │ ├── Makefile │ └── tracked_racer_42065.ino └── power_test1 │ ├── Makefile │ └── power_test1.ino ├── keywords.txt ├── Makefile ├── LICENSE ├── README.md ├── PowerFunctions.h ├── arduino-makefile ├── Common.mk ├── chipKIT.mk ├── Teensy.mk └── Arduino.mk └── PowerFunctions.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | build-uno/ 2 | #Makefile# 3 | .#Makefile 4 | -------------------------------------------------------------------------------- /LEGO_Power_Functions_RC_v120.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jurriaan/Arduino-PowerFunctions/HEAD/LEGO_Power_Functions_RC_v120.pdf -------------------------------------------------------------------------------- /examples/power_functions/power_functions.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | PowerFunctions pf(12, 0); 4 | 5 | void setup() { 6 | // put your setup code here, to run once: 7 | } 8 | 9 | void loop() { 10 | // put your main code here, to run repeatedly: 11 | step(RED, PWM_FWD7, 500); 12 | delay(1000); 13 | } 14 | 15 | void step(uint8_t output, uint8_t pwm, uint16_t time) { 16 | pf.single_pwm(output, pwm); 17 | delay(time); 18 | pf.single_pwm(output, PWM_BRK); 19 | delay(30); 20 | pf.single_pwm(output, PWM_FLT); 21 | } -------------------------------------------------------------------------------- /keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Messenger 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | PowerFunctions KEYWORD1 10 | 11 | ####################################### 12 | # Methods and Functions (KEYWORD2) 13 | ####################################### 14 | 15 | single_pwm KEYWORD2 16 | combo_pwm KEYWORD2 17 | red_pwm KEYWORD2 18 | blue_pwm KEYWORD2 19 | 20 | ####################################### 21 | # Instances (KEYWORD2) 22 | ####################################### 23 | 24 | ####################################### 25 | # Constants (LITERAL1) 26 | ####################################### 27 | 28 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile used only to check syntax with flymake 2 | BOARD_TAG = uno 3 | ARDUINO_LIBS = Arduino-PowerFunctions 4 | # ARDUINO_DIR = C:/Arduino 5 | 6 | ### CXXFLAGS_STD 7 | ### Set the C++ standard to be used during compilation. Documentation (https://github.com/WeAreLeka/Arduino-Makefile/blob/std-flags/arduino-mk-vars.md#cxxflags_std) 8 | CXXFLAGS_STD = -std=gnu++11 9 | 10 | ### CXXFLAGS 11 | ### Flags you might want to set for debugging purpose. Comment to stop. 12 | CXXFLAGS += -pedantic -Wall -Wextra 13 | 14 | include ./arduino-makefile/Arduino.mk 15 | 16 | # For emacs fly-make 17 | check-syntax: 18 | $(CXX) -c -include Arduino.h -x c++ $(CXXFLAGS) $(CPPFLAGS) -fsyntax-only $(CHK_SOURCES) 19 | 20 | doxygen: 21 | doxygen Doxyfile 22 | tags: 23 | etags *.ino ../libraries/*/*.{c,h,cpp} 24 | -------------------------------------------------------------------------------- /examples/auto-brake/keywords.txt: -------------------------------------------------------------------------------- 1 | ################################### 2 | # Syntax Coloring Map For NewPing 3 | ################################### 4 | 5 | ################################### 6 | # Datatypes (KEYWORD1) 7 | ################################### 8 | 9 | NewPing KEYWORD1 10 | 11 | ################################### 12 | # Methods and Functions (KEYWORD2) 13 | ################################### 14 | 15 | ping KEYWORD2 16 | ping_in KEYWORD2 17 | ping_cm KEYWORD2 18 | ping_median KEYWORD2 19 | ping_timer KEYWORD2 20 | check_timer KEYWORD2 21 | timer_us KEYWORD2 22 | timer_ms KEYWORD2 23 | timer_stop KEYWORD2 24 | convert_in KEYWORD2 25 | convert_cm KEYWORD2 26 | 27 | ################################### 28 | # Constants (LITERAL1) 29 | ################################### 30 | 31 | -------------------------------------------------------------------------------- /examples/tracked_racer_42065/Makefile: -------------------------------------------------------------------------------- 1 | BOARD_TAG = uno 2 | ARDUINO_LIBS = Arduino-PowerFunctions 3 | # ARDUINO_DIR = C:/Arduino 4 | 5 | ### CXXFLAGS_STD 6 | ### Set the C++ standard to be used during compilation. Documentation (https://github.com/WeAreLeka/Arduino-Makefile/blob/std-flags/arduino-mk-vars.md#cxxflags_std) 7 | CXXFLAGS_STD = -std=gnu++11 8 | 9 | ### CXXFLAGS 10 | ### Flags you might want to set for debugging purpose. Comment to stop. 11 | ## GG C++ Extension with -std=c++11 12 | CXXFLAGS += -pedantic -Wall -Wextra 13 | 14 | include ../../arduino-makefile/Arduino.mk 15 | 16 | # For emacs fly-make 17 | check-syntax: 18 | $(CXX) -c -include Arduino.h -x c++ $(CXXFLAGS) $(CPPFLAGS) -fsyntax-only $(CHK_SOURCES) 19 | 20 | doxygen: 21 | doxygen Doxyfile 22 | tags: 23 | etags *.ino ../libraries/*/*.{c,h,cpp} 24 | -------------------------------------------------------------------------------- /examples/power_test1/Makefile: -------------------------------------------------------------------------------- 1 | BOARD_TAG = uno 2 | ARDUINO_LIBS = Arduino-PowerFunctions 3 | # ARDUINO_DIR = C:/Arduino 4 | 5 | ### CXXFLAGS_STD 6 | ### Set the C++ standard to be used during compilation. Documentation (https://github.com/WeAreLeka/Arduino-Makefile/blob/std-flags/arduino-mk-vars.md#cxxflags_std) 7 | CXXFLAGS_STD = -std=gnu++11 8 | 9 | ### CXXFLAGS 10 | ### Flags you might want to set for debugging purpose. Comment to stop. 11 | ## GG C++ Extension with -std=c++11 12 | CXXFLAGS += -pedantic -Wall -Wextra -std=c++1y 13 | 14 | include ../../arduino-makefile/Arduino.mk 15 | 16 | # For emacs fly-make 17 | check-syntax: 18 | $(CXX) -c -include Arduino.h -x c++ $(CXXFLAGS) $(CPPFLAGS) -fsyntax-only $(CHK_SOURCES) 19 | 20 | doxygen: 21 | doxygen Doxyfile 22 | tags: 23 | etags *.ino ../libraries/*/*.{c,h,cpp} 24 | -------------------------------------------------------------------------------- /examples/auto-brake/Makefile: -------------------------------------------------------------------------------- 1 | BOARD_TAG = uno 2 | ARDUINO_LIBS = Arduino-PowerFunctions 3 | # ARDUINO_DIR = C:/Arduino 4 | 5 | ### CXXFLAGS_STD 6 | ### Set the C++ standard to be used during compilation. Documentation (https://github.com/WeAreLeka/Arduino-Makefile/blob/std-flags/arduino-mk-vars.md#cxxflags_std) 7 | CXXFLAGS_STD = -std=gnu++11 8 | 9 | ### CXXFLAGS 10 | ### Flags you might want to set for debugging purpose. Comment to stop. 11 | ## GG C++ Extension with -std=c++11 12 | CXXFLAGS += -pedantic -Wall -Wextra 13 | 14 | include ../../arduino-makefile/Arduino.mk 15 | 16 | # For emacs fly-make 17 | check-syntax: 18 | $(CXX) -c -include Arduino.h -x c++ $(CXXFLAGS) $(CPPFLAGS) -fsyntax-only $(CHK_SOURCES) 19 | 20 | doxygen: 21 | doxygen Doxyfile 22 | tags: 23 | etags *.ino ../libraries/*/*.{c,h,cpp} 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Jurriaan Pruis 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /examples/power_test1/power_test1.ino: -------------------------------------------------------------------------------- 1 | // -*- mode:c++; mode: flymake -*- 2 | #include 3 | 4 | 5 | 6 | /*** 7 | * This demo uses an arduino to drive a 8 | * LEGO RC Tracked Racer 42065 9 | * We go forward a bit then backward 10 | * This is only a test sketch to test infrared-circuit on pin 12 11 | * DEfault channel is 1 (Channel 'Zero' on pdf) 12 | */ 13 | 14 | PowerFunctions pf(12, 0); 15 | 16 | 17 | void setup() { 18 | Serial.begin(9600); 19 | Serial.println(F("READY")); 20 | } 21 | 22 | 23 | void goForward(uint16_t time){ 24 | //Serial.println(F("FORWARD")); 25 | pf.combo_pwm(PWM_FWD2, PWM_REV2); 26 | delay(time); 27 | pf.combo_pwm(PWM_BRK,PWM_BRK); 28 | pf.combo_pwm(PWM_FLT,PWM_FLT); 29 | } 30 | 31 | 32 | void goBackward(uint16_t time){ 33 | //Serial.println(F("BACKWARD")); 34 | pf.combo_pwm(PWM_REV2, PWM_FWD2); 35 | delay(time); 36 | pf.combo_pwm(PWM_BRK,PWM_BRK); 37 | pf.combo_pwm(PWM_FLT,PWM_FLT); 38 | } 39 | 40 | void loop() { 41 | // put your main code here, to run repeatedly: 42 | goForward(1500); 43 | goBackward(500); 44 | //while(true) { delay(1000); } 45 | 46 | } 47 | 48 | 49 | 50 | 51 | 52 | void step(uint8_t output, uint8_t pwm, uint16_t time) { 53 | pf.single_pwm(output, pwm); 54 | delay(time); 55 | pf.single_pwm(output, PWM_BRK); 56 | delay(30); 57 | pf.single_pwm(output, PWM_FLT); 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lego Power Functions Infrared Control for Arduino 2 | 3 | This is a Arduino Lego Power Functions Library. 4 | For now it only supports single/combo PWM. 5 | Based on [SuperCow's code](http://forum.arduino.cc/index.php?topic=38142.msg282833#msg282833) 6 | 7 | ## Protocol 8 | 9 | See [LEGO_Power_Functions_RC_v120.pdf](https://github.com/jurriaan/Arduino-PowerFunctions/raw/master/LEGO_Power_Functions_RC_v120.pdf) for more info 10 | The first version of the specification was published on 2008 [1]. 11 | The version described in the pdf is the 1.2 12 | 13 | ## Usage 14 | 15 | See [example](https://github.com/jurriaan/Arduino-PowerFunctions/blob/master/examples/power_functions/power_functions.ino). 16 | 17 | ## Standalone Compile (optional) 18 | The [Arduino Makefile project](https://github.com/sudar/Arduino-Makefile) is used for standalone compile of examples. 19 | Refer to arduino-makefile/Arduino.mk for instructions on how to 20 | configure it. 21 | Under windows, try to define a user variable like 22 | `setx ARDUINO_DIR C:/Arduino` 23 | 24 | Then to get a list of supported command issue 25 | 26 | `make help` 27 | 28 | Also, you can spped up large project construction with the GNU Make 29 | "-j option" to make a parallel build. 30 | 31 | ## Other projects 32 | This project [is able to decode IR protocol](https://raw.githubusercontent.com/matthiaszimmermann/ArduinoLegoIrReceiver) and can be paired with this one 33 | 34 | The [New Ping library give you some insight about how the ping code was optimized](https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home) 35 | 36 | 37 | 38 | 39 | ## References 40 | 41 | [1] http://www.technicbricks.com/2008/01/power-functions-rc-protocol-released-as.html
42 | [2] [General introduction into decoding IR signals with Arduino]https://learn.adafruit.com/ir-sensor/using-an-ir-sensor
43 | 44 | (c) 2013 Jurriaan Pruis 45 | (c) 2017 Giovanni Giorgi 46 | -------------------------------------------------------------------------------- /PowerFunctions.h: -------------------------------------------------------------------------------- 1 | #ifndef PowerFunctions_h 2 | #define PowerFunctions_h 3 | 4 | #include 5 | #include "Arduino.h" 6 | 7 | #define COMBO_DIRECT_MODE 0x01 8 | #define SINGLE_PIN_CONTINUOUS 0x2 9 | #define SINGLE_PIN_TIMEOUT 0x3 10 | #define SINGLE_OUTPUT 0x4 11 | #define SINGLE_EXT 0x6 12 | #define ESCAPE 0x4 13 | 14 | #define IR_CYCLES(num) (uint16_t) ((1.0/38000.0) * 1000 * 1000 * num) 15 | 16 | #define START_STOP IR_CYCLES(39) 17 | #define HIGH_PAUSE IR_CYCLES(21) 18 | #define LOW_PAUSE IR_CYCLES(10) 19 | #define HALF_PERIOD IR_CYCLES(0.5) 20 | #define MAX_MESSAGE_LENGTH IR_CYCLES(522) // 2 * 45 + 16 * 27 21 | 22 | //PWM speed steps 23 | #define PWM_FLT 0x0 24 | #define PWM_FWD1 0x1 25 | #define PWM_FWD2 0x2 26 | #define PWM_FWD3 0x3 27 | #define PWM_FWD4 0x4 28 | #define PWM_FWD5 0x5 29 | #define PWM_FWD6 0x6 30 | #define PWM_FWD7 0x7 31 | #define PWM_BRK 0x8 32 | #define PWM_REV7 0x9 33 | #define PWM_REV6 0xA 34 | #define PWM_REV5 0xB 35 | #define PWM_REV4 0xC 36 | #define PWM_REV3 0xD 37 | #define PWM_REV2 0xE 38 | #define PWM_REV1 0xf 39 | 40 | //speed 41 | /* 42 | #define RED_FLT 0x0 43 | #define RED_FWD 0x1 44 | #define RED_REV 0x2 45 | #define RED_BRK 0x3 46 | #define BLUE_FLT 0x0 47 | #define BLUE_FWD 0x4 48 | #define BLUE_REV 0x8 49 | #define BLUE_BRK 0xC 50 | */ 51 | 52 | //output 53 | #define RED 0x0 54 | #define BLUE 0x1 55 | 56 | class PowerFunctions 57 | { 58 | public: 59 | PowerFunctions(uint8_t pin, uint8_t channel, bool _debug = false); 60 | void single_pwm(uint8_t, uint8_t); 61 | void single_increment(uint8_t); 62 | void single_decrement(uint8_t); 63 | void red_pwm(uint8_t); 64 | void blue_pwm(uint8_t); 65 | void combo_pwm(uint8_t, uint8_t); 66 | 67 | private: 68 | void pause(uint8_t); 69 | void send_bit(); 70 | void send(); 71 | void start_stop_bit(); 72 | 73 | void toggle(); 74 | 75 | uint8_t _channel; 76 | uint8_t _pin; 77 | uint8_t _nib1, _nib2, _nib3; 78 | uint8_t _toggle; 79 | bool _debug; 80 | }; 81 | 82 | #endif 83 | // END OF FILE 84 | -------------------------------------------------------------------------------- /examples/tracked_racer_42065/tracked_racer_42065.ino: -------------------------------------------------------------------------------- 1 | // -*- mode:c++; mode: flymake -*- 2 | #include 3 | 4 | 5 | 6 | /*** 7 | * Zig Zag a RC Tracked Racer! 8 | * Version 1.1 9 | * 10 | * This demo uses an arduino to drive a 11 | * LEGO RC Tracked Racer 42065 12 | * To drive it you must give inverted command in sync. 13 | * 14 | * Wiring: wire 4 buttons with different resistence to pin A0, using the keyboard example 7 in ardruino starter kit 15 | * Connect the led to pin 12. 16 | * 17 | * Alternate Wiring: Use a mosfet to drive more power to the led (use pin 12 to control the mosfet. 18 | * 19 | * 20 | */ 21 | 22 | PowerFunctions pf(12, 0,true /* <= Enable debug mode on pin 13? */); 23 | 24 | 25 | 26 | int j=0; 27 | void setup() { 28 | // put your setup code here, to run once: 29 | Serial.begin(9600); 30 | } 31 | 32 | 33 | 34 | void goForward(uint16_t time){ 35 | 36 | pf.combo_pwm(PWM_FWD4, PWM_REV4); 37 | delay(time); 38 | pf.combo_pwm(PWM_FLT,PWM_FLT); 39 | } 40 | 41 | /** NEEDS STILL TESTING 42 | void turn90Degrees(){ 43 | // Now try to do a 90 angle with a moderate speed. To do it is enough to run a motor 44 | pf.combo_pwm(PWM_BRK,PWM_BRK); 45 | pf.combo_pwm(PWM_REV5,PWM_BRK); 46 | delay(500); 47 | pf.combo_pwm(PWM_BRK,PWM_BRK); 48 | } 49 | */ 50 | 51 | 52 | 53 | 54 | void step(uint8_t output, uint8_t pwm, uint16_t time) { 55 | pf.single_pwm(output, pwm); 56 | delay(time); 57 | pf.single_pwm(output, PWM_BRK); 58 | delay(30); 59 | pf.single_pwm(output, PWM_FLT); 60 | } 61 | 62 | 63 | ///////////// 64 | void zigZag(uint16_t msTime){ 65 | unsigned long startTime=millis(); 66 | const int delayf=2; 67 | const int zigRange=2; 68 | do { 69 | 70 | // TO TEST THE TURNING MECHANINCS 71 | 72 | 73 | // Zig to left 74 | pf.combo_pwm(PWM_FWD4, PWM_REV2); 75 | delay(100*delayf*zigRange); 76 | 77 | goForward(50*delayf); 78 | 79 | // Center again 80 | pf.combo_pwm(PWM_FWD2, PWM_REV4); 81 | delay(100*delayf*zigRange); 82 | 83 | // Zig to right 84 | pf.combo_pwm(PWM_FWD2, PWM_REV4); 85 | delay(100*delayf*zigRange); 86 | 87 | goForward(50* delayf); 88 | 89 | 90 | 91 | }while ((millis()-startTime) < msTime); 92 | } 93 | 94 | boolean stop=true; 95 | void loop() { 96 | /* Make a Square: 97 | */ 98 | // Analog read button and then do the trick... 99 | int keyVal = analogRead(A0); 100 | 101 | // play the note corresponding to each value on A0 102 | if (keyVal >=1016) { 103 | // Super start: 104 | stop=false; 105 | } else if (keyVal >= 990 && keyVal <= 1010) { 106 | // Super stop 107 | stop=true; 108 | Serial.println(F("STOP")); 109 | } else if (keyVal >= 505 && keyVal <= 515) { 110 | } else if (keyVal >= 5 && keyVal <= 10) { 111 | } else { 112 | } 113 | 114 | if(!stop) { 115 | Serial.println(F("ZIGZAG")); 116 | zigZag(10000); // 10 sec zig zag 117 | stop=true; 118 | } 119 | Serial.println(keyVal); 120 | 121 | 122 | 123 | } 124 | -------------------------------------------------------------------------------- /examples/auto-brake/auto-brake.ino: -------------------------------------------------------------------------------- 1 | // -*- mode:c++; mode: flymake -*- 2 | /** 3 | This Small examples uses a HC RS04 ultrasonic sensor on pin 7,8 to 4 | show an auto brake function. 5 | Mount the arduino with the sensor on the car. 6 | Define the Security distance (based on your project) 7 | 8 | 9 | If the sensor detect a object in a range <= AutoBrakeDistanceCm 10 | Arduino system will issue a power function brake on first channel, possibly overriding 11 | your orders. 12 | 13 | The NewPing v 1.8 is used for better measurements: for more information see https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home 14 | 15 | TODO: TRY TO COMPUTE RELATIVE SPEED VIA FORMULA LIKE 16 | Speed = (FirstDistance - SecondDistance) / (SecondTime - FirstTime) 17 | 18 | 19 | Note: there are 1,000 microseconds in a millisecond and 1,000,000 microseconds in a second. 20 | */ 21 | // CONFIG 22 | const int triggerPort = 7; 23 | const int echoPort = 8; 24 | const int PowerFunctionPort = 12; 25 | const int AutoBrakeDistanceCm = 10; 26 | 27 | // HCRS04 Specs talk about 400cm. NewPing default is 500 28 | const int MaxDistCm = 400; 29 | 30 | 31 | #include 32 | #include "NewPing.h" 33 | 34 | // Decomment your preferred debug 35 | #define log(x) Serial.print(F(x)) 36 | //#define log(x) 37 | 38 | 39 | PowerFunctions powerFunction(12, 0, /*debug=*/ true); 40 | NewPing sonar(triggerPort, echoPort, MaxDistCm); 41 | 42 | void setup() { 43 | 44 | pinMode( triggerPort, OUTPUT ); 45 | pinMode( echoPort, INPUT ); 46 | //pinMode( blueLed, OUTPUT); 47 | //pinMode(redLed, OUTPUT); 48 | Serial.begin( 9600 ); 49 | Serial.println( F( "AutoBrake v1.2+")); 50 | // 51 | // Make a two break cmd (test set) 52 | // 53 | powerFunction.combo_pwm(PWM_BRK, PWM_BRK); 54 | powerFunction.combo_pwm(PWM_BRK, PWM_BRK); 55 | 56 | } 57 | 58 | void loop() { 59 | 60 | // Static registered last distance 61 | static unsigned long lastDistance = 0; 62 | //analogWrite(blueLed, 255); 63 | 64 | 65 | unsigned long startTime = millis(); 66 | 67 | // We do 3 short measures to gain better accuracy 68 | //unsigned long r = sonar.ping_cm(); 69 | unsigned long r = sonar.convert_cm(sonar.ping_median(3)); 70 | 71 | 72 | 73 | if (r == 0 ) { 74 | // Could also mean there are no obstacles and live happily... 75 | //log("OUT OF RANGE"); 76 | } else { 77 | if (r != lastDistance) { 78 | log("> ") ; 79 | Serial.println( r ); 80 | log("cm") ; 81 | //int ledValue=map(rlong,minDistCm*10,maxDistCm*10,0,255); 82 | 83 | //TODO: Implement a sort of progressive brake to avoid too much trouble 84 | // The system should be able to extimate current velocity 85 | if ( r <= AutoBrakeDistanceCm ) { 86 | log("!BRAKE|\n"); 87 | // Brake! (short way) 88 | powerFunction.combo_pwm(PWM_BRK, PWM_BRK); 89 | //analogWrite(blueLed, ledValue); 90 | } else { 91 | // TODO: Push the old one (lastDistance) 92 | // Serial.print(F("..")); 93 | } 94 | /// PUT HERE Other low priorty housekeeping 95 | 96 | lastDistance = r; 97 | log("\n"); 98 | } 99 | 100 | } 101 | 102 | } 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /arduino-makefile/Common.mk: -------------------------------------------------------------------------------- 1 | # Useful functions 2 | # Returns the first argument (typically a directory), if the file or directory 3 | # named by concatenating the first and optionally second argument 4 | # (directory and optional filename) exists 5 | dir_if_exists = $(if $(wildcard $(1)$(2)),$(1)) 6 | 7 | # Run a shell script if it exists. Stops make on error. 8 | runscript_if_exists = \ 9 | $(if $(wildcard $(1)), \ 10 | $(if $(findstring 0, \ 11 | $(lastword $(shell $(abspath $(wildcard $(1))); echo $$?))), \ 12 | $(info Info: $(1) success), \ 13 | $(error ERROR: $(1) failed))) 14 | 15 | # For message printing: pad the right side of the first argument with spaces to 16 | # the number of bytes indicated by the second argument. 17 | space_pad_to = $(shell echo $(1) " " | head -c$(2)) 18 | 19 | # Call with some text, and a prefix tag if desired (like [AUTODETECTED]), 20 | show_config_info = $(call arduino_output,- $(call space_pad_to,$(2),20) $(1)) 21 | 22 | # Call with the name of the variable, a prefix tag if desired (like [AUTODETECTED]), 23 | # and an explanation if desired (like (found in $$PATH) 24 | show_config_variable = $(call show_config_info,$(1) = $($(1)) $(3),$(2)) 25 | 26 | # Just a nice simple visual separator 27 | show_separator = $(call arduino_output,-------------------------) 28 | 29 | $(call show_separator) 30 | $(call arduino_output,Arduino.mk Configuration:) 31 | 32 | ######################################################################## 33 | # 34 | # Detect OS 35 | ifeq ($(OS),Windows_NT) 36 | CURRENT_OS = WINDOWS 37 | else 38 | UNAME_S := $(shell uname -s) 39 | ifeq ($(UNAME_S),Linux) 40 | CURRENT_OS = LINUX 41 | endif 42 | ifeq ($(UNAME_S),Darwin) 43 | CURRENT_OS = MAC 44 | endif 45 | endif 46 | $(call show_config_variable,CURRENT_OS,[AUTODETECTED]) 47 | 48 | ######################################################################## 49 | # 50 | # Travis-CI 51 | ifneq ($(TEST),) 52 | DEPENDENCIES_DIR = /var/tmp/Arduino-Makefile-testing-dependencies 53 | 54 | DEPENDENCIES_MPIDE_DIR = $(DEPENDENCIES_DIR)/mpide-0023-linux64-20130817-test 55 | ifeq ($(MPIDE_DIR),) 56 | MPIDE_DIR = $(DEPENDENCIES_MPIDE_DIR) 57 | endif 58 | 59 | DEPENDENCIES_ARDUINO_DIR = $(DEPENDENCIES_DIR)/arduino-1.0.6 60 | ifeq ($(ARDUINO_DIR),) 61 | ARDUINO_DIR = $(DEPENDENCIES_ARDUINO_DIR) 62 | endif 63 | endif 64 | 65 | ######################################################################## 66 | # Arduino Directory 67 | 68 | ifndef ARDUINO_DIR 69 | AUTO_ARDUINO_DIR := $(firstword \ 70 | $(call dir_if_exists,/usr/share/arduino) \ 71 | $(call dir_if_exists,/Applications/Arduino.app/Contents/Resources/Java) \ 72 | $(call dir_if_exists,/Applications/Arduino.app/Contents/Java) ) 73 | ifdef AUTO_ARDUINO_DIR 74 | ARDUINO_DIR = $(AUTO_ARDUINO_DIR) 75 | $(call show_config_variable,ARDUINO_DIR,[AUTODETECTED]) 76 | else 77 | echo $(error "ARDUINO_DIR is not defined") 78 | endif 79 | else 80 | $(call show_config_variable,ARDUINO_DIR,[USER]) 81 | endif 82 | 83 | ifeq ($(CURRENT_OS),WINDOWS) 84 | ifneq ($(shell echo $(ARDUINO_DIR) | egrep '^(/|[a-zA-Z]:\\)'),) 85 | echo $(error On Windows, ARDUINO_DIR must be a relative path) 86 | endif 87 | endif 88 | -------------------------------------------------------------------------------- /PowerFunctions.cpp: -------------------------------------------------------------------------------- 1 | // -*- mode:c++; mode: flymake -*- 2 | // Lego Power Functions Infrared Control for Arduino 3 | // see http://www.philohome.com/pf/LEGO_Power_Functions_RC_v120.pdf for more info 4 | // Based on SuperCow's code (http://forum.arduino.cc/index.php?topic=38142.0) 5 | // 6 | 7 | // By spec CHECKSUM is a XOR based on the 4-bit triplet you are sending 8 | #define CHECKSUM() (0xf ^ _nib1 ^ _nib2 ^ _nib3) 9 | 10 | #include 11 | #include "PowerFunctions.h" 12 | #include "Arduino.h" 13 | 14 | // Aliases 15 | void PowerFunctions::red_pwm(uint8_t pwm) { single_pwm(RED, pwm); } 16 | void PowerFunctions::blue_pwm(uint8_t pwm) { single_pwm(BLUE, pwm); } 17 | 18 | // Constructor 19 | PowerFunctions::PowerFunctions(uint8_t pin, uint8_t channel, bool debug) 20 | { 21 | _channel = channel; 22 | _toggle = 0; 23 | _pin = pin; 24 | _debug=debug; 25 | pinMode(_pin, OUTPUT); 26 | digitalWrite(_pin, LOW); 27 | if(_debug){ 28 | pinMode(LED_BUILTIN, OUTPUT); 29 | digitalWrite(LED_BUILTIN, HIGH); 30 | } 31 | } 32 | 33 | 34 | 35 | // Single output mode PWM 36 | void PowerFunctions::single_pwm(uint8_t output, uint8_t pwm) { 37 | _nib1 = _toggle | _channel; 38 | _nib2 = SINGLE_OUTPUT | output; 39 | _nib3 = pwm; 40 | send(); 41 | toggle(); 42 | } 43 | 44 | void PowerFunctions::single_increment(uint8_t output){ 45 | _nib1 = _toggle | _channel; 46 | _nib2 = SINGLE_EXT | output; 47 | _nib3 = 0x4; 48 | send(); 49 | toggle(); 50 | } 51 | 52 | void PowerFunctions::single_decrement(uint8_t output){ 53 | _nib1 = _toggle | _channel; 54 | _nib2 = SINGLE_EXT | output; 55 | _nib3 = 0x5; 56 | send(); 57 | toggle(); 58 | } 59 | 60 | // Combo PWM mode 61 | void PowerFunctions::combo_pwm(uint8_t blue_speed, uint8_t red_speed) 62 | { 63 | _nib1 = ESCAPE | _channel; 64 | _nib2 = blue_speed; 65 | _nib3 = red_speed; 66 | send(); 67 | } 68 | 69 | // 70 | // Private methods 71 | // 72 | 73 | // Pause function see "Transmitting Messages" in Power Functions PDF 74 | void PowerFunctions::pause(uint8_t count) 75 | { 76 | uint8_t pause = 0; 77 | 78 | if(count == 0) { 79 | pause = 4 - (_channel + 1); 80 | } else if(count < 3) { // 1, 2 81 | pause = 5; 82 | } else { // 3, 4, 5 83 | pause = 5 + (_channel + 1) * 2; 84 | } 85 | delayMicroseconds(pause * 77); //MAX_MESSAGE_LENGTH 86 | } 87 | 88 | // Send the start/stop bit 89 | void PowerFunctions::start_stop_bit() 90 | { 91 | send_bit(); 92 | delayMicroseconds(START_STOP); // Extra pause for start_stop_bit 93 | } 94 | 95 | // Send a bit 96 | void PowerFunctions::send_bit() { 97 | for(uint8_t i = 0; i < 6; i++) { 98 | digitalWrite(_pin, HIGH); 99 | delayMicroseconds(HALF_PERIOD); 100 | digitalWrite(_pin, LOW); 101 | delayMicroseconds(HALF_PERIOD); 102 | } 103 | } 104 | 105 | void PowerFunctions::send() 106 | { 107 | uint8_t i, j; 108 | uint16_t message = _nib1 << 12 | _nib2 << 8 | _nib3 << 4 | CHECKSUM(); 109 | bool flipDebugLed=false; 110 | for(i = 0; i < 6; i++) 111 | { 112 | pause(i); 113 | start_stop_bit(); 114 | for(j = 0; j < 16; j++) { 115 | send_bit(); 116 | delayMicroseconds((0x8000 & (message << j)) != 0 ? HIGH_PAUSE : LOW_PAUSE); 117 | if(_debug) { 118 | if(flipDebugLed) { 119 | digitalWrite(LED_BUILTIN, LOW); 120 | } else { 121 | digitalWrite(LED_BUILTIN, HIGH); 122 | } 123 | flipDebugLed = !flipDebugLed; 124 | } 125 | } 126 | start_stop_bit(); 127 | } // for 128 | } 129 | 130 | inline void PowerFunctions::toggle(){ 131 | _toggle ^= 0x8; 132 | } 133 | -------------------------------------------------------------------------------- /arduino-makefile/chipKIT.mk: -------------------------------------------------------------------------------- 1 | # 2 | # chipKIT extensions for Arduino Makefile 3 | # System part (i.e. project independent) 4 | # 5 | # Copyright (C) 2011, 2012, 2013 Christopher Peplin 6 | # , based on work that is Copyright Martin 7 | # Oldfield 8 | # 9 | # This file is free software; you can redistribute it and/or modify it 10 | # under the terms of the GNU Lesser General Public License as 11 | # published by the Free Software Foundation; either version 2.1 of the 12 | # License, or (at your option) any later version. 13 | # 14 | # Modified by John Wallbank for Visual Studio 15 | # 16 | # Development changes, John Wallbank, 17 | # 18 | # - made inclusion of WProgram.h optional so that 19 | # including it in the source doesn't mess up compile error line numbers 20 | # - parameterised the routine used to reset the serial port 21 | # 22 | 23 | ######################################################################## 24 | # Makefile distribution path 25 | # 26 | 27 | # The show_config_variable is unavailable before we include the common makefile, 28 | # so we defer logging the ARDMK_DIR info until it happens in Arduino.mk 29 | ifndef ARDMK_DIR 30 | # presume it's the same path to our own file 31 | ARDMK_DIR := $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST))))) 32 | endif 33 | 34 | include $(ARDMK_DIR)/Common.mk 35 | 36 | ifndef MPIDE_DIR 37 | AUTO_MPIDE_DIR := $(firstword \ 38 | $(call dir_if_exists,/usr/share/mpide) \ 39 | $(call dir_if_exists,/Applications/Mpide.app/Contents/Resources/Java) ) 40 | ifdef AUTO_MPIDE_DIR 41 | MPIDE_DIR = $(AUTO_MPIDE_DIR) 42 | $(call show_config_variable,MPIDE_DIR,[autodetected]) 43 | else 44 | echo $(error "mpide_dir is not defined") 45 | endif 46 | else 47 | $(call show_config_variable,MPIDE_DIR,[USER]) 48 | endif 49 | 50 | ifeq ($(CURRENT_OS),WINDOWS) 51 | ifneq ($(shell echo $(ARDUINO_DIR) | egrep '^(/|[a-zA-Z]:\\)'),) 52 | echo $(error On Windows, MPIDE_DIR must be a relative path) 53 | endif 54 | endif 55 | 56 | ifndef MPIDE_PREFERENCES_PATH 57 | AUTO_MPIDE_PREFERENCES_PATH := $(firstword \ 58 | $(call dir_if_exists,$(HOME)/.mpide/preferences.txt) \ 59 | $(call dir_if_exists,$(HOME)/Library/Mpide/preferences.txt) ) 60 | ifdef AUTO_MPIDE_PREFERENCES_PATH 61 | MPIDE_PREFERENCES_PATH = $(AUTO_MPIDE_PREFERENCES_PATH) 62 | $(call show_config_variable,MPIDE_PREFERENCES_PATH,[autodetected]) 63 | endif 64 | endif 65 | 66 | # The same as in Arduino, the Linux distribution contains avrdude and # 67 | # avrdude.conf in a different location, but for chipKIT it's even slightly 68 | # different than the Linux paths for Arduino, so we have to "double override". 69 | ifeq ($(CURRENT_OS),LINUX) 70 | AVRDUDE_DIR = $(ARDUINO_DIR)/hardware/tools 71 | AVRDUDE = $(AVRDUDE_DIR)/avrdude 72 | AVRDUDE_CONF = $(AVRDUDE_DIR)/avrdude.conf 73 | endif 74 | 75 | PIC32_TOOLS_DIR = $(ARDUINO_DIR)/hardware/pic32/compiler/pic32-tools 76 | PIC32_TOOLS_PATH = $(PIC32_TOOLS_DIR)/bin 77 | 78 | ALTERNATE_CORE = pic32 79 | ALTERNATE_CORE_PATH = $(MPIDE_DIR)/hardware/pic32 80 | ARDUINO_CORE_PATH = $(ALTERNATE_CORE_PATH)/cores/$(ALTERNATE_CORE) 81 | ARDUINO_PREFERENCES_PATH = $(MPIDE_PREFERENCES_PATH) 82 | ARDUINO_DIR = $(MPIDE_DIR) 83 | 84 | CORE_AS_SRCS = $(ARDUINO_CORE_PATH)/vector_table.S \ 85 | $(ARDUINO_CORE_PATH)/cpp-startup.S \ 86 | $(ARDUINO_CORE_PATH)/crti.S \ 87 | $(ARDUINO_CORE_PATH)/crtn.S \ 88 | $(ARDUINO_CORE_PATH)/pic32_software_reset.S 89 | 90 | ARDUINO_VERSION = 23 91 | 92 | CC_NAME = pic32-gcc 93 | CXX_NAME = pic32-g++ 94 | AR_NAME = pic32-ar 95 | OBJDUMP_NAME = pic32-objdump 96 | OBJCOPY_NAME = pic32-objcopy 97 | SIZE_NAME = pic32-size 98 | NM_NAME = pic32-nm 99 | 100 | OVERRIDE_EXECUTABLES = 1 101 | CC = $(PIC32_TOOLS_PATH)/$(CC_NAME) 102 | CXX = $(PIC32_TOOLS_PATH)/$(CXX_NAME) 103 | AS = $(PIC32_TOOLS_PATH)/$(AS_NAME) 104 | OBJCOPY = $(PIC32_TOOLS_PATH)/$(OBJCOPY_NAME) 105 | OBJDUMP = $(PIC32_TOOLS_PATH)/$(OBJDUMP_NAME) 106 | AR = $(PIC32_TOOLS_PATH)/$(AR_NAME) 107 | SIZE = $(PIC32_TOOLS_PATH)/$(SIZE_NAME) 108 | NM = $(PIC32_TOOLS_PATH)/$(NM_NAME) 109 | 110 | LDSCRIPT = $(call PARSE_BOARD,$(BOARD_TAG),ldscript) 111 | LDSCRIPT_FILE = $(ARDUINO_CORE_PATH)/$(LDSCRIPT) 112 | 113 | MCU_FLAG_NAME=mprocessor 114 | LDFLAGS += -mdebugger -mno-peripheral-libs -nostartfiles -Wl,--gc-sections 115 | LINKER_SCRIPTS += -T $(ARDUINO_CORE_PATH)/$(LDSCRIPT) 116 | LINKER_SCRIPTS += -T $(ARDUINO_CORE_PATH)/chipKIT-application-COMMON.ld 117 | CPPFLAGS += -mno-smart-io -fno-short-double -fframe-base-loclist \ 118 | -g3 -Wcast-align -D_BOARD_MEGA_ 119 | CFLAGS_STD = 120 | 121 | include $(ARDMK_DIR)/Arduino.mk 122 | -------------------------------------------------------------------------------- /arduino-makefile/Teensy.mk: -------------------------------------------------------------------------------- 1 | ######################################################################## 2 | # 3 | # Support for Teensy 3.x boards 4 | # 5 | # https://www.pjrc.com/teensy/ 6 | # 7 | # You must install teensyduino for this Makefile to work: 8 | # 9 | # http://www.pjrc.com/teensy/teensyduino.html 10 | # 11 | # Copyright (C) 2014 Jeremy Shaw based on 12 | # work that is copyright Sudar, Nicholas Zambetti, David A. Mellis 13 | # & Hernando Barragan. 14 | # 15 | # This file is free software; you can redistribute it and/or modify it 16 | # under the terms of the GNU Lesser General Public License as 17 | # published by the Free Software Foundation; either version 2.1 of the 18 | # License, or (at your option) any later version. 19 | # 20 | # Adapted from Arduino 0011 Makefile by M J Oldfield 21 | # 22 | # Original Arduino adaptation by mellis, eighthave, oli.keller 23 | # 24 | # Refer to HISTORY.md file for complete history of changes 25 | # 26 | ######################################################################## 27 | 28 | 29 | ifndef ARDMK_DIR 30 | ARDMK_DIR := $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST))))) 31 | endif 32 | 33 | # include Common.mk now we know where it is 34 | include $(ARDMK_DIR)/Common.mk 35 | 36 | ARDMK_VENDOR = teensy 37 | ARDUINO_CORE_PATH = $(ARDUINO_DIR)/hardware/teensy/avr/cores/teensy3 38 | BOARDS_TXT = $(ARDUINO_DIR)/hardware/$(ARDMK_VENDOR)/avr/boards.txt 39 | 40 | ifndef F_CPU 41 | F_CPU=96000000 42 | endif 43 | 44 | ifndef PARSE_TEENSY 45 | # result = $(call READ_BOARD_TXT, 'boardname', 'parameter') 46 | PARSE_TEENSY = $(shell grep -v "^\#" "$(BOARDS_TXT)" | grep $(1).$(2) | cut -d = -f 2- ) 47 | endif 48 | 49 | # if boards.txt gets modified, look there, else hard code it 50 | ARCHITECTURE = $(call PARSE_TEENSY,$(BOARD_TAG),build.architecture) 51 | ifeq ($(strip $(ARCHITECTURE)),) 52 | ARCHITECTURE = arm 53 | endif 54 | 55 | AVR_TOOLS_DIR = $(call dir_if_exists,$(ARDUINO_DIR)/hardware/tools/$(ARCHITECTURE)) 56 | 57 | # define plaform lib dir ignoring teensy's oversight on putting it all in avr 58 | ifndef ARDUINO_PLATFORM_LIB_PATH 59 | ARDUINO_PLATFORM_LIB_PATH = $(ARDUINO_DIR)/hardware/$(ARDMK_VENDOR)/avr/libraries 60 | $(call show_config_variable,ARDUINO_PLATFORM_LIB_PATH,[COMPUTED],(from ARDUINO_DIR)) 61 | endif 62 | 63 | ######################################################################## 64 | # command names 65 | 66 | ifndef CC_NAME 67 | CC_NAME := $(call PARSE_TEENSY,$(BOARD_TAG),build.command.gcc) 68 | ifndef CC_NAME 69 | CC_NAME := arm-none-eabi-gcc 70 | else 71 | $(call show_config_variable,CC_NAME,[COMPUTED]) 72 | endif 73 | endif 74 | 75 | ifndef CXX_NAME 76 | CXX_NAME := $(call PARSE_TEENSY,$(BOARD_TAG),build.command.g++) 77 | ifndef CXX_NAME 78 | CXX_NAME := arm-none-eabi-g++ 79 | else 80 | $(call show_config_variable,CXX_NAME,[COMPUTED]) 81 | endif 82 | endif 83 | 84 | ifndef AS_NAME 85 | AS_NAME := $(call PARSE_TEENSY,$(BOARD_TAG),build.command.as) 86 | ifndef AS_NAME 87 | AS_NAME := arm-none-eabi-gcc-as 88 | else 89 | $(call show_config_variable,AS_NAME,[COMPUTED]) 90 | endif 91 | endif 92 | 93 | ifndef OBJCOPY_NAME 94 | OBJCOPY_NAME := $(call PARSE_TEENSY,$(BOARD_TAG),build.command.objcopy) 95 | ifndef OBJCOPY_NAME 96 | OBJCOPY_NAME := arm-none-eabi-objcopy 97 | else 98 | $(call show_config_variable,OBJCOPY_NAME,[COMPUTED]) 99 | endif 100 | endif 101 | 102 | ifndef OBJDUMP_NAME 103 | OBJDUMP_NAME := $(call PARSE_TEENSY,$(BOARD_TAG),build.command.objdump) 104 | ifndef OBJDUMP_NAME 105 | OBJDUMP_NAME := arm-none-eabi-objdump 106 | else 107 | $(call show_config_variable,OBJDUMP_NAME,[COMPUTED]) 108 | endif 109 | endif 110 | 111 | ifndef AR_NAME 112 | AR_NAME := $(call PARSE_TEENSY,$(BOARD_TAG),build.command.ar) 113 | ifndef AR_NAME 114 | AR_NAME := arm-none-eabi-ar 115 | else 116 | $(call show_config_variable,AR_NAME,[COMPUTED]) 117 | endif 118 | endif 119 | 120 | ifndef SIZE_NAME 121 | SIZE_NAME := $(call PARSE_TEENSY,$(BOARD_TAG),build.command.size) 122 | ifndef SIZE_NAME 123 | SIZE_NAME := arm-none-eabi-size 124 | else 125 | $(call show_config_variable,SIZE_NAME,[COMPUTED]) 126 | endif 127 | endif 128 | 129 | ifndef NM_NAME 130 | NM_NAME := $(call PARSE_TEENSY,$(BOARD_TAG),build.command.nm) 131 | ifndef NM_NAME 132 | NM_NAME := arm-none-eabi-gcc-nm 133 | else 134 | $(call show_config_variable,NM_NAME,[COMPUTED]) 135 | endif 136 | endif 137 | 138 | # processor stuff 139 | ifndef MCU 140 | MCU := $(call PARSE_TEENSY,$(BOARD_TAG),build.cpu) 141 | endif 142 | 143 | ifndef MCU_FLAG_NAME 144 | MCU_FLAG_NAME=mcpu 145 | endif 146 | 147 | ######################################################################## 148 | # FLAGS 149 | ifndef USB_TYPE 150 | USB_TYPE = USB_SERIAL 151 | endif 152 | 153 | CPPFLAGS += -DLAYOUT_US_ENGLISH -D$(USB_TYPE) 154 | 155 | CPPFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.option) 156 | 157 | CXXFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.cppoption) 158 | ifeq ("$(call PARSE_TEENSY,$(BOARD_TAG),build.gnu0x)","true") 159 | CXXFLAGS_STD += -std=gnu++0x 160 | endif 161 | 162 | ifeq ("$(call PARSE_TEENSY,$(BOARD_TAG),build.elide_constructors)", "true") 163 | CXXFLAGS += -felide-constructors 164 | endif 165 | 166 | CXXFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.common) 167 | CXXFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.cpu) 168 | CXXFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.defs) 169 | CXXFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.cpp) 170 | 171 | CFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.common) 172 | CFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.cpu) 173 | CFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.defs) 174 | 175 | ASFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.common) 176 | ASFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.cpu) 177 | ASFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.defs) 178 | ASFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.S) 179 | 180 | LDFLAGS += $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.cpu) 181 | 182 | AMCU := $(call PARSE_TEENSY,$(BOARD_TAG),build.mcu) 183 | LDFLAGS += -Wl,--gc-sections,--relax 184 | LINKER_SCRIPTS = -T${ARDUINO_CORE_PATH}/${AMCU}.ld 185 | OTHER_LIBS = $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.libs) 186 | 187 | CPUFLAGS = $(call PARSE_TEENSY,$(BOARD_TAG),build.flags.cpu) 188 | # usually defined as per teensy31.build.mcu=mk20dx256 but that isn't valid switch 189 | MCU := $(shell echo ${CPUFLAGS} | sed -n -e 's/.*-mcpu=\([a-zA-Z0-9_-]*\).*/\1/p') 190 | 191 | ######################################################################## 192 | # some fairly odd settings so that 'make upload' works 193 | # 194 | # may require additional patches for Windows support 195 | 196 | do_upload: override get_monitor_port="" 197 | AVRDUDE=@true 198 | RESET_CMD = nohup $(ARDUINO_DIR)/hardware/tools/teensy_post_compile -board=$(BOARD_TAG) -tools=$(abspath $(ARDUINO_DIR)/hardware/tools) -path=$(abspath $(OBJDIR)) -file=$(TARGET) > /dev/null ; $(ARDUINO_DIR)/hardware/tools/teensy_reboot 199 | 200 | ######################################################################## 201 | # automatially include Arduino.mk for the user 202 | 203 | include $(ARDMK_DIR)/Arduino.mk 204 | 205 | -------------------------------------------------------------------------------- /examples/auto-brake/NewPing.h: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------- 2 | // NewPing Library - v1.8 - 07/30/2016 3 | // 4 | // AUTHOR/LICENSE: 5 | // Created by Tim Eckel - teckel@leethost.com 6 | // Copyright 2016 License: GNU GPL v3 http://www.gnu.org/licenses/gpl.html 7 | // 8 | // LINKS: 9 | // Project home: https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home 10 | // Blog: http://arduino.cc/forum/index.php/topic,106043.0.html 11 | // 12 | // DISCLAIMER: 13 | // This software is furnished "as is", without technical support, and with no 14 | // warranty, express or implied, as to its usefulness for any purpose. 15 | // 16 | // BACKGROUND: 17 | // When I first received an ultrasonic sensor I was not happy with how poorly 18 | // it worked. Quickly I realized the problem wasn't the sensor, it was the 19 | // available ping and ultrasonic libraries causing the problem. The NewPing 20 | // library totally fixes these problems, adds many new features, and breaths 21 | // new life into these very affordable distance sensors. 22 | // 23 | // FEATURES: 24 | // * Works with many different ultrasonic sensors: SR04, SRF05, SRF06, DYP-ME007, URM37 & Parallax PING))). 25 | // * Compatible with the entire Arduino line-up (and clones), Teensy family (including $19 96Mhz 32 bit Teensy 3.2) and non-AVR microcontrollers. 26 | // * Interface with all but the SRF06 sensor using only one Arduino pin. 27 | // * Doesn't lag for a full second if no ping/echo is received. 28 | // * Ping sensors consistently and reliably at up to 30 times per second. 29 | // * Timer interrupt method for event-driven sketches. 30 | // * Built-in digital filter method ping_median() for easy error correction. 31 | // * Uses port registers for a faster pin interface and smaller code size. 32 | // * Allows you to set a maximum distance where pings beyond that distance are read as no ping "clear". 33 | // * Ease of using multiple sensors (example sketch with 15 sensors). 34 | // * More accurate distance calculation (cm, inches & uS). 35 | // * Doesn't use pulseIn, which is slow and gives incorrect results with some ultrasonic sensor models. 36 | // * Actively developed with features being added and bugs/issues addressed. 37 | // 38 | // CONSTRUCTOR: 39 | // NewPing sonar(trigger_pin, echo_pin [, max_cm_distance]) 40 | // trigger_pin & echo_pin - Arduino pins connected to sensor trigger and echo. 41 | // NOTE: To use the same Arduino pin for trigger and echo, specify the same pin for both values. 42 | // max_cm_distance - [Optional] Maximum distance you wish to sense. Default=500cm. 43 | // 44 | // METHODS: 45 | // sonar.ping([max_cm_distance]) - Send a ping and get the echo time (in microseconds) as a result. [max_cm_distance] allows you to optionally set a new max distance. 46 | // sonar.ping_in([max_cm_distance]) - Send a ping and get the distance in whole inches. [max_cm_distance] allows you to optionally set a new max distance. 47 | // sonar.ping_cm([max_cm_distance]) - Send a ping and get the distance in whole centimeters. [max_cm_distance] allows you to optionally set a new max distance. 48 | // sonar.ping_median(iterations [, max_cm_distance]) - Do multiple pings (default=5), discard out of range pings and return median in microseconds. [max_cm_distance] allows you to optionally set a new max distance. 49 | // NewPing::convert_in(echoTime) - Convert echoTime from microseconds to inches (rounds to nearest inch). 50 | // NewPing::convert_cm(echoTime) - Convert echoTime from microseconds to centimeters (rounds to nearest cm). 51 | // sonar.ping_timer(function [, max_cm_distance]) - Send a ping and call function to test if ping is complete. [max_cm_distance] allows you to optionally set a new max distance. 52 | // sonar.check_timer() - Check if ping has returned within the set distance limit. 53 | // NewPing::timer_us(frequency, function) - Call function every frequency microseconds. 54 | // NewPing::timer_ms(frequency, function) - Call function every frequency milliseconds. 55 | // NewPing::timer_stop() - Stop the timer. 56 | // 57 | // HISTORY: 58 | // 07/30/2016 v1.8 - Added support for non-AVR microcontrollers. For non-AVR 59 | // microcontrollers, advanced ping_timer() timer methods are disabled due to 60 | // inconsistencies or no support at all between platforms. However, standard 61 | // ping methods are all supported. Added new optional variable to ping(), 62 | // ping_in(), ping_cm(), ping_median(), and ping_timer() methods which allows 63 | // you to set a new maximum distance for each ping. Added support for the 64 | // ATmega16, ATmega32 and ATmega8535 microcontrollers. Changed convert_cm() 65 | // and convert_in() methods to static members. You can now call them without 66 | // an object. For example: cm = NewPing::convert_cm(distance); 67 | // 68 | // 09/29/2015 v1.7 - Removed support for the Arduino Due and Zero because 69 | // they're both 3.3 volt boards and are not 5 volt tolerant while the HC-SR04 70 | // is a 5 volt sensor. Also, the Due and Zero don't support pin manipulation 71 | // compatibility via port registers which can be done (see the Teensy 3.2). 72 | // 73 | // 06/17/2014 v1.6 - Corrected delay between pings when using ping_median() 74 | // method. Added support for the URM37 sensor (must change URM37_ENABLED from 75 | // false to true). Added support for Arduino microcontrollers like the $20 76 | // 32 bit ARM Cortex-M4 based Teensy 3.2. Added automatic support for the 77 | // Atmel ATtiny family of microcontrollers. Added timer support for the 78 | // ATmega8 microcontroller. Rounding disabled by default, reduces compiled 79 | // code size (can be turned on with ROUNDING_ENABLED switch). Added 80 | // TIMER_ENABLED switch to get around compile-time "__vector_7" errors when 81 | // using the Tone library, or you can use the toneAC, NewTone or 82 | // TimerFreeTone libraries: https://bitbucket.org/teckel12/arduino-toneac/ 83 | // Other speed and compiled size optimizations. 84 | // 85 | // 08/15/2012 v1.5 - Added ping_median() method which does a user specified 86 | // number of pings (default=5) and returns the median ping in microseconds 87 | // (out of range pings ignored). This is a very effective digital filter. 88 | // Optimized for smaller compiled size (even smaller than sketches that 89 | // don't use a library). 90 | // 91 | // 07/14/2012 v1.4 - Added support for the Parallax PING)))� sensor. Interface 92 | // with all but the SRF06 sensor using only one Arduino pin. You can also 93 | // interface with the SRF06 using one pin if you install a 0.1uf capacitor 94 | // on the trigger and echo pins of the sensor then tie the trigger pin to 95 | // the Arduino pin (doesn't work with Teensy). To use the same Arduino pin 96 | // for trigger and echo, specify the same pin for both values. Various bug 97 | // fixes. 98 | // 99 | // 06/08/2012 v1.3 - Big feature addition, event-driven ping! Uses Timer2 100 | // interrupt, so be mindful of PWM or timing conflicts messing with Timer2 101 | // may cause (namely PWM on pins 3 & 11 on Arduino, PWM on pins 9 and 10 on 102 | // Mega, and Tone library). Simple to use timer interrupt functions you can 103 | // use in your sketches totally unrelated to ultrasonic sensors (don't use if 104 | // you're also using NewPing's ping_timer because both use Timer2 interrupts). 105 | // Loop counting ping method deleted in favor of timing ping method after 106 | // inconsistent results kept surfacing with the loop timing ping method. 107 | // Conversion to cm and inches now rounds to the nearest cm or inch. Code 108 | // optimized to save program space and fixed a couple minor bugs here and 109 | // there. Many new comments added as well as line spacing to group code 110 | // sections for better source readability. 111 | // 112 | // 05/25/2012 v1.2 - Lots of code clean-up thanks to Arduino Forum members. 113 | // Rebuilt the ping timing code from scratch, ditched the pulseIn code as it 114 | // doesn't give correct results (at least with ping sensors). The NewPing 115 | // library is now VERY accurate and the code was simplified as a bonus. 116 | // Smaller and faster code as well. Fixed some issues with very close ping 117 | // results when converting to inches. All functions now return 0 only when 118 | // there's no ping echo (out of range) and a positive value for a successful 119 | // ping. This can effectively be used to detect if something is out of range 120 | // or in-range and at what distance. Now compatible with Arduino 0023. 121 | // 122 | // 05/16/2012 v1.1 - Changed all I/O functions to use low-level port registers 123 | // for ultra-fast and lean code (saves from 174 to 394 bytes). Tested on both 124 | // the Arduino Uno and Teensy 2.0 but should work on all Arduino-based 125 | // platforms because it calls standard functions to retrieve port registers 126 | // and bit masks. Also made a couple minor fixes to defines. 127 | // 128 | // 05/15/2012 v1.0 - Initial release. 129 | // --------------------------------------------------------------------------- 130 | 131 | #ifndef NewPing_h 132 | #define NewPing_h 133 | 134 | #if defined (ARDUINO) && ARDUINO >= 100 135 | #include 136 | #else 137 | #include 138 | #include 139 | #endif 140 | 141 | #if defined (__AVR__) 142 | #include 143 | #include 144 | #endif 145 | 146 | // Shouldn't need to change these values unless you have a specific need to do so. 147 | #define MAX_SENSOR_DISTANCE 500 // Maximum sensor distance can be as high as 500cm, no reason to wait for ping longer than sound takes to travel this distance and back. Default=500 148 | #define US_ROUNDTRIP_CM 57 // Microseconds (uS) it takes sound to travel round-trip 1cm (2cm total), uses integer to save compiled code space. Default=57 149 | #define US_ROUNDTRIP_IN 146 // Microseconds (uS) it takes sound to travel round-trip 1 inch (2 inches total), uses integer to save compiled code space. Defalult=146 150 | #define ONE_PIN_ENABLED true // Set to "false" to disable one pin mode which saves around 14-26 bytes of binary size. Default=true 151 | #define ROUNDING_ENABLED false // Set to "true" to enable distance rounding which also adds 64 bytes to binary size. Default=false 152 | #define URM37_ENABLED false // Set to "true" to enable support for the URM37 sensor in PWM mode. Default=false 153 | // GG Disabled to avoid timer useage 154 | #define TIMER_ENABLED false // Set to "false" to disable the timer ISR (if getting "__vector_7" compile errors set this to false). Default=true 155 | 156 | // Probably shouldn't change these values unless you really know what you're doing. 157 | #define NO_ECHO 0 // Value returned if there's no ping echo within the specified MAX_SENSOR_DISTANCE or max_cm_distance. Default=0 158 | #define MAX_SENSOR_DELAY 5800 // Maximum uS it takes for sensor to start the ping. Default=5800 159 | #define ECHO_TIMER_FREQ 24 // Frequency to check for a ping echo (every 24uS is about 0.4cm accuracy). Default=24 160 | #define PING_MEDIAN_DELAY 29000 // Microsecond delay between pings in the ping_median method. Default=29000 161 | #define PING_OVERHEAD 5 // Ping overhead in microseconds (uS). Default=5 162 | #define PING_TIMER_OVERHEAD 13 // Ping timer overhead in microseconds (uS). Default=13 163 | #if URM37_ENABLED == true 164 | #undef US_ROUNDTRIP_CM 165 | #undef US_ROUNDTRIP_IN 166 | #define US_ROUNDTRIP_CM 50 // Every 50uS PWM signal is low indicates 1cm distance. Default=50 167 | #define US_ROUNDTRIP_IN 127 // If 50uS is 1cm, 1 inch would be 127uS (50 x 2.54 = 127). Default=127 168 | #endif 169 | 170 | // Conversion from uS to distance (round result to nearest cm or inch). 171 | #define NewPingConvert(echoTime, conversionFactor) (max(((unsigned int)echoTime + conversionFactor / 2) / conversionFactor, (echoTime ? 1 : 0))) 172 | 173 | // Detect non-AVR microcontrollers (Teensy 3.x, Arduino DUE, etc.) and don't use port registers or timer interrupts as required. 174 | #if (defined (__arm__) && defined (TEENSYDUINO)) 175 | #undef PING_OVERHEAD 176 | #define PING_OVERHEAD 1 177 | #undef PING_TIMER_OVERHEAD 178 | #define PING_TIMER_OVERHEAD 1 179 | #define DO_BITWISE true 180 | #elif !defined (__AVR__) 181 | #undef PING_OVERHEAD 182 | #define PING_OVERHEAD 1 183 | #undef PING_TIMER_OVERHEAD 184 | #define PING_TIMER_OVERHEAD 1 185 | #undef TIMER_ENABLED 186 | #define TIMER_ENABLED false 187 | #define DO_BITWISE false 188 | #else 189 | #define DO_BITWISE true 190 | #endif 191 | 192 | // Disable the timer interrupts when using ATmega128 and all ATtiny microcontrollers. 193 | #if defined (__AVR_ATmega128__) || defined (__AVR_ATtiny24__) || defined (__AVR_ATtiny44__) || defined (__AVR_ATtiny84__) || defined (__AVR_ATtiny25__) || defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) || defined (__AVR_ATtiny261__) || defined (__AVR_ATtiny461__) || defined (__AVR_ATtiny861__) || defined (__AVR_ATtiny43U__) 194 | #undef TIMER_ENABLED 195 | #define TIMER_ENABLED false 196 | #endif 197 | 198 | // Define timers when using ATmega8, ATmega16, ATmega32 and ATmega8535 microcontrollers. 199 | #if defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega8535__) 200 | #define OCR2A OCR2 201 | #define TIMSK2 TIMSK 202 | #define OCIE2A OCIE2 203 | #endif 204 | 205 | class NewPing { 206 | public: 207 | NewPing(uint8_t trigger_pin, uint8_t echo_pin, unsigned int max_cm_distance = MAX_SENSOR_DISTANCE); 208 | unsigned int ping(unsigned int max_cm_distance = 0); 209 | unsigned long ping_cm(unsigned int max_cm_distance = 0); 210 | unsigned long ping_in(unsigned int max_cm_distance = 0); 211 | unsigned long ping_median(uint8_t it = 5, unsigned int max_cm_distance = 0); 212 | static unsigned int convert_cm(unsigned int echoTime); 213 | static unsigned int convert_in(unsigned int echoTime); 214 | #if TIMER_ENABLED == true 215 | void ping_timer(void (*userFunc)(void), unsigned int max_cm_distance = 0); 216 | boolean check_timer(); 217 | unsigned long ping_result; 218 | static void timer_us(unsigned int frequency, void (*userFunc)(void)); 219 | static void timer_ms(unsigned long frequency, void (*userFunc)(void)); 220 | static void timer_stop(); 221 | #endif 222 | private: 223 | boolean ping_trigger(); 224 | void set_max_distance(unsigned int max_cm_distance); 225 | #if TIMER_ENABLED == true 226 | boolean ping_trigger_timer(unsigned int trigger_delay); 227 | boolean ping_wait_timer(); 228 | static void timer_setup(); 229 | static void timer_ms_cntdwn(); 230 | #endif 231 | #if DO_BITWISE == true 232 | uint8_t _triggerBit; 233 | uint8_t _echoBit; 234 | volatile uint8_t *_triggerOutput; 235 | volatile uint8_t *_echoInput; 236 | volatile uint8_t *_triggerMode; 237 | #else 238 | uint8_t _triggerPin; 239 | uint8_t _echoPin; 240 | #endif 241 | unsigned int _maxEchoTime; 242 | unsigned long _max_time; 243 | }; 244 | 245 | 246 | #endif 247 | -------------------------------------------------------------------------------- /examples/auto-brake/NewPing.cpp: -------------------------------------------------------------------------------- 1 | // --------------------------------------------------------------------------- 2 | // Created by Tim Eckel - teckel@leethost.com 3 | // Copyright 2016 License: GNU GPL v3 http://www.gnu.org/licenses/gpl.html 4 | // 5 | // See "NewPing.h" for purpose, syntax, version history, links, and more. 6 | // --------------------------------------------------------------------------- 7 | 8 | #include "NewPing.h" 9 | 10 | 11 | // --------------------------------------------------------------------------- 12 | // NewPing constructor 13 | // --------------------------------------------------------------------------- 14 | 15 | NewPing::NewPing(uint8_t trigger_pin, uint8_t echo_pin, unsigned int max_cm_distance) { 16 | #if DO_BITWISE == true 17 | _triggerBit = digitalPinToBitMask(trigger_pin); // Get the port register bitmask for the trigger pin. 18 | _echoBit = digitalPinToBitMask(echo_pin); // Get the port register bitmask for the echo pin. 19 | 20 | _triggerOutput = portOutputRegister(digitalPinToPort(trigger_pin)); // Get the output port register for the trigger pin. 21 | _echoInput = portInputRegister(digitalPinToPort(echo_pin)); // Get the input port register for the echo pin. 22 | 23 | _triggerMode = (uint8_t *) portModeRegister(digitalPinToPort(trigger_pin)); // Get the port mode register for the trigger pin. 24 | #else 25 | _triggerPin = trigger_pin; 26 | _echoPin = echo_pin; 27 | #endif 28 | 29 | set_max_distance(max_cm_distance); // Call function to set the max sensor distance. 30 | 31 | #if (defined (__arm__) && defined (TEENSYDUINO)) || DO_BITWISE != true 32 | pinMode(echo_pin, INPUT); // Set echo pin to input (on Teensy 3.x (ARM), pins default to disabled, at least one pinMode() is needed for GPIO mode). 33 | pinMode(trigger_pin, OUTPUT); // Set trigger pin to output (on Teensy 3.x (ARM), pins default to disabled, at least one pinMode() is needed for GPIO mode). 34 | #endif 35 | 36 | #if defined (ARDUINO_AVR_YUN) 37 | pinMode(echo_pin, INPUT); // Set echo pin to input for the Arduino Yun, not sure why it doesn't default this way. 38 | #endif 39 | 40 | #if ONE_PIN_ENABLED != true && DO_BITWISE == true 41 | *_triggerMode |= _triggerBit; // Set trigger pin to output. 42 | #endif 43 | } 44 | 45 | 46 | // --------------------------------------------------------------------------- 47 | // Standard ping methods 48 | // --------------------------------------------------------------------------- 49 | 50 | unsigned int NewPing::ping(unsigned int max_cm_distance) { 51 | if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance. 52 | 53 | if (!ping_trigger()) return NO_ECHO; // Trigger a ping, if it returns false, return NO_ECHO to the calling function. 54 | 55 | #if URM37_ENABLED == true 56 | #if DO_BITWISE == true 57 | while (!(*_echoInput & _echoBit)) // Wait for the ping echo. 58 | #else 59 | while (!digitalRead(_echoPin)) // Wait for the ping echo. 60 | #endif 61 | if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance. 62 | #else 63 | #if DO_BITWISE == true 64 | while (*_echoInput & _echoBit) // Wait for the ping echo. 65 | #else 66 | while (digitalRead(_echoPin)) // Wait for the ping echo. 67 | #endif 68 | if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance. 69 | #endif 70 | 71 | return (micros() - (_max_time - _maxEchoTime) - PING_OVERHEAD); // Calculate ping time, include overhead. 72 | } 73 | 74 | 75 | unsigned long NewPing::ping_cm(unsigned int max_cm_distance) { 76 | unsigned long echoTime = NewPing::ping(max_cm_distance); // Calls the ping method and returns with the ping echo distance in uS. 77 | #if ROUNDING_ENABLED == false 78 | return (echoTime / US_ROUNDTRIP_CM); // Call the ping method and returns the distance in centimeters (no rounding). 79 | #else 80 | return NewPingConvert(echoTime, US_ROUNDTRIP_CM); // Convert uS to centimeters. 81 | #endif 82 | } 83 | 84 | 85 | unsigned long NewPing::ping_in(unsigned int max_cm_distance) { 86 | unsigned long echoTime = NewPing::ping(max_cm_distance); // Calls the ping method and returns with the ping echo distance in uS. 87 | #if ROUNDING_ENABLED == false 88 | return (echoTime / US_ROUNDTRIP_IN); // Call the ping method and returns the distance in inches (no rounding). 89 | #else 90 | return NewPingConvert(echoTime, US_ROUNDTRIP_IN); // Convert uS to inches. 91 | #endif 92 | } 93 | 94 | 95 | unsigned long NewPing::ping_median(uint8_t it, unsigned int max_cm_distance) { 96 | unsigned int uS[it], last; 97 | uint8_t j, i = 0; 98 | unsigned long t; 99 | uS[0] = NO_ECHO; 100 | 101 | while (i < it) { 102 | t = micros(); // Start ping timestamp. 103 | last = ping(max_cm_distance); // Send ping. 104 | 105 | if (last != NO_ECHO) { // Ping in range, include as part of median. 106 | if (i > 0) { // Don't start sort till second ping. 107 | for (j = i; j > 0 && uS[j - 1] < last; j--) // Insertion sort loop. 108 | uS[j] = uS[j - 1]; // Shift ping array to correct position for sort insertion. 109 | } else j = 0; // First ping is sort starting point. 110 | uS[j] = last; // Add last ping to array in sorted position. 111 | i++; // Move to next ping. 112 | } else it--; // Ping out of range, skip and don't include as part of median. 113 | 114 | if (i < it && micros() - t < PING_MEDIAN_DELAY) 115 | delay((PING_MEDIAN_DELAY + t - micros()) / 1000); // Millisecond delay between pings. 116 | 117 | } 118 | return (uS[it >> 1]); // Return the ping distance median. 119 | } 120 | 121 | 122 | // --------------------------------------------------------------------------- 123 | // Standard and timer interrupt ping method support functions (not called directly) 124 | // --------------------------------------------------------------------------- 125 | 126 | boolean NewPing::ping_trigger() { 127 | #if DO_BITWISE == true 128 | #if ONE_PIN_ENABLED == true 129 | *_triggerMode |= _triggerBit; // Set trigger pin to output. 130 | #endif 131 | 132 | *_triggerOutput &= ~_triggerBit; // Set the trigger pin low, should already be low, but this will make sure it is. 133 | delayMicroseconds(4); // Wait for pin to go low. 134 | *_triggerOutput |= _triggerBit; // Set trigger pin high, this tells the sensor to send out a ping. 135 | delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS. 136 | *_triggerOutput &= ~_triggerBit; // Set trigger pin back to low. 137 | 138 | #if ONE_PIN_ENABLED == true 139 | *_triggerMode &= ~_triggerBit; // Set trigger pin to input (when using one Arduino pin, this is technically setting the echo pin to input as both are tied to the same Arduino pin). 140 | #endif 141 | 142 | #if URM37_ENABLED == true 143 | if (!(*_echoInput & _echoBit)) return false; // Previous ping hasn't finished, abort. 144 | _max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!) 145 | while (*_echoInput & _echoBit) // Wait for ping to start. 146 | if (micros() > _max_time) return false; // Took too long to start, abort. 147 | #else 148 | if (*_echoInput & _echoBit) return false; // Previous ping hasn't finished, abort. 149 | _max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!) 150 | while (!(*_echoInput & _echoBit)) // Wait for ping to start. 151 | if (micros() > _max_time) return false; // Took too long to start, abort. 152 | #endif 153 | #else 154 | #if ONE_PIN_ENABLED == true 155 | pinMode(_triggerPin, OUTPUT); // Set trigger pin to output. 156 | #endif 157 | 158 | digitalWrite(_triggerPin, LOW); // Set the trigger pin low, should already be low, but this will make sure it is. 159 | delayMicroseconds(4); // Wait for pin to go low. 160 | digitalWrite(_triggerPin, HIGH); // Set trigger pin high, this tells the sensor to send out a ping. 161 | delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS. 162 | digitalWrite(_triggerPin, LOW); // Set trigger pin back to low. 163 | 164 | #if ONE_PIN_ENABLED == true 165 | pinMode(_triggerPin, INPUT); // Set trigger pin to input (when using one Arduino pin, this is technically setting the echo pin to input as both are tied to the same Arduino pin). 166 | #endif 167 | 168 | #if URM37_ENABLED == true 169 | if (!digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort. 170 | _max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!) 171 | while (digitalRead(_echoPin)) // Wait for ping to start. 172 | if (micros() > _max_time) return false; // Took too long to start, abort. 173 | #else 174 | if (digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort. 175 | _max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!) 176 | while (!digitalRead(_echoPin)) // Wait for ping to start. 177 | if (micros() > _max_time) return false; // Took too long to start, abort. 178 | #endif 179 | #endif 180 | 181 | _max_time = micros() + _maxEchoTime; // Ping started, set the time-out. 182 | return true; // Ping started successfully. 183 | } 184 | 185 | 186 | void NewPing::set_max_distance(unsigned int max_cm_distance) { 187 | #if ROUNDING_ENABLED == false 188 | _maxEchoTime = min(max_cm_distance + 1, (unsigned int) MAX_SENSOR_DISTANCE + 1) * US_ROUNDTRIP_CM; // Calculate the maximum distance in uS (no rounding). 189 | #else 190 | _maxEchoTime = min(max_cm_distance, (unsigned int) MAX_SENSOR_DISTANCE) * US_ROUNDTRIP_CM + (US_ROUNDTRIP_CM / 2); // Calculate the maximum distance in uS. 191 | #endif 192 | } 193 | 194 | 195 | #if TIMER_ENABLED == true && DO_BITWISE == true 196 | 197 | // --------------------------------------------------------------------------- 198 | // Timer interrupt ping methods (won't work with non-AVR, ATmega128 and all ATtiny microcontrollers) 199 | // --------------------------------------------------------------------------- 200 | 201 | void NewPing::ping_timer(void (*userFunc)(void), unsigned int max_cm_distance) { 202 | if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance. 203 | 204 | if (!ping_trigger()) return; // Trigger a ping, if it returns false, return without starting the echo timer. 205 | timer_us(ECHO_TIMER_FREQ, userFunc); // Set ping echo timer check every ECHO_TIMER_FREQ uS. 206 | } 207 | 208 | 209 | boolean NewPing::check_timer() { 210 | if (micros() > _max_time) { // Outside the time-out limit. 211 | timer_stop(); // Disable timer interrupt 212 | return false; // Cancel ping timer. 213 | } 214 | 215 | #if URM37_ENABLED == false 216 | if (!(*_echoInput & _echoBit)) { // Ping echo received. 217 | #else 218 | if (*_echoInput & _echoBit) { // Ping echo received. 219 | #endif 220 | timer_stop(); // Disable timer interrupt 221 | ping_result = (micros() - (_max_time - _maxEchoTime) - PING_TIMER_OVERHEAD); // Calculate ping time including overhead. 222 | return true; // Return ping echo true. 223 | } 224 | 225 | return false; // Return false because there's no ping echo yet. 226 | } 227 | 228 | 229 | // --------------------------------------------------------------------------- 230 | // Timer2/Timer4 interrupt methods (can be used for non-ultrasonic needs) 231 | // --------------------------------------------------------------------------- 232 | 233 | // Variables used for timer functions 234 | void (*intFunc)(); 235 | void (*intFunc2)(); 236 | unsigned long _ms_cnt_reset; 237 | volatile unsigned long _ms_cnt; 238 | #if defined(__arm__) && defined(TEENSYDUINO) 239 | IntervalTimer itimer; 240 | #endif 241 | 242 | 243 | void NewPing::timer_us(unsigned int frequency, void (*userFunc)(void)) { 244 | intFunc = userFunc; // User's function to call when there's a timer event. 245 | timer_setup(); // Configure the timer interrupt. 246 | 247 | #if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo). 248 | OCR4C = min((frequency>>2) - 1, 255); // Every count is 4uS, so divide by 4 (bitwise shift right 2) subtract one, then make sure we don't go over 255 limit. 249 | TIMSK4 = (1<>2) - 1, 255); // Every count is 4uS, so divide by 4 (bitwise shift right 2) subtract one, then make sure we don't go over 255 limit. 254 | TIMSK2 |= (1<, based on 7 | # M J Oldfield work: https://github.com/mjoldfield/Arduino-Makefile 8 | # 9 | # Copyright (C) 2010,2011,2012 Martin Oldfield , based on 10 | # work that is copyright Nicholas Zambetti, David A. Mellis & Hernando 11 | # Barragan. 12 | # 13 | # This file is free software; you can redistribute it and/or modify it 14 | # under the terms of the GNU Lesser General Public License as 15 | # published by the Free Software Foundation; either version 2.1 of the 16 | # License, or (at your option) any later version. 17 | # 18 | # Adapted from Arduino 0011 Makefile by M J Oldfield 19 | # 20 | # Original Arduino adaptation by mellis, eighthave, oli.keller 21 | # 22 | # Current version: 1.5.2 23 | # 24 | # Refer to HISTORY.md file for complete history of changes 25 | # 26 | ######################################################################## 27 | # 28 | # PATHS YOU NEED TO SET UP 29 | # 30 | # We need to worry about three different sorts of files: 31 | # 32 | # 1. The directory where the *.mk files are stored 33 | # => ARDMK_DIR 34 | # 35 | # 2. Things which are always in the Arduino distribution e.g. 36 | # boards.txt, libraries, etc. 37 | # => ARDUINO_DIR 38 | # 39 | # 3. Things which might be bundled with the Arduino distribution, but 40 | # might come from the system. Most of the toolchain is like this: 41 | # on Linux it is supplied by the system. 42 | # => AVR_TOOLS_DIR 43 | # 44 | # Having set these three variables, we can work out the rest assuming 45 | # that things are canonically arranged beneath the directories defined 46 | # above. 47 | # 48 | # On the Mac with IDE 1.0 you might want to set: 49 | # 50 | # ARDUINO_DIR = /Applications/Arduino.app/Contents/Resources/Java 51 | # ARDMK_DIR = /usr/local 52 | # 53 | # On the Mac with IDE 1.5+ you might want to set: 54 | # 55 | # ARDUINO_DIR = /Applications/Arduino.app/Contents/Java 56 | # ARDMK_DIR = /usr/local 57 | # 58 | # On Linux, you might prefer: 59 | # 60 | # ARDUINO_DIR = /usr/share/arduino 61 | # ARDMK_DIR = /usr/share/arduino 62 | # AVR_TOOLS_DIR = /usr 63 | # 64 | # On Windows declare this environmental variables using the windows 65 | # configuration options. Control Panel > System > Advanced system settings 66 | # Also take into account that when you set them you have to add '\' on 67 | # all spaces and special characters. 68 | # ARDUINO_DIR and AVR_TOOLS_DIR have to be relative and not absolute. 69 | # This are just examples, you have to adapt this variables accordingly to 70 | # your system. 71 | # 72 | # ARDUINO_DIR =../../../../../Arduino 73 | # AVR_TOOLS_DIR =../../../../../Arduino/hardware/tools/avr 74 | # ARDMK_DIR = /cygdrive/c/Users/"YourUser"/Arduino-Makefile 75 | # 76 | # On Windows it is highly recommended that you create a symbolic link directory 77 | # for avoiding using the normal directories name of windows such as 78 | # c:\Program Files (x86)\Arduino 79 | # For this use the command mklink on the console. 80 | # 81 | # 82 | # You can either set these up in the Makefile, or put them in your 83 | # environment e.g. in your .bashrc 84 | # 85 | # If you don't specify these, we can try to guess, but that might not work 86 | # or work the way you want it to. 87 | # 88 | # If you'd rather not see the configuration output, define ARDUINO_QUIET. 89 | # 90 | ######################################################################## 91 | # 92 | # DEPENDENCIES 93 | # 94 | # to reset a board the (python) pySerial program is used. 95 | # please install it prior to continue. 96 | # 97 | ######################################################################## 98 | # 99 | # STANDARD ARDUINO WORKFLOW 100 | # 101 | # Given a normal sketch directory, all you need to do is to create 102 | # a small Makefile which defines a few things, and then includes this one. 103 | # 104 | # For example: 105 | # 106 | # ARDUINO_LIBS = Ethernet SPI 107 | # BOARD_TAG = uno 108 | # MONITOR_PORT = /dev/cu.usb* 109 | # 110 | # include /usr/share/arduino/Arduino.mk 111 | # 112 | # Hopefully these will be self-explanatory but in case they're not: 113 | # 114 | # ARDUINO_LIBS - A list of any libraries used by the sketch (we 115 | # assume these are in $(ARDUINO_DIR)/hardware/libraries 116 | # or your sketchbook's libraries directory) 117 | # 118 | # MONITOR_PORT - The port where the Arduino can be found (only needed 119 | # when uploading) 120 | # 121 | # BOARD_TAG - The tag for the board e.g. uno or mega 122 | # 'make show_boards' shows a list 123 | # 124 | # If you have your additional libraries relative to your source, rather 125 | # than in your "sketchbook", also set USER_LIB_PATH, like this example: 126 | # 127 | # USER_LIB_PATH := $(realpath ../../libraries) 128 | # 129 | # If you've added the Arduino-Makefile repository to your git repo as a 130 | # submodule (or other similar arrangement), you might have lines like this 131 | # in your Makefile: 132 | # 133 | # ARDMK_DIR := $(realpath ../../tools/Arduino-Makefile) 134 | # include $(ARDMK_DIR)/Arduino.mk 135 | # 136 | # In any case, once this file has been created the typical workflow is just 137 | # 138 | # $ make upload 139 | # 140 | # All of the object files are created in the build-{BOARD_TAG} subdirectory 141 | # All sources should be in the current directory and can include: 142 | # - at most one .pde or .ino file which will be treated as C++ after 143 | # the standard Arduino header and footer have been affixed. 144 | # - any number of .c, .cpp, .s and .h files 145 | # 146 | # Included libraries are built in the build-{BOARD_TAG}/libs subdirectory. 147 | # 148 | # Besides make upload, there are a couple of other targets that are available. 149 | # Do make help to get the complete list of targets and their description 150 | # 151 | ######################################################################## 152 | # 153 | # SERIAL MONITOR 154 | # 155 | # The serial monitor just invokes the GNU screen program with suitable 156 | # options. For more information see screen (1) and search for 157 | # 'character special device'. 158 | # 159 | # The really useful thing to know is that ^A-k gets you out! 160 | # 161 | # The fairly useful thing to know is that you can bind another key to 162 | # escape too, by creating $HOME{.screenrc} containing e.g. 163 | # 164 | # bindkey ^C kill 165 | # 166 | # If you want to change the baudrate, just set MONITOR_BAUDRATE. If you 167 | # don't set it, it tries to read from the sketch. If it couldn't read 168 | # from the sketch, then it defaults to 9600 baud. 169 | # 170 | ######################################################################## 171 | # 172 | # ARDUINO WITH ISP 173 | # 174 | # You need to specify some details of your ISP programmer and might 175 | # also need to specify the fuse values: 176 | # 177 | # ISP_PROG = stk500v2 178 | # ISP_PORT = /dev/ttyACM0 179 | # 180 | # You might also need to set the fuse bits, but typically they'll be 181 | # read from boards.txt, based on the BOARD_TAG variable: 182 | # 183 | # ISP_LOCK_FUSE_PRE = 0x3f 184 | # ISP_LOCK_FUSE_POST = 0xcf 185 | # ISP_HIGH_FUSE = 0xdf 186 | # ISP_LOW_FUSE = 0xff 187 | # ISP_EXT_FUSE = 0x01 188 | # 189 | # You can specify to also upload the EEPROM file: 190 | # ISP_EEPROM = 1 191 | # 192 | # I think the fuses here are fine for uploading to the ATmega168 193 | # without bootloader. 194 | # 195 | # To actually do this upload use the ispload target: 196 | # 197 | # make ispload 198 | # 199 | # 200 | ######################################################################## 201 | # 202 | # ALTERNATIVE CORES 203 | # 204 | # To use alternative cores for platforms such as ATtiny, you need to 205 | # specify a few more variables, depending on the core in use. 206 | # 207 | # The HLT (attiny-master) core can be used just by specifying 208 | # ALTERNATE_CORE, assuming your core is in your ~/sketchbook/hardware 209 | # directory. For example: 210 | # 211 | # ISP_PORT = /dev/ttyACM0 212 | # BOARD_TAG = attiny85 213 | # ALTERNATE_CORE = attiny-master 214 | # 215 | # To use the more complex arduino-tiny and TinyCore2 cores, you must 216 | # also set ARDUINO_CORE_PATH and ARDUINO_VAR_PATH to the core 217 | # directory, as these cores essentially replace the main Arduino core. 218 | # For example: 219 | # 220 | # ISP_PORT = /dev/ttyACM0 221 | # BOARD_TAG = attiny85at8 222 | # ALTERNATE_CORE = arduino-tiny 223 | # ARDUINO_VAR_PATH = ~/sketchbook/hardware/arduino-tiny/cores/tiny 224 | # ARDUINO_CORE_PATH = ~/sketchbook/hardware/arduino-tiny/cores/tiny 225 | # 226 | # or.... 227 | # 228 | # ISP_PORT = /dev/ttyACM0 229 | # BOARD_TAG = attiny861at8 230 | # ALTERNATE_CORE = tiny2 231 | # ARDUINO_VAR_PATH = ~/sketchbook/hardware/tiny2/cores/tiny 232 | # ARDUINO_CORE_PATH = ~/sketchbook/hardware/tiny2/cores/tiny 233 | # 234 | ######################################################################## 235 | 236 | arduino_output = 237 | # When output is not suppressed and we're in the top-level makefile, 238 | # running for the first time (i.e., not after a restart after 239 | # regenerating the dependency file), then output the configuration. 240 | ifndef ARDUINO_QUIET 241 | ifeq ($(MAKE_RESTARTS),) 242 | ifeq ($(MAKELEVEL),0) 243 | arduino_output = $(info $(1)) 244 | endif 245 | endif 246 | endif 247 | 248 | ######################################################################## 249 | # Makefile distribution path 250 | 251 | ifndef ARDMK_DIR 252 | # presume it's the same path to our own file 253 | ARDMK_DIR := $(realpath $(dir $(realpath $(lastword $(MAKEFILE_LIST))))) 254 | else 255 | # show_config_variable macro is defined in Common.mk file and is not available yet. 256 | # Let's define a variable to know that user specified ARDMK_DIR 257 | ARDMK_DIR_MSG = USER 258 | endif 259 | 260 | # include Common.mk now we know where it is 261 | include $(ARDMK_DIR)/Common.mk 262 | 263 | # show_config_variable macro is available now. So let's print config details for ARDMK_DIR 264 | ifndef ARDMK_DIR_MSG 265 | $(call show_config_variable,ARDMK_DIR,[COMPUTED],(relative to $(notdir $(lastword $(MAKEFILE_LIST))))) 266 | else 267 | $(call show_config_variable,ARDMK_DIR,[USER]) 268 | endif 269 | 270 | ######################################################################## 271 | # Default TARGET to pwd (ex Daniele Vergini) 272 | 273 | ifndef TARGET 274 | space := 275 | space += 276 | TARGET = $(notdir $(subst $(space),_,$(CURDIR))) 277 | endif 278 | 279 | ######################################################################## 280 | # Arduino version number 281 | 282 | ifndef ARDUINO_VERSION 283 | # Remove all the decimals, remove anything before/including ":", remove anything after/including "+" and finally grab the last 5 bytes. 284 | # Works for 1.0 and 1.0.1 and 1.6.10 and debian-style 2:1.0.5+dfsg2-4 285 | VERSION_FILE := $(ARDUINO_DIR)/lib/version.txt 286 | AUTO_ARDUINO_VERSION := $(shell [ -e $(VERSION_FILE) ] && cat $(VERSION_FILE) | sed -e 's/^[0-9]://g' -e 's/[.]//g' -e 's/\+.*//g' | head -c5) 287 | ifdef AUTO_ARDUINO_VERSION 288 | ARDUINO_VERSION = $(AUTO_ARDUINO_VERSION) 289 | $(call show_config_variable,ARDUINO_VERSION,[AUTODETECTED]) 290 | else 291 | ARDUINO_VERSION = 100 292 | $(call show_config_variable,ARDUINO_VERSION,[DEFAULT]) 293 | endif 294 | else 295 | $(call show_config_variable,ARDUINO_VERSION,[USER]) 296 | endif 297 | 298 | ######################################################################## 299 | # 1.5.x architecture - avr or sam for arduino vendor 300 | ifndef ARCHITECTURE 301 | ifeq ($(shell expr $(ARDUINO_VERSION) '>' 150), 1) 302 | # default to avr for 1.5 303 | ARCHITECTURE = avr 304 | ARDUINO_ARCH_FLAG = -DARDUINO_ARCH_AVR 305 | else 306 | # unset for 1.0 307 | ARCHITECTURE = 308 | endif 309 | $(call show_config_variable,ARCHITECTURE,[DEFAULT]) 310 | else 311 | $(call show_config_variable,ARCHITECTURE,[USER]) 312 | 313 | #avoid using shell for known architectures 314 | ifeq ($(ARCHITECTURE),avr) 315 | ARDUINO_ARCH_FLAG = -DARDUINO_ARCH_AVR 316 | else 317 | ifeq ($(ARCHITECTURE),sam) 318 | ARDUINO_ARCH_FLAG = -DARDUINO_ARCH_SAM 319 | else 320 | ARDUINO_ARCH_FLAG = -DARDUINO_ARCH_$(shell echo $(ARCHITECTURE) | tr '[:lower:]' '[:upper:]') 321 | endif 322 | endif 323 | endif 324 | 325 | ######################################################################## 326 | # 1.5.x vendor - defaults to arduino 327 | ifndef ARDMK_VENDOR 328 | ARDMK_VENDOR = arduino 329 | $(call show_config_variable,ARDMK_VENDOR,[DEFAULT]) 330 | else 331 | $(call show_config_variable,ARDMK_VENDOR,[USER]) 332 | endif 333 | 334 | ######################################################################## 335 | # Arduino Sketchbook folder 336 | 337 | ifndef ARDUINO_SKETCHBOOK 338 | ifndef ARDUINO_PREFERENCES_PATH 339 | ifeq ($(shell expr $(ARDUINO_VERSION) '>' 150), 1) 340 | AUTO_ARDUINO_PREFERENCES := $(firstword \ 341 | $(call dir_if_exists,$(HOME)/.arduino15/preferences.txt) \ 342 | $(call dir_if_exists,$(HOME)/Library/Arduino15/preferences.txt) ) 343 | else 344 | AUTO_ARDUINO_PREFERENCES := $(firstword \ 345 | $(call dir_if_exists,$(HOME)/.arduino/preferences.txt) \ 346 | $(call dir_if_exists,$(HOME)/Library/Arduino/preferences.txt) ) 347 | endif 348 | 349 | ifdef AUTO_ARDUINO_PREFERENCES 350 | ARDUINO_PREFERENCES_PATH = $(AUTO_ARDUINO_PREFERENCES) 351 | $(call show_config_variable,ARDUINO_PREFERENCES_PATH,[AUTODETECTED]) 352 | endif 353 | 354 | else 355 | $(call show_config_variable,ARDUINO_PREFERENCES_PATH,[USER]) 356 | endif 357 | 358 | ifneq ($(ARDUINO_PREFERENCES_PATH),) 359 | ARDUINO_SKETCHBOOK := $(shell grep --max-count=1 --regexp='sketchbook.path=' \ 360 | $(ARDUINO_PREFERENCES_PATH) | \ 361 | sed -e 's/sketchbook.path=//' ) 362 | endif 363 | 364 | ifneq ($(ARDUINO_SKETCHBOOK),) 365 | $(call show_config_variable,ARDUINO_SKETCHBOOK,[AUTODETECTED],(from arduino preferences file)) 366 | else 367 | ARDUINO_SKETCHBOOK := $(firstword \ 368 | $(call dir_if_exists,$(HOME)/sketchbook) \ 369 | $(call dir_if_exists,$(HOME)/Documents/Arduino) ) 370 | $(call show_config_variable,ARDUINO_SKETCHBOOK,[DEFAULT]) 371 | endif 372 | else 373 | $(call show_config_variable,ARDUINO_SKETCHBOOK,[USER]) 374 | endif 375 | 376 | ######################################################################## 377 | # Arduino and system paths 378 | 379 | ifndef CC_NAME 380 | CC_NAME = avr-gcc 381 | endif 382 | 383 | ifndef CXX_NAME 384 | CXX_NAME = avr-g++ 385 | endif 386 | 387 | ifndef OBJCOPY_NAME 388 | OBJCOPY_NAME = avr-objcopy 389 | endif 390 | 391 | ifndef OBJDUMP_NAME 392 | OBJDUMP_NAME = avr-objdump 393 | endif 394 | 395 | ifndef SIZE_NAME 396 | SIZE_NAME = avr-size 397 | endif 398 | 399 | ifndef NM_NAME 400 | NM_NAME = avr-nm 401 | endif 402 | 403 | ifndef AVR_TOOLS_DIR 404 | 405 | BUNDLED_AVR_TOOLS_DIR := $(call dir_if_exists,$(ARDUINO_DIR)/hardware/tools/avr) 406 | 407 | ifdef BUNDLED_AVR_TOOLS_DIR 408 | AVR_TOOLS_DIR = $(BUNDLED_AVR_TOOLS_DIR) 409 | $(call show_config_variable,AVR_TOOLS_DIR,[BUNDLED],(in Arduino distribution)) 410 | 411 | # In Linux distribution of Arduino, the path to avrdude and avrdude.conf are different 412 | # More details at https://github.com/sudar/Arduino-Makefile/issues/48 and 413 | # https://groups.google.com/a/arduino.cc/d/msg/developers/D_m97jGr8Xs/uQTt28KO_8oJ 414 | ifeq ($(CURRENT_OS),LINUX) 415 | 416 | ifndef AVRDUDE 417 | ifeq ($(shell expr $(ARDUINO_VERSION) '>' 157), 1) 418 | # 1.5.8 has different location than all prior versions! 419 | AVRDUDE = $(AVR_TOOLS_DIR)/bin/avrdude 420 | else 421 | AVRDUDE = $(AVR_TOOLS_DIR)/../avrdude 422 | endif 423 | endif 424 | 425 | ifndef AVRDUDE_CONF 426 | ifeq ($(shell expr $(ARDUINO_VERSION) '>' 157), 1) 427 | AVRDUDE_CONF = $(AVR_TOOLS_DIR)/etc/avrdude.conf 428 | else 429 | AVRDUDE_CONF = $(AVR_TOOLS_DIR)/../avrdude.conf 430 | endif 431 | endif 432 | 433 | else 434 | 435 | ifndef AVRDUDE_CONF 436 | AVRDUDE_CONF = $(AVR_TOOLS_DIR)/etc/avrdude.conf 437 | endif 438 | 439 | endif 440 | 441 | else 442 | 443 | SYSTEMPATH_AVR_TOOLS_DIR := $(call dir_if_exists,$(abspath $(dir $(shell which $(CC_NAME)))/..)) 444 | ifdef SYSTEMPATH_AVR_TOOLS_DIR 445 | AVR_TOOLS_DIR = $(SYSTEMPATH_AVR_TOOLS_DIR) 446 | $(call show_config_variable,AVR_TOOLS_DIR,[AUTODETECTED],(found in $$PATH)) 447 | else 448 | echo $(error No AVR tools directory found) 449 | endif # SYSTEMPATH_AVR_TOOLS_DIR 450 | 451 | endif # BUNDLED_AVR_TOOLS_DIR 452 | 453 | else 454 | $(call show_config_variable,AVR_TOOLS_DIR,[USER]) 455 | 456 | # ensure we can still find avrdude.conf 457 | ifndef AVRDUDE_CONF 458 | ifeq ($(shell expr $(ARDUINO_VERSION) '>' 157), 1) 459 | AVRDUDE_CONF = $(AVR_TOOLS_DIR)/etc/avrdude.conf 460 | else 461 | AVRDUDE_CONF = $(AVR_TOOLS_DIR)/../avrdude.conf 462 | endif 463 | endif 464 | 465 | endif #ndef AVR_TOOLS_DIR 466 | 467 | ifndef AVR_TOOLS_PATH 468 | AVR_TOOLS_PATH = $(AVR_TOOLS_DIR)/bin 469 | endif 470 | 471 | ifndef ARDUINO_LIB_PATH 472 | ARDUINO_LIB_PATH = $(ARDUINO_DIR)/libraries 473 | $(call show_config_variable,ARDUINO_LIB_PATH,[COMPUTED],(from ARDUINO_DIR)) 474 | else 475 | $(call show_config_variable,ARDUINO_LIB_PATH,[USER]) 476 | endif 477 | 478 | # 1.5.x platform dependent libs path 479 | ifndef ARDUINO_PLATFORM_LIB_PATH 480 | ifeq ($(shell expr $(ARDUINO_VERSION) '>' 150), 1) 481 | # only for 1.5 482 | ARDUINO_PLATFORM_LIB_PATH = $(ARDUINO_DIR)/hardware/$(ARDMK_VENDOR)/$(ARCHITECTURE)/libraries 483 | $(call show_config_variable,ARDUINO_PLATFORM_LIB_PATH,[COMPUTED],(from ARDUINO_DIR)) 484 | endif 485 | else 486 | $(call show_config_variable,ARDUINO_PLATFORM_LIB_PATH,[USER]) 487 | endif 488 | 489 | # Third party hardware and core like ATtiny or ATmega 16 490 | ifdef ALTERNATE_CORE 491 | $(call show_config_variable,ALTERNATE_CORE,[USER]) 492 | 493 | ifndef ALTERNATE_CORE_PATH 494 | ALTERNATE_CORE_PATH = $(ARDUINO_SKETCHBOOK)/hardware/$(ALTERNATE_CORE)/$(ARCHITECTURE) 495 | endif 496 | endif 497 | 498 | ifdef ALTERNATE_CORE_PATH 499 | 500 | ifdef ALTERNATE_CORE 501 | $(call show_config_variable,ALTERNATE_CORE_PATH,[COMPUTED], (from ARDUINO_SKETCHBOOK and ALTERNATE_CORE)) 502 | else 503 | $(call show_config_variable,ALTERNATE_CORE_PATH,[USER]) 504 | endif 505 | 506 | ifndef ARDUINO_VAR_PATH 507 | ARDUINO_VAR_PATH = $(ALTERNATE_CORE_PATH)/variants 508 | $(call show_config_variable,ARDUINO_VAR_PATH,[COMPUTED],(from ALTERNATE_CORE_PATH)) 509 | endif 510 | 511 | ifndef BOARDS_TXT 512 | BOARDS_TXT = $(ALTERNATE_CORE_PATH)/boards.txt 513 | $(call show_config_variable,BOARDS_TXT,[COMPUTED],(from ALTERNATE_CORE_PATH)) 514 | endif 515 | 516 | else 517 | 518 | ifndef ARDUINO_VAR_PATH 519 | ARDUINO_VAR_PATH = $(ARDUINO_DIR)/hardware/$(ARDMK_VENDOR)/$(ARCHITECTURE)/variants 520 | $(call show_config_variable,ARDUINO_VAR_PATH,[COMPUTED],(from ARDUINO_DIR)) 521 | else 522 | $(call show_config_variable,ARDUINO_VAR_PATH,[USER]) 523 | endif 524 | 525 | ifndef BOARDS_TXT 526 | BOARDS_TXT = $(ARDUINO_DIR)/hardware/$(ARDMK_VENDOR)/$(ARCHITECTURE)/boards.txt 527 | $(call show_config_variable,BOARDS_TXT,[COMPUTED],(from ARDUINO_DIR)) 528 | else 529 | $(call show_config_variable,BOARDS_TXT,[USER]) 530 | endif 531 | 532 | endif 533 | 534 | ######################################################################## 535 | # Miscellaneous 536 | 537 | ifndef USER_LIB_PATH 538 | USER_LIB_PATH = $(ARDUINO_SKETCHBOOK)/libraries 539 | $(call show_config_variable,USER_LIB_PATH,[DEFAULT],(in user sketchbook)) 540 | else 541 | $(call show_config_variable,USER_LIB_PATH,[USER]) 542 | endif 543 | 544 | ifndef PRE_BUILD_HOOK 545 | PRE_BUILD_HOOK = pre-build-hook.sh 546 | $(call show_config_variable,PRE_BUILD_HOOK,[DEFAULT]) 547 | else 548 | $(call show_config_variable,PRE_BUILD_HOOK,[USER]) 549 | endif 550 | 551 | ######################################################################## 552 | # boards.txt parsing 553 | 554 | ifdef BOARD_SUB 555 | BOARD_SUB := $(strip $(BOARD_SUB)) 556 | $(call show_config_variable,BOARD_SUB,[USER]) 557 | endif 558 | 559 | ifndef BOARD_TAG 560 | BOARD_TAG = uno 561 | $(call show_config_variable,BOARD_TAG,[DEFAULT]) 562 | else 563 | # Strip the board tag of any extra whitespace, since it was causing the makefile to fail 564 | # https://github.com/sudar/Arduino-Makefile/issues/57 565 | BOARD_TAG := $(strip $(BOARD_TAG)) 566 | $(call show_config_variable,BOARD_TAG,[USER]) 567 | endif 568 | 569 | ifndef PARSE_BOARD 570 | # result = $(call READ_BOARD_TXT, 'boardname', 'parameter') 571 | PARSE_BOARD = $(shell grep -Ev '^\#' $(BOARDS_TXT) | grep -E "^[ \t]*$(1).$(2)=" | cut -d = -f 2 | cut -d : -f 2) 572 | endif 573 | 574 | # If NO_CORE is set, then we don't have to parse boards.txt file 575 | # But the user might have to define MCU, F_CPU etc 576 | ifeq ($(strip $(NO_CORE)),) 577 | 578 | # Select a core from the 'cores' directory. Two main values: 'arduino' or 579 | # 'robot', but can also hold 'tiny', for example, if using 580 | # https://code.google.com/p/arduino-tiny alternate core. 581 | ifndef CORE 582 | CORE = $(call PARSE_BOARD,$(BOARD_TAG),build.core) 583 | $(call show_config_variable,CORE,[COMPUTED],(from build.core)) 584 | else 585 | $(call show_config_variable,CORE,[USER]) 586 | endif 587 | 588 | # Which variant ? This affects the include path 589 | ifndef VARIANT 590 | VARIANT := $(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).build.variant) 591 | ifndef VARIANT 592 | VARIANT := $(call PARSE_BOARD,$(BOARD_TAG),build.variant) 593 | endif 594 | $(call show_config_variable,VARIANT,[COMPUTED],(from build.variant)) 595 | else 596 | $(call show_config_variable,VARIANT,[USER]) 597 | endif 598 | 599 | # see if we are a caterina device like leonardo or micro 600 | CATERINA := $(findstring caterina,$(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).bootloader.file)) 601 | ifndef CATERINA 602 | # 1.5+ method if not a submenu 603 | CATERINA := $(findstring caterina,$(call PARSE_BOARD,$(BOARD_TAG),bootloader.file)) 604 | endif 605 | ifndef CATERINA 606 | # 1.0 method uses deprecated bootloader.path 607 | CATERINA := $(findstring caterina,$(call PARSE_BOARD,$(BOARD_TAG),bootloader.path)) 608 | endif 609 | 610 | # processor stuff 611 | ifndef MCU 612 | MCU := $(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).build.mcu) 613 | ifndef MCU 614 | MCU := $(call PARSE_BOARD,$(BOARD_TAG),build.mcu) 615 | endif 616 | endif 617 | 618 | ifndef F_CPU 619 | F_CPU := $(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).build.f_cpu) 620 | ifndef F_CPU 621 | F_CPU := $(call PARSE_BOARD,$(BOARD_TAG),build.f_cpu) 622 | endif 623 | endif 624 | 625 | ifneq ($(CATERINA),) 626 | # USB IDs for the caterina devices like leonardo or micro 627 | ifndef USB_VID 628 | USB_VID = $(call PARSE_BOARD,$(BOARD_TAG),build.vid) 629 | endif 630 | 631 | ifndef USB_PID 632 | USB_PID = $(call PARSE_BOARD,$(BOARD_TAG),build.pid) 633 | endif 634 | endif 635 | 636 | # normal programming info 637 | ifndef AVRDUDE_ARD_PROGRAMMER 638 | AVRDUDE_ARD_PROGRAMMER := $(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).upload.protocol) 639 | ifndef AVRDUDE_ARD_PROGRAMMER 640 | AVRDUDE_ARD_PROGRAMMER := $(call PARSE_BOARD,$(BOARD_TAG),upload.protocol) 641 | endif 642 | endif 643 | 644 | ifndef AVRDUDE_ARD_BAUDRATE 645 | AVRDUDE_ARD_BAUDRATE := $(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).upload.speed) 646 | ifndef AVRDUDE_ARD_BAUDRATE 647 | AVRDUDE_ARD_BAUDRATE := $(call PARSE_BOARD,$(BOARD_TAG),upload.speed) 648 | endif 649 | endif 650 | 651 | # fuses if you're using e.g. ISP 652 | ifndef ISP_LOCK_FUSE_PRE 653 | ISP_LOCK_FUSE_PRE = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.unlock_bits) 654 | endif 655 | 656 | ifndef ISP_HIGH_FUSE 657 | ISP_HIGH_FUSE := $(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).bootloader.high_fuses) 658 | ifndef ISP_HIGH_FUSE 659 | ISP_HIGH_FUSE := $(call PARSE_BOARD,$(BOARD_TAG),bootloader.high_fuses) 660 | endif 661 | endif 662 | 663 | ifndef ISP_LOW_FUSE 664 | ISP_LOW_FUSE := $(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).bootloader.low_fuses) 665 | ifndef ISP_LOW_FUSE 666 | ISP_LOW_FUSE := $(call PARSE_BOARD,$(BOARD_TAG),bootloader.low_fuses) 667 | endif 668 | endif 669 | 670 | ifndef ISP_EXT_FUSE 671 | ISP_EXT_FUSE := $(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).bootloader.extended_fuses) 672 | ifndef ISP_EXT_FUSE 673 | ISP_EXT_FUSE := $(call PARSE_BOARD,$(BOARD_TAG),bootloader.extended_fuses) 674 | endif 675 | endif 676 | 677 | ifndef BOOTLOADER_PATH 678 | BOOTLOADER_PATH = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.path) 679 | endif 680 | 681 | ifndef BOOTLOADER_FILE 682 | BOOTLOADER_FILE := $(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).bootloader.file) 683 | ifndef BOOTLOADER_FILE 684 | BOOTLOADER_FILE := $(call PARSE_BOARD,$(BOARD_TAG),bootloader.file) 685 | endif 686 | endif 687 | 688 | ifndef ISP_LOCK_FUSE_POST 689 | ISP_LOCK_FUSE_POST = $(call PARSE_BOARD,$(BOARD_TAG),bootloader.lock_bits) 690 | endif 691 | 692 | ifndef HEX_MAXIMUM_SIZE 693 | HEX_MAXIMUM_SIZE := $(call PARSE_BOARD,$(BOARD_TAG),menu.(chip|cpu).$(BOARD_SUB).upload.maximum_size) 694 | ifndef HEX_MAXIMUM_SIZE 695 | HEX_MAXIMUM_SIZE := $(call PARSE_BOARD,$(BOARD_TAG),upload.maximum_size) 696 | endif 697 | endif 698 | 699 | endif 700 | 701 | # Everything gets built in here (include BOARD_TAG now) 702 | ifndef OBJDIR 703 | OBJDIR = build-$(BOARD_TAG) 704 | ifdef BOARD_SUB 705 | OBJDIR = build-$(BOARD_TAG)-$(BOARD_SUB) 706 | endif 707 | $(call show_config_variable,OBJDIR,[COMPUTED],(from BOARD_TAG)) 708 | else 709 | $(call show_config_variable,OBJDIR,[USER]) 710 | endif 711 | 712 | # Now that we have ARDUINO_DIR, ARDMK_VENDOR, ARCHITECTURE and CORE, 713 | # we can set ARDUINO_CORE_PATH. 714 | ifndef ARDUINO_CORE_PATH 715 | ifeq ($(strip $(CORE)),) 716 | ARDUINO_CORE_PATH = $(ARDUINO_DIR)/hardware/$(ARDMK_VENDOR)/$(ARCHITECTURE)/cores/arduino 717 | $(call show_config_variable,ARDUINO_CORE_PATH,[DEFAULT]) 718 | else 719 | ARDUINO_CORE_PATH = $(ALTERNATE_CORE_PATH)/cores/$(CORE) 720 | ifeq ($(wildcard $(ARDUINO_CORE_PATH)),) 721 | ARDUINO_CORE_PATH = $(ARDUINO_DIR)/hardware/$(ARDMK_VENDOR)/$(ARCHITECTURE)/cores/$(CORE) 722 | $(call show_config_variable,ARDUINO_CORE_PATH,[COMPUTED],(from ARDUINO_DIR, BOARD_TAG and boards.txt)) 723 | else 724 | $(call show_config_variable,ARDUINO_CORE_PATH,[COMPUTED],(from ALTERNATE_CORE_PATH, BOARD_TAG and boards.txt)) 725 | endif 726 | endif 727 | else 728 | $(call show_config_variable,ARDUINO_CORE_PATH,[USER]) 729 | endif 730 | 731 | ######################################################################## 732 | # Reset 733 | 734 | ifndef RESET_CMD 735 | ARD_RESET_ARDUINO := $(shell which ard-reset-arduino 2> /dev/null) 736 | ifndef ARD_RESET_ARDUINO 737 | # same level as *.mk in bin directory when checked out from git 738 | # or in $PATH when packaged 739 | ARD_RESET_ARDUINO = $(ARDMK_DIR)/bin/ard-reset-arduino 740 | endif 741 | ifneq ($(CATERINA),) 742 | ifneq (,$(findstring CYGWIN,$(shell uname -s))) 743 | RESET_CMD = $(ARD_RESET_ARDUINO) --caterina $(ARD_RESET_OPTS) $(DEVICE_PATH) 744 | else 745 | RESET_CMD = $(ARD_RESET_ARDUINO) --caterina $(ARD_RESET_OPTS) $(call get_monitor_port) 746 | endif 747 | else 748 | ifneq (,$(findstring CYGWIN,$(shell uname -s))) 749 | RESET_CMD = $(ARD_RESET_ARDUINO) $(ARD_RESET_OPTS) $(DEVICE_PATH) 750 | else 751 | RESET_CMD = $(ARD_RESET_ARDUINO) $(ARD_RESET_OPTS) $(call get_monitor_port) 752 | endif 753 | endif 754 | endif 755 | 756 | ifneq ($(CATERINA),) 757 | ERROR_ON_CATERINA = $(error On $(BOARD_TAG), raw_xxx operation is not supported) 758 | else 759 | ERROR_ON_CATERINA = 760 | endif 761 | 762 | ######################################################################## 763 | # Local sources 764 | 765 | LOCAL_C_SRCS ?= $(wildcard *.c) 766 | LOCAL_CPP_SRCS ?= $(wildcard *.cpp) 767 | LOCAL_CC_SRCS ?= $(wildcard *.cc) 768 | LOCAL_PDE_SRCS ?= $(wildcard *.pde) 769 | LOCAL_INO_SRCS ?= $(wildcard *.ino) 770 | LOCAL_AS_SRCS ?= $(wildcard *.S) 771 | LOCAL_SRCS = $(LOCAL_C_SRCS) $(LOCAL_CPP_SRCS) \ 772 | $(LOCAL_CC_SRCS) $(LOCAL_PDE_SRCS) \ 773 | $(LOCAL_INO_SRCS) $(LOCAL_AS_SRCS) 774 | LOCAL_OBJ_FILES = $(LOCAL_C_SRCS:.c=.c.o) $(LOCAL_CPP_SRCS:.cpp=.cpp.o) \ 775 | $(LOCAL_CC_SRCS:.cc=.cc.o) $(LOCAL_PDE_SRCS:.pde=.pde.o) \ 776 | $(LOCAL_INO_SRCS:.ino=.ino.o) $(LOCAL_AS_SRCS:.S=.S.o) 777 | LOCAL_OBJS = $(patsubst %,$(OBJDIR)/%,$(LOCAL_OBJ_FILES)) 778 | 779 | ifeq ($(words $(LOCAL_SRCS)), 0) 780 | $(error At least one source file (*.ino, *.pde, *.cpp, *c, *cc, *.S) is needed) 781 | endif 782 | 783 | # CHK_SOURCES is used by flymake 784 | # flymake creates a tmp file in the same directory as the file under edition 785 | # we must skip the verification in this particular case 786 | ifeq ($(strip $(CHK_SOURCES)),) 787 | ifeq ($(strip $(NO_CORE)),) 788 | 789 | # Ideally, this should just check if there are more than one file 790 | ifneq ($(words $(LOCAL_PDE_SRCS) $(LOCAL_INO_SRCS)), 1) 791 | ifeq ($(words $(LOCAL_PDE_SRCS) $(LOCAL_INO_SRCS)), 0) 792 | $(call show_config_info,No .pde or .ino files found. If you are compiling .c or .cpp files then you need to explicitly include Arduino header files) 793 | else 794 | #TODO: Support more than one file. https://github.com/sudar/Arduino-Makefile/issues/49 795 | $(error Need exactly one .pde or .ino file. This makefile doesn't support multiple .ino/.pde files yet) 796 | endif 797 | endif 798 | 799 | endif 800 | endif 801 | 802 | # core sources 803 | ifeq ($(strip $(NO_CORE)),) 804 | ifdef ARDUINO_CORE_PATH 805 | CORE_C_SRCS = $(wildcard $(ARDUINO_CORE_PATH)/*.c) 806 | CORE_C_SRCS += $(wildcard $(ARDUINO_CORE_PATH)/avr-libc/*.c) 807 | CORE_CPP_SRCS = $(wildcard $(ARDUINO_CORE_PATH)/*.cpp) 808 | CORE_AS_SRCS = $(wildcard $(ARDUINO_CORE_PATH)/*.S) 809 | 810 | ifneq ($(strip $(NO_CORE_MAIN_CPP)),) 811 | CORE_CPP_SRCS := $(filter-out %main.cpp, $(CORE_CPP_SRCS)) 812 | $(call show_config_info,NO_CORE_MAIN_CPP set so core library will not include main.cpp,[MANUAL]) 813 | endif 814 | 815 | CORE_OBJ_FILES = $(CORE_C_SRCS:.c=.c.o) $(CORE_CPP_SRCS:.cpp=.cpp.o) $(CORE_AS_SRCS:.S=.S.o) 816 | CORE_OBJS = $(patsubst $(ARDUINO_CORE_PATH)/%, \ 817 | $(OBJDIR)/core/%,$(CORE_OBJ_FILES)) 818 | endif 819 | else 820 | $(call show_config_info,NO_CORE set so core library will not be built,[MANUAL]) 821 | endif 822 | 823 | 824 | ######################################################################## 825 | # Determine ARDUINO_LIBS automatically 826 | 827 | ifndef ARDUINO_LIBS 828 | # automatically determine included libraries 829 | ARDUINO_LIBS += $(filter $(notdir $(wildcard $(ARDUINO_DIR)/libraries/*)), \ 830 | $(shell sed -ne 's/^ *\# *include *[<\"]\(.*\)\.h[>\"]/\1/p' $(LOCAL_SRCS))) 831 | ARDUINO_LIBS += $(filter $(notdir $(wildcard $(ARDUINO_SKETCHBOOK)/libraries/*)), \ 832 | $(shell sed -ne 's/^ *\# *include *[<\"]\(.*\)\.h[>\"]/\1/p' $(LOCAL_SRCS))) 833 | ARDUINO_LIBS += $(filter $(notdir $(wildcard $(USER_LIB_PATH)/*)), \ 834 | $(shell sed -ne 's/^ *\# *include *[<\"]\(.*\)\.h[>\"]/\1/p' $(LOCAL_SRCS))) 835 | ARDUINO_LIBS += $(filter $(notdir $(wildcard $(ARDUINO_PLATFORM_LIB_PATH)/*)), \ 836 | $(shell sed -ne 's/^ *\# *include *[<\"]\(.*\)\.h[>\"]/\1/p' $(LOCAL_SRCS))) 837 | endif 838 | 839 | ######################################################################## 840 | # Serial monitor (just a screen wrapper) 841 | 842 | # Quite how to construct the monitor command seems intimately tied 843 | # to the command we're using (here screen). So, read the screen docs 844 | # for more information (search for 'character special device'). 845 | 846 | ifeq ($(strip $(NO_CORE)),) 847 | ifndef MONITOR_BAUDRATE 848 | ifeq ($(words $(LOCAL_PDE_SRCS) $(LOCAL_INO_SRCS)), 1) 849 | SPEED = $(shell egrep -h 'Serial.begin *\([0-9]+\)' $(LOCAL_PDE_SRCS) $(LOCAL_INO_SRCS) | sed -e 's/[^0-9]//g'| head -n1) 850 | MONITOR_BAUDRATE = $(findstring $(SPEED),300 1200 2400 4800 9600 14400 19200 28800 38400 57600 115200) 851 | endif 852 | 853 | ifeq ($(MONITOR_BAUDRATE),) 854 | MONITOR_BAUDRATE = 9600 855 | $(call show_config_variable,MONITOR_BAUDRATE,[ASSUMED]) 856 | else 857 | $(call show_config_variable,MONITOR_BAUDRATE,[DETECTED], (in sketch)) 858 | endif 859 | else 860 | $(call show_config_variable,MONITOR_BAUDRATE, [USER]) 861 | endif 862 | 863 | ifndef MONITOR_CMD 864 | MONITOR_CMD = screen 865 | endif 866 | endif 867 | 868 | ######################################################################## 869 | # Include Arduino Header file 870 | 871 | ifndef ARDUINO_HEADER 872 | # We should check for Arduino version, not just the file extension 873 | # because, a .pde file can be used in Arduino 1.0 as well 874 | ifeq ($(shell expr $(ARDUINO_VERSION) '<' 100), 1) 875 | ARDUINO_HEADER=WProgram.h 876 | else 877 | ARDUINO_HEADER=Arduino.h 878 | endif 879 | endif 880 | 881 | ######################################################################## 882 | # Rules for making stuff 883 | 884 | # The name of the main targets 885 | TARGET_HEX = $(OBJDIR)/$(TARGET).hex 886 | TARGET_ELF = $(OBJDIR)/$(TARGET).elf 887 | TARGET_EEP = $(OBJDIR)/$(TARGET).eep 888 | CORE_LIB = $(OBJDIR)/libcore.a 889 | 890 | # Names of executables - chipKIT needs to override all to set paths to PIC32 891 | # tools, and we can't use "?=" assignment because these are already implicitly 892 | # defined by Make (e.g. $(CC) == cc). 893 | ifndef OVERRIDE_EXECUTABLES 894 | CC = $(AVR_TOOLS_PATH)/$(CC_NAME) 895 | CXX = $(AVR_TOOLS_PATH)/$(CXX_NAME) 896 | AS = $(AVR_TOOLS_PATH)/$(AS_NAME) 897 | OBJCOPY = $(AVR_TOOLS_PATH)/$(OBJCOPY_NAME) 898 | OBJDUMP = $(AVR_TOOLS_PATH)/$(OBJDUMP_NAME) 899 | AR = $(AVR_TOOLS_PATH)/$(AR_NAME) 900 | SIZE = $(AVR_TOOLS_PATH)/$(SIZE_NAME) 901 | NM = $(AVR_TOOLS_PATH)/$(NM_NAME) 902 | endif 903 | 904 | REMOVE = rm -rf 905 | MV = mv -f 906 | CAT = cat 907 | ECHO = printf 908 | MKDIR = mkdir -p 909 | 910 | # recursive wildcard function, call with params: 911 | # - start directory (finished with /) or empty string for current dir 912 | # - glob pattern 913 | # (taken from http://blog.jgc.org/2011/07/gnu-make-recursive-wildcard-function.html) 914 | rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) 915 | 916 | # functions used to determine various properties of library 917 | # called with library path. Needed because of differences between library 918 | # layouts in arduino 1.0.x and 1.5.x. 919 | # Assuming new 1.5.x layout when there is "src" subdirectory in main directory 920 | # and library.properties file 921 | 922 | # Gets include flags for library 923 | get_library_includes = $(if $(and $(wildcard $(1)/src), $(wildcard $(1)/library.properties)), \ 924 | -I$(1)/src, \ 925 | $(addprefix -I,$(1) $(wildcard $(1)/utility))) 926 | 927 | # Gets all sources with given extension (param2) for library (path = param1) 928 | # for old (1.0.x) layout looks in . and "utility" directories 929 | # for new (1.5.x) layout looks in src and recursively its subdirectories 930 | get_library_files = $(if $(and $(wildcard $(1)/src), $(wildcard $(1)/library.properties)), \ 931 | $(call rwildcard,$(1)/src/,*.$(2)), \ 932 | $(wildcard $(1)/*.$(2) $(1)/utility/*.$(2))) 933 | 934 | # General arguments 935 | USER_LIBS := $(sort $(wildcard $(patsubst %,$(USER_LIB_PATH)/%,$(ARDUINO_LIBS)))) 936 | USER_LIB_NAMES := $(patsubst $(USER_LIB_PATH)/%,%,$(USER_LIBS)) 937 | 938 | # Let user libraries override system ones. 939 | SYS_LIBS := $(sort $(wildcard $(patsubst %,$(ARDUINO_LIB_PATH)/%,$(filter-out $(USER_LIB_NAMES),$(ARDUINO_LIBS))))) 940 | SYS_LIB_NAMES := $(patsubst $(ARDUINO_LIB_PATH)/%,%,$(SYS_LIBS)) 941 | 942 | ifdef ARDUINO_PLATFORM_LIB_PATH 943 | PLATFORM_LIBS := $(sort $(wildcard $(patsubst %,$(ARDUINO_PLATFORM_LIB_PATH)/%,$(filter-out $(USER_LIB_NAMES),$(ARDUINO_LIBS))))) 944 | PLATFORM_LIB_NAMES := $(patsubst $(ARDUINO_PLATFORM_LIB_PATH)/%,%,$(PLATFORM_LIBS)) 945 | endif 946 | 947 | 948 | # Error here if any are missing. 949 | LIBS_NOT_FOUND = $(filter-out $(USER_LIB_NAMES) $(SYS_LIB_NAMES) $(PLATFORM_LIB_NAMES),$(ARDUINO_LIBS)) 950 | ifneq (,$(strip $(LIBS_NOT_FOUND))) 951 | ifdef ARDUINO_PLATFORM_LIB_PATH 952 | $(error The following libraries specified in ARDUINO_LIBS could not be found (searched USER_LIB_PATH, ARDUINO_LIB_PATH and ARDUINO_PLATFORM_LIB_PATH): $(LIBS_NOT_FOUND)) 953 | else 954 | $(error The following libraries specified in ARDUINO_LIBS could not be found (searched USER_LIB_PATH and ARDUINO_LIB_PATH): $(LIBS_NOT_FOUND)) 955 | endif 956 | endif 957 | 958 | SYS_INCLUDES := $(foreach lib, $(SYS_LIBS), $(call get_library_includes,$(lib))) 959 | USER_INCLUDES := $(foreach lib, $(USER_LIBS), $(call get_library_includes,$(lib))) 960 | LIB_C_SRCS := $(foreach lib, $(SYS_LIBS), $(call get_library_files,$(lib),c)) 961 | LIB_CPP_SRCS := $(foreach lib, $(SYS_LIBS), $(call get_library_files,$(lib),cpp)) 962 | LIB_AS_SRCS := $(foreach lib, $(SYS_LIBS), $(call get_library_files,$(lib),S)) 963 | USER_LIB_CPP_SRCS := $(foreach lib, $(USER_LIBS), $(call get_library_files,$(lib),cpp)) 964 | USER_LIB_C_SRCS := $(foreach lib, $(USER_LIBS), $(call get_library_files,$(lib),c)) 965 | USER_LIB_AS_SRCS := $(foreach lib, $(USER_LIBS), $(call get_library_files,$(lib),S)) 966 | LIB_OBJS = $(patsubst $(ARDUINO_LIB_PATH)/%.c,$(OBJDIR)/libs/%.c.o,$(LIB_C_SRCS)) \ 967 | $(patsubst $(ARDUINO_LIB_PATH)/%.cpp,$(OBJDIR)/libs/%.cpp.o,$(LIB_CPP_SRCS)) \ 968 | $(patsubst $(ARDUINO_LIB_PATH)/%.S,$(OBJDIR)/libs/%.S.o,$(LIB_AS_SRCS)) 969 | USER_LIB_OBJS = $(patsubst $(USER_LIB_PATH)/%.cpp,$(OBJDIR)/userlibs/%.cpp.o,$(USER_LIB_CPP_SRCS)) \ 970 | $(patsubst $(USER_LIB_PATH)/%.c,$(OBJDIR)/userlibs/%.c.o,$(USER_LIB_C_SRCS)) \ 971 | $(patsubst $(USER_LIB_PATH)/%.S,$(OBJDIR)/userlibs/%.S.o,$(USER_LIB_AS_SRCS)) 972 | 973 | ifdef ARDUINO_PLATFORM_LIB_PATH 974 | PLATFORM_INCLUDES := $(foreach lib, $(PLATFORM_LIBS), $(call get_library_includes,$(lib))) 975 | PLATFORM_LIB_CPP_SRCS := $(foreach lib, $(PLATFORM_LIBS), $(call get_library_files,$(lib),cpp)) 976 | PLATFORM_LIB_C_SRCS := $(foreach lib, $(PLATFORM_LIBS), $(call get_library_files,$(lib),c)) 977 | PLATFORM_LIB_AS_SRCS := $(foreach lib, $(PLATFORM_LIBS), $(call get_library_files,$(lib),S)) 978 | PLATFORM_LIB_OBJS := $(patsubst $(ARDUINO_PLATFORM_LIB_PATH)/%.cpp,$(OBJDIR)/platformlibs/%.cpp.o,$(PLATFORM_LIB_CPP_SRCS)) \ 979 | $(patsubst $(ARDUINO_PLATFORM_LIB_PATH)/%.c,$(OBJDIR)/platformlibs/%.c.o,$(PLATFORM_LIB_C_SRCS)) \ 980 | $(patsubst $(ARDUINO_PLATFORM_LIB_PATH)/%.S,$(OBJDIR)/platformlibs/%.S.o,$(PLATFORM_LIB_AS_SRCS)) 981 | 982 | endif 983 | 984 | # Dependency files 985 | DEPS = $(LOCAL_OBJS:.o=.d) $(LIB_OBJS:.o=.d) $(PLATFORM_OBJS:.o=.d) $(USER_LIB_OBJS:.o=.d) $(CORE_OBJS:.o=.d) 986 | 987 | # Optimization level for the compiler. 988 | # You can get the list of options at http://www.nongnu.org/avr-libc/user-manual/using_tools.html#gcc_optO 989 | # Also read http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_optflags 990 | ifndef OPTIMIZATION_LEVEL 991 | OPTIMIZATION_LEVEL=s 992 | $(call show_config_variable,OPTIMIZATION_LEVEL,[DEFAULT]) 993 | else 994 | $(call show_config_variable,OPTIMIZATION_LEVEL,[USER]) 995 | endif 996 | 997 | ifndef DEBUG_FLAGS 998 | DEBUG_FLAGS = -O0 -g 999 | endif 1000 | 1001 | # SoftwareSerial requires -Os (some delays are tuned for this optimization level) 1002 | %SoftwareSerial.cpp.o : OPTIMIZATION_FLAGS = -Os 1003 | 1004 | ifndef MCU_FLAG_NAME 1005 | MCU_FLAG_NAME = mmcu 1006 | $(call show_config_variable,MCU_FLAG_NAME,[DEFAULT]) 1007 | else 1008 | $(call show_config_variable,MCU_FLAG_NAME,[USER]) 1009 | endif 1010 | 1011 | # Using += instead of =, so that CPPFLAGS can be set per sketch level 1012 | CPPFLAGS += -$(MCU_FLAG_NAME)=$(MCU) -DF_CPU=$(F_CPU) -DARDUINO=$(ARDUINO_VERSION) $(ARDUINO_ARCH_FLAG) -D__PROG_TYPES_COMPAT__ \ 1013 | -I$(ARDUINO_CORE_PATH) -I$(ARDUINO_VAR_PATH)/$(VARIANT) \ 1014 | $(SYS_INCLUDES) $(PLATFORM_INCLUDES) $(USER_INCLUDES) -Wall -ffunction-sections \ 1015 | -fdata-sections 1016 | 1017 | ifdef DEBUG 1018 | OPTIMIZATION_FLAGS= $(DEBUG_FLAGS) 1019 | else 1020 | OPTIMIZATION_FLAGS = -O$(OPTIMIZATION_LEVEL) 1021 | endif 1022 | 1023 | CPPFLAGS += $(OPTIMIZATION_FLAGS) 1024 | 1025 | # USB IDs for the Caterina devices like leonardo or micro 1026 | ifneq ($(CATERINA),) 1027 | CPPFLAGS += -DUSB_VID=$(USB_VID) -DUSB_PID=$(USB_PID) 1028 | endif 1029 | 1030 | # avr-gcc version that we can do maths on 1031 | CC_VERNUM = $(shell $(CC) -dumpversion | sed 's/\.//g') 1032 | 1033 | # moved from above so we can find version-dependant ar 1034 | ifndef AR_NAME 1035 | ifeq ($(shell expr $(CC_VERNUM) '>' 490), 1) 1036 | AR_NAME = avr-gcc-ar 1037 | else 1038 | AR_NAME = avr-ar 1039 | endif 1040 | endif 1041 | 1042 | ifndef CFLAGS_STD 1043 | ifeq ($(shell expr $(CC_VERNUM) '>' 490), 1) 1044 | CFLAGS_STD = -std=gnu11 -flto -fno-fat-lto-objects 1045 | else 1046 | CFLAGS_STD = 1047 | endif 1048 | $(call show_config_variable,CFLAGS_STD,[DEFAULT]) 1049 | else 1050 | $(call show_config_variable,CFLAGS_STD,[USER]) 1051 | endif 1052 | 1053 | ifndef CXXFLAGS_STD 1054 | ifeq ($(shell expr $(CC_VERNUM) '>' 490), 1) 1055 | CXXFLAGS_STD = -std=gnu++11 -fno-threadsafe-statics -flto 1056 | else 1057 | CXXFLAGS_STD = 1058 | endif 1059 | $(call show_config_variable,CXXFLAGS_STD,[DEFAULT]) 1060 | else 1061 | $(call show_config_variable,CXXFLAGS_STD,[USER]) 1062 | endif 1063 | 1064 | CFLAGS += $(CFLAGS_STD) 1065 | CXXFLAGS += -fpermissive -fno-exceptions $(CXXFLAGS_STD) 1066 | ASFLAGS += -x assembler-with-cpp 1067 | ifeq ($(shell expr $(CC_VERNUM) '>' 490), 1) 1068 | ASFLAGS += -flto 1069 | endif 1070 | LDFLAGS += -$(MCU_FLAG_NAME)=$(MCU) -Wl,--gc-sections -O$(OPTIMIZATION_LEVEL) 1071 | ifeq ($(shell expr $(CC_VERNUM) '>' 490), 1) 1072 | LDFLAGS += -flto -fuse-linker-plugin 1073 | endif 1074 | SIZEFLAGS ?= --mcu=$(MCU) -C 1075 | 1076 | # for backwards compatibility, grab ARDUINO_PORT if the user has it set 1077 | # instead of MONITOR_PORT 1078 | MONITOR_PORT ?= $(ARDUINO_PORT) 1079 | 1080 | ifneq ($(strip $(MONITOR_PORT)),) 1081 | ifeq ($(CURRENT_OS), WINDOWS) 1082 | # Expect MONITOR_PORT to be '1' or 'com1' for COM1 in Windows. Split it up 1083 | # into the two styles required: /dev/ttyS* for ard-reset-arduino and com* 1084 | # for avrdude. This also could work with /dev/com* device names and be more 1085 | # consistent, but the /dev/com* is not recommended by Cygwin and doesn't 1086 | # always show up. 1087 | COM_PORT_ID = $(subst com,,$(MONITOR_PORT)) 1088 | COM_STYLE_MONITOR_PORT = com$(COM_PORT_ID) 1089 | DEVICE_PATH = /dev/ttyS$(shell awk 'BEGIN{ print $(COM_PORT_ID) - 1 }') 1090 | else 1091 | # set DEVICE_PATH based on user-defined MONITOR_PORT or ARDUINO_PORT 1092 | DEVICE_PATH = $(MONITOR_PORT) 1093 | endif 1094 | $(call show_config_variable,DEVICE_PATH,[COMPUTED],(from MONITOR_PORT)) 1095 | else 1096 | # If no port is specified, try to guess it from wildcards. 1097 | # Will only work if the Arduino is the only/first device matched. 1098 | DEVICE_PATH = $(firstword $(wildcard \ 1099 | /dev/ttyACM? /dev/ttyUSB? /dev/tty.usbserial* /dev/tty.usbmodem* /dev/tty.wchusbserial*)) 1100 | $(call show_config_variable,DEVICE_PATH,[AUTODETECTED]) 1101 | endif 1102 | 1103 | ifndef FORCE_MONITOR_PORT 1104 | $(call show_config_variable,FORCE_MONITOR_PORT,[DEFAULT]) 1105 | else 1106 | $(call show_config_variable,FORCE_MONITOR_PORT,[USER]) 1107 | endif 1108 | 1109 | ifdef FORCE_MONITOR_PORT 1110 | # Skips the DEVICE_PATH existance check. 1111 | get_monitor_port = $(DEVICE_PATH) 1112 | else 1113 | # Returns the Arduino port (first wildcard expansion) if it exists, otherwise it errors. 1114 | ifeq ($(CURRENT_OS), WINDOWS) 1115 | get_monitor_port = $(COM_STYLE_MONITOR_PORT) 1116 | else 1117 | get_monitor_port = $(if $(wildcard $(DEVICE_PATH)),$(firstword $(wildcard $(DEVICE_PATH))),$(error Arduino port $(DEVICE_PATH) not found!)) 1118 | endif 1119 | endif 1120 | 1121 | # Returns the ISP port (first wildcard expansion) if it exists, otherwise it errors. 1122 | get_isp_port = $(if $(wildcard $(ISP_PORT)),$(firstword $(wildcard $(ISP_PORT))),$(if $(findstring Xusb,X$(ISP_PORT)),$(ISP_PORT),$(error ISP port $(ISP_PORT) not found!))) 1123 | 1124 | # Command for avr_size: do $(call avr_size,elffile,hexfile) 1125 | ifneq (,$(findstring AVR,$(shell $(SIZE) --help))) 1126 | # We have a patched version of binutils that mentions AVR - pass the MCU 1127 | # and the elf to get nice output. 1128 | avr_size = $(SIZE) $(SIZEFLAGS) --format=avr $(1) 1129 | $(call show_config_info,Size utility: AVR-aware for enhanced output,[AUTODETECTED]) 1130 | else 1131 | # We have a plain-old binutils version - just give it the hex. 1132 | avr_size = $(SIZE) $(2) 1133 | $(call show_config_info,Size utility: Basic (not AVR-aware),[AUTODETECTED]) 1134 | endif 1135 | 1136 | ifneq (,$(strip $(ARDUINO_LIBS))) 1137 | $(call arduino_output,-) 1138 | $(call show_config_info,ARDUINO_LIBS =) 1139 | endif 1140 | 1141 | ifneq (,$(strip $(USER_LIB_NAMES))) 1142 | $(foreach lib,$(USER_LIB_NAMES),$(call show_config_info, $(lib),[USER])) 1143 | endif 1144 | 1145 | ifneq (,$(strip $(SYS_LIB_NAMES))) 1146 | $(foreach lib,$(SYS_LIB_NAMES),$(call show_config_info, $(lib),[SYSTEM])) 1147 | endif 1148 | 1149 | ifneq (,$(strip $(PLATFORM_LIB_NAMES))) 1150 | $(foreach lib,$(PLATFORM_LIB_NAMES),$(call show_config_info, $(lib),[PLATFORM])) 1151 | endif 1152 | 1153 | # either calculate parent dir from arduino dir, or user-defined path 1154 | ifndef BOOTLOADER_PARENT 1155 | BOOTLOADER_PARENT = $(ARDUINO_DIR)/hardware/$(ARDMK_VENDOR)/$(ARCHITECTURE)/bootloaders 1156 | $(call show_config_variable,BOOTLOADER_PARENT,[COMPUTED],(from ARDUINO_DIR)) 1157 | else 1158 | $(call show_config_variable,BOOTLOADER_PARENT,[USER]) 1159 | endif 1160 | 1161 | ######################################################################## 1162 | # Tools version info 1163 | ARDMK_VERSION = 1.5 1164 | $(call show_config_variable,ARDMK_VERSION,[COMPUTED]) 1165 | 1166 | CC_VERSION := $(shell $(CC) -dumpversion) 1167 | $(call show_config_variable,CC_VERSION,[COMPUTED],($(CC_NAME))) 1168 | 1169 | # end of config output 1170 | $(call show_separator) 1171 | 1172 | # Implicit rules for building everything (needed to get everything in 1173 | # the right directory) 1174 | # 1175 | # Rather than mess around with VPATH there are quasi-duplicate rules 1176 | # here for building e.g. a system C++ file and a local C++ 1177 | # file. Besides making things simpler now, this would also make it 1178 | # easy to change the build options in future 1179 | 1180 | # library sources 1181 | $(OBJDIR)/libs/%.c.o: $(ARDUINO_LIB_PATH)/%.c 1182 | @$(MKDIR) $(dir $@) 1183 | $(CC) -MMD -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 1184 | 1185 | $(OBJDIR)/libs/%.cpp.o: $(ARDUINO_LIB_PATH)/%.cpp 1186 | @$(MKDIR) $(dir $@) 1187 | $(CXX) -MMD -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1188 | 1189 | $(OBJDIR)/libs/%.S.o: $(ARDUINO_LIB_PATH)/%.S 1190 | @$(MKDIR) $(dir $@) 1191 | $(CC) -MMD -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ 1192 | 1193 | $(OBJDIR)/platformlibs/%.c.o: $(ARDUINO_PLATFORM_LIB_PATH)/%.c 1194 | @$(MKDIR) $(dir $@) 1195 | $(CC) -MMD -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 1196 | 1197 | $(OBJDIR)/platformlibs/%.cpp.o: $(ARDUINO_PLATFORM_LIB_PATH)/%.cpp 1198 | @$(MKDIR) $(dir $@) 1199 | $(CXX) -MMD -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1200 | 1201 | $(OBJDIR)/platformlibs/%.S.o: $(ARDUINO_PLATFORM_LIB_PATH)/%.S 1202 | @$(MKDIR) $(dir $@) 1203 | $(CC) -MMD -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ 1204 | 1205 | $(OBJDIR)/userlibs/%.cpp.o: $(USER_LIB_PATH)/%.cpp 1206 | @$(MKDIR) $(dir $@) 1207 | $(CXX) -MMD -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1208 | 1209 | $(OBJDIR)/userlibs/%.c.o: $(USER_LIB_PATH)/%.c 1210 | @$(MKDIR) $(dir $@) 1211 | $(CC) -MMD -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 1212 | 1213 | $(OBJDIR)/userlibs/%.S.o: $(USER_LIB_PATH)/%.S 1214 | @$(MKDIR) $(dir $@) 1215 | $(CC) -MMD -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ 1216 | 1217 | ifdef COMMON_DEPS 1218 | COMMON_DEPS := $(COMMON_DEPS) $(MAKEFILE_LIST) 1219 | else 1220 | COMMON_DEPS := $(MAKEFILE_LIST) 1221 | endif 1222 | 1223 | # normal local sources 1224 | $(OBJDIR)/%.c.o: %.c $(COMMON_DEPS) | $(OBJDIR) 1225 | @$(MKDIR) $(dir $@) 1226 | $(CC) -MMD -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 1227 | 1228 | $(OBJDIR)/%.cc.o: %.cc $(COMMON_DEPS) | $(OBJDIR) 1229 | @$(MKDIR) $(dir $@) 1230 | $(CXX) -MMD -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1231 | 1232 | $(OBJDIR)/%.cpp.o: %.cpp $(COMMON_DEPS) | $(OBJDIR) 1233 | @$(MKDIR) $(dir $@) 1234 | $(CXX) -MMD -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1235 | 1236 | $(OBJDIR)/%.S.o: %.S $(COMMON_DEPS) | $(OBJDIR) 1237 | @$(MKDIR) $(dir $@) 1238 | $(CC) -MMD -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ 1239 | 1240 | $(OBJDIR)/%.s.o: %.s $(COMMON_DEPS) | $(OBJDIR) 1241 | @$(MKDIR) $(dir $@) 1242 | $(CC) -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ 1243 | 1244 | # the pde -> o file 1245 | $(OBJDIR)/%.pde.o: %.pde $(COMMON_DEPS) | $(OBJDIR) 1246 | @$(MKDIR) $(dir $@) 1247 | $(CXX) -x c++ -include $(ARDUINO_HEADER) -MMD -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1248 | 1249 | # the ino -> o file 1250 | $(OBJDIR)/%.ino.o: %.ino $(COMMON_DEPS) | $(OBJDIR) 1251 | @$(MKDIR) $(dir $@) 1252 | $(CXX) -x c++ -include $(ARDUINO_HEADER) -MMD -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1253 | 1254 | # generated assembly 1255 | $(OBJDIR)/%.s: %.pde $(COMMON_DEPS) | $(OBJDIR) 1256 | @$(MKDIR) $(dir $@) 1257 | $(CXX) -x c++ -include $(ARDUINO_HEADER) -MMD -S -fverbose-asm $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1258 | 1259 | $(OBJDIR)/%.s: %.ino $(COMMON_DEPS) | $(OBJDIR) 1260 | @$(MKDIR) $(dir $@) 1261 | $(CXX) -x c++ -include $(ARDUINO_HEADER) -MMD -S -fverbose-asm $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1262 | 1263 | $(OBJDIR)/%.s: %.cpp $(COMMON_DEPS) | $(OBJDIR) 1264 | @$(MKDIR) $(dir $@) 1265 | $(CXX) -x c++ -MMD -S -fverbose-asm $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1266 | 1267 | # core files 1268 | $(OBJDIR)/core/%.c.o: $(ARDUINO_CORE_PATH)/%.c $(COMMON_DEPS) | $(OBJDIR) 1269 | @$(MKDIR) $(dir $@) 1270 | $(CC) -MMD -c $(CPPFLAGS) $(CFLAGS) $< -o $@ 1271 | 1272 | $(OBJDIR)/core/%.cpp.o: $(ARDUINO_CORE_PATH)/%.cpp $(COMMON_DEPS) | $(OBJDIR) 1273 | @$(MKDIR) $(dir $@) 1274 | $(CXX) -MMD -c $(CPPFLAGS) $(CXXFLAGS) $< -o $@ 1275 | 1276 | $(OBJDIR)/core/%.S.o: $(ARDUINO_CORE_PATH)/%.S $(COMMON_DEPS) | $(OBJDIR) 1277 | @$(MKDIR) $(dir $@) 1278 | $(CC) -MMD -c $(CPPFLAGS) $(ASFLAGS) $< -o $@ 1279 | 1280 | # various object conversions 1281 | $(OBJDIR)/%.hex: $(OBJDIR)/%.elf $(COMMON_DEPS) 1282 | @$(MKDIR) $(dir $@) 1283 | $(OBJCOPY) -O ihex -R .eeprom $< $@ 1284 | @$(ECHO) '\n' 1285 | $(call avr_size,$<,$@) 1286 | ifneq ($(strip $(HEX_MAXIMUM_SIZE)),) 1287 | @if [ `$(SIZE) $@ | awk 'FNR == 2 {print $$2}'` -le $(HEX_MAXIMUM_SIZE) ]; then touch $@.sizeok; fi 1288 | else 1289 | @$(ECHO) "Maximum flash memory of $(BOARD_TAG) is not specified. Make sure the size of $@ is less than $(BOARD_TAG)\'s flash memory" 1290 | @touch $@.sizeok 1291 | endif 1292 | 1293 | $(OBJDIR)/%.eep: $(OBJDIR)/%.elf $(COMMON_DEPS) 1294 | @$(MKDIR) $(dir $@) 1295 | -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom='alloc,load' \ 1296 | --no-change-warnings --change-section-lma .eeprom=0 -O ihex $< $@ 1297 | 1298 | $(OBJDIR)/%.lss: $(OBJDIR)/%.elf $(COMMON_DEPS) 1299 | @$(MKDIR) $(dir $@) 1300 | $(OBJDUMP) -h --source --demangle --wide $< > $@ 1301 | 1302 | $(OBJDIR)/%.sym: $(OBJDIR)/%.elf $(COMMON_DEPS) 1303 | @$(MKDIR) $(dir $@) 1304 | $(NM) --size-sort --demangle --reverse-sort --line-numbers $< > $@ 1305 | 1306 | ######################################################################## 1307 | # Avrdude 1308 | 1309 | # If avrdude is installed separately, it can find its own config file 1310 | ifndef AVRDUDE 1311 | AVRDUDE = $(AVR_TOOLS_PATH)/avrdude 1312 | endif 1313 | 1314 | # Default avrdude options 1315 | # -V Do not verify 1316 | # -q - suppress progress output 1317 | ifndef AVRDUDE_OPTS 1318 | AVRDUDE_OPTS = -q -V 1319 | endif 1320 | 1321 | # Decouple the mcu between the compiler options (-mmcu) and the avrdude options (-p). 1322 | # This is needed to be able to compile for attiny84a but specify the upload mcu as attiny84. 1323 | # We default to picking the -mmcu flag, but you can override this by setting 1324 | # AVRDUDE_MCU in your makefile. 1325 | ifndef AVRDUDE_MCU 1326 | AVRDUDE_MCU = $(MCU) 1327 | endif 1328 | 1329 | AVRDUDE_COM_OPTS = $(AVRDUDE_OPTS) -p $(AVRDUDE_MCU) 1330 | ifdef AVRDUDE_CONF 1331 | AVRDUDE_COM_OPTS += -C $(AVRDUDE_CONF) 1332 | endif 1333 | 1334 | # -D - Disable auto erase for flash memory 1335 | # Note: -D is needed for Mega boards. 1336 | # (See https://github.com/sudar/Arduino-Makefile/issues/114#issuecomment-25011005) 1337 | AVRDUDE_ARD_OPTS = -D -c $(AVRDUDE_ARD_PROGRAMMER) -b $(AVRDUDE_ARD_BAUDRATE) -P 1338 | ifeq ($(CURRENT_OS), WINDOWS) 1339 | # get_monitor_port checks to see if the monitor port exists, assuming it is 1340 | # a file. In Windows, avrdude needs the port in the format 'com1' which is 1341 | # not a file, so we have to add the COM-style port directly. 1342 | AVRDUDE_ARD_OPTS += $(COM_STYLE_MONITOR_PORT) 1343 | else 1344 | AVRDUDE_ARD_OPTS += $(call get_monitor_port) 1345 | endif 1346 | 1347 | ifndef ISP_PROG 1348 | ifneq ($(strip $(AVRDUDE_ARD_PROGRAMMER)),) 1349 | ISP_PROG = $(AVRDUDE_ARD_PROGRAMMER) 1350 | else 1351 | ISP_PROG = stk500v1 1352 | endif 1353 | endif 1354 | 1355 | ifndef AVRDUDE_ISP_BAUDRATE 1356 | ifneq ($(strip $(AVRDUDE_ARD_BAUDRATE)),) 1357 | AVRDUDE_ISP_BAUDRATE = $(AVRDUDE_ARD_BAUDRATE) 1358 | else 1359 | AVRDUDE_ISP_BAUDRATE = 19200 1360 | endif 1361 | endif 1362 | 1363 | # Fuse settings copied from Arduino IDE. 1364 | # https://github.com/arduino/Arduino/blob/master/app/src/processing/app/debug/AvrdudeUploader.java#L254 1365 | 1366 | # Pre fuse settings 1367 | ifndef AVRDUDE_ISP_FUSES_PRE 1368 | ifneq ($(strip $(ISP_LOCK_FUSE_PRE)),) 1369 | AVRDUDE_ISP_FUSES_PRE += -U lock:w:$(ISP_LOCK_FUSE_PRE):m 1370 | endif 1371 | 1372 | ifneq ($(strip $(ISP_EXT_FUSE)),) 1373 | AVRDUDE_ISP_FUSES_PRE += -U efuse:w:$(ISP_EXT_FUSE):m 1374 | endif 1375 | 1376 | ifneq ($(strip $(ISP_HIGH_FUSE)),) 1377 | AVRDUDE_ISP_FUSES_PRE += -U hfuse:w:$(ISP_HIGH_FUSE):m 1378 | endif 1379 | 1380 | ifneq ($(strip $(ISP_LOW_FUSE)),) 1381 | AVRDUDE_ISP_FUSES_PRE += -U lfuse:w:$(ISP_LOW_FUSE):m 1382 | endif 1383 | endif 1384 | 1385 | # Bootloader file settings 1386 | ifndef AVRDUDE_ISP_BURN_BOOTLOADER 1387 | ifneq ($(strip $(BOOTLOADER_FILE)),) 1388 | AVRDUDE_ISP_BURN_BOOTLOADER += -U flash:w:$(BOOTLOADER_PARENT)/$(BOOTLOADER_PATH)/$(BOOTLOADER_FILE):i 1389 | endif 1390 | endif 1391 | 1392 | # Post fuse settings 1393 | ifndef AVRDUDE_ISP_FUSES_POST 1394 | ifneq ($(strip $(ISP_LOCK_FUSE_POST)),) 1395 | AVRDUDE_ISP_FUSES_POST += -U lock:w:$(ISP_LOCK_FUSE_POST):m 1396 | endif 1397 | endif 1398 | 1399 | # Note: setting -D to disable flash erase before programming may cause issues 1400 | # with some boards like attiny84a, making the program not "take", 1401 | # so we do not set it by default. 1402 | AVRDUDE_ISP_OPTS = -c $(ISP_PROG) -b $(AVRDUDE_ISP_BAUDRATE) 1403 | 1404 | ifndef $(ISP_PORT) 1405 | ifneq ($(strip $(ISP_PROG)),$(filter $(ISP_PROG), usbasp usbtiny gpio linuxgpio avrispmkii dragon_isp dragon_dw)) 1406 | AVRDUDE_ISP_OPTS += -P $(call get_isp_port) 1407 | endif 1408 | else 1409 | AVRDUDE_ISP_OPTS += -P $(call get_isp_port) 1410 | endif 1411 | 1412 | ifndef ISP_EEPROM 1413 | ISP_EEPROM = 0 1414 | endif 1415 | 1416 | AVRDUDE_UPLOAD_HEX = -U flash:w:$(TARGET_HEX):i 1417 | AVRDUDE_UPLOAD_EEP = -U eeprom:w:$(TARGET_EEP):i 1418 | AVRDUDE_ISPLOAD_OPTS = $(AVRDUDE_UPLOAD_HEX) 1419 | 1420 | ifneq ($(ISP_EEPROM), 0) 1421 | AVRDUDE_ISPLOAD_OPTS += $(AVRDUDE_UPLOAD_EEP) 1422 | endif 1423 | 1424 | ######################################################################## 1425 | # Explicit targets start here 1426 | 1427 | all: $(TARGET_EEP) $(TARGET_HEX) 1428 | 1429 | # Rule to create $(OBJDIR) automatically. All rules with recipes that 1430 | # create a file within it, but do not already depend on a file within it 1431 | # should depend on this rule. They should use a "order-only 1432 | # prerequisite" (e.g., put "| $(OBJDIR)" at the end of the prerequisite 1433 | # list) to prevent remaking the target when any file in the directory 1434 | # changes. 1435 | $(OBJDIR): pre-build 1436 | $(MKDIR) $(OBJDIR) 1437 | 1438 | pre-build: 1439 | $(call runscript_if_exists,$(PRE_BUILD_HOOK)) 1440 | 1441 | $(TARGET_ELF): $(LOCAL_OBJS) $(CORE_LIB) $(OTHER_OBJS) 1442 | $(CC) $(LDFLAGS) -o $@ $(LOCAL_OBJS) $(CORE_LIB) $(OTHER_OBJS) $(OTHER_LIBS) -lc -lm $(LINKER_SCRIPTS) 1443 | 1444 | $(CORE_LIB): $(CORE_OBJS) $(LIB_OBJS) $(PLATFORM_LIB_OBJS) $(USER_LIB_OBJS) 1445 | $(AR) rcs $@ $(CORE_OBJS) $(LIB_OBJS) $(PLATFORM_LIB_OBJS) $(USER_LIB_OBJS) 1446 | 1447 | error_on_caterina: 1448 | $(ERROR_ON_CATERINA) 1449 | 1450 | 1451 | # Use submake so we can guarantee the reset happens 1452 | # before the upload, even with make -j 1453 | upload: $(TARGET_HEX) verify_size 1454 | $(MAKE) reset 1455 | $(MAKE) do_upload 1456 | 1457 | raw_upload: $(TARGET_HEX) verify_size 1458 | $(MAKE) error_on_caterina 1459 | $(MAKE) do_upload 1460 | 1461 | do_upload: 1462 | $(AVRDUDE) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ARD_OPTS) \ 1463 | $(AVRDUDE_UPLOAD_HEX) 1464 | 1465 | do_eeprom: $(TARGET_EEP) $(TARGET_HEX) 1466 | $(AVRDUDE) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ARD_OPTS) \ 1467 | $(AVRDUDE_UPLOAD_EEP) 1468 | 1469 | eeprom: $(TARGET_HEX) verify_size 1470 | $(MAKE) reset 1471 | $(MAKE) do_eeprom 1472 | 1473 | raw_eeprom: $(TARGET_HEX) verify_size 1474 | $(MAKE) error_on_caterina 1475 | $(MAKE) do_eeprom 1476 | 1477 | reset: 1478 | $(call arduino_output,Resetting Arduino...) 1479 | $(RESET_CMD) 1480 | 1481 | # stty on MacOS likes -F, but on Debian it likes -f redirecting 1482 | # stdin/out appears to work but generates a spurious error on MacOS at 1483 | # least. Perhaps it would be better to just do it in perl ? 1484 | reset_stty: 1485 | for STTYF in 'stty -F' 'stty --file' 'stty -f' 'stty <' ; \ 1486 | do $$STTYF /dev/tty >/dev/null 2>&1 && break ; \ 1487 | done ; \ 1488 | $$STTYF $(call get_monitor_port) hupcl ; \ 1489 | (sleep 0.1 2>/dev/null || sleep 1) ; \ 1490 | $$STTYF $(call get_monitor_port) -hupcl 1491 | 1492 | ispload: $(TARGET_EEP) $(TARGET_HEX) verify_size 1493 | $(AVRDUDE) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) \ 1494 | $(AVRDUDE_ISPLOAD_OPTS) 1495 | 1496 | burn_bootloader: 1497 | ifneq ($(strip $(AVRDUDE_ISP_FUSES_PRE)),) 1498 | $(AVRDUDE) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) -e $(AVRDUDE_ISP_FUSES_PRE) 1499 | endif 1500 | ifneq ($(strip $(AVRDUDE_ISP_BURN_BOOTLOADER)),) 1501 | $(AVRDUDE) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) $(AVRDUDE_ISP_BURN_BOOTLOADER) 1502 | endif 1503 | ifneq ($(strip $(AVRDUDE_ISP_FUSES_POST)),) 1504 | $(AVRDUDE) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) $(AVRDUDE_ISP_FUSES_POST) 1505 | endif 1506 | 1507 | set_fuses: 1508 | ifneq ($(strip $(AVRDUDE_ISP_FUSES_PRE)),) 1509 | $(AVRDUDE) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) -e $(AVRDUDE_ISP_FUSES_PRE) 1510 | endif 1511 | ifneq ($(strip $(AVRDUDE_ISP_FUSES_POST)),) 1512 | $(AVRDUDE) $(AVRDUDE_COM_OPTS) $(AVRDUDE_ISP_OPTS) $(AVRDUDE_ISP_FUSES_POST) 1513 | endif 1514 | 1515 | clean:: 1516 | $(REMOVE) $(OBJDIR) 1517 | 1518 | size: $(TARGET_HEX) 1519 | $(call avr_size,$(TARGET_ELF),$(TARGET_HEX)) 1520 | 1521 | show_boards: 1522 | @$(CAT) $(BOARDS_TXT) | grep -E '^[a-zA-Z0-9_\-]+.name' | sort -uf | sed 's/.name=/:/' | column -s: -t 1523 | 1524 | show_submenu: 1525 | @$(CAT) $(BOARDS_TXT) | grep -E '[a-zA-Z0-9_\-]+.menu.(cpu|chip).[a-zA-Z0-9_\-]+=' | sort -uf | sed 's/.menu.(cpu|chip)./:/' | sed 's/=/:/' | column -s: -t 1526 | 1527 | monitor: 1528 | ifeq ($(MONITOR_CMD), 'putty') 1529 | ifneq ($(strip $(MONITOR_PARMS)),) 1530 | $(MONITOR_CMD) -serial -sercfg $(MONITOR_BAUDRATE),$(MONITOR_PARMS) $(call get_monitor_port) 1531 | else 1532 | $(MONITOR_CMD) -serial -sercfg $(MONITOR_BAUDRATE) $(call get_monitor_port) 1533 | endif 1534 | else ifeq ($(MONITOR_CMD), picocom) 1535 | $(MONITOR_CMD) -b $(MONITOR_BAUDRATE) $(MONITOR_PARAMS) $(call get_monitor_port) 1536 | else 1537 | $(MONITOR_CMD) $(call get_monitor_port) $(MONITOR_BAUDRATE) 1538 | endif 1539 | 1540 | disasm: $(OBJDIR)/$(TARGET).lss 1541 | @$(ECHO) "The compiled ELF file has been disassembled to $(OBJDIR)/$(TARGET).lss\n\n" 1542 | 1543 | symbol_sizes: $(OBJDIR)/$(TARGET).sym 1544 | @$(ECHO) "A symbol listing sorted by their size have been dumped to $(OBJDIR)/$(TARGET).sym\n\n" 1545 | 1546 | verify_size: 1547 | ifeq ($(strip $(HEX_MAXIMUM_SIZE)),) 1548 | @$(ECHO) "\nMaximum flash memory of $(BOARD_TAG) is not specified. Make sure the size of $(TARGET_HEX) is less than $(BOARD_TAG)\'s flash memory\n\n" 1549 | endif 1550 | @if [ ! -f $(TARGET_HEX).sizeok ]; then echo >&2 "\nThe size of the compiled binary file is greater than the $(BOARD_TAG)'s flash memory. \ 1551 | See http://www.arduino.cc/en/Guide/Troubleshooting#size for tips on reducing it."; false; fi 1552 | 1553 | generate_assembly: $(OBJDIR)/$(TARGET).s 1554 | @$(ECHO) "Compiler-generated assembly for the main input source has been dumped to $(OBJDIR)/$(TARGET).s\n\n" 1555 | 1556 | generated_assembly: generate_assembly 1557 | @$(ECHO) "\"generated_assembly\" target is deprecated. Use \"generate_assembly\" target instead\n\n" 1558 | 1559 | help_vars: 1560 | @$(CAT) $(ARDMK_DIR)/arduino-mk-vars.md 1561 | 1562 | help: 1563 | @$(ECHO) "\nAvailable targets:\n\ 1564 | make - compile the code\n\ 1565 | make upload - upload\n\ 1566 | make ispload - upload using an ISP\n\ 1567 | make raw_upload - upload without first resetting\n\ 1568 | make eeprom - upload the eep file\n\ 1569 | make raw_eeprom - upload the eep file without first resetting\n\ 1570 | make clean - remove all our dependencies\n\ 1571 | make depends - update dependencies\n\ 1572 | make reset - reset the Arduino by tickling DTR or changing baud\n\ 1573 | rate on the serial port.\n\ 1574 | make show_boards - list all the boards defined in boards.txt\n\ 1575 | make show_submenu - list all board submenus defined in boards.txt\n\ 1576 | make monitor - connect to the Arduino's serial port\n\ 1577 | make size - show the size of the compiled output (relative to\n\ 1578 | resources, if you have a patched avr-size).\n\ 1579 | make verify_size - verify that the size of the final file is less than\n\ 1580 | the capacity of the micro controller.\n\ 1581 | make symbol_sizes - generate a .sym file containing symbols and their\n\ 1582 | sizes.\n\ 1583 | make disasm - generate a .lss file that contains disassembly\n\ 1584 | of the compiled file interspersed with your\n\ 1585 | original source code.\n\ 1586 | make generate_assembly - generate a .s file containing the compiler\n\ 1587 | generated assembly of the main sketch.\n\ 1588 | make burn_bootloader - burn bootloader and fuses\n\ 1589 | make set_fuses - set fuses without burning bootloader\n\ 1590 | make help_vars - print all variables that can be overridden\n\ 1591 | make help - show this help\n\ 1592 | " 1593 | @$(ECHO) "Please refer to $(ARDMK_DIR)/Arduino.mk for more details.\n" 1594 | 1595 | .PHONY: all upload raw_upload raw_eeprom error_on_caterina reset reset_stty ispload \ 1596 | clean depends size show_boards monitor disasm symbol_sizes generated_assembly \ 1597 | generate_assembly verify_size burn_bootloader help pre-build 1598 | 1599 | # added - in the beginning, so that we don't get an error if the file is not present 1600 | -include $(DEPS) 1601 | --------------------------------------------------------------------------------