commit 40be50fa06286be0a4b302f5919e53d8074a53ca Author: Softonik Date: Sun Nov 20 17:43:24 2022 +0300 Лампа плавного включения с датчиками движения diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..85e1862 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +_config.priv.h +build diff --git a/ble.cpp b/ble.cpp new file mode 100644 index 0000000..bbb2f5e --- /dev/null +++ b/ble.cpp @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include "config.h" + +// https://www.instructables.com/ESP32-Bluetooth-Low-Energy/ + +void setup_BLE(); + +BLEServer *server; +bool deviceConnected = false; +#define SERVICE_UUID "ab0828b1-198e-4351-b779-901fa0e0371e" +#define CHARACTERISTIC_UUID_RX "4ac8a682-9736-4e5d-932b-e9b31405049c" +#define CHARACTERISTIC_UUID_TX "0972EF8C-7613-4075-AD52-756F33D4DA91" + +class CharacteristicCallbacks : public BLECharacteristicCallbacks { + void onWrite(BLECharacteristic *characteristic) { + std::string rxValue = characteristic->getValue(); + if (rxValue.length() <= 0) { + return; + } + + if (rxValue.find("wifi") != -1 || rxValue.find("w") != -1) { + triggerWifi(); + } else { + action(); + } + } +}; + +class ServerCallbacks : public BLEServerCallbacks { + void onConnect(BLEServer *pServer) { + deviceConnected = true; + BLEDevice::startAdvertising(); + }; + + void onDisconnect(BLEServer *pServer) { + deviceConnected = false; + BLEDevice::startAdvertising(); + } +}; + +void setup_BLE() { + BLEDevice::init(BLE_NAME); + server = BLEDevice::createServer(); + server->setCallbacks(new ServerCallbacks()); + BLEService *service = server->createService(SERVICE_UUID); + + BLECharacteristic *characteristicTX = service->createCharacteristic( + CHARACTERISTIC_UUID_TX, + BLECharacteristic::PROPERTY_NOTIFY); + characteristicTX->addDescriptor(new BLE2902()); + + BLECharacteristic *characteristic = service->createCharacteristic( + CHARACTERISTIC_UUID_RX, + BLECharacteristic::PROPERTY_WRITE); + characteristic->setCallbacks(new CharacteristicCallbacks()); + + service->start(); + BLEDevice::startAdvertising(); +} \ No newline at end of file diff --git a/config.h b/config.h new file mode 100644 index 0000000..2521cff --- /dev/null +++ b/config.h @@ -0,0 +1,20 @@ +#include "_config.priv.h" + +#define UPDATES_ENABLED 1 +#define DEBUG 0 + +// Prod +#define DVIZH_VERH_PIN 4 +#define DVIZH_NIZ_PIN 16 +#define DVIZH_TRIGGER RISING + +// TTGO for test +// #define DVIZH_VERH_PIN 35 +// #define DVIZH_NIZ_PIN 0 +// #define DVIZH_TRIGGER FALLING + +#define SVET_ONOFF_PIN 18 +#define SVET_YARK_PIN 19 + +void triggerWifi(); +void action(); diff --git a/dvizh.cpp b/dvizh.cpp new file mode 100644 index 0000000..62bca60 --- /dev/null +++ b/dvizh.cpp @@ -0,0 +1,50 @@ +#include +#include "config.h" +#include "main.go.h" + +static TaskHandle_t taskInterruptsReceiverHandle = NULL; + +void IRAM_ATTR dvizhHandler() { + BaseType_t xHigherPriorityTaskWoken; + + /* xHigherPriorityTaskWoken must be initialised to pdFALSE. + If calling vTaskNotifyGiveFromISR() unblocks the handling + task, and the priority of the handling task is higher than + the priority of the currently running task, then + xHigherPriorityTaskWoken will be automatically set to pdTRUE. */ + xHigherPriorityTaskWoken = pdFALSE; + + /* Unblock the handling task so the task can perform + any processing necessitated by the interrupt. xHandlingTask + is the task's handle, which was obtained when the task was + created. vTaskNotifyGiveFromISR() also increments + the receiving task's notification value. */ + vTaskNotifyGiveFromISR(taskInterruptsReceiverHandle, &xHigherPriorityTaskWoken); + + /* Force a context switch if xHigherPriorityTaskWoken is now + set to pdTRUE. The macro used to do this is dependent on + the port and may be called portEND_SWITCHING_ISR. */ + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +} + +void TaskInterruptsReceiver(void*) { + TaskSveta(); +} + +void setup_dvizh() { + pinMode(DVIZH_VERH_PIN, INPUT); + pinMode(DVIZH_NIZ_PIN, INPUT); + pinMode(SVET_ONOFF_PIN, OUTPUT); + pinMode(SVET_YARK_PIN, OUTPUT); + + initSvet(); + + xTaskCreate(TaskInterruptsReceiver, "taskInterruptsReceiver", 4096, NULL, ESP_TASKD_EVENT_PRIO - 1, &taskInterruptsReceiverHandle); + attachInterrupt(DVIZH_VERH_PIN, dvizhHandler, DVIZH_TRIGGER); + attachInterrupt(DVIZH_NIZ_PIN, dvizhHandler, DVIZH_TRIGGER); +} + +void action() { + if (DEBUG) + Serial.println("Action!"); +} \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..9a2081a --- /dev/null +++ b/go.mod @@ -0,0 +1,28 @@ +module my/app + +go 1.19 + +require ( + github.com/cucumber/godog v0.12.5 + github.com/magefile/mage v1.11.0 + github.com/onsi/gomega v1.19.0 + my/go-controller v0.0.0 +) + +require ( + github.com/cucumber/gherkin-go/v19 v19.0.3 // indirect + github.com/cucumber/messages-go/v16 v16.0.1 // indirect + github.com/gofrs/uuid v4.2.0+incompatible // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-memdb v1.3.2 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect + golang.org/x/text v0.3.7 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) + +replace github.com/cucumber/godog => /gopath/src/my/godog + +replace my/go-controller => /gopath/src/my/go-controller diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..d967968 --- /dev/null +++ b/go.sum @@ -0,0 +1,71 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cucumber/gherkin-go/v19 v19.0.3 h1:mMSKu1077ffLbTJULUfM5HPokgeBcIGboyeNUof1MdE= +github.com/cucumber/gherkin-go/v19 v19.0.3/go.mod h1:jY/NP6jUtRSArQQJ5h1FXOUgk5fZK24qtE7vKi776Vw= +github.com/cucumber/messages-go/v16 v16.0.0/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g= +github.com/cucumber/messages-go/v16 v16.0.1 h1:fvkpwsLgnIm0qugftrw2YwNlio+ABe2Iu94Ap8GMYIY= +github.com/cucumber/messages-go/v16 v16.0.1/go.mod h1:EJcyR5Mm5ZuDsKJnT2N9KRnBK30BGjtYotDKpwQ0v6g= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.2.0+incompatible h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.3.2 h1:RBKHOsnSszpU6vxq80LzC2BaQjuuvoyaQbkLTf7V7g8= +github.com/hashicorp/go-memdb v1.3.2/go.mod h1:Mluclgwib3R93Hk5fxEfiRhB+6Dar64wWh71LpNSe3g= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magefile/mage v1.11.0 h1:C/55Ywp9BpgVVclD3lRnSYCwXTYxmSppIgLeDYlNuls= +github.com/magefile/mage v1.11.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= +github.com/onsi/ginkgo/v2 v2.1.3 h1:e/3Cwtogj0HA+25nMP1jCMDIf8RtRYbGwGGuBIFztkc= +github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lestnica_dvizh.ino b/lestnica_dvizh.ino new file mode 100644 index 0000000..02af58e --- /dev/null +++ b/lestnica_dvizh.ino @@ -0,0 +1,31 @@ +// Partition Scheme: Minimal SPIFFS +#include "config.h" + +void setup_dvizh(); + +void setup_BLE(); +void handleWifi(); +extern bool wifiEnabled; + +SET_LOOP_TASK_STACK_SIZE(16 * 1024); + +void setup() { + setup_dvizh(); + if (DEBUG) + Serial.begin(115200); +#if UPDATES_ENABLED + setup_BLE(); +#endif +} + +void loop() { +#if UPDATES_ENABLED + handleWifi(); +#endif + + if (!wifiEnabled) { + delay(60000); + } else { + delay(1000); + } +} \ No newline at end of file diff --git a/main.go.h b/main.go.h new file mode 100644 index 0000000..ee503c4 --- /dev/null +++ b/main.go.h @@ -0,0 +1,34 @@ +void initSvet(); +void DvizhEst(int start); +void DvizhaNet(); +void PlavnoVklyuchit(int start); +void PlavnoVyklyuchit(); +void Vklyuchit(); +void Vyklyuchit(); +void TaskSveta(); + + +const unsigned long VREMYA_SVETA = 20000; TickType_t loopBlockTime = pdMS_TO_TICKS(1000); TickType_t vklYarkBlockTime = pdMS_TO_TICKS(10); TickType_t vyklYarkBlockTime = pdMS_TO_TICKS(50); bool vkl; unsigned long kogdaVyklyuchit; void initSvet() { + vkl=false; kogdaVyklyuchit=0; Vyklyuchit(); +} +void DvizhEst(int start) { + kogdaVyklyuchit=millis()+VREMYA_SVETA; if (!vkl) { vkl=true; if (DEBUG) { Serial.println("Vkl svet"); } PlavnoVklyuchit(start); } +} +void DvizhaNet() { + if (kogdaVyklyuchit>millis()) { return; } if (vkl) { vkl=false; if (DEBUG) { Serial.println("Vykl"); } PlavnoVyklyuchit(); } +} +void PlavnoVklyuchit(int start) { + digitalWrite(SVET_ONOFF_PIN,1); int i; for(i=start; i>=0; i--) {analogWrite(SVET_YARK_PIN,i); if (DEBUG) { Serial.println(i); } delay(5);} Vklyuchit(); +} +void PlavnoVyklyuchit() { + int v; int i; for(i=0; i<=255; i++) {analogWrite(SVET_YARK_PIN,i); if (DEBUG) { Serial.println(i); } v=ulTaskNotifyTake(0,vyklYarkBlockTime); if (v>0) { DvizhEst(i); return; }} Vyklyuchit(); +} +void Vklyuchit() { + digitalWrite(SVET_YARK_PIN,0); digitalWrite(SVET_ONOFF_PIN,1); +} +void Vyklyuchit() { + digitalWrite(SVET_YARK_PIN,1); digitalWrite(SVET_ONOFF_PIN,0); +} +void TaskSveta() { + int v; while(1) {v=ulTaskNotifyTake(0,loopBlockTime); if (v>0) { DvizhEst(255); } else { DvizhaNet(); }} +} diff --git a/pkg/app/features/app.feature b/pkg/app/features/app.feature new file mode 100644 index 0000000..89c6ca3 --- /dev/null +++ b/pkg/app/features/app.feature @@ -0,0 +1,3 @@ +# language: ru + +Функциональность: Лампа с датчиком движения diff --git a/pkg/app/init_test.go b/pkg/app/init_test.go new file mode 100644 index 0000000..5985915 --- /dev/null +++ b/pkg/app/init_test.go @@ -0,0 +1,50 @@ +package app + +import ( + "context" + "os" + "testing" + + . "my/app/pkg/testlib" + + "github.com/cucumber/godog" + "github.com/cucumber/godog/colors" + + . "github.com/onsi/gomega" +) + +func InitializeScenario(ctx *godog.ScenarioContext) { + + // ----------------------- + ctx.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) { + beforeScenario() + return ctx, nil + }) + ctx.After(func(ctx context.Context, sc *godog.Scenario, err error) (context.Context, error) { + afterScenario() + return ctx, nil + }) + InitializeGomegaForGodog(ctx) + _ = Ω +} + +func InitializeSuite(tsc *godog.TestSuiteContext) { + tsc.BeforeSuite(beforeSuite) + tsc.AfterSuite(afterSuite) +} + +func TestMain(m *testing.M) { + var opts = godog.Options{ + Output: colors.Colored(os.Stdout), + Strict: true, + StopOnFailure: true, + } + + godog.BindCommandLineFlags("godog.", &opts) + status := godog.TestSuite{ + Name: "app", + TestSuiteInitializer: InitializeSuite, + ScenarioInitializer: InitializeScenario, + Options: &opts, + }.Run() +} diff --git a/pkg/app/main.go b/pkg/app/main.go new file mode 100644 index 0000000..0b8c5b8 --- /dev/null +++ b/pkg/app/main.go @@ -0,0 +1,113 @@ +package app + +import ( + "my/go-controller/analog" + "my/go-controller/digital" + "my/go-controller/serial" + "my/go-controller/task" + "my/go-controller/timer" +) + +const VREMYA_SVETA uint32 = 20000 + +var loopBlockTime task.TickType = task.MS_TO_TICKS(1000) +var vklYarkBlockTime task.TickType = task.MS_TO_TICKS(10) +var vyklYarkBlockTime task.TickType = task.MS_TO_TICKS(50) + +var vkl bool +var kogdaVyklyuchit uint32 + +func initSvet() { + vkl = false + kogdaVyklyuchit = 0 + + Vyklyuchit() +} + +func DvizhEst(start int) { + kogdaVyklyuchit = timer.Millis() + VREMYA_SVETA + + if !vkl { + vkl = true + if DEBUG { + serial.Println("Vkl svet") + } + PlavnoVklyuchit(start) + } +} +func DvizhaNet() { + if kogdaVyklyuchit > timer.Millis() { + return + } + + if vkl { + vkl = false + if DEBUG { + serial.Println("Vykl") + } + PlavnoVyklyuchit() + } +} + +func PlavnoVklyuchit(start int) { + digital.Write(SVET_ONOFF_PIN, 1) + + var i int + for i = start; i >= 0; i-- { + analog.Write(SVET_YARK_PIN, i) + if DEBUG { + serial.Println(i) + } + timer.Delay(5) + } + + Vklyuchit() +} +func PlavnoVyklyuchit() { + var v int + var i int + for i = 0; i <= 255; i++ { + analog.Write(SVET_YARK_PIN, i) + if DEBUG { + serial.Println(i) + } + + v = task.TaskNotifyTake(0, vyklYarkBlockTime) + if v > 0 { + DvizhEst(i) + return + } + } + Vyklyuchit() +} + +func Vklyuchit() { + digital.Write(SVET_YARK_PIN, 0) // логика яркости инвертирована + digital.Write(SVET_ONOFF_PIN, 1) +} +func Vyklyuchit() { + digital.Write(SVET_YARK_PIN, 1) // логика яркости инвертирована + digital.Write(SVET_ONOFF_PIN, 0) +} + +func TaskSveta() { + var v int + + for { + /* Block to wait for a notification. Here the RTOS + task notification is being used as a counting semaphore. + The task's notification value is incremented each time + the ISR calls vTaskNotifyGiveFromISR(), and decremented + each time the RTOS task calls ulTaskNotifyTake() - so in + effect holds a count of the number of outstanding interrupts. + The first parameter is set to pdFALSE, so the notification + value is only decremented and not cleared to zero, and one + deferred interrupt event is processed at a time. */ + v = task.TaskNotifyTake(0, loopBlockTime) + if v > 0 { + DvizhEst(255) + } else { + DvizhaNet() + } + } +} diff --git a/pkg/app/main_test.go b/pkg/app/main_test.go new file mode 100644 index 0000000..74f6317 --- /dev/null +++ b/pkg/app/main_test.go @@ -0,0 +1,25 @@ +package app + +type testData struct { +} + +var ( + t *testData +) + +func resetTestData() { + t = &testData{} +} + +func beforeSuite() { +} +func afterSuite() { +} + +func beforeScenario() { + resetTestData() +} +func afterScenario() { +} + +// ----------------------- diff --git a/pkg/app/variables.go b/pkg/app/variables.go new file mode 100644 index 0000000..fef42e3 --- /dev/null +++ b/pkg/app/variables.go @@ -0,0 +1,6 @@ +package app + +const DEBUG = false + +const SVET_ONOFF_PIN = 0 +const SVET_YARK_PIN = 0 diff --git a/pkg/testlib/testlib.go b/pkg/testlib/testlib.go new file mode 100644 index 0000000..799daf9 --- /dev/null +++ b/pkg/testlib/testlib.go @@ -0,0 +1,48 @@ +package testlib + +import ( + "context" + "fmt" + "time" + + "github.com/cucumber/godog" + . "github.com/onsi/gomega" +) + +var Be = Equal + +func NoErr(err error) { + ExpectWithOffset(1, err).NotTo(HaveOccurred()) +} + +var Ok = NoErr + +func Yes(b bool) { + ExpectWithOffset(1, b).To(BeTrue()) +} +func YesText(b bool, text string) { + ExpectWithOffset(1, b).To(BeTrue(), text) +} + +var TestResult error + +func InitializeGomegaForGodog(ctx *godog.ScenarioContext) { + ctx.StepContext().Before(func(ctx context.Context, st *godog.Step) (context.Context, error) { + TestResult = nil + return ctx, nil + }) + ctx.StepContext().After(func(ctx context.Context, st *godog.Step, status godog.StepResultStatus, err error) (context.Context, error) { + return ctx, TestResult + }) + RegisterFailHandler(func(message string, callerSkip ...int) { + // remember only the expectation failed first + // anything thereafter is not to be believed + if TestResult == nil { + TestResult = fmt.Errorf(message) + } + }) +} + +func Sleep(m time.Duration) { + time.Sleep(m * time.Millisecond) +} diff --git a/wifi.cpp b/wifi.cpp new file mode 100644 index 0000000..f359b99 --- /dev/null +++ b/wifi.cpp @@ -0,0 +1,78 @@ +#include +#include "config.h" + +NET_IP +NET_GATEWAY +NET_SUBNET + +bool wifiEnabled = false; + +void startWifi() { + wifiEnabled = true; + + if (!WiFi.config(local_IP, gateway, subnet)) { + // err + return; + } + + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + // while (WiFi.waitForConnectResult() != WL_CONNECTED) { + // DEBUG_PRINTLN("Connection Failed! Rebooting..."); + // delay(5000); + // ESP.restart(); + // } + + ArduinoOTA.setPasswordHash(PASSWORD_HASH); + + ArduinoOTA + .onStart([]() { + String type; + if (ArduinoOTA.getCommand() == U_FLASH) + type = "sketch"; + else // U_SPIFFS + type = "filesystem"; + + // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() + // Serial.println("Start updating " + type); + }) + .onEnd([]() { + // Serial.println("\nEnd"); + }) + .onProgress([](unsigned int progress, unsigned int total) { + // Serial.printf("Progress: %u%%\r", (progress / (total / 100))); + }) + .onError([](ota_error_t error) { + // Serial.printf("Error[%u]: ", error); + // if (error == OTA_AUTH_ERROR) Serial.println("Auth Failed"); + // else if (error == OTA_BEGIN_ERROR) Serial.println("Begin Failed"); + // else if (error == OTA_CONNECT_ERROR) Serial.println("Connect Failed"); + // else if (error == OTA_RECEIVE_ERROR) Serial.println("Receive Failed"); + // else if (error == OTA_END_ERROR) Serial.println("End Failed"); + }); + + ArduinoOTA.begin(); + + // Serial.println("Wifi started"); +} + +void stopWifi() { + wifiEnabled = false; + WiFi.disconnect(); +} + +void triggerWifi() { + if (!wifiEnabled) { + startWifi(); + } else { + stopWifi(); + } +} + +void handleWifi() { + if (!wifiEnabled) { + return; + } + + ArduinoOTA.handle(); +} \ No newline at end of file