commit 43f2dc25225dd55719145286b9a867103d65aa88 Author: Rohan Sircar Date: Fri Oct 18 11:00:55 2019 +0530 First commit diff --git a/.gitignore b/.gitignore new file mode 100755 index 0000000..2de98ab --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.pio +.pioenvs +.piolibdeps +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json diff --git a/.travis.yml b/.travis.yml new file mode 100755 index 0000000..7c486f1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,67 @@ +# Continuous Integration (CI) is the practice, in software +# engineering, of merging all developer working copies with a shared mainline +# several times a day < https://docs.platformio.org/page/ci/index.html > +# +# Documentation: +# +# * Travis CI Embedded Builds with PlatformIO +# < https://docs.travis-ci.com/user/integration/platformio/ > +# +# * PlatformIO integration with Travis CI +# < https://docs.platformio.org/page/ci/travis.html > +# +# * User Guide for `platformio ci` command +# < https://docs.platformio.org/page/userguide/cmd_ci.html > +# +# +# Please choose one of the following templates (proposed below) and uncomment +# it (remove "# " before each line) or use own configuration according to the +# Travis CI documentation (see above). +# + + +# +# Template #1: General project. Test it using existing `platformio.ini`. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio run + + +# +# Template #2: The project is intended to be used as a library with examples. +# + +# language: python +# python: +# - "2.7" +# +# sudo: false +# cache: +# directories: +# - "~/.platformio" +# +# env: +# - PLATFORMIO_CI_SRC=path/to/test/file.c +# - PLATFORMIO_CI_SRC=examples/file.ino +# - PLATFORMIO_CI_SRC=path/to/test/directory +# +# install: +# - pip install -U platformio +# - platformio update +# +# script: +# - platformio ci --lib="." --board=ID_1 --board=ID_2 --board=ID_N diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100755 index 0000000..8281e64 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100755 index 0000000..4af0465 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "terminal.integrated.env.linux": { + "PATH": "/home/rohan/.platformio/penv/bin:/home/rohan/.platformio/penv:/home/rohan/.cargo/bin:/home/rohan/bin:/home/rohan/.local/bin:/home/rohan/.nvm/versions/node/v12.10.0/bin:/home/rohan/miniconda3/condabin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/home/rohan/.cargo/bin", + "PLATFORMIO_CALLER": "vscode" + } +} \ No newline at end of file diff --git a/include/README b/include/README new file mode 100755 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100755 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100755 index 0000000..d3984ad --- /dev/null +++ b/platformio.ini @@ -0,0 +1,16 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nanoatmega328] +platform = atmelavr +; lib_extra_dirs = ~/Documents/Arduino/libraries +board = nanoatmega328 +framework = arduino +monitor_speed = 115200 \ No newline at end of file diff --git a/src/.vscode/c_cpp_properties.json b/src/.vscode/c_cpp_properties.json new file mode 100755 index 0000000..bed303b --- /dev/null +++ b/src/.vscode/c_cpp_properties.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": ["__AVR_ATmega328p__"], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "clang-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/src/sketch_oct28a2.cpp b/src/sketch_oct28a2.cpp new file mode 100755 index 0000000..cdbb315 --- /dev/null +++ b/src/sketch_oct28a2.cpp @@ -0,0 +1,473 @@ +#include +#include +#include "RTClib.h" +#include +#include +#include +#include +#define RELAY_ON 0 +#define RELAY_OFF 1 +// #define ESP_TO_ARDUINO_PIN 2 +SoftwareSerial s(5, 6); //RX,TX +RTC_DS1307 rtc; + +struct ballast +{ + int id; + int shour; + int smin; + uint32_t fadePeriod; + int ehour; + int emin; + int stage; + int brightness; + int pin; + unsigned long fadeStartMillis; + int relayPin; +}; +struct ballast ballast1, ballast2, ballast3; +// struct ballast ballasts[3]; + +void setupBallast(ballast *b); +void setupBallast(ballast *b, JsonObject &root, int i); +void doBallast(ballast *b); +void updateBallast(ballast *b, JsonObject &root); +void manualMode(ballast *b); +int getFreeRam(); +const size_t bufferSize = JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(2) + 3 * JSON_OBJECT_SIZE(5) + 180; + +unsigned long currentMillis; +unsigned long loopMillis; +unsigned long loopPeriod = 1000; +unsigned long data_send_millis; +unsigned long data_send_period = 2000; +static bool manualFlag; + +// char roul[] = "is a fag"; + +// char data[60]; + +void setup() +{ + // put your setup code here, to run once: + Serial.begin(115200); + //rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); + //Tell me esp that arduino has turned on + s.begin(9600); + // analogWrite(13, 255); + digitalWrite(13, 1); + + // strcpy(roul,""); + + //while (!Serial) continue; + // DateTime now = rtc.now(); + //StaticJsonBuffer<400> jsonBuffer1; + DynamicJsonBuffer jsonBuffer(bufferSize); + // StaticJsonBuffer<100> jsonBuffer; + JsonObject &root = jsonBuffer.parseObject(s); + // root.printTo(data); + // while(root == JsonObject::invalid()) + // { + // Serial.println(F("Error code1"); + // } + setupBallast(&ballast1, root, 1); + setupBallast(&ballast2, root, 2); + setupBallast(&ballast3, root, 3); + root.prettyPrintTo(Serial); + Serial.println(F("Settings initialized via json")); + if (root["manual"] == F("True")) + { + manualFlag = true; + } + + loopMillis = millis(); + data_send_millis = millis(); +} + +// // static bool newData = false; + +void loop() +{ + + while (!rtc.begin()) + { + Serial.println(F("Couldn't find RTC")); + //while (1); + delay(100); + } + + while (!rtc.isrunning()) + { + Serial.println(F("RTC is NOT running!")); + } + + if (s.available() > 0) + { + // delay(100); + DynamicJsonBuffer jsonBuffer(bufferSize); + // const size_t bufsize = JSON_ARRAY_SIZE(3) + JSON_OBJECT_SIZE(2) + 3*JSON_OBJECT_SIZE(5); + // StaticJsonBuffer jsonBuffer; + // StaticJsonBuffer jsonBuffer; + JsonObject &root = jsonBuffer.parseObject(s); + // if(root.succes()) + Serial << F("Received JSON") << endl; + root.prettyPrintTo(Serial); + // // data = ""; + // root.printTo(data); + // // newData = true; + // } + + // if (newData) + // { + // Serial.println(F("Parsing data")); + // DynamicJsonBuffer jsonBuffer(bufferSize); + // JsonObject &root = jsonBuffer.parseObject(data); + // root.prettyPrintTo(Serial); + updateBallast(&ballast1, root); + updateBallast(&ballast2, root); + updateBallast(&ballast3, root); + if (root["manual"] == "True") + { + manualFlag = true; + Serial.println(F("Manual set to true")); + } + else if (root["manual"] == "False") + { + manualFlag = false; + Serial.println(F("Manual set to false")); + } + // newData = false; + } + + currentMillis = millis(); + if (currentMillis - loopMillis >= loopPeriod) + { + + if (manualFlag == true) + { + Serial.println(F("Manual Mode")); + manualMode(&ballast1); + manualMode(&ballast2); + manualMode(&ballast3); + } + else + { + doBallast(&ballast1); + doBallast(&ballast2); + doBallast(&ballast3); + } + + Serial << F("Free RAM: ") << getFreeRam() << endl; + loopMillis = currentMillis; + } + + currentMillis = millis(); + if (currentMillis - data_send_millis >= data_send_period) + { + StaticJsonBuffer<50> jsonBuffer; + JsonObject& root = jsonBuffer.createObject(); + JsonArray& lcd_data = root.createNestedArray("lcdData"); + char time_buffer[10]; + DateTime now = rtc.now(); + sprintf(time_buffer,"%02d:%02d",now.hour(),now.minute()); + // root["hello"] = ("world"); + lcd_data.add("90%%"); + lcd_data.add(time_buffer); + root.printTo(s); + root.printTo(Serial); + data_send_millis = millis(); + Serial << endl; + } + delay(100); +} + +void setupBallast(ballast *b) +{ + b->id = 1; + b->shour = 14; + b->smin = 0; + b->fadePeriod = 60 * 60000; + //b->stage = 0; + b->brightness = 0; + b->pin = 11; +} +void setupBallast(ballast *b, JsonObject &root, int i) +{ + pinMode(b->pin, OUTPUT); + pinMode(b->relayPin, OUTPUT); + JsonArray &settings = root["settings"]; + JsonObject &settings0 = settings[0]; + JsonObject &settings1 = settings[1]; + JsonObject &settings2 = settings[2]; + if (i == 1) + { + b->id = 1; + b->shour = settings0["shour"]; + unsigned long fP = settings0["fadePeriod"]; + b->fadePeriod = fP * 60000; + b->smin = settings0["smin"]; + b->ehour = settings0["ehour"]; + b->emin = settings0["emin"]; + b->brightness = 0; + b->pin = 11; + b->relayPin = 2; + b->fadeStartMillis = millis(); + } + else if (i == 2) + { + b->id = 2; + b->shour = settings1["shour"]; + unsigned long fP = settings1["fadePeriod"]; + b->fadePeriod = fP * 60000; + b->smin = settings1["smin"]; + b->ehour = settings1["ehour"]; + b->emin = settings1["emin"]; + b->brightness = 0; + b->pin = 10; + b->relayPin = 4; + b->fadeStartMillis = millis(); + } + else if (i == 3) + { + b->id = 3; + b->shour = settings2["shour"]; + unsigned long fP = settings2["fadePeriod"]; + b->fadePeriod = fP * 60000; + b->smin = settings2["smin"]; + b->ehour = settings2["ehour"]; + b->emin = settings2["emin"]; + b->brightness = 0; + b->pin = 9; + b->relayPin = 7; + b->fadeStartMillis = millis(); + } +} + +void updateBallast(ballast *b, JsonObject &root) +{ + JsonArray &settings = root["settings"]; + JsonObject &settings0 = settings[0]; + JsonObject &settings1 = settings[1]; + JsonObject &settings2 = settings[2]; + if (b->id == 1) + { + b->shour = settings0["shour"]; + unsigned long fP = settings0["fadePeriod"]; + b->fadePeriod = fP * 60000; + b->smin = settings0["smin"]; + b->ehour = settings0["ehour"]; + b->emin = settings0["emin"]; + } + if (b->id == 2) + { + b->shour = settings1["shour"]; + unsigned long fP = settings1["fadePeriod"]; + b->fadePeriod = fP * 60000; + b->smin = settings1["smin"]; + b->ehour = settings1["ehour"]; + b->emin = settings1["emin"]; + } + if (b->id == 3) + { + b->shour = settings2["shour"]; + unsigned long fP = settings2["fadePeriod"]; + b->fadePeriod = fP * 60000; + b->smin = settings2["smin"]; + b->ehour = settings2["ehour"]; + b->emin = settings2["emin"]; + } +} +int getStage(ballast *b) +{ + DateTime now = rtc.now(); + int hr = now.hour(); + int mn = now.minute(); + Serial.print(F("Current hour is: ")); + Serial.println(hr); + Serial.print(F("Current minute is: ")); + Serial.println(mn); + + if (hr < b->shour) + return 0; + if ((float)hr >= (float)b->shour && hr < (b->shour + (float)(b->fadePeriod) / 3600000 + (float)(b->smin) / 60)) + { + if (hr == b->shour) + { + if (mn < b->smin) + return 0; + else + return 1; + } + return 1; + } + if ((float)hr >= (b->shour + (float)(b->fadePeriod) / 3600000 + (float)(b->smin) / 60) && hr < b->ehour) + { + return 2; + } + if ((float)hr >= (b->ehour + (float)(b->fadePeriod) / 3600000)) + { + if (hr == (b->ehour + (float)(b->fadePeriod) / 3600000)) + { + if (mn < b->emin) + return 3; + else + return 4; + } + else + { + // Serial.println((b->ehour + (float)(b->fadePeriod)/3600000)); + return 4; + } + } + if ((float)hr >= (float)b->ehour && hr < (b->ehour + (float)(b->fadePeriod) / 3600000 + (float)(b->emin) / 60)) + { + if (hr == b->ehour) + { + if (mn < b->emin) + return 2; + else + return 3; + } + else + return 3; + } + return 1; +} +void doBallast(ballast *b) +{ + if (b->id == 1) + { + Serial.println(F("-------------------Ballast1-------------------")); + } + if (b->id == 2) + { + Serial.println(F("-------------------Ballast2-------------------")); + } + if (b->id == 3) + { + Serial.println(F("-------------------Ballast3-------------------")); + } + // DateTime now = rtc.now(); + // int hr = now.hour(); + Serial.print(F("Start hour is: ")); + Serial.println(b->shour); + Serial.print(F("Start min is: ")); + Serial.println(b->smin); + Serial.print(F("Fade Period is: ")); + Serial.print((b->fadePeriod) / 60000); + Serial.println(F(" minutes")); + Serial.print(F("End hour is: ")); + Serial.println(b->ehour); + Serial.print(F("End min is: ")); + Serial.println(b->emin); + Serial.print(F("Brightness: ")); + Serial.println(b->brightness); + int stage = getStage(b); + Serial.print(F("Stage: ")); + Serial.println(stage); + if (stage == 0) + { + b->stage = 0; + b->brightness = 0; + analogWrite(b->pin, b->brightness); + Serial.print(F("Stage = ")); + Serial.println(stage); + Serial.print(F("brightness: ")); + Serial.println(b->brightness); + analogWrite(b->relayPin, RELAY_OFF); + } + else if (stage == 1) + { + if (currentMillis - b->fadeStartMillis >= (b->fadePeriod / 255)) + { + //Serial.println(b->fadePeriod/255); + Serial.print(F("Stage = ")); + Serial.println(stage); + digitalWrite(b->relayPin, RELAY_ON); + if (b->brightness <= 254) + { + analogWrite(b->pin, b->brightness++); + } + //d = b->fadePeriod/255; + Serial.print(F("Delay is: ")); + //t = d / 1000; + Serial.print(b->fadePeriod / 255 / 1000); + Serial.println(F(" seconds")); + Serial.print(F("Brightness: ")); + Serial.println(b->brightness); + //if(b->brightness == 255) + //b->brightness = 0; + //delay(d); + b->fadeStartMillis = currentMillis; + } + } + else if (stage == 2) + { + Serial.print(F("Stage = ")); + Serial.println(stage); + b->brightness = 255; + analogWrite(b->pin, b->brightness); + } + else if (stage == 3) + { + if (currentMillis - b->fadeStartMillis >= (b->fadePeriod / 255)) + { + //Serial.println(b->fadePeriod/255); + Serial.print(F("Stage = ")); + Serial.println(stage); + //if(b->brightness == 0 && (float)hr < (b->ehour + (float)(b->fadePeriod)/3600000)) + //b->brightness = 255; + if (b->brightness > 0) + { + + analogWrite(b->pin, --b->brightness); + } + //d = b->fadePeriod/255; + Serial.print(F("Delay is: ")); + //t = d / 1000; + Serial.print(b->fadePeriod / 255 / 1000); + Serial.println(F(" seconds")); + Serial.print(F("Brightness: ")); + Serial.println(b->brightness); + //if(b->brightness == 255) + //b->brightness = 0; + //delay(d); + b->fadeStartMillis = currentMillis; + } + } + else if (stage == 4) + { + Serial.print(F("Stage = ")); + Serial.println(stage); + analogWrite(b->pin, 0); + analogWrite(b->relayPin, RELAY_OFF); + } + Serial.println(F("----------------------------------------------")); +} + +void manualMode(ballast *b) +{ + /*DateTime now = rtc.now(); + byte hr = now.hour(); + byte mn = now.minute(); + + if(hr <= b-> shour) + { + analogWrite(" + }*/ + analogWrite(b->pin, 255); + analogWrite(b->relayPin, RELAY_ON); +} + +int getFreeRam() +{ + extern int __heap_start, *__brkval; + int v; + + v = (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval); + + Serial.print("Free RAM = "); + Serial.println(v, DEC); + + return v; +} \ No newline at end of file diff --git a/test/README b/test/README new file mode 100755 index 0000000..df5066e --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html