├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── SmartTriangle_Client ├── ADAction.cpp ├── ADAction.h ├── ADActor.cpp ├── ADActor.h ├── ADBrightnessAction.cpp ├── ADBrightnessAction.h ├── ADConfig.h ├── ADDirector.cpp ├── ADDirector.h ├── ADHSVAction.cpp ├── ADHSVAction.h ├── ADRGBAction.cpp ├── ADRGBAction.h ├── ArduiDispatch.h ├── HalfDuplexSerial.cpp ├── HalfDuplexSerial.h ├── MemoryFree.cpp ├── MemoryFree.h ├── SmartTriangle_Client.ino ├── TriangleProtocol.cpp ├── TriangleProtocol.h ├── Vector.cpp ├── Vector.h └── VectorDefinitions.h └── SmartTriangle_Server ├── .gitignore ├── _travis.yml ├── lib ├── Vector │ ├── LICENSE │ ├── README.org │ ├── examples │ │ └── VectorTester │ │ │ └── VectorTester.ino │ ├── library.properties │ └── src │ │ ├── Vector.h │ │ └── Vector │ │ ├── Vector.cpp │ │ └── VectorDefinitions.h └── WiFiManager │ ├── .gitignore │ ├── .travis.yml │ ├── LICENSE │ ├── WiFiManager.cpp │ ├── WiFiManager.h │ ├── extras │ ├── WiFiManager.template.html │ ├── parse.js │ ├── png_signal_strength_master.png │ ├── template.h │ └── test.html │ ├── keywords.txt │ ├── library.json │ ├── library.properties │ └── strings_en.h ├── platformio.ini └── src ├── ADAction.cpp ├── ADAction.h ├── ADActor.cpp ├── ADActor.h ├── ADConfig.h ├── ADDirector.cpp ├── ADDirector.h ├── ADHueAction.cpp ├── ADHueAction.h ├── ArduiDispatch.h ├── HalfDuplexSerial.cpp ├── HalfDuplexSerial.h ├── MemoryFree.cpp ├── MemoryFree.h ├── SmartTopology.cpp ├── SmartTopology.h ├── SmartTriangle_Server.ino ├── TriangleProtocol.cpp ├── TriangleProtocol.h ├── Vector.cpp ├── Vector.h └── VectorDefinitions.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pio/ 2 | .pioenvs/ 3 | .piolibdeps/ 4 | .vscode/ 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2019, Stephan Mühl 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SmartTriangle_Server_Esp8266 -------------------------------------------------------------------------------- /SmartTriangle_Client/ADAction.cpp: -------------------------------------------------------------------------------- 1 | #include "ADAction.h" 2 | 3 | ADAction::ADAction(ActionCallback func,uint32_t interval, uint32_t times,uint32_t delay, bool autoDelete) 4 | { 5 | _callback = func; 6 | _delay = delay; 7 | _delay_c = delay; 8 | _interval = interval; 9 | _interval_c = interval; 10 | _times = times; 11 | _times_c = 0; 12 | _autoDelete = autoDelete; 13 | } 14 | 15 | ADAction::~ADAction() 16 | { 17 | } 18 | 19 | void ADAction::callbackAction() 20 | { 21 | _times_c++; 22 | this->callback(); 23 | } 24 | 25 | void ADAction::callback() 26 | { 27 | _callback(_times_c, this); 28 | } 29 | 30 | ADAction *ADAction::create(ActionCallback func, uint32_t interval, uint32_t times,uint32_t delay, bool autoDelete) 31 | { 32 | ADAction *action = new ADAction(func, interval,times,delay,autoDelete); 33 | return action; 34 | } 35 | 36 | void ADAction::release() 37 | { 38 | delete this; 39 | } 40 | 41 | void ADAction::flush() 42 | { 43 | _times_c = 0; 44 | _delay_c = _delay; 45 | _interval_c = _interval; 46 | } 47 | 48 | bool ADAction::actNow(uint32_t dt) 49 | { 50 | if (_delay_c > dt) 51 | { 52 | _delay_c -= dt; 53 | } 54 | else 55 | { 56 | _delay_c = 0; 57 | if (_times_c == 0) 58 | { 59 | this->callbackAction(); 60 | } 61 | if (_interval_c > dt) 62 | { 63 | _interval_c -= dt; 64 | } 65 | else 66 | { 67 | _interval_c = 0; 68 | } 69 | } 70 | if (_delay_c == 0 && _interval_c == 0) 71 | { 72 | if (_times != 0 && _times_c >= _times) 73 | { 74 | this->flush(); 75 | if (_autoDelete) 76 | { 77 | return true; 78 | } 79 | }else 80 | { 81 | this->callbackAction(); 82 | _interval_c = _interval; 83 | } 84 | } 85 | return false; 86 | } 87 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADAction.h: -------------------------------------------------------------------------------- 1 | #ifndef __ADACTION_H__ 2 | #define __ADACTION_H__ 3 | 4 | #include "ADConfig.h" 5 | 6 | typedef void (*ActionCallback)(uint32_t, void *action); 7 | 8 | class ADAction 9 | { 10 | private: 11 | ActionCallback _callback; 12 | 13 | uint32_t _delay; 14 | 15 | uint32_t _interval; 16 | 17 | uint32_t _delay_c; 18 | 19 | uint32_t _interval_c; 20 | 21 | bool _autoDelete; 22 | 23 | void callbackAction(); 24 | 25 | virtual void callback(); 26 | 27 | protected: 28 | uint32_t _times; 29 | 30 | uint32_t _times_c; 31 | 32 | public: 33 | ADAction(ActionCallback func, uint32_t interval, uint32_t times = 0, uint32_t delay = 0, bool autoDelete = true); 34 | 35 | virtual ~ADAction(); 36 | 37 | //延迟delay毫秒,每间隔interval毫秒执行一次func,共执行times次。如果times==0,一直重复执行 38 | static ADAction *create(ActionCallback func, uint32_t interval, uint32_t times = 0, uint32_t delay = 0, bool autoDelete = true); 39 | 40 | void release(); 41 | 42 | void flush(); 43 | 44 | virtual bool actNow(uint32_t dt); 45 | }; 46 | 47 | #endif // __ADACTION_H__ -------------------------------------------------------------------------------- /SmartTriangle_Client/ADActor.cpp: -------------------------------------------------------------------------------- 1 | #include "ADActor.h" 2 | 3 | ADActor::ADActor(uint32_t showTime, bool autoDelete) 4 | { 5 | _showTime = showTime; 6 | _showTime_c = showTime; 7 | _autoDelete = autoDelete; 8 | _actionVec.setStorage(_actionVec_array); 9 | } 10 | 11 | ADActor::~ADActor() 12 | { 13 | } 14 | 15 | ADActor *ADActor::create(uint32_t showTime, bool autoDelete) 16 | { 17 | ADActor *actor = new ADActor(showTime, autoDelete); 18 | return actor; 19 | } 20 | 21 | ADActor *ADActor::create(uint32_t showTime, ADAction *action, bool autoDelete) 22 | { 23 | ADActor *actor = new ADActor(showTime, autoDelete); 24 | actor->addAction(action); 25 | return actor; 26 | } 27 | 28 | void ADActor::release() 29 | { 30 | for (int i = _actionVec.size() - 1; i >= 0; i--) 31 | { 32 | this->removeAction(i,true); 33 | } 34 | delete this; 35 | } 36 | 37 | void ADActor::addAction(ADAction *action) 38 | { 39 | if (action) 40 | { 41 | _actionVec.push_back(action); 42 | } 43 | 44 | } 45 | 46 | void ADActor::removeAction(ADAction *action, bool autoDelete) 47 | { 48 | for (int i = _actionVec.size() - 1; i >= 0; i--) 49 | { 50 | if (action == _actionVec[i]) 51 | { 52 | _actionVec.remove(i); 53 | if (autoDelete) 54 | { 55 | action->release(); 56 | } 57 | break; 58 | } 59 | } 60 | } 61 | 62 | void ADActor::removeAction(uint32_t index, bool autoDelete) 63 | { 64 | ADAction *action = _actionVec[index]; 65 | if (action) 66 | { 67 | _actionVec.remove(index); 68 | if (autoDelete) 69 | { 70 | action->release(); 71 | } 72 | } 73 | } 74 | 75 | bool ADActor::show(uint32_t dt, bool autoSwitch) 76 | { 77 | for (int i = _actionVec.size() - 1; i >= 0; i--) 78 | { 79 | ADAction *action = _actionVec[i]; 80 | if (action->actNow(dt)) 81 | { 82 | this->removeAction(i, autoSwitch); 83 | } 84 | } 85 | if (autoSwitch) 86 | { 87 | if (_showTime_c > dt) 88 | { 89 | _showTime_c -= dt; 90 | } 91 | else 92 | { 93 | _showTime_c = _showTime; // 产生些许时间误差 94 | return true; 95 | } 96 | } 97 | return false; 98 | } 99 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADActor.h: -------------------------------------------------------------------------------- 1 | #ifndef __ADACTOR_H__ 2 | #define __ADACTOR_H__ 3 | 4 | #include "ADConfig.h" 5 | #include "ADAction.h" 6 | #include "Vector.h" 7 | 8 | class ADActor 9 | { 10 | private: 11 | ADAction *_actionVec_array[10]; 12 | 13 | Vector _actionVec; 14 | 15 | uint32_t _showTime = 0; 16 | 17 | uint32_t _showTime_c = 0; 18 | 19 | bool _autoDelete; 20 | 21 | public: 22 | ADActor(uint32_t showTime , bool autoDelete = false); 23 | 24 | ~ADActor(); 25 | 26 | static ADActor *create(uint32_t showTime , bool autoDelete = false); 27 | 28 | static ADActor *create(uint32_t showTime, ADAction *action , bool autoDelete = false); 29 | 30 | void release(); 31 | 32 | void addAction(ADAction *action); 33 | 34 | void removeAction(ADAction *action, bool autoDelete = true); 35 | 36 | void removeAction(uint32_t index, bool autoDelete = true); 37 | 38 | bool show(uint32_t dt,bool autoSwitch); 39 | 40 | bool autoDelete(){return _autoDelete;} 41 | }; 42 | 43 | #endif // __ADACTOR_H__ 44 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADBrightnessAction.cpp: -------------------------------------------------------------------------------- 1 | #include "ADBrightnessAction.h" 2 | 3 | ADBrightnessAction::ADBrightnessAction(BrightnessActionCallback func, 4 | uint8_t from, 5 | uint8_t to, 6 | uint32_t duration, 7 | uint32_t fps, 8 | bool autoDelete) : ADAction(NULL, 1000 / fps, duration * fps / 1000.0, 0, autoDelete) 9 | { 10 | _callback = func; 11 | _from = from; 12 | _to = to; 13 | } 14 | 15 | ADBrightnessAction::~ADBrightnessAction() 16 | { 17 | } 18 | 19 | ADBrightnessAction *ADBrightnessAction::create(BrightnessActionCallback func, 20 | uint8_t from, 21 | uint8_t to, 22 | uint32_t duration, 23 | uint32_t fps, 24 | bool autoDelete) 25 | { 26 | ADBrightnessAction *action = new ADBrightnessAction(func, from, to, duration, fps, autoDelete); 27 | return action; 28 | } 29 | 30 | void ADBrightnessAction::callback() 31 | { 32 | uint8_t res = _to; 33 | if (_times != 0) 34 | { 35 | int32_t from = _from; 36 | int32_t to = _to; 37 | res = (from + (to - from) * (int32_t)_times_c / (int32_t)_times) % 256; 38 | } 39 | _callback(res, this); 40 | } 41 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADBrightnessAction.h: -------------------------------------------------------------------------------- 1 | #ifndef __AD_BRIGHTNESS_ACTION_H__ 2 | #define __AD_BRIGHTNESS_ACTION_H__ 3 | 4 | #include "ADAction.h" 5 | 6 | typedef void (*BrightnessActionCallback)(uint8_t, void *action); 7 | 8 | class ADBrightnessAction : public ADAction 9 | { 10 | private: 11 | uint8_t _from; 12 | 13 | uint8_t _to; 14 | 15 | BrightnessActionCallback _callback; 16 | 17 | void callback(); 18 | 19 | public: 20 | ADBrightnessAction(BrightnessActionCallback func, 21 | uint8_t from, 22 | uint8_t to, 23 | uint32_t duration, 24 | uint32_t fps = 30, 25 | bool autoDelete = true); 26 | 27 | virtual ~ADBrightnessAction(); 28 | 29 | static ADBrightnessAction *create(BrightnessActionCallback func, 30 | uint8_t from, 31 | uint8_t to, 32 | uint32_t duration, 33 | uint32_t fps = 30, 34 | bool autoDelete = true); 35 | }; 36 | 37 | #endif // __AD_BRIGHTNESS_ACTION_H__ 38 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef __ADCONFIG_H__ 2 | #define __ADCONFIG_H__ 3 | 4 | #define DEBUG 1 5 | 6 | #define ADLOG_V(n) Serial.println(#n + String(":") + String(n)) 7 | #define ADLOG_SV(s,n) Serial.println(s + String(" ") + #n + String(":") + String(n)) 8 | #define ADLOG_S(s) Serial.println(s) 9 | 10 | #include 11 | #include 12 | //#include 13 | 14 | #endif // __ADCONFIG_H__ 15 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADDirector.cpp: -------------------------------------------------------------------------------- 1 | #include "ADDirector.h" 2 | 3 | ADDirector::ADDirector(/* args */) 4 | { 5 | _actorVec.setStorage(_actorVec_array); 6 | } 7 | 8 | ADDirector::~ADDirector() 9 | { 10 | } 11 | 12 | void ADDirector::startAction(uint32_t ct) 13 | { 14 | _lastMillis = ct; 15 | _invalid = false; 16 | } 17 | 18 | void ADDirector::stopAction() 19 | { 20 | _invalid = true; 21 | } 22 | 23 | void ADDirector::startAutoSwitch() 24 | { 25 | _autoSwitch = true; 26 | } 27 | 28 | void ADDirector::stopAutoSwitch() 29 | { 30 | _autoSwitch = false; 31 | } 32 | 33 | void ADDirector ::begin(bool autoSwitch) 34 | { 35 | _invalid = true; 36 | _autoSwitch = autoSwitch; 37 | } 38 | void ADDirector ::loop(uint32_t ct) 39 | { 40 | if (_lastMillis >= ct) 41 | return; 42 | 43 | uint32_t dt = ct - _lastMillis; 44 | 45 | _lastMillis = ct; 46 | 47 | if (_invalid) 48 | return; 49 | // Serial.println("L0 " + String(_autoSwitchPointer) + " " + String(_actorVec.size())); 50 | 51 | for (int i = _actorVec.size() - 1; i >= 0; i--) 52 | { 53 | ADActor *actor = _actorVec[i]; 54 | if (actor && actor->show(dt, _autoSwitch)) 55 | { 56 | if (actor->autoDelete()) 57 | { 58 | this->removeActor(actor); 59 | } 60 | } 61 | } 62 | 63 | // ADActor *actor = _actorVec[_autoSwitchPointer]; 64 | // 65 | // if (actor && actor->show(dt, _autoSwitch)) 66 | // { 67 | // if (actor->autoDelete()) 68 | // { 69 | // this->removeActor(actor); 70 | // } 71 | // _autoSwitchPointer++; 72 | // if (_autoSwitchPointer >= _actorVec.size()) 73 | // { 74 | // _autoSwitchPointer = 0; 75 | // } 76 | // } 77 | 78 | } 79 | 80 | void ADDirector::addActor(ADActor *actor) 81 | { 82 | _actorVec.push_back(actor); 83 | } 84 | 85 | void ADDirector::removeActor(ADActor *actor, bool autoDelete) 86 | { 87 | for (uint32_t i = 0; i < _actorVec.size(); i++) 88 | { 89 | if (actor == _actorVec[i]) 90 | { 91 | _actorVec.remove(i); 92 | if (autoDelete) 93 | { 94 | actor->release(); 95 | } 96 | break; 97 | } 98 | } 99 | } 100 | 101 | void ADDirector::removeActor(uint32_t index, bool autoDelete) 102 | { 103 | ADActor *actor = _actorVec[index]; 104 | if (actor) 105 | { 106 | _actorVec.remove(index); 107 | if (autoDelete) 108 | { 109 | actor->release(); 110 | } 111 | } 112 | } 113 | 114 | void ADDirector::flush() 115 | { 116 | this->stopAction(); 117 | for (int i = _actorVec.size() - 1; i >= 0; i--) 118 | { 119 | this->removeActor(i, true); 120 | } 121 | } 122 | 123 | ADDirector Director; 124 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADDirector.h: -------------------------------------------------------------------------------- 1 | #ifndef __ADDIRECTOR_H__ 2 | #define __ADDIRECTOR_H__ 3 | 4 | #include "ADConfig.h" 5 | #include "ADActor.h" 6 | #include "Vector.h" 7 | 8 | class ADDirector 9 | { 10 | private: 11 | bool _invalid = false; 12 | 13 | bool _autoSwitch = false; 14 | 15 | uint16_t _autoSwitchPointer = 0; 16 | 17 | uint32_t _lastMillis = 0; 18 | 19 | ADActor *_actorVec_array[10]; 20 | 21 | Vector _actorVec; 22 | 23 | public: 24 | ADDirector(); 25 | 26 | ~ADDirector(); 27 | 28 | void begin(bool autoSwitch = true); 29 | 30 | void loop(uint32_t ct); 31 | 32 | void startAction(uint32_t ct); 33 | 34 | void stopAction(); 35 | 36 | void startAutoSwitch(); 37 | 38 | void stopAutoSwitch(); 39 | 40 | void addActor(ADActor *actor); 41 | 42 | void removeActor(ADActor *actor, bool autoDelete = true); 43 | 44 | void removeActor(uint32_t index, bool autoDelete = true); 45 | 46 | void flush(); 47 | }; 48 | 49 | extern ADDirector Director; 50 | 51 | #endif // __ADDIRECTOR_H__ 52 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADHSVAction.cpp: -------------------------------------------------------------------------------- 1 | #include "ADHSVAction.h" 2 | 3 | ADHSVAction::ADHSVAction(HSVActionCallback func, 4 | uint8_t *from, 5 | uint8_t *to, 6 | uint32_t duration, 7 | uint32_t fps, 8 | bool autoDelete) : ADAction(NULL, 1000 / fps, duration * fps / 1000.0, 0, autoDelete) 9 | { 10 | _callback = func; 11 | for(int i = 0;i<3;i++) 12 | { 13 | _from[i] = from[i]; 14 | _to[i] = to[i]; 15 | } 16 | } 17 | 18 | ADHSVAction::~ADHSVAction() 19 | { 20 | } 21 | 22 | ADHSVAction *ADHSVAction::create(HSVActionCallback func, 23 | uint8_t *from, 24 | uint8_t *to, 25 | uint32_t duration, 26 | uint32_t fps, 27 | bool autoDelete) 28 | { 29 | ADHSVAction *action = new ADHSVAction(func, from, to, duration, fps, autoDelete); 30 | return action; 31 | } 32 | 33 | void ADHSVAction::callback() 34 | { 35 | uint8_t res[3] = {_to[0],_to[1],_to[2]}; 36 | if (_times != 0) 37 | { 38 | int32_t from[3] = {_from[0],_from[1],_from[2]}; 39 | int32_t to[3] = {_to[0],_to[1],_to[2]}; 40 | if (from[0] > to[0]) 41 | { 42 | to[0] += 256; 43 | } 44 | for(int i = 0;i<3;i++) 45 | { 46 | res[i] = (from[i] + (to[i] - from[i]) * (int32_t)_times_c / (int32_t)_times) % 256; 47 | } 48 | } 49 | _callback(res[0],res[1],res[2],this); 50 | } 51 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADHSVAction.h: -------------------------------------------------------------------------------- 1 | #ifndef __AD_HSV_ACTION_H__ 2 | #define __AD_HSV_ACTION_H__ 3 | 4 | #include "ADAction.h" 5 | 6 | typedef void (*HSVActionCallback)(uint8_t,uint8_t,uint8_t,void *action); 7 | 8 | class ADHSVAction : public ADAction 9 | { 10 | private: 11 | uint8_t _from[3]; 12 | 13 | uint8_t _to[3]; 14 | 15 | HSVActionCallback _callback; 16 | 17 | void callback(); 18 | 19 | public: 20 | ADHSVAction(HSVActionCallback func, 21 | uint8_t *from, 22 | uint8_t *to, 23 | uint32_t duration, 24 | uint32_t fps = 30, 25 | bool autoDelete = true); 26 | 27 | virtual ~ADHSVAction(); 28 | 29 | static ADHSVAction *create(HSVActionCallback func, 30 | uint8_t *from, 31 | uint8_t *to, 32 | uint32_t duration, 33 | uint32_t fps = 30, 34 | bool autoDelete = true); 35 | }; 36 | 37 | #endif // __AD_HSV_ACTION_H__ 38 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADRGBAction.cpp: -------------------------------------------------------------------------------- 1 | #include "ADRGBAction.h" 2 | 3 | ADRGBAction::ADRGBAction(RGBActionCallback func, 4 | uint8_t *from, 5 | uint8_t *to, 6 | uint32_t duration, 7 | uint32_t fps, 8 | bool autoDelete) : ADAction(NULL, 1000 / fps, duration * fps / 1000.0, 0, autoDelete) 9 | { 10 | _callback = func; 11 | for(int i = 0;i<3;i++) 12 | { 13 | _from[i] = from[i]; 14 | _to[i] = to[i]; 15 | } 16 | } 17 | 18 | ADRGBAction::~ADRGBAction() 19 | { 20 | } 21 | 22 | ADRGBAction *ADRGBAction::create(RGBActionCallback func, 23 | uint8_t *from, 24 | uint8_t *to, 25 | uint32_t duration, 26 | uint32_t fps, 27 | bool autoDelete) 28 | { 29 | ADRGBAction *action = new ADRGBAction(func, from, to, duration, fps, autoDelete); 30 | return action; 31 | } 32 | 33 | void ADRGBAction::callback() 34 | { 35 | uint8_t res[3] = {_to[0],_to[1],_to[2]}; 36 | if (_times != 0) 37 | { 38 | int32_t from[3] = {_from[0],_from[1],_from[2]}; 39 | int32_t to[3] = {_to[0],_to[1],_to[2]}; 40 | for(int i = 0;i<3;i++) 41 | { 42 | res[i] = (from[i] + (to[i] - from[i]) * (int32_t)_times_c / (int32_t)_times) % 256; 43 | } 44 | } 45 | _callback(res[0],res[1],res[2],this); 46 | } 47 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ADRGBAction.h: -------------------------------------------------------------------------------- 1 | #ifndef __AD_RGB_ACTION_H__ 2 | #define __AD_RGB_ACTION_H__ 3 | 4 | #include "ADAction.h" 5 | 6 | typedef void (*RGBActionCallback)(uint8_t,uint8_t,uint8_t,void *action); 7 | 8 | class ADRGBAction : public ADAction 9 | { 10 | private: 11 | uint8_t _from[3]; 12 | 13 | uint8_t _to[3]; 14 | 15 | RGBActionCallback _callback; 16 | 17 | void callback(); 18 | 19 | public: 20 | ADRGBAction(RGBActionCallback func, 21 | uint8_t *from, 22 | uint8_t *to, 23 | uint32_t duration, 24 | uint32_t fps = 30, 25 | bool autoDelete = true); 26 | 27 | virtual ~ADRGBAction(); 28 | 29 | static ADRGBAction *create(RGBActionCallback func, 30 | uint8_t *from, 31 | uint8_t *to, 32 | uint32_t duration, 33 | uint32_t fps = 30, 34 | bool autoDelete = true); 35 | }; 36 | 37 | #endif // __AD_HSV_ACTION_H__ 38 | -------------------------------------------------------------------------------- /SmartTriangle_Client/ArduiDispatch.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARDUI_DISPATCH_H__ 2 | #define __ARDUI_DISPATCH_H__ 3 | 4 | #include "ADConfig.h" 5 | 6 | #include "ADDirector.h" 7 | #include "ADActor.h" 8 | #include "ADAction.h" 9 | 10 | 11 | 12 | #endif // __ARDUI_DISPATCH_H__ -------------------------------------------------------------------------------- /SmartTriangle_Client/HalfDuplexSerial.cpp: -------------------------------------------------------------------------------- 1 | #include "HalfDuplexSerial.h" 2 | #include 3 | 4 | HalfDuplexSerial::HalfDuplexSerial(int8_t pin) 5 | { 6 | m_transmitSeirial = new SoftwareSerial(-1, pin); 7 | m_receiveSerial = new SoftwareSerial(pin, -1); 8 | m_pin = pin; 9 | m_serialModeType = SMT_NONE; 10 | } 11 | 12 | HalfDuplexSerial::~HalfDuplexSerial() 13 | { 14 | delete m_transmitSeirial; 15 | delete m_receiveSerial; 16 | } 17 | 18 | void HalfDuplexSerial::begin(long speed) 19 | { 20 | m_transmitSeirial->begin(speed); 21 | m_receiveSerial->begin(speed); 22 | } 23 | 24 | void HalfDuplexSerial::end() 25 | { 26 | m_receiveSerial->end(); 27 | m_transmitSeirial->end(); 28 | m_serialModeType = SMT_NONE; 29 | } 30 | 31 | size_t HalfDuplexSerial::write(uint8_t byte) 32 | { 33 | if (m_serialModeType == SMT_TRANSMIT) 34 | { 35 | return m_transmitSeirial->write(byte); 36 | } 37 | else 38 | { 39 | return -1; 40 | } 41 | } 42 | 43 | int HalfDuplexSerial::read() 44 | { 45 | if (m_serialModeType == SMT_RECEIVE) 46 | { 47 | return m_receiveSerial->read(); 48 | } 49 | else 50 | { 51 | return -1; 52 | } 53 | } 54 | 55 | int HalfDuplexSerial::available() 56 | { 57 | if (m_serialModeType == SMT_RECEIVE) 58 | { 59 | return m_receiveSerial->available(); 60 | } 61 | else 62 | { 63 | return 0; 64 | } 65 | } 66 | 67 | void HalfDuplexSerial::setMode(SerialModeType smt) 68 | { 69 | switch (smt) 70 | { 71 | case SMT_TRANSMIT: 72 | { 73 | pinMode(m_pin, OUTPUT); 74 | #if defined(ESP8266) 75 | m_transmitSeirial->listen(); 76 | m_transmitSeirial->flush(); 77 | m_transmitSeirial->enableRx(false); 78 | m_transmitSeirial->enableTx(true); 79 | m_receiveSerial->enableRx(false); 80 | m_receiveSerial->enableTx(false); 81 | #else 82 | m_receiveSerial->end(); 83 | m_transmitSeirial->listen(); 84 | #endif 85 | m_serialModeType = SMT_TRANSMIT; 86 | } 87 | break; 88 | case SMT_RECEIVE: 89 | { 90 | pinMode(m_pin, INPUT_PULLUP); 91 | #if defined(ESP8266) 92 | m_receiveSerial->listen(); 93 | m_receiveSerial->flush(); 94 | m_transmitSeirial->enableRx(false); 95 | m_transmitSeirial->enableTx(false); 96 | m_receiveSerial->enableRx(true); 97 | m_receiveSerial->enableTx(false); 98 | #else 99 | m_transmitSeirial->end(); 100 | m_receiveSerial->listen(); 101 | #endif 102 | m_serialModeType = SMT_RECEIVE; 103 | } 104 | break; 105 | default: 106 | break; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /SmartTriangle_Client/HalfDuplexSerial.h: -------------------------------------------------------------------------------- 1 | #ifndef HalfDuplexSerial_h 2 | #define HalfDuplexSerial_h 3 | 4 | #include 5 | 6 | enum SerialModeType 7 | { 8 | SMT_NONE = 0, 9 | SMT_TRANSMIT = 1, 10 | SMT_RECEIVE, 11 | }; 12 | 13 | class HalfDuplexSerial 14 | { 15 | private: 16 | SoftwareSerial *m_transmitSeirial; 17 | SoftwareSerial *m_receiveSerial; 18 | SerialModeType m_serialModeType; 19 | int m_pin; 20 | public: 21 | HalfDuplexSerial(int8_t pin); 22 | ~HalfDuplexSerial(); 23 | void begin(long speed); 24 | void end(); 25 | size_t write(uint8_t byte); 26 | int read(); 27 | int available(); 28 | 29 | void setMode(SerialModeType smt); 30 | SerialModeType serialModeType(){return m_serialModeType;} 31 | 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /SmartTriangle_Client/MemoryFree.cpp: -------------------------------------------------------------------------------- 1 | #if (ARDUINO >= 100) 2 | #include 3 | #else 4 | #include 5 | #endif 6 | 7 | extern unsigned int __heap_start; 8 | extern void *__brkval; 9 | 10 | /* 11 | * The free list structure as maintained by the 12 | * avr-libc memory allocation routines. 13 | */ 14 | struct __freelist 15 | { 16 | size_t sz; 17 | struct __freelist *nx; 18 | }; 19 | 20 | /* The head of the free list structure */ 21 | extern struct __freelist *__flp; 22 | 23 | #include "MemoryFree.h" 24 | 25 | /* Calculates the size of the free list */ 26 | int freeListSize() 27 | { 28 | struct __freelist* current; 29 | int total = 0; 30 | for (current = __flp; current; current = current->nx) 31 | { 32 | total += 2; /* Add two bytes for the memory block's header */ 33 | total += (int) current->sz; 34 | } 35 | 36 | return total; 37 | } 38 | 39 | int freeMemory() 40 | { 41 | int free_memory; 42 | if ((int)__brkval == 0) 43 | { 44 | free_memory = ((int)&free_memory) - ((int)&__heap_start); 45 | } 46 | else 47 | { 48 | free_memory = ((int)&free_memory) - ((int)__brkval); 49 | free_memory += freeListSize(); 50 | } 51 | return free_memory; 52 | } 53 | -------------------------------------------------------------------------------- /SmartTriangle_Client/MemoryFree.h: -------------------------------------------------------------------------------- 1 | // MemoryFree library based on code posted here: 2 | // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213583720/15 3 | // Extended by Matthew Murdoch to include walking of the free list. 4 | 5 | #ifndef MEMORY_FREE_H 6 | #define MEMORY_FREE_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | int freeMemory(); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /SmartTriangle_Client/SmartTriangle_Client.ino: -------------------------------------------------------------------------------- 1 | #include "HalfDuplexSerial.h" 2 | #include "TriangleProtocol.h" 3 | #include "ArduiDispatch.h" 4 | #include "ADRGBAction.h" 5 | #include "ADHSVAction.h" 6 | #include "ADBrightnessAction.h" 7 | #include 8 | #include "MemoryFree.h" 9 | 10 | #define PROTOCOL_VER "0.1.0" 11 | 12 | #define PROTOCOL_CALLBACK(x) void pId_callback_##x(byte *payload, unsigned int length, bool isTimeout) 13 | 14 | #define PORTOCOL_REGISTER(x) \ 15 | { \ 16 | if (isTimeout || m_nodeId == payload[0] || payload[0] == 255) \ 17 | { \ 18 | pId_callback_##x(payload + 1, length - 1, isTimeout); \ 19 | } \ 20 | } \ 21 | break 22 | 23 | #define HDSERIAL_PIN 10 24 | 25 | #define NUM_LEDS 15 26 | 27 | #define LED_PIN 4 28 | 29 | enum TriangleStateType 30 | { 31 | TST_NONE = 0, 32 | TST_WATING_LOCATE = 1, 33 | TST_LOCATED = 2, 34 | }; 35 | 36 | HalfDuplexSerial hdSerial(HDSERIAL_PIN); 37 | 38 | CRGB leds[NUM_LEDS]; 39 | 40 | int selectPin[3] = {6, 7, 8}; 41 | 42 | uint16_t ledNumOffset = 0; 43 | 44 | TriangleStateType m_triangleStateType; 45 | 46 | int m_fatherNodePin = -1; 47 | 48 | int m_leftLeafNodePin = -1; 49 | 50 | int m_rightLeafNodePin = -1; 51 | 52 | uint8_t m_nodeId = 254; // 254 代表未分配ID 53 | 54 | bool m_debugMode = false; 55 | 56 | uint16_t ledNumsConverter(uint16_t n) 57 | { 58 | return (n + ledNumOffset) % NUM_LEDS; 59 | } 60 | 61 | void startSelect(bool isLeft) 62 | { 63 | if (isLeft) 64 | { 65 | pinMode(m_leftLeafNodePin, OUTPUT); 66 | digitalWrite(m_leftLeafNodePin, HIGH); 67 | } 68 | else 69 | { 70 | pinMode(m_rightLeafNodePin, OUTPUT); 71 | digitalWrite(m_rightLeafNodePin, HIGH); 72 | } 73 | } 74 | 75 | void stopSelect(bool isLeft) 76 | { 77 | if (isLeft) 78 | { 79 | pinMode(m_leftLeafNodePin, INPUT); 80 | } 81 | else 82 | { 83 | pinMode(m_rightLeafNodePin, INPUT); 84 | } 85 | } 86 | 87 | bool seekFatherPin() 88 | { 89 | if (m_triangleStateType == TST_LOCATED) 90 | { 91 | return false; 92 | } 93 | m_fatherNodePin = -1; 94 | for (int i = 0; i < 3; i++) 95 | { 96 | if (digitalRead(selectPin[i]) == HIGH) 97 | { 98 | m_fatherNodePin = selectPin[i]; 99 | m_leftLeafNodePin = selectPin[(i - 1) < 0 ? 2 : (i - 1)]; 100 | m_rightLeafNodePin = selectPin[(i + 1) > 2 ? 0 : (i + 1)]; 101 | if (m_fatherNodePin == 6) 102 | { 103 | ledNumOffset = 5; 104 | } 105 | else if (m_fatherNodePin == 8) 106 | { 107 | ledNumOffset = 10; 108 | } 109 | break; 110 | } 111 | } 112 | if (m_fatherNodePin != -1) 113 | return true; 114 | else 115 | return false; 116 | } 117 | 118 | void topologyCheck() 119 | { 120 | } 121 | 122 | void flush() 123 | { 124 | for (int i = 0; i < 3; i++) 125 | { 126 | pinMode(selectPin[i], INPUT); 127 | } 128 | m_triangleStateType = TST_NONE; 129 | m_fatherNodePin = -1; 130 | m_leftLeafNodePin = -1; 131 | m_rightLeafNodePin = -1; 132 | m_nodeId = 254; 133 | Director.flush(); 134 | FastLED.clear(); 135 | FastLED.show(); 136 | Director.startAction(millis()); 137 | Serial.println("TOPOLOGY RESET"); 138 | } 139 | 140 | void transmitAction() 141 | { 142 | hdSerial.setMode(SMT_TRANSMIT); 143 | TPT.tpTransmit(); 144 | hdSerial.setMode(SMT_RECEIVE); 145 | TPT.tpBeginReceive(); 146 | } 147 | 148 | 149 | /* 150 | 协议类型 151 | 1~50 拓扑仲裁单向消息 152 | 51~100 拓扑仲裁需应答消息 153 | 101~255 效果展示类消息 154 | */ 155 | 156 | //重置状态 157 | PROTOCOL_CALLBACK(1) 158 | { 159 | flush(); 160 | LEDS.setBrightness(payload[0]); 161 | m_debugMode = payload[1] > 0 & 0x01; 162 | ADLOG_V(m_debugMode); 163 | } 164 | 165 | //分配ID 166 | PROTOCOL_CALLBACK(2) 167 | { 168 | if (m_triangleStateType == TST_WATING_LOCATE) 169 | { 170 | m_nodeId = payload[0]; 171 | Serial.println("GET NODE ID:" + String(m_nodeId)); 172 | m_triangleStateType = TST_LOCATED; 173 | } 174 | } 175 | 176 | //左仲裁接脚高电平 177 | PROTOCOL_CALLBACK(21) 178 | { 179 | startSelect(true); 180 | } 181 | 182 | //左仲裁接脚低电平 183 | PROTOCOL_CALLBACK(22) 184 | { 185 | stopSelect(true); 186 | } 187 | 188 | //右仲裁接脚高电平 189 | PROTOCOL_CALLBACK(23) 190 | { 191 | startSelect(false); 192 | } 193 | 194 | //右仲裁接脚低电平 195 | PROTOCOL_CALLBACK(24) 196 | { 197 | stopSelect(false); 198 | } 199 | 200 | //查找上级仲裁接脚-根节点查找 201 | PROTOCOL_CALLBACK(51) 202 | { 203 | if (seekFatherPin()) 204 | { 205 | //确认上级节点位置 206 | m_triangleStateType = TST_WATING_LOCATE; 207 | TPT.tpBegin(51, 0).tpStr(PROTOCOL_VER); 208 | transmitAction(); 209 | } 210 | } 211 | 212 | //查找上级仲裁接脚-子节点 213 | PROTOCOL_CALLBACK(52) 214 | { 215 | if (seekFatherPin()) 216 | { 217 | //确认上级节点位置 218 | m_triangleStateType = TST_WATING_LOCATE; 219 | TPT.tpBegin(52, 0).tpStr(PROTOCOL_VER); 220 | transmitAction(); 221 | } 222 | } 223 | 224 | //心跳 225 | PROTOCOL_CALLBACK(100) 226 | { 227 | TPT.tpBegin(100, 0).tpByte(m_nodeId); 228 | transmitAction(); 229 | } 230 | 231 | void effect101Callback(uint8_t b, void *e) 232 | { 233 | LEDS.setBrightness(b); 234 | FastLED.show(); 235 | } 236 | 237 | //在[0][1]毫秒内,所有灯亮度从当前亮度改为[2],如时间为0,则直接修改 238 | PROTOCOL_CALLBACK(101) 239 | { 240 | uint16_t t = uint16_t(payload[0] << 8) + uint16_t(payload[1]); 241 | uint8_t b = payload[2]; 242 | if (t > 0) 243 | { 244 | ADBrightnessAction *action = ADBrightnessAction::create(effect101Callback, LEDS.getBrightness(), b, t); 245 | ADActor *actor = ADActor::create(t, action, true); 246 | Director.addActor(actor); 247 | } else 248 | { 249 | effect101Callback(b, NULL); 250 | } 251 | } 252 | 253 | void effect102Callback(uint8_t h,uint8_t s,uint8_t v, void *e) 254 | { 255 | for (int i = 0; i < NUM_LEDS; i++) 256 | { 257 | leds[ledNumsConverter(i)] = CHSV(h, s, v); 258 | } 259 | FastLED.show(); 260 | } 261 | 262 | //在[0][1]毫秒内,所有灯颜色从0号灯当前HSV颜色改为HSV颜色[2][3][4],如时间为0,则直接修改 263 | PROTOCOL_CALLBACK(102) 264 | { 265 | uint16_t t = uint16_t(payload[0] << 8) + uint16_t(payload[1]); 266 | if (t > 0) 267 | { 268 | CHSV hsv = rgb2hsv_approximate(leds[ledNumsConverter(0)]); 269 | uint8_t c[3] = {hsv.h,hsv.s,hsv.v}; 270 | ADHSVAction *action = ADHSVAction::create(effect102Callback, c, payload + 2, t); 271 | ADActor *actor = ADActor::create(t, action, true); 272 | Director.addActor(actor); 273 | } else 274 | { 275 | effect102Callback(payload[2],payload[3],payload[4], NULL); 276 | } 277 | } 278 | 279 | uint8_t m_hueInterval = 10; 280 | 281 | void effect103Callback(uint8_t h,uint8_t s,uint8_t v,void *e) 282 | { 283 | for (int i = 0; i < NUM_LEDS; i++) 284 | { 285 | leds[ledNumsConverter(i)] = CHSV((h + i * m_hueInterval) % 256, s, v); 286 | } 287 | FastLED.show(); 288 | } 289 | 290 | //在[0][1]毫秒内,将灯颜色从HSV颜色[2][3][4]变为颜色[5][6][7],每一个灯珠色相值增加[8],如时间为0,则直接修改 291 | PROTOCOL_CALLBACK(103) 292 | { 293 | uint16_t t = uint16_t(payload[0] << 8) + uint16_t(payload[1]); 294 | m_hueInterval = payload[8]; 295 | if (t > 0) 296 | { 297 | ADHSVAction *action = ADHSVAction::create(effect103Callback, payload+2, payload+5, t); 298 | ADActor *actor = ADActor::create(t, action, true); 299 | Director.addActor(actor); 300 | } else 301 | { 302 | effect103Callback(payload[5],payload[6],payload[7], NULL); 303 | } 304 | } 305 | 306 | void effect104Callback(uint8_t h,uint8_t s,uint8_t v, void *e) 307 | { 308 | for (int i = 0; i < NUM_LEDS; i++) 309 | { 310 | leds[ledNumsConverter(i)] = CHSV((h + (i / 5) * m_hueInterval) % 256, s, v); 311 | } 312 | FastLED.show(); 313 | } 314 | 315 | //在[0][1]毫秒内,将灯颜色从HSV颜色[2][3][4]变为颜色[5][6][7],每五个灯珠为一组色相值增加[8],如时间为0,则直接修改 316 | PROTOCOL_CALLBACK(104) 317 | { 318 | uint16_t t = uint16_t(payload[0] << 8) + uint16_t(payload[1]); 319 | m_hueInterval = payload[8]; 320 | if (t > 0) 321 | { 322 | ADHSVAction *action = ADHSVAction::create(effect104Callback, payload+2, payload+5, t); 323 | ADActor *actor = ADActor::create(t, action, true); 324 | Director.addActor(actor); 325 | } else 326 | { 327 | effect104Callback(payload[5],payload[6],payload[7], NULL); 328 | } 329 | } 330 | 331 | void effect105Callback(uint8_t r,uint8_t g,uint8_t b, void *e) 332 | { 333 | Serial.println("r:"+String(r)+" g:" + String(g) + " b:"+ String(b)); 334 | for (int i = 0; i < NUM_LEDS; i++) 335 | { 336 | leds[ledNumsConverter(i)] = CRGB(r,g,b); 337 | } 338 | FastLED.show(); 339 | } 340 | 341 | //在[0][1]毫秒内,将灯颜色从RGB颜色[2][3][4]变为颜色[5][6][7],如时间为0,则直接修改 342 | PROTOCOL_CALLBACK(105) 343 | { 344 | uint16_t t = uint16_t(payload[0] << 8) + uint16_t(payload[1]); 345 | if (t > 0) 346 | { 347 | ADRGBAction *action = ADRGBAction::create(effect105Callback, payload+2, payload+5, t); 348 | ADActor *actor = ADActor::create(t, action, true); 349 | Director.addActor(actor); 350 | } else 351 | { 352 | effect105Callback(payload[5],payload[6],payload[7], NULL); 353 | } 354 | } 355 | 356 | void effect200Callback(uint32_t n, void *e) 357 | { 358 | uint8_t c = (n % 2 == 1) ? 200 : 0; 359 | for (int i = 0; i < NUM_LEDS; i++) 360 | { 361 | leds[i] = CRGB(c, c, c); 362 | } 363 | FastLED.show(); 364 | } 365 | 366 | PROTOCOL_CALLBACK(200) 367 | { 368 | // Serial.println("200call"); 369 | ADAction *action = ADAction::create(effect200Callback, 200, 2); 370 | ADActor *actor = ADActor::create(1000, action, true); 371 | Director.addActor(actor); 372 | 373 | } 374 | 375 | void tpCallback(byte pId, byte *payload, unsigned int length, bool isTimeout) 376 | { 377 | Serial.println("<<==Rec. " + String(pId) + (isTimeout ? " T " : " F ") + String(freeMemory())); 378 | if (m_triangleStateType == TST_NONE && pId >= 100) 379 | { 380 | Serial.println(" DIS==>>"); 381 | return; 382 | } 383 | switch (pId) 384 | { 385 | case 1: 386 | PORTOCOL_REGISTER(1); 387 | case 2: 388 | PORTOCOL_REGISTER(2); 389 | case 21: 390 | PORTOCOL_REGISTER(21); 391 | case 22: 392 | PORTOCOL_REGISTER(22); 393 | case 23: 394 | PORTOCOL_REGISTER(23); 395 | case 24: 396 | PORTOCOL_REGISTER(24); 397 | case 51: 398 | PORTOCOL_REGISTER(51); 399 | case 52: 400 | PORTOCOL_REGISTER(52); 401 | case 100: 402 | PORTOCOL_REGISTER(100); 403 | case 101: 404 | PORTOCOL_REGISTER(101); 405 | case 102: 406 | PORTOCOL_REGISTER(102); 407 | case 103: 408 | PORTOCOL_REGISTER(103); 409 | case 104: 410 | PORTOCOL_REGISTER(104); 411 | case 105: 412 | PORTOCOL_REGISTER(105); 413 | case 200: 414 | PORTOCOL_REGISTER(200); 415 | } 416 | Serial.println("==>>"); 417 | } 418 | 419 | void transmitCallback(byte *ptBuffer, unsigned int ptLength) 420 | { 421 | // Serial.print("Sent pID=" + String(ptBuffer[3])); 422 | // Serial.println(" Length=" + String(ptLength) + " "); 423 | // ADLOG_V(freeMemory()); 424 | Serial.println("<<==Sent " + String(ptBuffer[3]) + " Length=" + String(ptLength) + " " + String(freeMemory())); 425 | for (int i = 0; i < ptLength; i++) 426 | { 427 | byte c = ptBuffer[i]; 428 | hdSerial.write(c); 429 | } 430 | Serial.println("==>>"); 431 | } 432 | 433 | void setup() 434 | { 435 | pinMode(A0, INPUT); 436 | 437 | Serial.begin(9600); 438 | 439 | delay(100); 440 | 441 | Serial.println("STARTING......."); 442 | 443 | LEDS.addLeds(leds, NUM_LEDS); 444 | 445 | LEDS.setBrightness(200); 446 | 447 | hdSerial.begin(57600); 448 | 449 | hdSerial.setMode(SMT_RECEIVE); 450 | 451 | pinMode(11, INPUT_PULLUP); 452 | 453 | TPT.callbackRegister(tpCallback, transmitCallback); 454 | 455 | TPT.tpBeginReceive(); 456 | 457 | flush(); 458 | 459 | Director.begin(true); 460 | 461 | Director.startAction(millis()); 462 | } 463 | 464 | void loop() 465 | { 466 | TPT.protocolLoop(); 467 | if (hdSerial.serialModeType() == SMT_RECEIVE) 468 | { 469 | while (hdSerial.available()) 470 | { 471 | TPT.tpPushData(hdSerial.read()).tpParse(); 472 | } 473 | } 474 | 475 | Director.loop(millis()); 476 | 477 | } 478 | -------------------------------------------------------------------------------- /SmartTriangle_Client/TriangleProtocol.cpp: -------------------------------------------------------------------------------- 1 | #include "TriangleProtocol.h" 2 | 3 | static uint8_t m_ptBuffer[MAX_PROTOCOL_BUFFER]; 4 | 5 | static uint16_t m_ptLength; 6 | 7 | TriangleProtocol::TriangleProtocol() 8 | { 9 | this->parse_callback = NULL; 10 | this->trans_callback = NULL; 11 | m_protoCallbackVec.setStorage(m_protoCallbackVec_array); 12 | } 13 | 14 | TriangleProtocol::~TriangleProtocol() 15 | { 16 | } 17 | 18 | void TriangleProtocol::callbackRegister(TP_PARSE_CALLBACK, TP_TRANSMIT_CALLBACK) 19 | { 20 | this->parse_callback = parse_callback; 21 | this->trans_callback = trans_callback; 22 | } 23 | 24 | void TriangleProtocol::InvertUint16(uint16_t *dBuf, uint16_t *srcBuf) 25 | { 26 | uint16_t tmp[4] = {0}; 27 | for (uint8_t i = 0; i < 16; i++) 28 | { 29 | if (srcBuf[0] & (1 << i)) 30 | tmp[0] |= 1 << (15 - i); 31 | } 32 | dBuf[0] = tmp[0]; 33 | } 34 | 35 | uint16_t TriangleProtocol::CRC16_MODBUS(uint8_t *data, uint16_t datalen) 36 | { 37 | uint16_t wCRCin = 0xFFFF; 38 | uint16_t wCPoly = 0x8005; 39 | InvertUint16(&wCPoly, &wCPoly); 40 | while (datalen--) 41 | { 42 | wCRCin ^= *(data++); 43 | for (uint8_t i = 0; i < 8; i++) 44 | { 45 | if (wCRCin & 0x01) 46 | wCRCin = (wCRCin >> 1) ^ wCPoly; 47 | else 48 | wCRCin = wCRCin >> 1; 49 | } 50 | } 51 | uint16_t wCRCinTemp = wCRCin; 52 | return (wCRCin >> 8 & 0x00FF) | (wCRCinTemp << 8 & 0xFF00); 53 | } 54 | 55 | void TriangleProtocol::waitProtocolTimeout(uint8_t pId, uint32_t timeout) 56 | { 57 | ProtocolCallbackDef *protocolCallbackDef = new ProtocolCallbackDef(); 58 | protocolCallbackDef->pId = pId; 59 | protocolCallbackDef->recordTime = millis(); 60 | protocolCallbackDef->timeout = timeout; 61 | m_protoCallbackVec.push_back(protocolCallbackDef); 62 | } 63 | 64 | void TriangleProtocol::protocolTimeoutRemove(uint8_t pId) 65 | { 66 | for (int i = m_protoCallbackVec.size() - 1; i >= 0; i--) 67 | { 68 | ProtocolCallbackDef *protocolCallbackDef = m_protoCallbackVec[i]; 69 | if (protocolCallbackDef->pId == pId) 70 | { 71 | m_protoCallbackVec.remove(i); 72 | delete protocolCallbackDef; 73 | protocolCallbackDef = NULL; 74 | } 75 | } 76 | } 77 | 78 | void TriangleProtocol::protocolLoop() 79 | { 80 | for (int i = m_protoCallbackVec.size() - 1; i >= 0; i--) 81 | { 82 | ProtocolCallbackDef *protocolCallbackDef = m_protoCallbackVec[i]; 83 | if (millis() - protocolCallbackDef->recordTime > protocolCallbackDef->timeout) 84 | { 85 | this->parse_callback(protocolCallbackDef->pId, NULL, 0, true); 86 | m_protoCallbackVec.remove(i); 87 | delete protocolCallbackDef; 88 | protocolCallbackDef = NULL; 89 | } 90 | } 91 | } 92 | 93 | TriangleProtocol &TriangleProtocol::tpBegin(byte pid, byte nid) 94 | { 95 | m_ptBuffer[0] = 0; 96 | m_ptBuffer[1] = 0; 97 | m_ptBuffer[2] = 0; 98 | m_ptLength = 3; 99 | m_ptBuffer[m_ptLength++] = pid; 100 | m_ptBuffer[m_ptLength++] = nid; 101 | return TPT; 102 | } 103 | 104 | TriangleProtocol &TriangleProtocol::tpByte(byte b) 105 | { 106 | m_ptBuffer[m_ptLength++] = b; 107 | return TPT; 108 | } 109 | 110 | TriangleProtocol &TriangleProtocol::tpUint16(uint16_t i) 111 | { 112 | m_ptBuffer[m_ptLength++] = (i >> 8) & 0xFF; 113 | m_ptBuffer[m_ptLength++] = (i >> 0) & 0xFF; 114 | return TPT; 115 | } 116 | 117 | TriangleProtocol &TriangleProtocol::tpUint32(uint32_t i) 118 | { 119 | m_ptBuffer[m_ptLength++] = (i >> 24) & 0xFF; 120 | m_ptBuffer[m_ptLength++] = (i >> 16) & 0xFF; 121 | m_ptBuffer[m_ptLength++] = (i >> 8) & 0xFF; 122 | m_ptBuffer[m_ptLength++] = (i >> 0) & 0xFF; 123 | return TPT; 124 | } 125 | 126 | TriangleProtocol &TriangleProtocol::tpColor(byte r, byte g, byte b) 127 | { 128 | m_ptBuffer[m_ptLength++] = r; 129 | m_ptBuffer[m_ptLength++] = g; 130 | m_ptBuffer[m_ptLength++] = b; 131 | return TPT; 132 | } 133 | 134 | TriangleProtocol &TriangleProtocol::tpStr(const String &str) 135 | { 136 | int length = str.length(); 137 | m_ptBuffer[m_ptLength++] = length; 138 | for (int i = 0; i < length; i++) 139 | { 140 | m_ptBuffer[m_ptLength++] = str[i]; 141 | } 142 | return TPT; 143 | } 144 | 145 | void TriangleProtocol::tpTransmit(bool checkTimeout) 146 | { 147 | m_ptBuffer[1] = ((m_ptLength + 2) >> 8) & 0xFF; 148 | m_ptBuffer[2] = ((m_ptLength + 2) >> 0) & 0xFF; 149 | 150 | uint16_t crc = this->CRC16_MODBUS(m_ptBuffer, m_ptLength); 151 | this->tpUint16(crc); 152 | 153 | this->trans_callback(m_ptBuffer, m_ptLength); 154 | if (checkTimeout) 155 | { 156 | this->waitProtocolTimeout(m_ptBuffer[3]); 157 | } 158 | } 159 | 160 | TriangleProtocol &TriangleProtocol::tpBeginReceive() 161 | { 162 | m_ptLength = 0; 163 | memset(m_ptBuffer, 0, sizeof(uint8_t) * MAX_PROTOCOL_BUFFER); 164 | return TPT; 165 | } 166 | 167 | TriangleProtocol &TriangleProtocol::tpPushData(uint8_t d) 168 | { 169 | if (m_ptLength == 0 && d != 0) //开头过滤 170 | { 171 | return TPT; 172 | } 173 | m_ptBuffer[m_ptLength++] = d; 174 | return TPT; 175 | } 176 | 177 | void TriangleProtocol::tpParse() 178 | { 179 | if (m_ptLength < 3) 180 | return; 181 | uint16_t pLength = uint16_t(m_ptBuffer[1] << 8) + uint16_t(m_ptBuffer[2]); 182 | if (pLength > MAX_PROTOCOL_BUFFER) 183 | { 184 | TPT.tpBeginReceive();//协议缓存重置 185 | return; 186 | } 187 | if (pLength < 6) 188 | return; //无有效载荷,协议至少六位 189 | if (pLength > m_ptLength) 190 | return; //未完全接收数据,等待 191 | if (pLength <= m_ptLength) 192 | { 193 | if (this->CRC16_MODBUS(m_ptBuffer, pLength) == 0) //crc校验 194 | { 195 | uint8_t pId = m_ptBuffer[3]; 196 | this->protocolTimeoutRemove(pId); 197 | this->parse_callback(pId, m_ptBuffer + 4, pLength - 4, false); 198 | } else 199 | { 200 | for (int i = 0; i < pLength; i++) 201 | { 202 | Serial.println("m_ptBuffer[" + String(i) + "]=" + String(m_ptBuffer[i])); 203 | } 204 | Serial.println("parse failed"); 205 | } 206 | } 207 | TPT.tpBeginReceive();//协议缓存重置 208 | } 209 | 210 | String TriangleProtocol::parseString(uint8_t *payload) const 211 | { 212 | uint8_t stringLength = payload[0]; 213 | char *buff = (char *)malloc(stringLength + 1); 214 | memset(buff, 0, stringLength + 1); 215 | for (int i = 0; i < stringLength; i++) 216 | { 217 | buff[i] = payload[i + 1]; 218 | } 219 | String res = String(buff); 220 | delete buff; 221 | return res; 222 | } 223 | 224 | TriangleProtocol TPT; 225 | -------------------------------------------------------------------------------- /SmartTriangle_Client/TriangleProtocol.h: -------------------------------------------------------------------------------- 1 | #ifndef TriangleProtocol_h 2 | #define TriangleProtocol_h 3 | 4 | #include 5 | #include 6 | #include "Vector.h" 7 | 8 | struct ProtocolCallbackDef 9 | { 10 | uint8_t pId; 11 | uint32_t recordTime; 12 | uint32_t timeout; 13 | }; 14 | 15 | #define TP_PARSE_CALLBACK void (*parse_callback)(byte, uint8_t *, unsigned int, bool) 16 | 17 | #define TP_TRANSMIT_CALLBACK void (*trans_callback)(uint8_t *, unsigned int) 18 | 19 | #define DEFAULT_PROTOCO_TIMEOUT 200 20 | 21 | #define MAX_PROTOCOL_BUFFER 256 22 | 23 | class TriangleProtocol 24 | { 25 | private: 26 | TP_PARSE_CALLBACK; 27 | 28 | TP_TRANSMIT_CALLBACK; 29 | 30 | ProtocolCallbackDef *m_protoCallbackVec_array[10]; 31 | 32 | Vector m_protoCallbackVec; 33 | 34 | void protocolTimeoutRemove(uint8_t pId); 35 | 36 | void InvertUint16(uint16_t *dBuf, uint16_t *srcBuf); 37 | 38 | uint16_t CRC16_MODBUS(uint8_t *data, uint16_t datalen); 39 | 40 | public: 41 | TriangleProtocol(); 42 | 43 | ~TriangleProtocol(); 44 | 45 | void callbackRegister(TP_PARSE_CALLBACK, TP_TRANSMIT_CALLBACK); 46 | 47 | void waitProtocolTimeout(uint8_t pId, uint32_t timeout = DEFAULT_PROTOCO_TIMEOUT); 48 | 49 | void protocolLoop(); 50 | /* 51 | 协议标准 52 | [0]:固定0为开头 53 | [1][2]:含开头、自身、有效负载、校验位总长度 54 | [3]:协议ID 55 | [4]:奇光板ID , 255 为广播ID 56 | [5]-[n]:协议有效负载 57 | [n+1][n+2]:CRC校验码 58 | */ 59 | TriangleProtocol &tpBegin(byte pid,byte nid); 60 | 61 | TriangleProtocol &tpByte(byte b); 62 | 63 | TriangleProtocol &tpUint16(uint16_t i); 64 | 65 | TriangleProtocol &tpUint32(uint32_t i); 66 | 67 | TriangleProtocol &tpColor(byte r, byte g, byte b); 68 | 69 | TriangleProtocol &tpStr(const String &str); 70 | 71 | void tpTransmit(bool checkTimeout = false); 72 | 73 | TriangleProtocol &tpBeginReceive(); 74 | 75 | TriangleProtocol &tpPushData(uint8_t d); 76 | 77 | void tpParse(); 78 | 79 | String parseString(uint8_t *payload) const; 80 | 81 | 82 | }; 83 | 84 | extern TriangleProtocol TPT; 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /SmartTriangle_Client/Vector.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Vector.cpp 3 | // 4 | // 5 | // Authors: 6 | // Peter Polidoro peterpolidoro@gmail.com 7 | // ---------------------------------------------------------------------------- 8 | #include "Vector.h" 9 | -------------------------------------------------------------------------------- /SmartTriangle_Client/Vector.h: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Vector.h 3 | // 4 | // 5 | // Authors: 6 | // Peter Polidoro peterpolidoro@gmail.com 7 | // ---------------------------------------------------------------------------- 8 | #ifndef VECTOR_H 9 | #define VECTOR_H 10 | #ifdef ARDUINO 11 | #include 12 | #else 13 | #include 14 | #endif 15 | 16 | 17 | template 18 | class Vector 19 | { 20 | public: 21 | Vector(); 22 | template 23 | Vector(T (&values)[MAX_SIZE], 24 | size_t size=0); 25 | template 26 | void setStorage(T (&values)[MAX_SIZE], 27 | size_t size=0); 28 | void setStorage(T * values, 29 | size_t max_size, 30 | size_t size); 31 | const T & operator[](size_t index) const; 32 | T & operator[](size_t index); 33 | const T & at(size_t index) const; 34 | T & at(size_t index); 35 | T & front(); 36 | T & back(); 37 | void clear(); 38 | template 39 | void fill(const U & value); 40 | template 42 | void fill(const U (&values)[N]); 43 | template 44 | void fill(const Vector & values); 45 | template 46 | void assign(size_t n, 47 | const U & value); 48 | template 50 | void assign(size_t n, 51 | const U (&values)[N]); 52 | template 53 | void assign(size_t n, 54 | const Vector & values); 55 | void push_back(const T & value); 56 | void pop_back(); 57 | void remove(size_t index); 58 | size_t size() const; 59 | size_t max_size() const; 60 | bool empty() const; 61 | bool full() const; 62 | const T * data() const; 63 | T * data(); 64 | 65 | private: 66 | T * values_; 67 | size_t max_size_; 68 | size_t size_; 69 | }; 70 | 71 | template 72 | inline Print & operator <<(Print & stream, 73 | const Vector & vector) 74 | { 75 | stream.print("["); 76 | for (size_t i=0; i 13 | #endif 14 | 15 | template 16 | Vector::Vector() 17 | { 18 | values_ = NULL; 19 | max_size_ = 0; 20 | size_ = 0; 21 | } 22 | 23 | template 24 | template 25 | Vector::Vector(T (&values)[MAX_SIZE], 26 | size_t size) 27 | { 28 | setStorage(values,size); 29 | } 30 | 31 | template 32 | template 33 | void Vector::setStorage(T (&values)[MAX_SIZE], 34 | size_t size) 35 | { 36 | values_ = values; 37 | max_size_ = MAX_SIZE; 38 | size_ = size; 39 | } 40 | 41 | template 42 | void Vector::setStorage(T * values, 43 | size_t max_size, 44 | size_t size) 45 | { 46 | values_ = values; 47 | max_size_ = max_size; 48 | size_ = size; 49 | } 50 | 51 | template 52 | const T & Vector::operator[](size_t index) const 53 | { 54 | return values_[index]; 55 | } 56 | 57 | template 58 | T & Vector::operator[](size_t index) 59 | { 60 | return values_[index]; 61 | } 62 | 63 | template 64 | T & Vector::at(size_t index) 65 | { 66 | return values_[index]; 67 | } 68 | 69 | template 70 | const T & Vector::at(size_t index) const 71 | { 72 | return values_[index]; 73 | } 74 | 75 | template 76 | T & Vector::front() 77 | { 78 | return values_[0]; 79 | } 80 | 81 | template 82 | T & Vector::back() 83 | { 84 | return values_[size_-1]; 85 | } 86 | 87 | template 88 | void Vector::clear() 89 | { 90 | size_ = 0; 91 | } 92 | 93 | template 94 | template 95 | void Vector::fill(const U & value) 96 | { 97 | assign(max_size_,value); 98 | } 99 | 100 | template 101 | template 103 | void Vector::fill(const U (&values)[N]) 104 | { 105 | assign(N,values); 106 | } 107 | 108 | template 109 | template 110 | void Vector::fill(const Vector & values) 111 | { 112 | assign(values.size(),values); 113 | } 114 | 115 | template 116 | template 117 | void Vector::assign(size_t n, 118 | const U & value) 119 | { 120 | size_t assign_size = ((n < max_size_) ? n : max_size_); 121 | size_ = assign_size; 122 | for (size_t i=0; i 129 | template 131 | void Vector::assign(size_t n, 132 | const U (&values)[N]) 133 | { 134 | size_t n_smallest = ((n < N) ? n : N); 135 | size_t assign_size = ((n_smallest < max_size_) ? n_smallest : max_size_); 136 | size_ = assign_size; 137 | for (size_t i=0; i 144 | template 145 | void Vector::assign(size_t n, 146 | const Vector & values) 147 | { 148 | size_t n_smallest = ((n < values.size()) ? n : values.size()); 149 | size_t assign_size = ((n_smallest < max_size_) ? n_smallest : max_size_); 150 | size_ = assign_size; 151 | for (size_t i=0; i 158 | void Vector::push_back(const T & value) 159 | { 160 | if ((values_ != NULL) && (size_ < max_size_)) 161 | { 162 | values_[size_++] = value; 163 | } 164 | } 165 | 166 | template 167 | void Vector::pop_back() 168 | { 169 | if (size_ > 0) 170 | { 171 | --size_; 172 | } 173 | } 174 | 175 | template 176 | void Vector::remove(size_t index) 177 | { 178 | if (size_ > index) 179 | { 180 | for (size_t i=index; i<(size_-1); ++i) 181 | { 182 | values_[i] = values_[i+1]; 183 | } 184 | --size_; 185 | } 186 | } 187 | 188 | template 189 | size_t Vector::size() const 190 | { 191 | return size_; 192 | } 193 | 194 | template 195 | size_t Vector::max_size() const 196 | { 197 | return max_size_; 198 | } 199 | 200 | template 201 | bool Vector::empty() const 202 | { 203 | return size_ == 0; 204 | } 205 | 206 | template 207 | bool Vector::full() const 208 | { 209 | return size_ == max_size_; 210 | } 211 | 212 | template 213 | T * Vector::data() 214 | { 215 | return values_; 216 | } 217 | 218 | template 219 | const T * Vector::data() const 220 | { 221 | return values_; 222 | } 223 | 224 | #endif 225 | -------------------------------------------------------------------------------- /SmartTriangle_Server/.gitignore: -------------------------------------------------------------------------------- 1 | .pio 2 | .vscode/.browse.c_cpp.db* 3 | .vscode/c_cpp_properties.json 4 | .vscode/launch.json 5 | .vscode/ipch 6 | -------------------------------------------------------------------------------- /SmartTriangle_Server/_travis.yml: -------------------------------------------------------------------------------- 1 | # Continuous Integration (CI) is the practice, in software 2 | # engineering, of merging all developer working copies with a shared mainline 3 | # several times a day < https://docs.platformio.org/page/ci/index.html > 4 | # 5 | # Documentation: 6 | # 7 | # * Travis CI Embedded Builds with PlatformIO 8 | # < https://docs.travis-ci.com/user/integration/platformio/ > 9 | # 10 | # * PlatformIO integration with Travis CI 11 | # < https://docs.platformio.org/page/ci/travis.html > 12 | # 13 | # * User Guide for `platformio ci` command 14 | # < https://docs.platformio.org/page/userguide/cmd_ci.html > 15 | # 16 | # 17 | # Please choose one of the following templates (proposed below) and uncomment 18 | # it (remove "# " before each line) or use own configuration according to the 19 | # Travis CI documentation (see above). 20 | # 21 | 22 | 23 | # 24 | # Template #1: General project. Test it using existing `platformio.ini`. 25 | # 26 | 27 | # language: python 28 | # python: 29 | # - "2.7" 30 | # 31 | # sudo: false 32 | # cache: 33 | # directories: 34 | # - "~/.platformio" 35 | # 36 | # install: 37 | # - pip install -U platformio 38 | # - platformio update 39 | # 40 | # script: 41 | # - platformio run 42 | 43 | 44 | # 45 | # Template #2: The project is intended to be used as a library with examples. 46 | # 47 | 48 | # language: python 49 | # python: 50 | # - "2.7" 51 | # 52 | # sudo: false 53 | # cache: 54 | # directories: 55 | # - "~/.platformio" 56 | # 57 | # env: 58 | # - PLATFORMIO_CI_SRC=path/to/test/file.c 59 | # - PLATFORMIO_CI_SRC=examples/file.ino 60 | # - PLATFORMIO_CI_SRC=path/to/test/directory 61 | # 62 | # install: 63 | # - pip install -U platformio 64 | # - platformio update 65 | # 66 | # script: 67 | # - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N 68 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/Vector/LICENSE: -------------------------------------------------------------------------------- 1 | License Agreement 2 | (3-clause BSD License) 3 | Janelia Research Campus Software Copyright 1.1 4 | 5 | Copyright (c) 2014, Howard Hughes Medical Institute 6 | All rights reserved. 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | 11 | * Redistributions of source code must retain the above copyright notice, this 12 | list of conditions and the following disclaimer. 13 | 14 | * Redistributions in binary form must reproduce the above copyright notice, 15 | this list of conditions and the following disclaimer in the documentation 16 | and/or other materials provided with the distribution. 17 | 18 | * Neither the name of the Howard Hughes Medical Institute nor the 19 | names of its contributors may be used to endorse or promote products 20 | derived from this software without specific prior written 21 | permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 24 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 27 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 31 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/Vector/README.org: -------------------------------------------------------------------------------- 1 | #+TITLE: Vector 2 | #+AUTHOR: Peter Polidoro 3 | #+EMAIL: peterpolidoro@gmail.com 4 | 5 | * Library Information 6 | - Name :: Vector 7 | - Version :: 1.1.2 8 | - License :: BSD 9 | - URL :: https://github.com/janelia-arduino/Vector 10 | - Author :: Peter Polidoro 11 | - Email :: peterpolidoro@gmail.com 12 | 13 | A sequence container similar to the C++ 14 | [[http://www.cplusplus.com/reference/vector/vector/][std::vector]], but 15 | instead of allocating memory dynamically, this container points to an 16 | external, statically allocated c style array. The maximum size is 17 | fixed at compile time, but the size can change by pushing and popping 18 | elements from the vector. Static memory allocation is used to avoid 19 | dynamic allocation problems on very small embedded processors. Care 20 | must be taken not to dereference an empty vector, access elements 21 | beyond bounds, or use without setting the storage array. 22 | 23 | This library is very similar to 24 | [[https://github.com/janelia-arduino/Array][Array]], however Array 25 | stores data internally in the container and this library stores data 26 | externally. The pointer to the external memory causes this container 27 | to use more memory than the Array container, but storing the data 28 | externally avoids needing the maximum size as a class template 29 | parameter. 30 | 31 | * Vector vs Array 32 | ** Vector 33 | 34 | #+BEGIN_SRC C++ 35 | const int ELEMENT_COUNT = 5; 36 | int storage_array[ELEMENT_COUNT_MAX]; 37 | Vector vector(storage_array); 38 | vector.push_back(77); 39 | #+END_SRC 40 | 41 | ** Array 42 | 43 | #+BEGIN_SRC C++ 44 | const int ELEMENT_COUNT = 5; 45 | Array array; 46 | array.push_back(77); 47 | #+END_SRC 48 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/Vector/examples/VectorTester/VectorTester.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | const long BAUD = 115200; 7 | 8 | const int ELEMENT_COUNT_MAX = 5; 9 | 10 | void setup() 11 | { 12 | Serial.begin(BAUD); 13 | delay(1000); 14 | 15 | } 16 | 17 | void loop() 18 | { 19 | int storage_array[ELEMENT_COUNT_MAX]; 20 | Vector vector; 21 | vector.setStorage(storage_array); 22 | Serial << "vector.max_size(): " << vector.max_size() << endl; 23 | Serial << "vector.size(): " << vector.size() << endl; 24 | Serial << "vector:" << endl; 25 | Serial << vector << endl; 26 | delay(1000); 27 | 28 | vector.push_back(10); 29 | vector.push_back(8); 30 | vector.push_back(7); 31 | Serial << "vector.max_size(): " << vector.max_size() << endl; 32 | Serial << "vector.size(): " << vector.size() << endl; 33 | Serial << "vector:" << endl; 34 | Serial << vector << endl; 35 | vector.remove(0); 36 | Serial << "vector.remove(0):" << endl; 37 | Serial << vector << endl; 38 | vector.remove(1); 39 | Serial << "vector.remove(1):" << endl; 40 | Serial << vector << endl; 41 | delay(1000); 42 | 43 | int storage_array2[ELEMENT_COUNT_MAX]; 44 | Vector vector2(storage_array2); 45 | vector2.push_back(1); 46 | vector2.push_back(2); 47 | vector2.push_back(4); 48 | vector2.pop_back(); 49 | Serial << "vector2.max_size(): " << vector2.max_size() << endl; 50 | Serial << "vector2.size(): " << vector2.size() << endl; 51 | Serial << "vector2:" << endl; 52 | Serial << vector2 << endl; 53 | delay(1000); 54 | 55 | int storage_array3[ELEMENT_COUNT_MAX]; 56 | storage_array3[0] = 3; 57 | storage_array3[1] = 5; 58 | Vector vector3(storage_array3); 59 | Serial << "vector3.max_size(): " << vector3.max_size() << endl; 60 | Serial << "vector3.size(): " << vector3.size() << endl; 61 | Serial << "vector3:" << endl; 62 | Serial << vector3 << endl; 63 | delay(1000); 64 | 65 | int storage_array4[ELEMENT_COUNT_MAX]; 66 | storage_array4[0] = 3; 67 | storage_array4[1] = 5; 68 | Vector vector4(storage_array4,2); 69 | Serial << "vector4.max_size(): " << vector4.max_size() << endl; 70 | Serial << "vector4.size(): " << vector4.size() << endl; 71 | Serial << "vector4:" << endl; 72 | Serial << vector4 << endl; 73 | delay(1000); 74 | 75 | int storage_array5[1]; 76 | Vector vector5(storage_array5); 77 | Serial << "vector5.max_size(): " << vector5.max_size() << endl; 78 | Serial << "vector5.size(): " << vector5.size() << endl; 79 | Serial << "vector5:" << endl; 80 | Serial << vector5 << endl; 81 | delay(1000); 82 | 83 | int storage_array6[ELEMENT_COUNT_MAX]; 84 | Vector vector6(storage_array6); 85 | vector6.assign(ELEMENT_COUNT_MAX-1,8); 86 | Serial << "vector6:" << endl; 87 | Serial << vector6 << endl; 88 | delay(1000); 89 | } 90 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/Vector/library.properties: -------------------------------------------------------------------------------- 1 | name=Vector 2 | version=1.1.2 3 | author=Peter Polidoro 4 | maintainer=Peter Polidoro 5 | sentence=An array container similar to the C++ std::vector 6 | paragraph=Like this project? Please star it on GitHub! 7 | category=Data Storage 8 | url=https://github.com/janelia-arduino/Vector.git 9 | architectures=* 10 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/Vector/src/Vector.h: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Vector.h 3 | // 4 | // 5 | // Authors: 6 | // Peter Polidoro peterpolidoro@gmail.com 7 | // ---------------------------------------------------------------------------- 8 | #ifndef VECTOR_H 9 | #define VECTOR_H 10 | #ifdef ARDUINO 11 | #include 12 | #else 13 | #include 14 | #endif 15 | 16 | 17 | template 18 | class Vector 19 | { 20 | public: 21 | Vector(); 22 | template 23 | Vector(T (&values)[MAX_SIZE], 24 | size_t size=0); 25 | template 26 | void setStorage(T (&values)[MAX_SIZE], 27 | size_t size=0); 28 | void setStorage(T * values, 29 | size_t max_size, 30 | size_t size); 31 | const T & operator[](size_t index) const; 32 | T & operator[](size_t index); 33 | const T & at(size_t index) const; 34 | T & at(size_t index); 35 | T & front(); 36 | T & back(); 37 | void clear(); 38 | template 39 | void fill(const U & value); 40 | template 42 | void fill(const U (&values)[N]); 43 | template 44 | void fill(const Vector & values); 45 | template 46 | void assign(size_t n, 47 | const U & value); 48 | template 50 | void assign(size_t n, 51 | const U (&values)[N]); 52 | template 53 | void assign(size_t n, 54 | const Vector & values); 55 | void push_back(const T & value); 56 | void pop_back(); 57 | void remove(size_t index); 58 | size_t size() const; 59 | size_t max_size() const; 60 | bool empty() const; 61 | bool full() const; 62 | const T * data() const; 63 | T * data(); 64 | 65 | private: 66 | T * values_; 67 | size_t max_size_; 68 | size_t size_; 69 | }; 70 | 71 | template 72 | inline Print & operator <<(Print & stream, 73 | const Vector & vector) 74 | { 75 | stream.print("["); 76 | for (size_t i=0; i 13 | #endif 14 | 15 | template 16 | Vector::Vector() 17 | { 18 | values_ = NULL; 19 | max_size_ = 0; 20 | size_ = 0; 21 | } 22 | 23 | template 24 | template 25 | Vector::Vector(T (&values)[MAX_SIZE], 26 | size_t size) 27 | { 28 | setStorage(values,size); 29 | } 30 | 31 | template 32 | template 33 | void Vector::setStorage(T (&values)[MAX_SIZE], 34 | size_t size) 35 | { 36 | values_ = values; 37 | max_size_ = MAX_SIZE; 38 | size_ = size; 39 | } 40 | 41 | template 42 | void Vector::setStorage(T * values, 43 | size_t max_size, 44 | size_t size) 45 | { 46 | values_ = values; 47 | max_size_ = max_size; 48 | size_ = size; 49 | } 50 | 51 | template 52 | const T & Vector::operator[](size_t index) const 53 | { 54 | return values_[index]; 55 | } 56 | 57 | template 58 | T & Vector::operator[](size_t index) 59 | { 60 | return values_[index]; 61 | } 62 | 63 | template 64 | T & Vector::at(size_t index) 65 | { 66 | return values_[index]; 67 | } 68 | 69 | template 70 | const T & Vector::at(size_t index) const 71 | { 72 | return values_[index]; 73 | } 74 | 75 | template 76 | T & Vector::front() 77 | { 78 | return values_[0]; 79 | } 80 | 81 | template 82 | T & Vector::back() 83 | { 84 | return values_[size_-1]; 85 | } 86 | 87 | template 88 | void Vector::clear() 89 | { 90 | size_ = 0; 91 | } 92 | 93 | template 94 | template 95 | void Vector::fill(const U & value) 96 | { 97 | assign(max_size_,value); 98 | } 99 | 100 | template 101 | template 103 | void Vector::fill(const U (&values)[N]) 104 | { 105 | assign(N,values); 106 | } 107 | 108 | template 109 | template 110 | void Vector::fill(const Vector & values) 111 | { 112 | assign(values.size(),values); 113 | } 114 | 115 | template 116 | template 117 | void Vector::assign(size_t n, 118 | const U & value) 119 | { 120 | size_t assign_size = ((n < max_size_) ? n : max_size_); 121 | size_ = assign_size; 122 | for (size_t i=0; i 129 | template 131 | void Vector::assign(size_t n, 132 | const U (&values)[N]) 133 | { 134 | size_t n_smallest = ((n < N) ? n : N); 135 | size_t assign_size = ((n_smallest < max_size_) ? n_smallest : max_size_); 136 | size_ = assign_size; 137 | for (size_t i=0; i 144 | template 145 | void Vector::assign(size_t n, 146 | const Vector & values) 147 | { 148 | size_t n_smallest = ((n < values.size()) ? n : values.size()); 149 | size_t assign_size = ((n_smallest < max_size_) ? n_smallest : max_size_); 150 | size_ = assign_size; 151 | for (size_t i=0; i 158 | void Vector::push_back(const T & value) 159 | { 160 | if ((values_ != NULL) && (size_ < max_size_)) 161 | { 162 | values_[size_++] = value; 163 | } 164 | } 165 | 166 | template 167 | void Vector::pop_back() 168 | { 169 | if (size_ > 0) 170 | { 171 | --size_; 172 | } 173 | } 174 | 175 | template 176 | void Vector::remove(size_t index) 177 | { 178 | if (size_ > index) 179 | { 180 | for (size_t i=index; i<(size_-1); ++i) 181 | { 182 | values_[i] = values_[i+1]; 183 | } 184 | --size_; 185 | } 186 | } 187 | 188 | template 189 | size_t Vector::size() const 190 | { 191 | return size_; 192 | } 193 | 194 | template 195 | size_t Vector::max_size() const 196 | { 197 | return max_size_; 198 | } 199 | 200 | template 201 | bool Vector::empty() const 202 | { 203 | return size_ == 0; 204 | } 205 | 206 | template 207 | bool Vector::full() const 208 | { 209 | return size_ == max_size_; 210 | } 211 | 212 | template 213 | T * Vector::data() 214 | { 215 | return values_; 216 | } 217 | 218 | template 219 | const T * Vector::data() const 220 | { 221 | return values_; 222 | } 223 | 224 | #endif 225 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/WiFiManager/.gitignore: -------------------------------------------------------------------------------- 1 | platformio.ini 2 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/WiFiManager/.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | sudo: false 3 | 4 | before_install: 5 | - "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16" 6 | - sleep 3 7 | - export DISPLAY=:1.0 8 | - wget http://downloads.arduino.cc/arduino-1.8.8-linux64.tar.xz 9 | - tar xf arduino-1.8.8-linux64.tar.xz 10 | - sudo mv arduino-1.8.8 /usr/local/share/arduino 11 | - sudo ln -s /usr/local/share/arduino/arduino /usr/local/bin/arduino 12 | 13 | install: 14 | - ln -s $PWD /usr/local/share/arduino/libraries/WiFiManager 15 | - arduino --pref "boardsmanager.additional.urls=http://arduino.esp8266.com/stable/package_esp8266com_index.json,http://dl.espressif.com/dl/package_esp32_index.json" --save-prefs 16 | - arduino --install-library "ArduinoJson:5.13.2" 17 | - arduino --install-boards esp8266:esp8266 18 | - arduino --pref "compiler.warning_level=all" --save-prefs 19 | # install esp32 20 | - arduino --install-boards esp32:esp32 21 | # - pushd . 22 | # - mkdir -p ~/Arduino/hardware/espressif 23 | # - cd ~/Arduino/hardware/espressif 24 | # - git clone https://github.com/espressif/arduino-esp32.git esp32 25 | # - cd esp32 26 | # - git submodule update --init --recursive 27 | # - cd tools 28 | # - python2 get.py 29 | # - popd 30 | # esp32 needs WebServer_tng for now 31 | # - git clone https://github.com/bbx10/WebServer_tng.git /usr/local/share/arduino/libraries/WebServer_tng 32 | 33 | script: 34 | - "echo $PWD" 35 | - "echo $HOME" 36 | - "ls $PWD" 37 | - source $TRAVIS_BUILD_DIR/travis/common.sh 38 | - arduino --board esp8266:esp8266:generic:xtal=80,eesz=4M1M,FlashMode=qio,FlashFreq=80,dbg=Serial,lvl=CORE --save-prefs 39 | - build_examples 40 | - arduino --board esp32:esp32:esp32:FlashFreq=80,FlashSize=4M,DebugLevel=info --save-prefs 41 | # some examples fail (SPIFFS defines differ esp32 vs esp8266) so we exclude them 42 | - build_examples 43 | # - arduino -v --verbose-build --verify $PWD/examples/AutoConnect/AutoConnect.ino 44 | 45 | # no coverage generated, no need to run 46 | # 47 | #after_success: 48 | # - bash <(curl -s https://codecov.io/bash) 49 | 50 | notifications: 51 | email: 52 | on_success: change 53 | on_failure: change 54 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/WiFiManager/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 tzapu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/WiFiManager/WiFiManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | * WiFiManager.h 3 | * 4 | * WiFiManager, a library for the ESP8266/Arduino platform 5 | * for configuration of WiFi credentials using a Captive Portal 6 | * 7 | * @author Creator tzapu 8 | * @author tablatronix 9 | * @version 0.0.0 10 | * @license MIT 11 | */ 12 | 13 | 14 | #ifndef WiFiManager_h 15 | #define WiFiManager_h 16 | 17 | #if defined(ESP8266) || defined(ESP32) 18 | 19 | #ifdef ESP8266 20 | #include 21 | #endif 22 | 23 | #include 24 | 25 | // #define WM_MDNS // also set MDNS with sethostname 26 | // #define WM_FIXERASECONFIG // use erase flash fix 27 | // #define WM_ERASE_NVS // esp32 erase(true) will erase NVS 28 | // #define WM_RTC // esp32 info page will include reset reasons 29 | 30 | #ifdef ARDUINO_ESP8266_RELEASE_2_3_0 31 | #warning "ARDUINO_ESP8266_RELEASE_2_3_0, some WM features disabled" 32 | #define WM_NOASYNC // esp8266 no async scan wifi 33 | #endif 34 | 35 | // #include "soc/efuse_reg.h" // include to add efuse chip rev to info, getChipRevision() is almost always the same though, so not sure why it matters. 36 | 37 | // #define esp32autoreconnect // implement esp32 autoreconnect event listener kludge, @DEPRECATED 38 | // autoreconnect is WORKING https://github.com/espressif/arduino-esp32/issues/653#issuecomment-405604766 39 | 40 | #define WM_WEBSERVERSHIM // use webserver shim lib 41 | 42 | #ifdef ESP8266 43 | 44 | extern "C" { 45 | #include "user_interface.h" 46 | } 47 | #include 48 | #include 49 | 50 | #ifdef WM_MDNS 51 | #include 52 | #endif 53 | 54 | #define WIFI_getChipId() ESP.getChipId() 55 | #define WM_WIFIOPEN ENC_TYPE_NONE 56 | 57 | #elif defined(ESP32) 58 | 59 | #include 60 | #include 61 | 62 | #define WIFI_getChipId() (uint32_t)ESP.getEfuseMac() 63 | #define WM_WIFIOPEN WIFI_AUTH_OPEN 64 | 65 | #ifndef WEBSERVER_H 66 | #ifdef WM_WEBSERVERSHIM 67 | #include 68 | #else 69 | #include 70 | // Forthcoming official ? 71 | // https://github.com/esp8266/ESPWebServer 72 | #endif 73 | #endif 74 | 75 | #ifdef WM_ERASE_NVS 76 | #include 77 | #include 78 | #endif 79 | 80 | #ifdef WM_MDNS 81 | #include 82 | #endif 83 | 84 | #ifdef WM_RTC 85 | #include 86 | #endif 87 | 88 | 89 | #else 90 | #endif 91 | 92 | #include 93 | #include 94 | #include "strings_en.h" 95 | 96 | #ifndef WIFI_MANAGER_MAX_PARAMS 97 | #define WIFI_MANAGER_MAX_PARAMS 5 // params will autoincrement and realloc by this amount when max is reached 98 | #endif 99 | 100 | #define WFM_LABEL_BEFORE 1 101 | #define WFM_LABEL_AFTER 2 102 | #define WFM_NO_LABEL 0 103 | 104 | class WiFiManagerParameter { 105 | public: 106 | /** 107 | Create custom parameters that can be added to the WiFiManager setup web page 108 | @id is used for HTTP queries and must not contain spaces nor other special characters 109 | */ 110 | WiFiManagerParameter(); 111 | WiFiManagerParameter(const char *custom); 112 | WiFiManagerParameter(const char *id, const char *label); 113 | WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length); 114 | WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom); 115 | WiFiManagerParameter(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement); 116 | ~WiFiManagerParameter(); 117 | 118 | const char *getID(); 119 | const char *getValue(); 120 | const char *getLabel(); 121 | const char *getPlaceholder(); // @deprecated, use getLabel 122 | int getValueLength(); 123 | int getLabelPlacement(); 124 | const char *getCustomHTML(); 125 | void setValue(const char *defaultValue, int length); 126 | 127 | protected: 128 | void init(const char *id, const char *label, const char *defaultValue, int length, const char *custom, int labelPlacement); 129 | 130 | private: 131 | const char *_id; 132 | const char *_label; 133 | char *_value; 134 | int _length; 135 | int _labelPlacement; 136 | const char *_customHTML; 137 | 138 | friend class WiFiManager; 139 | }; 140 | 141 | 142 | class WiFiManager 143 | { 144 | public: 145 | WiFiManager(Stream& consolePort); 146 | WiFiManager(); 147 | ~WiFiManager(); 148 | void WiFiManagerInit(); 149 | 150 | // auto connect to saved wifi, or custom, and start config portal on failures 151 | boolean autoConnect(); 152 | boolean autoConnect(char const *apName, char const *apPassword = NULL); 153 | 154 | //manually start the config portal, autoconnect does this automatically on connect failure 155 | boolean startConfigPortal(); // auto generates apname 156 | boolean startConfigPortal(char const *apName, char const *apPassword = NULL); 157 | 158 | //manually stop the config portal if started manually, stop immediatly if non blocking, flag abort if blocking 159 | bool stopConfigPortal(); 160 | 161 | //manually start the web portal, autoconnect does this automatically on connect failure 162 | void startWebPortal(); 163 | //manually stop the web portal if started manually 164 | void stopWebPortal(); 165 | // Run webserver processing, if setConfigPortalBlocking(false) 166 | boolean process(); 167 | 168 | // get the AP name of the config portal, so it can be used in the callback 169 | String getConfigPortalSSID(); 170 | int getRSSIasQuality(int RSSI); 171 | 172 | // erase wifi credentials 173 | void resetSettings(); 174 | // reboot esp 175 | void reboot(); 176 | // disconnect wifi, without persistent saving or erasing 177 | bool disconnect(); 178 | // erase esp 179 | bool erase(); 180 | bool erase(bool opt); 181 | 182 | //adds a custom parameter, returns false on failure 183 | bool addParameter(WiFiManagerParameter *p); 184 | //returns the list of Parameters 185 | WiFiManagerParameter** getParameters(); 186 | // returns the Parameters Count 187 | int getParametersCount(); 188 | 189 | 190 | // SET CALLBACKS 191 | 192 | //called after AP mode and config portal has started 193 | void setAPCallback( std::function func ); 194 | //called after webserver has started 195 | void setWebServerCallback( std::function func ); 196 | //called when settings reset have been triggered 197 | void setConfigResetCallback( std::function func ); 198 | //called when wifi settings have been changed and connection was successful ( or setBreakAfterConfig(true) ) 199 | void setSaveConfigCallback( std::function func ); 200 | //called when settings have been changed and connection was successful 201 | void setSaveParamsCallback( std::function func ); 202 | //called when settings before have been changed and connection was successful 203 | void setPreSaveConfigCallback( std::function func ); 204 | 205 | 206 | //sets timeout before AP,webserver loop ends and exits even if there has been no setup. 207 | //useful for devices that failed to connect at some point and got stuck in a webserver loop 208 | //in seconds setConfigPortalTimeout is a new name for setTimeout, ! not used if setConfigPortalBlocking 209 | void setConfigPortalTimeout(unsigned long seconds); 210 | void setTimeout(unsigned long seconds); // @deprecated, alias 211 | 212 | //sets timeout for which to attempt connecting, useful if you get a lot of failed connects 213 | void setConnectTimeout(unsigned long seconds); 214 | //sets timeout for which to attempt connecting on saves, useful if there are bugs in esp waitforconnectloop 215 | void setSaveConnectTimeout(unsigned long seconds); 216 | // toggle debug output 217 | void setDebugOutput(boolean debug); 218 | //set min quality percentage to include in scan, defaults to 8% if not specified 219 | void setMinimumSignalQuality(int quality = 8); 220 | //sets a custom ip /gateway /subnet configuration 221 | void setAPStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn); 222 | //sets config for a static IP 223 | void setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn); 224 | //sets config for a static IP with DNS 225 | void setSTAStaticIPConfig(IPAddress ip, IPAddress gw, IPAddress sn, IPAddress dns); 226 | //if this is set, it will exit after config, even if connection is unsuccessful. 227 | void setBreakAfterConfig(boolean shouldBreak); 228 | // if this is set, portal will be blocking and wait until save or exit, 229 | // is false user must manually `process()` to handle config portal, 230 | // setConfigPortalTimeout is ignored in this mode, user is responsible for closing configportal 231 | void setConfigPortalBlocking(boolean shouldBlock); 232 | //if this is set, customise style 233 | void setCustomHeadElement(const char* element); 234 | //if this is true, remove duplicated Access Points - defaut true 235 | void setRemoveDuplicateAPs(boolean removeDuplicates); 236 | //setter for ESP wifi.persistent so we can remember it and restore user preference, as WIFi._persistent is protected 237 | void setRestorePersistent(boolean persistent); 238 | //if true, always show static net inputs, IP, subnet, gateway, else only show if set via setSTAStaticIPConfig 239 | void setShowStaticFields(boolean alwaysShow); 240 | //if true, always show static dns, esle only show if set via setSTAStaticIPConfig 241 | void setShowDnsFields(boolean alwaysShow); 242 | //if false, disable captive portal redirection 243 | void setCaptivePortalEnable(boolean enabled); 244 | //if false, timeout captive portal even if a STA client connected to softAP (false), suggest disabling if captiveportal is open 245 | void setAPClientCheck(boolean enabled); 246 | //if true, reset timeout when webclient connects (true), suggest disabling if captiveportal is open 247 | void setWebPortalClientCheck(boolean enabled); 248 | // if true, enable autoreconnecting 249 | void setWiFiAutoReconnect(boolean enabled); 250 | // if true, wifiscan will show percentage instead of quality icons, until we have better templating 251 | void setScanDispPerc(boolean enabled); 252 | // if true (default) then start the config portal from autoConnect if connection failed 253 | void setEnableConfigPortal(boolean enable); 254 | // set a custom hostname, sets sta and ap dhcp client id for esp32, and sta for esp8266 255 | bool setHostname(const char * hostname); 256 | // show erase wifi onfig button on info page, true 257 | void setShowInfoErase(boolean enabled); 258 | // set custom menu 259 | 260 | // set custom menu items and order 261 | void setMenu(std::vector& menu); 262 | void setMenu(const char* menu[], uint8_t size); 263 | 264 | // get last connection result, includes autoconnect and wifisave 265 | uint8_t getLastConxResult(); 266 | // get a status as string 267 | String getWLStatusString(uint8_t status); 268 | String getModeString(uint8_t mode); 269 | // check if the module has a saved ap to connect to 270 | bool getWiFiIsSaved(); 271 | 272 | // debug output the softap config 273 | void debugSoftAPConfig(); 274 | // debug output platform info and versioning 275 | void debugPlatformInfo(); 276 | String htmlEntities(String str); 277 | 278 | // set the country code for wifi settings 279 | void setCountry(String cc); 280 | // set body class (invert) 281 | void setClass(String str); 282 | 283 | std::unique_ptr dnsServer; 284 | 285 | #if defined(ESP32) && defined(WM_WEBSERVERSHIM) 286 | using WM_WebServer = WebServer; 287 | #else 288 | using WM_WebServer = ESP8266WebServer; 289 | #endif 290 | 291 | std::unique_ptr server; 292 | 293 | private: 294 | std::vector _menuIds; 295 | std::vector _menuIdsDefault = {"wifi","info","exit"}; 296 | 297 | // ip configs @todo struct ? 298 | IPAddress _ap_static_ip; 299 | IPAddress _ap_static_gw; 300 | IPAddress _ap_static_sn; 301 | IPAddress _sta_static_ip; 302 | IPAddress _sta_static_gw; 303 | IPAddress _sta_static_sn; 304 | IPAddress _sta_static_dns; 305 | 306 | // defaults 307 | const byte DNS_PORT = 53; 308 | const byte HTTP_PORT = 80; 309 | String _apName = "no-net"; 310 | String _apPassword = ""; 311 | String _ssid = ""; 312 | String _pass = ""; 313 | 314 | // options flags 315 | unsigned long _configPortalTimeout = 0; // ms close config portal loop if set (depending on _cp/webClientCheck options) 316 | unsigned long _connectTimeout = 0; // ms stop trying to connect to ap if set 317 | unsigned long _saveTimeout = 0; // ms stop trying to connect to ap on saves, in case bugs in esp waitforconnectresult 318 | unsigned long _configPortalStart = 0; // ms config portal start time (updated for timeouts) 319 | unsigned long _webPortalAccessed = 0; // ms last web access time 320 | WiFiMode_t _usermode = WIFI_OFF; 321 | String _wifissidprefix = FPSTR(S_ssidpre); // auto apname prefix prefix+chipid 322 | uint8_t _lastconxresult = WL_IDLE_STATUS; 323 | int _numNetworks = 0; 324 | unsigned long _lastscan = 0; // ms for timing wifi scans 325 | unsigned long _startscan = 0; // ms for timing wifi scans 326 | int _cpclosedelay = 2000; // delay before wifisave, prevents captive portal from closing to fast. 327 | bool _cleanConnect = true; // disconnect before connect in connectwifi, increases stability on connects 328 | 329 | bool _disableSTA = false; // disable sta when starting ap, always 330 | bool _disableSTAConn = true; // disable sta when starting ap, if sta is not connected ( stability ) 331 | bool _channelSync = false; // use wifi channel when starting ap 332 | 333 | #ifdef ESP32 334 | static uint8_t _lastconxresulttmp; // tmp var for esp32 callback 335 | #endif 336 | 337 | #ifndef WL_STATION_WRONG_PASSWORD 338 | uint8_t WL_STATION_WRONG_PASSWORD = 7; // @kludge define a WL status for wrong password 339 | #endif 340 | 341 | // parameter options 342 | int _minimumQuality = -1; // filter wifiscan ap by this rssi 343 | int _staShowStaticFields = 0; // ternary always show static ip fields, only if not set in code, never(cannot change ips via web!) 344 | int _staShowDns = 0; // ternary always show dns, only if not set in code, never(cannot change dns via web!) 345 | boolean _removeDuplicateAPs = true; // remove dup aps from wifiscan 346 | boolean _shouldBreakAfterConfig = false; // stop configportal on save failure 347 | boolean _configPortalIsBlocking = true; // configportal enters blocking loop 348 | boolean _enableCaptivePortal = true; // enable captive portal redirection 349 | boolean _userpersistent = true; // users preffered persistence to restore 350 | boolean _wifiAutoReconnect = true; // there is no platform getter for this, we must assume its true and make it so 351 | boolean _apClientCheck = false; // keep cp alive if ap have station 352 | boolean _webClientCheck = true; // keep cp alive if web have client 353 | boolean _scanDispOptions = false; // show percentage in scans not icons 354 | boolean _paramsInWifi = true; // show custom parameters on wifi page 355 | boolean _showInfoErase = true; // info page erase button 356 | boolean _enableConfigPortal = true; // use config portal if autoconnect failed 357 | const char * _hostname = ""; 358 | 359 | const char* _customHeadElement = ""; // store custom head element html from user 360 | String _bodyClass = ""; // class to add to body 361 | 362 | // internal options 363 | boolean _preloadwifiscan = true; // preload wifiscan if true 364 | boolean _disableIpFields = false; // edge case, if true, showxFields(false) forces ip fields off instead of default show when set 365 | 366 | String _wificountry = ""; // country code, @todo define in strings lang 367 | 368 | // wrapper functions for handling setting and unsetting persistent for now. 369 | bool esp32persistent = false; 370 | bool _hasBegun = false; 371 | void _begin(); 372 | void _end(); 373 | 374 | void setupConfigPortal(); 375 | bool shutdownConfigPortal(); 376 | 377 | #ifdef NO_EXTRA_4K_HEAP 378 | boolean _tryWPS = false; // try WPS on save failure, unsupported 379 | void startWPS(); 380 | #endif 381 | 382 | bool startAP(); 383 | 384 | uint8_t connectWifi(String ssid, String pass); 385 | bool setSTAConfig(); 386 | bool wifiConnectDefault(); 387 | bool wifiConnectNew(String ssid, String pass); 388 | 389 | uint8_t waitForConnectResult(); 390 | uint8_t waitForConnectResult(uint16_t timeout); 391 | void updateConxResult(uint8_t status); 392 | 393 | // webserver handlers 394 | void handleRoot(); 395 | void handleWifi(boolean scan); 396 | void handleWifiSave(); 397 | void handleInfo(); 398 | void handleReset(); 399 | void handleNotFound(); 400 | void handleExit(); 401 | void handleClose(); 402 | // void handleErase(); 403 | void handleErase(boolean opt); 404 | void handleParam(); 405 | void handleWiFiStatus(); 406 | void handleRequest(); 407 | void handleParamSave(); 408 | void doParamSave(); 409 | 410 | boolean captivePortal(); 411 | boolean configPortalHasTimeout(); 412 | uint8_t processConfigPortal(); 413 | void stopCaptivePortal(); 414 | 415 | // wifi platform abstractions 416 | bool WiFi_Mode(WiFiMode_t m); 417 | bool WiFi_Mode(WiFiMode_t m,bool persistent); 418 | bool WiFi_Disconnect(); 419 | bool WiFi_enableSTA(bool enable); 420 | bool WiFi_enableSTA(bool enable,bool persistent); 421 | bool WiFi_eraseConfig(); 422 | uint8_t WiFi_softap_num_stations(); 423 | bool WiFi_hasAutoConnect(); 424 | void WiFi_autoReconnect(); 425 | String WiFi_SSID(); 426 | bool WiFi_scanNetworks(); 427 | bool WiFi_scanNetworks(bool force,bool async); 428 | bool WiFi_scanNetworks(unsigned int cachetime,bool async); 429 | bool WiFi_scanNetworks(unsigned int cachetime); 430 | void WiFi_scanComplete(int networksFound); 431 | bool WiFiSetCountry(); 432 | 433 | #ifdef ESP32 434 | void WiFiEvent(WiFiEvent_t event, system_event_info_t info); 435 | #endif 436 | 437 | // output helpers 438 | String getParamOut(); 439 | String getIpForm(String id, String title, String value); 440 | String getScanItemOut(); 441 | String getStaticOut(); 442 | String getHTTPHead(String title); 443 | String getMenuOut(); 444 | //helpers 445 | boolean isIp(String str); 446 | String toStringIp(IPAddress ip); 447 | boolean validApPassword(); 448 | String encryptionTypeStr(uint8_t authmode); 449 | void reportStatus(String &page); 450 | String getInfoData(String id); 451 | 452 | // flags 453 | boolean connect; 454 | boolean abort; 455 | boolean reset = false; 456 | boolean configPortalActive = false; 457 | boolean webPortalActive = false; 458 | boolean portalTimeoutResult = false; 459 | boolean portalAbortResult = false; 460 | boolean storeSTAmode = true; // option store persistent STA mode in connectwifi 461 | int timer = 0; 462 | 463 | // WiFiManagerParameter 464 | int _paramsCount = 0; 465 | int _max_params; 466 | WiFiManagerParameter** _params = NULL; 467 | 468 | // debugging 469 | typedef enum { 470 | DEBUG_ERROR = 0, 471 | DEBUG_NOTIFY = 1, // default 472 | DEBUG_VERBOSE = 2, 473 | DEBUG_DEV = 3, 474 | DEBUG_MAX = 4 475 | } wm_debuglevel_t; 476 | 477 | boolean _debug = true; 478 | uint8_t _debugLevel = DEBUG_DEV; 479 | Stream& _debugPort; // debug output stream ref 480 | 481 | template 482 | void DEBUG_WM(Generic text); 483 | 484 | template 485 | void DEBUG_WM(wm_debuglevel_t level,Generic text); 486 | template 487 | void DEBUG_WM(Generic text,Genericb textb); 488 | template 489 | void DEBUG_WM(wm_debuglevel_t level, Generic text,Genericb textb); 490 | 491 | // callbacks 492 | // @todo use cb list (vector) maybe event ids, allow no return value 493 | std::function _apcallback; 494 | std::function _webservercallback; 495 | std::function _savewificallback; 496 | std::function _presavecallback; 497 | std::function _saveparamscallback; 498 | std::function _resetcallback; 499 | 500 | template 501 | auto optionalIPFromString(T *obj, const char *s) -> decltype( obj->fromString(s) ) { 502 | return obj->fromString(s); 503 | } 504 | auto optionalIPFromString(...) -> bool { 505 | // DEBUG_WM("NO fromString METHOD ON IPAddress, you need ESP8266 core 2.1.0 or newer for Custom IP configuration to work."); 506 | return false; 507 | } 508 | }; 509 | 510 | #endif 511 | 512 | #endif -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/WiFiManager/extras/WiFiManager.template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | {v} 7 | 8 | 9 | 170 | 171 | 172 | 175 | 176 | 177 | 178 | 179 |
180 | 181 | 182 | 183 |

/


184 | 185 | 186 | 187 | 188 |

189 | 190 |

191 |

192 |

193 |

194 |

195 |

196 | 197 | 198 |

/wifi


199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 |



220 | 221 | 222 |

custom parameter


223 |
224 |
225 | 226 | 227 |
228 | 229 | 230 |
231 | 232 | 233 |
234 | 235 | 236 |
237 | 238 | 239 |

Saving Credentials

Trying to connect ESP to network.
If it fails reconnect to AP to try again
240 | 241 | 242 |
Connected to {v}
with IP {i}
243 | 244 | 245 |
Not Connected to {v}{r}
246 | 247 | 248 |
Not Connected to apname 249 | 250 | 251 |
Authentication Failure 252 | 253 | 254 |
AP not found 255 | 256 | 257 |
Could not Connect 258 | 259 |
260 | 261 |
No AP set
262 | 263 | 264 |

H4 Color Header

content
265 | 266 | 267 |

/info


268 |
269 |
Chip ID
123456
270 |
Flash Chip ID
1234556
271 |
IDE Flash Size
4194304 bytes
272 |
Real Flash Size
4194304 bytes
273 |
Empty
274 |
Soft AP IP
192.168.4.1
275 |
Soft AP MAC
00:00:00:00:00:00
276 |
Station MAC
00:00:00:00:00:00
277 |
278 | 279 | 280 |

Available Pages


281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 |
PageFunction
/Menu page.
/wifiShow WiFi scan results and enter WiFi configuration.(/0wifi noscan)
/wifisaveSave WiFi configuration information and configure device. Needs variables supplied.
/closeClose the configuration server and configuration WiFi network.
/infoInformation page
/closeClose the captiveportal popup,configportal will remain active
/exitExit Config Portal, configportal will close
/restartReboot the device
/eraseErase WiFi configuration and reboot Device. Device will not reconnect to a network until new WiFi configuration data is entered.
302 |

More information about WiFiManager at https://github.com/tzapu/WiFiManager 303 | 304 | 305 |

Form UPLOAD

306 | 307 | 308 | 309 |
310 | 311 | 312 | 313 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/WiFiManager/extras/parse.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | 5 | console.log('starting'); 6 | 7 | const inFile = 'WiFiManager.template.html'; 8 | const outFile = 'template.h'; 9 | 10 | const defineRegEx = //gm; 11 | console.log('parsing', inFile); 12 | 13 | fs.readFile(inFile, 'utf8', function (err,data) { 14 | if (err) { 15 | return console.log(err); 16 | } 17 | //console.log(data); 18 | 19 | let defines = data.match(defineRegEx); 20 | 21 | //console.log(defines); 22 | var stream = fs.createWriteStream(outFile); 23 | stream.once('open', function(fd) { 24 | for (const i in defines) { 25 | 26 | const start = defines[i]; 27 | const end = start.replace(' 133 |
134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 |
149 |
150 | 151 |
152 | 153 |
154 |
155 | 156 |
157 | 158 |
159 | 160 |
161 |
162 | 163 |
164 | 165 |
166 | 167 |
168 |
169 | 170 |
171 |
172 | 173 |
174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/WiFiManager/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For WifiManager 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | WiFiManager KEYWORD1 10 | WiFiManagerParameter KEYWORD1 11 | 12 | 13 | ####################################### 14 | # Methods and Functions (KEYWORD2) 15 | ####################################### 16 | autoConnect KEYWORD2 17 | getSSID KEYWORD2 18 | getPassword KEYWORD2 19 | getConfigPortalSSID KEYWORD2 20 | resetSettings KEYWORD2 21 | setConfigPortalTimeout KEYWORD2 22 | setConnectTimeout KEYWORD2 23 | setDebugOutput KEYWORD2 24 | setMinimumSignalQuality KEYWORD2 25 | setAPStaticIPConfig KEYWORD2 26 | setSTAStaticIPConfig KEYWORD2 27 | setAPCallback KEYWORD2 28 | setSaveConfigCallback KEYWORD2 29 | addParameter KEYWORD2 30 | getID KEYWORD2 31 | getValue KEYWORD2 32 | getPlaceholder KEYWORD2 33 | getValueLength KEYWORD2 34 | 35 | ####################################### 36 | # Constants (LITERAL1) 37 | ####################################### 38 | 39 | # LITERAL1 40 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/WiFiManager/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WifiManager", 3 | "keywords": "wifi,wi-fi,esp,esp8266,esp32,espressif8266,espressif32,nodemcu,wemos,arduino", 4 | "description": "WiFi Configuration manager with web configuration portal for ESP boards", 5 | "authors": 6 | [ 7 | { 8 | "name": "tzapu", 9 | "url": "https://github.com/tzapu" 10 | }, 11 | { 12 | "name": "tablatronix", 13 | "url": "https://github.com/tablatronix", 14 | "maintainer": true 15 | } 16 | ], 17 | "repository": 18 | { 19 | "type": "git", 20 | "url": "https://github.com/tzapu/WiFiManager.git" 21 | }, 22 | "frameworks": "arduino", 23 | "platforms": 24 | [ 25 | "espressif8266", 26 | "espressif32" 27 | ], 28 | "version": "1.0.0" 29 | } 30 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/WiFiManager/library.properties: -------------------------------------------------------------------------------- 1 | name=WiFiManager 2 | version=1.0.0 3 | author=tzapu,tablatronix 4 | maintainer=tablatronix 5 | sentence=WiFi Configuration manager with web configuration portal for ESP boards 6 | paragraph=Library for configuring ESP8266/ESP32 modules WiFi credentials and custom parameters at runtime. 7 | category=Communication 8 | url=https://github.com/tzapu/WiFiManager.git 9 | architectures=esp8266,esp32 10 | -------------------------------------------------------------------------------- /SmartTriangle_Server/lib/WiFiManager/strings_en.h: -------------------------------------------------------------------------------- 1 | /** 2 | * strings_en.h 3 | * engligh strings for 4 | * WiFiManager, a library for the ESP8266/Arduino platform 5 | * for configuration of WiFi credentials using a Captive Portal 6 | * 7 | * @author Creator tzapu 8 | * @author tablatronix 9 | * @version 0.0.0 10 | * @license MIT 11 | */ 12 | 13 | #ifndef WIFI_MANAGER_OVERRIDE_STRINGS 14 | // !!! THIS DOES NOT WORK, you cannot define in a sketch, if anyone one knows how to order includes to be able to do this help! 15 | 16 | const char HTTP_HEAD_START[] PROGMEM = "{v}"; 17 | const char HTTP_SCRIPT[] PROGMEM = ""; 18 | const char HTTP_HEAD_END[] PROGMEM = "
"; 19 | 20 | const char HTTP_ROOT_MAIN[] PROGMEM = "

{v}

v0.2

"; 21 | const char * const HTTP_PORTAL_MENU[] PROGMEM = { 22 | "

\n", // MENU_WIFI 23 | "

\n", // MENU_CLOSE 24 | "

\n",// MENU_RESTART 25 | "

\n", // MENU_EXIT 26 | "

\n", // MENU_ERASE 27 | "

" // MENU_SEP 28 | }; 29 | 30 | // const char HTTP_PORTAL_OPTIONS[] PROGMEM = strcat(HTTP_PORTAL_MENU[0] , HTTP_PORTAL_MENU[3] , HTTP_PORTAL_MENU[7]); 31 | const char HTTP_PORTAL_OPTIONS[] PROGMEM = ""; 32 | const char HTTP_ITEM_QI[] PROGMEM = ""; // rssi icons 33 | const char HTTP_ITEM_QP[] PROGMEM = "
{r}%
"; // rssi percentage 34 | const char HTTP_ITEM[] PROGMEM = "
{v}{qi}{qp}
"; // {q} = HTTP_ITEM_QI, {r} = HTTP_ITEM_QP 35 | // const char HTTP_ITEM[] PROGMEM = "
{v} {R} {r}% {q} {e}
"; // test all tokens 36 | const char DESCRIPTION[] PROGMEM = "
Saving Settings
Trying to connect Matrix Controller to network.
If it fails reconnect to Hotspot to try again
"; 37 | 38 | const char HTTP_FORM_START[] PROGMEM = "
"; 39 | const char HTTP_FORM_WIFI[] PROGMEM = "
"; 40 | const char HTTP_FORM_WIFI_END[] PROGMEM = ""; 41 | const char HTTP_FORM_STATIC_HEAD[] PROGMEM = "

"; 42 | const char HTTP_FORM_END[] PROGMEM = "

"; 43 | const char HTTP_FORM_LABEL[] PROGMEM = ""; 44 | const char HTTP_FORM_PARAM_HEAD[] PROGMEM = "

"; 45 | const char HTTP_FORM_PARAM[] PROGMEM = "
"; 46 | 47 | const char HTTP_SCAN_LINK[] PROGMEM = "
"; 48 | const char HTTP_SAVED[] PROGMEM = "
Saving Settings
Trying to connect Matrix Controller to network.
If it fails reconnect to Hotspot to try again
"; 49 | const char HTTP_PARAMSAVED[] PROGMEM = "
Saved
"; 50 | const char HTTP_END[] PROGMEM = "
"; 51 | const char HTTP_ERASEBTN[] PROGMEM = "
"; 52 | 53 | const char HTTP_STATUS_ON[] PROGMEM = "
Connected to {v}
with IP {i}
"; 54 | const char HTTP_STATUS_OFF[] PROGMEM = "
Not Connected to {v}{r}
"; 55 | const char HTTP_STATUS_OFFPW[] PROGMEM = "
Authentication Failure"; // STATION_WRONG_PASSWORD, no eps32 56 | const char HTTP_STATUS_OFFNOAP[] PROGMEM = "
AP not found"; // WL_NO_SSID_AVAIL 57 | const char HTTP_STATUS_OFFFAIL[] PROGMEM = "
Could not Connect"; // WL_CONNECT_FAILED 58 | const char HTTP_STATUS_NONE[] PROGMEM = "
No AP set
"; 59 | const char HTTP_BR[] PROGMEM = "
"; 60 | 61 | const char HTTP_STYLE[] PROGMEM = ""; 88 | 89 | const char HTTP_HELP[] PROGMEM = 90 | "

Available Pages


" 91 | "" 92 | "" 93 | "" 94 | "" 95 | "" 96 | "" 97 | "" 98 | "" 99 | "" 100 | "" 101 | "" 102 | "" 103 | "" 104 | "" 105 | "" 106 | "" 107 | "" 108 | "" 109 | "" 110 | "" 111 | "
PageFunction
/Menu page.
/wifiShow WiFi scan results and enter WiFi configuration.(/0wifi noscan)
/wifisaveSave WiFi configuration information and configure device. Needs variables supplied.
/paramParameter page
/infoInformation page
/closeClose the captiveportal popup,configportal will remain active
/exitExit Config Portal, configportal will close
/restartReboot the device
/eraseErase WiFi configuration and reboot Device. Device will not reconnect to a network until new WiFi configuration data is entered.
" 112 | "

More information about WiFiManager at https://github.com/tzapu/WiFiManager."; 113 | 114 | #ifdef JSTEST 115 | const char HTTP_JS[] PROGMEM = 116 | ""; 132 | #endif 133 | 134 | // Info html 135 | #ifdef ESP32 136 | const char HTTP_INFO_esphead[] PROGMEM = "

esp32


"; 137 | const char HTTP_INFO_chiprev[] PROGMEM = "
Chip Rev
{1}
"; 138 | const char HTTP_INFO_lastreset[] PROGMEM = "
Last reset reason
CPU0: {1}
CPU1: {2}
"; 139 | const char HTTP_INFO_aphost[] PROGMEM = "
Acccess Point Hostname
{1}
"; 140 | #else 141 | const char HTTP_INFO_esphead[] PROGMEM = "

esp8266


"; 142 | const char HTTP_INFO_flashsize[] PROGMEM = "
Real Flash Size
{1} bytes
"; 143 | const char HTTP_INFO_fchipid[] PROGMEM = "
Flash Chip ID
{1}
"; 144 | const char HTTP_INFO_corever[] PROGMEM = "
Core Version
{1}
"; 145 | const char HTTP_INFO_bootver[] PROGMEM = "
Boot Version
{1}
"; 146 | const char HTTP_INFO_memsketch[] PROGMEM = "
Memory - Sketch Size
Used / Total bytes
{1} / {2}"; 147 | const char HTTP_INFO_memsmeter[] PROGMEM = "
"; 148 | const char HTTP_INFO_lastreset[] PROGMEM = "
Last reset reason
{1}
"; 149 | #endif 150 | 151 | const char HTTP_INFO_freeheap[] PROGMEM = "
Memory - Free Heap
{1} bytes available
"; 152 | const char HTTP_INFO_wifihead[] PROGMEM = "

WiFi


"; 153 | const char HTTP_INFO_uptime[] PROGMEM = "
Uptime
{1} Mins {2} Secs
"; 154 | const char HTTP_INFO_chipid[] PROGMEM = "
Chip ID
{1}
"; 155 | const char HTTP_INFO_idesize[] PROGMEM = "
Flash Size
{1} bytes
"; 156 | const char HTTP_INFO_sdkver[] PROGMEM = "
SDK Version
{1}
"; 157 | const char HTTP_INFO_cpufreq[] PROGMEM = "
CPU Frequency
{1}MHz
"; 158 | const char HTTP_INFO_apip[] PROGMEM = "
Access Point IP
{1}
"; 159 | const char HTTP_INFO_apmac[] PROGMEM = "
Access Point MAC
{1}
"; 160 | const char HTTP_INFO_apssid[] PROGMEM = "
SSID
{1}
"; 161 | const char HTTP_INFO_apbssid[] PROGMEM = "
BSSID
{1}
"; 162 | const char HTTP_INFO_staip[] PROGMEM = "
Station IP
{1}
"; 163 | const char HTTP_INFO_stagw[] PROGMEM = "
Station Gateway
{1}
"; 164 | const char HTTP_INFO_stasub[] PROGMEM = "
Station Subnet
{1}
"; 165 | const char HTTP_INFO_dnss[] PROGMEM = "
DNS Server
{1}
"; 166 | const char HTTP_INFO_host[] PROGMEM = "
Hostname
{1}
"; 167 | const char HTTP_INFO_stamac[] PROGMEM = "
Station MAC
{1}
"; 168 | const char HTTP_INFO_conx[] PROGMEM = "
Connected
{1}
"; 169 | const char HTTP_INFO_autoconx[] PROGMEM = "
Autoconnect
{1}
"; 170 | const char HTTP_INFO_temp[] PROGMEM = "
Temperature
{1} C° / {2} F°
"; 171 | 172 | // Strings 173 | const char S_y[] PROGMEM = "Yes"; 174 | const char S_n[] PROGMEM = "No"; 175 | const char S_enable[] PROGMEM = "Enabled"; 176 | const char S_disable[] PROGMEM = "Disabled"; 177 | const char S_GET[] PROGMEM = "GET"; 178 | const char S_POST[] PROGMEM = "POST"; 179 | const char S_NA[] PROGMEM = "Unknown"; 180 | 181 | const char S_titlewifisaved[] PROGMEM = "Credentials Saved"; 182 | const char S_titlewifi[] PROGMEM = "Config ESP"; 183 | const char S_titleinfo[] PROGMEM = "Info"; 184 | const char S_titleparam[] PROGMEM = "Setup"; 185 | const char S_titleparamsaved[] PROGMEM = "Setup Saved"; 186 | const char S_titleexit[] PROGMEM = "Exit"; 187 | const char S_titlereset[] PROGMEM = "Reset"; 188 | const char S_titleerase[] PROGMEM = "Erase"; 189 | const char S_titleclose[] PROGMEM = "Close"; 190 | const char S_options[] PROGMEM = "options"; 191 | const char S_nonetworks[] PROGMEM = "No networks found. Refresh to scan again."; 192 | const char S_staticip[] PROGMEM = "Static IP"; 193 | const char S_staticgw[] PROGMEM = "Static Gateway"; 194 | const char S_staticdns[] PROGMEM = "Static DNS"; 195 | const char S_subnet[] PROGMEM = "Subnet"; 196 | const char S_exiting[] PROGMEM = "Exiting"; 197 | const char S_resetting[] PROGMEM = "Module will reset in a few seconds."; 198 | const char S_closing[] PROGMEM = "You can close the page, portal will continue to run"; 199 | const char S_error[] PROGMEM = "An Error Occured"; 200 | const char S_notfound[] PROGMEM = "File Not Found\n\n"; 201 | const char S_uri[] PROGMEM = "URI: "; 202 | const char S_method[] PROGMEM = "\nMethod: "; 203 | const char S_args[] PROGMEM = "\nArguments: "; 204 | const char S_parampre[] PROGMEM = "param_"; 205 | 206 | // debug strings 207 | const char D_HR[] PROGMEM = "--------------------"; 208 | 209 | // END WIFI_MANAGER_OVERRIDE_STRINGS 210 | #endif 211 | 212 | // ----------------------------------------------------------------------------------------------- 213 | // DO NOT EDIT BELOW THIS LINE 214 | 215 | const uint8_t _nummenutokens = 9; 216 | const char * const _menutokens[9] PROGMEM = { 217 | "wifi", 218 | "wifinoscan", 219 | "info", 220 | "param", 221 | "close", 222 | "restart", 223 | "exit", 224 | "erase", 225 | "sep" 226 | }; 227 | 228 | const char R_root[] PROGMEM = "/"; 229 | const char R_wifi[] PROGMEM = "/wifi"; 230 | const char R_wifinoscan[] PROGMEM = "/0wifi"; 231 | const char R_wifisave[] PROGMEM = "/wifisave"; 232 | const char R_info[] PROGMEM = "/info"; 233 | const char R_param[] PROGMEM = "/param"; 234 | const char R_paramsave[] PROGMEM = "/paramsave"; 235 | const char R_restart[] PROGMEM = "/restart"; 236 | const char R_exit[] PROGMEM = "/exit"; 237 | const char R_close[] PROGMEM = "/close"; 238 | const char R_erase[] PROGMEM = "/erase"; 239 | const char R_status[] PROGMEM = "/status"; 240 | 241 | 242 | //Strings 243 | const char S_ip[] PROGMEM = "ip"; 244 | const char S_gw[] PROGMEM = "gw"; 245 | const char S_sn[] PROGMEM = "sn"; 246 | const char S_dns[] PROGMEM = "dns"; 247 | 248 | // softap ssid default prefix 249 | #ifdef ESP8266 250 | const char S_ssidpre[] PROGMEM = "ESP"; 251 | #elif defined(ESP32) 252 | const char S_ssidpre[] PROGMEM = "ESP32"; 253 | #else 254 | const char S_ssidpre[] PROGMEM = "WM"; 255 | #endif 256 | 257 | //Tokens 258 | //@todo consolidate and reduce 259 | const char T_ss[] PROGMEM = "{"; // token start sentinel 260 | const char T_es[] PROGMEM = "}"; // token end sentinel 261 | const char T_1[] PROGMEM = "{1}"; // @token 1 262 | const char T_2[] PROGMEM = "{2}"; // @token 2 263 | const char T_v[] PROGMEM = "{v}"; // @token v 264 | const char T_I[] PROGMEM = "{I}"; // @token I 265 | const char T_i[] PROGMEM = "{i}"; // @token i 266 | const char T_n[] PROGMEM = "{n}"; // @token n 267 | const char T_p[] PROGMEM = "{p}"; // @token p 268 | const char T_t[] PROGMEM = "{t}"; // @token t 269 | const char T_l[] PROGMEM = "{l}"; // @token l 270 | const char T_c[] PROGMEM = "{c}"; // @token c 271 | const char T_e[] PROGMEM = "{e}"; // @token e 272 | const char T_q[] PROGMEM = "{q}"; // @token q 273 | const char T_r[] PROGMEM = "{r}"; // @token r 274 | const char T_R[] PROGMEM = "{R}"; // @token R 275 | const char T_h[] PROGMEM = "{h}"; // @token h 276 | 277 | // http 278 | const char HTTP_HEAD_CL[] PROGMEM = "Content-Length"; 279 | const char HTTP_HEAD_CT[] PROGMEM = "text/html"; 280 | const char HTTP_HEAD_CT2[] PROGMEM = "text/plain"; 281 | const char HTTP_HEAD_CORS[] PROGMEM = "Access-Control-Allow-Origin"; 282 | const char HTTP_HEAD_CORS_ALLOW_ALL[] PROGMEM = "*"; 283 | 284 | const char * const WIFI_STA_STATUS[] PROGMEM 285 | { 286 | "WL_IDLE_STATUS", // 0 STATION_IDLE 287 | "WL_NO_SSID_AVAIL", // 1 STATION_NO_AP_FOUND 288 | "WL_SCAN_COMPLETED", // 2 289 | "WL_CONNECTED", // 3 STATION_GOT_IP 290 | "WL_CONNECT_FAILED", // 4 STATION_CONNECT_FAIL, STATION_WRONG_PASSWORD(NI) 291 | "WL_CONNECTION_LOST", // 5 292 | "WL_DISCONNECTED", // 6 293 | "WL_STATION_WRONG_PASSWORD" // 7 KLUDGE 294 | }; 295 | 296 | #ifdef ESP32 297 | const char * const AUTH_MODE_NAMES[] PROGMEM 298 | { 299 | "OPEN", 300 | "WEP", 301 | "WPA_PSK", 302 | "WPA2_PSK", 303 | "WPA_WPA2_PSK", 304 | "WPA2_ENTERPRISE", 305 | "MAX" 306 | }; 307 | #elif defined(ESP8266) 308 | const char * const AUTH_MODE_NAMES[] PROGMEM 309 | { 310 | "", 311 | "", 312 | "WPA_PSK", // 2 ENC_TYPE_TKIP 313 | "", 314 | "WPA2_PSK", // 4 ENC_TYPE_CCMP 315 | "WEP", // 5 ENC_TYPE_WEP 316 | "", 317 | "OPEN", //7 ENC_TYPE_NONE 318 | "WPA_WPA2_PSK", // 8 ENC_TYPE_AUTO 319 | }; 320 | #endif 321 | 322 | const char* const WIFI_MODES[] PROGMEM = { "NULL", "STA", "AP", "STA+AP" }; 323 | 324 | #ifdef ESP32 325 | const wifi_country_t WM_COUNTRY_US{"US",1,11,WIFI_COUNTRY_POLICY_AUTO}; 326 | const wifi_country_t WM_COUNTRY_CN{"CN",1,13,WIFI_COUNTRY_POLICY_AUTO}; 327 | const wifi_country_t WM_COUNTRY_JP{"JP",1,14,WIFI_COUNTRY_POLICY_AUTO}; 328 | #endif 329 | -------------------------------------------------------------------------------- /SmartTriangle_Server/platformio.ini: -------------------------------------------------------------------------------- 1 | ; PlatformIO Project Configuration File 2 | ; 3 | ; Build options: build flags, source filter 4 | ; Upload options: custom upload port, speed and extra flags 5 | ; Library options: dependencies, extra library storages 6 | ; Advanced options: extra scripting 7 | ; 8 | ; Please visit documentation for the other options and examples 9 | ; http://docs.platformio.org/page/projectconf.html 10 | 11 | [platformio] 12 | default_envs = nodemcuv2 13 | 14 | [common] 15 | lib_deps_builtin = 16 | SPI 17 | 18 | lib_deps= 19 | BME280_Light 20 | 5426 21 | 566 22 | [env:nodemcuv2] 23 | platform = espressif8266 24 | #board = nodemcuv2 25 | board = d1_mini 26 | build_flags = 27 | -DMQTT_MAX_PACKET_SIZE=3000 28 | -Wl,-Teagle.flash.4m1m.ld 29 | board_build.f_cpu = 80000000L 30 | framework = arduino 31 | monitor_speed = 115200 32 | upload_speed = 921600 33 | #upload_port = COM6 34 | lib_deps = 35 | ${common.lib_deps_builtin} 36 | ${common.lib_deps} -------------------------------------------------------------------------------- /SmartTriangle_Server/src/ADAction.cpp: -------------------------------------------------------------------------------- 1 | #include "ADAction.h" 2 | 3 | ADAction::ADAction(ActionCallback func,uint32_t interval, uint32_t times,uint32_t delay, bool autoDelete) 4 | { 5 | _callback = func; 6 | _delay = delay; 7 | _delay_c = delay; 8 | _interval = interval; 9 | _interval_c = interval; 10 | _times = times; 11 | _times_c = 0; 12 | _autoDelete = autoDelete; 13 | } 14 | 15 | ADAction::~ADAction() 16 | { 17 | } 18 | 19 | void ADAction::callbackAction() 20 | { 21 | _times_c++; 22 | this->callback(); 23 | } 24 | 25 | void ADAction::callback() 26 | { 27 | Serial.println(_times_c); 28 | _callback(_times_c, this); 29 | } 30 | 31 | ADAction *ADAction::create(ActionCallback func, uint32_t interval, uint32_t times,uint32_t delay, bool autoDelete) 32 | { 33 | ADAction *action = new ADAction(func, interval, times, delay, autoDelete); 34 | return action; 35 | } 36 | 37 | void ADAction::release() 38 | { 39 | delete this; 40 | } 41 | 42 | void ADAction::flush() 43 | { 44 | _times_c = 0; 45 | _delay_c = _delay; 46 | _interval_c = _interval; 47 | } 48 | 49 | bool ADAction::actNow(uint32_t dt) 50 | { 51 | if (_delay_c > dt) 52 | { 53 | _delay_c -= dt; 54 | } 55 | else 56 | { 57 | _delay_c = 0; 58 | if (_times_c == 0) 59 | { 60 | this->callbackAction(); 61 | } 62 | if (_interval_c > dt) 63 | { 64 | _interval_c -= dt; 65 | } 66 | else 67 | { 68 | _interval_c = 0; 69 | } 70 | 71 | } 72 | 73 | if (_delay_c == 0 && _interval_c == 0) 74 | { 75 | if (_times != 0 && _times_c >= _times) 76 | { 77 | this->flush(); 78 | if (_autoDelete) 79 | { 80 | return true; 81 | } 82 | }else 83 | { 84 | this->callbackAction(); 85 | _interval_c = _interval; 86 | } 87 | } 88 | return false; 89 | } 90 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/ADAction.h: -------------------------------------------------------------------------------- 1 | #ifndef __ADACTION_H__ 2 | #define __ADACTION_H__ 3 | 4 | #include "ADConfig.h" 5 | 6 | typedef void (*ActionCallback)(uint32_t, void *action); 7 | 8 | class ADAction 9 | { 10 | private: 11 | ActionCallback _callback; 12 | 13 | uint32_t _delay; 14 | 15 | uint32_t _interval; 16 | 17 | uint32_t _delay_c; 18 | 19 | uint32_t _interval_c; 20 | 21 | bool _autoDelete; 22 | 23 | void callbackAction(); 24 | 25 | virtual void callback(); 26 | 27 | protected: 28 | uint32_t _times; 29 | 30 | uint32_t _times_c; 31 | 32 | public: 33 | ADAction(ActionCallback func, uint32_t interval, uint32_t times = 0, uint32_t delay = 0, bool autoDelete = true); 34 | 35 | virtual ~ADAction(); 36 | 37 | //延迟delay毫秒,每间隔interval毫秒执行一次func,共执行times次。如果times==0,一直重复执行 38 | static ADAction *create(ActionCallback func, uint32_t interval, uint32_t times = 0, uint32_t delay = 0, bool autoDelete = true); 39 | 40 | void release(); 41 | 42 | void flush(); 43 | 44 | virtual bool actNow(uint32_t dt); 45 | }; 46 | 47 | #endif // __ADACTION_H__ -------------------------------------------------------------------------------- /SmartTriangle_Server/src/ADActor.cpp: -------------------------------------------------------------------------------- 1 | #include "ADActor.h" 2 | 3 | ADActor::ADActor(uint32_t showTime, bool autoDelete) 4 | { 5 | _showTime = showTime; 6 | _showTime_c = showTime; 7 | _autoDelete = autoDelete; 8 | _actionVec.setStorage(_actionVec_array); 9 | } 10 | 11 | ADActor::~ADActor() 12 | { 13 | } 14 | 15 | ADActor *ADActor::create(uint32_t showTime, bool autoDelete) 16 | { 17 | ADActor *actor = new ADActor(showTime, autoDelete); 18 | return actor; 19 | } 20 | 21 | ADActor *ADActor::create(uint32_t showTime, ADAction *action, bool autoDelete) 22 | { 23 | ADActor *actor = new ADActor(showTime, autoDelete); 24 | actor->addAction(action); 25 | return actor; 26 | } 27 | 28 | void ADActor::release() 29 | { 30 | for (int i = _actionVec.size() - 1; i >= 0; i--) 31 | { 32 | this->removeAction(i, true); 33 | } 34 | delete this; 35 | } 36 | 37 | void ADActor::addAction(ADAction *action) 38 | { 39 | if (action) 40 | { 41 | _actionVec.push_back(action); 42 | } 43 | } 44 | 45 | void ADActor::removeAction(ADAction *action, bool autoDelete) 46 | { 47 | for (int i = _actionVec.size() - 1; i >= 0; i--) 48 | { 49 | if (action == _actionVec[i]) 50 | { 51 | _actionVec.remove(i); 52 | if (autoDelete) 53 | { 54 | action->release(); 55 | } 56 | break; 57 | } 58 | } 59 | } 60 | 61 | void ADActor::removeAction(uint32_t index, bool autoDelete) 62 | { 63 | ADAction *action = _actionVec[index]; 64 | if (action) 65 | { 66 | _actionVec.remove(index); 67 | if (autoDelete) 68 | { 69 | action->release(); 70 | } 71 | } 72 | } 73 | 74 | bool ADActor::show(uint32_t dt, bool autoSwitch) 75 | { 76 | for (int i = _actionVec.size() - 1; i >= 0; i--) 77 | { 78 | ADAction *action = _actionVec[i]; 79 | if (action->actNow(dt)) 80 | { 81 | this->removeAction(i, autoSwitch); 82 | } 83 | } 84 | if (autoSwitch) 85 | { 86 | if (_showTime_c > dt) 87 | { 88 | _showTime_c -= dt; 89 | } 90 | else 91 | { 92 | _showTime_c = _showTime; // 产生些许时间误差 93 | return true; 94 | } 95 | } 96 | return false; 97 | } 98 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/ADActor.h: -------------------------------------------------------------------------------- 1 | #ifndef __ADACTOR_H__ 2 | #define __ADACTOR_H__ 3 | 4 | #include "ADConfig.h" 5 | #include "ADAction.h" 6 | #include "Vector.h" 7 | 8 | class ADActor 9 | { 10 | private: 11 | ADAction *_actionVec_array[3]; 12 | 13 | Vector _actionVec; 14 | 15 | uint32_t _showTime = 0; 16 | 17 | uint32_t _showTime_c = 0; 18 | 19 | bool _autoDelete; 20 | 21 | public: 22 | ADActor(uint32_t showTime , bool autoDelete = false); 23 | 24 | ~ADActor(); 25 | 26 | static ADActor *create(uint32_t showTime , bool autoDelete = false); 27 | 28 | static ADActor *create(uint32_t showTime, ADAction *action , bool autoDelete = false); 29 | 30 | void release(); 31 | 32 | void addAction(ADAction *action); 33 | 34 | void removeAction(ADAction *action, bool autoDelete = true); 35 | 36 | void removeAction(uint32_t index, bool autoDelete = true); 37 | 38 | bool show(uint32_t dt,bool autoSwitch); 39 | 40 | bool autoDelete(){return _autoDelete;} 41 | }; 42 | 43 | #endif // __ADACTOR_H__ -------------------------------------------------------------------------------- /SmartTriangle_Server/src/ADConfig.h: -------------------------------------------------------------------------------- 1 | #ifndef __ADCONFIG_H__ 2 | #define __ADCONFIG_H__ 3 | 4 | #define DEBUG 1 5 | 6 | #define ADLOG_V(n) Serial.println(#n + String(":") + String(n)) 7 | #define ADLOG_SV(s,n) Serial.println(s + String(" ") + #n + String(":") + String(n)) 8 | #define ADLOG_S(s) Serial.println(s) 9 | 10 | #include 11 | #include 12 | 13 | 14 | #endif // __ADCONFIG_H__ -------------------------------------------------------------------------------- /SmartTriangle_Server/src/ADDirector.cpp: -------------------------------------------------------------------------------- 1 | #include "ADDirector.h" 2 | 3 | ADDirector::ADDirector(/* args */) 4 | { 5 | _actorVec.setStorage(_actorVec_array); 6 | } 7 | 8 | ADDirector::~ADDirector() 9 | { 10 | } 11 | 12 | void ADDirector::startAction(uint32_t ct) 13 | { 14 | _lastMillis = ct; 15 | _invalid = false; 16 | } 17 | 18 | void ADDirector::stopAction() 19 | { 20 | _invalid = true; 21 | } 22 | 23 | void ADDirector::startAutoSwitch() 24 | { 25 | _autoSwitch = true; 26 | } 27 | 28 | void ADDirector::stopAutoSwitch() 29 | { 30 | _autoSwitch = false; 31 | } 32 | 33 | void ADDirector ::begin(bool autoSwitch) 34 | { 35 | _invalid = true; 36 | _autoSwitch = autoSwitch; 37 | } 38 | 39 | void ADDirector ::loop(uint32_t ct) 40 | { 41 | if (_lastMillis >= ct) 42 | return; 43 | 44 | uint32_t dt = ct - _lastMillis; 45 | 46 | _lastMillis = ct; 47 | 48 | if (_invalid) 49 | return; 50 | 51 | ADActor *actor = _actorVec[_autoSwitchPointer]; 52 | 53 | if (actor && actor->show(dt, _autoSwitch)) 54 | { 55 | if (actor->autoDelete()) 56 | { 57 | this->removeActor(actor); 58 | } 59 | _autoSwitchPointer++; 60 | if (_autoSwitchPointer >= _actorVec.size()) 61 | { 62 | _autoSwitchPointer = 0; 63 | } 64 | } 65 | 66 | } 67 | 68 | void ADDirector::addActor(ADActor *actor) 69 | { 70 | _actorVec.push_back(actor); 71 | } 72 | 73 | void ADDirector::removeActor(ADActor *actor, bool autoDelete) 74 | { 75 | for (uint32_t i = 0; i < _actorVec.size(); i++) 76 | { 77 | if (actor == _actorVec[i]) 78 | { 79 | _actorVec.remove(i); 80 | if (autoDelete) 81 | { 82 | actor->release(); 83 | } 84 | break; 85 | } 86 | } 87 | } 88 | 89 | void ADDirector::removeActor(uint32_t index, bool autoDelete) 90 | { 91 | ADActor *actor = _actorVec[index]; 92 | if (actor) 93 | { 94 | _actorVec.remove(index); 95 | if (autoDelete) 96 | { 97 | actor->release(); 98 | } 99 | } 100 | } 101 | 102 | void ADDirector::flush() 103 | { 104 | this->stopAction(); 105 | for (int i = _actorVec.size() - 1; i >= 0; i--) 106 | { 107 | this->removeActor(i, true); 108 | } 109 | } 110 | ADDirector Director; -------------------------------------------------------------------------------- /SmartTriangle_Server/src/ADDirector.h: -------------------------------------------------------------------------------- 1 | #ifndef __ADDIRECTOR_H__ 2 | #define __ADDIRECTOR_H__ 3 | 4 | #include "ADConfig.h" 5 | #include "ADActor.h" 6 | #include "Vector.h" 7 | 8 | class ADDirector 9 | { 10 | private: 11 | bool _invalid = false; 12 | 13 | bool _autoSwitch = false; 14 | 15 | uint16_t _autoSwitchPointer = 0; 16 | 17 | uint32_t _lastMillis = 0; 18 | 19 | ADActor *_actorVec_array[10]; 20 | 21 | Vector _actorVec; 22 | 23 | public: 24 | ADDirector(); 25 | 26 | ~ADDirector(); 27 | 28 | void begin(bool autoSwitch = true); 29 | 30 | void loop(uint32_t ct); 31 | 32 | void startAction(uint32_t ct); 33 | 34 | void stopAction(); 35 | 36 | void startAutoSwitch(); 37 | 38 | void stopAutoSwitch(); 39 | 40 | void addActor(ADActor *actor); 41 | 42 | void removeActor(ADActor *actor, bool autoDelete = true); 43 | 44 | void removeActor(uint32_t index, bool autoDelete = true); 45 | 46 | void flush(); 47 | }; 48 | 49 | extern ADDirector Director; 50 | 51 | #endif // __ADDIRECTOR_H__ -------------------------------------------------------------------------------- /SmartTriangle_Server/src/ADHueAction.cpp: -------------------------------------------------------------------------------- 1 | #include "ADHueAction.h" 2 | 3 | ADHueAction::ADHueAction(HueActionCallback func, 4 | uint8_t from, 5 | uint8_t to, 6 | uint32_t duration, 7 | uint32_t fps, 8 | bool autoDelete) : ADAction(NULL, 1000 / fps, duration / 1000.0 * fps, 0, autoDelete) 9 | { 10 | _callback = func; 11 | _from = from; 12 | _to = to; 13 | } 14 | 15 | ADHueAction::~ADHueAction() 16 | { 17 | } 18 | 19 | ADHueAction *ADHueAction::create(HueActionCallback func, 20 | uint8_t from, 21 | uint8_t to, 22 | uint32_t duration, 23 | uint32_t fps, 24 | bool autoDelete) 25 | { 26 | ADHueAction *action = new ADHueAction(func, from, to, duration, fps ,autoDelete); 27 | return action; 28 | } 29 | 30 | void ADHueAction::callback() 31 | { 32 | int32_t from = _from; 33 | int32_t to = _to; 34 | if (from > to) 35 | { 36 | to += 256; 37 | } 38 | uint8_t res = ((to - from) * _times_c / _times + from) % 256; 39 | _callback(res, this); 40 | } -------------------------------------------------------------------------------- /SmartTriangle_Server/src/ADHueAction.h: -------------------------------------------------------------------------------- 1 | #ifndef __AD_HUE_ACTION_H__ 2 | #define __AD_HUE_ACTION_H__ 3 | 4 | #include "ADAction.h" 5 | 6 | typedef void (*HueActionCallback)(uint32_t, void *action); 7 | 8 | class ADHueAction : public ADAction 9 | { 10 | private: 11 | uint8_t _from; 12 | 13 | uint8_t _to; 14 | 15 | HueActionCallback _callback; 16 | 17 | void callback(); 18 | 19 | public: 20 | ADHueAction(HueActionCallback func, 21 | uint8_t from, 22 | uint8_t to, 23 | uint32_t duration, 24 | uint32_t fpsfps = 30, 25 | bool autoDelete = true); 26 | 27 | virtual ~ADHueAction(); 28 | 29 | static ADHueAction *create(HueActionCallback func, 30 | uint8_t from, 31 | uint8_t to, 32 | uint32_t duration, 33 | uint32_t fpsfps = 30, 34 | bool autoDelete = true); 35 | }; 36 | 37 | #endif // __AD_HUE_ACTION_H__ -------------------------------------------------------------------------------- /SmartTriangle_Server/src/ArduiDispatch.h: -------------------------------------------------------------------------------- 1 | #ifndef __ARDUI_DISPATCH_H__ 2 | #define __ARDUI_DISPATCH_H__ 3 | 4 | #include "ADConfig.h" 5 | 6 | #include "ADDirector.h" 7 | #include "ADActor.h" 8 | #include "ADAction.h" 9 | 10 | 11 | 12 | #endif // __ARDUI_DISPATCH_H__ -------------------------------------------------------------------------------- /SmartTriangle_Server/src/HalfDuplexSerial.cpp: -------------------------------------------------------------------------------- 1 | #include "HalfDuplexSerial.h" 2 | #include 3 | 4 | HalfDuplexSerial::HalfDuplexSerial(int8_t pin) 5 | { 6 | m_transmitSeirial = new SoftwareSerial(-1, pin); 7 | m_receiveSerial = new SoftwareSerial(pin, -1); 8 | m_pin = pin; 9 | m_serialModeType = SMT_NONE; 10 | } 11 | 12 | HalfDuplexSerial::~HalfDuplexSerial() 13 | { 14 | delete m_transmitSeirial; 15 | delete m_receiveSerial; 16 | } 17 | 18 | void HalfDuplexSerial::begin(long speed) 19 | { 20 | m_transmitSeirial->begin(speed); 21 | m_receiveSerial->begin(speed); 22 | } 23 | 24 | void HalfDuplexSerial::end() 25 | { 26 | m_receiveSerial->end(); 27 | m_transmitSeirial->end(); 28 | m_serialModeType = SMT_NONE; 29 | } 30 | 31 | size_t HalfDuplexSerial::write(uint8_t byte) 32 | { 33 | if (m_serialModeType == SMT_TRANSMIT) 34 | { 35 | return m_transmitSeirial->write(byte); 36 | } 37 | else 38 | { 39 | return -1; 40 | } 41 | } 42 | 43 | int HalfDuplexSerial::read() 44 | { 45 | if (m_serialModeType == SMT_RECEIVE) 46 | { 47 | return m_receiveSerial->read(); 48 | } 49 | else 50 | { 51 | return -1; 52 | } 53 | } 54 | 55 | int HalfDuplexSerial::available() 56 | { 57 | if (m_serialModeType == SMT_RECEIVE) 58 | { 59 | return m_receiveSerial->available(); 60 | } 61 | else 62 | { 63 | return 0; 64 | } 65 | } 66 | 67 | void HalfDuplexSerial::setMode(SerialModeType smt) 68 | { 69 | switch (smt) 70 | { 71 | case SMT_TRANSMIT: 72 | { 73 | pinMode(m_pin, OUTPUT); 74 | #if defined(ESP8266) 75 | m_transmitSeirial->listen(); 76 | m_transmitSeirial->flush(); 77 | m_transmitSeirial->enableRx(false); 78 | m_transmitSeirial->enableTx(true); 79 | m_receiveSerial->enableRx(false); 80 | m_receiveSerial->enableTx(false); 81 | #else 82 | m_receiveSerial->end(); 83 | m_transmitSeirial->listen(); 84 | #endif 85 | m_serialModeType = SMT_TRANSMIT; 86 | } 87 | break; 88 | case SMT_RECEIVE: 89 | { 90 | pinMode(m_pin, INPUT_PULLUP); 91 | #if defined(ESP8266) 92 | m_receiveSerial->listen(); 93 | m_receiveSerial->flush(); 94 | m_transmitSeirial->enableRx(false); 95 | m_transmitSeirial->enableTx(false); 96 | m_receiveSerial->enableRx(true); 97 | m_receiveSerial->enableTx(false); 98 | #else 99 | m_transmitSeirial->end(); 100 | m_receiveSerial->listen(); 101 | #endif 102 | m_serialModeType = SMT_RECEIVE; 103 | } 104 | break; 105 | default: 106 | break; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/HalfDuplexSerial.h: -------------------------------------------------------------------------------- 1 | #ifndef HalfDuplexSerial_h 2 | #define HalfDuplexSerial_h 3 | 4 | #include 5 | 6 | enum SerialModeType 7 | { 8 | SMT_NONE = 0, 9 | SMT_TRANSMIT = 1, 10 | SMT_RECEIVE, 11 | }; 12 | 13 | class HalfDuplexSerial 14 | { 15 | private: 16 | SoftwareSerial *m_transmitSeirial; 17 | SoftwareSerial *m_receiveSerial; 18 | SerialModeType m_serialModeType; 19 | int m_pin; 20 | public: 21 | HalfDuplexSerial(int8_t pin); 22 | ~HalfDuplexSerial(); 23 | void begin(long speed); 24 | void end(); 25 | size_t write(uint8_t byte); 26 | int read(); 27 | int available(); 28 | 29 | void setMode(SerialModeType smt); 30 | SerialModeType serialModeType(){return m_serialModeType;} 31 | 32 | }; 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/MemoryFree.cpp: -------------------------------------------------------------------------------- 1 | #if (ARDUINO >= 100) 2 | #include 3 | #else 4 | #include 5 | #endif 6 | 7 | extern unsigned int __heap_start; 8 | extern void *__brkval; 9 | 10 | /* 11 | * The free list structure as maintained by the 12 | * avr-libc memory allocation routines. 13 | */ 14 | struct __freelist 15 | { 16 | size_t sz; 17 | struct __freelist *nx; 18 | }; 19 | 20 | /* The head of the free list structure */ 21 | extern struct __freelist *__flp; 22 | 23 | #include "MemoryFree.h" 24 | 25 | /* Calculates the size of the free list */ 26 | int freeListSize() 27 | { 28 | struct __freelist* current; 29 | int total = 0; 30 | for (current = __flp; current; current = current->nx) 31 | { 32 | total += 2; /* Add two bytes for the memory block's header */ 33 | total += (int) current->sz; 34 | } 35 | 36 | return total; 37 | } 38 | 39 | int freeMemory() 40 | { 41 | int free_memory; 42 | if ((int)__brkval == 0) 43 | { 44 | free_memory = ((int)&free_memory) - ((int)&__heap_start); 45 | } 46 | else 47 | { 48 | free_memory = ((int)&free_memory) - ((int)__brkval); 49 | free_memory += freeListSize(); 50 | } 51 | return free_memory; 52 | } 53 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/MemoryFree.h: -------------------------------------------------------------------------------- 1 | // MemoryFree library based on code posted here: 2 | // http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1213583720/15 3 | // Extended by Matthew Murdoch to include walking of the free list. 4 | 5 | #ifndef MEMORY_FREE_H 6 | #define MEMORY_FREE_H 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | int freeMemory(); 13 | 14 | #ifdef __cplusplus 15 | } 16 | #endif 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/SmartTopology.cpp: -------------------------------------------------------------------------------- 1 | #include "SmartTopology.h" 2 | #include 3 | #include 4 | 5 | STNodeDef *stNodeStack_storage[64]; 6 | Vector stNodeStack; 7 | 8 | static uint8_t idCreator = 1; 9 | 10 | SmartTopology::SmartTopology() 11 | { 12 | idCreator = 1; 13 | m_rootNode = NULL; 14 | stNodeStack.setStorage(stNodeStack_storage); 15 | } 16 | 17 | SmartTopology::~SmartTopology() 18 | { 19 | if (m_rootNode) 20 | { 21 | delete m_rootNode; 22 | m_rootNode = NULL; 23 | } 24 | } 25 | 26 | uint8_t SmartTopology::creadId() 27 | { 28 | return idCreator++; 29 | } 30 | 31 | STNodeDef *SmartTopology::creatNode() 32 | { 33 | STNodeDef *node = new STNodeDef(); 34 | memset(node, 0, sizeof(STNodeDef)); 35 | node->nodeId = this->creadId(); 36 | stNodeStack.push_back(node); 37 | return node; 38 | } 39 | 40 | uint8_t SmartTopology::creatRootNode() 41 | { 42 | m_rootNode = this->creatNode(); 43 | return m_rootNode->nodeId; 44 | } 45 | 46 | uint8_t SmartTopology::nodeCount() 47 | { 48 | return stNodeStack.size(); 49 | } 50 | 51 | STNodeDef *SmartTopology::rootNode() 52 | { 53 | return m_rootNode; 54 | } 55 | 56 | // //深度优先遍历 57 | // void SmartTopology::nextNode(STNodeDef* node) 58 | // { 59 | // int stackSize = stNodeStack.size(); 60 | // if(stackSize<=0) 61 | // { 62 | // m_currentNode = m_rootNode; 63 | // stNodeStack.push_back(m_currentNode); 64 | // return; 65 | // } 66 | // STNodeDef* topNode = stNodeStack.at(stackSize - 1); 67 | // if (topNode == node) 68 | // { 69 | // if (node->leftChild) 70 | // { 71 | // m_currentNode = node->leftChild; 72 | // stNodeStack.push_back(m_currentNode); 73 | // } else if (node->rightChild) 74 | // { 75 | // m_currentNode = node->rightChild; 76 | // stNodeStack.push_back(m_currentNode); 77 | // } else 78 | // { 79 | // stNodeStack.pop_back(); 80 | // this->nextNode(node); 81 | // } 82 | // } else if (topNode->leftChild == node) 83 | // { 84 | // if (topNode->rightChild) 85 | // { 86 | // m_currentNode = topNode->rightChild; 87 | // stNodeStack.push_back(m_currentNode); 88 | // }else 89 | // { 90 | // stNodeStack.pop_back(); 91 | // this->nextNode(topNode); 92 | // } 93 | // }else if (topNode->rightChild == node) 94 | // { 95 | // stNodeStack.pop_back(); 96 | // this->nextNode(node); 97 | // } 98 | // } 99 | 100 | void SmartTopology::flush() 101 | { 102 | idCreator = 1; 103 | this->deleteTree(m_rootNode); 104 | } 105 | 106 | void SmartTopology::deleteTree(STNodeDef *node) 107 | { 108 | if (node) 109 | { 110 | this->deleteTree(node->leftChild); 111 | this->deleteTree(node->rightChild); 112 | delete node; 113 | } 114 | } 115 | uint8_t *randomCache = NULL; 116 | uint8_t randomLength = 0; 117 | 118 | void SmartTopology::fullRandomInit(uint8_t n) 119 | { 120 | if (randomCache) 121 | { 122 | delete randomCache; 123 | randomCache = NULL; 124 | } 125 | if (n > 0) 126 | { 127 | randomCache = (uint8_t *)malloc(n); 128 | randomLength = n; 129 | for(int i = 0;i 5 | #include 6 | 7 | enum STNodeType 8 | { 9 | STNT_WAITING_CHECK = 0, 10 | STNT_CHECKING = 1, 11 | STNT_HAS_NO_CHILD, 12 | STNT_HAS_CHILD 13 | }; 14 | 15 | struct STNodeDef 16 | { 17 | uint8_t nodeId; 18 | STNodeType leftChildType; 19 | STNodeType rightChildType; 20 | STNodeDef *leftChild; 21 | STNodeDef *rightChild; 22 | }; 23 | 24 | class SmartTopology 25 | { 26 | private: 27 | STNodeDef *m_rootNode; 28 | uint8_t creadId(); 29 | void deleteTree(STNodeDef* node); 30 | public: 31 | SmartTopology(); 32 | ~SmartTopology(); 33 | STNodeDef *creatNode(); 34 | STNodeDef *rootNode(); 35 | // void nextNode(STNodeDef* node); 36 | uint8_t creatRootNode(); 37 | uint8_t nodeCount(); 38 | void flush(); 39 | void fullRandomInit(uint8_t n); 40 | 41 | uint8_t fullRandom(); 42 | }; 43 | 44 | extern SmartTopology ST; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/SmartTriangle_Server.ino: -------------------------------------------------------------------------------- 1 | #include "HalfDuplexSerial.h" 2 | #include "TriangleProtocol.h" 3 | #include "SmartTopology.h" 4 | #include 5 | #include "ArduiDispatch.h" 6 | #include "ADHueAction.h" 7 | 8 | #if defined ARDUINO 9 | #include "MemoryFree.h" 10 | #endif 11 | 12 | #define PROTOCOL_VER "0.1.0" 13 | 14 | #define DEBUG 1 15 | 16 | #define PROTOCOL_CALLBACK(x) void pId_callback_##x(byte *payload, unsigned int length, bool isTimeout) 17 | 18 | #define PORTOCOL_REGISTER(x) \ 19 | { \ 20 | if (isTimeout || m_nodeId == payload[0] || payload[0] == 255) \ 21 | { \ 22 | pId_callback_##x(payload + 1, length - 1, isTimeout); \ 23 | } \ 24 | } \ 25 | break 26 | 27 | #if defined ESP8266 28 | #define HDSERIAL_PIN D6 29 | #define HDSERIAL_PIN_BAKE D7 30 | #define SLECTED_PIN D5 31 | #elif defined ARDUINO 32 | #define HDSERIAL_PIN 6 33 | #define HDSERIAL_PIN_BAKE 7 34 | #define SLECTED_PIN 5 35 | #endif 36 | 37 | enum STLightType 38 | { 39 | STLT_WAITING_CHECK = 0, 40 | STLT_CHECKING = 1, 41 | STLT_SHOW_EFFECT 42 | }; 43 | 44 | STNodeDef *seekNodeQueue_storage[64]; 45 | 46 | Vector seekNodeQueue; 47 | 48 | STNodeDef *currentNode; 49 | 50 | STLightType stLightType; 51 | 52 | HalfDuplexSerial hdSerial(HDSERIAL_PIN); 53 | 54 | uint8_t m_nodeId = 0; 55 | 56 | void waitingReceive() 57 | { 58 | hdSerial.setMode(SMT_RECEIVE); 59 | TPT.tpBeginReceive(); 60 | } 61 | 62 | void waitingTransmit() 63 | { 64 | hdSerial.setMode(SMT_TRANSMIT); 65 | } 66 | 67 | void startSelect() 68 | { 69 | pinMode(SLECTED_PIN, OUTPUT); 70 | digitalWrite(SLECTED_PIN, HIGH); 71 | } 72 | 73 | void stopSelect() 74 | { 75 | pinMode(SLECTED_PIN, INPUT); 76 | } 77 | 78 | void seekRootNode() 79 | { 80 | //寻找根节点 81 | stLightType = STLT_CHECKING; 82 | startSelect(); 83 | TPT.tpBegin(51, 255).tpTransmit(true); 84 | waitingReceive(); 85 | } 86 | 87 | void uniformColorEffect(uint32_t c, void *effect) 88 | { 89 | TPT.tpBegin(102, 255).tpUint16(1900).tpByte(random(0, 256)).tpTransmit(); 90 | } 91 | 92 | void singleRandomEffect(uint32_t n, uint32_t c, void *effect) 93 | { 94 | // TPT.tpBegin(102,c).tpUint16(1000).tpByte(random(0, 256)).tpTransmit(); 95 | } 96 | 97 | void singleLedEffect(uint32_t c, void *effect) 98 | { 99 | TPT.tpBegin(102, 255).tpUint16(2800).tpColor(random(0, 256), 255, 255).tpTransmit(); 100 | } 101 | 102 | void allShowEffect(uint32_t n, void *effect) 103 | { 104 | TPT.tpBegin(102, 255).tpUint16(3000).tpColor(random(0, 256), 255, 255).tpTransmit(); 105 | } 106 | 107 | void singleShowEffect(uint32_t n, void *effect) 108 | { 109 | if(n>25)return; 110 | uint32_t count = ST.nodeCount(); 111 | if(n%count == 1) 112 | { 113 | ST.fullRandomInit(count); 114 | } 115 | uint8_t c = ST.fullRandom(); 116 | ADLOG_V(count); 117 | ADLOG_V(n); 118 | ADLOG_V(c); 119 | TPT.tpBegin(102, c).tpUint16(random(1500,2800)).tpColor(random(0, 256), 255, 255).tpTransmit(); 120 | } 121 | 122 | void flowerShowEffect(unsigned int n, void *effect) 123 | { 124 | uint32_t count = ST.nodeCount(); 125 | TPT.tpBegin(104, 255).tpUint16(3000).tpColor(random(0, 256), 255, 255).tpColor(random(0, 256), 255, 255).tpByte(50).tpTransmit(); 126 | } 127 | 128 | void effectSetup() 129 | { 130 | uint32_t count = ST.nodeCount(); 131 | 132 | ADAction *allShowAction = ADAction::create(allShowEffect, 3000, 3, 0, false); 133 | ADActor *allShowActor = ADActor::create(9000, allShowAction); 134 | Director.addActor(allShowActor); 135 | 136 | ADAction *singleShowAction = ADAction::create(singleShowEffect, 1000, 30, 0, false); 137 | ADActor *singleShowActor = ADActor::create(30000, singleShowAction); 138 | Director.addActor(singleShowActor); 139 | 140 | ADAction *flowerShowAction = ADAction::create(flowerShowEffect, 3000, 3, 0, false); 141 | ADActor *flowerShowActor = ADActor::create(9000, flowerShowAction); 142 | Director.addActor(flowerShowActor); 143 | 144 | // effectCreate(5000*count,count,5000,randomEffect); 145 | // effectCreate(10000,2,5000,uniformColorEffect); 146 | // effectCreate(10000,2,5000,singleLedEffect); 147 | } 148 | 149 | void seekNodeByQueue() 150 | { 151 | if (seekNodeQueue.size() <= 0) 152 | { 153 | stLightType = STLT_SHOW_EFFECT; 154 | effectSetup(); 155 | ADLOG_SV("Topo SUCCESSED!!!", millis()); 156 | TPT.tpBegin(200, 255).tpTransmit(); 157 | delay(500); 158 | Director.startAction(millis()); 159 | return; 160 | } 161 | STNodeDef *node = seekNodeQueue[0]; 162 | if (node->leftChildType == STNT_WAITING_CHECK) 163 | { 164 | node->leftChildType = STNT_CHECKING; 165 | TPT.tpBegin(21, node->nodeId).tpTransmit(); 166 | delay(100); 167 | TPT.tpBegin(52, 255).tpTransmit(true); 168 | waitingReceive(); 169 | currentNode = node; 170 | } 171 | else if (node->rightChildType == STNT_WAITING_CHECK) 172 | { 173 | node->rightChildType = STNT_CHECKING; 174 | TPT.tpBegin(23, node->nodeId).tpTransmit(); 175 | delay(100); 176 | TPT.tpBegin(52, 255).tpTransmit(true); 177 | waitingReceive(); 178 | currentNode = node; 179 | } 180 | } 181 | 182 | void seekLeafNode() 183 | { 184 | seekNodeQueue.push_back(ST.rootNode()); 185 | seekNodeByQueue(); 186 | } 187 | 188 | PROTOCOL_CALLBACK(51) 189 | { 190 | stopSelect(); 191 | Serial.println(TPT.parseString(payload)); 192 | if (isTimeout) 193 | { 194 | //无根节点,拓扑结束 195 | Serial.println(F("Topo Failed!!!")); 196 | } 197 | else 198 | { 199 | //有节点 200 | uint8_t nodeId = ST.creatRootNode(); 201 | Serial.println("ROOT NODE ID:" + String(nodeId)); 202 | TPT.tpBegin(2, 255).tpByte(nodeId).tpTransmit(); 203 | TPT.tpBegin(200, nodeId).tpTransmit(); 204 | #if DEBUG == 1 205 | delay(600); 206 | #endif 207 | seekLeafNode(); 208 | } 209 | } 210 | 211 | PROTOCOL_CALLBACK(52) 212 | { 213 | if (isTimeout) 214 | { 215 | //无子节点 216 | if (currentNode->leftChildType == STNT_CHECKING) 217 | { 218 | TPT.tpBegin(22, currentNode->nodeId).tpTransmit(); 219 | currentNode->leftChildType = STNT_HAS_NO_CHILD; 220 | } 221 | else if (currentNode->rightChildType == STNT_CHECKING) 222 | { 223 | TPT.tpBegin(24, currentNode->nodeId).tpTransmit(); 224 | currentNode->rightChildType = STNT_HAS_NO_CHILD; 225 | seekNodeQueue.remove(0); 226 | } 227 | seekNodeByQueue(); 228 | } 229 | else 230 | { 231 | //有子节点 232 | STNodeDef *node = ST.creatNode(); 233 | seekNodeQueue.push_back(node); 234 | Serial.println("CHILD NODE ID:" + String(node->nodeId)); 235 | if (currentNode->leftChildType == STNT_CHECKING) 236 | { 237 | currentNode->leftChildType = STNT_HAS_CHILD; 238 | currentNode->leftChild = node; 239 | TPT.tpBegin(22, currentNode->nodeId).tpTransmit(); 240 | TPT.tpBegin(2, 255).tpByte(node->nodeId).tpTransmit(); 241 | TPT.tpBegin(200, node->nodeId).tpTransmit(); 242 | #if DEBUG == 1 243 | delay(600); 244 | #endif 245 | } 246 | else if (currentNode->rightChildType == STNT_CHECKING) 247 | { 248 | currentNode->rightChildType = STNT_HAS_CHILD; 249 | currentNode->rightChild = node; 250 | TPT.tpBegin(24, currentNode->nodeId).tpTransmit(); 251 | TPT.tpBegin(2, 255).tpByte(node->nodeId).tpTransmit(); 252 | TPT.tpBegin(200, node->nodeId).tpTransmit(); 253 | #if DEBUG == 1 254 | delay(600); 255 | #endif 256 | seekNodeQueue.remove(0); 257 | } 258 | else 259 | { 260 | seekNodeQueue.pop_back(); 261 | delete node; 262 | } 263 | seekNodeByQueue(); 264 | } 265 | } 266 | 267 | void tpCallback(byte pId, byte *payload, unsigned int length, bool isTimeout) 268 | { 269 | waitingTransmit(); 270 | #if defined ESP8266 271 | Serial.println("<<==Rec. " + String(pId) + (isTimeout ? " T " : " F ") + String(ESP.getMaxFreeBlockSize())); 272 | #elif defined ARDUINO 273 | Serial.println("<<==Rec. " + String(pId) + (isTimeout ? " T " : " F ") + String(freeMemory())); 274 | #endif 275 | switch (pId) 276 | { 277 | case 51: 278 | PORTOCOL_REGISTER(51); 279 | case 52: 280 | PORTOCOL_REGISTER(52); 281 | } 282 | Serial.println("==>>"); 283 | } 284 | 285 | 286 | void transmitCallback(byte *ptBuffer, unsigned int ptLength) 287 | { 288 | 289 | #if defined ESP8266 290 | Serial.println("<<==Sent " + String(ptBuffer[3]) + " Length=" + String(ptLength) + " " + String(ESP.getMaxFreeBlockSize())); 291 | #elif defined ARDUINO 292 | Serial.println("<<==Sent " + String(ptBuffer[3]) + " Length=" + String(ptLength) + " " + String(freeMemory())); 293 | #endif 294 | for (unsigned int i = 0; i < ptLength; i++) 295 | { 296 | uint8_t c = ptBuffer[i]; 297 | hdSerial.write(c); 298 | } 299 | Serial.println("==>>"); 300 | } 301 | 302 | void setup() 303 | { 304 | 305 | seekNodeQueue.setStorage(seekNodeQueue_storage); 306 | stLightType = STLT_WAITING_CHECK; 307 | Serial.begin(115200); 308 | 309 | hdSerial.begin(57600); 310 | hdSerial.setMode(SMT_TRANSMIT); 311 | pinMode(HDSERIAL_PIN_BAKE, INPUT_PULLUP); 312 | TPT.callbackRegister(tpCallback, transmitCallback); 313 | 314 | pinMode(A0, INPUT); 315 | randomSeed(analogRead(A0)); 316 | delay(2000);//等待2秒,让所有客户端启动 317 | Serial.println("STARTING..."); 318 | /* 319 | 0b00000001 配置信息 320 | 右1位 客户端调试模式 321 | 322 | */ 323 | TPT.tpBegin(1, 255).tpByte(200).tpByte(0b00000001).tpTransmit(); //所有节点初始化 324 | delay(50); 325 | seekRootNode(); 326 | Director.begin(true); 327 | } 328 | 329 | void loop() 330 | { 331 | TPT.protocolLoop(); 332 | if (hdSerial.serialModeType() == SMT_RECEIVE) 333 | { 334 | while (hdSerial.available()) 335 | { 336 | byte c = hdSerial.read(); 337 | TPT.tpPushData(c).tpParse(); 338 | } 339 | } 340 | if (stLightType == STLT_SHOW_EFFECT) 341 | { 342 | Director.loop(millis()); 343 | } 344 | } 345 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/TriangleProtocol.cpp: -------------------------------------------------------------------------------- 1 | #include "TriangleProtocol.h" 2 | 3 | static uint8_t m_ptBuffer[MAX_PROTOCOL_BUFFER]; 4 | 5 | static uint16_t m_ptLength; 6 | 7 | TriangleProtocol::TriangleProtocol() 8 | { 9 | this->parse_callback = NULL; 10 | this->trans_callback = NULL; 11 | m_protoCallbackVec.setStorage(m_protoCallbackVec_array); 12 | } 13 | 14 | TriangleProtocol::~TriangleProtocol() 15 | { 16 | } 17 | 18 | void TriangleProtocol::callbackRegister(TP_PARSE_CALLBACK, TP_TRANSMIT_CALLBACK) 19 | { 20 | this->parse_callback = parse_callback; 21 | this->trans_callback = trans_callback; 22 | } 23 | 24 | void TriangleProtocol::InvertUint16(uint16_t *dBuf, uint16_t *srcBuf) 25 | { 26 | uint16_t tmp[4] = {0}; 27 | for (uint8_t i = 0; i < 16; i++) 28 | { 29 | if (srcBuf[0] & (1 << i)) 30 | tmp[0] |= 1 << (15 - i); 31 | } 32 | dBuf[0] = tmp[0]; 33 | } 34 | 35 | uint16_t TriangleProtocol::CRC16_MODBUS(uint8_t *data, uint16_t datalen) 36 | { 37 | uint16_t wCRCin = 0xFFFF; 38 | uint16_t wCPoly = 0x8005; 39 | InvertUint16(&wCPoly, &wCPoly); 40 | while (datalen--) 41 | { 42 | wCRCin ^= *(data++); 43 | for (uint8_t i = 0; i < 8; i++) 44 | { 45 | if (wCRCin & 0x01) 46 | wCRCin = (wCRCin >> 1) ^ wCPoly; 47 | else 48 | wCRCin = wCRCin >> 1; 49 | } 50 | } 51 | uint16_t wCRCinTemp = wCRCin; 52 | return (wCRCin >> 8 & 0x00FF) | (wCRCinTemp << 8 & 0xFF00); 53 | } 54 | 55 | void TriangleProtocol::waitProtocolTimeout(uint8_t pId, uint32_t timeout) 56 | { 57 | ProtocolCallbackDef *protocolCallbackDef = new ProtocolCallbackDef(); 58 | protocolCallbackDef->pId = pId; 59 | protocolCallbackDef->recordTime = millis(); 60 | protocolCallbackDef->timeout = timeout; 61 | m_protoCallbackVec.push_back(protocolCallbackDef); 62 | } 63 | 64 | void TriangleProtocol::protocolTimeoutRemove(uint8_t pId) 65 | { 66 | for (int i = m_protoCallbackVec.size() - 1; i >= 0; i--) 67 | { 68 | ProtocolCallbackDef *protocolCallbackDef = m_protoCallbackVec[i]; 69 | if (protocolCallbackDef->pId == pId) 70 | { 71 | m_protoCallbackVec.remove(i); 72 | delete protocolCallbackDef; 73 | protocolCallbackDef = NULL; 74 | } 75 | } 76 | } 77 | 78 | void TriangleProtocol::protocolLoop() 79 | { 80 | for (int i = m_protoCallbackVec.size() - 1; i >= 0; i--) 81 | { 82 | ProtocolCallbackDef *protocolCallbackDef = m_protoCallbackVec[i]; 83 | if (millis() - protocolCallbackDef->recordTime > protocolCallbackDef->timeout) 84 | { 85 | this->parse_callback(protocolCallbackDef->pId, NULL, 0, true); 86 | m_protoCallbackVec.remove(i); 87 | delete protocolCallbackDef; 88 | protocolCallbackDef = NULL; 89 | } 90 | } 91 | } 92 | 93 | TriangleProtocol &TriangleProtocol::tpBegin(byte pid, byte nid) 94 | { 95 | m_ptBuffer[0] = 0; 96 | m_ptBuffer[1] = 0; 97 | m_ptBuffer[2] = 0; 98 | m_ptLength = 3; 99 | m_ptBuffer[m_ptLength++] = pid; 100 | m_ptBuffer[m_ptLength++] = nid; 101 | return TPT; 102 | } 103 | 104 | TriangleProtocol &TriangleProtocol::tpByte(byte b) 105 | { 106 | m_ptBuffer[m_ptLength++] = b; 107 | return TPT; 108 | } 109 | 110 | TriangleProtocol &TriangleProtocol::tpUint16(uint16_t i) 111 | { 112 | m_ptBuffer[m_ptLength++] = (i >> 8) & 0xFF; 113 | m_ptBuffer[m_ptLength++] = (i >> 0) & 0xFF; 114 | return TPT; 115 | } 116 | 117 | TriangleProtocol &TriangleProtocol::tpUint32(uint32_t i) 118 | { 119 | m_ptBuffer[m_ptLength++] = (i >> 24) & 0xFF; 120 | m_ptBuffer[m_ptLength++] = (i >> 16) & 0xFF; 121 | m_ptBuffer[m_ptLength++] = (i >> 8) & 0xFF; 122 | m_ptBuffer[m_ptLength++] = (i >> 0) & 0xFF; 123 | return TPT; 124 | } 125 | 126 | TriangleProtocol &TriangleProtocol::tpColor(byte r, byte g, byte b) 127 | { 128 | m_ptBuffer[m_ptLength++] = r; 129 | m_ptBuffer[m_ptLength++] = g; 130 | m_ptBuffer[m_ptLength++] = b; 131 | return TPT; 132 | } 133 | 134 | TriangleProtocol &TriangleProtocol::tpStr(const String &str) 135 | { 136 | int length = str.length(); 137 | m_ptBuffer[m_ptLength++] = length; 138 | for (int i = 0; i < length; i++) 139 | { 140 | m_ptBuffer[m_ptLength++] = str[i]; 141 | } 142 | return TPT; 143 | } 144 | 145 | void TriangleProtocol::tpTransmit(bool checkTimeout) 146 | { 147 | m_ptBuffer[1] = ((m_ptLength + 2) >> 8) & 0xFF; 148 | m_ptBuffer[2] = ((m_ptLength + 2) >> 0) & 0xFF; 149 | 150 | uint16_t crc = this->CRC16_MODBUS(m_ptBuffer, m_ptLength); 151 | this->tpUint16(crc); 152 | 153 | this->trans_callback(m_ptBuffer, m_ptLength); 154 | if (checkTimeout) 155 | { 156 | this->waitProtocolTimeout(m_ptBuffer[3]); 157 | } 158 | } 159 | 160 | TriangleProtocol &TriangleProtocol::tpBeginReceive() 161 | { 162 | m_ptLength = 0; 163 | memset(m_ptBuffer, 0, sizeof(uint8_t) * MAX_PROTOCOL_BUFFER); 164 | return TPT; 165 | } 166 | 167 | TriangleProtocol &TriangleProtocol::tpPushData(uint8_t d) 168 | { 169 | if (m_ptLength == 0 && d != 0) //开头过滤 170 | { 171 | return TPT; 172 | } 173 | m_ptBuffer[m_ptLength++] = d; 174 | return TPT; 175 | } 176 | 177 | void TriangleProtocol::tpParse() 178 | { 179 | if (m_ptLength < 3) 180 | return; 181 | uint16_t pLength = uint16_t(m_ptBuffer[1] << 8) + uint16_t(m_ptBuffer[2]); 182 | if (pLength > MAX_PROTOCOL_BUFFER) 183 | { 184 | TPT.tpBeginReceive();//协议缓存重置 185 | return; 186 | } 187 | if (pLength < 6) 188 | return; //无有效载荷,协议至少六位 189 | if (pLength > m_ptLength) 190 | return; //未完全接收数据,等待 191 | if (pLength <= m_ptLength) 192 | { 193 | if (this->CRC16_MODBUS(m_ptBuffer, pLength) == 0) //crc校验 194 | { 195 | uint8_t pId = m_ptBuffer[3]; 196 | this->protocolTimeoutRemove(pId); 197 | this->parse_callback(pId, m_ptBuffer + 4, pLength - 4, false); 198 | } else 199 | { 200 | for (int i = 0; i < pLength; i++) 201 | { 202 | Serial.println("m_ptBuffer[" + String(i) + "]=" + String(m_ptBuffer[i])); 203 | } 204 | Serial.println("parse failed"); 205 | } 206 | } 207 | TPT.tpBeginReceive();//协议缓存重置 208 | } 209 | 210 | String TriangleProtocol::parseString(uint8_t *payload) const 211 | { 212 | uint8_t stringLength = payload[0]; 213 | char *buff = (char *)malloc(stringLength + 1); 214 | memset(buff, 0, stringLength + 1); 215 | for (int i = 0; i < stringLength; i++) 216 | { 217 | buff[i] = payload[i + 1]; 218 | } 219 | String res = String(buff); 220 | delete buff; 221 | return res; 222 | } 223 | 224 | 225 | 226 | TriangleProtocol TPT; 227 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/TriangleProtocol.h: -------------------------------------------------------------------------------- 1 | #ifndef TriangleProtocol_h 2 | #define TriangleProtocol_h 3 | 4 | #include 5 | #include 6 | #include "Vector.h" 7 | 8 | struct ProtocolCallbackDef 9 | { 10 | uint8_t pId; 11 | uint32_t recordTime; 12 | uint32_t timeout; 13 | }; 14 | 15 | #define TP_PARSE_CALLBACK void (*parse_callback)(byte, uint8_t *, unsigned int, bool) 16 | 17 | #define TP_TRANSMIT_CALLBACK void (*trans_callback)(uint8_t *, unsigned int) 18 | 19 | #define DEFAULT_PROTOCO_TIMEOUT 5 20 | 21 | #define MAX_PROTOCOL_BUFFER 256 22 | 23 | class TriangleProtocol 24 | { 25 | private: 26 | TP_PARSE_CALLBACK; 27 | 28 | TP_TRANSMIT_CALLBACK; 29 | 30 | ProtocolCallbackDef *m_protoCallbackVec_array[10]; 31 | 32 | Vector m_protoCallbackVec; 33 | 34 | void protocolTimeoutRemove(uint8_t pId); 35 | 36 | void InvertUint16(uint16_t *dBuf, uint16_t *srcBuf); 37 | 38 | uint16_t CRC16_MODBUS(uint8_t *data, uint16_t datalen); 39 | 40 | public: 41 | TriangleProtocol(); 42 | 43 | ~TriangleProtocol(); 44 | 45 | void callbackRegister(TP_PARSE_CALLBACK, TP_TRANSMIT_CALLBACK); 46 | 47 | void waitProtocolTimeout(uint8_t pId, uint32_t timeout = DEFAULT_PROTOCO_TIMEOUT); 48 | 49 | void protocolLoop(); 50 | /* 51 | 协议标准 52 | [0]:固定0为开头 53 | [1][2]:含开头、自身、有效负载、校验位总长度 54 | [3]:协议ID 55 | [4]:奇光板ID , 255 为广播ID 56 | [5]-[n]:协议有效负载 57 | [n+1][n+2]:CRC校验码 58 | */ 59 | TriangleProtocol &tpBegin(byte pid,byte nid); 60 | 61 | TriangleProtocol &tpByte(byte b); 62 | 63 | TriangleProtocol &tpUint16(uint16_t i); 64 | 65 | TriangleProtocol &tpUint32(uint32_t i); 66 | 67 | TriangleProtocol &tpColor(byte r, byte g, byte b); 68 | 69 | TriangleProtocol &tpStr(const String &str); 70 | 71 | void tpTransmit(bool checkTimeout = false); 72 | 73 | TriangleProtocol &tpBeginReceive(); 74 | 75 | TriangleProtocol &tpPushData(uint8_t d); 76 | 77 | void tpParse(); 78 | 79 | String parseString(uint8_t *payload) const; 80 | 81 | }; 82 | 83 | extern TriangleProtocol TPT; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/Vector.cpp: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Vector.cpp 3 | // 4 | // 5 | // Authors: 6 | // Peter Polidoro peterpolidoro@gmail.com 7 | // ---------------------------------------------------------------------------- 8 | #include "Vector.h" 9 | -------------------------------------------------------------------------------- /SmartTriangle_Server/src/Vector.h: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Vector.h 3 | // 4 | // 5 | // Authors: 6 | // Peter Polidoro peterpolidoro@gmail.com 7 | // ---------------------------------------------------------------------------- 8 | #ifndef VECTOR_H 9 | #define VECTOR_H 10 | #ifdef ARDUINO 11 | #include 12 | #else 13 | #include 14 | #endif 15 | 16 | 17 | template 18 | class Vector 19 | { 20 | public: 21 | Vector(); 22 | template 23 | Vector(T (&values)[MAX_SIZE], 24 | size_t size=0); 25 | template 26 | void setStorage(T (&values)[MAX_SIZE], 27 | size_t size=0); 28 | void setStorage(T * values, 29 | size_t max_size, 30 | size_t size); 31 | const T & operator[](size_t index) const; 32 | T & operator[](size_t index); 33 | const T & at(size_t index) const; 34 | T & at(size_t index); 35 | T & front(); 36 | T & back(); 37 | void clear(); 38 | template 39 | void fill(const U & value); 40 | template 42 | void fill(const U (&values)[N]); 43 | template 44 | void fill(const Vector & values); 45 | template 46 | void assign(size_t n, 47 | const U & value); 48 | template 50 | void assign(size_t n, 51 | const U (&values)[N]); 52 | template 53 | void assign(size_t n, 54 | const Vector & values); 55 | void push_back(const T & value); 56 | void pop_back(); 57 | void remove(size_t index); 58 | size_t size() const; 59 | size_t max_size() const; 60 | bool empty() const; 61 | bool full() const; 62 | const T * data() const; 63 | T * data(); 64 | 65 | private: 66 | T * values_; 67 | size_t max_size_; 68 | size_t size_; 69 | }; 70 | 71 | template 72 | inline Print & operator <<(Print & stream, 73 | const Vector & vector) 74 | { 75 | stream.print("["); 76 | for (size_t i=0; i 13 | #endif 14 | 15 | template 16 | Vector::Vector() 17 | { 18 | values_ = NULL; 19 | max_size_ = 0; 20 | size_ = 0; 21 | } 22 | 23 | template 24 | template 25 | Vector::Vector(T (&values)[MAX_SIZE], 26 | size_t size) 27 | { 28 | setStorage(values,size); 29 | } 30 | 31 | template 32 | template 33 | void Vector::setStorage(T (&values)[MAX_SIZE], 34 | size_t size) 35 | { 36 | values_ = values; 37 | max_size_ = MAX_SIZE; 38 | size_ = size; 39 | } 40 | 41 | template 42 | void Vector::setStorage(T * values, 43 | size_t max_size, 44 | size_t size) 45 | { 46 | values_ = values; 47 | max_size_ = max_size; 48 | size_ = size; 49 | } 50 | 51 | template 52 | const T & Vector::operator[](size_t index) const 53 | { 54 | return values_[index]; 55 | } 56 | 57 | template 58 | T & Vector::operator[](size_t index) 59 | { 60 | return values_[index]; 61 | } 62 | 63 | template 64 | T & Vector::at(size_t index) 65 | { 66 | return values_[index]; 67 | } 68 | 69 | template 70 | const T & Vector::at(size_t index) const 71 | { 72 | return values_[index]; 73 | } 74 | 75 | template 76 | T & Vector::front() 77 | { 78 | return values_[0]; 79 | } 80 | 81 | template 82 | T & Vector::back() 83 | { 84 | return values_[size_-1]; 85 | } 86 | 87 | template 88 | void Vector::clear() 89 | { 90 | size_ = 0; 91 | } 92 | 93 | template 94 | template 95 | void Vector::fill(const U & value) 96 | { 97 | assign(max_size_,value); 98 | } 99 | 100 | template 101 | template 103 | void Vector::fill(const U (&values)[N]) 104 | { 105 | assign(N,values); 106 | } 107 | 108 | template 109 | template 110 | void Vector::fill(const Vector & values) 111 | { 112 | assign(values.size(),values); 113 | } 114 | 115 | template 116 | template 117 | void Vector::assign(size_t n, 118 | const U & value) 119 | { 120 | size_t assign_size = ((n < max_size_) ? n : max_size_); 121 | size_ = assign_size; 122 | for (size_t i=0; i 129 | template 131 | void Vector::assign(size_t n, 132 | const U (&values)[N]) 133 | { 134 | size_t n_smallest = ((n < N) ? n : N); 135 | size_t assign_size = ((n_smallest < max_size_) ? n_smallest : max_size_); 136 | size_ = assign_size; 137 | for (size_t i=0; i 144 | template 145 | void Vector::assign(size_t n, 146 | const Vector & values) 147 | { 148 | size_t n_smallest = ((n < values.size()) ? n : values.size()); 149 | size_t assign_size = ((n_smallest < max_size_) ? n_smallest : max_size_); 150 | size_ = assign_size; 151 | for (size_t i=0; i 158 | void Vector::push_back(const T & value) 159 | { 160 | if ((values_ != NULL) && (size_ < max_size_)) 161 | { 162 | values_[size_++] = value; 163 | } 164 | } 165 | 166 | template 167 | void Vector::pop_back() 168 | { 169 | if (size_ > 0) 170 | { 171 | --size_; 172 | } 173 | } 174 | 175 | template 176 | void Vector::remove(size_t index) 177 | { 178 | if (size_ > index) 179 | { 180 | for (size_t i=index; i<(size_-1); ++i) 181 | { 182 | values_[i] = values_[i+1]; 183 | } 184 | --size_; 185 | } 186 | } 187 | 188 | template 189 | size_t Vector::size() const 190 | { 191 | return size_; 192 | } 193 | 194 | template 195 | size_t Vector::max_size() const 196 | { 197 | return max_size_; 198 | } 199 | 200 | template 201 | bool Vector::empty() const 202 | { 203 | return size_ == 0; 204 | } 205 | 206 | template 207 | bool Vector::full() const 208 | { 209 | return size_ == max_size_; 210 | } 211 | 212 | template 213 | T * Vector::data() 214 | { 215 | return values_; 216 | } 217 | 218 | template 219 | const T * Vector::data() const 220 | { 221 | return values_; 222 | } 223 | 224 | #endif 225 | --------------------------------------------------------------------------------