├── .gitignore ├── .travis.yml ├── Arduino_Pedelec_Controller ├── Arduino_Pedelec_Controller.ino ├── BMP085.cpp ├── BMP085.h ├── CMakeLists.txt ├── DSPC01_nano.cpp ├── DSPC01_nano.h ├── DallasTemp.cpp ├── DallasTemp.h ├── HX711.cpp ├── HX711.h ├── HX711_license.txt ├── HX711_readme.txt ├── LiquidCrystalDogm.cpp ├── LiquidCrystalDogm.h ├── MenuSystem.cpp ├── MenuSystem.h ├── PCD8544_charset.cpp ├── PCD8544_nano.cpp ├── PCD8544_nano.h ├── PID_v1_nano.cpp ├── PID_v1_nano.h ├── config.h ├── display.cpp ├── display.h ├── display_backlight.cpp ├── display_backlight.h ├── display_bafang.cpp ├── display_bafang.h ├── display_kingmeter.cpp ├── display_kingmeter.h ├── ds1307.cpp ├── ds1307.h ├── globals.h ├── hrmi_funcs.cpp ├── hrmi_funcs.h ├── menu.cpp ├── menu.h ├── one_Wire.cpp ├── one_Wire.h ├── serial_command.cpp ├── serial_command.h ├── serial_lcd.cpp ├── serial_lcd.h ├── switches.cpp ├── switches.h └── switches_action.h ├── Bluetooth_Setup └── Bluetooth_Setup.ino ├── CMakeLists.txt ├── Hardware_Test ├── CMakeLists.txt ├── EEPROMAnything.h ├── Hardware_Test.ino ├── LiquidCrystalDogm.cpp ├── LiquidCrystalDogm.h ├── PCD8544_charset.cpp ├── PCD8544_nano.cpp └── PCD8544_nano.h ├── cmake ├── Arduino-toolchain.cmake ├── Arduino │ ├── System │ │ ├── BoardBuildTargets.cmake │ │ ├── BoardToolchain.cmake │ │ ├── BoardsIndex.cmake │ │ ├── PackagePathIndex.cmake │ │ └── PlatformIndex.cmake │ ├── Templates │ │ ├── ArduinoSystem.cmake.in │ │ ├── BoardOptions_BoardHeader.cmake.in │ │ ├── BoardOptions_BoardSel.cmake.in │ │ ├── BoardOptions_FileHeader.cmake.in │ │ ├── BoardOptions_MenuBoardHdr.cmake.in │ │ ├── BoardOptions_MenuHeader.cmake.in │ │ ├── BoardOptions_Menuoption.cmake.in │ │ ├── BoardOptions_ProgHeader.cmake.in │ │ ├── BoardOptions_ProgSel.cmake.in │ │ ├── DummySource.cpp.in │ │ ├── ExecuteRecipe.cmake.in │ │ ├── FirmwareSizePrint.cmake.in │ │ └── FirmwareUpload.cmake.in │ └── Utilities │ │ ├── CommonUtils.cmake │ │ ├── JSONParser.cmake │ │ ├── PropertiesReader.cmake │ │ ├── SourceDependency.cmake │ │ └── SourceLocator.cmake ├── CHANGELOG.md ├── LICENSE.md ├── Platform │ ├── Arduino-Determine.cmake │ └── Arduino.cmake ├── README.md └── _config.yml ├── docs ├── Doxyfile.in ├── README_breadboard.md ├── README_cmake.txt ├── README_hacking.txt └── README_menu.txt ├── readme.md └── tools ├── code_reformat.sh └── compile_test.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Backup files and stuff from patches 2 | *.orig 3 | *.rej 4 | *~ 5 | .*.swp 6 | 7 | # CMake 8 | build/ 9 | CMakeCache.txt 10 | cmake_install.cmake 11 | CMakeFiles 12 | Arduino_Pedelec_Controller/Arduino_Pedelec_Controller.pde 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | sudo: required 3 | dist: focal 4 | 5 | language: 6 | - c 7 | 8 | cache: 9 | - ccache 10 | 11 | before_install: 12 | - wget http://downloads.arduino.cc/arduino-1.8.3-linux64.tar.xz 13 | - tar xf arduino-1.8.3-linux64.tar.xz 14 | - sudo mv arduino-1.8.3 /usr/local/share/arduino 15 | - sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino 16 | 17 | install: 18 | - arduino --install-boards "arduino:avr:1.8.3" 19 | - arduino --install-library Servo:1.1.6 20 | - mkdir -p $TRAVIS_BUILD_DIR/libraries 21 | - mv ~/Arduino/libraries/* $TRAVIS_BUILD_DIR/libraries 22 | 23 | addons: 24 | apt: 25 | packages: 26 | - python3.6 27 | 28 | script: 29 | - tools/compile_test.py 30 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/BMP085.cpp: -------------------------------------------------------------------------------- 1 | // This is a simple but accurate BMP085 sensor library that doesn't suck 2 | // Does high res temperature, pressure and altitude calculations based on 3 | // the datasheet documentation 4 | // (c) adafruit - MIT license - https://github.com/adafruit/BMP085-Library 5 | 6 | #include "BMP085.h" 7 | #include 8 | 9 | BMP085::BMP085() 10 | { 11 | } 12 | 13 | 14 | void BMP085::begin(uint8_t mode) 15 | { 16 | if (mode > BMP085_ULTRAHIGHRES) 17 | mode = BMP085_ULTRAHIGHRES; 18 | oversampling = mode; 19 | 20 | Wire.begin(); 21 | 22 | /* read calibration data */ 23 | ac1 = read16(BMP085_CAL_AC1); 24 | ac2 = read16(BMP085_CAL_AC2); 25 | ac3 = read16(BMP085_CAL_AC3); 26 | ac4 = read16(BMP085_CAL_AC4); 27 | ac5 = read16(BMP085_CAL_AC5); 28 | ac6 = read16(BMP085_CAL_AC6); 29 | 30 | b1 = read16(BMP085_CAL_B1); 31 | b2 = read16(BMP085_CAL_B2); 32 | 33 | mb = read16(BMP085_CAL_MB); 34 | mc = read16(BMP085_CAL_MC); 35 | md = read16(BMP085_CAL_MD); 36 | #if (BMP085_DEBUG == 1) 37 | Serial.print("ac1 = "); Serial.println(ac1, DEC); 38 | Serial.print("ac2 = "); Serial.println(ac2, DEC); 39 | Serial.print("ac3 = "); Serial.println(ac3, DEC); 40 | Serial.print("ac4 = "); Serial.println(ac4, DEC); 41 | Serial.print("ac5 = "); Serial.println(ac5, DEC); 42 | Serial.print("ac6 = "); Serial.println(ac6, DEC); 43 | 44 | Serial.print("b1 = "); Serial.println(b1, DEC); 45 | Serial.print("b2 = "); Serial.println(b2, DEC); 46 | 47 | Serial.print("mb = "); Serial.println(mb, DEC); 48 | Serial.print("mc = "); Serial.println(mc, DEC); 49 | Serial.print("md = "); Serial.println(md, DEC); 50 | #endif 51 | } 52 | 53 | uint16_t BMP085::readRawTemperature(void) 54 | { 55 | write8(BMP085_CONTROL, BMP085_READTEMPCMD); 56 | _delay_ms(5); 57 | #if BMP085_DEBUG == 1 58 | Serial.print("Raw temp: "); Serial.println(read16(BMP085_TEMPDATA)); 59 | #endif 60 | return read16(BMP085_TEMPDATA); 61 | } 62 | 63 | uint32_t BMP085::readRawPressure(void) 64 | { 65 | uint32_t raw; 66 | 67 | write8(BMP085_CONTROL, BMP085_READPRESSURECMD + (oversampling << 6)); 68 | 69 | if (oversampling == BMP085_ULTRALOWPOWER) 70 | _delay_ms(5); 71 | else if (oversampling == BMP085_STANDARD) 72 | _delay_ms(8); 73 | else if (oversampling == BMP085_HIGHRES) 74 | _delay_ms(14); 75 | else 76 | _delay_ms(26); 77 | 78 | raw = read16(BMP085_PRESSUREDATA); 79 | raw <<= 8; 80 | raw |= read8(BMP085_PRESSUREDATA+2); 81 | raw >>= (8 - oversampling); 82 | #if BMP085_DEBUG == 1 83 | Serial.print("Raw pressure: "); Serial.println(raw); 84 | #endif 85 | return raw; 86 | } 87 | 88 | 89 | int32_t BMP085::readPressure(void) 90 | { 91 | int32_t UT, UP, B3, B5, B6, X1, X2, X3, p; 92 | uint32_t B4, B7; 93 | 94 | UT = readRawTemperature(); 95 | UP = readRawPressure(); 96 | 97 | #if BMP085_DEBUG == 1 98 | // use datasheet numbers! 99 | UT = 27898; 100 | UP = 23843; 101 | ac6 = 23153; 102 | ac5 = 32757; 103 | mc = -8711; 104 | md = 2868; 105 | b1 = 6190; 106 | b2 = 4; 107 | ac3 = -14383; 108 | ac2 = -72; 109 | ac1 = 408; 110 | ac4 = 32741; 111 | oversampling = 0; 112 | #endif 113 | 114 | // do temperature calculations 115 | X1 = ((UT - (int32_t)ac6) * (int32_t)ac5) >> 15; 116 | X2 = ((int32_t)mc << 11) - (X1 + md)/2; // round up 117 | X2 /= (X1 + md); 118 | B5 = X1 + X2; 119 | 120 | #if BMP085_DEBUG == 1 121 | Serial.print("X1 = "); Serial.println(X1); 122 | Serial.print("X2 = "); Serial.println(X2); 123 | Serial.print("B5 = "); Serial.println(B5); 124 | #endif 125 | 126 | // do pressure calcs 127 | B6 = B5 - 4000; 128 | X1 = ((int32_t)b2 * ( (B6 * B6)>>12 )) >> 11; 129 | X2 = ((int32_t)ac2 * B6) >> 11; 130 | X3 = X1 + X2; 131 | B3 = ((((int32_t)ac1*4 + X3) << oversampling) + 2) / 4; 132 | 133 | #if BMP085_DEBUG == 1 134 | Serial.print("B6 = "); Serial.println(B6); 135 | Serial.print("X1 = "); Serial.println(X1); 136 | Serial.print("X2 = "); Serial.println(X2); 137 | Serial.print("B3 = "); Serial.println(B3); 138 | #endif 139 | 140 | X1 = ((int32_t)ac3 * B6) >> 13; 141 | X2 = ((int32_t)b1 * ((B6 * B6) >> 12)) >> 16; 142 | X3 = ((X1 + X2) + 2) >> 2; 143 | B4 = ((uint32_t)ac4 * (uint32_t)(X3 + 32768)) >> 15; 144 | B7 = ((uint32_t)UP - B3) * (uint32_t)( 50000UL >> oversampling ); 145 | 146 | #if BMP085_DEBUG == 1 147 | Serial.print("X1 = "); Serial.println(X1); 148 | Serial.print("X2 = "); Serial.println(X2); 149 | Serial.print("B4 = "); Serial.println(B4); 150 | Serial.print("B7 = "); Serial.println(B7); 151 | #endif 152 | 153 | if (B7 < 0x80000000) 154 | { 155 | p = (B7 * 2) / B4; 156 | } 157 | else 158 | { 159 | p = (B7 * 2) / B3; 160 | } 161 | X1 = (p >> 8) * (p >> 8); 162 | X1 = (X1 * 3038) >> 16; 163 | X2 = (-7357 * p) >> 16; 164 | 165 | #if BMP085_DEBUG == 1 166 | Serial.print("p = "); Serial.println(p); 167 | Serial.print("X1 = "); Serial.println(X1); 168 | Serial.print("X2 = "); Serial.println(X2); 169 | #endif 170 | 171 | p = p + ((X1 + X2 + (int32_t)3791)>>4); 172 | #if BMP085_DEBUG == 1 173 | Serial.print("p = "); Serial.println(p); 174 | #endif 175 | return p; 176 | } 177 | 178 | 179 | float BMP085::readTemperature(void) 180 | { 181 | int32_t UT, X1, X2, B5; // following ds convention 182 | float temp; 183 | 184 | UT = readRawTemperature(); 185 | 186 | #if BMP085_DEBUG == 1 187 | // use datasheet numbers! 188 | UT = 27898; 189 | ac6 = 23153; 190 | ac5 = 32757; 191 | mc = -8711; 192 | md = 2868; 193 | #endif 194 | 195 | // step 1 196 | X1 = ((UT - (int32_t)ac6) * (int32_t)ac5) >> 15; 197 | X2 = ((int32_t)mc << 11) / (X1 + (int32_t)md); 198 | B5 = X1 + X2; 199 | temp = (B5 + 8) >> 4; 200 | temp /= 10; 201 | 202 | return temp; 203 | } 204 | 205 | float BMP085::readAltitude() 206 | { 207 | float altitude; 208 | 209 | float pressure = readPressure(); 210 | 211 | altitude=12517.15344-0.16439*pressure+4.03319e-7*pressure*pressure; 212 | 213 | return altitude; 214 | } 215 | 216 | 217 | /*********************************************************************/ 218 | 219 | uint8_t BMP085::read8(uint8_t a) 220 | { 221 | uint8_t ret; 222 | 223 | Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device 224 | #if (ARDUINO >= 100) 225 | Wire.write(a); // sends register address to read from 226 | #else 227 | Wire.send(a); // sends register address to read from 228 | #endif 229 | Wire.endTransmission(); // end transmission 230 | 231 | Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device 232 | Wire.requestFrom(BMP085_I2CADDR, 1);// send data n-bytes read 233 | #if (ARDUINO >= 100) 234 | ret = Wire.read(); // receive DATA 235 | #else 236 | ret = Wire.receive(); // receive DATA 237 | #endif 238 | Wire.endTransmission(); // end transmission 239 | 240 | return ret; 241 | } 242 | 243 | uint16_t BMP085::read16(uint8_t a) 244 | { 245 | uint16_t ret; 246 | 247 | Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device 248 | #if (ARDUINO >= 100) 249 | Wire.write(a); // sends register address to read from 250 | #else 251 | Wire.send(a); // sends register address to read from 252 | #endif 253 | Wire.endTransmission(); // end transmission 254 | 255 | Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device 256 | Wire.requestFrom(BMP085_I2CADDR, 2);// send data n-bytes read 257 | #if (ARDUINO >= 100) 258 | ret = Wire.read(); // receive DATA 259 | ret <<= 8; 260 | ret |= Wire.read(); // receive DATA 261 | #else 262 | ret = Wire.receive(); // receive DATA 263 | ret <<= 8; 264 | ret |= Wire.receive(); // receive DATA 265 | #endif 266 | Wire.endTransmission(); // end transmission 267 | 268 | return ret; 269 | } 270 | 271 | void BMP085::write8(uint8_t a, uint8_t d) 272 | { 273 | Wire.beginTransmission(BMP085_I2CADDR); // start transmission to device 274 | #if (ARDUINO >= 100) 275 | Wire.write(a); // sends register address to read from 276 | Wire.write(d); // write data 277 | #else 278 | Wire.send(a); // sends register address to read from 279 | Wire.send(d); // write data 280 | #endif 281 | Wire.endTransmission(); // end transmission 282 | } 283 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/BMP085.h: -------------------------------------------------------------------------------- 1 | #ifndef BMP085_H 2 | #define BMP085_H 3 | // BMP085 Pressure/Temperature (Altimeter) sensor 4 | 5 | // MIT license 6 | 7 | #if (ARDUINO >= 100) 8 | #include "Arduino.h" 9 | #else 10 | #include "WProgram.h" 11 | #endif 12 | #include "Wire.h" 13 | 14 | #define BMP085_DEBUG 0 15 | 16 | #define BMP085_I2CADDR 0x77 17 | 18 | #define BMP085_ULTRALOWPOWER 0 19 | #define BMP085_STANDARD 1 20 | #define BMP085_HIGHRES 2 21 | #define BMP085_ULTRAHIGHRES 3 22 | #define BMP085_CAL_AC1 0xAA // R Calibration data (16 bits) 23 | #define BMP085_CAL_AC2 0xAC // R Calibration data (16 bits) 24 | #define BMP085_CAL_AC3 0xAE // R Calibration data (16 bits) 25 | #define BMP085_CAL_AC4 0xB0 // R Calibration data (16 bits) 26 | #define BMP085_CAL_AC5 0xB2 // R Calibration data (16 bits) 27 | #define BMP085_CAL_AC6 0xB4 // R Calibration data (16 bits) 28 | #define BMP085_CAL_B1 0xB6 // R Calibration data (16 bits) 29 | #define BMP085_CAL_B2 0xB8 // R Calibration data (16 bits) 30 | #define BMP085_CAL_MB 0xBA // R Calibration data (16 bits) 31 | #define BMP085_CAL_MC 0xBC // R Calibration data (16 bits) 32 | #define BMP085_CAL_MD 0xBE // R Calibration data (16 bits) 33 | 34 | #define BMP085_CONTROL 0xF4 35 | #define BMP085_TEMPDATA 0xF6 36 | #define BMP085_PRESSUREDATA 0xF6 37 | #define BMP085_READTEMPCMD 0x2E 38 | #define BMP085_READPRESSURECMD 0x34 39 | 40 | 41 | class BMP085 42 | { 43 | public: 44 | BMP085(); 45 | void begin(uint8_t mode = BMP085_ULTRAHIGHRES); // by default go highres 46 | float readTemperature(void); 47 | int32_t readPressure(void); 48 | float readAltitude(void); // std atmosphere 49 | uint16_t readRawTemperature(void); 50 | uint32_t readRawPressure(void); 51 | 52 | private: 53 | uint8_t read8(uint8_t addr); 54 | uint16_t read16(uint8_t addr); 55 | void write8(uint8_t addr, uint8_t data); 56 | 57 | uint8_t oversampling; 58 | 59 | int16_t ac1, ac2, ac3, b1, b2, mb, mc, md; 60 | uint16_t ac4, ac5, ac6; 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #=============================================================================# 2 | # Author: Thomas Jarosch # 3 | # Date: 24.04.2012 # 4 | # # 5 | # Description: Pedelec controller cmake project # 6 | # # 7 | #=============================================================================# 8 | include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} 9 | ${CMAKE_SOURCE_DIR}/Arduino_Pedelec_Controller) 10 | 11 | set(FIRMWARE_NAME pcontroller) 12 | 13 | # special compile flags for the Travis CI environment 14 | # (avr-gcc is rather outdated and outputs crazy warnings) 15 | if("$ENV{TRAVIS}" STREQUAL "true") 16 | message(STATUS "Detected Travis CI environment") 17 | 18 | # disable compiler invocation output since Travis CI has a 4MB log output limit 19 | set_property(GLOBAL PROPERTY RULE_MESSAGES off) 20 | endif("$ENV{TRAVIS}" STREQUAL "true") 21 | 22 | # Hack until we replace the .ino file with a stub 23 | # and move everything to main.cpp 24 | configure_file(Arduino_Pedelec_Controller.ino main.cpp COPYONLY) 25 | 26 | add_executable(${FIRMWARE_NAME} 27 | ${CMAKE_CURRENT_BINARY_DIR}/main.cpp 28 | BMP085.cpp 29 | BMP085.h 30 | DSPC01_nano.cpp 31 | DSPC01_nano.h 32 | DallasTemp.cpp 33 | DallasTemp.h 34 | HX711.cpp 35 | HX711.h 36 | LiquidCrystalDogm.cpp 37 | LiquidCrystalDogm.h 38 | MenuSystem.cpp 39 | MenuSystem.h 40 | PCD8544_charset.cpp 41 | PCD8544_nano.cpp 42 | PCD8544_nano.h 43 | PID_v1_nano.cpp 44 | PID_v1_nano.h 45 | config.h 46 | display.cpp 47 | display.h 48 | display_backlight.cpp 49 | display_backlight.h 50 | display_bafang.cpp 51 | display_bafang.h 52 | display_kingmeter.cpp 53 | display_kingmeter.h 54 | ds1307.cpp 55 | ds1307.h 56 | globals.h 57 | hrmi_funcs.cpp 58 | hrmi_funcs.h 59 | menu.cpp 60 | menu.h 61 | one_Wire.cpp 62 | one_Wire.h 63 | serial_command.cpp 64 | serial_command.h 65 | serial_lcd.cpp 66 | serial_lcd.h 67 | switches.cpp 68 | switches.h 69 | switches_action.h 70 | ) 71 | target_link_arduino_libraries(${FIRMWARE_NAME} PRIVATE AUTO_PUBLIC) 72 | 73 | # Upload support: Usage: 74 | # make upload-pcontroller SERIAL_PORT=/dev/ttyUSB0 75 | target_enable_arduino_upload(${FIRMWARE_NAME}) 76 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/DSPC01_nano.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Arduino Library for the Dorji DSPC01 module 3 | written by Jens Kießling 4 | For more Information see 5 | http://www.dorji.com/pro/sensor-module/Compass_pressure_sensor.html 6 | Copyright (C) 2013 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program; if not, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | #include "DSPC01_nano.h" 24 | #include 25 | #include "globals.h" 26 | 27 | DSPC01::DSPC01() 28 | { 29 | } 30 | 31 | void DSPC01::begin(int SCK_pin,int DATA_pin) 32 | { 33 | DATA_PIN=DATA_pin; 34 | SCK_PIN=SCK_pin; 35 | pinMode(SCK_PIN,OUTPUT); 36 | pinMode(DATA_PIN,OUTPUT); 37 | } 38 | 39 | 40 | void DSPC01::calibrate_compass() 41 | { 42 | send_SPC01_write_command(COMPASS_CALIBRATION_COMMAND); 43 | while ( communicate_status != COMMUNI_SUCCEED) 44 | { 45 | send_SPC01_write_command(COMPASS_CALIBRATION_COMMAND); 46 | } 47 | } 48 | 49 | unsigned long int DSPC01::pressure(void) 50 | { 51 | unsigned long int press_temp=0; 52 | IIC_Start(); 53 | communicate_status = IIC_WriteByte(0x21); 54 | if( communicate_status == COMMUNI_SUCCEED) 55 | { 56 | press_temp = IIC_ReadByte(); 57 | press_temp*=256; 58 | press_temp*=256; 59 | IIC_ACK(); 60 | press_temp+= (unsigned int)(IIC_ReadByte()<<8); 61 | IIC_ACK(); 62 | press_temp+= IIC_ReadByte(); 63 | IIC_NoAck(); 64 | IIC_Stop(); 65 | } 66 | return press_temp; 67 | } 68 | 69 | long int DSPC01::altitude(void) 70 | { 71 | long int alt_temp=0; 72 | IIC_Start(); 73 | communicate_status = IIC_WriteByte(0x21); 74 | if( communicate_status == COMMUNI_SUCCEED) 75 | { 76 | alt_temp = IIC_ReadByte(); 77 | alt_temp*=256; 78 | alt_temp*=256; 79 | IIC_ACK(); 80 | alt_temp+= (unsigned int)(IIC_ReadByte()<<8); 81 | IIC_ACK(); 82 | alt_temp+= IIC_ReadByte(); 83 | IIC_NoAck(); 84 | IIC_Stop(); 85 | } 86 | if (alt_temp>8388608) //negative! 87 | alt_temp=8388608-alt_temp; 88 | return alt_temp; 89 | } 90 | 91 | long int DSPC01::temperature(void) 92 | { 93 | long int temp=0; 94 | IIC_Start(); 95 | communicate_status = IIC_WriteByte(0x21); 96 | if( communicate_status == COMMUNI_SUCCEED) 97 | { 98 | temp +=(unsigned int)(IIC_ReadByte()<<8); 99 | IIC_ACK(); 100 | temp +=IIC_ReadByte(); 101 | IIC_NoAck(); 102 | IIC_Stop(); 103 | } 104 | if (temp>32768) 105 | temp = 32768-temp; 106 | return temp; 107 | } 108 | 109 | unsigned int DSPC01::compass(void) 110 | { 111 | unsigned int comp=0; 112 | IIC_Start(); 113 | communicate_status = IIC_WriteByte(0x21); 114 | if( communicate_status == COMMUNI_SUCCEED) 115 | { 116 | comp+= (unsigned long int)(IIC_ReadByte()<<8); 117 | IIC_ACK(); 118 | comp+=IIC_ReadByte(); 119 | IIC_NoAck(); 120 | IIC_Stop(); 121 | } 122 | return comp; 123 | } 124 | 125 | 126 | void DSPC01::request_pressure() 127 | { 128 | send_SPC01_write_command(PRESS_WRITE_COMMAND); 129 | while ( communicate_status != COMMUNI_SUCCEED) 130 | { 131 | send_SPC01_write_command(PRESS_WRITE_COMMAND); 132 | } 133 | } 134 | 135 | void DSPC01::request_altitude() 136 | { 137 | send_SPC01_write_command(ALTITUDE_WRITE_COMMAND); 138 | while ( communicate_status != COMMUNI_SUCCEED) 139 | { 140 | send_SPC01_write_command(ALTITUDE_WRITE_COMMAND); 141 | } 142 | } 143 | 144 | void DSPC01::request_temperature() 145 | { 146 | send_SPC01_write_command(TEMPERATURE_WRITE_COMMAND); 147 | while ( communicate_status != COMMUNI_SUCCEED) 148 | { 149 | send_SPC01_write_command(TEMPERATURE_WRITE_COMMAND); 150 | } 151 | } 152 | 153 | void DSPC01::request_compass() 154 | { 155 | send_SPC01_write_command(COMPASS_WRITE_COMMAND); 156 | while ( communicate_status != COMMUNI_SUCCEED) 157 | { 158 | send_SPC01_write_command(COMPASS_WRITE_COMMAND); 159 | } 160 | } 161 | 162 | //HELPER FUNCTIONS============================================================================== 163 | void DSPC01::send_SPC01_write_command(unsigned char command) 164 | { 165 | IIC_Start(); 166 | communicate_status = IIC_WriteByte(0x20); 167 | if( communicate_status == COMMUNI_SUCCEED) 168 | { 169 | communicate_status = IIC_WriteByte(command); 170 | if( communicate_status == COMMUNI_SUCCEED) 171 | { 172 | IIC_Stop(); 173 | } 174 | } 175 | } 176 | 177 | void DSPC01::IIC_SCL_HIGH(void) 178 | { 179 | digitalWrite(SCK_PIN,1); 180 | } 181 | 182 | void DSPC01::IIC_SCL_LOW(void) 183 | { 184 | digitalWrite(SCK_PIN,0); 185 | } 186 | 187 | void DSPC01::IIC_Start(void) 188 | { 189 | pinMode(DATA_PIN,OUTPUT); 190 | digitalWrite(DATA_PIN,1); 191 | 192 | delayMicroseconds(100); 193 | 194 | IIC_SCL_HIGH(); 195 | delayMicroseconds(100); 196 | 197 | digitalWrite(DATA_PIN,0); 198 | delayMicroseconds(100); 199 | 200 | IIC_SCL_LOW(); 201 | delayMicroseconds(100); 202 | 203 | } 204 | 205 | void DSPC01::IIC_Stop(void) 206 | { 207 | pinMode(DATA_PIN,OUTPUT); 208 | IIC_SCL_LOW(); 209 | delayMicroseconds(100); 210 | 211 | digitalWrite(DATA_PIN,0); 212 | delayMicroseconds(100); 213 | 214 | IIC_SCL_HIGH(); 215 | delayMicroseconds(100); 216 | 217 | digitalWrite(DATA_PIN,1); 218 | delayMicroseconds(100); 219 | } 220 | 221 | void DSPC01::IIC_ACK(void) 222 | { 223 | pinMode(DATA_PIN,OUTPUT); 224 | delayMicroseconds(100); 225 | 226 | digitalWrite(DATA_PIN,0); 227 | delayMicroseconds(100); 228 | 229 | IIC_SCL_HIGH(); 230 | delayMicroseconds(100); 231 | IIC_SCL_LOW(); 232 | delayMicroseconds(100); 233 | 234 | } 235 | 236 | void DSPC01::IIC_NoAck(void) 237 | { 238 | pinMode(DATA_PIN,OUTPUT); 239 | delayMicroseconds(100); 240 | 241 | digitalWrite(DATA_PIN,1); 242 | delayMicroseconds(100); 243 | 244 | IIC_SCL_HIGH(); 245 | delayMicroseconds(100); 246 | 247 | IIC_SCL_LOW(); 248 | delayMicroseconds(100); 249 | 250 | } 251 | 252 | unsigned char DSPC01::IIC_ReadByte(void) 253 | { 254 | unsigned char ucValue; 255 | unsigned char ucIndex; 256 | 257 | ucValue = 0; 258 | pinMode(DATA_PIN,INPUT); 259 | delayMicroseconds(100); 260 | 261 | 262 | for ( ucIndex = 0; ucIndex < 8; ucIndex++ ) 263 | { 264 | ucValue <<= 1; 265 | 266 | IIC_SCL_LOW(); 267 | delayMicroseconds(100); 268 | 269 | IIC_SCL_HIGH(); 270 | delayMicroseconds(100); 271 | 272 | if(digitalRead(DATA_PIN)) ucValue |= 1; 273 | 274 | 275 | delayMicroseconds(100); 276 | IIC_SCL_LOW(); 277 | delayMicroseconds(100); 278 | 279 | } 280 | return ucValue; 281 | } 282 | 283 | unsigned char DSPC01::IIC_WriteByte( unsigned char ucData ) 284 | { 285 | unsigned char i; 286 | 287 | pinMode(DATA_PIN,OUTPUT); 288 | delayMicroseconds(100); 289 | for( i = 0; i < 8; i++ ) 290 | { 291 | IIC_SCL_LOW(); 292 | delayMicroseconds(100); 293 | 294 | if((ucData & 0x80) == 0x80) 295 | { 296 | digitalWrite(DATA_PIN,1); 297 | delayMicroseconds(100); 298 | } 299 | else 300 | 301 | { 302 | digitalWrite(DATA_PIN,0); 303 | delayMicroseconds(100); 304 | } 305 | 306 | 307 | IIC_SCL_HIGH(); 308 | delayMicroseconds(100); 309 | ucData <<= 1; 310 | IIC_SCL_LOW(); 311 | } 312 | pinMode(DATA_PIN,INPUT); 313 | delayMicroseconds(100); 314 | IIC_SCL_LOW(); 315 | delayMicroseconds(100); 316 | 317 | IIC_SCL_HIGH(); 318 | delayMicroseconds(100); 319 | 320 | 321 | if( digitalRead(DATA_PIN) != 0) 322 | { 323 | IIC_SCL_LOW(); 324 | delayMicroseconds(100); 325 | delay(10); 326 | return (COMMUNI_FAILED); 327 | } 328 | else 329 | 330 | { 331 | IIC_SCL_LOW(); 332 | delayMicroseconds(100); 333 | return (COMMUNI_SUCCEED); 334 | } 335 | } 336 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/DSPC01_nano.h: -------------------------------------------------------------------------------- 1 | /* 2 | Arduino Library for the Dorji DSPC01 module 3 | written by Jens Kießling 4 | For more Information see 5 | http://www.dorji.com/pro/sensor-module/Compass_pressure_sensor.html 6 | Copyright (C) 2013 7 | 8 | This program is free software; you can redistribute it and/or modify 9 | it under the terms of the GNU General Public License as published by 10 | the Free Software Foundation; either version 3 of the License, or 11 | (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program; if not, write to the Free Software Foundation, 20 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | #define COMMUNI_SUCCEED 1 24 | #define COMMUNI_FAILED 0 25 | 26 | #define noACK 0 27 | #define ACK 1 28 | 29 | #define COMPASS_CALIBRATION_COMMAND 0xe0 30 | #define PRESS_WRITE_COMMAND 0xB0 31 | #define TEMPERATURE_WRITE_COMMAND 0x80 32 | #define ALTITUDE_WRITE_COMMAND 0xA0 33 | #define COMPASS_WRITE_COMMAND 0xC0 34 | 35 | class DSPC01 36 | { 37 | public: 38 | DSPC01(); 39 | void request_pressure(void); 40 | void request_altitude(void); 41 | void request_temperature(void); 42 | void request_compass(void); 43 | void calibrate_compass(void); 44 | unsigned long int pressure(void); 45 | long int altitude(void); 46 | long int temperature(void); 47 | unsigned int compass(void); 48 | void begin(int SCK_pin,int DATA_pin); 49 | 50 | private: 51 | int SCK_PIN; 52 | int DATA_PIN; 53 | unsigned char communicate_status; 54 | void send_SPC01_write_command(unsigned char command); 55 | void IIC_SCL_HIGH(void); 56 | void IIC_SCL_LOW(void); 57 | void IIC_Start(void); 58 | void IIC_Stop(void); 59 | void IIC_ACK(void); 60 | void IIC_NoAck(void); 61 | unsigned char IIC_ReadByte(void); 62 | unsigned char IIC_WriteByte( unsigned char ucData ); 63 | }; 64 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/DallasTemp.h: -------------------------------------------------------------------------------- 1 | #ifndef DallasTemperature_h 2 | #define DallasTemperature_h 3 | 4 | #define DALLASTEMPLIBVERSION "3.7.2" 5 | 6 | // This library is free software; you can redistribute it and/or 7 | // modify it under the terms of the GNU Lesser General Public 8 | // License as published by the Free Software Foundation; either 9 | // version 2.1 of the License, or (at your option) any later version. 10 | 11 | // set to true to include code for new and delete operators 12 | #ifndef REQUIRESNEW 13 | #define REQUIRESNEW false 14 | #endif 15 | 16 | // set to true to include code implementing alarm search functions 17 | #ifndef REQUIRESALARMS 18 | #define REQUIRESALARMS true 19 | #endif 20 | 21 | #include 22 | #include "one_Wire.h" 23 | 24 | // Model IDs 25 | #define DS18S20MODEL 0x10 26 | #define DS18B20MODEL 0x28 27 | #define DS1822MODEL 0x22 28 | 29 | // OneWire commands 30 | #define STARTCONVO 0x44 // Tells device to take a temperature reading and put it on the scratchpad 31 | #define COPYSCRATCH 0x48 // Copy EEPROM 32 | #define READSCRATCH 0xBE // Read EEPROM 33 | #define WRITESCRATCH 0x4E // Write to EEPROM 34 | #define RECALLSCRATCH 0xB8 // Reload from last known 35 | #define READPOWERSUPPLY 0xB4 // Determine if device needs parasite power 36 | #define ALARMSEARCH 0xEC // Query bus for devices with an alarm condition 37 | 38 | // Scratchpad locations 39 | #define TEMP_LSB 0 40 | #define TEMP_MSB 1 41 | #define HIGH_ALARM_TEMP 2 42 | #define LOW_ALARM_TEMP 3 43 | #define CONFIGURATION 4 44 | #define INTERNAL_BYTE 5 45 | #define COUNT_REMAIN 6 46 | #define COUNT_PER_C 7 47 | #define SCRATCHPAD_CRC 8 48 | 49 | // Device resolution 50 | #define TEMP_9_BIT 0x1F // 9 bit 51 | #define TEMP_10_BIT 0x3F // 10 bit 52 | #define TEMP_11_BIT 0x5F // 11 bit 53 | #define TEMP_12_BIT 0x7F // 12 bit 54 | 55 | // Error Codes 56 | #define DEVICE_DISCONNECTED -127 57 | 58 | typedef uint8_t DeviceAddress[8]; 59 | 60 | class DallasTemperature 61 | { 62 | public: 63 | 64 | DallasTemperature(OneWire*); 65 | 66 | // initalise bus 67 | void begin(void); 68 | 69 | // returns the number of devices found on the bus 70 | uint8_t getDeviceCount(void); 71 | 72 | // Is a conversion complete on the wire? 73 | bool isConversionComplete(void); 74 | 75 | // returns true if address is valid 76 | bool validAddress(uint8_t*); 77 | 78 | // finds an address at a given index on the bus 79 | bool getAddress(uint8_t*, const uint8_t); 80 | 81 | // attempt to determine if the device at the given address is connected to the bus 82 | bool isConnected(uint8_t*); 83 | 84 | // attempt to determine if the device at the given address is connected to the bus 85 | // also allows for updating the read scratchpad 86 | bool isConnected(uint8_t*, uint8_t*); 87 | 88 | // read device's scratchpad 89 | void readScratchPad(uint8_t*, uint8_t*); 90 | 91 | // write device's scratchpad 92 | void writeScratchPad(uint8_t*, const uint8_t*); 93 | 94 | // read device's power requirements 95 | bool readPowerSupply(uint8_t*); 96 | 97 | // get global resolution 98 | uint8_t getResolution(); 99 | 100 | // set global resolution to 9, 10, 11, or 12 bits 101 | void setResolution(uint8_t); 102 | 103 | // returns the device resolution, 9-12 104 | uint8_t getResolution(uint8_t*); 105 | 106 | // set resolution of a device to 9, 10, 11, or 12 bits 107 | bool setResolution(uint8_t*, uint8_t); 108 | 109 | // sets/gets the waitForConversion flag 110 | void setWaitForConversion(bool); 111 | bool getWaitForConversion(void); 112 | 113 | // sets/gets the checkForConversion flag 114 | void setCheckForConversion(bool); 115 | bool getCheckForConversion(void); 116 | 117 | // sends command for all devices on the bus to perform a temperature conversion 118 | void requestTemperatures(void); 119 | 120 | // sends command for one device to perform a temperature conversion by address 121 | bool requestTemperaturesByAddress(uint8_t*); 122 | 123 | // sends command for one device to perform a temperature conversion by index 124 | bool requestTemperaturesByIndex(uint8_t); 125 | 126 | // returns temperature in degrees C 127 | float getTempC(uint8_t*); 128 | 129 | // returns temperature in degrees F 130 | float getTempF(uint8_t*); 131 | 132 | // Get temperature for device index (slow) 133 | float getTempCByIndex(uint8_t); 134 | 135 | // Get temperature for device index (slow) 136 | float getTempFByIndex(uint8_t); 137 | 138 | // returns true if the bus requires parasite power 139 | bool isParasitePowerMode(void); 140 | 141 | bool isConversionAvailable(uint8_t*); 142 | 143 | #if REQUIRESALARMS 144 | 145 | typedef void AlarmHandler(uint8_t*); 146 | 147 | // sets the high alarm temperature for a device 148 | // accepts a char. valid range is -55C - 125C 149 | void setHighAlarmTemp(uint8_t*, const char); 150 | 151 | // sets the low alarm temperature for a device 152 | // accepts a char. valid range is -55C - 125C 153 | void setLowAlarmTemp(uint8_t*, const char); 154 | 155 | // returns a signed char with the current high alarm temperature for a device 156 | // in the range -55C - 125C 157 | char getHighAlarmTemp(uint8_t*); 158 | 159 | // returns a signed char with the current low alarm temperature for a device 160 | // in the range -55C - 125C 161 | char getLowAlarmTemp(uint8_t*); 162 | 163 | // resets internal variables used for the alarm search 164 | void resetAlarmSearch(void); 165 | 166 | // search the wire for devices with active alarms 167 | bool alarmSearch(uint8_t*); 168 | 169 | // returns true if ia specific device has an alarm 170 | bool hasAlarm(uint8_t*); 171 | 172 | // returns true if any device is reporting an alarm on the bus 173 | bool hasAlarm(void); 174 | 175 | // runs the alarm handler for all devices returned by alarmSearch() 176 | void processAlarms(void); 177 | 178 | // sets the alarm handler 179 | void setAlarmHandler(AlarmHandler *); 180 | 181 | // The default alarm handler 182 | static void defaultAlarmHandler(uint8_t*); 183 | 184 | #endif 185 | 186 | // convert from celcius to farenheit 187 | static float toFahrenheit(const float); 188 | 189 | // convert from farenheit to celsius 190 | static float toCelsius(const float); 191 | 192 | #if REQUIRESNEW 193 | 194 | // initalize memory area 195 | void* operator new (unsigned int); 196 | 197 | // delete memory reference 198 | void operator delete(void*); 199 | 200 | #endif 201 | 202 | private: 203 | typedef uint8_t ScratchPad[9]; 204 | 205 | // parasite power on or off 206 | bool parasite; 207 | 208 | // used to determine the delay amount needed to allow for the 209 | // temperature conversion to take place 210 | uint8_t bitResolution; 211 | 212 | // used to requestTemperature with or without delay 213 | bool waitForConversion; 214 | 215 | // used to requestTemperature to dynamically check if a conversion is complete 216 | bool checkForConversion; 217 | 218 | // count of devices on the bus 219 | uint8_t devices; 220 | 221 | // Take a pointer to one wire instance 222 | OneWire* _wire; 223 | 224 | // reads scratchpad and returns the temperature in degrees C 225 | float calculateTemperature(uint8_t*, uint8_t*); 226 | 227 | void blockTillConversionComplete(uint8_t*,uint8_t*); 228 | 229 | #if REQUIRESALARMS 230 | 231 | // required for alarmSearch 232 | uint8_t alarmSearchAddress[8]; 233 | char alarmSearchJunction; 234 | uint8_t alarmSearchExhausted; 235 | 236 | // the alarm handler function pointer 237 | AlarmHandler *_AlarmHandler; 238 | 239 | #endif 240 | 241 | }; 242 | #endif 243 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/HX711.cpp: -------------------------------------------------------------------------------- 1 | //taken and modified from https://github.com/bogde/HX711 2 | #include 3 | #include "HX711.h" 4 | 5 | HX711::HX711(byte dout, byte pd_sck, byte gain) { 6 | PD_SCK = pd_sck; 7 | DOUT = dout; 8 | 9 | pinMode(PD_SCK, OUTPUT); 10 | pinMode(DOUT, INPUT); 11 | 12 | set_gain(gain); 13 | } 14 | 15 | bool HX711::is_ready() { 16 | return digitalRead(DOUT) == LOW; 17 | } 18 | 19 | void HX711::set_gain(byte gain) { 20 | switch (gain) { 21 | case 128: // channel A, gain factor 128 22 | GAIN = 1; 23 | break; 24 | case 64: // channel A, gain factor 64 25 | GAIN = 3; 26 | break; 27 | case 32: // channel B, gain factor 32 28 | GAIN = 2; 29 | break; 30 | } 31 | 32 | digitalWrite(PD_SCK, LOW); 33 | read(); 34 | } 35 | 36 | long HX711::read() { 37 | // wait for the chip to become ready 38 | while (!is_ready()); 39 | return read_fast(); 40 | } 41 | 42 | long HX711::read_fast() { 43 | unsigned long value = 0; 44 | byte data[3] = { 0 }; 45 | byte filler = 0x00; 46 | 47 | // pulse the clock pin 24 times to read the data 48 | data[2] = shiftIn(DOUT, PD_SCK, MSBFIRST); 49 | data[1] = shiftIn(DOUT, PD_SCK, MSBFIRST); 50 | data[0] = shiftIn(DOUT, PD_SCK, MSBFIRST); 51 | 52 | // set the channel and the gain factor for the next reading using the clock pin 53 | for (unsigned int i = 0; i < GAIN; i++) { 54 | digitalWrite(PD_SCK, HIGH); 55 | digitalWrite(PD_SCK, LOW); 56 | } 57 | 58 | // Datasheet indicates the value is returned as a two's complement value 59 | // Flip all the bits 60 | data[2] = ~data[2]; 61 | data[1] = ~data[1]; 62 | data[0] = ~data[0]; 63 | 64 | // Replicate the most significant bit to pad out a 32-bit signed integer 65 | if ( data[2] & 0x80 ) { 66 | filler = 0xFF; 67 | } else if ((0x7F == data[2]) && (0xFF == data[1]) && (0xFF == data[0])) { 68 | filler = 0xFF; 69 | } else { 70 | filler = 0x00; 71 | } 72 | 73 | // Construct a 32-bit signed integer 74 | value = ( static_cast(filler) << 24 75 | | static_cast(data[2]) << 16 76 | | static_cast(data[1]) << 8 77 | | static_cast(data[0]) ); 78 | 79 | // ... and add 1 80 | return static_cast(++value); 81 | } 82 | 83 | long HX711::read_average(byte times) { 84 | long sum = 0; 85 | for (byte i = 0; i < times; i++) { 86 | sum += read(); 87 | } 88 | return sum / times; 89 | } 90 | 91 | double HX711::get_value(byte times) { 92 | return read_average(times) - OFFSET; 93 | } 94 | 95 | float HX711::get_units(byte times) { 96 | return get_value(times) / SCALE; 97 | } 98 | 99 | float HX711::get_units_fast() { 100 | return (read_fast()-OFFSET)/SCALE; 101 | } 102 | 103 | void HX711::tare(byte times) { 104 | double sum = read_average(times); 105 | set_offset(sum); 106 | } 107 | 108 | void HX711::set_scale(float scale) { 109 | SCALE = scale; 110 | } 111 | 112 | float HX711::get_scale() { 113 | return SCALE; 114 | } 115 | 116 | void HX711::set_offset(long offset) { 117 | OFFSET = offset; 118 | } 119 | 120 | long HX711::get_offset() { 121 | return OFFSET; 122 | } 123 | 124 | void HX711::power_down() { 125 | digitalWrite(PD_SCK, LOW); 126 | digitalWrite(PD_SCK, HIGH); 127 | } 128 | 129 | void HX711::power_up() { 130 | digitalWrite(PD_SCK, LOW); 131 | } 132 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/HX711.h: -------------------------------------------------------------------------------- 1 | //taken and modified from https://github.com/bogde/HX711 2 | #ifndef HX711_h 3 | #define HX711_h 4 | 5 | #if ARDUINO >= 100 6 | #include "Arduino.h" 7 | #else 8 | #include "WProgram.h" 9 | #endif 10 | 11 | class HX711 12 | { 13 | private: 14 | byte PD_SCK; // Power Down and Serial Clock Input Pin 15 | byte DOUT; // Serial Data Output Pin 16 | byte GAIN; // amplification factor 17 | long OFFSET; // used for tare weight 18 | float SCALE; // used to return weight in grams, kg, ounces, whatever 19 | 20 | public: 21 | // define clock and data pin, channel, and gain factor 22 | // channel selection is made by passing the appropriate gain: 128 or 64 for channel A, 32 for channel B 23 | // gain: 128 or 64 for channel A; channel B works with 32 gain factor only 24 | HX711(byte dout, byte pd_sck, byte gain = 128); 25 | 26 | // check if HX711 is ready 27 | // from the datasheet: When output data is not ready for retrieval, digital output pin DOUT is high. Serial clock 28 | // input PD_SCK should be low. When DOUT goes to low, it indicates data is ready for retrieval. 29 | bool is_ready(); 30 | 31 | // set the gain factor; takes effect only after a call to read() 32 | // channel A can be set for a 128 or 64 gain; channel B has a fixed 32 gain 33 | // depending on the parameter, the channel is also set to either A or B 34 | void set_gain(byte gain = 128); 35 | 36 | // waits for the chip to be ready and returns a reading 37 | long read(); 38 | 39 | //returns a reading. chip must be ready before executing this command! 40 | long read_fast(); 41 | 42 | // returns an average reading; times = how many times to read 43 | long read_average(byte times = 10); 44 | 45 | // returns (read_average() - OFFSET), that is the current value without the tare weight; times = how many readings to do 46 | double get_value(byte times = 1); 47 | 48 | // returns get_value() divided by SCALE, that is the raw value divided by a value obtained via calibration 49 | // times = how many readings to do 50 | float get_units(byte times = 1); 51 | 52 | // same as get_units but without averaging and without waiting for chip to be ready 53 | float get_units_fast(); 54 | 55 | // set the OFFSET value for tare weight; times = how many times to read the tare value 56 | void tare(byte times = 10); 57 | 58 | // set the SCALE value; this value is used to convert the raw data to "human readable" data (measure units) 59 | void set_scale(float scale = 1.f); 60 | 61 | // get the current SCALE 62 | float get_scale(); 63 | 64 | // set OFFSET, the value that's subtracted from the actual reading (tare weight) 65 | void set_offset(long offset = 0); 66 | 67 | // get the current OFFSET 68 | long get_offset(); 69 | 70 | // puts the chip into power down mode 71 | void power_down(); 72 | 73 | // wakes up the chip after power down mode 74 | void power_up(); 75 | }; 76 | 77 | #endif /* HX711_h */ 78 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/HX711_readme.txt: -------------------------------------------------------------------------------- 1 | //taken from https://github.com/bogde/HX711 2 | HX711 3 | ===== 4 | 5 | An Arduino library to interface the Avia Semiconductor HX711 24-Bit Analog-to-Digital Converter (ADC) for Weight Scales. 6 | 7 | This is my humble attempt at creating an Arduino library for this ADC: 8 | http://www.dfrobot.com/image/data/SEN0160/hx711_english.pdf 9 | 10 | Other libraries exist, including this very good one, which I first used and which is the starting point for my library: 11 | https://github.com/aguegu/ardulibs/tree/master/hx711 12 | 13 | Although other libraries exist, I needed a slightly different approach, so here's how my library is different than others: 14 | 15 | 1. It provides a tare() function, which "resets" the scale to 0. Many other implementations calculate the tare weight when the ADC is initialized only. I needed a way to be able to set the tare weight at any time. Use case: place an empty container on the scale, call tare() to reset the readings to 0, fill the container and get the weight of the content. 16 | 17 | 2. It provides a power_down() function, to put the ADC into a low power mode. According to the datasheet, "When PD_SCK pin changes from low to high and stays at high for longer than 60μs, HX711 enters power down mode". Use case: battery powered scales. Accordingly, there is a power_up() function to get the chip out of the low power mode. 18 | 19 | 3. It has a set_gain(byte gain) function that allows you to set the gain factor and select the channel. According to the datasheet, "Channel A can be programmed with a gain of 128 or 64, corresponding to a full-scale differential input voltage of ±20mV or ±40mV respectively, when a 5V supply is connected to AVDD analog power supply pin. Channel B has a fixed gain of 32.". The same function is used to select the channel A or channel B, by passing 128 or 64 for channel A, or 32 for channel B as the parameter. The default value is 128, which means "channel A with a gain factor of 128", so one can simply call set_gain(). Also, the function is called from the constructor. 20 | 21 | 4. The constructor has an extra parameter "gain" that allows you to set the gain factor and channel. The constructor calls the "set_gain" function mentioned above. 22 | 23 | 5. The "get_value" and "get_units" functions can receive an extra parameter "times", and they will return the average of multiple readings instead of a single reading. 24 | 25 | How to Calibrate Your Scale 26 | 27 | 1. Call set_scale() with no parameter. 28 | 2. Call tare() with no parameter. 29 | 3. Place a known weight on the scale and call get_units(10). 30 | 4. Divide the result in step 3 to your known weight. You should get about the parameter you need to pass to set_scale. 31 | 5. Adjust the parameter in step 4 until you get an accurate reading. 32 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/LiquidCrystalDogm.h: -------------------------------------------------------------------------------- 1 | #ifndef LiquidCrystal_h 2 | #define LiquidCrystal_h 3 | 4 | #include 5 | #include "Print.h" 6 | 7 | // commands 8 | #define LCD_CLEARDISPLAY 0x01 9 | #define LCD_RETURNHOME 0x02 10 | #define LCD_ENTRYMODESET 0x04 11 | #define LCD_DISPLAYCONTROL 0x08 12 | #define LCD_CURSORSHIFT 0x10 13 | #define LCD_FUNCTIONSET 0x29 14 | #define LCD_SETCGRAMADDR 0x40 15 | #define LCD_SETDDRAMADDR 0x80 16 | 17 | // flags for display entry mode 18 | #define LCD_ENTRYRIGHT 0x00 19 | #define LCD_ENTRYLEFT 0x02 20 | #define LCD_ENTRYSHIFTINCREMENT 0x01 21 | #define LCD_ENTRYSHIFTDECREMENT 0x00 22 | 23 | // flags for display on/off control 24 | #define LCD_DISPLAYON 0x04 25 | #define LCD_DISPLAYOFF 0x00 26 | #define LCD_CURSORON 0x02 27 | #define LCD_CURSOROFF 0x00 28 | #define LCD_BLINKON 0x01 29 | #define LCD_BLINKOFF 0x00 30 | 31 | // flags for display/cursor shift 32 | #define LCD_DISPLAYMOVE 0x08 33 | #define LCD_CURSORMOVE 0x00 34 | #define LCD_MOVERIGHT 0x04 35 | #define LCD_MOVELEFT 0x00 36 | 37 | // flags for function set 38 | #define LCD_8BITMODE 0x10 39 | #define LCD_4BITMODE 0x00 40 | #define LCD_2LINE 0x08 41 | #define LCD_1LINE 0x00 42 | #define LCD_5x10DOTS 0x04 43 | #define LCD_5x8DOTS 0x00 44 | 45 | class LiquidCrystal : public Print 46 | { 47 | public: 48 | LiquidCrystal(uint8_t rs, uint8_t enable, 49 | uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 50 | uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); 51 | LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 52 | uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 53 | uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); 54 | LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 55 | uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); 56 | LiquidCrystal(uint8_t rs, uint8_t enable, 57 | uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); 58 | 59 | void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, 60 | uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 61 | uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); 62 | 63 | void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); 64 | 65 | void clear(); 66 | void home(); 67 | 68 | void noDisplay(); 69 | void display(); 70 | void noBlink(); 71 | void blink(); 72 | void noCursor(); 73 | void cursor(); 74 | void scrollDisplayLeft(); 75 | void scrollDisplayRight(); 76 | void leftToRight(); 77 | void rightToLeft(); 78 | void autoscroll(); 79 | void noAutoscroll(); 80 | 81 | void createChar(uint8_t, const uint8_t[]); 82 | void setCursor(uint8_t, uint8_t); 83 | virtual size_t write(uint8_t); 84 | void command(uint8_t); 85 | 86 | using Print::write; 87 | private: 88 | void send(uint8_t, uint8_t); 89 | void write4bits(uint8_t); 90 | void write8bits(uint8_t); 91 | void pulseEnable(); 92 | 93 | uint8_t _rs_pin; // LOW: command. HIGH: character. 94 | uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD. 95 | uint8_t _enable_pin; // activated by a HIGH pulse. 96 | uint8_t _data_pins[8]; 97 | 98 | uint8_t _displayfunction; 99 | uint8_t _displaycontrol; 100 | uint8_t _displaymode; 101 | 102 | uint8_t _initialized; 103 | 104 | uint8_t _numlines,_currline; 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/MenuSystem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | MenuSystem.h - Library for creating menu structures. 3 | Created by Jon Black, August 8th 2011. 4 | Released into the public domain. 5 | 6 | License: LGPL 3 7 | */ 8 | 9 | #include "MenuSystem.h" 10 | 11 | // ********************************************************* 12 | // MenuComponent 13 | // ********************************************************* 14 | 15 | MenuComponent::MenuComponent(const char* name) 16 | : _name(name) 17 | { 18 | } 19 | 20 | const char* MenuComponent::get_name() const 21 | { 22 | return _name; 23 | } 24 | 25 | void MenuComponent::set_name(const char* name) 26 | { 27 | _name = name; 28 | } 29 | 30 | 31 | // ********************************************************* 32 | // Menu 33 | // ********************************************************* 34 | 35 | Menu::Menu(const char* name) 36 | : MenuComponent(name), 37 | _p_sel_menu_component(NULL), 38 | _p_parent(NULL), 39 | _num_menu_components(0), 40 | _cur_menu_component_num(0) 41 | { 42 | } 43 | 44 | boolean Menu::next(boolean loop) 45 | { 46 | if (_cur_menu_component_num != _num_menu_components - 1) 47 | { 48 | _cur_menu_component_num++; 49 | _p_sel_menu_component = _menu_components[_cur_menu_component_num]; 50 | 51 | return true; 52 | } else if (loop) 53 | { 54 | _cur_menu_component_num = 0; 55 | _p_sel_menu_component = _menu_components[_cur_menu_component_num]; 56 | 57 | return true; 58 | } 59 | 60 | return false; 61 | } 62 | 63 | boolean Menu::prev(boolean loop) 64 | { 65 | if (_cur_menu_component_num != 0) 66 | { 67 | _cur_menu_component_num--; 68 | _p_sel_menu_component = _menu_components[_cur_menu_component_num]; 69 | 70 | return true; 71 | } else if (loop) 72 | { 73 | _cur_menu_component_num = _num_menu_components - 1; 74 | _p_sel_menu_component = _menu_components[_cur_menu_component_num]; 75 | 76 | return true; 77 | } 78 | 79 | return false; 80 | } 81 | 82 | MenuComponent* Menu::activate() 83 | { 84 | MenuComponent* pComponent = _menu_components[_cur_menu_component_num]; 85 | 86 | if (pComponent == NULL) 87 | return NULL; 88 | 89 | return pComponent->select(); 90 | } 91 | 92 | MenuComponent* Menu::select() 93 | { 94 | return this; 95 | } 96 | 97 | void Menu::add_item(MenuItem* pItem, void (*on_select)(MenuItem*)) 98 | { 99 | // Prevent memory overrun 100 | if (_num_menu_components == MAX_MENU_ITEMS) 101 | return; 102 | 103 | _menu_components[_num_menu_components] = pItem; 104 | 105 | pItem->set_select_function(on_select); 106 | 107 | if (_num_menu_components == 0) 108 | _p_sel_menu_component = pItem; 109 | 110 | _num_menu_components++; 111 | } 112 | 113 | Menu const* Menu::get_parent() const 114 | { 115 | return _p_parent; 116 | } 117 | 118 | void Menu::set_parent(Menu* pParent) 119 | { 120 | _p_parent = pParent; 121 | } 122 | 123 | Menu const* Menu::add_menu(Menu* pMenu) 124 | { 125 | pMenu->set_parent(this); 126 | 127 | _menu_components[_num_menu_components] = pMenu; 128 | 129 | if (_num_menu_components == 0) 130 | _p_sel_menu_component = pMenu; 131 | 132 | _num_menu_components++; 133 | 134 | return pMenu; 135 | } 136 | 137 | MenuComponent const* Menu::get_menu_component(byte index) const 138 | { 139 | return _menu_components[index]; 140 | } 141 | 142 | MenuComponent const* Menu::get_selected() const 143 | { 144 | return _p_sel_menu_component; 145 | } 146 | 147 | byte Menu::get_num_menu_components() const 148 | { 149 | return _num_menu_components; 150 | } 151 | 152 | byte Menu::get_cur_menu_component_num() const 153 | { 154 | return _cur_menu_component_num; 155 | } 156 | 157 | // ********************************************************* 158 | // MenuItem 159 | // ********************************************************* 160 | 161 | MenuItem::MenuItem(const char* name) 162 | : MenuComponent(name), 163 | _on_select(0) 164 | { 165 | } 166 | 167 | void MenuItem::set_select_function(void (*on_select)(MenuItem*)) 168 | { 169 | _on_select = on_select; 170 | } 171 | 172 | MenuComponent* MenuItem::select() 173 | { 174 | if (_on_select != NULL) 175 | _on_select(this); 176 | 177 | return 0; 178 | } 179 | 180 | // ********************************************************* 181 | // MenuSystem 182 | // ********************************************************* 183 | 184 | MenuSystem::MenuSystem() 185 | : _p_root_menu(NULL), 186 | _p_curr_menu(NULL) 187 | { 188 | } 189 | 190 | boolean MenuSystem::next(boolean loop) 191 | { 192 | return _p_curr_menu->next(loop); 193 | } 194 | 195 | boolean MenuSystem::prev(boolean loop) 196 | { 197 | return _p_curr_menu->prev(loop); 198 | } 199 | 200 | void MenuSystem::select() 201 | { 202 | MenuComponent* pComponent = _p_curr_menu->activate(); 203 | 204 | if (pComponent != NULL) 205 | { 206 | _p_curr_menu = (Menu*) pComponent; 207 | } 208 | else 209 | { 210 | // A menu item was selected, so reset the menu ready for when 211 | // it's used again. 212 | _p_curr_menu = _p_root_menu; 213 | } 214 | } 215 | 216 | boolean MenuSystem::back() 217 | { 218 | if (_p_curr_menu != _p_root_menu) 219 | { 220 | _p_curr_menu = const_cast(_p_curr_menu->get_parent()); 221 | return true; 222 | } 223 | 224 | // We are already in the root menu 225 | return false; 226 | } 227 | 228 | void MenuSystem::set_root_menu(Menu* p_root_menu) 229 | { 230 | _p_root_menu = p_root_menu; 231 | _p_curr_menu = p_root_menu; 232 | } 233 | 234 | Menu const* MenuSystem::get_current_menu() const 235 | { 236 | return _p_curr_menu; 237 | } 238 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/MenuSystem.h: -------------------------------------------------------------------------------- 1 | /* 2 | MenuSystem.h - Library for creating menu structures. 3 | Created by Jon Black, August 8th 2011. 4 | Released into the public domain. 5 | 6 | License: LGPL 3 7 | */ 8 | 9 | #ifndef MENUSYSTEM_H 10 | #define MENUSYSTEM_H 11 | 12 | #if defined(ARDUINO) && ARDUINO >= 100 13 | #include 14 | #else 15 | #include 16 | #endif 17 | 18 | 19 | #define MAX_MENU_ITEMS 10 20 | 21 | 22 | class MenuComponent 23 | { 24 | public: 25 | MenuComponent(const char* name); 26 | 27 | void set_name(const char* name); 28 | const char* get_name() const; 29 | 30 | virtual MenuComponent* select() = 0; 31 | 32 | protected: 33 | const char* _name; 34 | }; 35 | 36 | 37 | class MenuItem : public MenuComponent 38 | { 39 | public: 40 | MenuItem(const char* name); 41 | 42 | void set_select_function(void (*on_select)(MenuItem*)); 43 | 44 | virtual MenuComponent* select(); 45 | 46 | private: 47 | void (*_on_select)(MenuItem*); 48 | }; 49 | 50 | 51 | class Menu : public MenuComponent 52 | { 53 | public: 54 | Menu(const char* name); 55 | 56 | boolean next(boolean loop=false); 57 | boolean prev(boolean loop=false); 58 | MenuComponent* activate(); 59 | virtual MenuComponent* select(); 60 | 61 | void add_item(MenuItem* pItem, void (*on_select)(MenuItem*)); 62 | Menu const* add_menu(Menu* pMenu); 63 | 64 | void set_parent(Menu* pParent); 65 | Menu const* get_parent() const; 66 | 67 | MenuComponent const* get_selected() const; 68 | MenuComponent const* get_menu_component(byte index) const; 69 | 70 | byte get_num_menu_components() const; 71 | byte get_cur_menu_component_num() const; 72 | 73 | private: 74 | MenuComponent* _p_sel_menu_component; 75 | MenuComponent* _menu_components[MAX_MENU_ITEMS]; 76 | Menu* _p_parent; 77 | byte _num_menu_components; 78 | byte _cur_menu_component_num; 79 | }; 80 | 81 | 82 | class MenuSystem 83 | { 84 | public: 85 | MenuSystem(); 86 | 87 | boolean next(boolean loop=false); 88 | boolean prev(boolean loop=false); 89 | void select(); 90 | boolean back(); 91 | 92 | void set_root_menu(Menu* p_root_menu); 93 | 94 | Menu const* get_current_menu() const; 95 | 96 | private: 97 | Menu* _p_root_menu; 98 | Menu* _p_curr_menu; 99 | }; 100 | 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/PCD8544_charset.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PCD8544 - Interface with Philips PCD8544 (or compatible) LCDs. 3 | * 4 | * Copyright (c) 2010 Carlos Rodrigues 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | #include 27 | 28 | 29 | // The 7-bit ASCII character set... 30 | const PROGMEM unsigned char charset[][5] = 31 | { 32 | { 0x00, 0x00, 0x00, 0x00, 0x00 }, // 20 space 33 | { 0x00, 0x00, 0x5f, 0x00, 0x00 }, // 21 ! 34 | { 0x00, 0x07, 0x00, 0x07, 0x00 }, // 22 " 35 | { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // 23 # 36 | { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // 24 $ 37 | { 0x23, 0x13, 0x08, 0x64, 0x62 }, // 25 % 38 | { 0x36, 0x49, 0x55, 0x22, 0x50 }, // 26 & 39 | { 0x00, 0x05, 0x03, 0x00, 0x00 }, // 27 ' 40 | { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // 28 ( 41 | { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // 29 ) 42 | { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // 2a * 43 | { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // 2b + 44 | { 0x00, 0x50, 0x30, 0x00, 0x00 }, // 2c , 45 | { 0x08, 0x08, 0x08, 0x08, 0x08 }, // 2d - 46 | { 0x00, 0x60, 0x60, 0x00, 0x00 }, // 2e . 47 | { 0x20, 0x10, 0x08, 0x04, 0x02 }, // 2f / 48 | { 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 30 0 49 | { 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 31 1 50 | { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 32 2 51 | { 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 33 3 52 | { 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 34 4 53 | { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 35 5 54 | { 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 36 6 55 | { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 37 7 56 | { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 38 8 57 | { 0x06, 0x49, 0x49, 0x29, 0x1e }, // 39 9 58 | { 0x00, 0x36, 0x36, 0x00, 0x00 }, // 3a : 59 | { 0x00, 0x56, 0x36, 0x00, 0x00 }, // 3b ; 60 | { 0x08, 0x14, 0x22, 0x41, 0x00 }, // 3c < 61 | { 0x14, 0x14, 0x14, 0x14, 0x14 }, // 3d = 62 | { 0x00, 0x41, 0x22, 0x14, 0x08 }, // 3e > 63 | { 0x02, 0x01, 0x51, 0x09, 0x06 }, // 3f ? 64 | { 0x32, 0x49, 0x79, 0x41, 0x3e }, // 40 @ 65 | { 0x7e, 0x11, 0x11, 0x11, 0x7e }, // 41 A 66 | { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // 42 B 67 | { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // 43 C 68 | { 0x7f, 0x41, 0x41, 0x22, 0x1c }, // 44 D 69 | { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // 45 E 70 | { 0x7f, 0x09, 0x09, 0x09, 0x01 }, // 46 F 71 | { 0x3e, 0x41, 0x49, 0x49, 0x7a }, // 47 G 72 | { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // 48 H 73 | { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // 49 I 74 | { 0x20, 0x40, 0x41, 0x3f, 0x01 }, // 4a J 75 | { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // 4b K 76 | { 0x7f, 0x40, 0x40, 0x40, 0x40 }, // 4c L 77 | { 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // 4d M 78 | { 0x7f, 0x04, 0x08, 0x10, 0x7f }, // 4e N 79 | { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // 4f O 80 | { 0x7f, 0x09, 0x09, 0x09, 0x06 }, // 50 P 81 | { 0x3e, 0x41, 0x51, 0x21, 0x5e }, // 51 Q 82 | { 0x7f, 0x09, 0x19, 0x29, 0x46 }, // 52 R 83 | { 0x46, 0x49, 0x49, 0x49, 0x31 }, // 53 S 84 | { 0x01, 0x01, 0x7f, 0x01, 0x01 }, // 54 T 85 | { 0x3f, 0x40, 0x40, 0x40, 0x3f }, // 55 U 86 | { 0x1f, 0x20, 0x40, 0x20, 0x1f }, // 56 V 87 | { 0x3f, 0x40, 0x38, 0x40, 0x3f }, // 57 W 88 | { 0x63, 0x14, 0x08, 0x14, 0x63 }, // 58 X 89 | { 0x07, 0x08, 0x70, 0x08, 0x07 }, // 59 Y 90 | { 0x61, 0x51, 0x49, 0x45, 0x43 }, // 5a Z 91 | { 0x00, 0x7f, 0x41, 0x41, 0x00 }, // 5b [ 92 | { 0x02, 0x04, 0x08, 0x10, 0x20 }, // 5c backslash 93 | { 0x00, 0x41, 0x41, 0x7f, 0x00 }, // 5d ] 94 | { 0x04, 0x02, 0x01, 0x02, 0x04 }, // 5e ^ 95 | { 0x40, 0x40, 0x40, 0x40, 0x40 }, // 5f _ 96 | { 0x00, 0x01, 0x02, 0x04, 0x00 }, // 60 ` 97 | { 0x20, 0x54, 0x54, 0x54, 0x78 }, // 61 a 98 | { 0x7f, 0x48, 0x44, 0x44, 0x38 }, // 62 b 99 | { 0x38, 0x44, 0x44, 0x44, 0x20 }, // 63 c 100 | { 0x38, 0x44, 0x44, 0x48, 0x7f }, // 64 d 101 | { 0x38, 0x54, 0x54, 0x54, 0x18 }, // 65 e 102 | { 0x08, 0x7e, 0x09, 0x01, 0x02 }, // 66 f 103 | { 0x0c, 0x52, 0x52, 0x52, 0x3e }, // 67 g 104 | { 0x7f, 0x08, 0x04, 0x04, 0x78 }, // 68 h 105 | { 0x00, 0x44, 0x7d, 0x40, 0x00 }, // 69 i 106 | { 0x20, 0x40, 0x44, 0x3d, 0x00 }, // 6a j 107 | { 0x7f, 0x10, 0x28, 0x44, 0x00 }, // 6b k 108 | { 0x00, 0x41, 0x7f, 0x40, 0x00 }, // 6c l 109 | { 0x7c, 0x04, 0x18, 0x04, 0x78 }, // 6d m 110 | { 0x7c, 0x08, 0x04, 0x04, 0x78 }, // 6e n 111 | { 0x38, 0x44, 0x44, 0x44, 0x38 }, // 6f o 112 | { 0x7c, 0x14, 0x14, 0x14, 0x08 }, // 70 p 113 | { 0x08, 0x14, 0x14, 0x18, 0x7c }, // 71 q 114 | { 0x7c, 0x08, 0x04, 0x04, 0x08 }, // 72 r 115 | { 0x48, 0x54, 0x54, 0x54, 0x20 }, // 73 s 116 | { 0x04, 0x3f, 0x44, 0x40, 0x20 }, // 74 t 117 | { 0x3c, 0x40, 0x40, 0x20, 0x7c }, // 75 u 118 | { 0x1c, 0x20, 0x40, 0x20, 0x1c }, // 76 v 119 | { 0x3c, 0x40, 0x30, 0x40, 0x3c }, // 77 w 120 | { 0x44, 0x28, 0x10, 0x28, 0x44 }, // 78 x 121 | { 0x0c, 0x50, 0x50, 0x50, 0x3c }, // 79 y 122 | { 0x44, 0x64, 0x54, 0x4c, 0x44 }, // 7a z 123 | { 0x00, 0x08, 0x36, 0x41, 0x00 }, // 7b { 124 | { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // 7c | 125 | { 0x00, 0x41, 0x36, 0x08, 0x00 }, // 7d } 126 | { 0x10, 0x08, 0x08, 0x10, 0x08 }, // 7e ~ 127 | { 0x00, 0x00, 0x00, 0x00, 0x00 } // 7f 128 | }; 129 | 130 | 131 | /* vim: set expandtab ts=4 sw=4: */ 132 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/PCD8544_nano.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PCD8544 - Interface with Philips PCD8544 (or compatible) LCDs. 3 | * 4 | * Copyright (c) 2010 Carlos Rodrigues 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | #include "config.h" 27 | 28 | #if (DISPLAY_TYPE & DISPLAY_TYPE_NOKIA) 29 | #ifndef PCD8544_H 30 | #define PCD8544_H 31 | 32 | 33 | 34 | #if ARDUINO < 100 35 | #include 36 | #else 37 | #include 38 | #endif 39 | 40 | 41 | // Chip variants supported... 42 | #define CHIP_PCD8544 0 43 | #define CHIP_ST7576 1 44 | 45 | 46 | class PCD8544: public Print 47 | { 48 | 49 | public: 50 | // All the pins can be changed from the default values... 51 | #if HARDWARE_REV <= 5 52 | #define DISPLAYPORT PORTB 53 | #define DISPLAYPORT_DIR DDRB 54 | PCD8544(unsigned char sclk = 1, /* clock (display pin 2) */ 55 | unsigned char sdin = 2, /* data-in (display pin 3) */ 56 | unsigned char dc = 3, /* data select (display pin 4) */ 57 | #if (DISPLAY_TYPE==DISPLAY_TYPE_NOKIA_4PIN) 58 | unsigned char reset = 5, /* reset (display pin 8) */ 59 | unsigned char sce = 4); /* enable (display pin 5) */ 60 | #endif 61 | #if (DISPLAY_TYPE==DISPLAY_TYPE_NOKIA_5PIN) 62 | unsigned char reset = 4, /* reset (display pin 8) */ 63 | unsigned char sce = 5); /* enable (display pin 5) */ 64 | #endif 65 | #endif 66 | 67 | #if HARDWARE_REV >= 20 68 | #define DISPLAYPORT PORTH 69 | #define DISPLAYPORT_DIR DDRH 70 | PCD8544(unsigned char sclk = 4, /* clock (display pin 2) */ 71 | unsigned char sdin = 0, /* data-in (display pin 3) */ 72 | unsigned char dc = 1, /* data select (display pin 4) */ 73 | #if (DISPLAY_TYPE==DISPLAY_TYPE_NOKIA_4PIN) 74 | unsigned char reset = 3, /* reset (display pin 8) */ 75 | unsigned char sce = 2); /* enable (display pin 5) */ 76 | #endif 77 | #if (DISPLAY_TYPE==DISPLAY_TYPE_NOKIA_5PIN) 78 | unsigned char reset = 2, /* reset (display pin 8) */ 79 | unsigned char sce = 3); /* enable (display pin 5) */ 80 | #endif 81 | #endif 82 | 83 | 84 | // Display initialization (dimensions in pixels)... 85 | void begin(unsigned char width=84, unsigned char height=48, unsigned char model=CHIP_PCD8544); 86 | void stop(); 87 | 88 | // Erase everything on the display... 89 | void clear(); 90 | void clearLine(); // ...or just the current line 91 | 92 | // Control the display's power state... 93 | void setPower(bool on); 94 | 95 | // For compatibility with the LiquidCrystal library... 96 | void display(); 97 | void noDisplay(); 98 | 99 | // Activate white-on-black mode (whole display)... 100 | void setInverse(bool inverse); 101 | 102 | // Place the cursor at the start of the current line... 103 | void home(); 104 | 105 | // Place the cursor at position (column, line)... 106 | void setCursor(unsigned char column, unsigned char line); 107 | 108 | //same as SetCursor, but the column is specified in pixels, not in 6-pixel wide characters 109 | void setCursorInPixels(unsigned char column, unsigned char line); 110 | 111 | // Assign a user-defined glyph (5x8) to an ASCII character (0-31)... 112 | void createChar(unsigned char chr, const unsigned char *glyph); 113 | 114 | void shiftOutFast(unsigned char myDataPin, unsigned char myClockPin, unsigned char myDataOut); 115 | 116 | // Write an ASCII character at the current cursor position (7-bit)... 117 | #if ARDUINO < 100 118 | virtual void write(uint8_t chr); 119 | #else 120 | virtual size_t write(uint8_t chr); 121 | #endif 122 | 123 | // Draw a bitmap at the current cursor position... 124 | void drawBitmap(const unsigned char *data, unsigned char columns, unsigned char lines); 125 | 126 | // Draw a chart element at the current cursor position... 127 | void drawColumn(unsigned char lines, unsigned char value); 128 | 129 | //Draws a vertical bargraph with an outer and inner frame. One pixel line at the bottom is left free. It is not used because of 1 pixel necessary distance to the next line of text below the bar. 130 | //An (optional) horizontal limit line is drawn into the bar. If you do not want to use the limit line, then set limit to the same value as maxValue. E.G. drawVerticalBar(100,100,50); 131 | void drawVerticalBar(word maxValue, word limit, word value, byte widthInPixels, byte heightInBytes, byte outerFrameInPixels=2, byte innerFrameInPixels=1); 132 | 133 | private: 134 | unsigned char pin_sclk; 135 | unsigned char pin_sdin; 136 | unsigned char pin_dc; 137 | unsigned char pin_reset; 138 | unsigned char pin_sce; 139 | 140 | // The size of the display, in pixels... 141 | unsigned char width; 142 | unsigned char height; 143 | 144 | // Current cursor position... 145 | unsigned char column; 146 | unsigned char line; 147 | 148 | // User-defined glyphs (below the ASCII space character)... 149 | const unsigned char *custom[' ']; 150 | 151 | // Send a command or data to the display... 152 | void send(unsigned char type, unsigned char data); 153 | }; 154 | 155 | 156 | #endif /* PCD8544_H */ 157 | 158 | 159 | /* vim: set expandtab ts=4 sw=4: */ 160 | #endif 161 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/PID_v1_nano.cpp: -------------------------------------------------------------------------------- 1 | /********************************************************************************************** 2 | * Arduino PID Library - Version 1.0.1 3 | * by Brett Beauregard brettbeauregard.com 4 | * 5 | * This Library is licensed under a GPLv3 License 6 | **********************************************************************************************/ 7 | 8 | #if ARDUINO >= 100 9 | #include "Arduino.h" 10 | #else 11 | #include "WProgram.h" 12 | #endif 13 | 14 | #include "PID_v1_nano.h" 15 | 16 | /*Constructor (...)********************************************************* 17 | * The parameters specified here are those for for which we can't set up 18 | * reliable defaults, so we need to have the user set them. 19 | ***************************************************************************/ 20 | PID::PID(double* Input, double* Output, double* Setpoint, 21 | double Kp, double Ki, double Kd, int ControllerDirection) 22 | { 23 | 24 | myOutput = Output; 25 | myInput = Input; 26 | mySetpoint = Setpoint; 27 | inAuto = false; 28 | 29 | PID::SetOutputLimits(0, 255); //default output limit corresponds to 30 | //the arduino pwm limits 31 | 32 | SampleTime = 100; //default Controller Sample Time is 0.1 seconds 33 | 34 | PID::SetControllerDirection(ControllerDirection); 35 | PID::SetTunings(Kp, Ki, Kd); 36 | 37 | lastTime = millis()-SampleTime; 38 | lastTimeShrink = millis()-SampleTime; 39 | } 40 | 41 | 42 | /* Compute() ********************************************************************** 43 | * This, as they say, is where the magic happens. this function should be called 44 | * every time "void loop()" executes. the function will decide for itself whether a new 45 | * pid Output needs to be computed. returns true when the output is computed, 46 | * false when nothing has been done. 47 | **********************************************************************************/ 48 | bool PID::Compute() 49 | { 50 | if(!inAuto) return false; 51 | unsigned long now = millis(); 52 | unsigned long timeChange = (now - lastTime); 53 | if(timeChange>=SampleTime) 54 | { 55 | /*Compute all the working error variables*/ 56 | double input = *myInput; 57 | double error = *mySetpoint - input; 58 | ITerm+= (ki * error); 59 | if(ITerm > outMax) ITerm= outMax; 60 | else if(ITerm < outMin) ITerm= outMin; 61 | double dInput = (input - lastInput); 62 | 63 | /*Compute PID Output*/ 64 | double output = kp * error + ITerm- kd * dInput; 65 | 66 | if(output > outMax) output = outMax; 67 | else if(output < outMin) output = outMin; 68 | *myOutput = output; 69 | 70 | /*Remember some variables for next time*/ 71 | lastInput = input; 72 | lastTime = now; 73 | return true; 74 | } 75 | else return false; 76 | } 77 | 78 | 79 | /* SetTunings(...)************************************************************* 80 | * This function allows the controller's dynamic performance to be adjusted. 81 | * it's called automatically from the constructor, but tunings can also 82 | * be adjusted on the fly during normal operation 83 | ******************************************************************************/ 84 | void PID::SetTunings(double Kp, double Ki, double Kd) 85 | { 86 | if (Kp<0 || Ki<0 || Kd<0) return; 87 | 88 | dispKp = Kp; dispKi = Ki; dispKd = Kd; 89 | 90 | double SampleTimeInSec = ((double)SampleTime)/1000; 91 | kp = Kp; 92 | ki = Ki * SampleTimeInSec; 93 | kd = Kd / SampleTimeInSec; 94 | 95 | if(controllerDirection ==REVERSE) 96 | { 97 | kp = (0 - kp); 98 | ki = (0 - ki); 99 | kd = (0 - kd); 100 | } 101 | } 102 | 103 | /* SetSampleTime(...) ********************************************************* 104 | * sets the period, in Milliseconds, at which the calculation is performed 105 | ******************************************************************************/ 106 | void PID::SetSampleTime(int NewSampleTime) 107 | { 108 | if (NewSampleTime > 0) 109 | { 110 | double ratio = (double)NewSampleTime 111 | / (double)SampleTime; 112 | ki *= ratio; 113 | kd /= ratio; 114 | SampleTime = (unsigned long)NewSampleTime; 115 | } 116 | } 117 | 118 | /* SetOutputLimits(...)**************************************************** 119 | * This function will be used far more often than SetInputLimits. while 120 | * the input to the controller will generally be in the 0-1023 range (which is 121 | * the default already,) the output will be a little different. maybe they'll 122 | * be doing a time window and will need 0-8000 or something. or maybe they'll 123 | * want to clamp it from 0-125. who knows. at any rate, that can all be done 124 | * here. 125 | **************************************************************************/ 126 | void PID::SetOutputLimits(double Min, double Max) 127 | { 128 | if(Min >= Max) return; 129 | outMin = Min; 130 | outMax = Max; 131 | 132 | if(inAuto) 133 | { 134 | if(*myOutput > outMax) *myOutput = outMax; 135 | else if(*myOutput < outMin) *myOutput = outMin; 136 | 137 | if(ITerm > outMax) ITerm= outMax; 138 | else if(ITerm < outMin) ITerm= outMin; 139 | } 140 | } 141 | 142 | /* SetMode(...)**************************************************************** 143 | * Allows the controller Mode to be set to manual (0) or Automatic (non-zero) 144 | * when the transition from manual to auto occurs, the controller is 145 | * automatically initialized 146 | ******************************************************************************/ 147 | void PID::SetMode(int Mode) 148 | { 149 | bool newAuto = (Mode == AUTOMATIC); 150 | if(newAuto == !inAuto) 151 | { 152 | /*we just went from manual to auto*/ 153 | PID::Initialize(); 154 | } 155 | inAuto = newAuto; 156 | } 157 | 158 | /* Initialize()**************************************************************** 159 | * does all the things that need to happen to ensure a bumpless transfer 160 | * from manual to automatic mode. 161 | ******************************************************************************/ 162 | void PID::Initialize() 163 | { 164 | ITerm = *myOutput; 165 | lastInput = *myInput; 166 | if(ITerm > outMax) ITerm = outMax; 167 | else if(ITerm < outMin) ITerm = outMin; 168 | } 169 | 170 | /* SetControllerDirection(...)************************************************* 171 | * The PID will either be connected to a DIRECT acting process (+Output leads 172 | * to +Input) or a REVERSE acting process(+Output leads to -Input.) we need to 173 | * know which one, because otherwise we may increase the output when we should 174 | * be decreasing. This is called from the constructor. 175 | ******************************************************************************/ 176 | void PID::SetControllerDirection(int Direction) 177 | { 178 | if(inAuto && Direction !=controllerDirection) 179 | { 180 | kp = (0 - kp); 181 | ki = (0 - ki); 182 | kd = (0 - kd); 183 | } 184 | controllerDirection = Direction; 185 | } 186 | 187 | /* Status Funcions************************************************************* 188 | * Just because you set the Kp=-1 doesn't mean it actually happened. these 189 | * functions query the internal state of the PID. they're here for display 190 | * purposes. this are the functions the PID Front-end uses for example 191 | ******************************************************************************/ 192 | double PID::GetKp() { return dispKp; } 193 | double PID::GetKi() { return dispKi;} 194 | double PID::GetKd() { return dispKd;} 195 | int PID::GetMode() { return inAuto ? AUTOMATIC : MANUAL;} 196 | int PID::GetDirection() { return controllerDirection;} 197 | 198 | /* Reset ITerm************************************************* 199 | * Reset integral part 200 | ******************************************************************************/ 201 | void PID::ResetIntegral() 202 | { 203 | ITerm = 0; 204 | } 205 | 206 | void PID::ShrinkIntegral() 207 | { 208 | unsigned long now = millis(); 209 | unsigned long timeChange = (now - lastTimeShrink); 210 | if(timeChange>=SampleTime) 211 | { 212 | ITerm*=0.99; 213 | lastTimeShrink = now; 214 | } 215 | } 216 | 217 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/PID_v1_nano.h: -------------------------------------------------------------------------------- 1 | #ifndef PID_v1_h 2 | #define PID_v1_h 3 | #define LIBRARY_VERSION 1.0.0 4 | 5 | class PID 6 | { 7 | 8 | 9 | public: 10 | 11 | //Constants used in some of the functions below 12 | #define AUTOMATIC 1 13 | #define MANUAL 0 14 | #define DIRECT 0 15 | #define REVERSE 1 16 | 17 | //commonly used functions ************************************************************************** 18 | PID(double*, double*, double*, // * constructor. links the PID to the Input, Output, and 19 | double, double, double, int); // Setpoint. Initial tuning parameters are also set here 20 | 21 | void SetMode(int Mode); // * sets PID to either Manual (0) or Auto (non-0) 22 | 23 | bool Compute(); // * performs the PID calculation. it should be 24 | // called every time loop() cycles. ON/OFF and 25 | // calculation frequency can be set using SetMode 26 | // SetSampleTime respectively 27 | 28 | void SetOutputLimits(double, double); //clamps the output to a specific range. 0-255 by default, but 29 | //it's likely the user will want to change this depending on 30 | //the application 31 | 32 | 33 | 34 | //available but not commonly used functions ******************************************************** 35 | void SetTunings(double, double, // * While most users will set the tunings once in the 36 | double); // constructor, this function gives the user the option 37 | // of changing tunings during runtime for Adaptive control 38 | void SetControllerDirection(int); // * Sets the Direction, or "Action" of the controller. DIRECT 39 | // means the output will increase when error is positive. REVERSE 40 | // means the opposite. it's very unlikely that this will be needed 41 | // once it is set in the constructor. 42 | void SetSampleTime(int); // * sets the frequency, in Milliseconds, with which 43 | // the PID calculation is performed. default is 100 44 | 45 | void ResetIntegral(); //resets integral part 46 | void ShrinkIntegral(); //shrinks integral part, used to slowly fade out 47 | 48 | 49 | 50 | //Display functions **************************************************************** 51 | double GetKp(); // These functions query the pid for interal values. 52 | double GetKi(); // they were created mainly for the pid front-end, 53 | double GetKd(); // where it's important to know what is actually 54 | int GetMode(); // inside the PID. 55 | int GetDirection(); // 56 | 57 | private: 58 | void Initialize(); 59 | 60 | double dispKp; // * we'll hold on to the tuning parameters in user-entered 61 | double dispKi; // format for display purposes 62 | double dispKd; // 63 | 64 | double kp; // * (P)roportional Tuning Parameter 65 | double ki; // * (I)ntegral Tuning Parameter 66 | double kd; // * (D)erivative Tuning Parameter 67 | 68 | int controllerDirection; 69 | 70 | double *myInput; // * Pointers to the Input, Output, and Setpoint variables 71 | double *myOutput; // This creates a hard link between the variables and the 72 | double *mySetpoint; // PID, freeing the user from having to constantly tell us 73 | // what these values are. with pointers we'll just know. 74 | 75 | unsigned long lastTime, lastTimeShrink; 76 | double ITerm, lastInput; 77 | 78 | unsigned long SampleTime; 79 | double outMin, outMax; 80 | bool inAuto; 81 | }; 82 | #endif 83 | 84 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/display.h: -------------------------------------------------------------------------------- 1 | /* 2 | Generic display init and update functions 3 | Written by Thomas Jarosch 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | #ifndef DISPLAY_H 20 | #define DISPLAY_H 21 | 22 | #include "Arduino.h" 23 | 24 | void display_init(); 25 | void display_update(); 26 | void display_debug(HardwareSerial* localSerial); 27 | 28 | void display_show_important_info(const char *str, int duration_secs); 29 | void display_show_important_info(const __FlashStringHelper *str, int duration_secs); 30 | 31 | void display_show_welcome_msg(); 32 | void display_show_welcome_msg_temp(); 33 | 34 | void display_prev_view(); 35 | void display_next_view(); 36 | 37 | #if (DISPLAY_TYPE & DISPLAY_TYPE_16X2_SERIAL) 38 | void display_16x_serial_enable_backlight(); 39 | void display_16x_serial_disable_backlight(); 40 | #endif 41 | 42 | //definitions for different screen mode 43 | typedef enum {DISPLAY_MODE_TEXT, 44 | DISPLAY_MODE_GRAPHIC, // Note: Same as _TEXT on 16x2 displays 45 | DISPLAY_MODE_MENU, 46 | DISPLAY_MODE_IMPORTANT_INFO 47 | } display_mode_type; 48 | 49 | typedef enum {DISPLAY_VIEW_MAIN=0, 50 | #if (DISPLAY_TYPE & DISPLAY_TYPE_NOKIA)&&(defined(DV_GRAPHIC)) 51 | DISPLAY_VIEW_GRAPHIC, 52 | #endif 53 | #if (DISPLAY_TYPE & DISPLAY_TYPE_16X2) 54 | #if defined(DV_TIME) 55 | DISPLAY_VIEW_TIME, 56 | #endif 57 | #if defined(DV_BATTERY) 58 | DISPLAY_VIEW_BATTERY, 59 | #endif 60 | #endif 61 | #if (defined(SUPPORT_BMP085) || defined(SUPPORT_DSPC01) || defined(SUPPORT_TEMP_SENSOR) || defined(SUPPORT_THERMISTOR)) && defined(DV_ENVIRONMENT) 62 | DISPLAY_VIEW_ENVIRONMENT, 63 | #endif 64 | #if defined(DV_HUMAN) 65 | DISPLAY_VIEW_HUMAN, 66 | #endif 67 | #if defined(DV_ODOMETER) 68 | DISPLAY_VIEW_ODOMETER, 69 | #endif 70 | _DISPLAY_VIEW_END 71 | } display_view_type; 72 | 73 | extern display_view_type display_view; 74 | 75 | extern display_mode_type display_mode; //currently display mode 76 | extern boolean display_force_text; //only valid for Nokia displays 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/display_backlight.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Generic LCD display backlight functions 3 | (c) 2012 Thomas Jarosch 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | #include "display_backlight.h" 20 | #include "display.h" 21 | #include "config.h" 22 | 23 | #ifdef SUPPORT_DISPLAY_BACKLIGHT 24 | const unsigned int backlight_default_show_ms = 5 * 1000; // Time backlight stays on by default 25 | const unsigned int backlight_blink_pause = 500; // Blink mode: Number of milliseconds between blink switch 26 | const unsigned int backlight_blink_goal = 4; // Number of blinks to do 27 | 28 | bool force_backlight_on = false; 29 | 30 | enum backlight_states 31 | { 32 | BacklightOff, // backlight is off 33 | BacklightTriggerOff, // backlight should be disabled 34 | BacklightOn, // backlight is on 35 | BacklightTriggerOn, // backlight should be enabled 36 | BacklightBlink, // backlight in blick mode 37 | BacklightTriggerBlink // backlight should start to blink 38 | }; 39 | 40 | backlight_states backlight_state = BacklightOff; 41 | unsigned long backlight_next_event_ms = 0; // When should we process next backlight state 42 | 43 | unsigned int backlight_show_ms = 0; // Custom show time if wanted 44 | bool backlight_blink_currently_enabled = false; // Blink mode: True if backlight is currently on 45 | bool backlight_blink_done_stay_on = false; // If true we stay on after blinking 46 | unsigned int backlight_blink_count = 0; // Number of blinks done 47 | 48 | static void turn_backlight_on() 49 | { 50 | #if (DISPLAY_TYPE & DISPLAY_TYPE_16X2_SERIAL) 51 | display_16x_serial_enable_backlight(); 52 | #elif HARDWARE_REV >= 20 53 | // TODO: Make configurable 54 | bitSet(PORTH, 2); 55 | #else 56 | digitalWrite(display_backlight_pin, HIGH); 57 | #endif 58 | } 59 | 60 | static void turn_backlight_off() 61 | { 62 | // User wants the backlight to be temporarily "always on" 63 | if (force_backlight_on) 64 | { 65 | turn_backlight_on(); 66 | return; 67 | } 68 | 69 | #if (DISPLAY_TYPE & DISPLAY_TYPE_16X2_SERIAL) 70 | display_16x_serial_disable_backlight(); 71 | #elif HARDWARE_REV >= 20 72 | // TODO: Make configurable 73 | bitClear(PORTH, 2); 74 | #else 75 | digitalWrite(display_backlight_pin, LOW); 76 | #endif 77 | } 78 | 79 | static void enter_backlight_state(const backlight_states new_state) 80 | { 81 | // We reached the next backlight event. Process it 82 | switch (new_state) 83 | { 84 | case BacklightTriggerOn: 85 | backlight_state = BacklightOn; 86 | backlight_next_event_ms = millis() + backlight_show_ms; 87 | turn_backlight_on(); 88 | break; 89 | case BacklightTriggerBlink: 90 | backlight_blink_count = 0; 91 | backlight_blink_currently_enabled = false; 92 | backlight_state = BacklightBlink; 93 | case BacklightBlink: 94 | ++backlight_blink_count; 95 | backlight_next_event_ms = millis() + backlight_blink_pause; 96 | 97 | // Trigger state change if we are done blinking 98 | if (backlight_blink_count > backlight_blink_goal) 99 | { 100 | if (backlight_blink_done_stay_on) 101 | { 102 | backlight_show_ms = backlight_default_show_ms; 103 | backlight_state = BacklightTriggerOn; 104 | } 105 | else 106 | backlight_state = BacklightTriggerOff; 107 | } 108 | 109 | backlight_blink_currently_enabled = !backlight_blink_currently_enabled; 110 | if (backlight_blink_currently_enabled) 111 | turn_backlight_on(); 112 | else 113 | turn_backlight_off(); 114 | break; 115 | case BacklightTriggerOff: 116 | case BacklightOn: 117 | case BacklightOff: 118 | default: 119 | backlight_state = BacklightOff; 120 | backlight_next_event_ms = 0; 121 | backlight_show_ms = backlight_default_show_ms; 122 | backlight_blink_count = 0; 123 | backlight_blink_currently_enabled = false; 124 | backlight_blink_done_stay_on = false; 125 | turn_backlight_off(); 126 | break; 127 | } 128 | } 129 | 130 | void enable_backlight() 131 | { 132 | backlight_show_ms = backlight_default_show_ms; 133 | enter_backlight_state(BacklightTriggerOn); 134 | } 135 | 136 | void enable_custom_backlight(unsigned int duration_ms) 137 | { 138 | backlight_show_ms = duration_ms; 139 | enter_backlight_state(BacklightTriggerOn); 140 | } 141 | 142 | void blink_backlight() 143 | { 144 | backlight_blink_done_stay_on = false; 145 | enter_backlight_state(BacklightTriggerBlink); 146 | } 147 | 148 | void blink_backlight_stay_on() 149 | { 150 | backlight_blink_done_stay_on = true; 151 | enter_backlight_state(BacklightTriggerBlink); 152 | } 153 | 154 | void handle_backlight() 155 | { 156 | if (backlight_state == BacklightOff) 157 | return; 158 | 159 | if (millis() < backlight_next_event_ms) 160 | return; 161 | 162 | // Enter next backlight state 163 | enter_backlight_state(backlight_state); 164 | } 165 | 166 | bool toggle_force_backlight_on() 167 | { 168 | force_backlight_on = !force_backlight_on; 169 | return force_backlight_on; 170 | } 171 | 172 | #endif 173 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/display_backlight.h: -------------------------------------------------------------------------------- 1 | /* 2 | Generic LCD display backlight functions 3 | (c) 2012 Thomas Jarosch 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | #ifndef DISPLAY_BACKLIGHT_H 20 | #define DISPLAY_BACKLIGHT_H 21 | 22 | #include "config.h" 23 | 24 | #ifdef SUPPORT_DISPLAY_BACKLIGHT 25 | void enable_backlight(); 26 | void enable_custom_backlight(unsigned int duration_ms); 27 | void blink_backlight(); 28 | void blink_backlight_stay_on(); 29 | void handle_backlight(); 30 | 31 | bool toggle_force_backlight_on(); 32 | 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/display_bafang.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library for Bafang BBS01/BBS02 Displays (C965) 3 | 4 | Copyright © 2016 Jens Kießling (jenskiessling@gmail.com) 5 | inspired by Kingmeter Library (Michael Fabry) 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | */ 21 | 22 | 23 | #ifndef BAFANG_H 24 | #define BAFANG_H 25 | 26 | 27 | // Includes 28 | #include "config.h" 29 | 30 | #if (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG) 31 | 32 | #if HARDWARE_REV < 20 33 | #include 34 | #endif 35 | 36 | 37 | // Definitions 38 | #define BF_CMD_STARTREQUEST 17 39 | #define BF_CMD_STARTINFO 22 40 | #define BF_CMD_LEVEL 11 41 | #define BF_CMD_LIGHT 26 42 | #define BF_CMD_WHEELDIAM 31 43 | #define BF_CMD_GETSPEED 32 44 | #define BF_CMD_GETERROR 8 45 | #define BF_CMD_GETBAT 17 46 | #define BF_CMD_GETPOWER 10 47 | #define BF_CMD_GET2 49 48 | 49 | #define BF_LIGHTON 241 50 | 51 | #define BF_MAX_RXBUFF 6 52 | #define BF_MAX_TXBUFF 3 53 | 54 | #define BF_LEVEL0 0 55 | #define BF_LEVEL1 1 56 | #define BF_LEVEL2 11 57 | #define BF_LEVEL3 12 58 | #define BF_LEVEL4 13 59 | #define BF_LEVEL5 2 60 | #define BF_LEVEL6 21 61 | #define BF_LEVEL7 22 62 | #define BF_LEVEL8 23 63 | #define BF_LEVEL9 3 64 | #define BF_PUSHASSIST 6 65 | 66 | #define BF_DISPLAYTIMEOUT 10 67 | 68 | typedef struct 69 | { 70 | // Parameters received from display in operation mode: 71 | uint8_t AssistLevel; // 0..9 Power Assist Level 72 | uint8_t Headlight; // BF_HEADLIGHT_OFF / BF_HEADLIGHT_ON 73 | uint8_t PushAssist; // BF_PUSHASSIST_OFF / BF_PUSHASSIST_ON 74 | uint16_t Wheeldiameter; // Wheel Diameter 75 | }RX_PARAM_t; 76 | 77 | 78 | typedef struct 79 | { 80 | #if HARDWARE_REV < 20 81 | SoftwareSerial* SerialPort; 82 | #else 83 | HardwareSerial* SerialPort; 84 | #endif 85 | 86 | uint8_t RxState; 87 | uint32_t LastRx; 88 | 89 | uint8_t RxBuff[BF_MAX_RXBUFF]; 90 | uint8_t RxCnt; 91 | uint8_t InfoLength; 92 | 93 | RX_PARAM_t Rx; 94 | 95 | }BAFANG_t; 96 | 97 | 98 | 99 | 100 | // Public function prototypes 101 | #if HARDWARE_REV < 20 102 | void Bafang_Init (BAFANG_t* BF_ctx, SoftwareSerial* DisplaySerial); 103 | #else 104 | void Bafang_Init (BAFANG_t* BF_ctx, HardwareSerial* DisplaySerial); 105 | #endif 106 | 107 | void Bafang_Service(BAFANG_t* BF_ctx); 108 | 109 | void BF_sendmessage(BAFANG_t* BF_ctx,uint8_t count); 110 | 111 | 112 | #endif // BAFANG 113 | #endif // (DISPLAY_TYPE & DISPLAY_TYPE_BAFANG) 114 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/display_kingmeter.h: -------------------------------------------------------------------------------- 1 | /* 2 | Library for King-Meter displays 3 | 4 | Copyright © 2015 Michael Fabry (Michael@Fabry.de) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | 19 | */ 20 | 21 | 22 | #ifndef KINGMETER_H 23 | #define KINGMETER_H 24 | 25 | 26 | // Includes 27 | #include "config.h" 28 | 29 | #if (DISPLAY_TYPE & DISPLAY_TYPE_KINGMETER) 30 | 31 | #if HARDWARE_REV < 20 32 | #include 33 | #endif 34 | 35 | 36 | // Definitions 37 | #define KM_MAX_WHEELTIME 0x0DAC // Maximum Wheeltime reported to the display (e.g. when wheel is stopped) 38 | 39 | #if (DISPLAY_TYPE == DISPLAY_TYPE_KINGMETER_618U) 40 | #define KM_MAX_RXBUFF 6 41 | #define KM_MAX_TXBUFF 8 42 | #endif 43 | 44 | #if (DISPLAY_TYPE == DISPLAY_TYPE_KINGMETER_901U) 45 | #define KM_MAX_RXBUFF 20 46 | #define KM_MAX_TXBUFF 11 47 | #endif 48 | 49 | 50 | #define KM_PASDIR_FORWARD 0x00 51 | #define KM_PASDIR_BACKWARD 0x01 52 | 53 | #define KM_HND_HL_NO 0x00 54 | #define KM_HND_HL_YES 0x01 55 | 56 | #define KM_HND_HF_NO 0x00 57 | #define KM_HND_HF_YES 0x01 58 | 59 | 60 | #define KM_WHEELSIZE_8 638 61 | #define KM_WHEELSIZE_10 798 62 | #define KM_WHEELSIZE_12 958 63 | #define KM_WHEELSIZE_14 1117 64 | 65 | #define KM_WHEELSIZE_16 1277 66 | #define KM_WHEELSIZE_18 1436 67 | #define KM_WHEELSIZE_20 1596 68 | #define KM_WHEELSIZE_22 1756 69 | #define KM_WHEELSIZE_24 1915 70 | #define KM_WHEELSIZE_26 2075 71 | #define KM_WHEELSIZE_700 2154 72 | #define KM_WHEELSIZE_28 2234 73 | 74 | #define KM_WHEELSIZE_29 2294 75 | 76 | 77 | #if (DISPLAY_TYPE == DISPLAY_TYPE_KINGMETER_618U) 78 | const uint16_t KM_WHEELSIZE[8] = { KM_WHEELSIZE_16, KM_WHEELSIZE_18, KM_WHEELSIZE_20, KM_WHEELSIZE_22, 79 | KM_WHEELSIZE_24, KM_WHEELSIZE_26, KM_WHEELSIZE_700, KM_WHEELSIZE_28 }; 80 | #endif 81 | 82 | 83 | typedef struct 84 | { 85 | // Parameters received from display in setting mode: 86 | uint16_t WheelSize_mm; // Unit: 1mm 87 | uint8_t PAS_RUN_Direction; // KM_PASDIR_FORWARD / KM_PASDIR_BACKWARD 88 | uint8_t PAS_SCN_Tolerance; // Number of PAS signals to start the motor 89 | uint8_t PAS_N_Ratio; // 0..255 PAS ratio 90 | uint8_t HND_HL_ThrParam; // KM_HND_HL_NO / KM_HND_HL_YES 91 | uint8_t HND_HF_ThrParam; // KM_HND_HF_NO / KM_HND_HF_YES 92 | uint8_t SYS_SSP_SlowStart; // 1..4 Level of soft ramping at start 93 | uint8_t SPS_SpdMagnets; // Number of magnets of speedsensor 94 | uint16_t VOL_1_UnderVolt_x10; // Unit: 0.1V 95 | 96 | }RX_SETTINGS_t; 97 | 98 | 99 | 100 | #define KM_HEADLIGHT_OFF 0x00 101 | #define KM_HEADLIGHT_ON 0x01 102 | #define KM_HEADLIGHT_LOW 0x02 103 | #define KM_HEADLIGHT_HIGH 0x03 104 | 105 | #define KM_BATTERY_NORMAL 0x00 106 | #define KM_BATTERY_LOW 0x01 107 | 108 | #define KM_PUSHASSIST_OFF 0x00 109 | #define KM_PUSHASSIST_ON 0x01 110 | 111 | #define KM_POWERASSIST_OFF 0x00 112 | #define KM_POWERASSIST_ON 0x01 113 | 114 | #define KM_THROTTLE_OFF 0x00 115 | #define KM_THROTTLE_ON 0x01 116 | 117 | #define KM_CRUISE_OFF 0x00 118 | #define KM_CRUISE_ON 0x01 119 | 120 | #define KM_OVERSPEED_NO 0x00 // Speed below limit 121 | #define KM_OVERSPEED_YES 0x01 // Overspeed detected 122 | 123 | 124 | typedef struct 125 | { 126 | // Parameters received from display in operation mode: 127 | uint8_t AssistLevel; // 0..255 Power Assist Level 128 | uint8_t Headlight; // KM_HEADLIGHT_OFF / KM_HEADLIGHT_ON / KM_HEADLIGHT_LOW / KM_HEADLIGHT_HIGH 129 | uint8_t Battery; // KM_BATTERY_NORMAL / KM_BATTERY_LOW 130 | uint8_t PushAssist; // KM_PUSHASSIST_OFF / KM_PUSHASSIST_ON 131 | uint8_t PowerAssist; // KM_POWERASSIST_OFF / KM_POWERASSIST_ON 132 | uint8_t Throttle; // KM_THROTTLE_OFF / KM_THROTTLE_ON 133 | uint8_t CruiseControl; // KM_CRUISE_OFF / KM_CRUISE_ON 134 | uint8_t OverSpeed; // KM_OVERSPEED_OFF / KM_OVERSPEED_ON 135 | uint16_t SPEEDMAX_Limit_x10; // Unit: 0.1km/h 136 | uint16_t CUR_Limit_x10; // Unit: 0.1A 137 | 138 | }RX_PARAM_t; 139 | 140 | 141 | 142 | #define KM_ERROR_NONE 0x00 143 | #define KM_ERROR_COMM 0x30 144 | 145 | typedef struct 146 | { 147 | // Parameters to be send to display in operation mode: 148 | uint8_t Battery; // KM_BATTERY_NORMAL / KM_BATTERY_LOW 149 | uint16_t Wheeltime_ms; // Unit:1ms 150 | uint8_t Error; // KM_ERROR_NONE, .. 151 | uint16_t Current_x10; // Unit: 0.1A 152 | 153 | }TX_PARAM_t; 154 | 155 | 156 | 157 | typedef struct 158 | { 159 | #if HARDWARE_REV < 20 160 | SoftwareSerial* SerialPort; 161 | #else 162 | HardwareSerial* SerialPort; 163 | #endif 164 | 165 | uint8_t RxState; 166 | uint32_t LastRx; 167 | 168 | uint8_t RxBuff[KM_MAX_RXBUFF]; 169 | uint8_t RxCnt; 170 | 171 | RX_SETTINGS_t Settings; 172 | RX_PARAM_t Rx; 173 | TX_PARAM_t Tx; 174 | 175 | }KINGMETER_t; 176 | 177 | 178 | 179 | 180 | // Public function prototypes 181 | #if HARDWARE_REV < 20 182 | void KingMeter_Init (KINGMETER_t* KM_ctx, SoftwareSerial* DisplaySerial); 183 | #else 184 | void KingMeter_Init (KINGMETER_t* KM_ctx, HardwareSerial* DisplaySerial); 185 | #endif 186 | 187 | void KingMeter_Service(KINGMETER_t* KM_ctx); 188 | 189 | 190 | #endif // KINGMETER_H 191 | #endif // (DISPLAY_TYPE & DISPLAY_TYPE_KINGMETER) 192 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/ds1307.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Code by JeeLabs http://news.jeelabs.org/code/ 3 | Released to the public domain! Enjoy! 4 | modified by Jens Kießling / jenkie 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software Foundation, 18 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include 22 | #include "ds1307.h" 23 | #include 24 | #define WIRE Wire 25 | #define DS1307_ADDRESS 0x68 26 | 27 | #if (ARDUINO >= 100) 28 | #include // capital A so it is error prone on case-sensitive filesystems 29 | #else 30 | #include 31 | #endif 32 | 33 | static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); } 34 | static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); } 35 | 36 | void RTC_DS1307::adjust_time(uint8_t hh, uint8_t mm, uint8_t ss) 37 | { 38 | WIRE.beginTransmission(DS1307_ADDRESS); 39 | WIRE.write((uint8_t)0); 40 | WIRE.write(bin2bcd(ss)); 41 | WIRE.write(bin2bcd(mm)); 42 | WIRE.write(bin2bcd(hh)); 43 | WIRE.endTransmission(); 44 | } 45 | 46 | Time RTC_DS1307::get_time() 47 | { 48 | WIRE.beginTransmission(DS1307_ADDRESS); 49 | WIRE.write((uint8_t)0); 50 | WIRE.endTransmission(); 51 | WIRE.requestFrom(DS1307_ADDRESS, 7); 52 | uint8_t ss = bcd2bin(WIRE.read() & 0x7F); 53 | uint8_t mm = bcd2bin(WIRE.read()); 54 | uint8_t hh = bcd2bin(WIRE.read()); 55 | return (Time) {hh,mm,ss}; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/ds1307.h: -------------------------------------------------------------------------------- 1 | /* 2 | Code by JeeLabs http://news.jeelabs.org/code/ 3 | Released to the public domain! Enjoy! 4 | modified by Jens Kießling / jenkie 5 | 6 | This program is free software; you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation; either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program; if not, write to the Free Software Foundation, 18 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _ds1307_H_ 22 | #define _ds1307_H_ 23 | 24 | struct Time 25 | { 26 | uint8_t hh; //hours 27 | uint8_t mm; //minutes 28 | uint8_t ss; //seconds 29 | }; 30 | 31 | class RTC_DS1307 32 | { 33 | public: 34 | static void adjust_time(uint8_t hh, uint8_t mm, uint8_t ss); 35 | Time get_time(void); 36 | }; 37 | 38 | 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/globals.h: -------------------------------------------------------------------------------- 1 | /* 2 | Global variables from the main program code end up here. 3 | (c) 2013 Thomas Jarosch / pedelecforum.de 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef GLOBALS_H 21 | #define GLOBALS_H 22 | 23 | #include "ds1307.h" 24 | 25 | // Global defines from the main program code 26 | extern float mah; 27 | extern boolean display_force_text; 28 | extern float voltage_display; 29 | extern float current_display; 30 | extern byte battery_percent_fromvoltage; 31 | extern byte battery_percent_fromcapacity; 32 | extern double power; 33 | extern double power_display; 34 | extern double power_set; 35 | extern float wh; 36 | extern double wh_human; 37 | extern unsigned int charge_count; 38 | extern volatile float spd; 39 | extern volatile int cad; 40 | extern volatile float km; 41 | extern float range; 42 | extern unsigned long odo; 43 | extern float temperature; 44 | extern float altitude; 45 | extern float altitude_start; 46 | extern float slope; 47 | extern int poti_stat; 48 | extern int throttle_stat; 49 | extern boolean brake_stat; 50 | extern volatile unsigned long wheel_time; 51 | extern byte pulse_human; 52 | extern double power_human; 53 | extern boolean variables_saved; 54 | 55 | extern const int bluetooth_pin; 56 | extern const int fet_out; 57 | extern const int lights_pin; 58 | 59 | extern int curr_startingaid_speed; 60 | extern int curr_spd_max1; 61 | extern int curr_spd_max2; 62 | extern int curr_power_max; 63 | extern int curr_power_poti_max; 64 | extern double curr_capacity; 65 | extern boolean current_profile; 66 | 67 | extern boolean first_aid_ignore_break; 68 | extern boolean first_aid_ignore_pas; 69 | extern boolean first_aid_ignore_speed; 70 | extern boolean first_aid_ignore_poti; 71 | extern boolean first_aid_ignore_throttle; 72 | extern boolean first_aid_ignore_temp_sensor; 73 | 74 | extern void save_eeprom(); 75 | extern void save_shutdown(); 76 | extern void activate_new_profile(); 77 | 78 | extern RTC_DS1307 rtc; 79 | extern Time now; 80 | 81 | void torque_rezero(); 82 | 83 | #ifdef SUPPORT_TEMP_SENSOR 84 | #include "DallasTemp.h" 85 | extern DallasTemperature sensors; 86 | #endif 87 | #ifdef SUPPORT_THERMISTOR 88 | extern float temperature_thermistor; 89 | #endif 90 | 91 | // Define own version of F() macro since compile will 92 | // fail on newer gcc versions with a "const" warning. 93 | // This is the version as in Arduino 1.5 and newer. 94 | #define MY_F(string_literal) (reinterpret_cast(PSTR(string_literal))) 95 | 96 | #define FROM_FLASH(str) (reinterpret_cast(str)) 97 | 98 | #if HARDWARE_REV <= 5 99 | #define FET_ON LOW 100 | #define FET_OFF HIGH 101 | #else 102 | #define FET_ON HIGH 103 | #define FET_OFF LOW 104 | #endif 105 | 106 | #endif 107 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/hrmi_funcs.cpp: -------------------------------------------------------------------------------- 1 | // HRMI-Breakout: http://www.sparkfun.com/products/8661 2 | // Code mainly taken from: http://bildr.org/2011/08/heartrate-arduino/ 3 | 4 | #include 5 | #include "hrmi_funcs.h" 6 | 7 | #define HRMI_I2C_ADDR 127 8 | 9 | // Forward declarations 10 | static void writeRegister(int deviceAddress, byte address, byte val); 11 | static boolean hrmiGetData(byte addr, byte numBytes, byte* dataArray); 12 | 13 | void hrmi_open() 14 | { 15 | Wire.begin(); 16 | writeRegister(HRMI_I2C_ADDR, 0x53, 1); // Configure the HRMI with the requested algorithm mode 17 | } 18 | 19 | int getHeartRate() 20 | { 21 | //get and return heart rate 22 | //returns 0 if we could not determine the heart rate 23 | byte i2cRspArray[3]; // I2C response array 24 | i2cRspArray[2] = 0; 25 | 26 | writeRegister(HRMI_I2C_ADDR, 0x47, 0x1); // Request a set of heart rate values 27 | 28 | if (hrmiGetData(127, 3, i2cRspArray)) 29 | { 30 | return i2cRspArray[2]; 31 | } 32 | else 33 | { 34 | return 0; 35 | } 36 | } 37 | 38 | static void writeRegister(int deviceAddress, byte address, byte val) 39 | { 40 | //I2C command to send data to a specific address on the device 41 | Wire.beginTransmission(deviceAddress); // start transmission to device 42 | Wire.write(address); // send register address 43 | Wire.write(val); // send value to write 44 | Wire.endTransmission(); // end transmission 45 | } 46 | 47 | static boolean hrmiGetData(byte addr, byte numBytes, byte* dataArray) 48 | { 49 | //Get data from heart rate monitor and fill dataArray byte with responce 50 | //Returns true if it was able to get it, false if not 51 | Wire.requestFrom(addr, numBytes); 52 | if (Wire.available()) 53 | { 54 | 55 | for (int i=0; i 9 | #else 10 | #include 11 | #endif 12 | 13 | void hrmi_open(); 14 | int getHeartRate(); 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/menu.h: -------------------------------------------------------------------------------- 1 | /* 2 | On the go menu system 3 | (c) 2013 Thomas Jarosch / pedelecforum.de 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #ifndef MENU_H 21 | #define MENU_H 22 | 23 | #include "Arduino.h" 24 | #include "MenuSystem.h" 25 | 26 | void init_menu(); 27 | 28 | extern unsigned long menu_activity_expire; // Timestamp when we kick the user ouf of the menu 29 | extern boolean menu_active; //Flag to indicate menu is shown or not 30 | extern boolean menu_changed; //Flag to indicate menu display needs update 31 | 32 | extern MenuSystem menu_system; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/one_Wire.h: -------------------------------------------------------------------------------- 1 | #ifndef OneWire_h 2 | #define OneWire_h 3 | 4 | #include 5 | 6 | #if ARDUINO >= 100 7 | #include "Arduino.h" // for delayMicroseconds, digitalPinToBitMask, etc 8 | #else 9 | #include "WProgram.h" // for delayMicroseconds 10 | #include "pins_arduino.h" // for digitalPinToBitMask, etc 11 | #endif 12 | 13 | // You can exclude certain features from OneWire. In theory, this 14 | // might save some space. In practice, the compiler automatically 15 | // removes unused code (technically, the linker, using -fdata-sections 16 | // and -ffunction-sections when compiling, and Wl,--gc-sections 17 | // when linking), so most of these will not result in any code size 18 | // reduction. Well, unless you try to use the missing features 19 | // and redesign your program to not need them! ONEWIRE_CRC8_TABLE 20 | // is the exception, because it selects a fast but large algorithm 21 | // or a small but slow algorithm. 22 | 23 | // you can exclude onewire_search by defining that to 0 24 | #ifndef ONEWIRE_SEARCH 25 | #define ONEWIRE_SEARCH 1 26 | #endif 27 | 28 | // You can exclude CRC checks altogether by defining this to 0 29 | #ifndef ONEWIRE_CRC 30 | #define ONEWIRE_CRC 1 31 | #endif 32 | 33 | // Select the table-lookup method of computing the 8-bit CRC 34 | // by setting this to 1. The lookup table enlarges code size by 35 | // about 250 bytes. It does NOT consume RAM (but did in very 36 | // old versions of OneWire). If you disable this, a slower 37 | // but very compact algorithm is used. 38 | #ifndef ONEWIRE_CRC8_TABLE 39 | #define ONEWIRE_CRC8_TABLE 1 40 | #endif 41 | 42 | // You can allow 16-bit CRC checks by defining this to 1 43 | // (Note that ONEWIRE_CRC must also be 1.) 44 | #ifndef ONEWIRE_CRC16 45 | #define ONEWIRE_CRC16 1 46 | #endif 47 | 48 | #define FALSE 0 49 | #define TRUE 1 50 | 51 | // Platform specific I/O definitions 52 | 53 | #if defined(__AVR__) 54 | #define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin))) 55 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 56 | #define IO_REG_TYPE uint8_t 57 | #define IO_REG_ASM asm("r30") 58 | #define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0) 59 | #define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask)) 60 | #define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask)) 61 | #define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask)) 62 | #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask)) 63 | 64 | #elif defined(__MK20DX128__) 65 | #define PIN_TO_BASEREG(pin) (portOutputRegister(pin)) 66 | #define PIN_TO_BITMASK(pin) (1) 67 | #define IO_REG_TYPE uint8_t 68 | #define IO_REG_ASM 69 | #define DIRECT_READ(base, mask) (*((base)+512)) 70 | #define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0) 71 | #define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1) 72 | #define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1) 73 | #define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1) 74 | 75 | #elif defined(__SAM3X8E__) 76 | // Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due. 77 | // http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268 78 | // If you have trouble with OneWire on Arduino Due, please check the 79 | // status of delayMicroseconds() before reporting a bug in OneWire! 80 | #define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER)) 81 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 82 | #define IO_REG_TYPE uint32_t 83 | #define IO_REG_ASM 84 | #define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0) 85 | #define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask)) 86 | #define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask)) 87 | #define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask)) 88 | #define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask)) 89 | #ifndef PROGMEM 90 | #define PROGMEM 91 | #endif 92 | #ifndef pgm_read_byte 93 | #define pgm_read_byte(addr) (*(const uint8_t *)(addr)) 94 | #endif 95 | 96 | #elif defined(__PIC32MX__) 97 | #define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin))) 98 | #define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin)) 99 | #define IO_REG_TYPE uint32_t 100 | #define IO_REG_ASM 101 | #define DIRECT_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) //PORTX + 0x10 102 | #define DIRECT_MODE_INPUT(base, mask) ((*(base+2)) = (mask)) //TRISXSET + 0x08 103 | #define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) = (mask)) //TRISXCLR + 0x04 104 | #define DIRECT_WRITE_LOW(base, mask) ((*(base+8+1)) = (mask)) //LATXCLR + 0x24 105 | #define DIRECT_WRITE_HIGH(base, mask) ((*(base+8+2)) = (mask)) //LATXSET + 0x28 106 | 107 | #else 108 | #error "Please define I/O register types here" 109 | #endif 110 | 111 | 112 | class OneWire 113 | { 114 | private: 115 | IO_REG_TYPE bitmask; 116 | volatile IO_REG_TYPE *baseReg; 117 | 118 | #if ONEWIRE_SEARCH 119 | // global search state 120 | unsigned char ROM_NO[8]; 121 | uint8_t LastDiscrepancy; 122 | uint8_t LastFamilyDiscrepancy; 123 | uint8_t LastDeviceFlag; 124 | #endif 125 | 126 | public: 127 | OneWire( uint8_t pin); 128 | 129 | // Perform a 1-Wire reset cycle. Returns 1 if a device responds 130 | // with a presence pulse. Returns 0 if there is no device or the 131 | // bus is shorted or otherwise held low for more than 250uS 132 | uint8_t reset(void); 133 | 134 | // Issue a 1-Wire rom select command, you do the reset first. 135 | void select(const uint8_t rom[8]); 136 | 137 | // Issue a 1-Wire rom skip command, to address all on bus. 138 | void skip(void); 139 | 140 | // Write a byte. If 'power' is one then the wire is held high at 141 | // the end for parasitically powered devices. You are responsible 142 | // for eventually depowering it by calling depower() or doing 143 | // another read or write. 144 | void write(uint8_t v, uint8_t power = 0); 145 | 146 | void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); 147 | 148 | // Read a byte. 149 | uint8_t read(void); 150 | 151 | void read_bytes(uint8_t *buf, uint16_t count); 152 | 153 | // Write a bit. The bus is always left powered at the end, see 154 | // note in write() about that. 155 | void write_bit(uint8_t v); 156 | 157 | // Read a bit. 158 | uint8_t read_bit(void); 159 | 160 | // Stop forcing power onto the bus. You only need to do this if 161 | // you used the 'power' flag to write() or used a write_bit() call 162 | // and aren't about to do another read or write. You would rather 163 | // not leave this powered if you don't have to, just in case 164 | // someone shorts your bus. 165 | void depower(void); 166 | 167 | #if ONEWIRE_SEARCH 168 | // Clear the search state so that if will start from the beginning again. 169 | void reset_search(); 170 | 171 | // Setup the search to find the device type 'family_code' on the next call 172 | // to search(*newAddr) if it is present. 173 | void target_search(uint8_t family_code); 174 | 175 | // Look for the next device. Returns 1 if a new address has been 176 | // returned. A zero might mean that the bus is shorted, there are 177 | // no devices, or you have already retrieved all of them. It 178 | // might be a good idea to check the CRC to make sure you didn't 179 | // get garbage. The order is deterministic. You will always get 180 | // the same devices in the same order. 181 | uint8_t search(uint8_t *newAddr); 182 | #endif 183 | 184 | #if ONEWIRE_CRC 185 | // Compute a Dallas Semiconductor 8 bit CRC, these are used in the 186 | // ROM and scratchpad registers. 187 | static uint8_t crc8(const uint8_t *addr, uint8_t len); 188 | 189 | #if ONEWIRE_CRC16 190 | // Compute the 1-Wire CRC16 and compare it against the received CRC. 191 | // Example usage (reading a DS2408): 192 | // // Put everything in a buffer so we can compute the CRC easily. 193 | // uint8_t buf[13]; 194 | // buf[0] = 0xF0; // Read PIO Registers 195 | // buf[1] = 0x88; // LSB address 196 | // buf[2] = 0x00; // MSB address 197 | // WriteBytes(net, buf, 3); // Write 3 cmd bytes 198 | // ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16 199 | // if (!CheckCRC16(buf, 11, &buf[11])) { 200 | // // Handle error. 201 | // } 202 | // 203 | // @param input - Array of bytes to checksum. 204 | // @param len - How many bytes to use. 205 | // @param inverted_crc - The two CRC16 bytes in the received data. 206 | // This should just point into the received data, 207 | // *not* at a 16-bit integer. 208 | // @param crc - The crc starting value (optional) 209 | // @return True, iff the CRC matches. 210 | static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0); 211 | 212 | // Compute a Dallas Semiconductor 16 bit CRC. This is required to check 213 | // the integrity of data received from many 1-Wire devices. Note that the 214 | // CRC computed here is *not* what you'll get from the 1-Wire network, 215 | // for two reasons: 216 | // 1) The CRC is transmitted bitwise inverted. 217 | // 2) Depending on the endian-ness of your processor, the binary 218 | // representation of the two-byte return value may have a different 219 | // byte order than the two bytes you get from 1-Wire. 220 | // @param input - Array of bytes to checksum. 221 | // @param len - How many bytes to use. 222 | // @param crc - The crc starting value (optional) 223 | // @return The CRC16, as defined by Dallas Semiconductor. 224 | static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0); 225 | #endif 226 | #endif 227 | }; 228 | 229 | #endif 230 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/serial_command.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Serial (bluetooth) communication functions 3 | Written by Jens Kießling and Thomas Jarosch 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #include "config.h" 21 | #include "serial_command.h" 22 | #include "globals.h" 23 | #include "switches.h" 24 | #ifdef SUPPORT_RTC 25 | #include "ds1307.h" 26 | #endif 27 | 28 | //a command is always AA# or AA? where AA# sets # to variable AA and AA? returns value of AA 29 | struct serial_command {char mnemonic[3];}; 30 | serial_command serial_commands[] = 31 | { 32 | {{"ps"}}, //0: poti stat, gets and sets poti stat 33 | {{"od"}}, //1: total kilometers (odo), gets and sets total kilometers 34 | {{"sp"}}, //2: short button press, send button between 0 and 3 35 | {{"lp"}}, //3: long button press, send button between 0 and 3 36 | {{"hh"}}, //4: set/get hours 37 | {{"mm"}}, //5: set/get minutes 38 | {{"ss"}}, //6: set/get seconds 39 | {{"cc"}}, //7: set/get charge count 40 | 41 | }; 42 | const byte n_commands = sizeof(serial_commands)/sizeof(serial_command); //number of commands that we have 43 | 44 | enum parse_states 45 | { 46 | Reset, 47 | SearchCommand, 48 | StoreNumber, 49 | ErrorWaitReturn, 50 | }; 51 | 52 | 53 | struct serial_struct 54 | { 55 | parse_states parse_state; 56 | char cmdbuf[2]; 57 | byte cmd_index; 58 | char numberstring[6]; 59 | byte number_pos; 60 | }; 61 | 62 | serial_struct serial_port1={Reset,{0},0,{0},0}; 63 | #if HARDWARE_REV>=20 64 | serial_struct serial_port2={Reset,{0},0,{0},0}; 65 | #endif 66 | 67 | serial_struct* active_serial = &serial_port1; 68 | HardwareSerial* active_serial_port = &Serial; 69 | 70 | /** 71 | * @brief Look for valid commands in command input buffer 72 | * Also sets "cmd_index". 73 | * 74 | * @return bool True if command found, false otherwise 75 | */ 76 | static bool find_commands() 77 | { 78 | for (byte i=0; i < n_commands; ++i) 79 | { 80 | if (serial_commands[i].mnemonic[0] == active_serial->cmdbuf[0] && serial_commands[i].mnemonic[1] == active_serial->cmdbuf[1]) 81 | { 82 | active_serial->cmd_index = i; 83 | return true; 84 | } 85 | } 86 | 87 | return false; 88 | } 89 | 90 | static void handle_command() 91 | { 92 | // sanity check 93 | if (active_serial->number_pos == 0 || active_serial->cmd_index == -1) 94 | { 95 | active_serial_port->println(MY_F("ERROR")); 96 | return; 97 | } 98 | 99 | active_serial_port->print(serial_commands[active_serial->cmd_index].mnemonic); 100 | // Info command? 101 | if (active_serial->numberstring[0] == '?') 102 | { 103 | switch(active_serial->cmd_index) 104 | { 105 | case 0: //poti_stat 106 | active_serial_port->println(poti_stat); 107 | break; 108 | case 1: //total kilometers 109 | active_serial_port->println(odo/1000.0*wheel_circumference,0); 110 | break; 111 | case 4: //hours read 112 | #ifdef SUPPORT_RTC 113 | active_serial_port->println(now.hh); 114 | #endif 115 | break; 116 | case 5: //minutes read 117 | #ifdef SUPPORT_RTC 118 | active_serial_port->println(now.mm); 119 | #endif 120 | break; 121 | case 6: //seconds read 122 | #ifdef SUPPORT_RTC 123 | active_serial_port->println(now.ss); 124 | #endif 125 | break; 126 | case 7: //charge count read 127 | #ifdef SUPPORT_BATTERY_CHARGE_COUNTER 128 | active_serial_port->println(charge_count); 129 | #endif 130 | break; 131 | } 132 | 133 | return; 134 | } 135 | 136 | // Write command? 137 | switch(active_serial->cmd_index) 138 | { 139 | case 0: //poti_stat 140 | poti_stat = min(atoi(active_serial->numberstring)*1023.0/power_poti_max,1023); 141 | break; 142 | case 1: //total kilometers 143 | odo = atoi(active_serial->numberstring)*1000.0/wheel_circumference; 144 | save_eeprom(); 145 | break; 146 | case 2: //short button press 147 | handle_switch(static_cast(atoi(active_serial->numberstring)), 0, PRESSED_SHORT); 148 | break; 149 | case 3: //long button press 150 | handle_switch(static_cast(atoi(active_serial->numberstring)), 0, PRESSED_LONG); 151 | break; 152 | case 4: //hours write 153 | #ifdef SUPPORT_RTC 154 | rtc.adjust_time(atoi(active_serial->numberstring),now.mm,now.ss); 155 | #endif 156 | break; 157 | case 5: //minutes write 158 | #ifdef SUPPORT_RTC 159 | rtc.adjust_time(now.hh,atoi(active_serial->numberstring),now.ss); 160 | #endif 161 | break; 162 | case 6: //seconds write 163 | #ifdef SUPPORT_RTC 164 | rtc.adjust_time(now.hh,now.mm,atoi(active_serial->numberstring)); 165 | #endif 166 | break; 167 | case 7: //charge count write 168 | #ifdef SUPPORT_BATTERY_CHARGE_COUNTER 169 | charge_count=atoi(active_serial->numberstring); 170 | save_eeprom(); 171 | #endif 172 | break; 173 | } 174 | active_serial_port->println(MY_F("OK")); 175 | } 176 | 177 | void parse_serial(const char &read_c, const byte port) 178 | { 179 | if (port==0) 180 | { 181 | active_serial=&serial_port1; 182 | active_serial_port=&Serial; 183 | } 184 | #if HARDWARE_REV>=20 185 | else 186 | { 187 | active_serial=&serial_port2; 188 | active_serial_port=&Serial1; 189 | } 190 | #endif 191 | byte i; 192 | 193 | switch(active_serial->parse_state) 194 | { 195 | case Reset: 196 | memset(active_serial->cmdbuf, 0, sizeof(active_serial->cmdbuf)); 197 | memset(active_serial->numberstring, 0, sizeof(active_serial->numberstring)); 198 | active_serial->cmd_index = -1; 199 | active_serial->number_pos = 0; 200 | 201 | active_serial->parse_state = SearchCommand; 202 | // fall through to "search command" 203 | 204 | case SearchCommand: 205 | // skip return chars 206 | if (read_c == 10 || read_c == 13) 207 | { 208 | active_serial->parse_state = Reset; 209 | break; 210 | } 211 | 212 | if (active_serial->cmdbuf[0] == 0) 213 | { 214 | // store first character 215 | active_serial->cmdbuf[0] = read_c; 216 | } 217 | else 218 | { 219 | active_serial->cmdbuf[1] = read_c; 220 | 221 | // Look for valid commands 222 | if (find_commands() == true) 223 | active_serial->parse_state = StoreNumber; 224 | else 225 | active_serial->parse_state = ErrorWaitReturn; 226 | } 227 | break; 228 | 229 | case StoreNumber: 230 | if (read_c == 10 || read_c == 13) 231 | { 232 | // User input is done 233 | handle_command(); 234 | active_serial->parse_state = Reset; 235 | } 236 | else 237 | { 238 | // Store character 239 | if (active_serial->number_pos < sizeof(active_serial->numberstring)-1) // reserve one byte for the terminating zero (atoi()) 240 | { 241 | active_serial->numberstring[active_serial->number_pos] = read_c; 242 | ++active_serial->number_pos; 243 | } 244 | } 245 | break; 246 | case ErrorWaitReturn: 247 | if (read_c == 10 || read_c == 13) 248 | { 249 | active_serial_port->println(MY_F("ERROR")); 250 | active_serial->parse_state = Reset; 251 | } 252 | break; 253 | } 254 | } 255 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/serial_command.h: -------------------------------------------------------------------------------- 1 | /* 2 | Serial (bluetooth) communication functions 3 | Written by Jens Kießling / jenkie 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | #ifndef SERIAL_COMMAND_H 20 | #define SERIAL_COMMAND_H 21 | 22 | #include "Arduino.h" 23 | 24 | void parse_serial(const char &read_c, const byte port); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/serial_lcd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Serial LCD function. Currently for New Haven display only. 3 | Written by Thomas Jarosch in 2014 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | 20 | #if ARDUINO < 100 21 | #include 22 | #else 23 | #include 24 | #endif 25 | 26 | #include "serial_lcd.h" 27 | 28 | #if (DISPLAY_TYPE & DISPLAY_TYPE_16X2_SERIAL) 29 | 30 | /** 31 | * @brief Constructor. No data is written to the display yet 32 | * 33 | * @param display_pin The pin the display is connected to 34 | */ 35 | SerialLCD::SerialLCD(const byte &display_pin, const byte &unused_pin) 36 | : SoftwareSerial(unused_pin, display_pin) 37 | , DisplayPin(display_pin) 38 | { 39 | } 40 | 41 | /** 42 | * @brief Initialize display. Clear screen, enable backlight etc. 43 | * 44 | */ 45 | void SerialLCD::init() 46 | { 47 | pinMode(DisplayPin, OUTPUT); 48 | begin(9600); 49 | 50 | // Controller on the display needs 100ms init time 51 | delay(100); 52 | 53 | // Clear screen 54 | clear(); 55 | 56 | // Set contrast 57 | setContrast(50); 58 | 59 | // Enable display 60 | display(true); 61 | } 62 | 63 | /** 64 | * @brief Clear screen and move cursor home 65 | * 66 | */ 67 | void SerialLCD::clear() 68 | { 69 | write(0xFE); 70 | write(0x51); 71 | 72 | // As clear() also clears the receive buffer 73 | // and takes 1.5ms to execute, we wait for 2 millis 74 | delay(2); 75 | } 76 | 77 | /** 78 | * @brief Move cursor home to (0,0) 79 | * 80 | */ 81 | void SerialLCD::home() 82 | { 83 | write(0xFE); 84 | write(0x46); 85 | } 86 | 87 | /** 88 | * @brief Set display contrast 89 | * 90 | * @param contrast Value between 1 and 50 91 | */ 92 | void SerialLCD::setContrast(const byte &contrast) 93 | { 94 | write(0xFE); 95 | write(0x52); 96 | write(contrast); 97 | } 98 | 99 | /** 100 | * @brief Set backlight brightness 101 | * 102 | * @param brightness Backlight brightness. Value between 1 and 8. '1' is off. 103 | */ 104 | void SerialLCD::setBacklight(const byte& brightness) 105 | { 106 | write(0xFE); 107 | write(0x53); 108 | write(brightness); 109 | } 110 | 111 | /** 112 | * @brief Set cursor x/y position. Use an out-of-screen position to hide the cursor 113 | * 114 | * @param x Horizontal position, starting at 0 115 | * @param y Line, starting at 0 116 | */ 117 | void SerialLCD::setCursor(const byte& x, const byte& y) 118 | { 119 | write(0xFE); 120 | write(0x45); 121 | write(y * 0x40 + x); 122 | } 123 | 124 | void SerialLCD::noDisplay(const bool &disable_backlight) 125 | { 126 | write(0xFE); 127 | write(0x42); 128 | 129 | if (disable_backlight) 130 | setBacklight(1); 131 | } 132 | 133 | void SerialLCD::display(const bool &enable_backlight) 134 | { 135 | write(0xFE); 136 | write(0x41); 137 | 138 | if (enable_backlight) 139 | setBacklight(8); 140 | } 141 | 142 | /** 143 | * @brief Load custom character 144 | * Custom characters can be printed via ASCII code 0 to 8 145 | * 146 | * @param address Character value to store this. Valid values are 0 to 8 147 | * @param data Character bitmap data. A character is 5x8 pixels. 148 | */ 149 | void SerialLCD::createChar(byte address, const byte data[]) 150 | { 151 | address = address & 0x7; 152 | 153 | write(0xFE); 154 | write(0x54); 155 | write(address); 156 | 157 | for (byte i = 0; i < 8; ++i) 158 | write(data[i]); 159 | } 160 | 161 | #endif 162 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/serial_lcd.h: -------------------------------------------------------------------------------- 1 | /* 2 | Serial LCD function. Currently for New Haven display only. 3 | Written by Thomas Jarosch in 2014 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | #ifndef SERIAL_LCD_H 20 | #define SERIAL_LCD_H 21 | 22 | #if ARDUINO < 100 23 | #include 24 | #else 25 | #include 26 | #endif 27 | 28 | #include "config.h" 29 | 30 | #if (DISPLAY_TYPE & DISPLAY_TYPE_16X2_SERIAL) 31 | 32 | #include 33 | 34 | class SerialLCD : public SoftwareSerial 35 | { 36 | public: 37 | SerialLCD(const byte &display_pin=10, const byte &unused_pin=11); 38 | 39 | void init(); 40 | void clear(); 41 | 42 | void home(); 43 | void setCursor(const byte &x, const byte &y); 44 | 45 | void setContrast(const byte &contrast); 46 | void setBacklight(const byte &brightness); 47 | 48 | void display(const bool &enable_backlight=true); 49 | void noDisplay(const bool &disable_backlight=true); 50 | 51 | void createChar(byte address, const byte data[]); 52 | 53 | private: 54 | byte DisplayPin; 55 | }; 56 | 57 | #endif //eo DISPLAY_TYPE_16X2_SERIAL 58 | #endif 59 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/switches.h: -------------------------------------------------------------------------------- 1 | /* 2 | Switch handling functions: short and long press detection 3 | (c) 2012-2013 jenkie and Thomas Jarosch / pedelecforum.de 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | #ifndef SWITCHES_H 20 | #define SWITCHES_H 21 | 22 | #include "Arduino.h" 23 | #include "config.h" 24 | 25 | enum switch_result { PRESSED_NONE=0, PRESSED_SHORT=1, PRESSED_LONG=2 }; 26 | 27 | void init_switches(); 28 | void handle_switch(const switch_name sw_name, boolean sw_state, const switch_result &force_press=PRESSED_NONE); 29 | 30 | void action_increase_poti(); 31 | void action_decrease_poti(); 32 | void action_set_soft_poti(int new_throttle_stat); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /Arduino_Pedelec_Controller/switches_action.h: -------------------------------------------------------------------------------- 1 | /* 2 | Switch actions for use in config.h 3 | (c) Thomas Jarosch / pedelecforum.de 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 | */ 19 | #ifndef SWITCHES_ACTION_H 20 | #define SWITCHES_ACTION_H 21 | 22 | // Switch names 23 | enum switch_name { SWITCH_THROTTLE=0, 24 | SWITCH_DISPLAY1=1, 25 | SWITCH_DISPLAY2=2, 26 | SWITCH_POTI=3, 27 | _SWITCHES_COUNT=4 28 | }; 29 | 30 | // Switch actions: Customizable actions for short and long press. See config.h 31 | enum sw_action { ACTION_NONE=0, // do nothing 32 | ACTION_SET_SOFT_POTI, // set soft poti 33 | ACTION_SHUTDOWN_SYSTEM, // power down system 34 | ACTION_ENABLE_BACKLIGHT_LONG, // enable backlight for 60s 35 | ACTION_TOGGLE_BLUETOOTH, // switch bluetooth on/off 36 | ACTION_ENTER_MENU, // enter on-the-go settings menu 37 | ACTION_PROFILE_1, // switch to profile 1 38 | ACTION_PROFILE_2, // switch to profile 2 39 | ACTION_PROFILE, // switch profiles 1 <-> 2 40 | ACTION_TOGGLE_LIGHTS, // toggle lights on/off. Needs hardware revision 1.4 or newer 41 | ACTION_INCREASE_POTI, // increase poti value. Only working when SUPPORT_POTI is disabled 42 | ACTION_DECREASE_POTI, // decrease poti value. Only working when SUPPORT_POTI is disabled 43 | ACTION_SET_FIXED_POTI_VALUE, // (re-)set soft poti to a fixed value in watts 44 | ACTION_FIXED_THROTTLE_VALUE, // set a fixed throttle value while switch is hold down (=emulate starting aid) 45 | ACTION_DISPLAY_PREV_VIEW, // go to prev view in display. Rools over if at the beginning 46 | ACTION_DISPLAY_NEXT_VIEW, // go the new view in display. Rolls over if at the end 47 | ACTION_GEAR_SHIFT_LOW, // gear shift: shift to low gear 48 | ACTION_GEAR_SHIFT_HIGH, // gear shift: shift to high gear 49 | ACTION_GEAR_SHIFT_AUTO, // gear shift: shift motor controller to "auto" mode 50 | ACTION_GEAR_SHIFT_TOGGLE_LOW_HIGH, // gear shift: toggle between low and high 51 | ACTION_GEAR_SHIFT_TOGGLE_LOW_HIGH_AUTO, // gear shift: toggle between low, high and auto 52 | ACTION_TORQUE_ZERO // Re-zero torque sensor 53 | }; 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /Bluetooth_Setup/Bluetooth_Setup.ino: -------------------------------------------------------------------------------- 1 | /* 2 | This program configures the bluetooth module with custom name and pin for 3 | use with the Arduino Pedelec Controller 4 | 5 | 1st step: Connect Bluetooth module to Arduino Pedelec Controller 6 | 2nd step: Wait 1 minute after uploading the program (bluetooth module should 7 | shut down and repower during this time), then you are ready. 8 | 9 | Written by Jens Kießling (jenkie) 10 | 11 | This program is free software; you can redistribute it and/or modify 12 | it under the terms of the GNU General Public License as published by 13 | the Free Software Foundation; either version 3 of the License, or 14 | (at your option) any later version. 15 | 16 | This program is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with this program; if not, write to the Free Software Foundation, 23 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 24 | */ 25 | 26 | 27 | #define HARDWARE_REV 21 //place your hardware revision here: 1-5 means hardware-revision 1.x, 2x means 2.x 28 | int SerialSpeed=9600; //set the current speed of your bluetooth module here, usually 9600 29 | 30 | #if HARDWARE_REV<20 31 | HardwareSerial btSerial=Serial; 32 | int btPin=7; 33 | #else 34 | HardwareSerial btSerial=Serial1; 35 | int btPin=13; 36 | #endif 37 | 38 | void setup() 39 | { 40 | #if HARDWARE_REV>=20 41 | pinMode(38,OUTPUT); 42 | digitalWrite(38, 1); // turn on whole system on 43 | delay(5000); 44 | #endif 45 | btSerial.begin(SerialSpeed); 46 | delay(1000); 47 | pinMode(btPin, OUTPUT); 48 | digitalWrite(btPin,HIGH); 49 | delay(5000); 50 | btSerial.print("AT"); 51 | delay(1000); 52 | btSerial.print("AT+VERSION?"); 53 | delay(1000); 54 | btSerial.print("AT+ORGL"); 55 | delay(1000); 56 | btSerial.print("AT+RMAAD"); 57 | delay(1000); 58 | btSerial.print("AT+ROLE=0"); 59 | delay(1000); 60 | btSerial.print("AT+PSWD=1234"); // Set pin to 1234 or anything of your choice 61 | delay(5000); 62 | btSerial.print("AT+NAMEArduinoPedelec"); //use your own name if you want 63 | delay(5000); 64 | btSerial.print("AT+BAUD8"); // Set baudrate to 115200, do not change 65 | delay(5000); 66 | digitalWrite(btPin,LOW); 67 | delay(10000); 68 | digitalWrite(btPin,HIGH); 69 | #if HARDWARE_REV>=20 70 | digitalWrite(38, 0); // turn on whole system off 71 | #endif 72 | 73 | } 74 | 75 | void loop() 76 | { 77 | 78 | } 79 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #=============================================================================# 2 | # Author: Thomas Jarosch # 3 | # Date: 24.04.2012 # 4 | # # 5 | # Description: Pedelec controller cmake project # 6 | # # 7 | #=============================================================================# 8 | set(CMAKE_TOOLCHAIN_FILE cmake/Arduino-toolchain.cmake) # Arduino Toolchain 9 | 10 | # "grep" for FC 2.0 hardware in config.h 11 | # Do this before project() since it invokes toolchain detection 12 | file(STRINGS Arduino_Pedelec_Controller/config.h config_h_lines REGEX "^#define HARDWARE_REV 2[0-9]") 13 | if (config_h_lines) 14 | message("Building firmware for FC 2.0 or higher") 15 | set(ARDUINO_BOARD "Arduino Mega or Mega 2560 [avr.mega]") 16 | set(ARDUINO_AVR_MEGA_MENU_CPU_ATMEGA2560 TRUE) 17 | else(config_h_lines) 18 | set(ARDUINO_BOARD "Arduino Nano [avr.nano]") 19 | 20 | option(OLD_BOOTLOADER "Arduino Nano uses old bootloader (57600 baud)" OFF) 21 | if (OLD_BOOTLOADER) 22 | set(ARDUINO_AVR_NANO_MENU_CPU_ATMEGA328OLD TRUE) 23 | else (OLD_BOOTLOADER) 24 | set(ARDUINO_AVR_NANO_MENU_CPU_ATMEGA328 TRUE) 25 | endif (OLD_BOOTLOADER) 26 | endif(config_h_lines) 27 | set(ARDUINO_PROGRAMMER "Arduino as ISP [avr.arduinoasisp]") 28 | 29 | cmake_minimum_required(VERSION 3.7.0) 30 | project(Pedelec_Controller C CXX) 31 | 32 | # Documentation 33 | option(DOCUMENTATION "Generate API documentation with Doxygen" OFF) 34 | 35 | find_package(Doxygen) 36 | if(DOCUMENTATION AND DOXYGEN_FOUND) 37 | 38 | # Set variables 39 | set(top_srcdir ${CMAKE_SOURCE_DIR}) 40 | 41 | # Find doxy config 42 | message(STATUS "Doxygen found.") 43 | set(DOXY_DIR "${CMAKE_SOURCE_DIR}/docs") 44 | set(DOXY_CONFIG "${DOXY_DIR}/Doxyfile.in") 45 | 46 | # Copy doxy.config.in 47 | configure_file("${DOXY_CONFIG}" "${CMAKE_BINARY_DIR}/doxy.config") 48 | 49 | # Create doc directory 50 | add_custom_command( 51 | OUTPUT ${CMAKE_BINARY_DIR}/doc 52 | COMMAND rm -rf ${CMAKE_BINARY_DIR}/doc/{html,man} 53 | COMMAND mkdir -p ${CMAKE_BINARY_DIR}/doc 54 | DEPENDS pcontroller 55 | ) 56 | 57 | # Run doxygen 58 | add_custom_command( 59 | OUTPUT ${CMAKE_BINARY_DIR}/doc/html/index.html 60 | COMMAND ${DOXYGEN_EXECUTABLE} "${CMAKE_BINARY_DIR}/doxy.config" 61 | DEPENDS "${CMAKE_BINARY_DIR}/doxy.config" "${CMAKE_BINARY_DIR}/doc" 62 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/doc 63 | ) 64 | 65 | add_custom_target(docs ALL DEPENDS ${CMAKE_BINARY_DIR}/doc/html/index.html) 66 | 67 | message(STATUS "Generating API documentation with Doxygen") 68 | else(DOCUMENTATION AND DOXYGEN_FOUND) 69 | message(STATUS "Not generating API documentation") 70 | endif(DOCUMENTATION AND DOXYGEN_FOUND) 71 | 72 | add_subdirectory(Arduino_Pedelec_Controller) 73 | add_subdirectory(Hardware_Test) 74 | -------------------------------------------------------------------------------- /Hardware_Test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #=============================================================================# 2 | # Author: Thomas Jarosch # 3 | # Date: 24.04.2012 # 4 | # # 5 | # Description: Pedelec controller cmake project # 6 | # # 7 | #=============================================================================# 8 | include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR} 9 | ${CMAKE_SOURCE_DIR}/Hardware_Test) 10 | 11 | configure_file(Hardware_Test.ino testprogram.cpp COPYONLY) 12 | 13 | # Hardware test program 14 | set(TESTPROGRAM_NAME testprogram) 15 | 16 | add_executable(${TESTPROGRAM_NAME} 17 | ${CMAKE_CURRENT_BINARY_DIR}/testprogram.cpp 18 | PCD8544_charset.cpp 19 | PCD8544_nano.cpp 20 | ) 21 | target_link_arduino_libraries(${TESTPROGRAM_NAME} PRIVATE EEPROM core) 22 | 23 | # Upload support: Usage: 24 | # make upload-testprogram SERIAL_PORT=/dev/ttyUSB0 25 | target_enable_arduino_upload(${TESTPROGRAM_NAME}) 26 | -------------------------------------------------------------------------------- /Hardware_Test/EEPROMAnything.h: -------------------------------------------------------------------------------- 1 | //EEPROMAnything is taken from here: http://www.arduino.cc/playground/Code/EEPROMWriteAnything 2 | 3 | #include "EEPROM.h" 4 | #if ARDUINO < 100 5 | #include 6 | #else 7 | #include 8 | #endif 9 | 10 | template int EEPROM_writeAnything(int ee, const T& value) 11 | { 12 | const byte* p = (const byte*)(const void*)&value; 13 | int i; 14 | for (i = 0; i < sizeof(value); i++) 15 | EEPROM.write(ee++, *p++); 16 | return i; 17 | } 18 | 19 | template int EEPROM_readAnything(int ee, T& value) 20 | { 21 | byte* p = (byte*)(void*)&value; 22 | int i; 23 | for (i = 0; i < sizeof(value); i++) 24 | *p++ = EEPROM.read(ee++); 25 | return i; 26 | } 27 | -------------------------------------------------------------------------------- /Hardware_Test/LiquidCrystalDogm.h: -------------------------------------------------------------------------------- 1 | #ifndef LiquidCrystal_h 2 | #define LiquidCrystal_h 3 | 4 | #include 5 | #include "Print.h" 6 | 7 | // commands 8 | #define LCD_CLEARDISPLAY 0x01 9 | #define LCD_RETURNHOME 0x02 10 | #define LCD_ENTRYMODESET 0x04 11 | #define LCD_DISPLAYCONTROL 0x08 12 | #define LCD_CURSORSHIFT 0x10 13 | #define LCD_FUNCTIONSET 0x29 14 | #define LCD_SETCGRAMADDR 0x40 15 | #define LCD_SETDDRAMADDR 0x80 16 | 17 | // flags for display entry mode 18 | #define LCD_ENTRYRIGHT 0x00 19 | #define LCD_ENTRYLEFT 0x02 20 | #define LCD_ENTRYSHIFTINCREMENT 0x01 21 | #define LCD_ENTRYSHIFTDECREMENT 0x00 22 | 23 | // flags for display on/off control 24 | #define LCD_DISPLAYON 0x04 25 | #define LCD_DISPLAYOFF 0x00 26 | #define LCD_CURSORON 0x02 27 | #define LCD_CURSOROFF 0x00 28 | #define LCD_BLINKON 0x01 29 | #define LCD_BLINKOFF 0x00 30 | 31 | // flags for display/cursor shift 32 | #define LCD_DISPLAYMOVE 0x08 33 | #define LCD_CURSORMOVE 0x00 34 | #define LCD_MOVERIGHT 0x04 35 | #define LCD_MOVELEFT 0x00 36 | 37 | // flags for function set 38 | #define LCD_8BITMODE 0x10 39 | #define LCD_4BITMODE 0x00 40 | #define LCD_2LINE 0x08 41 | #define LCD_1LINE 0x00 42 | #define LCD_5x10DOTS 0x04 43 | #define LCD_5x8DOTS 0x00 44 | 45 | class LiquidCrystal : public Print 46 | { 47 | public: 48 | LiquidCrystal(uint8_t rs, uint8_t enable, 49 | uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 50 | uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); 51 | LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 52 | uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 53 | uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); 54 | LiquidCrystal(uint8_t rs, uint8_t rw, uint8_t enable, 55 | uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); 56 | LiquidCrystal(uint8_t rs, uint8_t enable, 57 | uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3); 58 | 59 | void init(uint8_t fourbitmode, uint8_t rs, uint8_t rw, uint8_t enable, 60 | uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, 61 | uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7); 62 | 63 | void begin(uint8_t cols, uint8_t rows, uint8_t charsize = LCD_5x8DOTS); 64 | 65 | void clear(); 66 | void home(); 67 | 68 | void noDisplay(); 69 | void display(); 70 | void noBlink(); 71 | void blink(); 72 | void noCursor(); 73 | void cursor(); 74 | void scrollDisplayLeft(); 75 | void scrollDisplayRight(); 76 | void leftToRight(); 77 | void rightToLeft(); 78 | void autoscroll(); 79 | void noAutoscroll(); 80 | 81 | void createChar(uint8_t, const uint8_t[]); 82 | void setCursor(uint8_t, uint8_t); 83 | virtual size_t write(uint8_t); 84 | void command(uint8_t); 85 | 86 | using Print::write; 87 | private: 88 | void send(uint8_t, uint8_t); 89 | void write4bits(uint8_t); 90 | void write8bits(uint8_t); 91 | void pulseEnable(); 92 | 93 | uint8_t _rs_pin; // LOW: command. HIGH: character. 94 | uint8_t _rw_pin; // LOW: write to LCD. HIGH: read from LCD. 95 | uint8_t _enable_pin; // activated by a HIGH pulse. 96 | uint8_t _data_pins[8]; 97 | 98 | uint8_t _displayfunction; 99 | uint8_t _displaycontrol; 100 | uint8_t _displaymode; 101 | 102 | uint8_t _initialized; 103 | 104 | uint8_t _numlines,_currline; 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /Hardware_Test/PCD8544_charset.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * PCD8544 - Interface with Philips PCD8544 (or compatible) LCDs. 3 | * 4 | * Copyright (c) 2010 Carlos Rodrigues 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | #include 27 | 28 | 29 | // The 7-bit ASCII character set... 30 | const PROGMEM unsigned char charset[][5] = 31 | { 32 | { 0x00, 0x00, 0x00, 0x00, 0x00 }, // 20 space 33 | { 0x00, 0x00, 0x5f, 0x00, 0x00 }, // 21 ! 34 | { 0x00, 0x07, 0x00, 0x07, 0x00 }, // 22 " 35 | { 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // 23 # 36 | { 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // 24 $ 37 | { 0x23, 0x13, 0x08, 0x64, 0x62 }, // 25 % 38 | { 0x36, 0x49, 0x55, 0x22, 0x50 }, // 26 & 39 | { 0x00, 0x05, 0x03, 0x00, 0x00 }, // 27 ' 40 | { 0x00, 0x1c, 0x22, 0x41, 0x00 }, // 28 ( 41 | { 0x00, 0x41, 0x22, 0x1c, 0x00 }, // 29 ) 42 | { 0x14, 0x08, 0x3e, 0x08, 0x14 }, // 2a * 43 | { 0x08, 0x08, 0x3e, 0x08, 0x08 }, // 2b + 44 | { 0x00, 0x50, 0x30, 0x00, 0x00 }, // 2c , 45 | { 0x08, 0x08, 0x08, 0x08, 0x08 }, // 2d - 46 | { 0x00, 0x60, 0x60, 0x00, 0x00 }, // 2e . 47 | { 0x20, 0x10, 0x08, 0x04, 0x02 }, // 2f / 48 | { 0x3e, 0x51, 0x49, 0x45, 0x3e }, // 30 0 49 | { 0x00, 0x42, 0x7f, 0x40, 0x00 }, // 31 1 50 | { 0x42, 0x61, 0x51, 0x49, 0x46 }, // 32 2 51 | { 0x21, 0x41, 0x45, 0x4b, 0x31 }, // 33 3 52 | { 0x18, 0x14, 0x12, 0x7f, 0x10 }, // 34 4 53 | { 0x27, 0x45, 0x45, 0x45, 0x39 }, // 35 5 54 | { 0x3c, 0x4a, 0x49, 0x49, 0x30 }, // 36 6 55 | { 0x01, 0x71, 0x09, 0x05, 0x03 }, // 37 7 56 | { 0x36, 0x49, 0x49, 0x49, 0x36 }, // 38 8 57 | { 0x06, 0x49, 0x49, 0x29, 0x1e }, // 39 9 58 | { 0x00, 0x36, 0x36, 0x00, 0x00 }, // 3a : 59 | { 0x00, 0x56, 0x36, 0x00, 0x00 }, // 3b ; 60 | { 0x08, 0x14, 0x22, 0x41, 0x00 }, // 3c < 61 | { 0x14, 0x14, 0x14, 0x14, 0x14 }, // 3d = 62 | { 0x00, 0x41, 0x22, 0x14, 0x08 }, // 3e > 63 | { 0x02, 0x01, 0x51, 0x09, 0x06 }, // 3f ? 64 | { 0x32, 0x49, 0x79, 0x41, 0x3e }, // 40 @ 65 | { 0x7e, 0x11, 0x11, 0x11, 0x7e }, // 41 A 66 | { 0x7f, 0x49, 0x49, 0x49, 0x36 }, // 42 B 67 | { 0x3e, 0x41, 0x41, 0x41, 0x22 }, // 43 C 68 | { 0x7f, 0x41, 0x41, 0x22, 0x1c }, // 44 D 69 | { 0x7f, 0x49, 0x49, 0x49, 0x41 }, // 45 E 70 | { 0x7f, 0x09, 0x09, 0x09, 0x01 }, // 46 F 71 | { 0x3e, 0x41, 0x49, 0x49, 0x7a }, // 47 G 72 | { 0x7f, 0x08, 0x08, 0x08, 0x7f }, // 48 H 73 | { 0x00, 0x41, 0x7f, 0x41, 0x00 }, // 49 I 74 | { 0x20, 0x40, 0x41, 0x3f, 0x01 }, // 4a J 75 | { 0x7f, 0x08, 0x14, 0x22, 0x41 }, // 4b K 76 | { 0x7f, 0x40, 0x40, 0x40, 0x40 }, // 4c L 77 | { 0x7f, 0x02, 0x0c, 0x02, 0x7f }, // 4d M 78 | { 0x7f, 0x04, 0x08, 0x10, 0x7f }, // 4e N 79 | { 0x3e, 0x41, 0x41, 0x41, 0x3e }, // 4f O 80 | { 0x7f, 0x09, 0x09, 0x09, 0x06 }, // 50 P 81 | { 0x3e, 0x41, 0x51, 0x21, 0x5e }, // 51 Q 82 | { 0x7f, 0x09, 0x19, 0x29, 0x46 }, // 52 R 83 | { 0x46, 0x49, 0x49, 0x49, 0x31 }, // 53 S 84 | { 0x01, 0x01, 0x7f, 0x01, 0x01 }, // 54 T 85 | { 0x3f, 0x40, 0x40, 0x40, 0x3f }, // 55 U 86 | { 0x1f, 0x20, 0x40, 0x20, 0x1f }, // 56 V 87 | { 0x3f, 0x40, 0x38, 0x40, 0x3f }, // 57 W 88 | { 0x63, 0x14, 0x08, 0x14, 0x63 }, // 58 X 89 | { 0x07, 0x08, 0x70, 0x08, 0x07 }, // 59 Y 90 | { 0x61, 0x51, 0x49, 0x45, 0x43 }, // 5a Z 91 | { 0x00, 0x7f, 0x41, 0x41, 0x00 }, // 5b [ 92 | { 0x02, 0x04, 0x08, 0x10, 0x20 }, // 5c backslash 93 | { 0x00, 0x41, 0x41, 0x7f, 0x00 }, // 5d ] 94 | { 0x04, 0x02, 0x01, 0x02, 0x04 }, // 5e ^ 95 | { 0x40, 0x40, 0x40, 0x40, 0x40 }, // 5f _ 96 | { 0x00, 0x01, 0x02, 0x04, 0x00 }, // 60 ` 97 | { 0x20, 0x54, 0x54, 0x54, 0x78 }, // 61 a 98 | { 0x7f, 0x48, 0x44, 0x44, 0x38 }, // 62 b 99 | { 0x38, 0x44, 0x44, 0x44, 0x20 }, // 63 c 100 | { 0x38, 0x44, 0x44, 0x48, 0x7f }, // 64 d 101 | { 0x38, 0x54, 0x54, 0x54, 0x18 }, // 65 e 102 | { 0x08, 0x7e, 0x09, 0x01, 0x02 }, // 66 f 103 | { 0x0c, 0x52, 0x52, 0x52, 0x3e }, // 67 g 104 | { 0x7f, 0x08, 0x04, 0x04, 0x78 }, // 68 h 105 | { 0x00, 0x44, 0x7d, 0x40, 0x00 }, // 69 i 106 | { 0x20, 0x40, 0x44, 0x3d, 0x00 }, // 6a j 107 | { 0x7f, 0x10, 0x28, 0x44, 0x00 }, // 6b k 108 | { 0x00, 0x41, 0x7f, 0x40, 0x00 }, // 6c l 109 | { 0x7c, 0x04, 0x18, 0x04, 0x78 }, // 6d m 110 | { 0x7c, 0x08, 0x04, 0x04, 0x78 }, // 6e n 111 | { 0x38, 0x44, 0x44, 0x44, 0x38 }, // 6f o 112 | { 0x7c, 0x14, 0x14, 0x14, 0x08 }, // 70 p 113 | { 0x08, 0x14, 0x14, 0x18, 0x7c }, // 71 q 114 | { 0x7c, 0x08, 0x04, 0x04, 0x08 }, // 72 r 115 | { 0x48, 0x54, 0x54, 0x54, 0x20 }, // 73 s 116 | { 0x04, 0x3f, 0x44, 0x40, 0x20 }, // 74 t 117 | { 0x3c, 0x40, 0x40, 0x20, 0x7c }, // 75 u 118 | { 0x1c, 0x20, 0x40, 0x20, 0x1c }, // 76 v 119 | { 0x3c, 0x40, 0x30, 0x40, 0x3c }, // 77 w 120 | { 0x44, 0x28, 0x10, 0x28, 0x44 }, // 78 x 121 | { 0x0c, 0x50, 0x50, 0x50, 0x3c }, // 79 y 122 | { 0x44, 0x64, 0x54, 0x4c, 0x44 }, // 7a z 123 | { 0x00, 0x08, 0x36, 0x41, 0x00 }, // 7b { 124 | { 0x00, 0x00, 0x7f, 0x00, 0x00 }, // 7c | 125 | { 0x00, 0x41, 0x36, 0x08, 0x00 }, // 7d } 126 | { 0x10, 0x08, 0x08, 0x10, 0x08 }, // 7e ~ 127 | { 0x00, 0x00, 0x00, 0x00, 0x00 } // 7f 128 | }; 129 | 130 | 131 | /* vim: set expandtab ts=4 sw=4: */ 132 | -------------------------------------------------------------------------------- /Hardware_Test/PCD8544_nano.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PCD8544 - Interface with Philips PCD8544 (or compatible) LCDs. 3 | * 4 | * Copyright (c) 2010 Carlos Rodrigues 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | 26 | #ifndef PCD8544_H 27 | #define PCD8544_H 28 | 29 | 30 | #if ARDUINO < 100 31 | #include 32 | #else 33 | #include 34 | #endif 35 | 36 | 37 | // Chip variants supported... 38 | #define CHIP_PCD8544 0 39 | #define CHIP_ST7576 1 40 | 41 | 42 | class PCD8544: public Print 43 | { 44 | public: 45 | // All the pins can be changed from the default values... 46 | PCD8544(unsigned char sclk = 9, /* clock (display pin 2) */ 47 | unsigned char sdin = 10, /* data-in (display pin 3) */ 48 | unsigned char dc = 11, /* data select (display pin 4) */ 49 | unsigned char reset = 12, /* reset (display pin 8) */ 50 | unsigned char sce = 13); /* enable (display pin 5) */ 51 | 52 | // Display initialization (dimensions in pixels)... 53 | void begin(unsigned char width=84, unsigned char height=48, unsigned char model=CHIP_PCD8544); 54 | void stop(); 55 | 56 | // Erase everything on the display... 57 | void clear(); 58 | void clearLine(); // ...or just the current line 59 | 60 | // Control the display's power state... 61 | void setPower(bool on); 62 | 63 | // For compatibility with the LiquidCrystal library... 64 | void display(); 65 | void noDisplay(); 66 | 67 | // Activate white-on-black mode (whole display)... 68 | void setInverse(bool inverse); 69 | 70 | // Place the cursor at the start of the current line... 71 | void home(); 72 | 73 | // Place the cursor at position (column, line)... 74 | void setCursor(unsigned char column, unsigned char line); 75 | 76 | // Assign a user-defined glyph (5x8) to an ASCII character (0-31)... 77 | void createChar(unsigned char chr, const unsigned char *glyph); 78 | 79 | // Write an ASCII character at the current cursor position (7-bit)... 80 | #if ARDUINO < 100 81 | virtual void write(uint8_t chr); 82 | #else 83 | virtual size_t write(uint8_t chr); 84 | #endif 85 | 86 | // Draw a bitmap at the current cursor position... 87 | void drawBitmap(const unsigned char *data, unsigned char columns, unsigned char lines); 88 | 89 | // Draw a chart element at the current cursor position... 90 | void drawColumn(unsigned char lines, unsigned char value); 91 | 92 | private: 93 | unsigned char pin_sclk; 94 | unsigned char pin_sdin; 95 | unsigned char pin_dc; 96 | unsigned char pin_reset; 97 | unsigned char pin_sce; 98 | 99 | // The size of the display, in pixels... 100 | unsigned char width; 101 | unsigned char height; 102 | 103 | // Current cursor position... 104 | unsigned char column; 105 | unsigned char line; 106 | 107 | // User-defined glyphs (below the ASCII space character)... 108 | const unsigned char *custom[' ']; 109 | 110 | // Send a command or data to the display... 111 | void send(unsigned char type, unsigned char data); 112 | }; 113 | 114 | 115 | #endif /* PCD8544_H */ 116 | 117 | 118 | /* vim: set expandtab ts=4 sw=4: */ 119 | -------------------------------------------------------------------------------- /cmake/Arduino-toolchain.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | 3 | #============================================================================= 4 | # A toolchain for the Arduino compatile boards. 5 | # Please refer to README.md for the usage. 6 | 7 | # If the version of CMake used is below 3.7.0, exit with error. 8 | # 9 | # Intended to support CMake version 3.0.0, but there are limitations which 10 | # requires a minimum CMake version of 3.7.0. However, wherever possible, the 11 | # toolchain remains compatible with 3.0.0, looking for some workarounds for 12 | # the limitations in the future. The limitations are captured below. 13 | # 14 | # Version below 3.2.0 has no support for continue() command. Can be fixed. 15 | # 16 | # Version below 3.4.0 has no support for target properties BINARY_DIR, 17 | # SOURCE_DIR etc. These are required in target command generator expressions. 18 | # 19 | # Version below 3.6.0 has issues in identifying try_compile output for 20 | # static library. So there are some errors during the configuration, but 21 | # may still possibly work. 22 | # 23 | # Version below 3.7.0 has no support for CMAKE_SYSTEM_CUSTOM_CODE, which 24 | # is required when there is some dynamic information, like Board options, 25 | # that needs to be included in the toolchain. Here just including the user 26 | # provided path will not work, because the user variables, cache or root 27 | # binary directory path etc. are not passed to try_compile. 28 | 29 | if (CMAKE_VERSION VERSION_LESS 3.7.0) 30 | message(FATAL_ERROR "CMake version below 3.7.0 unsupported!!!") 31 | endif() 32 | 33 | # Save the policy state. We will restore it at the end. 34 | cmake_policy(PUSH) 35 | 36 | # Set policy to above 3.0.0 37 | cmake_policy(VERSION 3.0.0) 38 | 39 | # Interpret if() arguments without quotes as variables/keywords 40 | if (NOT CMAKE_VERSION VERSION_LESS 3.1) 41 | cmake_policy(SET CMP0054 NEW) 42 | endif() 43 | 44 | #***************************************************************************** 45 | # Set system name and basic information 46 | set(CMAKE_SYSTEM_NAME "Arduino") 47 | 48 | # Set module path to enable local modules search 49 | set(ARDUINO_TOOLCHAIN_DIR "${CMAKE_CURRENT_LIST_DIR}") 50 | set(_ARDUINO_TOOLCHAIN_PARENT "${CMAKE_PARENT_LIST_FILE}") 51 | set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH}" "${CMAKE_CURRENT_LIST_DIR}") 52 | set (ARDUINO_TOOLCHAIN_VERSION "1.0") 53 | 54 | # Include modules 55 | include(Arduino/System/BoardsIndex) 56 | include(Arduino/System/BoardToolchain) 57 | include(Arduino/System/BoardBuildTargets) 58 | 59 | #***************************************************************************** 60 | # For improved speed, indexing of boards is done only once during a 61 | # cmake invocation. However, this toolchain file is included multiple 62 | # times in multiple contexts (system determination context, separate 63 | # context for each try compile etc.). After indexing, the selected 64 | # board's toolchain info is configured to a generated file that gets 65 | # included in every other inclusion of this toolchain. 66 | if (NOT _BOARD_INDEXING_COMPLETED) 67 | get_property(_in_try_compile GLOBAL PROPERTY IN_TRY_COMPILE) 68 | # IN_TRY_COMPILE check seems to be not enough. Check for parent 69 | # script works, but may be undocumented! 70 | get_filename_component(parent_script "${_ARDUINO_TOOLCHAIN_PARENT}" 71 | NAME_WE) 72 | if (parent_script STREQUAL "CMakeSystem") 73 | check_board_options_changed(_b_changed) 74 | if (NOT _b_changed) 75 | set(_BOARD_INDEXING_COMPLETED TRUE) 76 | endif() 77 | endif() 78 | endif() 79 | 80 | if (NOT _BOARD_INDEXING_COMPLETED) 81 | SetupBoardToolchain() 82 | set(CMAKE_SYSTEM_CUSTOM_CODE 83 | "include(\"${CMAKE_BINARY_DIR}/ArduinoSystem.cmake\")" 84 | ) 85 | set (_BOARD_INDEXING_COMPLETED TRUE) 86 | endif() 87 | 88 | # Search for programs in the build host directories 89 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) 90 | # For libraries and headers in the target directories 91 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 92 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 93 | 94 | # Do not try to link during the configure time, due to the dependency on the 95 | # core, which we do not have a target yet. 96 | set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) 97 | 98 | cmake_policy(POP) 99 | -------------------------------------------------------------------------------- /cmake/Arduino/System/PackagePathIndex.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | 3 | # No need to include this recursively 4 | if(_PACKAGE_PATH_INDEX_INCLUDED) 5 | return() 6 | endif() 7 | set(_PACKAGE_PATH_INDEX_INCLUDED TRUE) 8 | 9 | #***************************************************************************** 10 | # Find the standard installation and package folders of Ardunio. Currently 11 | # this toolchain has a dependency of Arduino IDE installation and any arduino 12 | # board management through arduino IDE. In future this dependency might be 13 | # removed, and instead a mechanism will be provided to download an arduino 14 | # platform (like avr, esp32) and board management on the go. 15 | # 16 | # The identified paths are stored in cached ARDUINO_* variables (see below). 17 | # 18 | function(InitializeArduinoPackagePathList) 19 | 20 | if (${CMAKE_HOST_APPLE}) 21 | 22 | set(install_search_paths "$ENV{HOME}/Applications" /Applications 23 | /Developer/Applications /sw /opt/local) 24 | set(install_path_suffixes Arduino.app/Contents/Java 25 | Arduino.app/Contents/Resources/Java) 26 | 27 | file(GLOB package_search_paths "$ENV{HOME}/Library/Arduino15") 28 | set(package_path_suffixes "") 29 | 30 | file(GLOB sketchbook_search_paths "$ENV{HOME}/Library/Arduino15") 31 | set(sketchbook_path_suffixes "") 32 | 33 | elseif (${CMAKE_HOST_UNIX}) # Probably Linux or some unix-like 34 | 35 | set(install_search_paths) 36 | set(install_path_suffixes "") 37 | 38 | # Resolve from arduino executable path 39 | execute_process(COMMAND which arduino OUTPUT_VARIABLE _bin_path 40 | ERROR_VARIABLE _ignore RESULT_VARIABLE _cmd_result) 41 | if (_cmd_result STREQUAL 0) 42 | string(STRIP "${_bin_path}" _bin_path) 43 | execute_process(COMMAND readlink -f "${_bin_path}" 44 | OUTPUT_VARIABLE _link_path RESULT_VARIABLE _cmd_result) 45 | if (_cmd_result STREQUAL 0) 46 | string(STRIP "${_link_path}" _bin_path) 47 | endif() 48 | get_filename_component(_install_path "${_bin_path}" DIRECTORY) 49 | list(APPEND install_search_paths "${_install_path}") 50 | else() # Resolve from application shortcut 51 | set(_app_path "$ENV{HOME}/.local/share/applications") 52 | if (EXISTS "${_app_path}/arduino-arduinoide.desktop") 53 | file(STRINGS "${_app_path}/arduino-arduinoide.desktop" 54 | _exec_prop REGEX "^Exec=") 55 | if ("${_exec_prop}" MATCHES "^Exec=\"?(.*)\"?") 56 | get_filename_component(_install_path "${CMAKE_MATCH_1}" 57 | DIRECTORY) 58 | list(APPEND install_search_paths "${_install_path}") 59 | endif() 60 | endif() 61 | endif() 62 | 63 | # Other usual locations 64 | file(GLOB other_search_paths "$ENV{HOME}/.local/share/arduino*" 65 | /usr/share/arduino* /usr/local/share/arduino* /opt/local/arduino* 66 | /opt/arduino* "$ENV{HOME}/opt/arduino*") 67 | list(APPEND install_search_paths "${other_search_paths}") 68 | 69 | file(GLOB package_search_paths "$ENV{HOME}/.arduino15") 70 | set(package_path_suffixes "") 71 | 72 | file(GLOB sketchbook_search_paths "$ENV{HOME}/.arduino15") 73 | set(sketchbook_path_suffixes "") 74 | 75 | elseif (${CMAKE_HOST_WIN32}) 76 | 77 | set(Prog86Path "ProgramFiles(x86)") 78 | set(install_search_paths "$ENV{${Prog86Path}}/Arduino" 79 | "$ENV{ProgramFiles}/Arduino") 80 | set(install_path_suffixes "") 81 | 82 | file(GLOB package_search_paths "$ENV{LOCALAPPDATA}/Arduino15") 83 | set(package_path_suffixes "") 84 | 85 | set(_reg_software "HKEY_LOCAL_MACHINE\\SOFTWARE") 86 | set(_reg_win "${_reg_software}\\Microsoft\\Windows\\CurrentVersion") 87 | set(_reg_explorer "${_reg_win}\\Explorer") 88 | file(GLOB sketchbook_search_paths "$ENV{LOCALAPPDATA}/Arduino15" 89 | "[${_reg_explorer}\\User Shell Folders;Personal]/ArduinoData") 90 | set(sketchbook_path_suffixes "") 91 | else() 92 | 93 | message(FATAL_ERROR 94 | "Host system ${CMAKE_HOST_SYSTEM} is not supported!!!") 95 | 96 | endif() 97 | 98 | # Search for Arduino install path 99 | find_path(ARDUINO_INSTALL_PATH 100 | NAMES lib/version.txt 101 | PATH_SUFFIXES ${install_path_suffixes} 102 | HINTS ${install_search_paths} 103 | NO_DEFAULT_PATH 104 | NO_CMAKE_FIND_ROOT_PATH 105 | DOC "Path to Arduino IDE installation") 106 | if (NOT ARDUINO_INSTALL_PATH) 107 | message(FATAL_ERROR "Arduino IDE installation is not found!!!\n" 108 | "Use -DARDUINO_INSTALL_PATH= to manually specify the path\n" 109 | ) 110 | elseif(ARDUINO_INSTALL_PATH AND NOT "${ARDUINO_ENABLE_PACKAGE_MANAGER}" 111 | AND "${ARDUINO_BOARD_MANAGER_URL}" STREQUAL "") 112 | message("${ARDUINO_INSTALL_PATH}") 113 | # TJ: Needs fixing 114 | # file(READ "${ARDUINO_INSTALL_PATH}/lib/version.txt" _version) 115 | string(REGEX MATCH "[0-9]+\\.[0-9]" _ard_version "${_version}") 116 | if (_version AND "${_ard_version}" VERSION_LESS "1.5") 117 | message(WARNING "${ARDUINO_INSTALL_PATH} may be unsupported version " 118 | "${_version}. Please install newer version!") 119 | endif() 120 | endif() 121 | # message("ARDUINO_INSTALL_PATH:${ARDUINO_INSTALL_PATH}") 122 | 123 | # Search for Arduino library path 124 | find_path(ARDUINO_PACKAGE_PATH 125 | NAMES package_index.json 126 | PATH_SUFFIXES ${package_path_suffixes} 127 | HINTS ${package_search_paths} 128 | NO_DEFAULT_PATH 129 | NO_CMAKE_FIND_ROOT_PATH 130 | DOC "Path to Arduino platform packages") 131 | # message("ARDUINO_PACKAGE_PATH:${ARDUINO_PACKAGE_PATH}") 132 | 133 | # Search for sketchbook path 134 | find_file(ARDUINO_PREFERENCE_FILE 135 | NAMES preferences.txt 136 | PATH_SUFFIXES ${sketchbook_path_suffixes} 137 | HINTS ${sketchbook_search_paths} 138 | NO_DEFAULT_PATH 139 | NO_CMAKE_FIND_ROOT_PATH) 140 | # message("ARDUINO_PREFERENCE_FILE:${ARDUINO_PREFERENCE_FILE}") 141 | if (ARDUINO_PREFERENCE_FILE) 142 | file(STRINGS "${ARDUINO_PREFERENCE_FILE}" preferences) 143 | list_filter_include_regex(preferences "sketchbook.path=.*") 144 | string(REGEX MATCH "sketchbook.path=(.*)" match "${preferences}") 145 | if (match) 146 | file(TO_CMAKE_PATH "${CMAKE_MATCH_1}" ARDUINO_SKETCHBOOK_PATH) 147 | set(ARDUINO_SKETCHBOOK_PATH "${ARDUINO_SKETCHBOOK_PATH}" 148 | CACHE PATH "Path to Arduino Sketchbook") 149 | endif() 150 | endif() 151 | # message("ARDUINO_SKETCHBOOK_PATH:${ARDUINO_SKETCHBOOK_PATH}") 152 | 153 | endfunction() 154 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/ArduinoSystem.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | 3 | set(ARDUINO_INSTALL_PATH "@ARDUINO_INSTALL_PATH@") 4 | set(ARDUINO_PACKAGE_PATH "@ARDUINO_PACKAGE_PATH@") 5 | set(ARDUINO_SKETCHBOOK_PATH "@ARDUINO_SKETCHBOOK_PATH@") 6 | 7 | set(ARDUINO "@CMAKE_SYSTEM_VERSION@") 8 | set("ARDUINO_ARCH_@CMAKE_SYSTEM_PROCESSOR@" TRUE) 9 | set("ARDUINO_@ARDUINO_BOARD@" TRUE) 10 | 11 | set(ARDUINO_BOARD "@ARDUINO_BOARD@") 12 | set(ARDUINO_BOARD_IDENTIFIER "@ARDUINO_BOARD_IDENTIFIER@") 13 | set(ARDUINO_BOARD_NAME "@ARDUINO_BOARD_NAME@") 14 | set(ARDUINO_BOARD_BUILD_ARCH "@ARDUINO_BOARD_BUILD_ARCH@") 15 | set(ARDUINO_BOARD_RUNTIME_PLATFORM_PATH "@ARDUINO_BOARD_RUNTIME_PLATFORM_PATH@") 16 | set(ARDUINO_CORE_SPECIFIC_PLATFORM_PATH "@ARDUINO_CORE_SPECIFIC_PLATFORM_PATH@") 17 | set(ARDUINO_BOARD_BUILD_CORE_PATH "@ARDUINO_BOARD_BUILD_CORE_PATH@") 18 | set(ARDUINO_BOARD_BUILD_VARIANT_PATH "@ARDUINO_BOARD_BUILD_VARIANT_PATH@") 19 | set(ARDUINO_BOARD_HOST_NAME "@ARDUINO_BOARD_HOST_NAME@") 20 | 21 | set(ARDUINO_BOARD_UPLOAD_TOOL @ARDUINO_BOARD_UPLOAD_TOOL@) 22 | set(ARDUINO_BOARD_PROGRAM_TOOL @ARDUINO_BOARD_PROGRAM_TOOL@) 23 | set(ARDUINO_BOARD_BOOTLOADER_TOOL @ARDUINO_BOARD_BOOTLOADER_TOOL@) 24 | 25 | set(ARDUINO_PROGRAMMER_ID "@ARDUINO_PROGRAMMER_ID@") 26 | set(ARDUINO_PROGRAMMER_NAME "@ARDUINO_PROGRAMMER_NAME@") 27 | 28 | set(ARDUINO_RULE_NAMES_LIST "@ARDUINO_RULE_NAMES_LIST@") 29 | @ARDUINO_RULE_SET_LIST@ 30 | @ARDUINO_SEL_MENU_SET_LIST@ 31 | 32 | set(CMAKE_C_COMPILER "@CMAKE_C_COMPILER@") 33 | set(CMAKE_C_COMPILE_OBJECT "@CMAKE_C_COMPILE_OBJECT@") 34 | set(CMAKE_C_LINK_EXECUTABLE "@CMAKE_C_LINK_EXECUTABLE@") 35 | set(CMAKE_C_CREATE_STATIC_LIBRARY "@CMAKE_C_CREATE_STATIC_LIBRARY@") 36 | 37 | set(CMAKE_CXX_COMPILER "@CMAKE_CXX_COMPILER@") 38 | set(CMAKE_CXX_COMPILE_OBJECT "@CMAKE_CXX_COMPILE_OBJECT@") 39 | set(CMAKE_CXX_LINK_EXECUTABLE "@CMAKE_CXX_LINK_EXECUTABLE@") 40 | set(CMAKE_CXX_CREATE_STATIC_LIBRARY "@CMAKE_CXX_CREATE_STATIC_LIBRARY@") 41 | 42 | set(CMAKE_ASM_COMPILER "@CMAKE_ASM_COMPILER@") 43 | set(CMAKE_ASM_COMPILE_OBJECT "@CMAKE_ASM_COMPILE_OBJECT@") 44 | 45 | # Need to include this in cache as plain setting of this variable is 46 | # overwritten when marking it as advanced (This is fixed only in CMake 3.13.0) 47 | set(CMAKE_AR "@CMAKE_AR@" CACHE INTERNAL "" FORCE) 48 | 49 | set(ARDUINO_FIND_ROOT_PATH "@ARDUINO_FIND_ROOT_PATH@") 50 | set(ARDUINO_SYSTEM_PROGRAM_PATH "@ARDUINO_SYSTEM_PROGRAM_PATH@") 51 | 52 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/BoardOptions_BoardHeader.cmake.in: -------------------------------------------------------------------------------- 1 | 2 | #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 3 | # Arduino boards. 4 | # Platform: @_pl_name@ 5 | #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 6 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/BoardOptions_BoardSel.cmake.in: -------------------------------------------------------------------------------- 1 | @_board_sel_comment@set(ARDUINO_BOARD "@_board_name_in_menu@") # @_board_name@ 2 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/BoardOptions_FileHeader.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | 3 | ############################################################################### 4 | # This is an automatically generated template file for board options. 5 | # You may edit it to comment/uncomment selected board and board options. 6 | # However do not change the structure of this template, which is fixed and 7 | # any change to the structure gets overwritten. 8 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/BoardOptions_MenuBoardHdr.cmake.in: -------------------------------------------------------------------------------- 1 | 2 | #============================================================================== 3 | # Menu options. 4 | # Board: @_board_name_in_menu@ 5 | #============================================================================== 6 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/BoardOptions_MenuHeader.cmake.in: -------------------------------------------------------------------------------- 1 | 2 | # Option: @_menu_name@ 3 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/BoardOptions_Menuoption.cmake.in: -------------------------------------------------------------------------------- 1 | @_menu_opt_sel_comment@set(ARDUINO_@_menu_opt_identifier@ TRUE) # @_menu_opt_name@ 2 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/BoardOptions_ProgHeader.cmake.in: -------------------------------------------------------------------------------- 1 | 2 | #****************************************************************************** 3 | # Arduino programmers. 4 | # Platform: @_pl_name@ 5 | #****************************************************************************** 6 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/BoardOptions_ProgSel.cmake.in: -------------------------------------------------------------------------------- 1 | @_prog_sel_comment@set(ARDUINO_PROGRAMMER "@_prog_name_in_menu@") # @_prog_name@ 2 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/DummySource.cpp.in: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jenkie/Arduino-Pedelec-Controller/5895db3d4e86cc6ca684cde21d62682ef5b284e9/cmake/Arduino/Templates/DummySource.cpp.in -------------------------------------------------------------------------------- /cmake/Arduino/Templates/ExecuteRecipe.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | 3 | set(ARDUINO_TOOLCHAIN_DIR "@ARDUINO_TOOLCHAIN_DIR@") 4 | include("${ARDUINO_TOOLCHAIN_DIR}/Arduino/Utilities/PropertiesReader.cmake") 5 | 6 | function(_get_usage_str req_var_list opt_var_list ret_usage_str) 7 | set(_ret_usage_str) 8 | foreach(var_name IN LISTS req_var_list) 9 | string(MAKE_C_IDENTIFIER "${var_name}" var_id) 10 | string(TOUPPER "${var_id}" var_id) 11 | set(_ret_usage_str "${_ret_usage_str} ${var_id}=<${var_name}>") 12 | endforeach() 13 | foreach(var_name IN LISTS opt_var_list) 14 | string(MAKE_C_IDENTIFIER "${var_name}" var_id) 15 | string(TOUPPER "${var_id}" var_id) 16 | set(_ret_usage_str "${_ret_usage_str} [${var_id}=<${var_name}>]") 17 | endforeach() 18 | set("${ret_usage_str}" "${_ret_usage_str}" PARENT_SCOPE) 19 | endfunction() 20 | 21 | if (CONFIRM_RECIPE_PATTERN) 22 | set(RECIPE_PATTERN "${CONFIRM_RECIPE_PATTERN}") 23 | endif() 24 | 25 | properties_resolve_value_env("${RECIPE_PATTERN}" RECIPE_PATTERN 26 | _req_var_list _opt_var_list _all_resolved) 27 | _get_usage_str("${_req_var_list}" "${_opt_var_list}" _usage_str) 28 | 29 | if (CONFIRM_RECIPE_PATTERN) 30 | set(_usage_str "${_usage_str} CONFIRM=1") 31 | if (NOT "$ENV{CONFIRM}") 32 | set(_all_resolved 0) 33 | endif() 34 | endif() 35 | 36 | set(cmd_pattern "${RECIPE_PATTERN}") 37 | 38 | if (CMAKE_VERBOSE_MAKEFILE OR DEFINED ENV{VERBOSE}) 39 | string(REPLACE ";" " " printable_cmd_line "${cmd_pattern}") 40 | message("${printable_cmd_line}") 41 | endif() 42 | 43 | if (NOT _all_resolved) 44 | if (NOT MAKE_PROGRAM) 45 | set(MAKE_PROGRAM "") 46 | endif() 47 | get_filename_component(_make_ "${MAKE_PROGRAM}" NAME_WE) 48 | 49 | message(FATAL_ERROR 50 | "\nExpected environment variable(s) not provided. Usage as follows:\n" 51 | "Usage: '${_make_}${_usage_str} ${OPERATION}'") 52 | endif() 53 | 54 | execute_process(COMMAND ${cmd_pattern} RESULT_VARIABLE result) 55 | if (NOT "${result}" EQUAL 0) 56 | message(FATAL_ERROR "${OPERATION} failed!!!") 57 | endif() 58 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/FirmwareSizePrint.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | 3 | message("################## Size Summary ##################") 4 | # separate_arguments(cmd_pattern UNIX_COMMAND "${RECIPE_SIZE_PATTERN}") 5 | set(cmd_pattern "${RECIPE_SIZE_PATTERN}") 6 | execute_process(COMMAND ${cmd_pattern} RESULT_VARIABLE result OUTPUT_VARIABLE SizeRecipeOutput) 7 | string(REPLACE "\n" ";" SizeRecipeOutput "${SizeRecipeOutput}") 8 | 9 | set (size_regex_list "@SIZE_REGEX_LIST@") 10 | set (size_name_list "@SIZE_NAME_LIST@") 11 | set (maximum_size_list "@MAXIMUM_SIZE_LIST@") 12 | set (size_match_idx_list "@SIZE_MATCH_IDX_LIST@") 13 | 14 | # For each of the elements whose size is to be printed 15 | math(EXPR _last_index "@SIZE_REGEX_COUNT@ - 1") 16 | foreach(idx RANGE "${_last_index}") 17 | 18 | list(GET size_regex_list ${idx} size_regex) 19 | list(GET size_name_list ${idx} size_name) 20 | list(GET maximum_size_list ${idx} maximum_size) 21 | list(GET size_match_idx_list ${idx} size_match_idx) 22 | 23 | # Grep for the size in the output and add them all together 24 | set(tot_size 0) 25 | foreach(line IN LISTS SizeRecipeOutput) 26 | string(REGEX MATCH "${size_regex}" match "${line}") 27 | if (match) 28 | math(EXPR tot_size "${tot_size} + ${CMAKE_MATCH_${size_match_idx}}") 29 | endif() 30 | endforeach() 31 | 32 | 33 | # Capitalize first letter of element name 34 | string(SUBSTRING "${size_name}" 0 1 first_letter) 35 | string(SUBSTRING "${size_name}" 1 -1 rem_letters) 36 | string(TOUPPER "${first_letter}" first_letter) 37 | set(size_name "${first_letter}${rem_letters}") 38 | 39 | # Print total size of the element 40 | if (maximum_size GREATER 0) 41 | math(EXPR tot_size_percent "${tot_size} * 100 / ${maximum_size}") 42 | message("${size_name} Size: ${tot_size} of ${maximum_size} bytes (${tot_size_percent}%)") 43 | else() 44 | message("${size_name} Size: ${tot_size} bytes") 45 | endif() 46 | 47 | endforeach() 48 | 49 | message("##################################################") 50 | -------------------------------------------------------------------------------- /cmake/Arduino/Templates/FirmwareUpload.cmake.in: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | 3 | set(ARDUINO_TOOLCHAIN_DIR "@ARDUINO_TOOLCHAIN_DIR@") 4 | include("${ARDUINO_TOOLCHAIN_DIR}/Arduino/Utilities/PropertiesReader.cmake") 5 | 6 | function(_get_usage_str req_var_list opt_var_list ret_usage_str) 7 | set(_ret_usage_str) 8 | foreach(var_name IN LISTS req_var_list) 9 | string(MAKE_C_IDENTIFIER "${var_name}" var_id) 10 | string(TOUPPER "${var_id}" var_id) 11 | set(_ret_usage_str "${_ret_usage_str} ${var_id}=<${var_name}>") 12 | endforeach() 13 | foreach(var_name IN LISTS opt_var_list) 14 | string(MAKE_C_IDENTIFIER "${var_name}" var_id) 15 | string(TOUPPER "${var_id}" var_id) 16 | set(_ret_usage_str "${_ret_usage_str} [${var_id}=<${var_name}>]") 17 | endforeach() 18 | set("${ret_usage_str}" "${_ret_usage_str}" PARENT_SCOPE) 19 | endfunction() 20 | 21 | if(UPLOAD_SERIAL_PATTERN) 22 | 23 | properties_resolve_value_env("${UPLOAD_SERIAL_PATTERN}" 24 | UPLOAD_SERIAL_PATTERN _req_var_list _opt_var_list 25 | _all_serial_resolved) 26 | list(REMOVE_ITEM _req_var_list "serial.port") 27 | list(REMOVE_ITEM _opt_var_list "serial.port") 28 | _get_usage_str("${_req_var_list}" "${_opt_var_list}" 29 | _serial_usage_str) 30 | set(_serial_usage_str " SERIAL_PORT=${_serial_usage_str}") 31 | 32 | endif() 33 | 34 | if(UPLOAD_NETWORK_PATTERN) 35 | # NETWORK_PORT defines both IP and port. Split it 36 | if(DEFINED ENV{NETWORK_PORT}) 37 | string(REPLACE ":" ";" network_addr "$ENV{NETWORK_PORT}") 38 | list(LENGTH network_addr len) 39 | list(GET network_addr 0 network_ip) 40 | set(ENV{SERIAL_PORT} "${network_ip}") 41 | if("${len}" GREATER 1) 42 | list(GET network_addr 1 network_port) 43 | else() 44 | set(network_port 0) 45 | endif() 46 | set(ENV{NETWORK_PORT} "${network_port}") 47 | endif() 48 | 49 | properties_resolve_value_env("${UPLOAD_NETWORK_PATTERN}" 50 | UPLOAD_NETWORK_PATTERN _req_var_list _opt_var_list 51 | _all_network_resolved) 52 | list(REMOVE_ITEM _req_var_list "serial.port" "network.port") 53 | list(REMOVE_ITEM _opt_var_list "serial.port" "network.port") 54 | _get_usage_str("${_req_var_list}" "${_opt_var_list}" 55 | _network_usage_str) 56 | set(_network_usage_str " NETWORK_PORT=${_network_usage_str}") 57 | 58 | endif() 59 | 60 | set(OPERATION "upload-${TARGET}") 61 | 62 | if (_all_network_resolved) 63 | set(cmd_pattern "${UPLOAD_NETWORK_PATTERN}") 64 | elseif(_all_serial_resolved) 65 | set(cmd_pattern "${UPLOAD_SERIAL_PATTERN}") 66 | endif() 67 | 68 | if (CMAKE_VERBOSE_MAKEFILE OR DEFINED ENV{VERBOSE}) 69 | string(REPLACE ";" " " printable_cmd_line "${cmd_pattern}") 70 | message("${printable_cmd_line}") 71 | endif() 72 | 73 | if (NOT _all_serial_resolved AND NOT _all_network_resolved) 74 | if (NOT MAKE_PROGRAM) 75 | set(MAKE_PROGRAM "") 76 | endif() 77 | get_filename_component(_make_ "${MAKE_PROGRAM}" NAME_WE) 78 | 79 | message(FATAL_ERROR 80 | "\nExpected environment variable(s) not provided. Usage as follows:\n" 81 | "Serial Upload: '${_make_}${_serial_usage_str} ${OPERATION}'\n" 82 | "Network Upload: '${_make_}${_network_usage_str} ${OPERATION}'") 83 | endif() 84 | 85 | execute_process(COMMAND ${cmd_pattern} RESULT_VARIABLE result) 86 | if (NOT "${result}" EQUAL 0) 87 | message(FATAL_ERROR "upload-${OPERATION} failed!!!") 88 | endif() 89 | -------------------------------------------------------------------------------- /cmake/Arduino/Utilities/CommonUtils.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | 3 | # No need to include this recursively 4 | if(_TOOLCHAIN_COMMON_UTILS_INCLUDED) 5 | return() 6 | endif() 7 | set(_TOOLCHAIN_COMMON_UTILS_INCLUDED TRUE) 8 | 9 | # List filter is not available in older versions of cmake 10 | # Providing equivalent versions for the same 11 | function(list_filter_include_regex _list_var _regex) 12 | 13 | if (CMAKE_VERSION VERSION_LESS 3.6.3) 14 | set(_result) 15 | foreach(_elem IN LISTS "${_list_var}") 16 | string(REGEX MATCH "${_regex}" _match "${_elem}") 17 | if (_match) 18 | list(APPEND _result "${_elem}") 19 | endif() 20 | endforeach() 21 | set("${_list_var}" "${_result}" PARENT_SCOPE) 22 | else() 23 | list(FILTER "${_list_var}" INCLUDE REGEX "${_regex}") 24 | set("${_list_var}" "${${_list_var}}" PARENT_SCOPE) 25 | endif() 26 | 27 | endfunction() 28 | 29 | # List filter is not available in older versions of cmake 30 | # Providing equivalent versions for the same 31 | function(list_filter_exclude_regex _list_var _regex) 32 | 33 | if (CMAKE_VERSION VERSION_LESS 3.6.3) 34 | set(_result) 35 | foreach(_elem IN LISTS "${_list_var}") 36 | string(REGEX MATCH "${_regex}" _match "${_elem}") 37 | if (NOT _match) 38 | list(APPEND _result "${_elem}") 39 | endif() 40 | endforeach() 41 | set("${_list_var}" "${_result}" PARENT_SCOPE) 42 | else() 43 | list(FILTER "${_list_var}" EXCLUDE REGEX "${_regex}") 44 | set("${_list_var}" "${${_list_var}}" PARENT_SCOPE) 45 | endif() 46 | 47 | endfunction() 48 | 49 | 50 | # List TRANSFORM is not available in older versions of cmake 51 | # Providing equivalent versions for the same 52 | function(list_transform_replace _list_var _regex _replace) 53 | if (CMAKE_VERSION VERSION_LESS 3.12.4) 54 | set(_result) 55 | foreach (_elem IN LISTS "${_list_var}") 56 | string(REGEX REPLACE "${_regex}" "${_replace}" _new_elem "${_elem}") 57 | list(APPEND _result "${_new_elem}") 58 | endforeach() 59 | set("${_list_var}" "${_result}" PARENT_SCOPE) 60 | else() 61 | list(TRANSFORM "${_list_var}" REPLACE "${_regex}" "${_replace}") 62 | set("${_list_var}" "${${_list_var}}" PARENT_SCOPE) 63 | endif() 64 | endfunction() 65 | 66 | # String APPEND is not available in older versions of cmake 67 | # Providing equivalent versions for the same 68 | function(string_append _string_var _input) 69 | if (CMAKE_VERSION VERSION_LESS 3.4.3) 70 | set("${_string_var}" "${${_string_var}}${_input}" PARENT_SCOPE) 71 | else() 72 | string(APPEND "${_string_var}" "${_input}") 73 | set("${_string_var}" "${${_string_var}}" PARENT_SCOPE) 74 | endif() 75 | endfunction() 76 | 77 | # Make a string ready for quoting 78 | function(string_escape_quoting _string_var) 79 | string(REPLACE "\\" "\\\\" _escaped_str "${${_string_var}}") 80 | string(REPLACE "\"" "\\\"" _escaped_str "${_escaped_str}") 81 | set("${_string_var}" "${_escaped_str}" PARENT_SCOPE) 82 | endfunction() 83 | 84 | # Check if two files are the same 85 | function(check_same_file file1 file2 _ret_var) 86 | get_filename_component(x "${file1}" ABSOLUTE) 87 | get_filename_component(y "${file2}" ABSOLUTE) 88 | if (x STREQUAL y) 89 | set("${_ret_var}" TRUE PARENT_SCOPE) 90 | else() 91 | set("${_ret_var}" FALSE PARENT_SCOPE) 92 | endif() 93 | endfunction() 94 | 95 | # Add file(s) as configure dependency so that CMake re-runs when 96 | # those files change 97 | function(add_configure_dependency file) 98 | foreach(item IN LISTS ARGN ITEMS "${file}") 99 | # message("Configure dependency: ${item}") 100 | set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS 101 | "${item}") 102 | endforeach() 103 | endfunction() 104 | 105 | -------------------------------------------------------------------------------- /cmake/Arduino/Utilities/JSONParser.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | 3 | # No need to include this recursively 4 | if(_JSON_PARSER_INCLUDED) 5 | return() 6 | endif() 7 | set(_JSON_PARSER_INCLUDED TRUE) 8 | 9 | include(CMakeParseArguments) 10 | include(Arduino/Utilities/CommonUtils) 11 | 12 | function(json_parse json_content namespace) 13 | 14 | # States: NAME1, NAME_SEP, VALUE, VALUE_0, FIELD_SEP, ARRAY_SEP, NAME2, END 15 | set(json_parse_state "VALUE") 16 | 17 | string(REGEX MATCHALL "\"(\\\\.|[^\"])*\"|[][{}:,]|true|false|null|-?[0-9]+(\\.[0-9]*)?([eE][+-]?[0-9]+)?" token_list "${json_content}") 18 | _json_escape_cmake_sqr_brkt(token_list) 19 | 20 | set(curr_field "${namespace}") 21 | set(open_brace "(") 22 | set(close_brace ")") 23 | 24 | foreach(var ${token_list}) 25 | 26 | # message("token:${var}") 27 | if (${json_parse_state} STREQUAL "VALUE_0") 28 | if (var STREQUAL close_brace) 29 | # Array with 0 elements 30 | _json_leave_context() 31 | continue() 32 | else() 33 | # Start of value for the first element of the array 34 | # Switch to 0th array element context 35 | _json_enter_context("1") 36 | set(json_parse_state "VALUE") 37 | endif() 38 | endif() 39 | 40 | if (${json_parse_state} STREQUAL "VALUE") 41 | if (var STREQUAL "{") 42 | # Start of object value 43 | _json_set_prop("${curr_field}/type" "object") 44 | set(json_parse_state "NAME1") 45 | elseif (var STREQUAL open_brace) 46 | # Start of array value 47 | _json_set_prop("${curr_field}/type" "array") 48 | _json_set_prop("${curr_field}.N" "0") 49 | set(json_parse_state "VALUE_0") 50 | elseif(var MATCHES "^(true|false)") 51 | # Boolean value 52 | _json_set_prop("${curr_field}" "${var}") 53 | _json_set_prop("${curr_field}/type" "bool") 54 | _json_leave_context() 55 | elseif(var MATCHES "null") 56 | # NULL value 57 | _json_set_prop("${curr_field}" "${var}") 58 | _json_set_prop("${curr_field}/type" "null") 59 | _json_leave_context() 60 | elseif(var MATCHES "^-?[0-9]+") 61 | # Number value 62 | _json_set_prop("${curr_field}" "${var}") 63 | _json_set_prop("${curr_field}/type" "number") 64 | _json_leave_context() 65 | else() 66 | # String value 67 | string(REGEX MATCH "^\"(.*)\"$" match "${var}") 68 | if (NOT match) 69 | message(FATAL_ERROR "@${curr_field}: Expected a value, but got \"${var}\"") 70 | endif() 71 | set(value "${CMAKE_MATCH_1}") 72 | _json_unescape_cmake_sqr_brkt(value) 73 | _json_set_prop("${curr_field}" "${value}") 74 | _json_set_prop("${curr_field}/type" "string") 75 | _json_leave_context() 76 | endif() 77 | elseif (${json_parse_state} STREQUAL "NAME1" OR 78 | ${json_parse_state} STREQUAL "NAME2") 79 | 80 | if (${json_parse_state} STREQUAL "NAME1" AND 81 | var STREQUAL "}") 82 | # Object with 0 fields 83 | _json_leave_context() 84 | else() 85 | # Name of a field of an object 86 | string(REGEX MATCH "^\"(.*)\"$" match "${var}") 87 | if (NOT match) 88 | message(FATAL_ERROR "@${curr_field}: Expected a name, but got \"${var}\"") 89 | endif() 90 | string(STRIP "${CMAKE_MATCH_1}" name) 91 | _json_unescape_cmake_sqr_brkt(name) 92 | _json_enter_context("${name}") 93 | set(json_parse_state "NAME_SEP") 94 | 95 | endif() 96 | elseif (${json_parse_state} STREQUAL "FIELD_SEP") 97 | 98 | if (var STREQUAL ",") 99 | 100 | # Start of next field of an object 101 | set(json_parse_state "NAME2") 102 | 103 | elseif (var STREQUAL "}") 104 | # End of an object value 105 | _json_leave_context() 106 | else() 107 | message(FATAL_ERROR "@${curr_field}: Expected `,` or `}`, but got \"${var}\"") 108 | endif() 109 | 110 | elseif (${json_parse_state} STREQUAL "ARRAY_SEP") 111 | 112 | if (var STREQUAL ",") 113 | 114 | # increment array size 115 | math(EXPR n "${${curr_field}.N} + 1") 116 | _json_set_prop("${curr_field}.N" "${n}") 117 | math(EXPR n "${n} + 1") 118 | # Switch to next array element context 119 | _json_enter_context("${n}") 120 | set(json_parse_state "VALUE") 121 | 122 | elseif (var STREQUAL close_brace) 123 | 124 | # increment array size 125 | math(EXPR n "${${curr_field}.N} + 1") 126 | _json_set_prop("${curr_field}.N" "${n}") 127 | # Switch to the context of the parent of array 128 | _json_leave_context() 129 | 130 | else() 131 | 132 | message(FATAL_ERROR "@${curr_field}: Expected `]` or `,`, but got \"${var}\"") 133 | 134 | endif() 135 | 136 | elseif (${json_parse_state} STREQUAL "NAME_SEP") 137 | 138 | if (var STREQUAL ":") 139 | set(json_parse_state "VALUE") 140 | else() 141 | message(FATAL_ERROR "@${curr_field}: Expected `:`, but got \"${var}\"") 142 | endif() 143 | 144 | elseif (${json_parse_state} STREQUAL "END") 145 | 146 | message(FATAL_ERROR "@${curr_field}: Unexpected \"${var}\" after parsing completed") 147 | 148 | endif() 149 | endforeach() 150 | 151 | # print_json("${namespace}") 152 | 153 | endfunction() 154 | 155 | function(json_get_value namespace path return_value) 156 | cmake_parse_arguments(parsed_args "QUIET" "" "" ${ARGN}) 157 | if (NOT parsed_args_QUIET AND NOT DEFINED "${namespace}.${path}") 158 | message(FATAL_ERROR "JSON path '${path}' in '${namespace}' invalid!!!") 159 | endif() 160 | set("${return_value}" "${${namespace}.${path}}" PARENT_SCOPE) 161 | endfunction() 162 | 163 | function(json_get_list namespace pattern return_list) 164 | get_cmake_property(_variableNames VARIABLES) 165 | string(REGEX REPLACE "\\." "\\\\." namespace_regex "${namespace}") 166 | list_filter_include_regex(_variableNames "^${namespace_regex}\\.${pattern}") 167 | #foreach (_elem IN LISTS _variableNames) 168 | # string(REGEX REPLACE "^${namespace_regex}\\." "" _elem "${_elem}") 169 | # list(APPEND _variableNames2 "${_elem}") 170 | #endforeach() 171 | list_transform_replace(_variableNames "^${namespace_regex}\\." "") 172 | set("${return_list}" "${_variableNames}" PARENT_SCOPE) 173 | endfunction() 174 | 175 | function(json_print_all namespace) 176 | get_cmake_property(_variableNames VARIABLES) 177 | string(REGEX REPLACE "\\." "\\\\." namespace_regex "${namespace}") 178 | list_filter_include_regex(_variableNames "^${namespace_regex}\\.") 179 | foreach (_variableName ${_variableNames}) 180 | message("${_variableName}=${${_variableName}}") 181 | endforeach() 182 | endfunction() 183 | 184 | macro(json_set_parent_scope namespace) 185 | get_cmake_property(_variableNames VARIABLES) 186 | string(REGEX REPLACE "\\." "\\\\." namespace_regex "${namespace}") 187 | list_filter_include_regex(_variableNames "^${namespace_regex}(\\.|/)") 188 | foreach (_variableName ${_variableNames}) 189 | set("${_variableName}" "${${_variableName}}" PARENT_SCOPE) 190 | endforeach() 191 | endmacro() 192 | 193 | macro(_json_set_prop prop value) 194 | set("${prop}" "${value}") 195 | set("${prop}" "${value}" PARENT_SCOPE) 196 | endmacro() 197 | 198 | function(_json_enter_context ctx) 199 | set("${curr_field}.${ctx}/parent" "${curr_field}" PARENT_SCOPE) 200 | #message("Enter:${curr_field}.${ctx}") 201 | set(curr_field "${curr_field}.${ctx}" PARENT_SCOPE) 202 | endfunction() 203 | 204 | function(_json_leave_context) 205 | #message("Leave:${curr_field}") 206 | if (NOT DEFINED "${curr_field}/parent") 207 | set(json_parse_state "END" PARENT_SCOPE) 208 | # message("END") 209 | return() 210 | endif() 211 | 212 | set(curr_field "${${curr_field}/parent}") 213 | if ("${${curr_field}/type}" STREQUAL "object") 214 | set(json_parse_state "FIELD_SEP" PARENT_SCOPE) 215 | elseif ("${${curr_field}/type}" STREQUAL "array") # Array 216 | set(json_parse_state "ARRAY_SEP" PARENT_SCOPE) 217 | else() 218 | message(FATAL_ERROR "@${curr_field} Assert. Script error? ${${curr_field}/type}") 219 | endif() 220 | set(curr_field "${curr_field}" PARENT_SCOPE) 221 | endfunction() 222 | 223 | function(_json_escape_cmake_sqr_brkt str_var) 224 | string(REPLACE "(" "" ${str_var} "${${str_var}}") 225 | string(REPLACE ")" "" ${str_var} "${${str_var}}") 226 | string(REPLACE "[" "(" ${str_var} "${${str_var}}") 227 | string(REPLACE "]" ")" ${str_var} "${${str_var}}") 228 | set(${str_var} "${${str_var}}" PARENT_SCOPE) 229 | endfunction() 230 | 231 | function(_json_unescape_cmake_sqr_brkt str_var) 232 | string(REPLACE ")" "]" ${str_var} "${${str_var}}") 233 | string(REPLACE "(" "[" ${str_var} "${${str_var}}") 234 | string(REPLACE "" "(" ${str_var} "${${str_var}}") 235 | string(REPLACE "" ")" ${str_var} "${${str_var}}") 236 | set(${str_var} "${${str_var}}" PARENT_SCOPE) 237 | endfunction() 238 | 239 | macro(_json_clear namespace) 240 | get_cmake_property(_variableNames VARIABLES) 241 | string(REGEX REPLACE "\\." "\\\\." namespace_regex "${namespace}") 242 | list_filter_include_regex(_variableNames "^${namespace_regex}\\.") 243 | foreach (_variableName ${_variableNames}) 244 | unset("${_variableName}") 245 | unset("${_variableName}" PARENT_SCOPE) 246 | endforeach() 247 | endmacro() 248 | -------------------------------------------------------------------------------- /cmake/Arduino/Utilities/PropertiesReader.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | # Copyright (c) 2018 Arduino CMake 3 | 4 | # Note: Some code copied from Arduino-CMake-NG project and re-written 5 | # Thanks to the contributers of the project 6 | 7 | # No need to include this recursively 8 | if(_PROPERTIES_READER_INCLUDED) 9 | return() 10 | endif() 11 | set(_PROPERTIES_READER_INCLUDED TRUE) 12 | 13 | function(properties_read properties_file namespace) 14 | 15 | cmake_parse_arguments(parsed_args "RESET" "" "" ${ARGN}) 16 | if (parsed_args_RESET) 17 | set(_prop_list "${${namespace}/list}") 18 | foreach(_prop IN LISTS _prop_list) 19 | unset("${_prop}") 20 | unset("${_prop}" PARENT_SCOPE) 21 | endforeach() 22 | set("${namespace}/list") 23 | endif() 24 | file(STRINGS ${properties_file} _content) 25 | # message("\n${_content}") 26 | _properties_parse(_content "${namespace}") 27 | set("${namespace}/list" "${${namespace}/list}" PARENT_SCOPE) 28 | endfunction() 29 | 30 | function(properties_get_value namespace property_name return_value) 31 | cmake_parse_arguments(parsed_args "QUIET" "DEFAULT" "" ${ARGN}) 32 | if (NOT DEFINED "${namespace}.${property_name}") 33 | # message("parsed_args:${parsed_args_QUIET}:${parsed_args_DEFAULT}") 34 | if (NOT parsed_args_QUIET AND "${parsed_args_DEFAULT}" STREQUAL "") 35 | message(FATAL_ERROR "Property '${property_name}' in '${namespace}' invalid!!!") 36 | else() 37 | set("${return_value}" "${parsed_args_DEFAULT}" PARENT_SCOPE) 38 | endif() 39 | else() 40 | set("${return_value}" "${${namespace}.${property_name}}" PARENT_SCOPE) 41 | endif() 42 | 43 | endfunction() 44 | 45 | function(properties_set_value namespace prop value) 46 | if (NOT DEFINED "${namespace}.${prop}") 47 | LIST(APPEND "${namespace}/list" "${prop}") 48 | set("${namespace}/list" "${${namespace}/list}" PARENT_SCOPE) 49 | endif() 50 | # message("${namespace}:${prop}:${value}") 51 | set("${namespace}.${prop}" "${value}" PARENT_SCOPE) 52 | endfunction() 53 | 54 | function(properties_get_list namespace pattern return_list) 55 | set(_prop_list "${${namespace}/list}") 56 | list_filter_include_regex(_prop_list "${pattern}") 57 | set("${return_list}" "${_prop_list}" PARENT_SCOPE) 58 | endfunction() 59 | 60 | function(properties_resolve_value value return_value namespace) 61 | 62 | set(_expanded_prop_list) 63 | _properties_expand_value("${value}" _result_value "${namespace}" 64 | _expanded_prop_list) 65 | set("${return_value}" "${_result_value}" PARENT_SCOPE) 66 | foreach(_prop IN LISTS _expanded_prop_list) 67 | set("${namespace}.${_prop}" "${${namespace}.${_prop}}" PARENT_SCOPE) 68 | endforeach() 69 | 70 | endfunction() 71 | 72 | function(properties_resolve_all_values namespace) 73 | set(_prop_list "${${namespace}/list}") 74 | set(_expanded_prop_list) 75 | foreach(_prop IN LISTS _prop_list) 76 | list(APPEND _expanded_prop_list ${_prop}) 77 | # message("Resolve *** ${_prop} *** : ${${namespace}.${_prop}}") 78 | _properties_expand_value("${${namespace}.${_prop}}" _resolved_value "${namespace}" 79 | _expanded_prop_list) 80 | set("${namespace}.${_prop}" "${_resolved_value}") 81 | # message("EXPANDED ${_prop}: ${${namespace}.${_prop}}") 82 | endforeach() 83 | foreach(_prop IN LISTS _expanded_prop_list) 84 | set("${namespace}.${_prop}" "${${namespace}.${_prop}}" PARENT_SCOPE) 85 | endforeach() 86 | endfunction() 87 | 88 | function(properties_print_all namespace) 89 | set(_prop_list "${${namespace}/list}") 90 | foreach(_prop IN LISTS _prop_list) 91 | message("${_prop}=${${namespace}.${_prop}}") 92 | endforeach() 93 | endfunction() 94 | 95 | macro(properties_set_parent_scope namespace) 96 | set(_prop_list "${${namespace}/list}") 97 | foreach(_prop IN LISTS _prop_list) 98 | set("${namespace}.${_prop}" "${${namespace}.${_prop}}" PARENT_SCOPE) 99 | endforeach() 100 | set("${namespace}/list" "${${namespace}/list}" PARENT_SCOPE) 101 | endmacro() 102 | 103 | function(properties_resolve_value_env value ret_value 104 | ret_req_var_list ret_opt_var_list ret_all_resolved) 105 | 106 | string(REGEX MATCHALL "{([^}]+)}" var_list "${value}") 107 | list(REMOVE_DUPLICATES var_list) 108 | set(_ret_req_var_list) 109 | set(_ret_opt_var_list) 110 | set(_ret_all_resolved 1) 111 | 112 | if (var_list) 113 | foreach(var_str IN LISTS var_list) 114 | string(REGEX MATCH "{([^}]+)}" match "${var_str}") 115 | set(var_name "${CMAKE_MATCH_1}") 116 | string(MAKE_C_IDENTIFIER "${var_name}" var_id) 117 | string(TOUPPER "${var_id}" var_id) 118 | if (NOT DEFINED "${var_id}") 119 | list(APPEND _ret_req_var_list "${var_name}") 120 | if (NOT DEFINED ENV{${var_id}}) 121 | set(_ret_all_resolved 0) 122 | continue() 123 | else() 124 | set(var_value "$ENV{${var_id}}") 125 | endif() 126 | else() 127 | list(APPEND _ret_opt_var_list "${var_name}") 128 | if (NOT DEFINED ENV{${var_id}}) 129 | set(var_value "${${var_id}}") 130 | else() 131 | set(var_value "$ENV{${var_id}}") 132 | endif() 133 | endif() 134 | string(REPLACE "${var_str}" "${var_value}" value "${value}") 135 | endforeach() 136 | endif() 137 | 138 | set("${ret_value}" "${value}" PARENT_SCOPE) 139 | set("${ret_req_var_list}" "${_ret_req_var_list}" PARENT_SCOPE) 140 | set("${ret_opt_var_list}" "${_ret_opt_var_list}" PARENT_SCOPE) 141 | set("${ret_all_resolved}" "${_ret_all_resolved}" PARENT_SCOPE) 142 | 143 | endfunction() 144 | 145 | macro(_properties_parse content namespace) 146 | 147 | set(_last_property) 148 | foreach (_property IN LISTS "${content}") 149 | 150 | string(REGEX MATCH "^([^#=]+)=([^#]*)" match "${_property}") 151 | if (NOT match) 152 | # May be part of last string (Because CMake omits binary and splits 153 | # as list element 154 | string(REGEX MATCH "^([^#]+)" match "${_property}") 155 | if ("${match}" STREQUAL "") 156 | continue() 157 | endif() 158 | 159 | string(STRIP "${CMAKE_MATCH_1}" _last_part) 160 | set(_last_property "${_last_property}${_last_part}" ) 161 | string(REGEX MATCH "^([^#=]+)=([^#]*)" match "${_last_property}") 162 | if (NOT match) 163 | continue() 164 | endif() 165 | set(_property "${_last_property}" ) 166 | endif() 167 | 168 | set(_property_name "${CMAKE_MATCH_1}") 169 | set(_property_value "${CMAKE_MATCH_2}") 170 | 171 | if (NOT DEFINED "${namespace}.${_property_name}") 172 | LIST(APPEND "${namespace}/list" "${_property_name}") 173 | endif() 174 | 175 | set("${namespace}.${_property_name}" "${_property_value}") 176 | set("${namespace}.${_property_name}" "${_property_value}" PARENT_SCOPE) 177 | 178 | set(_last_property "${_property}") 179 | endforeach() 180 | 181 | endmacro() 182 | 183 | function(_properties_expand_value value return_value namespace 184 | expanded_prop_list) 185 | 186 | set(_value "${value}") 187 | 188 | # Don't resolve empty values - There's nothing to resolve 189 | if ("${_value}" STREQUAL "") 190 | set("${return_value}" "" PARENT_SCOPE) 191 | return() 192 | endif () 193 | 194 | set(_result_value "") 195 | while(TRUE) 196 | string(FIND "${_value}" "{" var_start_pos) 197 | string(SUBSTRING "${_value}" 0 ${var_start_pos} val_prefix) 198 | string_append(_result_value "${val_prefix}") 199 | if (var_start_pos EQUAL -1) 200 | break() 201 | ENDIF() 202 | math(EXPR var_start_pos "${var_start_pos} + 1") 203 | string(SUBSTRING "${_value}" ${var_start_pos} -1 val_suffix) 204 | string(FIND "${val_suffix}" "}" var_end_pos) 205 | if (var_end_pos EQUAL -1) 206 | string_append(_result_value "{${val_suffix}") 207 | break() 208 | ENDIF() 209 | string(SUBSTRING "${val_suffix}" 0 ${var_end_pos} var_name) 210 | if (DEFINED "${namespace}.${var_name}") 211 | list(FIND "${expanded_prop_list}" "${var_name}" _found_idx) 212 | if ("${_found_idx}" EQUAL -1) 213 | list(APPEND "${expanded_prop_list}" "${var_name}") 214 | # message("=> Resolve *** ${var_name} *** : ${${namespace}.${var_name}}") 215 | _properties_expand_value("${${namespace}.${var_name}}" 216 | _var_value "${namespace}" "${expanded_prop_list}") 217 | set("${namespace}.${var_name}" "${_var_value}") 218 | # message("=> EXPANDED ${var_name}: ${_var_value}") 219 | string_append(_result_value "${_var_value}") 220 | else() 221 | string_append(_result_value "${${namespace}.${var_name}}") 222 | endif() 223 | else() 224 | string_append(_result_value "{${var_name}}") 225 | endif() 226 | math(EXPR var_end_pos "${var_end_pos} + 1") 227 | string(SUBSTRING "${val_suffix}" ${var_end_pos} -1 _value) 228 | endwhile() 229 | 230 | set("${expanded_prop_list}" "${${expanded_prop_list}}" PARENT_SCOPE) 231 | foreach(_prop IN LISTS ${expanded_prop_list}) 232 | set("${namespace}.${_prop}" "${${namespace}.${_prop}}" PARENT_SCOPE) 233 | endforeach() 234 | set("${return_value}" "${_result_value}" PARENT_SCOPE) 235 | 236 | endfunction() 237 | 238 | -------------------------------------------------------------------------------- /cmake/Arduino/Utilities/SourceDependency.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | # Copyright (c) 2018 Arduino CMake 3 | 4 | # Note: Much of this code copied from Arduino-CMake-NG project and modified 5 | # Thanks to the contributers of the project 6 | 7 | # No need to include this recursively 8 | if(_SOURCE_DEPENDENCY_INCLUDED) 9 | return() 10 | endif() 11 | set(_SOURCE_DEPENDENCY_INCLUDED TRUE) 12 | 13 | set(ARDUINO_CMAKE_HEADER_FILES_SUFFIX_REGEX "(\\.[hH]|\\.[hH][hH]|\\.[hH][pP][pP]|\\.[hH][xX][xX])" CACHE STRING 14 | "Header Files suffix used for regular expression") 15 | set(ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN "^[ \t]*#[ \t]*include[ \t]*[<\"]" CACHE STRING 16 | "Regex pattern matching header inclusion in a source file") 17 | set(ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN 18 | "${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}(.+)${ARDUINO_CMAKE_HEADER_FILES_SUFFIX_REGEX}[>\"]$" CACHE STRING 19 | "Regex pattern matching a header's name when wrapped in inclusion line") 20 | 21 | include(CMakeParseArguments) 22 | include(Arduino/Utilities/CommonUtils) 23 | 24 | #=============================================================================# 25 | # Retrieves all headers includedby a source file. 26 | # Headers are returned by their name, with extension (such as '.h'). 27 | # _source_file - Path to a source file to get its' included headers. 28 | # _return_var - Name of variable in parent-scope holding the return value. 29 | # Returns - List of headers names with extension that are included by the given source file. 30 | #=============================================================================# 31 | function(get_source_file_included_headers _source_file _return_var) 32 | 33 | if (NOT EXISTS "${_source_file}") 34 | message(SEND_ERROR "Can't find '#includes', source file doesn't exist: ${_source_file}") 35 | return() 36 | endif () 37 | 38 | file(STRINGS "${_source_file}" source_lines) # Loc = Lines of code 39 | 40 | list_filter_include_regex(source_lines ${ARDUINO_CMAKE_HEADER_INCLUDE_REGEX_PATTERN}) 41 | 42 | # Extract header names from inclusion 43 | foreach (loc ${source_lines}) 44 | 45 | string(REGEX MATCH ${ARDUINO_CMAKE_HEADER_NAME_REGEX_PATTERN} match ${loc}) 46 | 47 | #get_filename_component(header_name "${CMAKE_MATCH_1}" NAME_WE) 48 | set(header_name "${CMAKE_MATCH_1}") 49 | list(APPEND headers ${header_name}) 50 | 51 | endforeach () 52 | 53 | if (headers) 54 | list(REMOVE_DUPLICATES headers) 55 | endif() 56 | set(${_return_var} ${headers} PARENT_SCOPE) 57 | 58 | endfunction() 59 | 60 | -------------------------------------------------------------------------------- /cmake/Arduino/Utilities/SourceLocator.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2020 Arduino CMake Toolchain 2 | # Copyright (c) 2018 Arduino CMake 3 | 4 | # Note: Much of this code copied from Arduino-CMake-NG project and modified 5 | # Thanks to the contributers of the project 6 | 7 | # No need to include this recursively 8 | if(_SOURCE_LOCATOR_INCLUDED) 9 | return() 10 | endif() 11 | set(_SOURCE_LOCATOR_INCLUDED TRUE) 12 | 13 | set(ARDUINO_CMAKE_C_FILES_PATTERN *.c CACHE STRING 14 | "C Source Files Pattern") 15 | set(ARDUINO_CMAKE_CXX_FILES_PATTERN *.cc *.cpp *.cxx CACHE STRING 16 | "CXX Source Files Pattern") 17 | set(ARDUINO_CMAKE_ASM_FILES_PATTERN *.[sS] CACHE STRING 18 | "ASM Source Files Pattern") 19 | set(ARDUINO_CMAKE_HEADER_FILES_PATTERN *.h *.hh *.hpp *.hxx CACHE STRING 20 | "Header Files Pattern") 21 | set(ARDUINO_CMAKE_SKETCH_FILES_PATTERN *.ino *.pde CACHE STRING 22 | "Sketch Files Pattern") 23 | set(ARDUINO_CMAKE_HEADER_FILE_EXTENSION_REGEX_PATTERN ".+\\.h.*$" CACHE STRING 24 | "Regex pattern matching all header file extensions") 25 | 26 | include(CMakeParseArguments) 27 | include(Arduino/Utilities/CommonUtils) 28 | 29 | #=============================================================================# 30 | # Finds source files matching the given pattern under the given path. 31 | # Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. 32 | # _base_path - Top-Directory path to search source files in. 33 | # [RECURSE] - Whether search should be done recursively or not. 34 | # _return_var - Name of variable in parent-scope holding the return value. 35 | # Returns - List of sources in the given path 36 | #=============================================================================# 37 | function(_find_sources _base_path _pattern _return_var) 38 | 39 | cmake_parse_arguments(source_file_search "RECURSE" "" "" ${ARGN}) 40 | 41 | # message("Find in ${_base_path}:${_pattern}") 42 | 43 | # Adapt the source files pattern to the given base dir 44 | set(current_pattern "") 45 | foreach (pattern_part ${_pattern}) 46 | list(APPEND current_pattern "${_base_path}/${pattern_part}") 47 | endforeach () 48 | 49 | if (${source_file_search_RECURSE}) 50 | file(GLOB_RECURSE source_files LIST_DIRECTORIES FALSE ${current_pattern}) 51 | else () 52 | file(GLOB source_files LIST_DIRECTORIES FALSE ${current_pattern}) 53 | endif () 54 | 55 | set(${_return_var} "${source_files}" PARENT_SCOPE) 56 | # message("Found ${source_files}") 57 | 58 | endfunction() 59 | 60 | #=============================================================================# 61 | # Finds header files matching the pre-defined header-file pattern under the given path. 62 | # This functions searchs explicitly for header-files such as '*.h'. 63 | # Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. 64 | # _base_path - Top-Directory path to search source files in. 65 | # [RECURSE] - Whether search should be done recursively or not. 66 | # _return_var - Name of variable in parent-scope holding the return value. 67 | # Returns - List of header files in the given path 68 | #=============================================================================# 69 | function(find_header_files _base_path _return_var) 70 | 71 | _find_sources("${_base_path}" "${ARDUINO_CMAKE_HEADER_FILES_PATTERN}" headers ${ARGN}) 72 | set(${_return_var} "${headers}" PARENT_SCOPE) 73 | 74 | endfunction() 75 | 76 | #=============================================================================# 77 | # Finds source files matching the pre-defined source-file pattern under the given path. 78 | # This functions searchs explicitly for source-files such as '*.c'. 79 | # Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. 80 | # _base_path - Top-Directory path to search source files in. 81 | # [RECURSE] - Whether search should be done recursively or not. 82 | # _return_var - Name of variable in parent-scope holding the return value. 83 | # Returns - List of source files in the given path 84 | #=============================================================================# 85 | function(find_source_files _base_path _return_var) 86 | 87 | _find_sources("${_base_path}" "${ARDUINO_CMAKE_C_FILES_PATTERN}" sources ${ARGN}) 88 | if (sources) 89 | list(APPEND all_sources "${sources}") 90 | enable_language(C) 91 | endif() 92 | _find_sources("${_base_path}" "${ARDUINO_CMAKE_CXX_FILES_PATTERN}" sources ${ARGN}) 93 | if (sources) 94 | list(APPEND all_sources "${sources}") 95 | enable_language(CXX) 96 | endif() 97 | _find_sources("${_base_path}" "${ARDUINO_CMAKE_ASM_FILES_PATTERN}" sources ${ARGN}) 98 | if (sources) 99 | list(APPEND all_sources "${sources}") 100 | enable_language(ASM) 101 | endif() 102 | 103 | set(${_return_var} "${all_sources}" PARENT_SCOPE) 104 | 105 | endfunction() 106 | 107 | #=============================================================================# 108 | # Finds sketch files matching the pre-defined sketch-file pattern under the given path. 109 | # This functions searchs explicitly for sketch-files such as '*.ino'. 110 | # Search could also be recursive (With sub-directories) if the optional 'RECURSE' option is passed. 111 | # _base_path - Top-Directory path to search source files in. 112 | # [RECURSE] - Whether search should be done recursively or not. 113 | # _return_var - Name of variable in parent-scope holding the return value. 114 | # Returns - List of header files in the given path 115 | #=============================================================================# 116 | function(find_sketch_files _base_path _return_var) 117 | 118 | _find_sources("${_base_path}" "${ARDUINO_CMAKE_SKETCH_FILES_PATTERN}" sketches ${ARGN}) 119 | set(${_return_var} "${sketches}" PARENT_SCOPE) 120 | 121 | endfunction() 122 | 123 | #=============================================================================# 124 | # Gets paths of parent directories from all header files amongst the given sources. 125 | # The list of paths is unique (without duplicates). 126 | # _sources - List of sources to get include directories from. 127 | # _return_var - Name of variable in parent-scope holding the return value. 128 | # Returns - List of directories representing the parent directories of all given headers. 129 | #=============================================================================# 130 | function(get_headers_parent_directories _sources _return_var) 131 | 132 | # Extract header files 133 | list_filter_include_regex(_sources "${ARDUINO_CMAKE_HEADER_FILE_EXTENSION_REGEX_PATTERN}") 134 | 135 | foreach (header_source ${_sources}) 136 | 137 | get_filename_component(header_parent_dir ${header_source} DIRECTORY) 138 | 139 | list(APPEND parent_dirs ${header_parent_dir}) 140 | 141 | endforeach () 142 | 143 | if (parent_dirs) # Check parent dirs, could be none if there aren't any headers amongst sources 144 | list(REMOVE_DUPLICATES parent_dirs) 145 | endif () 146 | 147 | set(${_return_var} ${parent_dirs} PARENT_SCOPE) 148 | 149 | endfunction() 150 | 151 | 152 | #=============================================================================# 153 | # Recursively finds header files under the given path, excluding those that don't belong to a library, 154 | # such as files under the 'exmaples' directory (In case sources reside under lib's root directory). 155 | # _base_path - Top-Directory path to search source files in. 156 | # _return_var - Name of variable in parent-scope holding the return value. 157 | # Returns - List of source files in the given path 158 | #=============================================================================# 159 | function(find_library_header_files _base_path _return_var) 160 | 161 | if (EXISTS "${_base_path}/src") # 'src' sub-dir exists and should contain sources 162 | 163 | # Headers are always searched recursively under the 'src' sub-dir 164 | find_header_files("${_base_path}/src" headers RECURSE) 165 | 166 | else () 167 | 168 | # Both root-dir and 'utility' sub-dir are searched when 'src' doesn't exist 169 | find_header_files("${_base_path}" root_headers) 170 | find_header_files("${_base_path}/utility" utility_headers) 171 | 172 | set(headers ${root_headers} ${utility_headers}) 173 | 174 | endif () 175 | 176 | set(${_return_var} "${headers}" PARENT_SCOPE) 177 | 178 | endfunction() 179 | 180 | #=============================================================================# 181 | # Recursively finds source files under the given path, excluding those that don't belong to a library, 182 | # such as files under the 'exmaples' directory (In case sources reside under lib's root directory). 183 | # _base_path - Top-Directory path to search source files in. 184 | # _return_var - Name of variable in parent-scope holding the return value. 185 | # Returns - List of source files in the given path 186 | #=============================================================================# 187 | function(find_library_source_files _base_path _return_var) 188 | 189 | if (EXISTS "${_base_path}/src") 190 | 191 | # Sources are always searched recursively under the 'src' sub-dir 192 | find_source_files("${_base_path}/src" sources RECURSE) 193 | 194 | else () 195 | 196 | # Both root-dir and 'utility' sub-dir are searched when 'src' doesn't exist 197 | find_source_files("${_base_path}" root_sources) 198 | find_source_files("${_base_path}/utility" utility_sources) 199 | 200 | set(sources ${root_sources} ${utility_sources}) 201 | 202 | endif () 203 | 204 | set(${_return_var} "${sources}" PARENT_SCOPE) 205 | 206 | endfunction() 207 | -------------------------------------------------------------------------------- /cmake/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## Version 1.0 4 | 5 | Initial version 6 | 7 | ### Features 8 | 9 | * CMake Arduino toolchain (passed to CMake using `-D CMAKE_TOOLCHAIN_FILE=/path/to/Arduino-toolchain.cmake)` 10 | * Support for all Arduino compatible platforms (such as **AVR**, **ESP32**, etc.) 11 | * Generic CMake scripting interface without requiring Arduino specific functions 12 | * Arduino IDE compatible build (e.g. use of build rules and flags in board.local.txt, pre/postbuild hooks etc.) 13 | * Selection of board and board-specific menu options as in Arduino IDE tools menu (See `ARDUINO_BOARD_OPTIONS_FILE`) 14 | * Generate Arduino HEX binaries and upload to Arduino boards (See `target_enable_arduino_upload`) 15 | * Upload using serial port 16 | * Remote provisioning through network 17 | * Upload using programmer 18 | * Burn bootloader 19 | * Support linking with Arduino libraries (see `target_link_arduino_libraries`) 20 | * Arduino *native* libraries (e.g. Ethernet, Wire) 21 | * User installed 3rd Party Arduino libraries (e.g. IRremote) 22 | * Project specific Arduino libraries (those present in `/libraries`) 23 | * Support for automatic dependency resolution (Arduino IDE like, but unprofessional) 24 | -------------------------------------------------------------------------------- /cmake/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Arduino CMake Toolchain 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cmake/Platform/Arduino-Determine.cmake: -------------------------------------------------------------------------------- 1 | set(_ARDUINO_DETERMINE_INCLUDED 1) 2 | if (NOT ARDUINO_BOARD_IDENTIFIER) 3 | message(FATAL_ERROR 4 | "\nPlease select a valid arduino board and its menu options using one of the below methods.\n" 5 | "1. From CMake GUI\n" 6 | "2. From the generated BoardOptions.cmake at ${CMAKE_BINARY_DIR}/BoardOptions.cmake\n" 7 | "3. Use yor own preset BoardOptions.cmake -DARDUINO_BOARD_OPTIONS_FILE=\n" 8 | "4. Use -DARDUINO_BOARD= and -DARDUINO__MENU__=!!!\n" 9 | ) 10 | endif() 11 | 12 | -------------------------------------------------------------------------------- /cmake/Platform/Arduino.cmake: -------------------------------------------------------------------------------- 1 | # ASM does not pass -I for include directories 2 | set(CMAKE_INCLUDE_FLAG_ASM "-I") 3 | 4 | # Set the suffix to match the target executable name 5 | set(CMAKE_EXECUTABLE_SUFFIX ".elf") 6 | 7 | # If we do not set to .o, some linker scripts aren't working correctly 8 | set(CMAKE_C_OUTPUT_EXTENSION ".o") 9 | set(CMAKE_CXX_OUTPUT_EXTENSION ".o") 10 | set(CMAKE_ASM_OUTPUT_EXTENSION ".o") 11 | 12 | # Where is the target environment 13 | # Add all tools paths and include paths?, tools/sdk in platform path? 14 | # message("ARDUINO_FIND_ROOT_PATH:${ARDUINO_FIND_ROOT_PATH}") 15 | set(CMAKE_FIND_ROOT_PATH ${ARDUINO_FIND_ROOT_PATH}) 16 | 17 | set(CMAKE_SYSTEM_INCLUDE_PATH "/include") 18 | set(CMAKE_SYSTEM_LIBRARY_PATH "/lib") 19 | # message("ARDUINO_SYSTEM_PROGRAM_PATH:${ARDUINO_SYSTEM_PROGRAM_PATH}") 20 | set(CMAKE_SYSTEM_PROGRAM_PATH ${ARDUINO_SYSTEM_PROGRAM_PATH}) 21 | 22 | -------------------------------------------------------------------------------- /cmake/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /docs/README_breadboard.md: -------------------------------------------------------------------------------- 1 | # Default configuration with Nokia 5510 Display (PCD8544) 2 | 3 | ## Arduino Pinout 4 | in config.h check ```HARDWARE_REV 21``` 5 | All options are left to default values, else you have to change the connections 6 | 7 | ### A14: Voltage read-Pin 8 | Leave it open, it will read some random values... 9 | 10 | ### 38: FET: Pull high to switch off 11 | Add an LED with Resistor (~470Ω) to GND 12 | 13 | ### A15: Current read-Pin 14 | Leave it open, it will read some random values... 15 | 16 | ### 11: Buzzer 17 | Connect buzzer with resistor (~200Ω) to GND 18 | 19 | ### 37: Switch 20 | Connect a push switch to GND 21 | 22 | ### 12: Switch 2 23 | Connect a push switch to GND 24 | 25 | ## Nokia 5510 Display (PCD8544) 26 | Connect Display pin -> To arduino Pin 27 | The Display only supports 3.3V, use a level shifter for I/O Pins! 28 | ``` 29 | LED+ -> 3.3V 30 | VCC -> 3.3V 31 | GND -> GND 32 | 33 | sclk -> 7 [PH4] (clock) 34 | sdin -> 17 [PH0] (data-in) 35 | dc -> 16 [PH1] (data select) 36 | reset -> 6 [PH3] 37 | sce -> 8 [PH5] (enable)** 38 | ``` 39 | 40 | SCE is connected to PH2, but PH2 is not connected on the Arduino, so change the line 41 | ```cpp 42 | unsigned char sce = 2); /* enable (display pin 5) */ 43 | ``` 44 | to 45 | ```cpp 46 | unsigned char sce = 5); /* enable (display pin 5) */ 47 | ``` 48 | 49 | ### Serial Port 50 | You get all information on the Serial port to Debug 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /docs/README_cmake.txt: -------------------------------------------------------------------------------- 1 | If you like more control over the build process 2 | than the Java based Arduino UI provides, 3 | the CMAKE based build system is for you. 4 | 5 | It invokes avr-gcc and avrdude directly. 6 | 7 | Note: Linux only for now. Windows support is untested. 8 | 9 | 1. Setup: Create a build directory 10 | 11 | mkdir build 12 | cd build 13 | cmake ../ 14 | 15 | Most likely you will have to give the Arduino install path: 16 | cmake -DARDUINO_INSTALL_PATH=/tmp ../ 17 | 18 | If you have a FC before 2.x and the Arduino Nano uses 19 | the old bootloader (57600 baud), use this option: 20 | 21 | cmake cmake -DARDUINO_INSTALL_PATH=/tmp -DOLD_BOOTLOADER=ON ../ 22 | 23 | 2. Compile 24 | 25 | cd build 26 | make 27 | 28 | 3. Upload 29 | 30 | cd build 31 | make upload-pcontroller SERIAL_PORT=/dev/ttyUSB0 32 | -------------------------------------------------------------------------------- /docs/README_hacking.txt: -------------------------------------------------------------------------------- 1 | *** Determine code size (linux only) *** 2 | nm --demangle --print-size --size-sort --reverse-sort -t d pcontroller.elf |less 3 | 4 | *** Interactive serial interface on linux *** 5 | socat - /dev/ttyUSB0,b115200,echo=0 6 | -------------------------------------------------------------------------------- /docs/README_menu.txt: -------------------------------------------------------------------------------- 1 | If you press display button 2 for a long time, 2 | you'll enter the on-the-go menu. 3 | 4 | Use display button 1 to go up, button 2 to go down. 5 | A long press of button 1 or button 2 will activate the current item. 6 | 7 | The menu closes automatically after selecting an item. 8 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Arduino-Pedelec-Controller 2 | Software for the Pedelec/E-Bike controller based on Arduino hardware, see www.pedelecforum.de "ForumsController" 3 | 4 | ## Board Pinout / Connections 5 | http://www.pedelecforum.de/wiki/doku.php?id=elektrotechnik:forumscontroller 6 | 7 | ## Documents 8 | * [Breadboard configuration](docs/README_breadboard.md) 9 | * [CMake](docs/README_cmake.txt) 10 | * [Hacking](docs/README_hacking.txt) 11 | * [Menu](docs/README_menu.txt) 12 | 13 | ## Code build status 14 | [![Build Status](https://travis-ci.org/jenkie/Arduino-Pedelec-Controller.svg?branch=master)](https://travis-ci.org/jenkie/Arduino-Pedelec-Controller) 15 | -------------------------------------------------------------------------------- /tools/code_reformat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # "astyle" tool used to reformat the 3 | # source code to a common base 4 | # TODO: Windows version 5 | /usr/bin/astyle --indent=spaces=4 --indent-switches --brackets=break \ 6 | --convert-tabs --keep-one-line-statements --keep-one-line-blocks \ 7 | $* 8 | --------------------------------------------------------------------------------