├── .cproject
├── .gitattributes
├── .gitignore
├── .project.copy
├── BatteryManager.cpp
├── BatteryManager.h
├── BrusaMotorController.cpp
├── BrusaMotorController.h
├── CMakeLists.txt
├── CanBrake.cpp
├── CanBrake.h
├── CanHandler.cpp
├── CanHandler.h
├── CanPIDListener.cpp
├── CanPIDListener.h
├── CanThrottle.cpp
├── CanThrottle.h
├── CodaMotorController.cpp
├── CodaMotorController.h
├── DCDCController.cpp
├── DCDCController.h
├── DMOC.txt
├── Device.cpp
├── Device.h
├── DeviceManager.cpp
├── DeviceManager.h
├── DeviceTypes.h
├── DmocMotorController.cpp
├── DmocMotorController.h
├── ELM327Processor.cpp
├── ELM327Processor.h
├── ELM327_Emu.cpp
├── ELM327_Emu.h
├── EVIC.cpp
├── EVIC.h
├── FaultCodes.h
├── FaultHandler.cpp
├── FaultHandler.h
├── GEVCU.h
├── GEVCU.ino
├── GEVCU.kdev4
├── GEVCU.sln
├── GEVCU.vcxproj
├── GEVCU.vcxproj.filters
├── Heartbeat.cpp
├── Heartbeat.h
├── Logger.cpp
├── Logger.h
├── MemCache.cpp
├── MemCache.h
├── MotorController.cpp
├── MotorController.h
├── OBD2Handler.cpp
├── OBD2Handler.h
├── PotBrake.cpp
├── PotBrake.h
├── PotThrottle.cpp
├── PotThrottle.h
├── PrefHandler.cpp
├── PrefHandler.h
├── README.md
├── SerialConsole.cpp
├── SerialConsole.h
├── Shield
├── Ampseal.lbr
├── Analog_Board.brd
├── Analog_Board.sch
├── Analog_Shield.brd
├── Analog_Shield.sch
├── Canbus-Proto.brd
├── Canbus-Proto.sch
├── Canbus-proto2.brd
├── Eagle_Dued_autorouted.brd
├── Eagle_Dued_autorouted.sch
├── GEVCU-4.brd
├── GEVCU-4.sch
├── canbus-proto2.sch
├── ck_custom.lbr
└── dc-dc-converter.lbr
├── Sys_Messages.h
├── ThinkBatteryManager.cpp
├── ThinkBatteryManager.h
├── Throttle.cpp
├── Throttle.h
├── ThrottleDetector.cpp
├── ThrottleDetector.h
├── TickHandler.cpp
├── TickHandler.h
├── config.h
├── constants.h
├── docs
├── Design Drawings.vsd
├── GEVCU pinout.txt
├── GEVCU-35pinout.jpg
├── GEVCU1-1.03.docx
├── ThrottleFiltering.xlsx
├── UQMplug.jpg
├── gevcumanual403.docx
└── howtocreatemodule.docx
├── eeprom_layout.h
├── gearsandopstates.txt
├── ichip_2128.cpp
├── ichip_2128.h
├── readme.eclipse.txt
├── sys_io.cpp
├── sys_io.h
├── util
├── BBESAB0801.IMF
├── MultiSerial
│ └── MultiSerial.ino
├── connectTOap
│ └── connectTOap.ino
├── connectasAP
│ └── connectasAP.ino
├── connectsetup
│ └── connectsetup.ino
├── i2128d810d35BCOM.IMF
└── i2128d810d35BCOM.IMZ
├── website
├── README.txt
├── src
│ ├── about.htm
│ ├── annunciator.htm
│ ├── annunciator.js
│ ├── config.htm
│ ├── config.xml
│ ├── control.js
│ ├── dashboard.htm
│ ├── dashboard.xml
│ ├── devices.htm
│ ├── devices.xml
│ ├── fonts
│ │ ├── digital-7-mono.eot
│ │ └── digital-7-mono.ttf
│ ├── gauge.js
│ ├── gauges.js
│ ├── index.htm
│ ├── inputs.htm
│ ├── inputs.xml
│ ├── outputs.htm
│ ├── outputs.xml
│ ├── status.htm
│ ├── status.xml
│ ├── styles.css
│ └── throttleSettingsCanvas.js
└── website.img
└── workinprogress.txt
/.cproject:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
29 |
30 |
31 |
32 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set default behaviour, in case users don't have core.autocrlf set.
2 | * text=auto
3 |
4 | # Explicitly declare text files we want to always be normalized and converted
5 | # to native line endings on checkout.
6 | *.c text
7 | *.h text
8 | *.cpp text
9 | *.ino text
10 | *.txt text
11 | *.brd text
12 | *.sch text
13 |
14 | # Declare files that will always have CRLF line endings on checkout.
15 | *.sln text eol=crlf
16 | *.vcxproj eol=crlf
17 |
18 | # Denote all files that are truly binary and should not be modified.
19 | *.png binary
20 | *.jpg binary
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build and Release Folders
2 | bin/
3 | bin-debug/
4 | bin-release/
5 |
6 | # Other files and folders
7 | .settings/
8 | arduino
9 | Libraries
10 | Release
11 | .project
12 |
13 | # Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
14 | # should NOT be excluded as they contain compiler settings and other important
15 | # information for Eclipse / Flash Builder.
16 | *.d
17 | *.eep
18 | *.o
19 | *.lss
20 | *.elf
21 | *.map
22 | *.srec
23 | *.vcx*
24 |
--------------------------------------------------------------------------------
/.project.copy:
--------------------------------------------------------------------------------
1 |
2 |
3 | GEVCU
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder
10 | clean,full,incremental,
11 |
12 |
13 |
14 |
15 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
16 | full,incremental,
17 |
18 |
19 |
20 |
21 |
22 | org.eclipse.cdt.core.cnature
23 | org.eclipse.cdt.core.ccnature
24 | org.eclipse.cdt.managedbuilder.core.managedBuildNature
25 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
26 | it.baeyens.arduinonature
27 |
28 |
29 |
30 | Libraries/DueTimer
31 | 2
32 | ArduinoPivateLibPath/DueTimer
33 |
34 |
35 | Libraries/due_can
36 | 2
37 | ArduinoPivateLibPath/due_can
38 |
39 |
40 | Libraries/due_rtc
41 | 2
42 | ArduinoPivateLibPath/due_rtc
43 |
44 |
45 | Libraries/due_wire
46 | 2
47 | ArduinoPivateLibPath/due_wire
48 |
49 |
50 | arduino/core
51 | 2
52 | ArduinoPlatformPath/cores/arduino
53 |
54 |
55 | arduino/variant
56 | 2
57 | ArduinoPinPath/arduino_due_x
58 |
59 |
60 |
61 |
62 | ArduinoHardwareLibPath
63 | file:/Z:/development/arduino/arduino-1.5.2_win_32bit/hardware/arduino/sam/libraries
64 |
65 |
66 | ArduinoPinPath
67 | file:/Z:/development/arduino/arduino-1.5.2_win_32bit/hardware/arduino/sam/variants
68 |
69 |
70 | ArduinoPlatformPath
71 | file:/Z:/development/arduino/arduino-1.5.2_win_32bit/hardware/arduino/sam
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/BatteryManager.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * BatteryManager.cpp
3 | *
4 | * Parent class for all battery management/monitoring systems
5 | *
6 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 | #include "BatteryManager.h"
30 |
31 | BatteryManager::BatteryManager() : Device()
32 | {
33 | packVoltage = 0;
34 | packCurrent = 0;
35 | }
36 |
37 | BatteryManager::~BatteryManager()
38 | {
39 | }
40 |
41 | DeviceType BatteryManager::getType() {
42 | return (DEVICE_BMS);
43 | }
44 |
45 | void BatteryManager::handleTick() {
46 | }
47 |
48 | void BatteryManager::setup() {
49 | #ifndef USE_HARD_CODED
50 | if (prefsHandler->checksumValid()) { //checksum is good, read in the values stored in EEPROM
51 | }
52 | else { //checksum invalid. Reinitialize values and store to EEPROM
53 | //prefsHandler->saveChecksum();
54 | }
55 | #else
56 | #endif
57 |
58 | //TickHandler::getInstance()->detach(this);
59 | //TickHandler::getInstance()->attach(this, CFG_TICK_INTERVAL_MOTOR_CONTROLLER_DMOC);
60 |
61 | }
62 |
63 | int BatteryManager::getPackVoltage()
64 | {
65 | return packVoltage;
66 | }
67 |
68 | signed int BatteryManager::getPackCurrent()
69 | {
70 | return packCurrent;
71 | }
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/BatteryManager.h:
--------------------------------------------------------------------------------
1 | /*
2 | * BatteryManager.h
3 | *
4 | * Parent class for battery management / monitoring systems
5 | *
6 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 | #ifndef BATTMANAGE_H_
30 | #define BATTMANAGE_H_
31 |
32 | #include
33 | #include "config.h"
34 | #include "Device.h"
35 |
36 | class BatteryManager : public Device {
37 | public:
38 | BatteryManager();
39 | ~BatteryManager();
40 | int getPackVoltage(); //in tenths of a volt
41 | signed int getPackCurrent(); //in tenths of an amp
42 | //bool allowCharging();
43 | //bool allowDischarging();
44 | DeviceType getType();
45 | void setup();
46 | void handleTick();
47 | //a bunch of boolean functions. Derived classes must implment
48 | //these functions to tell everyone else what they support
49 | virtual bool hasPackVoltage() = 0;
50 | virtual bool hasPackCurrent() = 0;
51 | virtual bool hasTemperatures() = 0;
52 | virtual bool isChargeOK() = 0;
53 | virtual bool isDischargeOK() = 0;
54 | protected:
55 | int packVoltage; //tenths of a volt
56 | signed int packCurrent; //tenths of an amp
57 | int SOC; //state of charge in percent
58 | int lowestCellV, highestCellV; //in mv
59 | int lowestCellTemp, highestCellTemp;
60 | //should be some form of discharge and charge limit. I don't know if it should be % or amps
61 | //some BMS systems will report one way and some the other.
62 | int dischargeLimit, chargeLimit;
63 | bool allowCharge, allowDischarge;
64 |
65 | private:
66 | };
67 |
68 | #endif
69 |
70 |
71 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | project(gevcu)
2 |
3 | add_executable(gevcu main.cpp)
4 |
5 | install(TARGETS gevcu RUNTIME DESTINATION bin)
6 |
--------------------------------------------------------------------------------
/CanBrake.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CanBrake.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef CAN_BRAKE_H_
28 | #define CAN_BRAKE_H_
29 |
30 | #include
31 | #include "config.h"
32 | #include "Throttle.h"
33 | #include "TickHandler.h"
34 | #include "CanHandler.h"
35 | #include "CanThrottle.h"
36 | #include "constants.h"
37 |
38 | class CanBrakeConfiguration : public ThrottleConfiguration {
39 | public:
40 | uint16_t minimumLevel1, maximumLevel1; // values for when the pedal is at its min and max
41 | uint16_t carType; // the type of car, so we know how to interpret which bytes
42 | };
43 |
44 | class CanBrake: public Throttle, CanObserver {
45 | public:
46 | CanBrake();
47 | void setup();
48 | void handleTick();
49 | void handleCanFrame(CAN_FRAME *frame);
50 | DeviceId getId();
51 | DeviceType getType();
52 |
53 | RawSignalData *acquireRawSignal();
54 | void loadConfiguration();
55 | void saveConfiguration();
56 |
57 | protected:
58 | bool validateSignal(RawSignalData *);
59 | uint16_t calculatePedalPosition(RawSignalData *);
60 | int16_t mapPedalPosition(int16_t);
61 |
62 | private:
63 | CAN_FRAME requestFrame; // the request frame sent to the car
64 | RawSignalData rawSignal; // raw signal
65 | uint8_t ticksNoResponse; // number of ticks no response was received
66 | uint32_t responseId; // the CAN id with which the response is sent;
67 | uint32_t responseMask; // the mask for the responseId
68 | bool responseExtended; // if the response is expected as an extended frame
69 | };
70 |
71 | #endif /* CAN_BRAKE_H_ */
72 |
73 |
74 |
--------------------------------------------------------------------------------
/CanHandler.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CanHandler.h
3 |
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef CAN_HANDLER_H_
27 | #define CAN_HANDLER_H_
28 |
29 | #include
30 | #include "config.h"
31 | #include "due_can.h"
32 | #include
33 | #include "variant.h"
34 | #include
35 | #include "Logger.h"
36 | #include "DeviceManager.h"
37 | #include "sys_io.h"
38 |
39 | class Device;
40 |
41 | class CanObserver {
42 | public:
43 | virtual void handleCanFrame(CAN_FRAME *frame);
44 | };
45 |
46 | class CanHandler {
47 | public:
48 | enum CanBusNode {
49 | CAN_BUS_EV, // CAN0 is intended to be connected to the EV bus (controller, charger, etc.)
50 | CAN_BUS_CAR // CAN1 is intended to be connected to the car's high speed bus (the one with the ECU)
51 | };
52 |
53 | void initialize();
54 | void attach(CanObserver *observer, uint32_t id, uint32_t mask, bool extended);
55 | void detach(CanObserver *observer, uint32_t id, uint32_t mask);
56 | void process();
57 | void sendFrame(CAN_FRAME& frame);
58 | void CANIO(CAN_FRAME& frame);
59 | static CanHandler *getInstanceCar();
60 | static CanHandler *getInstanceEV();
61 | protected:
62 |
63 | private:
64 | struct CanObserverData {
65 | uint32_t id; // what id to listen to
66 | uint32_t mask; // the CAN frame mask to listen to
67 | bool extended; // are extended frames expected
68 | uint8_t mailbox; // which mailbox is this observer assigned to
69 | CanObserver *observer; // the observer object (e.g. a device)
70 | };
71 | static CanHandler *canHandlerEV; // singleton reference to the EV instance (CAN0)
72 | static CanHandler *canHandlerCar; // singleton reference to the car instance (CAN1)
73 |
74 | CanBusNode canBusNode; // indicator to which can bus this instance is assigned to
75 | CANRaw *bus; // the can bus instance which this CanHandler instance is assigned to
76 | CanObserverData observerData[CFG_CAN_NUM_OBSERVERS]; // Can observers
77 |
78 | CanHandler(CanBusNode busNumber);
79 | void logFrame(CAN_FRAME& frame);
80 | int8_t findFreeObserverData();
81 | int8_t findFreeMailbox();
82 | };
83 |
84 | #endif /* CAN_HANDLER_H_ */
85 |
86 |
87 |
--------------------------------------------------------------------------------
/CanPIDListener.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CanPidListener.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef CAN_PID_H_
28 | #define CAN_PID_H_
29 |
30 | #include
31 | #include "config.h"
32 | #include "Throttle.h"
33 | #include "DeviceManager.h"
34 | #include "TickHandler.h"
35 | #include "CanHandler.h"
36 | #include "constants.h"
37 |
38 |
39 | class CanPIDConfiguration : public DeviceConfiguration {
40 | public:
41 | uint32_t pidId; //what ID are we listening for?
42 | uint32_t pidMask;
43 | bool useExtended;
44 | };
45 |
46 | class CanPIDListener: public Device, CanObserver {
47 | public:
48 | CanPIDListener();
49 | void setup();
50 | void handleTick();
51 | void handleCanFrame(CAN_FRAME *frame);
52 | DeviceId getId();
53 |
54 | void loadConfiguration();
55 | void saveConfiguration();
56 |
57 | protected:
58 |
59 | private:
60 | uint32_t responseId; // the CAN id with which the response is sent;
61 | uint32_t responseMask; // the mask for the responseId
62 | bool responseExtended; // if the response is expected as an extended frame
63 | bool processShowData(CAN_FRAME* inFrame, CAN_FRAME& outFrame);
64 | bool processShowCustomData(CAN_FRAME* inFrame, CAN_FRAME& outFrame);
65 | };
66 |
67 | #endif //CAN_PID_H_
68 |
69 |
70 |
--------------------------------------------------------------------------------
/CanThrottle.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CanThrottle.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef CAN_THROTTLE_H_
28 | #define CAN_THROTTLE_H_
29 |
30 | #include
31 | #include "config.h"
32 | #include "Throttle.h"
33 | #include "TickHandler.h"
34 | #include "CanHandler.h"
35 | #include "constants.h"
36 | #include "DeviceManager.h"
37 |
38 | enum CanCarType {
39 | unknowkn = 0x00,
40 | Volvo_S80_Gas = 0x01,
41 | Volvo_V50_Diesel = 0x02
42 | };
43 |
44 | class CanThrottleConfiguration : public ThrottleConfiguration {
45 | public:
46 | uint16_t minimumLevel1, maximumLevel1; // values for when the pedal is at its min and max
47 | uint16_t carType; // the type of car, so we know how to interpret which bytes
48 | };
49 |
50 | class CanThrottle: public Throttle, CanObserver {
51 | public:
52 | CanThrottle();
53 | void setup();
54 | void handleTick();
55 | void handleCanFrame(CAN_FRAME *frame);
56 | DeviceId getId();
57 |
58 | RawSignalData *acquireRawSignal();
59 | void loadConfiguration();
60 | void saveConfiguration();
61 |
62 | protected:
63 | bool validateSignal(RawSignalData *);
64 | uint16_t calculatePedalPosition(RawSignalData *);
65 |
66 | private:
67 | CAN_FRAME requestFrame; // the request frame sent to the car
68 | RawSignalData rawSignal; // raw signal
69 | uint8_t ticksNoResponse; // number of ticks no response was received
70 | uint32_t responseId; // the CAN id with which the response is sent;
71 | uint32_t responseMask; // the mask for the responseId
72 | bool responseExtended; // if the response is expected as an extended frame
73 | };
74 |
75 | #endif /* CAN_THROTTLE_H_ */
76 |
77 |
78 |
--------------------------------------------------------------------------------
/CodaMotorController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * CodaMotorController.h
3 | *
4 | * Note that the dmoc needs to have some form of input for gear selector (drive/neutral/reverse)
5 | *
6 | Copyright (c) 2014 Jack Rickard
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 | #ifndef CODA_H_
30 | #define CODA_H_
31 |
32 | #include
33 | #include "config.h"
34 | #include "MotorController.h"
35 | #include "sys_io.h"
36 | #include "TickHandler.h"
37 | #include "CanHandler.h"
38 |
39 | /*
40 | * Class for Coda UQM Powerphase 100 specific configuration parameters
41 | */
42 | class CodaMotorControllerConfiguration : public MotorControllerConfiguration {
43 | public:
44 | };
45 |
46 | class CodaMotorController: public MotorController, CanObserver {
47 |
48 |
49 |
50 | public:
51 | virtual void handleTick();
52 | virtual void handleCanFrame(CAN_FRAME *frame);
53 | virtual void setup();
54 |
55 | CodaMotorController();
56 | void timestamp();
57 | DeviceId getId();
58 | uint32_t getTickInterval();
59 |
60 |
61 | virtual void loadConfiguration();
62 | virtual void saveConfiguration();
63 |
64 | private:
65 | byte online; //counter for whether DMOC appears to be operating
66 | byte alive;
67 | int activityCount;
68 | byte sequence;
69 | uint16_t torqueCommand;
70 | void sendCmd1();
71 | void sendCmd2();
72 | uint8_t genCodaCRC(uint8_t cmd, uint8_t torq_lsb, uint8_t torq_msb);
73 |
74 | };
75 |
76 | #endif /* CODA_H_ */
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/DCDCController.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Delphi DC-DC Converter Controller.cpp
3 | *
4 | * CAN Interface to the Delphi DC-DC converter - Handles sending of commands and reception of status frames to drive the DC-DC converter and set its output voltage. SB following.
5 | *
6 | Copyright (c) 2014 Jack Rickard
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 |
30 |
31 | #include "DCDCController.h"
32 | template inline Print &operator <<(Print &obj, T arg) { obj.print(arg); return obj; }
33 |
34 |
35 |
36 | DCDCController::DCDCController() : Device()
37 | {
38 | prefsHandler = new PrefHandler(DCDC);
39 | //prefsHandler->setEnabledStatus(true);
40 |
41 | commonName = "Delphi DC-DC Converter";
42 |
43 | }
44 |
45 |
46 |
47 | void DCDCController::handleCanFrame(CAN_FRAME *frame)
48 | {
49 | Logger::debug("DCDC msg: %X", frame->id);
50 | Logger::debug("DCDC data: %X%X%X%X%X%X%X%X", frame->data.bytes[0],frame->data.bytes[1],frame->data.bytes[2],frame->data.bytes[3],frame->data.bytes[4],frame->data.bytes[5],frame->data.bytes[6],frame->data.bytes[7]);
51 | }
52 |
53 |
54 |
55 | void DCDCController::setup()
56 | {
57 | TickHandler::getInstance()->detach(this);
58 |
59 | loadConfiguration();
60 | Device::setup(); // run the parent class version of this function
61 |
62 | CanHandler::getInstanceCar()->attach(this, 0x1D5, 0x7ff, false);
63 | //Watch for 0x1D5 messages from Delphi converter
64 | TickHandler::getInstance()->attach(this, CFG_TICK_INTERVAL_DCDC);
65 | }
66 |
67 |
68 | void DCDCController::handleTick() {
69 |
70 | Device::handleTick(); //kick the ball up to papa
71 |
72 | sendCmd(); //Send our Delphi voltage control command
73 |
74 | }
75 |
76 |
77 | /*
78 | 1D7 08 80 77 00 00 00 00 00 00
79 | For 13.0 vdc output.
80 |
81 | 1D7 08 80 8E 00 00 00 00 00 00
82 | For 13.5 vdc output.
83 |
84 | To request 14.0 vdc, the message was:
85 | 1D7 08 80 A5 00 00 00 00 00 00
86 | */
87 |
88 | void DCDCController::sendCmd()
89 | {
90 | DCDCConfiguration *config = (DCDCConfiguration *)getConfiguration();
91 |
92 | CAN_FRAME output;
93 | output.length = 8;
94 | output.id = 0x1D7;
95 | output.extended = 0; //standard frame
96 | output.rtr = 0;
97 | output.fid = 0;
98 | output.data.bytes[0] = 0x80;
99 | output.data.bytes[1] = 0x8E;
100 | output.data.bytes[2] = 0;
101 | output.data.bytes[3] = 0;
102 | output.data.bytes[4] = 0;
103 | output.data.bytes[5] = 0;
104 | output.data.bytes[6] = 0;
105 | output.data.bytes[7] = 0x00;
106 |
107 | CanHandler::getInstanceCar()->sendFrame(output);
108 | timestamp();
109 | Logger::debug("Delphi DC-DC cmd: %X %X %X %X %X %X %X %X %X %d:%d:%d.%d",output.id, output.data.bytes[0],
110 | output.data.bytes[1],output.data.bytes[2],output.data.bytes[3],output.data.bytes[4],output.data.bytes[5],output.data.bytes[6],output.data.bytes[7], hours, minutes, seconds, milliseconds);
111 | }
112 |
113 | DeviceId DCDCController::getId() {
114 | return (DCDC);
115 | }
116 |
117 | uint32_t DCDCController::getTickInterval()
118 | {
119 | return CFG_TICK_INTERVAL_DCDC;
120 | }
121 |
122 | void DCDCController::loadConfiguration() {
123 | DCDCConfiguration *config = (DCDCConfiguration *)getConfiguration();
124 |
125 | if (!config) {
126 | config = new DCDCConfiguration();
127 | setConfiguration(config);
128 | }
129 |
130 | Device::loadConfiguration(); // call parent
131 | }
132 |
133 | void DCDCController::saveConfiguration() {
134 | Device::saveConfiguration();
135 | }
136 |
137 | void DCDCController::timestamp()
138 | {
139 | milliseconds = (int) (millis()/1) %1000 ;
140 | seconds = (int) (millis() / 1000) % 60 ;
141 | minutes = (int) ((millis() / (1000*60)) % 60);
142 | hours = (int) ((millis() / (1000*60*60)) % 24);
143 | }
144 |
145 |
146 |
--------------------------------------------------------------------------------
/DCDCController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * DCDCController.h
3 | *
4 | *
5 | *
6 | Copyright (c) 2014 Jack Rickard
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 | #ifndef DCDC_H_
30 | #define DCDC_H_
31 |
32 | #include
33 | #include "config.h"
34 | #include "Device.h"
35 | #include "sys_io.h"
36 | #include "TickHandler.h"
37 | #include "CanHandler.h"
38 |
39 | /*
40 | * Class for Delphi DCDC specific configuration parameters
41 | */
42 | class DCDCConfiguration : public DeviceConfiguration {
43 | public:
44 | };
45 |
46 | class DCDCController: public Device, CanObserver {
47 | public:
48 | virtual void handleTick();
49 | virtual void handleCanFrame(CAN_FRAME *frame);
50 | virtual void setup();
51 |
52 | DCDCController();
53 | void timestamp();
54 | DeviceId getId();
55 | uint32_t getTickInterval();
56 |
57 | virtual void loadConfiguration();
58 | virtual void saveConfiguration();
59 |
60 | private:
61 | int milliseconds ;
62 | int seconds;
63 | int minutes;
64 | int hours;
65 | void sendCmd();
66 | };
67 |
68 | #endif /* DCDC_H_ */
69 |
70 |
71 |
--------------------------------------------------------------------------------
/DMOC.txt:
--------------------------------------------------------------------------------
1 | This document explains a little bit of theory about the DMOC645
2 | motorcontroller object-module.
3 |
4 | The DMOC645 is a bit complicated in that you need to progressively establish
5 | operation in either speed mode or torque mode. We really don't use speed mode
6 | in vehicle applications.
7 |
8 | We control DMOC operation through two main variables and a torque command generated from our throttle:
9 |
10 | operationState= DISABLED = 0,
11 | STANDBY = 1,
12 | ENABLE = 2,
13 | POWERDOWN = 3
14 |
15 | selectedGear NEUTRAL =0
16 | DRIVE =1
17 | REVERSE=2
18 | ERROR=3
19 |
20 |
21 | The problem is, we have to allow some time for communications to establish, and then
22 | we have to progressively cycle from DISABLED to STANDBY to ENABLE. And we need acknowledgement from
23 | DMOC at each step.
24 |
25 | DMOC reports its state of operation via CAN and we hold that state in a variable titled activeState.
26 |
27 | We initialize as:
28 | selectedGear = NEUTRAL;
29 | operationState = DISABLED;
30 | actualState = DISABLED;
31 |
32 | We can set these values programmatically using two functions provided by our parent class MotorController. They are setOpState(operationState) and setSelectedGear(selectedGear).
33 |
34 | We can also set them via hardware input by activating the ENABLE input and the REVERSE input to any of the four digital inputs.
35 | When 12v is applied to the input designated as ENABLE, it will call setOpState(ENABLE). Likewise a 12v on the REVERSE input will cause a setSelectedGear(REVERSE) call. When they are in a low state, they actively setSelectedGear(DRIVE) and setOpState(DISABLED)
36 |
37 |
38 | The DMOC requires three different frames twice per second beginning very soon after power up or otherwise it faults out.
39 |
40 | We hold these in SENDCMD1, SENDCMD2, and SENDCMD3.
41 |
42 | SENDCMD1 sends a 0x232 frame we think of as the speed control frame. It is in speed mode. But we MUST transmit this frame even in torque mode. BYTE 5 is actually our ignition key state to get this thing running. Byte 6 is a bit map containing an ALIVE counter that increments by 2 from 0x00 to 0x0F. It also contains our selected gear and our requested operation state. We use the variable NEWSTATE for this.
43 |
44 | Examining our logic, if the DMOC reports, as it will initially, an activeState of DISABLED, if our operationState is DISABLED we will leave it there and in fact indicate a NEUTRAL gear selection as well, regardless of selectedGear.
45 |
46 | If DMOC reports DISABLED and we have an operationState of either STANDBY or ENABLE, we will set newstate to STANDBY and send that to the DMOC. This will continue UNTIL we receive an activeState BACK from the DMOC indicating STANDBY.
47 |
48 | Once we receive an actualState of STANDBY from the DMOC, on our next transmitted 232 frame, if our operationState is ENABLE we will send a newstate of ENABLE.
49 |
50 | Thereafter, if we receive an activeState indication from DMOC of ENABLE and our operationState is ENABLE, we continue to send ENABLE.
51 |
52 | Of course, if operationState goes to DISABLED, we will send a DISABLED to the DMOC and have to start the sequence all over again if we return to ENABLE on the operationState.
53 |
54 | IF we have a newstate of ENABLE, we also send our selectedGear instead of NEUTRAL. So the SpeedControl frame 232 is actually key to properly cycling through the DISABLED, STANDBY, and ENABLE states AND advising DMOC of our selectedGear.
55 |
56 | SENDCMD2 sends a 233 frame containing our torque command in bytes 0 and 1 and again in 2 and 3. It sends a STANDBy torque command in bytes 4 and 5. Byte 6 contains the SAME alive value as the 232 frame.
57 |
58 | Our torque command is calculated by multiplying our maximum allowed torque variable by our throttle percentage. Throttle runs from -1000 to +1000 as a percentage and is calculated by comparing the received analog values in the range of x1 to x2 to our throttle map of regen and forward torques. We multiply our throttle position x maximum torque and divide by 1000 to get a torque value that is a percentage of maxium torque, but has the sign of regen (-) or forward(+). This is added to an offset of 30,000. Numbers below 30000 are regen torque and above 30000 are forward torque.
59 |
60 | The problem comes in in REVERSE gear. DMOC takes negative values as positive torque in the reverse direction. And it takes positive values as regen in the reverse direction. By inverting the value, we can provide control in a reversed direction.
61 |
62 |
63 | And so in normal operation, we can set our selectedGear and operationState at will, and the proper cycling will occur within these two frames automatically.
64 |
65 | The only issue is on startup. We want to wait until we have received and sent some frames to establish communications before doing all this. And so we have an activity counter that is incremented by frames received, and decremented by our tick handler. Once we have accumulated a surplus of 40 on the activity counter, we can set our gear to DRIVE and our opstate to ENABLE.
66 |
67 | IF we have selected an input for either REVERSE or ENABlE, we don't want to do that. We want to leave it in neutral and disabled and let this be done by hardware signal input. If we have NOT selected inputs for these, we of course want to go ahead and set them automatically.
68 |
69 | The RUNNING advisory on our web status panel only appears on receipt of DMOC CAN packets. In fact, if we lose our stream of packets and our activity counter is decremented below 40, it will go out as well.
70 |
71 |
72 |
--------------------------------------------------------------------------------
/Device.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Device.cpp
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #include "Device.h"
28 | #include "DeviceManager.h"
29 |
30 | Device::Device() {
31 | deviceConfiguration = NULL;
32 | prefsHandler = NULL;
33 | //since all derived classes eventually call this base method this will cause every device to auto register itself with the device manager
34 | DeviceManager::getInstance()->addDevice(this);
35 | commonName = "Generic Device";
36 | }
37 |
38 | //Empty functions to handle these callbacks if the derived classes don't
39 |
40 | void Device::setup() {
41 | }
42 |
43 | char* Device::getCommonName() {
44 | return commonName;
45 | }
46 |
47 | void Device::handleTick() {
48 | }
49 |
50 | uint32_t Device::getTickInterval() {
51 | return 0;
52 | }
53 |
54 | //just bubbles up the value from the preference handler.
55 | bool Device::isEnabled() {
56 | return prefsHandler->isEnabled();
57 | }
58 |
59 | void Device::handleMessage(uint32_t msgType, void* message) {
60 | switch (msgType) {
61 | case MSG_STARTUP:
62 | this->setup();
63 | break;
64 | }
65 | }
66 |
67 | DeviceType Device::getType() {
68 | return DEVICE_NONE;
69 | }
70 |
71 | DeviceId Device::getId() {
72 | return INVALID;
73 | }
74 |
75 | void Device::loadConfiguration() {
76 | }
77 |
78 | void Device::saveConfiguration() {
79 | }
80 |
81 | DeviceConfiguration *Device::getConfiguration() {
82 | return this->deviceConfiguration;
83 | }
84 |
85 | void Device::setConfiguration(DeviceConfiguration *configuration) {
86 | this->deviceConfiguration = configuration;
87 | }
88 |
89 |
90 |
91 |
--------------------------------------------------------------------------------
/Device.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Device.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef DEVICE_H_
28 | #define DEVICE_H_
29 |
30 | #include
31 | #include "config.h"
32 | #include "DeviceTypes.h"
33 | #include "eeprom_layout.h"
34 | #include "PrefHandler.h"
35 | #include "Sys_Messages.h"
36 | #include "FaultHandler.h"
37 |
38 | /*
39 | * A abstract class to hold device configuration. It is to be accessed
40 | * by sub-classes via getConfiguration() and then cast into its
41 | * correct sub-class.
42 | */
43 | class DeviceConfiguration {
44 |
45 | };
46 |
47 | /*
48 | * A abstract class for all Devices.
49 | */
50 | class Device: public TickObserver {
51 | public:
52 | Device();
53 | virtual void setup();
54 | virtual void handleMessage(uint32_t, void* );
55 | virtual DeviceType getType();
56 | virtual DeviceId getId();
57 | void handleTick();
58 | bool isEnabled();
59 | virtual uint32_t getTickInterval();
60 | char* getCommonName();
61 |
62 | virtual void loadConfiguration();
63 | virtual void saveConfiguration();
64 | DeviceConfiguration *getConfiguration();
65 | void setConfiguration(DeviceConfiguration *);
66 |
67 | protected:
68 | PrefHandler *prefsHandler;
69 | char *commonName;
70 |
71 | private:
72 | DeviceConfiguration *deviceConfiguration; // reference to the currently active configuration
73 | };
74 |
75 | #endif /* DEVICE_H_ */
76 |
77 |
78 |
--------------------------------------------------------------------------------
/DeviceManager.h:
--------------------------------------------------------------------------------
1 | /*
2 | * DeviceManager.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef DEVICEMGR_H_
27 | #define DEVICEMGR_H_
28 |
29 | #include "config.h"
30 | #include "Throttle.h"
31 | #include "MotorController.h"
32 | #include "CanHandler.h"
33 | #include "Device.h"
34 | #include "Sys_Messages.h"
35 | #include "DeviceTypes.h"
36 |
37 | class MotorController; // cyclic reference between MotorController and DeviceManager
38 |
39 | class DeviceManager {
40 | public:
41 | static DeviceManager *getInstance();
42 | void addDevice(Device *device);
43 | void removeDevice(Device *device);
44 | // void addTickObserver(TickObserver *observer, uint32_t frequency);
45 | // void addCanObserver(CanObserver *observer, uint32_t id, uint32_t mask, bool extended, CanHandler::CanBusNode canBus);
46 | void sendMessage(DeviceType deviceType, DeviceId deviceId, uint32_t msgType, void* message);
47 | void setParameter(DeviceType deviceType, DeviceId deviceId, uint32_t msgType, char *key, char *value);
48 | void setParameter(DeviceType deviceType, DeviceId deviceId, uint32_t msgType, char *key, uint32_t value);
49 | uint8_t getNumThrottles();
50 | uint8_t getNumControllers();
51 | uint8_t getNumBMS();
52 | uint8_t getNumChargers();
53 | uint8_t getNumDisplays();
54 | Throttle *getAccelerator();
55 | Throttle *getBrake();
56 | MotorController *getMotorController();
57 | Device *getDeviceByID(DeviceId);
58 | Device *getDeviceByType(DeviceType);
59 | void printDeviceList();
60 | void updateWifi();
61 | Device *updateWifiByID(DeviceId);
62 |
63 | protected:
64 |
65 | private:
66 | DeviceManager(); // private constructor
67 | static DeviceManager *deviceManager;
68 |
69 | Device *devices[CFG_DEV_MGR_MAX_DEVICES];
70 | Throttle *throttle;
71 | Throttle *brake;
72 | MotorController *motorController;
73 |
74 | int8_t findDevice(Device *device);
75 | uint8_t countDeviceType(DeviceType deviceType);
76 | };
77 |
78 | #endif
79 |
80 |
81 |
--------------------------------------------------------------------------------
/DeviceTypes.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Device.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef DEVICE_TYPES_H_
28 | #define DEVICE_TYPES_H_
29 |
30 | enum DeviceType {
31 | DEVICE_ANY,
32 | DEVICE_MOTORCTRL,
33 | DEVICE_BMS,
34 | DEVICE_CHARGER,
35 | DEVICE_DISPLAY,
36 | DEVICE_THROTTLE,
37 | DEVICE_BRAKE,
38 | DEVICE_MISC,
39 | DEVICE_WIFI,
40 | DEVICE_NONE
41 | };
42 |
43 | enum DeviceId { //unique device ID for every piece of hardware possible
44 | DMOC645 = 0x1000,
45 | BRUSA_DMC5 = 0x1001,
46 | CODAUQM = 0x1002,
47 | BRUSACHARGE = 0x1010,
48 | TCCHCHARGE = 0x1011,
49 | LEAR=0x1012,
50 | THROTTLE = 0x1030,
51 | POTACCELPEDAL = 0x1031,
52 | POTBRAKEPEDAL = 0x1032,
53 | CANACCELPEDAL = 0x1033,
54 | CANBRAKEPEDAL = 0x1034,
55 | EVICTUS = 0x4400,
56 | ICHIP2128 = 0x1040,
57 | DCDC = 0x1050,
58 | THINKBMS = 0x2000,
59 | FAULTSYS = 0x4000,
60 | SYSTEM = 0x5000,
61 | HEARTBEAT = 0x5001,
62 | MEMCACHE = 0x5002,
63 | PIDLISTENER = 0x6000,
64 | ELM327EMU = 0x650,
65 | INVALID = 0xFFFF
66 | };
67 |
68 | #endif /* DEVICE_TYPES_H_ */
69 |
70 |
71 |
--------------------------------------------------------------------------------
/DmocMotorController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * DmocMotorController.h
3 | *
4 | * Note that the dmoc needs to have some form of input for gear selector (drive/neutral/reverse)
5 | *
6 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 | #ifndef DMOC_H_
30 | #define DMOC_H_
31 |
32 | #include
33 | #include "config.h"
34 | #include "MotorController.h"
35 | #include "sys_io.h"
36 | #include "TickHandler.h"
37 | #include "CanHandler.h"
38 |
39 | /*
40 | * Class for DMOC specific configuration parameters
41 | */
42 | class DmocMotorControllerConfiguration : public MotorControllerConfiguration {
43 | public:
44 | };
45 |
46 | class DmocMotorController: public MotorController, CanObserver {
47 | public:
48 |
49 | enum Step {
50 | SPEED_TORQUE,
51 | CHAL_RESP
52 | };
53 |
54 | enum KeyState {
55 | OFF = 0,
56 | ON = 1,
57 | RESERVED = 2,
58 | NOACTION = 3
59 | };
60 |
61 |
62 |
63 | public:
64 | virtual void handleTick();
65 | virtual void handleCanFrame(CAN_FRAME *frame);
66 | virtual void setup();
67 | void setGear(Gears gear);
68 |
69 | DmocMotorController();
70 | DeviceId getId();
71 | uint32_t getTickInterval();
72 |
73 | virtual void loadConfiguration();
74 | virtual void saveConfiguration();
75 |
76 | private:
77 |
78 | OperationState actualState; //what the controller is reporting it is
79 | int step;
80 | byte online; //counter for whether DMOC appears to be operating
81 | byte alive;
82 | int activityCount;
83 | uint16_t torqueCommand;
84 | void timestamp();
85 |
86 | void sendCmd1();
87 | void sendCmd2();
88 | void sendCmd3();
89 | void sendCmd4();
90 | void sendCmd5();
91 | byte calcChecksum(CAN_FRAME thisFrame);
92 |
93 | };
94 |
95 | #endif /* DMOC_H_ */
96 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/ELM327Processor.cpp:
--------------------------------------------------------------------------------
1 | #include "ELM327Processor.h"
2 |
3 | ELM327Processor::ELM327Processor() {
4 | obd2Handler = OBD2Handler::getInstance();
5 | }
6 |
7 | String ELM327Processor::processELMCmd(char *cmd) {
8 | String retString = String();
9 | String lineEnding;
10 | if (bLineFeed) lineEnding = String("\r\n");
11 | else lineEnding = String("\r");
12 |
13 | if (!strncmp(cmd, "at", 2)) {
14 |
15 | if (!strcmp(cmd, "atz")) { //reset hardware
16 | retString.concat(lineEnding);
17 | retString.concat("ELM327 v1.3a");
18 | }
19 | else if (!strncmp(cmd, "atsh",4)) { //set header address
20 | //ignore this - just say OK
21 | retString.concat("OK");
22 | }
23 | else if (!strncmp(cmd, "ate",3)) { //turn echo on/off
24 | //could support echo but I don't see the need, just ignore this
25 | retString.concat("OK");
26 | }
27 | else if (!strncmp(cmd, "ath",3)) { //turn headers on/off
28 | if (cmd[3] == '1') bHeader = true;
29 | else bHeader = false;
30 | retString.concat("OK");
31 | }
32 | else if (!strncmp(cmd, "atl",3)) { //turn linefeeds on/off
33 | if (cmd[3] == '1') bLineFeed = true;
34 | else bLineFeed = false;
35 | retString.concat("OK");
36 | }
37 | else if (!strcmp(cmd, "at@1")) { //send device description
38 | retString.concat("ELM327 Emulator");
39 | }
40 | else if (!strcmp(cmd, "ati")) { //send chip ID
41 | retString.concat("ELM327 v1.3a");
42 | }
43 | else if (!strncmp(cmd, "atat",4)) { //set adaptive timing
44 | //don't intend to support adaptive timing at all
45 | retString.concat("OK");
46 | }
47 | else if (!strncmp(cmd, "atsp",4)) { //set protocol
48 | //theoretically we can ignore this
49 | retString.concat("OK");
50 | }
51 | else if (!strcmp(cmd, "atdp")) { //show description of protocol
52 | retString.concat("can11/500");
53 | }
54 | else if (!strcmp(cmd, "atdpn")) { //show protocol number (same as passed to sp)
55 | retString.concat("6");
56 | }
57 | else if (!strcmp(cmd, "atd")) { //set to defaults
58 | retString.concat("OK");
59 | }
60 | else if (!strncmp(cmd, "atm", 3)) { //turn memory on/off
61 | retString.concat("OK");
62 | }
63 | else if (!strcmp(cmd, "atrv")) { //show 12v rail voltage
64 | //TODO: the system should actually have this value so it wouldn't hurt to
65 | //look it up and report the real value.
66 | retString.concat("14.2V");
67 | }
68 | else { //by default respond to anything not specifically handled by just saying OK and pretending.
69 | retString.concat("OK");
70 | }
71 | }
72 | else { //if no AT then assume it is a PID request. This takes the form of four bytes which form the alpha hex digit encoding for two bytes
73 | //there should be four or six characters here forming the ascii representation of the PID request. Easiest for now is to turn the ascii into
74 | //a 16 bit number and mask off to get the bytes
75 | if (strlen(cmd) == 4) {
76 | uint32_t valu = strtol((char *) cmd, NULL, 16); //the pid format is always in hex
77 | uint8_t pidnum = (uint8_t)(valu & 0xFF);
78 | uint8_t mode = (uint8_t)((valu >> 8) & 0xFF);
79 | Logger::debug(ELM327EMU, "Mode: %i, PID: %i", mode, pidnum);
80 | char out[7];
81 | char buff[10];
82 | if (obd2Handler->processRequest(mode, pidnum, NULL, out)) {
83 | if (bHeader) {
84 | retString.concat("7E8");
85 | out[0] += 2; //not sending only data bits but mode and pid too
86 | for (int i = 0; i <= out[0]; i++) {
87 | sprintf(buff, "%02X", out[i]);
88 | retString.concat(buff);
89 | }
90 | }
91 | else {
92 | mode += 0x40;
93 | sprintf(buff, "%02X", mode);
94 | retString.concat(buff);
95 | sprintf(buff, "%02X", pidnum);
96 | retString.concat(buff);
97 | for (int i = 1; i <= out[0]; i++) {
98 | sprintf(buff, "%02X", out[i+2]);
99 | retString.concat(buff);
100 | }
101 | }
102 | }
103 | }
104 | }
105 |
106 | retString.concat(lineEnding);
107 | retString.concat(">"); //prompt to show we're ready to receive again
108 |
109 | return retString;
110 | }
111 |
112 |
113 |
--------------------------------------------------------------------------------
/ELM327Processor.h:
--------------------------------------------------------------------------------
1 | #ifndef ELMPROC_H_
2 | #define ELMPROC_H_
3 |
4 | #include
5 | #include "config.h"
6 | #include "constants.h"
7 | #include "Sys_Messages.h"
8 | #include "DeviceTypes.h"
9 | #include "OBD2Handler.h"
10 |
11 | class ELM327Processor {
12 | public:
13 | ELM327Processor();
14 | String processELMCmd(char *cmd);
15 | private:
16 | OBD2Handler *obd2Handler;
17 | char buffer[30]; // a buffer for various string conversions
18 | bool bLineFeed;
19 | bool bHeader;
20 | };
21 |
22 | #endif
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ELM327_Emu.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * ELM327_Emu.cpp
3 | *
4 | * Class emulates the serial comm of an ELM327 chip - Used to create an OBDII interface
5 | *
6 | * Created: 3/18/2014
7 | * Author: Collin Kidder
8 | */
9 |
10 | /*
11 | Copyright (c) 2013-2014 Collin Kidder, Michael Neuweiler, Charles Galpin
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining
14 | a copy of this software and associated documentation files (the
15 | "Software"), to deal in the Software without restriction, including
16 | without limitation the rights to use, copy, modify, merge, publish,
17 | distribute, sublicense, and/or sell copies of the Software, and to
18 | permit persons to whom the Software is furnished to do so, subject to
19 | the following conditions:
20 |
21 | The above copyright notice and this permission notice shall be included
22 | in all copies or substantial portions of the Software.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 | */
32 |
33 | #include "ELM327_Emu.h"
34 |
35 |
36 | /*
37 | * Constructor. Assign serial interface to use for comm with bluetooth adapter we're emulating with
38 | */
39 | ELM327Emu::ELM327Emu() {
40 | prefsHandler = new PrefHandler(ELM327EMU);
41 |
42 | uint8_t sys_type;
43 | sysPrefs->read(EESYS_SYSTEM_TYPE, &sys_type);
44 | if (sys_type == 3 || sys_type == 4)
45 | serialInterface = &Serial2;
46 | else //older hardware used this instead
47 | serialInterface = &Serial3;
48 |
49 | commonName = "ELM327 Emulator over Bluetooth";
50 | }
51 |
52 | /*
53 | * Constructor. Pass serial interface to use
54 | */
55 | ELM327Emu::ELM327Emu(USARTClass *which) {
56 | prefsHandler = new PrefHandler(ELM327EMU);
57 | serialInterface = which;
58 | }
59 |
60 |
61 | /*
62 | * Initialization of hardware and parameters
63 | */
64 | void ELM327Emu::setup() {
65 |
66 | Logger::info("add device: ELM327 emulator (id: %X, %X", ELM327EMU, this);
67 |
68 | TickHandler::getInstance()->detach(this);
69 |
70 | tickCounter = 0;
71 | ibWritePtr = 0;
72 | serialInterface->begin(9600);
73 |
74 | elmProc = new ELM327Processor();
75 |
76 | //this isn't a wifi link but the timer interval can be the same
77 | //because it serves a similar function and has similar timing requirements
78 | TickHandler::getInstance()->attach(this, CFG_TICK_INTERVAL_WIFI);
79 | }
80 |
81 | /*
82 | * Send a command to ichip. The "AT+i" part will be added.
83 | */
84 | void ELM327Emu::sendCmd(String cmd) {
85 | serialInterface->write("AT");
86 | serialInterface->print(cmd);
87 | serialInterface->write(13);
88 | loop(); // parse the response
89 | }
90 |
91 | /*
92 |
93 | */
94 | void ELM327Emu::handleTick() {
95 |
96 | }
97 |
98 | /*
99 | * Handle a message sent by the DeviceManager.
100 | */
101 | void ELM327Emu::handleMessage(uint32_t messageType, void* message) {
102 | Device::handleMessage(messageType, message);
103 |
104 | switch (messageType) {
105 | case MSG_SET_PARAM: {
106 | break;
107 | }
108 | case MSG_CONFIG_CHANGE:
109 | break;
110 | case MSG_COMMAND:
111 | sendCmd((char *)message);
112 | break;
113 | }
114 | }
115 |
116 | /*
117 | * Called in the main loop (hopefully) in order to process serial input waiting for us
118 | * from the wifi module. It should always terminate its answers with 13 so buffer
119 | * until we get 13 (CR) and then process it.
120 | * But, for now just echo stuff to our serial port for debugging
121 | */
122 |
123 | void ELM327Emu::loop() {
124 | int incoming;
125 | while (serialInterface->available()) {
126 | incoming = serialInterface->read();
127 | if (incoming != -1) { //and there is no reason it should be -1
128 | if (incoming == 13 || ibWritePtr > 126) { // on CR or full buffer, process the line
129 | incomingBuffer[ibWritePtr] = 0; //null terminate the string
130 | ibWritePtr = 0; //reset the write pointer
131 |
132 | if (Logger::isDebug())
133 | Logger::debug(ELM327EMU, incomingBuffer);
134 | processCmd();
135 |
136 | } else { // add more characters
137 | if (incoming != 10 && incoming != ' ') // don't add a LF character or spaces. Strip them right out
138 | incomingBuffer[ibWritePtr++] = (char)tolower(incoming); //force lowercase to make processing easier
139 | }
140 | } else
141 | return;
142 | }
143 | }
144 |
145 | /*
146 | * There is no need to pass the string in here because it is local to the class so this function can grab it by default
147 | * But, for reference, this cmd processes the command in incomingBuffer
148 | */
149 | void ELM327Emu::processCmd() {
150 | String retString = elmProc->processELMCmd(incomingBuffer);
151 |
152 | serialInterface->print(retString);
153 | if (Logger::isDebug()) {
154 | char buff[30];
155 | retString.toCharArray(buff, 30);
156 | Logger::debug(ELM327EMU, buff);
157 | }
158 |
159 | }
160 |
161 | DeviceType ELM327Emu::getType() {
162 | return DEVICE_MISC;
163 | }
164 |
165 | DeviceId ELM327Emu::getId() {
166 | return (ELM327EMU);
167 | }
168 |
169 | void ELM327Emu::loadConfiguration() {
170 | ELM327Configuration *config = (ELM327Configuration *)getConfiguration();
171 |
172 | if (prefsHandler->checksumValid()) { //checksum is good, read in the values stored in EEPROM
173 | Logger::debug(ELM327EMU, "Valid checksum so using stored elm327 emulator config values");
174 | //TODO: implement processing of config params for WIFI
175 | // prefsHandler->read(EESYS_WIFI0_SSID, &config->ssid);
176 | }
177 | }
178 |
179 | void ELM327Emu::saveConfiguration() {
180 | ELM327Configuration *config = (ELM327Configuration *) getConfiguration();
181 |
182 | //TODO: implement processing of config params for WIFI
183 | // prefsHandler->write(EESYS_WIFI0_SSID, config->ssid);
184 | // prefsHandler->saveChecksum();
185 | }
186 |
187 |
188 |
189 |
--------------------------------------------------------------------------------
/ELM327_Emu.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ELM327_Emu.h
3 | *
4 | * Class emulates the serial comm of an ELM327 chip - Used to create an OBDII interface
5 | *
6 | * Created: 3/18/2014
7 | * Author: Collin Kidder
8 | */
9 |
10 | /*
11 | Copyright (c) 2013-2014 Collin Kidder, Michael Neuweiler, Charles Galpin
12 |
13 | Permission is hereby granted, free of charge, to any person obtaining
14 | a copy of this software and associated documentation files (the
15 | "Software"), to deal in the Software without restriction, including
16 | without limitation the rights to use, copy, modify, merge, publish,
17 | distribute, sublicense, and/or sell copies of the Software, and to
18 | permit persons to whom the Software is furnished to do so, subject to
19 | the following conditions:
20 |
21 | The above copyright notice and this permission notice shall be included
22 | in all copies or substantial portions of the Software.
23 |
24 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
28 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
29 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
30 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 | */
32 |
33 | /*
34 | List of AT commands to support:
35 | AT E0 (turn echo off)
36 | AT H (0/1) - Turn headers on or off - headers are used to determine how many ECUís present (hint: only send one response to 0100 and emulate a single ECU system to save time coding)
37 | AT L0 (Turn linefeeds off - just use CR)
38 | AT Z (reset)
39 | AT SH - Set header address - seems to set the ECU address to send to (though you may be able to ignore this if you wish)
40 | AT @1 - Display device description - ELM327 returns: Designed by Andy Honecker 2011
41 | AT I - Cause chip to output its ID: ELM327 says: ELM327 v1.3a
42 | AT AT (0/1/2) - Set adaptive timing (though you can ignore this)
43 | AT SP (set protocol) - you can ignore this
44 | AT DP (get protocol by name) - (always return can11/500)
45 | AT DPN (get protocol by number) - (always return 6)
46 | AT RV (adapter voltage) - Send something like 14.4V
47 | */
48 |
49 |
50 | #ifndef ELM327_H_
51 | #define ELM327_H_
52 |
53 | #include
54 | #include "config.h"
55 | #include "constants.h"
56 | #include "DeviceManager.h"
57 | #include "Sys_Messages.h"
58 | #include "DeviceTypes.h"
59 | #include "ELM327Processor.h"
60 |
61 | extern PrefHandler *sysPrefs;
62 |
63 | /*
64 | * The extended configuration class with additional parameters for ichip WLAN
65 | */
66 | class ELM327Configuration : public DeviceConfiguration {
67 | public:
68 | };
69 |
70 | class ELM327Emu : public Device {
71 | public:
72 |
73 | ELM327Emu();
74 | ELM327Emu(USARTClass *which);
75 | void setup(); //initialization on start up
76 | void handleTick(); //periodic processes
77 | void handleMessage(uint32_t messageType, void* message);
78 | DeviceType getType();
79 | DeviceId getId();
80 | void loop();
81 | void sendCmd(String cmd);
82 |
83 | void loadConfiguration();
84 | void saveConfiguration();
85 |
86 | private:
87 | USARTClass *serialInterface; //Allows for retargetting which serial port we use
88 | ELM327Processor *elmProc;
89 | char incomingBuffer[128]; //storage for one incoming line
90 | int tickCounter;
91 | int ibWritePtr;
92 | int currReply;
93 | char buffer[30]; // a buffer for various string conversions
94 |
95 | void processCmd();
96 | };
97 |
98 | #endif
99 |
100 |
101 |
--------------------------------------------------------------------------------
/EVIC.h:
--------------------------------------------------------------------------------
1 | /*
2 | * EVIC.h
3 | *
4 | * * Class to interface with the Electric Vehicle Interface Controller EVIC by Andromeda Interfaces. This Class will extract operating data from the GEVCU and send to EVIC via CAN message for display.
5 | *
6 | *
7 | * Created: 1/28/2015
8 | * Author: Jack Rickard
9 |
10 | Copyright (c) 2015 Jack Rickard
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining
13 | a copy of this software and associated documentation files (the
14 | "Software"), to deal in the Software without restriction, including
15 | without limitation the rights to use, copy, modify, merge, publish,
16 | distribute, sublicense, and/or sell copies of the Software, and to
17 | permit persons to whom the Software is furnished to do so, subject to
18 | the following conditions:
19 |
20 | The above copyright notice and this permission notice shall be included
21 | in all copies or substantial portions of the Software.
22 |
23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
26 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
27 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
28 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
29 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 | */
31 |
32 | #ifndef EVIC_H_
33 | #define EVIC_H_
34 |
35 | #include
36 | #include "config.h"
37 | #include "constants.h"
38 | #include "Device.h"
39 | #include "TickHandler.h"
40 | #include "CanHandler.h"
41 | #include "DeviceManager.h"
42 | #include "Sys_Messages.h"
43 | #include "DeviceTypes.h"
44 |
45 | extern PrefHandler *sysPrefs;
46 |
47 |
48 | class EVICConfiguration: public DeviceConfiguration {
49 | public:
50 | //uint8_t capacity;
51 | };
52 |
53 |
54 | class EVIC: public Device, CanObserver {
55 | public:
56 |
57 | EVIC();
58 | //EVIC(USARTClass *which);
59 | virtual void handleTick();
60 | virtual void handleCanFrame(CAN_FRAME *frame);
61 |
62 | virtual void setup(); //initialization on start up
63 | void timestamp();
64 | DeviceType getType();
65 | DeviceId getId();
66 |
67 | char *getTimeRunning();
68 | void loadConfiguration();
69 | void saveConfiguration();
70 | int16_t getdcVoltage();
71 | int16_t getdcCurrent();
72 | uint16_t getAH();
73 | uint8_t getCapacity();
74 | void setCapacity(uint8_t capacity);
75 | uint8_t getSOC();
76 | int16_t getPower();
77 | int16_t getkWh();
78 | int16_t getTemperatureMotor();
79 | int16_t getTemperatureInverter();
80 | int16_t getRPM();
81 | uint8_t getCellTemp1();
82 | uint8_t getCellTemp2();
83 | uint8_t getCellTemp3();
84 | uint8_t getCellTemp4();
85 | uint8_t getCellHi();
86 | uint8_t getCello();
87 |
88 | unsigned long timemark;
89 | unsigned long timemark2;
90 | int16_t torqueActual;
91 | int16_t speedActual;
92 | int16_t dcVoltage;
93 | int16_t dcCurrent;
94 | uint16_t nominalVolt;
95 | uint16_t AH;
96 | uint8_t capacity;
97 | uint8_t SOC;
98 | int16_t Power;
99 | int16_t kWh;
100 | int16_t temperatureMotor;
101 | int16_t temperatureInverter;
102 | int16_t rpm;
103 | uint8_t celltemp1;
104 | uint8_t celltemp2;
105 | uint8_t celltemp3;
106 | uint8_t celltemp4;
107 | uint8_t CellHi;
108 | uint8_t Cello;
109 |
110 | private:
111 | void sendTestCmdCurtis();
112 | void sendTestCmdOrion();
113 | void sendCmdCurtis();
114 | void sendCmdOrion();
115 |
116 | double AHf;
117 | double milliAH;
118 | float SOCf;
119 | int milliseconds ;
120 | int seconds;
121 | int minutes;
122 | int hours ;
123 | unsigned long elapsedtime;
124 | int16_t DCV;
125 | int16_t DCA;
126 | int8_t TEMPM;
127 | int8_t TEMPI;
128 |
129 | int tickCounter;
130 | char buffer[30]; // a buffer for various string conversions
131 | uint32_t lastSentTime;
132 | boolean weHave505;
133 | boolean testMode;
134 |
135 |
136 | };
137 |
138 | #endif
139 |
140 |
--------------------------------------------------------------------------------
/FaultCodes.h:
--------------------------------------------------------------------------------
1 | /*
2 | * config.h
3 | *
4 | * Defines the allowable fault codes
5 |
6 | Copyright (c) 2014 Collin Kidder, Michael Neuweiler, Charles Galpin, Jack Rickard
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 | *
27 | */
28 |
29 | #ifndef FAULTCODES_H_
30 | #define FAULTCODES_H_
31 |
32 | /*
33 | Format these fault codes in DTC format.
34 | DTC uses 16 bits to store a code
35 | Byte A is the first byte, B is the second byte
36 | A7-6 = Which fault system (00=P=PowerTrain, 01=C=Chassis, 10=B=Body, 11=U=Network)
37 | A5-4 = First Digit (0-3)
38 | A3-0 = Second Digit (0-F)
39 | B7-4 = Third Digit (0-F)
40 | B3-0 = Last / Fourth Digit (0-F)
41 |
42 | Many codes are already used in ICE vehicles but rarely with hex digits so exclusively use
43 | codes with hex digits to avoid overlap
44 | */
45 |
46 | enum FAULTCODE {
47 | FAULT_NONE = 0,
48 |
49 | //The A throttle seems to be stuck low
50 | FAULT_THROTTLE_LOW_A = 0x0F01, //P0F01
51 |
52 | //The A throttle seems to be stuck high
53 | FAULT_THROTTLE_HIGH_A = 0x0F02, //P0F02
54 |
55 | //The B throttle seems to be stuck low
56 | FAULT_THROTTLE_LOW_B = 0x0F06, //P0F06
57 |
58 | //The B throttle seems to be stuck high
59 | FAULT_THROTTLE_HIGH_B = 0x0F07, //P0F07
60 |
61 | //The C throttle seems to be stuck low
62 | FAULT_THROTTLE_LOW_C = 0x0F0A, //P0F0A
63 |
64 | //The C throttle seems to be stuck high
65 | FAULT_THROTTLE_HIGH_C = 0x0F0B, //P0F0B
66 |
67 | //Throttles A and B do not match
68 | FAULT_THROTTLE_MISMATCH_AB = 0x0F11, //P0F11
69 |
70 | //Throttles A and C do not match
71 | FAULT_THROTTLE_MISMATCH_AC = 0x0F12, //P0F12
72 |
73 | //Throttles B and C do not match
74 | FAULT_THROTTLE_MISMATCH_BC = 0x0F13, //P0F13
75 |
76 | //There was a general fault in the throttle
77 | FAULT_THROTTLE_MISC = 0x0F40, //P0F40
78 |
79 | //There was a problem communicating with an external throttle module
80 | FAULT_THROTTLE_COMM = 0x0F60, //P0F60
81 |
82 | //The brake input seems to be stuck low
83 | FAULT_BRAKE_LOW = 0x0B01, //P0B01
84 |
85 | //The brake input seems to be stuck high
86 | FAULT_BRAKE_HIGH = 0x0B02, //P0B02
87 |
88 | //There was a problem communicating with an external brake module
89 | FAULT_BRAKE_COMM = 0x0B60, //P0B60
90 |
91 | //The +12V battery or DC/DC system seems to have excessively high voltage
92 | FAULT_12V_BATT_HIGH = 0x0A01, //P0A01
93 |
94 | //The +12V battery or DC/DC system seems to have excessively low voltage
95 | FAULT_12V_BATT_LOW = 0x0A02, //P0A02
96 |
97 | //The HV battery has too high of a voltage
98 | FAULT_HV_BATT_HIGH = 0x0A11, //P0A11
99 |
100 | //The HV battery has too low of a voltage
101 | FAULT_HV_BATT_LOW = 0x0A12, //P0A12
102 |
103 | //A request has been made for more current than allowable from the HV battery
104 | FAULT_HV_BATT_OVERCURR = 0x0A30, //P0A30
105 |
106 | //The HV battery is too cold
107 | FAULT_HV_BATT_UNDERTEMP = 0x0A50, //P0A50
108 |
109 | //The HV battery is too hot
110 | FAULT_HV_BATT_OVERTEMP = 0x0A51, //P0A51
111 |
112 | //There is a problem with isolation of HV from the chassis
113 | FAULT_HV_BATT_ISOLATION = 0x0A70, //P0A70
114 |
115 | //A cell in the HV pack is too high of a voltage
116 | FAULT_HV_CELL_HIGH = 0x0AA1, //P0AA1
117 |
118 | //A cell in the HV pack is too low of a voltage
119 | FAULT_HV_CELL_LOW = 0x0AA2, //P0AA2
120 |
121 | //A cell in the HV pack is too cold
122 | FAULT_HV_CELL_UNDERTEMP = 0x0AB0, //P0AB0
123 |
124 | //A cell in the HV pack is too hot
125 | FAULT_HV_CELL_OVERTEMP = 0x0AB1, //P0AB1
126 |
127 | //BMS failed to initialize properly
128 | FAULT_BMS_INIT = 0xCC10, //U0C10
129 |
130 | //There was a problem communicating with the BMS
131 | FAULT_BMS_COMM = 0xCC60, //U0C60
132 |
133 | //There was a general fault at the BMS
134 | FAULT_BMS_MISC = 0xCC40, //U0C40
135 |
136 | //The motor is too hot
137 | FAULT_MOTOR_OVERTEMP = 0x0D50, //P0D50
138 |
139 | //The motor controller is too hot
140 | FAULT_MOTORCTRL_OVERTEMP = 0x0D80, //P0D80
141 |
142 | //There was a problem communicating with the motor controller
143 | FAULT_MOTORCTRL_COMM = 0x0D60, //P0D60
144 |
145 | //There was a general fault in the motor controller
146 | FAULT_MOTORCTRL_MISC = 0x0D40, //P0D40
147 |
148 | //The motor and controller cannot satisfy the torque request
149 | FAULT_MOTORCTRL_INSUFF_TORQUE = 0x0D10, //P0D10
150 |
151 | //The motor is spinning faster that it should be
152 | FAULT_MOTORCTRL_EXCESSIVE_SPEED = 0x0D20, //P0D20
153 |
154 | //The motor is providing more torque than it should be (didn't request this much)
155 | FAULT_MOTORCTRL_EXCESSIVE_TORQUE = 0x0D25, //P0D25
156 |
157 | //It seems that we cannot enable the motor controller though we've tried.
158 | FAULT_MOTORCTRL_CANT_ENABLE = 0x0DA0, //P0DA0
159 |
160 | //It seems we cannot go into drive even though we asked to go into drive
161 | FAULT_MOTORCTRL_CANT_DRIVE = 0x0DA4, //P0DA4
162 |
163 | //It seems we cannot go into reverse even though we asked to go into reverse
164 | FAULT_MOTORCTRL_CANT_REVERSE = 0x0DA8, //P0DA8
165 |
166 | //there was a request for power from the motor but the controller is not in a state to provide power
167 | FAULT_MOTORCTRL_POWERREQ_INV = 0x0DB0 //P0DB0
168 | };
169 |
170 |
171 | #endif
172 |
173 |
174 |
--------------------------------------------------------------------------------
/FaultHandler.h:
--------------------------------------------------------------------------------
1 | /*
2 | * FaultHandler.h
3 | *
4 | * Creates a universal fault handling system that stores faults in EEPROM and can create, return, and clear
5 | * fault data. Could be the basis for an OBDII compliant fault database or could be used on its own
6 | *
7 | * Technically, one can't clear or erase faults. They get acknowledged and quit showing up
8 | *
9 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining
12 | a copy of this software and associated documentation files (the
13 | "Software"), to deal in the Software without restriction, including
14 | without limitation the rights to use, copy, modify, merge, publish,
15 | distribute, sublicense, and/or sell copies of the Software, and to
16 | permit persons to whom the Software is furnished to do so, subject to
17 | the following conditions:
18 |
19 | The above copyright notice and this permission notice shall be included
20 | in all copies or substantial portions of the Software.
21 |
22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 | */
30 |
31 |
32 | #ifndef FAULT_H_
33 | #define FAULT_H_
34 |
35 | #include
36 | #include "config.h"
37 | #include "Logger.h"
38 | #include "FaultCodes.h"
39 | #include "MemCache.h"
40 |
41 | extern MemCache *memCache;
42 |
43 | //structure to use for storing and retrieving faults.
44 | //Stores the info a fault record will contain.
45 | typedef struct {
46 | uint32_t timeStamp; //number of
47 | uint16_t device; //which device is generating this fault
48 | uint16_t faultCode; //set by the device itself. There is a universal list of codes
49 | uint8_t ack : 1; ////whether this fault has been acknowledged or not 1 = ack'd
50 | uint8_t ongoing : 1; //whether fault still seems to be happening currently 1 = still going on
51 | } FAULT; //should be 9 bytes because the bottom two are bit fields in a single byte
52 |
53 |
54 | class FaultHandler : public TickObserver {
55 | public:
56 | FaultHandler(); //constructor
57 | uint16_t raiseFault(uint16_t device, uint16_t code, bool ongoing); //raise a new fault. Returns the fault # where this was stored
58 | void cancelOngoingFault(uint16_t device, uint16_t code); //if this fault was registered as ongoing then cancel it (set not ongoing) otherwise do nothing
59 | bool getNextFault(FAULT*); //get the next un-ack'd fault. Will also get first fault if the first call and you forgot to call getFirstFault
60 | bool getFault(uint16_t fault, FAULT*);
61 | uint16_t getFaultCount();
62 | void handleTick();
63 | void setup();
64 |
65 | uint16_t setFaultACK(uint16_t fault); //acknowledge the fault # - returns fault # if successful (0xFFFF otherwise)
66 | uint16_t setFaultOngoing(uint16_t fault, bool ongoing); //set value of ongoing flag - returns fault # on success
67 |
68 | private:
69 | void loadFromEEPROM();
70 | void saveToEEPROM();
71 | void writeFaultToEEPROM(int faultnum);
72 |
73 | uint16_t faultWritePointer; //fault # we're up to for writing. Location in EEPROM is start + (fault_ptr * sizeof(FAULT))
74 | uint16_t faultReadPointer; //fault # we're at when reading.
75 | FAULT faultList[CFG_FAULT_HISTORY_SIZE]; //store up to 50 faults for a long history. 50*9 = 450 bytes of EEPROM
76 | uint32_t globalTime; //how long the unit has been running in total (across all start ups).
77 | uint32_t baseTime; //the time loaded at system start up. millis() / 100 is added to this to get the above time
78 | };
79 |
80 | extern FaultHandler faultHandler;
81 |
82 | #endif /* FAULT_H_ */
83 |
84 |
85 |
--------------------------------------------------------------------------------
/GEVCU.h:
--------------------------------------------------------------------------------
1 | /*
2 | * GEVCU.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef GEVCU_H_
28 | #define GEVCU_H_
29 |
30 | #include
31 | #include "config.h"
32 | #include "Device.h"
33 | #include "Throttle.h"
34 | #include "CanThrottle.h"
35 | #include "CanBrake.h"
36 | #include "PotThrottle.h"
37 | #include "PotBrake.h"
38 | #include "BatteryManager.h"
39 | #include "ThinkBatteryManager.h"
40 | #include "MotorController.h"
41 | #include "DmocMotorController.h"
42 | #include "BrusaMotorController.h"
43 | #include "Heartbeat.h"
44 | #include "sys_io.h"
45 | #include "CanHandler.h"
46 | #include "MemCache.h"
47 | #include "ThrottleDetector.h"
48 | #include "DeviceManager.h"
49 | #include "SerialConsole.h"
50 | #include "ELM327_Emu.h"
51 | #include "ichip_2128.h"
52 | #include "Sys_Messages.h"
53 | #include "CodaMotorController.h"
54 | #include "FaultHandler.h"
55 | #include "DCDCController.h"
56 | #include "EVIC.h"
57 |
58 | #ifdef __cplusplus
59 | extern "C" {
60 | #endif
61 | void loop();
62 | void setup();
63 |
64 | #ifdef __cplusplus
65 | } // extern "C"
66 | #endif
67 |
68 | #define SYSTEM_PROTO 1
69 | #define SYSTEM_DUED 2
70 | #define SYSTEM_GEVCU3 3
71 |
72 | #endif /* GEVCU_H_ */
73 |
74 |
75 |
--------------------------------------------------------------------------------
/GEVCU.kdev4:
--------------------------------------------------------------------------------
1 | [Project]
2 | Name=GEVCU
3 | Manager=KDevCMakeManager
4 | VersionControl=kdevgit
5 |
--------------------------------------------------------------------------------
/GEVCU.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 2012
4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GEVCU", "GEVCU.vcxproj", "{6BFAB833-3C53-4597-9B31-C33D5EA78172}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|Win32 = Debug|Win32
9 | Release|Win32 = Release|Win32
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {6BFAB833-3C53-4597-9B31-C33D5EA78172}.Debug|Win32.ActiveCfg = Debug|Win32
13 | {6BFAB833-3C53-4597-9B31-C33D5EA78172}.Debug|Win32.Build.0 = Debug|Win32
14 | {6BFAB833-3C53-4597-9B31-C33D5EA78172}.Release|Win32.ActiveCfg = Release|Win32
15 | {6BFAB833-3C53-4597-9B31-C33D5EA78172}.Release|Win32.Build.0 = Release|Win32
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/Heartbeat.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Heartbeat.c
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #include "Heartbeat.h"
28 |
29 | Heartbeat::Heartbeat() {
30 | led = false;
31 | throttleDebug = false;
32 | }
33 |
34 | void Heartbeat::setup() {
35 | TickHandler::getInstance()->detach(this);
36 |
37 | TickHandler::getInstance()->attach(this, CFG_TICK_INTERVAL_HEARTBEAT);
38 | }
39 |
40 | void Heartbeat::setThrottleDebug(bool debug) {
41 | throttleDebug = debug;
42 | }
43 |
44 | bool Heartbeat::getThrottleDebug() {
45 | return throttleDebug;
46 | }
47 |
48 | void Heartbeat::handleTick() {
49 | // Print a dot if no other output has been made since the last tick
50 | if (Logger::getLastLogTime() < lastTickTime) {
51 | SerialUSB.print('.');
52 | if ((++dotCount % 80) == 0) {
53 | SerialUSB.println();
54 | }
55 | }
56 | lastTickTime = millis();
57 |
58 | if (led) {
59 | digitalWrite(BLINK_LED, HIGH);
60 | } else {
61 | digitalWrite(BLINK_LED, LOW);
62 | }
63 | led = !led;
64 |
65 | if (throttleDebug) {
66 | MotorController *motorController = DeviceManager::getInstance()->getMotorController();
67 | Throttle *accelerator = DeviceManager::getInstance()->getAccelerator();
68 | Throttle *brake = DeviceManager::getInstance()->getBrake();
69 |
70 | Logger::console("");
71 | if (motorController) {
72 | Logger::console("Motor Controller Status-> isRunning: %T isFaulted: %T", motorController->isRunning(), motorController->isFaulted());
73 | }
74 |
75 | Logger::console("AIN0: %d, AIN1: %d, AIN2: %d, AIN3: %d", getAnalog(0), getAnalog(1), getAnalog(2), getAnalog(3));
76 | Logger::console("DIN0: %d, DIN1: %d, DIN2: %d, DIN3: %d", getDigital(0), getDigital(1), getDigital(2), getDigital(3));
77 | Logger::console("DOUT0: %d, DOUT1: %d, DOUT2: %d, DOUT3: %d,DOUT4: %d, DOUT5: %d, DOUT6: %d, DOUT7: %d", getOutput(0), getOutput(1), getOutput(2), getOutput(3),getOutput(4), getOutput(5), getOutput(6), getOutput(7));
78 |
79 | if (accelerator) {
80 | Logger::console("Is throttle currently faulted: %T Throttle level: %i", accelerator->isFaulted(), accelerator->getLevel());
81 | RawSignalData *rawSignal = accelerator->acquireRawSignal();
82 | Logger::console("Throttle rawSignal1: %d, rawSignal2: %d", rawSignal->input1, rawSignal->input2);
83 | }
84 | if (brake) {
85 | Logger::console("Brake Output Level: %i", brake->getLevel());
86 | RawSignalData *rawSignal = brake->acquireRawSignal();
87 | Logger::console("Brake rawSignal1: %d", rawSignal->input1);
88 | }
89 | }
90 | }
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/Heartbeat.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Heartbeat.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef HEARTBEAT_H_
28 | #define HEARTBEAT_H_
29 |
30 | #include "config.h"
31 | #include "TickHandler.h"
32 | #include "DeviceManager.h"
33 | #include "sys_io.h"
34 |
35 | class Heartbeat: public TickObserver {
36 | public:
37 | Heartbeat();
38 | void setup();
39 | void handleTick();
40 | void setThrottleDebug(bool debug);
41 | bool getThrottleDebug();
42 |
43 | protected:
44 |
45 | private:
46 | bool led;
47 | bool throttleDebug;
48 | int dotCount;
49 | uint32_t lastTickTime;
50 | };
51 |
52 | #endif /* HEARTBEAT_H_ */
53 |
54 |
55 |
--------------------------------------------------------------------------------
/Logger.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Logger.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef LOGGER_H_
28 | #define LOGGER_H_
29 |
30 | #include
31 | #include "config.h"
32 | #include "DeviceTypes.h"
33 | #include "constants.h"
34 |
35 | class Logger {
36 | public:
37 | enum LogLevel {
38 | Debug = 0, Info = 1, Warn = 2, Error = 3, Off = 4
39 | };
40 | static void debug(char *, ...);
41 | static void debug(DeviceId, char *, ...);
42 | static void info(char *, ...);
43 | static void info(DeviceId, char *, ...);
44 | static void warn(char *, ...);
45 | static void warn(DeviceId, char *, ...);
46 | static void error(char *, ...);
47 | static void error(DeviceId, char *, ...);
48 | static void console(char *, ...);
49 | static void setLoglevel(LogLevel);
50 | static LogLevel getLogLevel();
51 | static uint32_t getLastLogTime();
52 | static boolean isDebug();
53 | private:
54 | static LogLevel logLevel;
55 | static uint32_t lastLogTime;
56 |
57 | static void log(DeviceId, LogLevel, char *format, va_list);
58 | static void logMessage(char *format, va_list args);
59 | static void printDeviceName(DeviceId);
60 | };
61 |
62 | #endif /* LOGGER_H_ */
63 |
64 |
65 |
--------------------------------------------------------------------------------
/MemCache.h:
--------------------------------------------------------------------------------
1 | /*
2 | * MemCache.h
3 | *
4 | * Handles caching of EEPROM pages to RAM
5 | *
6 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 | #ifndef MEM_CACHE_H_
30 | #define MEM_CACHE_H_
31 |
32 | #include
33 | #include "config.h"
34 | #include "TickHandler.h"
35 | #include
36 |
37 | //Total # of allowable pages to cache. Limits RAM usage
38 | #define NUM_CACHED_PAGES 16
39 |
40 | //maximum allowable age of a cache
41 | #define MAX_AGE 128
42 |
43 | /* # of system ticks per aging cycle. There are 128 aging levels total so
44 | // multiply 128 by this aging period and multiple that by system tick duration
45 | // to determine how long it will take for a page to age out fully and get written
46 | // if dirty. For instance, 128 levels * 500 aging period * 10ms (100Hz tick) = 640 seconds
47 | // EEPROM handles about 1 million write cycles. So, a flush time of 100 seconds means that
48 | // continuous writing would last 100M seconds which is 3.17 years
49 | // Another way to look at it is that 128 aging levels * 40ms tick is 5.12 seconds to flush for
50 | // each aging period below. Adjust acccordingly.
51 | */
52 | #define AGING_PERIOD 60
53 |
54 | //Current parameters as of Sept 7 2014 = 128 * 40ms * 60 = 307.2 seconds to flush = about 10 years EEPROM life
55 |
56 | class MemCache: public TickObserver {
57 | public:
58 | void setup();
59 | void handleTick();
60 | void FlushSinglePage();
61 | void FlushAllPages();
62 | void FlushPage(uint8_t page);
63 | void FlushAddress(uint32_t address);
64 | void InvalidatePage(uint8_t page);
65 | void InvalidateAddress(uint32_t address);
66 | void InvalidateAll();
67 | void AgeFullyPage(uint8_t page);
68 | void AgeFullyAddress(uint32_t address);
69 |
70 | boolean Write(uint32_t address, uint8_t valu);
71 | boolean Write(uint32_t address, uint16_t valu);
72 | boolean Write(uint32_t address, uint32_t valu);
73 | boolean Write(uint32_t address, void* data, uint16_t len);
74 |
75 | //It's sort of weird to make the read function take a reference but it allows for overloading
76 | boolean Read(uint32_t address, uint8_t* valu);
77 | boolean Read(uint32_t address, uint16_t* valu);
78 | boolean Read(uint32_t address, uint32_t* valu);
79 | boolean Read(uint32_t address, void* data, uint16_t len);
80 |
81 | MemCache();
82 |
83 | private:
84 | typedef struct {
85 | uint8_t data[256];
86 | uint32_t address; //address of start of page
87 | uint8_t age; //
88 | boolean dirty;
89 | } PageCache;
90 |
91 | PageCache pages[NUM_CACHED_PAGES];
92 | boolean isWriting();
93 | uint8_t cache_hit(uint32_t address);
94 | void cache_age();
95 | uint8_t cache_findpage();
96 | uint8_t cache_readpage(uint32_t addr);
97 | boolean cache_writepage(uint8_t page);
98 | uint8_t agingTimer;
99 | };
100 |
101 | #endif /* MEM_CACHE_H_ */
102 |
103 |
104 |
--------------------------------------------------------------------------------
/MotorController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * MotorController.h
3 | *
4 | * Parent class for all motor controllers.
5 | *
6 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 | #ifndef MOTORCTRL_H_
30 | #define MOTORCTRL_H_
31 |
32 | #include
33 | #include "config.h"
34 | #include "Device.h"
35 | #include "Throttle.h"
36 | #include "DeviceManager.h"
37 | #include "sys_io.h"
38 |
39 | #define MOTORCTL_INPUT_DRIVE_EN 3
40 | #define MOTORCTL_INPUT_FORWARD 4
41 | #define MOTORCTL_INPUT_REVERSE 5
42 | #define MOTORCTL_INPUT_LIMP 6
43 |
44 | class MotorControllerConfiguration : public DeviceConfiguration {
45 | public:
46 | uint16_t speedMax; // in rpm
47 | uint16_t torqueMax; // maximum torque in 0.1 Nm
48 | uint16_t torqueSlewRate; // for torque mode only: slew rate of torque value, 0=disabled, in 0.1Nm/sec
49 | uint16_t speedSlewRate; // for speed mode only: slew rate of speed value, 0=disabled, in rpm/sec
50 | uint8_t reversePercent;
51 | uint16_t kilowattHrs;
52 | uint16_t prechargeR; //resistance of precharge resistor in tenths of ohm
53 | uint16_t nominalVolt; //nominal pack voltage in tenths of a volt
54 | uint8_t prechargeRelay; //# of output to use for this relay or 255 if there is no relay
55 | uint8_t mainContactorRelay; //# of output to use for this relay or 255 if there is no relay
56 | uint8_t coolFan;
57 | uint8_t coolOn;
58 | uint8_t coolOff;
59 | uint8_t brakeLight;
60 | uint8_t revLight;
61 | uint8_t enableIn;
62 | uint8_t reverseIn;
63 | uint8_t capacity;
64 |
65 | };
66 |
67 | class MotorController: public Device {
68 |
69 | public:
70 | enum Gears {
71 | NEUTRAL = 0,
72 | DRIVE = 1,
73 | REVERSE = 2,
74 | ERROR = 3,
75 | };
76 |
77 | enum PowerMode {
78 | modeTorque,
79 | modeSpeed
80 | };
81 |
82 | enum OperationState {
83 | DISABLED = 0,
84 | STANDBY = 1,
85 | ENABLE = 2,
86 | POWERDOWN = 3
87 | };
88 |
89 | MotorController();
90 | DeviceType getType();
91 | void setup();
92 | void handleTick();
93 | uint32_t getTickInterval();
94 |
95 | void loadConfiguration();
96 | void saveConfiguration();
97 |
98 | void coolingcheck();
99 | void checkBrakeLight();
100 | void checkReverseLight();
101 | void checkEnableInput();
102 | void checkReverseInput();
103 | void checkPrecharge();
104 |
105 | void brakecheck();
106 | bool isReady();
107 | bool isRunning();
108 | bool isFaulted();
109 | bool isWarning();
110 |
111 | uint32_t getStatusBitfield1();
112 | uint32_t getStatusBitfield2();
113 | uint32_t getStatusBitfield3();
114 | uint32_t getStatusBitfield4();
115 |
116 | uint32_t statusBitfield1; // bitfield variable for use of the specific implementation
117 | uint32_t statusBitfield2;
118 | uint32_t statusBitfield3;
119 | uint32_t statusBitfield4;
120 | uint32_t kiloWattHours;
121 |
122 |
123 |
124 |
125 | void setPowerMode(PowerMode mode);
126 | PowerMode getPowerMode();
127 | void setOpState(OperationState op) ;
128 | OperationState getOpState() ;
129 | void setSelectedGear(Gears gear);
130 | Gears getSelectedGear();
131 |
132 | int16_t getThrottle();
133 | int8_t getCoolFan();
134 | int8_t getCoolOn();
135 | int8_t getCoolOff();
136 | int8_t getBrakeLight();
137 | int8_t getRevLight();
138 | int8_t getEnableIn();
139 | int8_t getReverseIn();
140 | int16_t getselectedGear();
141 | int16_t getprechargeR();
142 | int16_t getnominalVolt();
143 | int8_t getprechargeRelay();
144 | int8_t getmainContactorRelay();
145 | int16_t getSpeedRequested();
146 | int16_t getSpeedActual();
147 | int16_t getTorqueRequested();
148 | int16_t getTorqueActual();
149 | int16_t getTorqueAvailable();
150 | int preMillis();
151 |
152 | uint16_t getDcVoltage();
153 | int16_t getDcCurrent();
154 | uint16_t getAcCurrent();
155 | uint32_t getKiloWattHours();
156 | int16_t getMechanicalPower();
157 | int16_t getTemperatureMotor();
158 | int16_t getTemperatureInverter();
159 | int16_t getTemperatureSystem();
160 |
161 |
162 | int milliseconds ;
163 | int seconds;
164 | int minutes;
165 | int hours ;
166 | int premillis;
167 | uint16_t nominalVolts; //nominal pack voltage in 1/10 of a volt
168 | uint8_t capacity;
169 |
170 |
171 | protected:
172 | bool ready; // indicates if the controller is ready to enable the power stage
173 | bool running; // indicates if the power stage of the inverter is operative
174 | bool faulted; // indicates a error condition is present in the controller
175 | bool warning; // indicates a warning condition is present in the controller
176 | bool coolflag;
177 | bool testenableinput;
178 | bool testreverseinput;
179 |
180 |
181 | Gears selectedGear;
182 |
183 | PowerMode powerMode;
184 | OperationState operationState; //the op state we want
185 |
186 | int16_t throttleRequested; // -1000 to 1000 (per mille of throttle level)
187 | int16_t speedRequested; // in rpm
188 | int16_t speedActual; // in rpm
189 | int16_t torqueRequested; // in 0.1 Nm
190 | int16_t torqueActual; // in 0.1 Nm
191 | int16_t torqueAvailable; // the maximum available torque in 0.1Nm
192 |
193 | uint16_t dcVoltage; // DC voltage in 0.1 Volts
194 | int16_t dcCurrent; // DC current in 0.1 Amps
195 | uint16_t acCurrent; // AC current in 0.1 Amps
196 | int16_t mechanicalPower; // mechanical power of the motor 0.1 kW
197 | int16_t temperatureMotor; // temperature of motor in 0.1 degree C
198 | int16_t temperatureInverter; // temperature of inverter power stage in 0.1 degree C
199 | int16_t temperatureSystem; // temperature of controller in 0.1 degree C
200 |
201 |
202 |
203 | uint16_t prechargeTime; //time in ms that precharge should last
204 | uint32_t milliStamp; //how long we have precharged so far
205 | bool donePrecharge; //already completed the precharge cycle?
206 | bool prelay;
207 | uint32_t skipcounter;
208 | };
209 |
210 | #endif
211 |
212 |
213 |
--------------------------------------------------------------------------------
/OBD2Handler.h:
--------------------------------------------------------------------------------
1 | /*
2 | * OBD2Handler.h - Handles OBD2 PID requests
3 | *
4 | Copyright (c) 2013-14 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef OBD2_H_
28 | #define OBD2_H_
29 |
30 | #include
31 | #include "config.h"
32 | #include "Throttle.h"
33 | #include "MotorController.h"
34 | #include "BatteryManager.h"
35 | #include "DeviceManager.h"
36 | #include "TickHandler.h"
37 | #include "CanHandler.h"
38 | #include "constants.h"
39 |
40 | class OBD2Handler {
41 | public:
42 | bool processRequest(uint8_t mode, uint8_t pid, char *inData, char *outData);
43 | static OBD2Handler *getInstance();
44 |
45 | protected:
46 |
47 | private:
48 | OBD2Handler(); //it's not right to try to directly instantiate this class
49 | bool processShowData(uint8_t pid, char *inData, char *outData);
50 | bool processShowCustomData(uint16_t pid, char *inData, char *outData);
51 |
52 | static OBD2Handler *instance;
53 | MotorController* motorController;
54 | Throttle* accelPedal;
55 | Throttle* brakePedal;
56 | BatteryManager *BMS;
57 | };
58 |
59 | #endif
60 |
61 |
62 |
--------------------------------------------------------------------------------
/PotBrake.h:
--------------------------------------------------------------------------------
1 | /*
2 | * PotBrake.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef POT_BRAKE_H_
28 | #define POT_BRAKE_H_
29 |
30 | #include
31 | #include "config.h"
32 | #include "PotThrottle.h"
33 | #include "sys_io.h"
34 | #include "TickHandler.h"
35 | #include "Logger.h"
36 | #include "DeviceManager.h"
37 |
38 | #define THROTTLE_INPUT_BRAKELIGHT 2
39 |
40 | /*
41 | * The extended configuration class with additional parameters for PotBrake
42 | *
43 | * NOTE: Because of ThrottleDetector, this currently MUST be the same as PotThrottleConfiguratin !!!
44 | */
45 | class PotBrakeConfiguration: public PotThrottleConfiguration {
46 | public:
47 | };
48 |
49 | class PotBrake: public Throttle {
50 | public:
51 | PotBrake();
52 | void setup();
53 | void handleTick();
54 | DeviceId getId();
55 | DeviceType getType();
56 |
57 | RawSignalData *acquireRawSignal();
58 |
59 | void loadConfiguration();
60 | void saveConfiguration();
61 |
62 | protected:
63 | bool validateSignal(RawSignalData *);
64 | uint16_t calculatePedalPosition(RawSignalData *);
65 | int16_t mapPedalPosition(int16_t);
66 |
67 | private:
68 | RawSignalData rawSignal;
69 | };
70 |
71 | #endif /* POT_BRAKE_H_ */
72 |
73 |
74 |
--------------------------------------------------------------------------------
/PotThrottle.h:
--------------------------------------------------------------------------------
1 | /*
2 | * PotThrottle.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef PEDAL_POT_H_
28 | #define PEDAL_POT_H_
29 |
30 | #include
31 | #include "config.h"
32 | #include "Throttle.h"
33 | #include "sys_io.h"
34 | #include "TickHandler.h"
35 | #include "Logger.h"
36 | #include "DeviceManager.h"
37 | #include "FaultHandler.h"
38 | #include "FaultCodes.h"
39 |
40 | #define THROTTLE_INPUT_BRAKELIGHT 2
41 |
42 | /*
43 | * The extended configuration class with additional parameters for PotThrottle
44 | */
45 | class PotThrottleConfiguration: public ThrottleConfiguration {
46 | public:
47 | /*
48 | * Allows subclasses to have sub types for their pedal type
49 | * 0 - unknown type (prefs will return 0 if never set)
50 | * 1 - standard linear potentiometer (low-high). If 2 pots, both are low-high and the 2nd mirrors the 1st.
51 | * 2 - inverse potentiometer (high-low). If 2 pots, then 1st is low-high and 2nd is high-low)
52 | */
53 | uint8_t throttleSubType;
54 | uint16_t minimumLevel1, maximumLevel1, minimumLevel2, maximumLevel2; // values for when the pedal is at its min and max for each input
55 | uint8_t numberPotMeters; // the number of potentiometers to be used. Should support three as well since some pedals really do have that many
56 | uint8_t AdcPin1, AdcPin2; //which ADC pins to use for the throttle
57 | };
58 |
59 | class PotThrottle: public Throttle {
60 | public:
61 | PotThrottle();
62 | void setup();
63 | void handleTick();
64 | DeviceId getId();
65 | RawSignalData *acquireRawSignal();
66 |
67 | void loadConfiguration();
68 | void saveConfiguration();
69 |
70 | protected:
71 | bool validateSignal(RawSignalData *);
72 | uint16_t calculatePedalPosition(RawSignalData *);
73 |
74 | private:
75 | RawSignalData rawSignal;
76 | };
77 |
78 | #endif /* POT_THROTTLE_H_ */
79 |
80 |
81 |
--------------------------------------------------------------------------------
/PrefHandler.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * PrefHandler.cpp
3 | *
4 | * Abstracts away the particulars of how preferences are stored.
5 | * Transparently supports main and "last known good" storage and retrieval
6 | *
7 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining
10 | a copy of this software and associated documentation files (the
11 | "Software"), to deal in the Software without restriction, including
12 | without limitation the rights to use, copy, modify, merge, publish,
13 | distribute, sublicense, and/or sell copies of the Software, and to
14 | permit persons to whom the Software is furnished to do so, subject to
15 | the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included
18 | in all copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | */
29 |
30 | #include "PrefHandler.h"
31 |
32 | PrefHandler::PrefHandler() {
33 | lkg_address = EE_MAIN_OFFSET; //default to normal mode
34 | base_address = 0;
35 | }
36 |
37 | bool PrefHandler::isEnabled()
38 | {
39 | return enabled;
40 | }
41 |
42 | void PrefHandler::setEnabledStatus(bool en)
43 | {
44 | uint16_t id;
45 |
46 | enabled = en;
47 |
48 | if (enabled) {
49 | id |= 0x8000; //set enabled bit
50 | }
51 | else {
52 | id &= 0x7FFF; //clear enabled bit
53 | }
54 |
55 | memCache->Write(EE_DEVICE_TABLE + (2 * position), id);
56 | }
57 |
58 |
59 | void PrefHandler::initDevTable()
60 | {
61 | uint16_t id;
62 |
63 | memCache->Read(EE_DEVICE_TABLE, &id);
64 | if (id == 0xDEAD) return;
65 |
66 | Logger::debug("Initializing EEPROM device table");
67 |
68 | //initialize table with zeros
69 | id = 0;
70 | for (int x = 1; x < 64; x++) {
71 | memCache->Write(EE_DEVICE_TABLE + (2 * x), id);
72 | }
73 |
74 | //write out magic entry
75 | id = 0xDEAD;
76 | memCache->Write(EE_DEVICE_TABLE, id);
77 | }
78 |
79 | //Given a device ID we must search the 64 entry table found in EEPROM to see if the device
80 | //has a spot in EEPROM. If it does not then
81 | PrefHandler::PrefHandler(DeviceId id_in) {
82 | uint16_t id;
83 |
84 | enabled = false;
85 |
86 | initDevTable();
87 |
88 | for (int x = 1; x < 64; x++) {
89 | memCache->Read(EE_DEVICE_TABLE + (2 * x), &id);
90 | if ((id & 0x7FFF) == ((int)id_in)) {
91 | base_address = EE_DEVICES_BASE + (EE_DEVICE_SIZE * x);
92 | lkg_address = EE_MAIN_OFFSET;
93 | if (id & 0x8000) enabled = true;
94 | position = x;
95 | Logger::info("Device ID: %X was found in device table at entry: %i", (int)id_in, x);
96 | return;
97 | }
98 | }
99 |
100 | //if we got here then there was no entry for this device in the table yet.
101 | //try to find an empty spot and place it there.
102 | for (int x = 1; x < 64; x++) {
103 | memCache->Read(EE_DEVICE_TABLE + (2 * x), &id);
104 | if (id == 0) {
105 | base_address = EE_DEVICES_BASE + (EE_DEVICE_SIZE * x);
106 | lkg_address = EE_MAIN_OFFSET;
107 | enabled = false; //default to devices being off until the user says otherwise
108 | id = (int)id_in;
109 | memCache->Write(EE_DEVICE_TABLE + (2*x), id);
110 | position = x;
111 | Logger::info("Device ID: %X was placed into device table at entry: %i", (int)id, x);
112 | return;
113 | }
114 | }
115 |
116 | //we found no matches and could not allocate a space. This is bad. Error out here
117 | base_address = 0xF0F0;
118 | lkg_address = EE_MAIN_OFFSET;
119 | Logger::error("PrefManager - Device Table Full!!!");
120 | }
121 |
122 | //A special static function that can be called whenever, wherever to turn a specific device on/off. Does not
123 | //attempt to do so at runtime so the user will still have to power cycle to change the device status.
124 | //returns true if it could make the change, false if it could not.
125 | bool PrefHandler::setDeviceStatus(uint16_t device, bool enabled)
126 | {
127 | uint16_t id;
128 | for (int x = 1; x < 64; x++) {
129 | memCache->Read(EE_DEVICE_TABLE + (2 * x), &id);
130 | if ((id & 0x7FFF) == (device & 0x7FFF)) {
131 | Logger::debug("Found a device record to edit");
132 | if (enabled) {
133 | id |= 0x8000;
134 | }
135 | else {
136 | id &= 0x7FFF;
137 | }
138 | Logger::debug("ID to write: %X", id);
139 | memCache->Write(EE_DEVICE_TABLE + (2 * x), id);
140 | return true;
141 | }
142 | }
143 | return false;
144 | }
145 |
146 | PrefHandler::~PrefHandler() {
147 | }
148 |
149 | void PrefHandler::LKG_mode(bool mode) {
150 | if (mode) lkg_address = EE_LKG_OFFSET;
151 | else lkg_address = EE_MAIN_OFFSET;
152 | }
153 |
154 | bool PrefHandler::write(uint16_t address, uint8_t val) {
155 | if (address >= EE_DEVICE_SIZE) return false;
156 | return memCache->Write((uint32_t)address + base_address + lkg_address, val);
157 | }
158 |
159 | bool PrefHandler::write(uint16_t address, uint16_t val) {
160 | if (address >= EE_DEVICE_SIZE) return false;
161 | return memCache->Write((uint32_t)address + base_address + lkg_address, val);
162 | }
163 |
164 | bool PrefHandler::write(uint16_t address, uint32_t val) {
165 | if (address >= EE_DEVICE_SIZE) return false;
166 | return memCache->Write((uint32_t)address + base_address + lkg_address, val);
167 | }
168 |
169 | bool PrefHandler::read(uint16_t address, uint8_t *val) {
170 | if (address >= EE_DEVICE_SIZE) return false;
171 | return memCache->Read((uint32_t)address + base_address + lkg_address, val);
172 | }
173 |
174 | bool PrefHandler::read(uint16_t address, uint16_t *val) {
175 | if (address >= EE_DEVICE_SIZE) return false;
176 | return memCache->Read((uint32_t)address + base_address + lkg_address, val);
177 | }
178 |
179 | bool PrefHandler::read(uint16_t address, uint32_t *val) {
180 | if (address >= EE_DEVICE_SIZE) return false;
181 | return memCache->Read((uint32_t)address + base_address + lkg_address, val);
182 | }
183 |
184 | uint8_t PrefHandler::calcChecksum() {
185 | uint16_t counter;
186 | uint8_t accum = 0;
187 | uint8_t temp;
188 | for (counter = 1; counter < EE_DEVICE_SIZE; counter++) {
189 | memCache->Read((uint32_t)counter + base_address + lkg_address, &temp);
190 | accum += temp;
191 | }
192 | return accum;
193 | }
194 |
195 | //calculate the current checksum and save it to the proper place
196 | void PrefHandler::saveChecksum() {
197 | uint8_t csum;
198 | csum = calcChecksum();
199 | memCache->Write(EE_CHECKSUM + base_address + lkg_address, csum);
200 | }
201 |
202 | bool PrefHandler::checksumValid() {
203 | //get checksum from EEPROM and calculate the current checksum to see if they match
204 | uint8_t stored_chk, calc_chk;
205 |
206 | memCache->Read(EE_CHECKSUM + base_address + lkg_address, &stored_chk);
207 | calc_chk = calcChecksum();
208 | Logger::info("Stored Checksum: %X Calc: %X", stored_chk, calc_chk);
209 |
210 | return (stored_chk == calc_chk);
211 | }
212 |
213 | void PrefHandler::forceCacheWrite()
214 | {
215 | memCache->FlushAllPages();
216 | }
217 |
218 |
219 |
220 |
--------------------------------------------------------------------------------
/PrefHandler.h:
--------------------------------------------------------------------------------
1 | /*
2 | * PrefHandler.h
3 | *
4 | * header for preference handler
5 | *
6 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 | #ifndef PREF_HANDLER_H_
30 | #define PREF_HANDLER_H_
31 |
32 | #include
33 | #include "config.h"
34 | #include "eeprom_layout.h"
35 | #include "MemCache.h"
36 | #include "DeviceTypes.h"
37 | #include "Logger.h"
38 |
39 | //normal or Last Known Good configuration
40 | #define PREF_MODE_NORMAL false
41 | #define PREF_MODE_LKG true
42 |
43 | extern MemCache *memCache;
44 |
45 | class PrefHandler {
46 | public:
47 |
48 | PrefHandler();
49 | PrefHandler(DeviceId id);
50 | ~PrefHandler();
51 | void LKG_mode(bool mode);
52 | bool write(uint16_t address, uint8_t val);
53 | bool write(uint16_t address, uint16_t val);
54 | bool write(uint16_t address, uint32_t val);
55 | bool read(uint16_t address, uint8_t *val);
56 | bool read(uint16_t address, uint16_t *val);
57 | bool read(uint16_t address, uint32_t *val);
58 | uint8_t calcChecksum();
59 | void saveChecksum();
60 | bool checksumValid();
61 | void forceCacheWrite();
62 | bool isEnabled();
63 | void setEnabledStatus(bool en);
64 | static bool setDeviceStatus(uint16_t device, bool enabled);
65 |
66 | private:
67 | uint32_t base_address; //base address for the parent device
68 | uint32_t lkg_address;
69 | bool use_lkg; //use last known good config?
70 | bool enabled;
71 | int position; //position within the device table
72 | void initDevTable();
73 | };
74 |
75 | #endif
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | GEVCU
2 | =====
3 |
4 | Note - If you have pulled this code between July and Sept of 2016 then you received commits that have been
5 | removed from this repo. It has been decided to move development of GEVCU6 code over to the GEVCU6 repo.
6 | If you have the commits from that multi-month window then point your origin to the GEVCU6 repo instead
7 | and everything will still be there and be correct. Sorry for any inconvenience this causes.
8 |
9 | Generalized Electric Vehicle Control Unit
10 |
11 | Our website can be found at : http://www.gevcu.org
12 |
13 | A project to create a fairly Arduino compatible ECU firmware
14 | to interface with various electric vehicle hardware over canbus
15 | (and possibly other comm channels)
16 |
17 | The project now builds in the Arduino IDE. So, use it to compile, send the firmware to the Arduino, and monitor serial. It all works very nicely.
18 |
19 | The master branch of this project is now switched to support the Due. The master branch is sparsely updated and only when the source tree is in stable shape.
20 |
21 | The older Macchina code has been moved to its own branch. This code is now *VERY* old but should work to control a DMOC645.
22 |
23 | ArduinoDue branch is more experimental than the master branch and includes the work of Michael Neuweiler.
24 |
25 | The WIP branch is sync'd to EVTV's official changes and as such could be considered as a testing ground for the official source code distribution.
26 |
27 | You will need the following to have any hope of compiling and running the firmware:
28 | - A GEVCU board. Versions from 2 and up are supported.
29 | - Arduino IDE 1.5.4 - Do not use newer versions of the IDE
30 | - due_can library - There is a repo for this under Collin80
31 | - due_rtc library - Also under Collin80
32 | - due_wire library - once again
33 | - DueTimer library - and again
34 |
35 | All libraries belong in %USERPROFILE%\Documents\Arduino\libraries (Windows) or ~/Arduino/libraries (Linux/Mac).
36 | You will need to remove -master or any other postfixes. Your library folders should be named as above.
37 |
38 | The canbus is supposed to be terminated on both ends of the bus. If you are testing with a DMOC and GEVCU then you've got two devices, each on opposing ends of the bus. So, both really should be terminated but for really short canbus lines you will probably get away with terminating just one side.
39 |
40 | If you are using a custom board then add a terminating resistor.
41 |
42 | If you are using the new prototype shield then it should already be terminated. The DMOC can be terminated by soldering a 120 ohm resistor between the canbus lines. I did this on my DMOC and hid the resistor inside the plug shroud.
43 |
44 | This software is MIT licensed:
45 |
46 | Copyright (c) 2014 Collin Kidder, Michael Neuweiler, Charles Galpin, Jack Rickard
47 |
48 | Permission is hereby granted, free of charge, to any person obtaining
49 | a copy of this software and associated documentation files (the
50 | "Software"), to deal in the Software without restriction, including
51 | without limitation the rights to use, copy, modify, merge, publish,
52 | distribute, sublicense, and/or sell copies of the Software, and to
53 | permit persons to whom the Software is furnished to do so, subject to
54 | the following conditions:
55 |
56 | The above copyright notice and this permission notice shall be included
57 | in all copies or substantial portions of the Software.
58 |
59 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
60 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
61 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
62 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
63 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
64 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
65 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
66 |
67 |
--------------------------------------------------------------------------------
/SerialConsole.h:
--------------------------------------------------------------------------------
1 | /*
2 | * SerialConsole.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 |
25 | */
26 |
27 | #ifndef SERIALCONSOLE_H_
28 | #define SERIALCONSOLE_H_
29 |
30 | #include "config.h"
31 | #include "Heartbeat.h"
32 | #include "MemCache.h"
33 | #include "config.h"
34 | #include "sys_io.h"
35 | #include "PotThrottle.h"
36 | #include "DeviceManager.h"
37 | #include "MotorController.h"
38 | #include "DmocMotorController.h" //TODO: direct reference to dmoc must be removed
39 | #include "ThrottleDetector.h"
40 | #include "ichip_2128.h"
41 |
42 | class SerialConsole {
43 | public:
44 | SerialConsole(MemCache* memCache);
45 | SerialConsole(MemCache* memCache, Heartbeat* heartbeat);
46 | void loop();
47 | void printMenu();
48 |
49 | protected:
50 | enum CONSOLE_STATE
51 | {
52 | STATE_ROOT_MENU
53 | };
54 |
55 | private:
56 | Heartbeat* heartbeat;
57 | MemCache* memCache;
58 | bool handlingEvent;
59 | char cmdBuffer[80];
60 | int ptrBuffer;
61 | int state;
62 | int loopcount;
63 | bool cancel;
64 |
65 |
66 | void init();
67 | void serialEvent();
68 | void handleConsoleCmd();
69 | void handleShortCmd();
70 | void handleConfigCmd();
71 | void resetWiReachMini();
72 | void getResponse();
73 | };
74 |
75 | #endif /* SERIALCONSOLE_H_ */
76 |
77 |
78 |
--------------------------------------------------------------------------------
/Sys_Messages.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Sys_Messages.h
3 | *
4 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining
7 | a copy of this software and associated documentation files (the
8 | "Software"), to deal in the Software without restriction, including
9 | without limitation the rights to use, copy, modify, merge, publish,
10 | distribute, sublicense, and/or sell copies of the Software, and to
11 | permit persons to whom the Software is furnished to do so, subject to
12 | the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included
15 | in all copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 | */
25 |
26 | #ifndef SYSMSG_H_
27 | #define SYSMSG_H_
28 |
29 |
30 | enum SystemMessage {
31 | MSG_STARTUP = 0x3000,
32 | MSG_SOFT_FAULT = 0x3100,
33 | MSG_HARD_FAULT = 0x3150,
34 | MSG_DISABLE = 0x3200,
35 | MSG_ENABLE = 0x3300,
36 | MSG_SET_PARAM = 0x4000,
37 | MSG_CONFIG_CHANGE = 0x4001,
38 | MSG_COMMAND = 0x4002
39 | };
40 |
41 | #endif
42 |
43 |
44 |
--------------------------------------------------------------------------------
/ThinkBatteryManager.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * ThinkBatteryManager.cpp
3 | *
4 | * Interface to the BMS which is within the Think City battery packs
5 | *
6 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 | #include "ThinkBatteryManager.h"
30 |
31 | ThinkBatteryManager::ThinkBatteryManager() : BatteryManager() {
32 | prefsHandler = new PrefHandler(THINKBMS);
33 | allowCharge = false;
34 | allowDischarge = false;
35 | commonName = "Think City BMS";
36 | }
37 |
38 | void ThinkBatteryManager::setup() {
39 | TickHandler::getInstance()->detach(this);
40 |
41 | Logger::info("add device: Th!nk City BMS (id: %X, %X)", THINKBMS, this);
42 |
43 | BatteryManager::setup(); // run the parent class version of this function
44 |
45 | //Relevant BMS messages are 0x300 - 0x30F
46 | CanHandler::getInstanceEV()->attach(this, 0x300, 0x7f0, false);
47 |
48 | TickHandler::getInstance()->attach(this, CFG_TICK_INTERVAL_BMS_THINK);
49 | }
50 |
51 | /*For all multibyte integers the format is MSB first, LSB last
52 | */
53 | void ThinkBatteryManager::handleCanFrame(CAN_FRAME *frame) {
54 | int temp;
55 | switch (frame->id) {
56 | case 0x300: //Start up message
57 | //we're not really interested in much here except whether init worked.
58 | if ((frame->data.bytes[6] & 1) == 0) //there was an initialization error!
59 | {
60 | faultHandler.raiseFault(THINKBMS, FAULT_BMS_INIT, true);
61 | allowCharge = false;
62 | allowDischarge = false;
63 | }
64 | else
65 | {
66 | faultHandler.cancelOngoingFault(THINKBMS, FAULT_BMS_INIT);
67 | }
68 | break;
69 | case 0x301: //System Data 0
70 | //first two bytes = current, next two voltage, next two DOD, last two avg. temp
71 | //readings in tenths
72 | packVoltage = (frame->data.bytes[0] * 256 + frame->data.bytes[1]);
73 | packCurrent = (frame->data.bytes[2] * 256 + frame->data.bytes[3]);
74 | break;
75 | case 0x302: //System Data 1
76 | if ((frame->data.bytes[0] & 1) == 1) //Byte 0 bit 0 = general error
77 | {
78 | faultHandler.raiseFault(THINKBMS, FAULT_BMS_MISC, true);
79 | allowDischarge = false;
80 | allowCharge = false;
81 | }
82 | else
83 | {
84 | faultHandler.cancelOngoingFault(THINKBMS, FAULT_BMS_MISC);
85 | }
86 | if ((frame->data.bytes[2] & 1) == 1) //Byte 2 bit 0 = general isolation error
87 | {
88 | faultHandler.raiseFault(THINKBMS, FAULT_HV_BATT_ISOLATION, true);
89 | allowDischarge = false;
90 | allowCharge = false;
91 | }
92 | else
93 | {
94 | faultHandler.cancelOngoingFault(THINKBMS, FAULT_HV_BATT_ISOLATION);
95 | }
96 | //Min discharge voltage = bytes 4-5 - tenths of a volt
97 | //Max discharge current = bytes 6-7 - tenths of an amp
98 | temp = (S16)(frame->data.bytes[6] * 256 + frame->data.bytes[7]);
99 | if (temp > 0) allowDischarge = true;
100 | break;
101 | case 0x303: //System Data 2
102 | //bytes 0-1 = max charge voltage (tenths of volt)
103 | //bytes 2-3 = max charge current (tenths of amp)
104 | temp = (S16)(frame->data.bytes[2] * 256 + frame->data.bytes[3]);
105 | if (temp > 0) allowCharge = true;
106 | //byte 4 bit 1 = regen braking OK, bit 2 = Discharging OK
107 | //byte 6 bit 3 = EPO (emergency power off) happened, bit 5 = battery pack fan is on
108 | break;
109 | case 0x304: //System Data 3
110 | //Byte 2 lower 4 bits = highest error category
111 | //categories: 0 = no faults, 1 = Reserved, 2 = Warning, 3 = Delayed switch off, 4 = immediate switch off
112 | //bytes 4-5 = Pack max temperature (tenths of degree C) - Signed
113 | //byte 6-7 = Pack min temperature (tenths of a degree C) - Signed
114 | lowestCellTemp = (S16)(frame->data.bytes[4] * 256 + frame->data.bytes[5]);
115 | highestCellTemp = (S16)(frame->data.bytes[6] * 256 + frame->data.bytes[7]);
116 | break;
117 | case 0x305: //System Data 4
118 | //byte 2 bits 0-3 = BMS state
119 | //0 = idle state, 1 = discharge state (contactor closed), 15 = fault state
120 | //byte 2 bit 4 = Internal HV isolation fault
121 | //byte 2 bit 5 = External HV isolation fault
122 | break;
123 | case 0x306: //System Data 5
124 | //bytes 0-1 = Equiv. internal resistance in milliohms
125 | //not recommended to rely on so probably just ignore it
126 | break;
127 | //technically there is a specification for frames 0x307 - 0x30A but I have never seen these frames
128 | //sent on the canbus system so I doubt that they are used.
129 | /*
130 | case 0x307: //System Data 6
131 | case 0x308: //System Data 7
132 | case 0x309: //System Data 8
133 | case 0x30A: //System Data 9
134 | //do we care about the serial #? Probably not.
135 | case 0x30E: //Serial # part 1
136 | case 0x30B: //Serial # part 2
137 | */
138 | }
139 | }
140 |
141 | void ThinkBatteryManager::handleTick() {
142 | BatteryManager::handleTick(); //kick the ball up to papa
143 |
144 | sendKeepAlive();
145 |
146 | }
147 |
148 | //Contactors in pack will close if we sent these two frames with all zeros.
149 | void ThinkBatteryManager::sendKeepAlive()
150 | {
151 | CAN_FRAME output;
152 | output.length = 3;
153 | output.id = 0x310;
154 | output.extended = 0; //standard frame
155 | output.rtr = 0;
156 | for (int i = 0; i < 8; i++) output.data.bytes[i] = 0;
157 | CanHandler::getInstanceEV()->sendFrame(output);
158 |
159 | output.id = 0x311;
160 | output.length = 2;
161 | CanHandler::getInstanceEV()->sendFrame(output);
162 | }
163 |
164 | DeviceId ThinkBatteryManager::getId()
165 | {
166 | return (THINKBMS);
167 | }
168 |
169 | bool ThinkBatteryManager::hasPackVoltage()
170 | {
171 | return true;
172 | }
173 |
174 | bool ThinkBatteryManager::hasPackCurrent()
175 | {
176 | return true;
177 | }
178 |
179 | bool ThinkBatteryManager::hasTemperatures()
180 | {
181 | return true;
182 | }
183 |
184 | bool ThinkBatteryManager::isChargeOK()
185 | {
186 | return allowCharge;
187 | }
188 |
189 | bool ThinkBatteryManager::isDischargeOK()
190 | {
191 | return allowDischarge;
192 | }
193 |
194 |
195 |
196 |
--------------------------------------------------------------------------------
/ThinkBatteryManager.h:
--------------------------------------------------------------------------------
1 | /*
2 | * BatteryManager.h
3 | *
4 | * Parent class for battery management / monitoring systems
5 | *
6 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 | #ifndef THINKBATT_H_
30 | #define THINKBATT_H_
31 |
32 | #include
33 | #include "config.h"
34 | #include "Device.h"
35 | #include "DeviceManager.h"
36 | #include "BatteryManager.h"
37 | #include "CanHandler.h"
38 |
39 | class ThinkBatteryManager : public BatteryManager, CanObserver
40 | {
41 | public:
42 | ThinkBatteryManager();
43 | void setup();
44 | void handleTick();
45 | void handleCanFrame(CAN_FRAME *frame);
46 | DeviceId getId();
47 | bool hasPackVoltage();
48 | bool hasPackCurrent();
49 | bool hasTemperatures();
50 | bool isChargeOK();
51 | bool isDischargeOK();
52 | protected:
53 | private:
54 | void sendKeepAlive();
55 | };
56 |
57 | #endif
58 |
59 |
60 |
--------------------------------------------------------------------------------
/Throttle.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Throttle.h
3 | *
4 | * Parent class for all throttle controllers, be they canbus or pot or hall effect, etc
5 | * This class is virtually totally virtual. The derived classes redefine most everything
6 | * about this class. It might even be a good idea to make the class totally abstract.
7 |
8 |
9 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining
12 | a copy of this software and associated documentation files (the
13 | "Software"), to deal in the Software without restriction, including
14 | without limitation the rights to use, copy, modify, merge, publish,
15 | distribute, sublicense, and/or sell copies of the Software, and to
16 | permit persons to whom the Software is furnished to do so, subject to
17 | the following conditions:
18 |
19 | The above copyright notice and this permission notice shall be included
20 | in all copies or substantial portions of the Software.
21 |
22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 |
30 | */
31 |
32 | #ifndef THROTTLE_H_
33 | #define THROTTLE_H_
34 |
35 | #include
36 | #include "config.h"
37 | #include "Device.h"
38 |
39 | /*
40 | * Data structure to hold raw signal(s) of the throttle.
41 | * E.g. for a three pot pedal, all signals could be used.
42 | */
43 | struct RawSignalData {
44 | int32_t input1; // e.g. pot #1 or the signal from a can bus throttle
45 | int32_t input2; // e.g. pot #2 (optional)
46 | int32_t input3; // e.g. pot #3 (optional)
47 | };
48 |
49 | /*
50 | * A abstract class to hold throttle configuration parameters.
51 | * Can be extended by the subclass.
52 | */
53 | class ThrottleConfiguration: public DeviceConfiguration {
54 | public:
55 | uint16_t positionRegenMaximum, positionRegenMinimum; // throttle position where regen is highest and lowest
56 | uint16_t positionForwardMotionStart, positionHalfPower; // throttle position where forward motion starts and the mid point of throttle
57 | uint8_t maximumRegen; // percentage of max torque allowable for regen at maximum level
58 | uint8_t minimumRegen; // percentage of max torque allowable for regen at minimum level
59 | uint8_t creep; // percentage of torque used for creep function (imitate creep of automatic transmission, set 0 to disable)
60 | };
61 |
62 | /*
63 | * Abstract class for all throttle implementations.
64 | */
65 | class Throttle: public Device {
66 | public:
67 | enum ThrottleStatus {
68 | OK,
69 | ERR_LOW_T1,
70 | ERR_LOW_T2,
71 | ERR_HIGH_T1,
72 | ERR_HIGH_T2,
73 | ERR_MISMATCH,
74 | ERR_MISC
75 | };
76 |
77 | Throttle();
78 | virtual int16_t getLevel();
79 | void handleTick();
80 | virtual ThrottleStatus getStatus();
81 | virtual bool isFaulted();
82 | virtual DeviceType getType();
83 |
84 | virtual RawSignalData *acquireRawSignal();
85 | void loadConfiguration();
86 | void saveConfiguration();
87 |
88 | protected:
89 | ThrottleStatus status;
90 | virtual bool validateSignal(RawSignalData *);
91 | virtual uint16_t calculatePedalPosition(RawSignalData *);
92 | virtual int16_t mapPedalPosition(int16_t);
93 | uint16_t normalizeAndConstrainInput(int32_t, int32_t, int32_t);
94 | int32_t normalizeInput(int32_t, int32_t, int32_t);
95 |
96 | private:
97 | int16_t level; // the final signed throttle level. [-1000, 1000] in permille of maximum
98 | };
99 |
100 | #endif
101 |
102 |
103 |
--------------------------------------------------------------------------------
/ThrottleDetector.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ThrottleDetector.h
3 | *
4 | * This class can detect up to two potentiometers and determine their min/max values,
5 | * whether they read low to high or high to low, and if the second potentiometer is
6 | * the inverse of the first.
7 | *
8 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining
11 | a copy of this software and associated documentation files (the
12 | "Software"), to deal in the Software without restriction, including
13 | without limitation the rights to use, copy, modify, merge, publish,
14 | distribute, sublicense, and/or sell copies of the Software, and to
15 | permit persons to whom the Software is furnished to do so, subject to
16 | the following conditions:
17 |
18 | The above copyright notice and this permission notice shall be included
19 | in all copies or substantial portions of the Software.
20 |
21 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
25 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 |
29 | */
30 |
31 | #ifndef THROTTLE_DETECTOR_H_
32 | #define THROTTLE_DETECTOR_H_
33 |
34 | #include "PotThrottle.h"
35 | #include "Logger.h"
36 | #include "DeviceManager.h"
37 |
38 | class Throttle;
39 |
40 | class ThrottleDetector : public TickObserver {
41 |
42 | public:
43 | ThrottleDetector(Throttle *throttle);
44 | ~ThrottleDetector();
45 | void handleTick();
46 | void detect();
47 |
48 | private:
49 | enum DetectionState {
50 | DoNothing,
51 | DetectMinWait,
52 | DetectMinCalibrate,
53 | DetectMaxWait,
54 | DetectMaxCalibrate
55 | };
56 |
57 | void detectMinWait();
58 | void detectMinCalibrate();
59 | void detectMaxWait();
60 | void detectMaxCalibrate();
61 | void displayCalibratedValues(bool minPedal);
62 | void resetValues();
63 | void readThrottleValues();
64 | int checkLinear(uint16_t, uint16_t);
65 | int checkInverse(uint16_t, uint16_t);
66 | uint16_t normalize(uint16_t sensorValue, uint16_t sensorMin, uint16_t sensorMax, uint16_t constrainMin, uint16_t constrainMax);
67 |
68 | Throttle *throttle;
69 | PotThrottleConfiguration *config;
70 | DetectionState state;
71 | unsigned long startTime;
72 | int potentiometerCount; // the number of potentiometers detected
73 | uint16_t throttle1Min; // the minimum value of throttle1
74 | uint16_t throttle1Max; // the maximum value of throttle1
75 | uint16_t throttle2Min; // the minimum value of throttle2
76 | uint16_t throttle2Max; // the maximum value of throttle2
77 | uint8_t throttleSubType; // the throttle sub type
78 | bool throttle1HighLow; // true if throttle1 ranges from highest to lowest value as the pedal is pressed
79 | bool throttle2HighLow; // true if throttle2 ranges from highest to lowest value as the pedal is pressed
80 | bool throttle2Inverse; // true if throttle2 values are the opposite of the throttle1 values.
81 | int throttle1MinRest; // minimum sensor value at rest
82 | int throttle1MaxRest; // minimum sensor value at rest
83 | int throttle2MinRest; // minimum sensor value at rest
84 | int throttle2MaxRest; // maximum sensor value at rest
85 | int throttle1MinFluctuationPercent;
86 | int throttle1MaxFluctuationPercent;
87 | int throttle2MinFluctuationPercent;
88 | int throttle2MaxFluctuationPercent;
89 | int maxThrottleReadingDeviationPercent;
90 | // stats/counters when sampling
91 | static const int maxSamples = 300;
92 | int sampleCount;
93 | int linearCount;
94 | int inverseCount;
95 | uint16_t throttle1Values[maxSamples];
96 | uint16_t throttle2Values[maxSamples];
97 |
98 | };
99 |
100 | #endif /* THROTTLE_DETECTOR_H_ */
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/TickHandler.h:
--------------------------------------------------------------------------------
1 | /*
2 | * TickHandler.h
3 | *
4 | * Class where TickObservers can register to be triggered
5 | * on a certain interval.
6 | *
7 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining
10 | a copy of this software and associated documentation files (the
11 | "Software"), to deal in the Software without restriction, including
12 | without limitation the rights to use, copy, modify, merge, publish,
13 | distribute, sublicense, and/or sell copies of the Software, and to
14 | permit persons to whom the Software is furnished to do so, subject to
15 | the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included
18 | in all copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 |
28 | */
29 |
30 | #ifndef TICKHANDLER_H_
31 | #define TICKHANDLER_H_
32 |
33 | #include "config.h"
34 | #include
35 | #include "Logger.h"
36 |
37 | #define NUM_TIMERS 9
38 |
39 | class TickObserver {
40 | public:
41 | virtual void handleTick();
42 | };
43 |
44 |
45 | class TickHandler {
46 | public:
47 | static TickHandler *getInstance();
48 | void attach(TickObserver *observer, uint32_t interval);
49 | void detach(TickObserver *observer);
50 | void handleInterrupt(int timerNumber); // must be public when from the non-class functions
51 | #ifdef CFG_TIMER_USE_QUEUING
52 | void cleanBuffer();
53 | void process();
54 | #endif
55 |
56 | protected:
57 |
58 | private:
59 | struct TimerEntry {
60 | long interval; // interval of timer
61 | TickObserver *observer[CFG_TIMER_NUM_OBSERVERS]; // array of pointers to observers with this interval
62 | };
63 | TimerEntry timerEntry[NUM_TIMERS]; // array of timer entries (9 as there are 9 timers)
64 | static TickHandler *tickHandler;
65 | #ifdef CFG_TIMER_USE_QUEUING
66 | TickObserver *tickBuffer[CFG_TIMER_BUFFER_SIZE];
67 | volatile uint16_t bufferHead, bufferTail;
68 | #endif
69 |
70 | TickHandler();
71 | int findTimer(long interval);
72 | int findObserver(int timerNumber, TickObserver *observer);
73 | };
74 |
75 | void timer0Interrupt();
76 | void timer1Interrupt();
77 | void timer2Interrupt();
78 | void timer3Interrupt();
79 | void timer4Interrupt();
80 | void timer5Interrupt();
81 | void timer6Interrupt();
82 | void timer7Interrupt();
83 | void timer8Interrupt();
84 |
85 | #endif /* TICKHANDLER_H_ */
86 |
87 |
88 |
--------------------------------------------------------------------------------
/constants.h:
--------------------------------------------------------------------------------
1 | /*
2 | * constants.h
3 | *
4 | * Defines the global / application wide constants
5 | *
6 |
7 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
8 |
9 | Permission is hereby granted, free of charge, to any person obtaining
10 | a copy of this software and associated documentation files (the
11 | "Software"), to deal in the Software without restriction, including
12 | without limitation the rights to use, copy, modify, merge, publish,
13 | distribute, sublicense, and/or sell copies of the Software, and to
14 | permit persons to whom the Software is furnished to do so, subject to
15 | the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included
18 | in all copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 | * Author: Michael Neuweiler
28 | */
29 |
30 | #ifndef CONSTANTS_H_
31 | #define CONSTANTS_H_
32 |
33 | namespace Constants {
34 | // misc
35 | static const char* trueStr = "true";
36 | static const char* falseStr = "false";
37 | static const char* notAvailable = "n/a";
38 | static const char* ichipCommandPrefix = "AT+i";
39 | static const char* ichipErrorString = "I/ERROR";
40 |
41 | // configuration
42 |
43 | static const char* numThrottlePots = "numThrottlePots";
44 | static const char* throttleSubType = "throttleSubType";
45 | static const char* throttleMin1 = "throttleMin1";
46 | static const char* throttleMin2 = "throttleMin2";
47 | static const char* throttleMax1 = "throttleMax1";
48 | static const char* throttleMax2 = "throttleMax2";
49 | static const char* throttleRegenMax = "throttleRegenMax";
50 | static const char* throttleRegenMin = "throttleRegenMin";
51 | static const char* throttleFwd = "throttleFwd";
52 | static const char* throttleMap = "throttleMap";
53 | static const char* throttleMinRegen = "throttleMinRegen";
54 | static const char* throttleMaxRegen = "throttleMaxRegen";
55 | static const char* throttleCreep = "throttleCreep";
56 | static const char* brakeMin = "brakeMin";
57 | static const char* brakeMax = "brakeMax";
58 | static const char* brakeMinRegen = "brakeMinRegen";
59 | static const char* brakeMaxRegen = "brakeMaxRegen";
60 | static const char* brakeLight = "brakeLight";
61 | static const char* revLight = "revLight";
62 | static const char* enableIn = "enableIn";
63 | static const char* reverseIn = "reverseIn";
64 |
65 | static const char* speedMax = "speedMax";
66 | static const char* torqueMax = "torqueMax";
67 | static const char* logLevel = "logLevel";
68 |
69 | // status
70 | static const char* timeRunning = "timeRunning";
71 | static const char* torqueRequested = "torqueRequested";
72 | static const char* torqueActual = "torqueActual";
73 | static const char* throttle = "throttle";
74 | static const char* brake = "brake";
75 | static const char* motorMode = "motorMode";
76 | static const char* speedRequested = "speedRequested";
77 | static const char* speedActual = "speedActual";
78 | static const char* dcVoltage = "dcVoltage";
79 | static const char* nominalVolt = "nominalVolt";
80 | static const char* dcCurrent = "dcCurrent";
81 | static const char* acCurrent = "acCurrent";
82 | static const char* kiloWattHours = "kiloWattHours";
83 | static const char* bitfield1 = "bitfield1";
84 | static const char* bitfield2 = "bitfield2";
85 | static const char* bitfield3 = "bitfield3";
86 | static const char* bitfield4 = "bitfield4";
87 | static const char* running = "running";
88 | static const char* faulted = "faulted";
89 | static const char* warning = "warning";
90 | static const char* gear = "gear";
91 | static const char* tempMotor = "tempMotor";
92 | static const char* tempInverter = "tempInverter";
93 | static const char* tempSystem = "tempSystem";
94 | static const char* mechPower = "mechPower";
95 | static const char* prechargeR = "prechargeR";
96 | static const char* prechargeRelay = "prechargeRelay";
97 | static const char* mainContactorRelay = "mainContactorRelay";
98 | static const char* coolFan = "coolFan";
99 | static const char* coolOn = "coolOn";
100 | static const char* coolOff = "coolOff";
101 | static const char* validChecksum = "Valid checksum, using stored config values";
102 | static const char* invalidChecksum = "Invalid checksum, using hard coded config values";
103 | static const char* valueOutOfRange = "value out of range: %l";
104 | static const char* normalOperation = "normal operation restored";
105 | }
106 |
107 | #endif /* CONSTANTS_H_ */
108 |
109 |
110 |
--------------------------------------------------------------------------------
/docs/Design Drawings.vsd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/collin80/GEVCU/8a06011344b8e8840a7ac3f6d97b264d14bbe2bf/docs/Design Drawings.vsd
--------------------------------------------------------------------------------
/docs/GEVCU pinout.txt:
--------------------------------------------------------------------------------
1 | Pin 1 - +12V Input
2 | Pin 3 - +12V output for first digital input
3 | Pin 7 - EXT GND connection to chassis ground / Battery - (in my case)
4 | Pins 9 & 10 - First canbus
5 | Pin 19 - Gnd connection for first and second analog inputs (Throttle)
6 | Pin 20 - First analog input (Throttle)
7 | Pin 21 - Second analog input (Throttle)
8 | Pin 22 - Third analog input (brake / testing input for me)
9 | Pin 23 - Fourth analog input (test pot on my wires)
10 | Pin 24 - +5V power for first and second analog inputs (Throttle)
11 | Pin 26 - +5V power for third and fourth analog inputs (test pots for me,
12 | probably brake transducer for you)
13 | Pin 30 - Gnd connection for third and fourth analog inputs (Brake / Testing)
14 | Pin 32 - First digital input. Tied to pin 3 above through a switch
15 |
16 | I used a gnd at pin 19 for one of the gnds. It really doesn't matter
17 | which one you use. All four (19,29,30,31) are equivalent.
18 |
--------------------------------------------------------------------------------
/docs/GEVCU-35pinout.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/collin80/GEVCU/8a06011344b8e8840a7ac3f6d97b264d14bbe2bf/docs/GEVCU-35pinout.jpg
--------------------------------------------------------------------------------
/docs/GEVCU1-1.03.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/collin80/GEVCU/8a06011344b8e8840a7ac3f6d97b264d14bbe2bf/docs/GEVCU1-1.03.docx
--------------------------------------------------------------------------------
/docs/ThrottleFiltering.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/collin80/GEVCU/8a06011344b8e8840a7ac3f6d97b264d14bbe2bf/docs/ThrottleFiltering.xlsx
--------------------------------------------------------------------------------
/docs/UQMplug.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/collin80/GEVCU/8a06011344b8e8840a7ac3f6d97b264d14bbe2bf/docs/UQMplug.jpg
--------------------------------------------------------------------------------
/docs/gevcumanual403.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/collin80/GEVCU/8a06011344b8e8840a7ac3f6d97b264d14bbe2bf/docs/gevcumanual403.docx
--------------------------------------------------------------------------------
/docs/howtocreatemodule.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/collin80/GEVCU/8a06011344b8e8840a7ac3f6d97b264d14bbe2bf/docs/howtocreatemodule.docx
--------------------------------------------------------------------------------
/gearsandopstates.txt:
--------------------------------------------------------------------------------
1 | running = true if we have completed settup
2 | online = true if we are receiving CAN from DMOC
3 | alive
4 |
5 | activitycount = increments with each major frame received from DMOc
6 |
7 | operationState= DISABLED = 0,
8 | STANDBY = 1,
9 | ENABLE = 2,
10 | POWERDOWN = 3
11 | void setOpState(OperationState op) ; operationState
12 | OperationState getOpState() ; operationState
13 |
14 | OperationState operationState; We set and get this one, either in DMOC or in Motor
15 | OperationState actualState This can be checked directly - it is actually set by DMOC645
16 |
17 |
18 | selectedGear NEUTRAL =0
19 | DRIVE =1
20 | REVERSE=2
21 | ERROR=3
22 |
23 | void setSelectedGear(Gears gear); sets selectedGear motorcontroller version
24 |
25 | Gears getSelectedGear();
26 | setGear(Gears gear) - sets selectedGear - DMOC version
27 | Gears selectedGear;
28 | Gears actualGear;
29 |
30 |
31 |
32 | GearSwitch GS_NEUTRAL,
33 | GS_FORWARD,
34 | GS_REVERSE,
35 | GS_FAULT
36 |
37 | getGearSwitch()
38 | setGear()
39 |
40 |
41 | we do send alive, opstate, and gear information to DMOC645 as part of SendCmd1.
--------------------------------------------------------------------------------
/ichip_2128.h:
--------------------------------------------------------------------------------
1 | /*
2 | * ichip_2128.h
3 | *
4 | * Class to interface with the ichip 2128 based wifi adapter we're using on our board
5 | *
6 | * Created: 4/18/2013 8:10:00 PM
7 | * Author: Collin Kidder
8 | */
9 |
10 | /* The wifi adapter must be able to either create an adhoc network or connect to an existing network
11 | * the EEPROM has three entries for storing networks we'd like to be able to automatically join
12 | * If none of those networks can be found then the device will automatically try to form an
13 | * adhoc network with the 4th entry which is dedicated to that purpose.
14 | * All commands to the wifi start with "AT+i" and end with CR (ascii 13)
15 | *
16 | * Commands:
17 | * RP11 - get list of access points in range
18 | * RP7 - Status report (bit 10 if remote has changed a param)
19 | * RP8 - get system time
20 | * WWW - turn on HTTP server
21 | * WNXT - get next changed parameter (returns = or blank line at end)
22 | * WLTR - get/set transfer rate WIFI (0=max, 1=slow - 13 = max)
23 | * WRFU - turn on WIFI
24 | * WRFD - turn off wifi
25 | * WLBM - B wifi mode
26 | * WLGM - G wifi mode
27 | * AWPS - activate WPS mode
28 | * DIP - default IP address (set to 0.0.0.0 for DHCP client)
29 | * IPG - gateway address
30 | * SNET - subnet mask
31 | * DNS1 - DNS server
32 | * IPA - our IP address
33 | * DPSZ - DHCP server pool size (0 to disable server)
34 | * DSLT - DHCP server lease time
35 | * NTOD=1 - turn on time client (NTP)
36 | * WLCH - set WIFI channel
37 | * WLSI - SSID
38 | * WLWM - WEP MODE (0=disabled 1=64bit 2=128bit)
39 | * WLKx - WEP key
40 | * WLPP - WPA-PSK key
41 | * WSEC - 0 = TKIP 1 = AES
42 | * WSIx - x=0-9 = set SSIDs to associate with
43 | * WPPx - x=0-9 WPA pass phrases
44 | * WKYx - x=0-9 WEP keys
45 | * WSTx - x=0-9 security type = (0=none, 1=wep64, 2=WEP128,3=WPA/TKIP 4=WPA2
46 | *
47 | *
48 | * Web Parameters getting/setting
49 | * = set
50 | * ? get
51 | *
52 |
53 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
54 |
55 | Permission is hereby granted, free of charge, to any person obtaining
56 | a copy of this software and associated documentation files (the
57 | "Software"), to deal in the Software without restriction, including
58 | without limitation the rights to use, copy, modify, merge, publish,
59 | distribute, sublicense, and/or sell copies of the Software, and to
60 | permit persons to whom the Software is furnished to do so, subject to
61 | the following conditions:
62 |
63 | The above copyright notice and this permission notice shall be included
64 | in all copies or substantial portions of the Software.
65 |
66 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
67 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
68 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
69 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
70 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
71 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
72 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
73 |
74 | */
75 |
76 | #ifndef ICHIP2128_H_
77 | #define ICHIP2128_H_
78 |
79 | #include
80 | #include "config.h"
81 | #include "constants.h"
82 | #include "DeviceManager.h"
83 | #include "PotThrottle.h"
84 | #include "Sys_Messages.h"
85 | #include "DeviceTypes.h"
86 | #include "ELM327Processor.h"
87 | //#include "sys_io.h"
88 |
89 |
90 | extern PrefHandler *sysPrefs;
91 |
92 | enum ICHIP_COMM_STATE {IDLE, GET_PARAM, SET_PARAM, START_TCP_LISTENER, GET_ACTIVE_SOCKETS, POLL_SOCKET, SEND_SOCKET, GET_SOCKET};
93 |
94 | /*
95 | * The extended configuration class with additional parameters for ichip WLAN
96 | */
97 | class WifiConfiguration : public DeviceConfiguration {
98 | public:
99 | };
100 |
101 | /**
102 | * Cache of param values to avoid sending an update unless changed
103 | */
104 | struct ParamCache {
105 | uint32_t timeRunning;
106 | int16_t torqueRequested;
107 | int16_t torqueActual;
108 | int16_t throttle;
109 | int16_t brake;
110 | bool brakeNotAvailable;
111 | int16_t speedRequested;
112 | int16_t speedActual;
113 | MotorController::PowerMode powerMode;
114 | int16_t dcVoltage;
115 | int16_t dcCurrent;
116 | int16_t acCurrent;
117 | int16_t nominalVolt;
118 | int16_t kiloWattHours;
119 | uint32_t bitfield1;
120 | uint32_t bitfield2;
121 | uint32_t bitfield3;
122 | uint32_t bitfield4;
123 | bool running;
124 | bool faulted;
125 | bool warning;
126 | MotorController::Gears gear;
127 | int16_t tempMotor;
128 | int16_t tempInverter;
129 | int16_t tempSystem;
130 | int16_t mechPower;
131 | int16_t prechargeR;
132 | int8_t prechargeRelay;
133 | int8_t mainContactorRelay;
134 | int8_t coolFan;
135 | int8_t coolOn;
136 | int8_t coolOff;
137 | int8_t brakeLight;
138 | int8_t revLight;
139 | int8_t enableIn;
140 | int8_t reverseIn;
141 | };
142 |
143 | struct SendBuff {
144 | String cmd;
145 | ICHIP_COMM_STATE state;
146 | };
147 |
148 | class ICHIPWIFI : public Device {
149 | public:
150 |
151 | ICHIPWIFI();
152 | ICHIPWIFI(USARTClass *which);
153 | void setup(); //initialization on start up
154 | void handleTick(); //periodic processes
155 | void handleMessage(uint32_t messageType, void* message);
156 | DeviceType getType();
157 | DeviceId getId();
158 | void loop();
159 | char *getTimeRunning();
160 |
161 |
162 | void loadConfiguration();
163 | void saveConfiguration();
164 | void loadParameters();
165 |
166 |
167 | private:
168 | ELM327Processor *elmProc;
169 | USARTClass* serialInterface; //Allows for retargetting which serial port we use
170 | char incomingBuffer[128]; //storage for one incoming line
171 | int ibWritePtr; //write position into above buffer
172 | SendBuff sendingBuffer[64];
173 | int psWritePtr;
174 | int psReadPtr;
175 | int tickCounter;
176 | int currReply;
177 | char buffer[30]; // a buffer for various string conversions
178 | ParamCache paramCache;
179 | ICHIP_COMM_STATE state;
180 | bool didParamLoad;
181 | bool didTCPListener;
182 | int listeningSocket;
183 | int activeSockets[4]; //support for four sockets. Lowest byte is socket #, next byte is size of data waiting in that socket
184 | uint32_t lastSentTime;
185 | String lastSentCmd;
186 | ICHIP_COMM_STATE lastSentState;
187 |
188 | void getNextParam(); //get next changed parameter
189 | void getParamById(String paramName); //try to retrieve the value of the given parameter
190 | void setParam(String paramName, String value); //set the given parameter with the given string
191 | void setParam(String paramName, int32_t value);
192 | void setParam(String paramName, int16_t value);
193 | void setParam(String paramName, uint32_t value);
194 | void setParam(String paramName, uint16_t value);
195 | void setParam(String paramName, uint8_t value);
196 | void setParam(String paramName, float value, int precision);
197 | void sendCmd(String cmd);
198 | void sendCmd(String cmd, ICHIP_COMM_STATE cmdstate);
199 | void sendToSocket(int socket, String data);
200 | void processParameterChange(char *response);
201 |
202 |
203 | };
204 |
205 | #endif
206 |
207 |
208 |
--------------------------------------------------------------------------------
/readme.eclipse.txt:
--------------------------------------------------------------------------------
1 | How to get the Eclipse IDE running with GEVCU:
2 |
3 | * Install 32-bit or 64-bit version of Java JRE/JDK and "Eclipse IDE for C/C++ Developers Eclipse IDE for C/C++ Developers" (do not mix 32/64bit versions)
4 | * Start eclipse with a new workspace and 32-bit or 64-bit JRE/JDK respectively ("eclipse -vm /bin")
5 | * Install Arduino plug-in from http://www.baeyens.it/eclipse/V2 (Important: un-check "Group items by category" to see the plugin)
6 | * Restart eclipse if asked
7 | * Window -> Preferences -> C/C++ -> File Types -> New -> Pattern: *.ino Type: C++ Source File
8 | * Window -> Preferences -> Arduino: verify the Arduino IDE path (must point to 1.5.5) and
9 | the Private Library path (where you store additional libs), don't check the "Disable RTXT" checkbox
10 | * Copy the file ".project.copy" and rename the copy to ".project" (.project is in .gitignore which will prevent any upstream changes due to absolute paths in it)
11 | * File -> Import... -> General -> Existing Projects into Workspace -> enter GEVCU source directory as root directory
12 | * Right click the imported project -> Properties -> Arduino -> Change board and port (if necessary) -> OK
13 | This will cause the absolute paths to be corrected in the .project file
14 | * Select the project and click on "Verify". The project should compile.
15 |
16 | Note 1: In case you want to re-compile the entire souce tree, just delete the entire "Release" directory.
17 | It will be recreated automatically.
18 |
19 | Note 2: If the editor shows some errors in the code which should not be or if code completion doesn't
20 | complete as desired, right click the project -> Index -> Rebuild and open the file in the browser.
21 |
--------------------------------------------------------------------------------
/sys_io.h:
--------------------------------------------------------------------------------
1 | /*
2 | * sys_io.h
3 | *
4 | * Handles raw interaction with system I/O
5 | *
6 | Copyright (c) 2013 Collin Kidder, Michael Neuweiler, Charles Galpin
7 |
8 | Permission is hereby granted, free of charge, to any person obtaining
9 | a copy of this software and associated documentation files (the
10 | "Software"), to deal in the Software without restriction, including
11 | without limitation the rights to use, copy, modify, merge, publish,
12 | distribute, sublicense, and/or sell copies of the Software, and to
13 | permit persons to whom the Software is furnished to do so, subject to
14 | the following conditions:
15 |
16 | The above copyright notice and this permission notice shall be included
17 | in all copies or substantial portions of the Software.
18 |
19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
23 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 |
27 | */
28 |
29 |
30 | #ifndef SYS_IO_H_
31 | #define SYS_IO_H_
32 |
33 | #include
34 | #include "config.h"
35 | #include "eeprom_layout.h"
36 | #include "PrefHandler.h"
37 |
38 | typedef struct {
39 | uint16_t offset;
40 | uint16_t gain;
41 | } ADC_COMP;
42 |
43 | void setup_sys_io();
44 | uint16_t getAnalog(uint8_t which); //get value of one of the 4 analog inputs
45 | uint16_t getDiffADC(uint8_t which);
46 | uint16_t getRawADC(uint8_t which);
47 | boolean getDigital(uint8_t which); //get value of one of the 4 digital inputs
48 | void setOutput(uint8_t which, boolean active); //set output high or not
49 | boolean getOutput(uint8_t which); //get current value of output state (high?)
50 | void setupFastADC();
51 | void sys_io_adc_poll();
52 | void sys_early_setup();
53 | void sys_boot_setup();
54 |
55 | #endif
56 |
57 |
58 |
--------------------------------------------------------------------------------
/util/BBESAB0801.IMF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/collin80/GEVCU/8a06011344b8e8840a7ac3f6d97b264d14bbe2bf/util/BBESAB0801.IMF
--------------------------------------------------------------------------------
/util/MultiSerial/MultiSerial.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Transmit serial data back and forth between two ports
3 | in order to flash new firmware to ichip with the ichip config tool.
4 |
5 | Note: Steps 1-5 have to be completed within 30 seconds (30000ms)
6 |
7 | Steps:
8 | 1) reset arduino (e.g. power cycle)
9 | 2) start ichip software
10 | 3) menu "serial ports", select com port of ardiuno, set baud rate to 9600
11 | 4) click on "ichip uploader via serial"
12 | 5) select EBI flash 16 Megabit (if window doesn't appear, start over, act faster)
13 | 6) Click FW Update, select .imf file and wait until finished, close ichip program
14 | 7) power cycle arduino/gevcu and wait 20-30sec
15 | 8) menu "serial ports", set baud rate to 115200
16 | 9) go to configuration page
17 |
18 | check-out http://www.youtube.com/watch?v=vS60htz6h1g at 00:35:00
19 |
20 | */
21 |
22 | bool flag = true;
23 | void setup() {
24 | SerialUSB.begin(9600); // use SerialUSB only as the programming port doesn't work
25 | Serial2.begin(9600); // use Serial3 for GEVCU2, use Serial2 for GEVCU3+4
26 | /* pinMode(43, OUTPUT);
27 | digitalWrite(43,HIGH);
28 | delay(3000);
29 | digitalWrite(43,LOW);
30 | pinMode(18, OUTPUT);
31 | digitalWrite(18, LOW);*/
32 | }
33 |
34 | void loop() {
35 | while (Serial2.available()) {
36 | SerialUSB.write(Serial2.read());
37 | }
38 | while (SerialUSB.available()) {
39 | Serial2.write(SerialUSB.read());
40 | }
41 |
42 | //// if (millis() > 6000) {
43 | // digitalWrite(18, HIGH);
44 | // }
45 |
46 | //if (flag && millis() > 30000) {
47 | // SerialUSB.begin(115200);
48 | // Serial2.begin(115200);
49 | // flag = false;
50 | //}
51 | }
52 |
--------------------------------------------------------------------------------
/util/connectTOap/connectTOap.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Transmit serial data back and forth between two ports
3 | in order to flash new firmware to ichip with the ichip config tool.
4 |
5 | Note: Steps 1-5 have to be completed within 30 seconds (30000ms)
6 |
7 | Steps:
8 | 1) reset arduino (e.g. power cycle)
9 | 2) start ichip software
10 | 3) menu "serial ports", select com port of ardiuno, set baud rate to 9600
11 | 4) click on "ichip uploader via serial"
12 | 5) select EBI flash 16 Megabit (if window doesn't appear, start over, act faster)
13 | 6) Click FW Update, select .imf file and wait until finished, close ichip program
14 | 7) power cycle arduino/gevcu and wait 20-30sec
15 | 8) menu "serial ports", set baud rate to 115200
16 | 9) go to configuration page
17 |
18 | check-out http://www.youtube.com/watch?v=vS60htz6h1g at 00:35:00
19 |
20 | */
21 | char inbyte;
22 | bool flag = true;
23 | void setup() {
24 | SerialUSB.begin(9600); // use SerialUSB only as the programming port doesn't work
25 | Serial2.begin(9600); // use Serial3 for GEVCU2, use Serial2 for GEVCU3+4
26 | // pinMode(43, INPUT);
27 | pinMode(42, OUTPUT);
28 | digitalWrite(42, LOW);
29 | }
30 |
31 | void loop() {
32 | while (Serial2.available()) {
33 | SerialUSB.write(Serial2.read());
34 | }
35 | while (SerialUSB.available()) {
36 | inbyte=SerialUSB.read();
37 | if (inbyte=='~'){sendcommandlist();}
38 | else {Serial2.write(inbyte);}
39 | }
40 |
41 | if (millis() > 6000) {
42 | digitalWrite(42, HIGH);
43 | }
44 |
45 |
46 | }
47 |
48 | void sendcommandlist()
49 | {
50 | SerialUSB.println("Sending commands....");
51 |
52 | sendmessage("AT+iFD");//Clear all options
53 | sendmessage("AT+iHIF=1");//Host connection set to serial port
54 | sendmessage("AT+iBDRA");//Automatic baud rate on host serial port
55 | sendmessage("AT+iRP1");//Automatic baud rate on host serial port
56 |
57 | //sendmessage("AT+iWRST");//Wireless chip reset
58 | //sendmessage("AT+iWLBM"); //Set to 802.11b
59 | //sendmessage("AT+iWEBP=80");//Website port number
60 | //sendmessage("AT+iWLCH=3"); //Wireless channel
61 | sendmessage("AT+iWLSI=riverhouse");//SSID
62 | sendmessage("AT+iDIP=192.168.1.46");//default ip
63 | //sendmessage("AT+iSNET=255.255.255.0");//subnet
64 | //sendmessage("AT+iDPSZ=6");//DHCP pool size
65 | //sendmessage("AT+iWST0=0");//Connection security wap/wep/wap2
66 | //sendmessage("AT+iWLPW=14");//Max radio power
67 | //sendmessage("AT+iWRFU"); //Radio on
68 |
69 | sendmessage("AT+iRPG=secret");
70 | sendmessage("AT+iWPWD=secret");
71 | sendmessage("AT+iAWS=1");//Website on
72 | //sendmessage("AT+iSTAP=1");//Act as AP
73 | sendmessage("AT+iDOWN");//Powercycle reset
74 |
75 | SerialUSB.println("Command list completed....");
76 | }
77 |
78 | void sendmessage(char* message)
79 | {
80 | Serial2.println(message);
81 | delay(700);
82 | while (Serial2.available()) {SerialUSB.write(Serial2.read());}
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/util/connectasAP/connectasAP.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Transmit serial data back and forth between two ports
3 | in order to flash new firmware to ichip with the ichip config tool.
4 |
5 | Note: Steps 1-5 have to be completed within 30 seconds (30000ms)
6 |
7 | Steps:
8 | 1) reset arduino (e.g. power cycle)
9 | 2) start ichip software
10 | 3) menu "serial ports", select com port of ardiuno, set baud rate to 9600
11 | 4) click on "ichip uploader via serial"
12 | 5) select EBI flash 16 Megabit (if window doesn't appear, start over, act faster)
13 | 6) Click FW Update, select .imf file and wait until finished, close ichip program
14 | 7) power cycle arduino/gevcu and wait 20-30sec
15 | 8) menu "serial ports", set baud rate to 115200
16 | 9) go to configuration page
17 |
18 | check-out http://www.youtube.com/watch?v=vS60htz6h1g at 00:35:00
19 |
20 | */
21 | char inbyte;
22 | bool flag = true;
23 | void setup() {
24 | SerialUSB.begin(9600); // use SerialUSB only as the programming port doesn't work
25 | Serial2.begin(9600); // use Serial3 for GEVCU2, use Serial2 for GEVCU3+4
26 | // pinMode(43, INPUT);
27 | //pinMode(18, OUTPUT);
28 | //digitalWrite(18, LOW);
29 | }
30 |
31 | void loop() {
32 | while (Serial2.available()) {
33 | SerialUSB.write(Serial2.read());
34 | }
35 | while (SerialUSB.available()) {
36 | inbyte=SerialUSB.read();
37 | if (inbyte=='~'){sendcommandlist();}
38 | else {Serial2.write(inbyte);}
39 | }
40 |
41 | //if (millis() > 6000) {
42 | // digitalWrite(18, HIGH);
43 | // }
44 |
45 |
46 | }
47 |
48 | void sendcommandlist()
49 | {
50 | SerialUSB.println("Sending commands....");
51 |
52 | //sendmessage("AT+iFD");//Clear all options
53 | sendmessage("AT+iHIF=1");//Host connection set to serial port
54 | sendmessage("AT+iBDRA");//Automatic baud rate on host serial port
55 |
56 | sendmessage("AT+iRPG=secret");
57 | sendmessage("AT+iWPWD=secret");
58 | //sendmessage("AT+iWRST");//Wireless chip reset
59 | //sendmessage("AT+iWLBM"); //Set to 802.11b
60 | //sendmessage("AT+iWEBP=80");//Website port number
61 | //sendmessage("AT+iWLCH=3"); //Wireless channel
62 | sendmessage("AT+iWLSI=GEVCU");//SSID
63 | sendmessage("AT+iSTAP=1");//Act as AP
64 | sendmessage("AT+iDIP=10.0.0.1");//default ip
65 | //sendmessage("AT+iSNET=255.255.255.0");//subnet
66 | sendmessage("AT+iDPSZ=8");//DHCP pool size
67 | //sendmessage("AT+iWST0=0");//Connection security wap/wep/wap2
68 | //sendmessage("AT+iWLPW=14");//Max radio power
69 | //sendmessage("AT+iWRFU"); //Radio on
70 |
71 | sendmessage("AT+iAWS=1");//Website on
72 | //sendmessage("AT+iSTAP=1");//Act as AP
73 | sendmessage("AT+iDOWN");//Powercycle reset
74 |
75 | SerialUSB.println("Command list completed....");
76 | }
77 |
78 | void sendmessage(char* message)
79 | {
80 | Serial2.println(message);
81 | delay(700);
82 | while (Serial2.available()) {SerialUSB.write(Serial2.read());}
83 |
84 | }
85 |
--------------------------------------------------------------------------------
/util/connectsetup/connectsetup.ino:
--------------------------------------------------------------------------------
1 | /*
2 | Transmit serial data back and forth between two ports
3 | in order to flash new firmware to ichip with the ichip config tool.
4 |
5 | Note: Steps 1-5 have to be completed within 30 seconds (30000ms)
6 |
7 | Steps:
8 | 1) reset arduino (e.g. power cycle)
9 | 2) start ichip software
10 | 3) menu "serial ports", select com port of ardiuno, set baud rate to 9600
11 | 4) click on "ichip uploader via serial"
12 | 5) select EBI flash 16 Megabit (if window doesn't appear, start over, act faster)
13 | 6) Click FW Update, select .imf file and wait until finished, close ichip program
14 | 7) power cycle arduino/gevcu and wait 20-30sec
15 | 8) menu "serial ports", set baud rate to 115200
16 | 9) go to configuration page
17 |
18 | check-out http://www.youtube.com/watch?v=vS60htz6h1g at 00:35:00
19 |
20 | */
21 | char inbyte;
22 | bool flag = true;
23 | void setup() {
24 | SerialUSB.begin(9600); // use SerialUSB only as the programming port doesn't work
25 | Serial2.begin(9600); // use Serial3 for GEVCU2, use Serial2 for GEVCU3+4
26 | // pinMode(43, INPUT);
27 | pinMode(18, OUTPUT);
28 | digitalWrite(18, LOW);
29 | }
30 |
31 | void loop() {
32 | while (Serial2.available()) {
33 | SerialUSB.write(Serial2.read());
34 | }
35 | while (SerialUSB.available()) {
36 | inbyte=SerialUSB.read();
37 | if (inbyte=='~'){sendcommandlist();}
38 | else {Serial2.write(inbyte);}
39 | }
40 |
41 | if (millis() > 6000) {
42 | digitalWrite(18, HIGH);
43 | }
44 |
45 |
46 | }
47 |
48 | void sendcommandlist()
49 | {
50 | SerialUSB.println("Sending commands....");
51 |
52 | sendmessage("AT+iFD");
53 | sendmessage("AT+iHIF=1");
54 | sendmessage("AT+iBDRA");
55 | sendmessage("AT+iWLCH=8");
56 | sendmessage("AT+iWLSI=GEVCU1");
57 | sendmessage("AT+iDIP=192.168.1.46");
58 | sendmessage("AT+iSNET=255.255.255.0");
59 | sendmessage("AT+iDPSZ=8");
60 | sendmessage("AT+iWST0=4");
61 | sendmessage("AT+iWPP0=");
62 | sendmessage("AT+iRPG=secret");
63 | sendmessage("AT+iWPWD=secret");
64 |
65 | sendmessage("AT+iAWS=1");
66 | sendmessage("AT+iSTAP=1");
67 | sendmessage("AT+iDOWN");
68 |
69 | SerialUSB.println("Command list completed....");
70 | }
71 |
72 | void sendmessage(char* message)
73 | {
74 | Serial2.println(message);
75 | delay(500);
76 | while (Serial2.available()) {SerialUSB.write(Serial2.read());}
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/util/i2128d810d35BCOM.IMF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/collin80/GEVCU/8a06011344b8e8840a7ac3f6d97b264d14bbe2bf/util/i2128d810d35BCOM.IMF
--------------------------------------------------------------------------------
/util/i2128d810d35BCOM.IMZ:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/collin80/GEVCU/8a06011344b8e8840a7ac3f6d97b264d14bbe2bf/util/i2128d810d35BCOM.IMZ
--------------------------------------------------------------------------------
/website/README.txt:
--------------------------------------------------------------------------------
1 | The GEVCU uses the Mini Socket iWifi module from ConnectOne. Documentation can be found at
2 |
3 | http://www.connectone.com/?page_id=217
4 |
5 | To update the website on the iChip, you have to use their packing tool which is part of their iChipConfig utility and only runs on Windows XP. If you use Windows 7 you can use Windows XP mode:
6 |
7 | http://windows.microsoft.com/en-us/windows7/install-and-use-windows-xp-mode-in-windows-7
8 |
9 | Download and install the following:
10 |
11 | http://www.connectone.com/wp-content/uploads/2012/06/iChipConfigExternal_2.4.95_setup7.zip
12 |
13 | Then to update the website after changes,
14 |
15 | 1. Launch iChipConfig, click through warnings about not having the com port and limited functionality
16 | 2. Choose the "Site Pack" tool
17 | 3. Browse to the website/src dir, select the index.htm as default
18 | 4. Select "C02128" as the platform and click "Pack". At this point the parameters should show.
19 | 5. Select all the parameters, enter 20 for the max length value to fill and click "Fill"
20 | 6. Click "Save" and point it to website.img
21 |
22 | At this point you upload the image to the GEVCU using http://192.168.3.10/ichip and power cycle the GEVCU to have it activated.
23 |
--------------------------------------------------------------------------------
/website/src/about.htm:
--------------------------------------------------------------------------------
1 |
ABOUT GEVCU 5.220
2 |
3 |
4 |
5 | The Generalized Electric Vehicle Control Unit - GEVCU is an open source
6 | software and hardware project to develop a Vehicle Control Unit (VCU) specifically
7 | for electric vehicles.
8 |
9 | The purpose of GEVCU is to handle throttle control, regenerative
10 | braking, forward, reverse, and such peculiarities as precharge, cooling system control,
11 | instrumentation etc. - essentially the driver interface of the car.
12 |
13 | GEVCU then manages torque and speed commands to the power electronics
14 | via CAN bus to actually operate the vehicle in response to driver input.
15 |
16 | But it also provides outputs to instrumentation, brake lights, reverse lights, cooling systems, and other controls specific to that vehicle.
17 |
18 | GEVCU is both open-source and object-oriented allowing easy addition of
19 | additional C++ object modules to incorporate multiple standard power components.
20 | It is easily modified using the Arduino IDE to incorporate additional features
21 | peculiar to any specific electric car conversion or build.
22 |
23 | For most operations, it is easily configurable by non-programmers through
24 | simple web and serial port interfaces to adapt to a wide variety of power
25 | components and vehicle applications.
26 |
27 | GEVCU was originally conceived of and proposed by Jack Rickard of
28 | Electric Vehicle Television (http://EVtv.me) who wrote the original
29 | design specification.
30 |
31 | The main source of the program was developed and is maintained by Collin Kidder
32 | and the latest version is always available at http:/github.com/collin80/GEVCU.
33 | A list of major contributors to the project is maintained there.
34 |
35 | Hardware was designed and developed by Ed Clausen and Paulo Jorge Pires de Almeida
36 | based on the Arduino Due.
37 |
38 | GEVCU is open source hardware and software and is presented as EXPERIMENTAL - USE AT YOUR
39 | OWN RISK. It is offered strictly for experimental and educational
40 | purposes and is NOT intended for actual use in any commercial product
41 | or for any specific useful purpose.
42 |
--------------------------------------------------------------------------------
/website/src/annunciator.htm:
--------------------------------------------------------------------------------
1 |
2 |