From c947c8bb4cbdf01807d1f1c1c08abac1faf733db Mon Sep 17 00:00:00 2001 From: Andrey Klimov Date: Sun, 3 Nov 2019 03:31:32 +0300 Subject: [PATCH] Motor driver with feedback input (Airflow regulator Dospel) items pulling reworked --- lighthub/abstractch.h | 2 +- lighthub/inputs.cpp | 4 +- lighthub/item.cpp | 60 +++++- lighthub/item.h | 20 +- lighthub/lighthub.ino.cpp | 17 -- lighthub/main.cpp | 25 ++- lighthub/modules/in_ccs811_hdc1080.cpp | 8 +- lighthub/modules/in_ccs811_hdc1080.h | 4 +- lighthub/modules/out_ac.cpp | 6 +- lighthub/modules/out_ac.h | 2 +- lighthub/modules/out_motor.cpp | 246 +++++++++++++++++++++++++ lighthub/modules/out_motor.h | 32 ++++ lighthub/modules/out_spiled.cpp | 4 +- lighthub/modules/out_spiled.h | 2 +- 14 files changed, 383 insertions(+), 49 deletions(-) delete mode 100644 lighthub/lighthub.ino.cpp create mode 100644 lighthub/modules/out_motor.cpp create mode 100644 lighthub/modules/out_motor.h diff --git a/lighthub/abstractch.h b/lighthub/abstractch.h index 6c923ed..7276fdf 100644 --- a/lighthub/abstractch.h +++ b/lighthub/abstractch.h @@ -8,7 +8,7 @@ class abstractCh { public: abstractCh(){}; virtual ~abstractCh(){}; - virtual int Poll() = 0; + virtual int Poll(short cause) = 0; virtual int Setup() =0; //Should initialize hardware and reserve resources virtual int Anounce () {return 0;}; virtual int Stop() {return 0;}; //Should free resources diff --git a/lighthub/inputs.cpp b/lighthub/inputs.cpp index 45b9553..9b87cd9 100644 --- a/lighthub/inputs.cpp +++ b/lighthub/inputs.cpp @@ -167,10 +167,10 @@ switch (cause) { { #ifndef CSSHDC_DISABLE case IN_CCS811: - _ccs811.Poll(); + _ccs811.Poll(POLLING_SLOW); break; case IN_HDC1080: - _hdc1080.Poll(); + _hdc1080.Poll(POLLING_SLOW); break; #endif #ifndef DHT_DISABLE diff --git a/lighthub/item.cpp b/lighthub/item.cpp index a3ac831..61975d7 100644 --- a/lighthub/item.cpp +++ b/lighthub/item.cpp @@ -40,6 +40,7 @@ e-mail anklimov@gmail.com #include #include "modules/out_spiled.h" #include "modules/out_ac.h" +#include "modules/out_motor.h" short modbusBusy = 0; extern aJsonObject *pollingItem; @@ -122,7 +123,7 @@ void Item::Parse() { itemType = aJson.getArrayItem(itemArr, I_TYPE)->valueint; itemArg = aJson.getArrayItem(itemArr, I_ARG); itemVal = aJson.getArrayItem(itemArr, I_VAL); - + itemExt = aJson.getArrayItem(itemArr, I_EXT); switch (itemType) { #ifndef SPILED_DISABLE @@ -138,6 +139,13 @@ void Item::Parse() { // debugSerial<name << F(" T:") << itemType << F(" =") << getArg() << endl; @@ -297,6 +305,32 @@ void Item::setVal(long int par) // Only store if VAL is int (autogenerated or c } +long int Item::getExt() //Return Val if val is int or first elem of Value array +{ + if (!itemExt) return 0;//-1; + if (itemExt->type == aJson_Int) return itemExt->valueint; + else if (itemExt->type == aJson_Array) { + aJsonObject *t = aJson.getArrayItem(itemExt, 0); + if (t) return t->valueint; + else return 0;//-3; + } else return 0;//-2; +} + +void Item::setExt(long int par) // Only store if VAL is int (autogenerated or config-defined) +{ + if (!itemExt) + { + for (int i = aJson.getArraySize(itemArr); i <= 4; i++) + aJson.addItemToArray(itemArr, aJson.createItem(0)); + itemExt = aJson.getArrayItem(itemArr, I_EXT); + }; + + if(itemExt->type != aJson_Int) return; + itemExt->valueint = par; + debugSerial<type == aJson_Array)); } @@ -561,7 +595,7 @@ int Item::Ctrl(short cmd, short n, int *Parameters, boolean send, int suffixCode */ default: res = driver->Ctrl(cmd, n, Parameters, send, suffixCode, subItem); - setCmd(cmd); + if (cmd) setCmd(cmd); } return res; } @@ -1475,13 +1509,11 @@ int Item::checkModbusDimmer(int data) { } //if data changed } -int Item::Poll() { +int Item::Poll(short cause) { - if (driver && driver->Status()) - { - driver->Poll(); - return INTERVAL_POLLING; //TODO refactoring - } +switch (cause) +{ + case POLLING_SLOW: // Legacy polling switch (itemType) { case CH_MODBUS: @@ -1504,12 +1536,20 @@ int Item::Poll() { default: sendDelayedStatus(); } + } + + if (driver && driver->Status()) + { + return driver->Poll(cause); + } + return INTERVAL_POLLING; } void Item::sendDelayedStatus() -{ - if (getFlag(SEND_COMMAND | SEND_PARAMETERS)) +{ long int flags = getFlag(SEND_COMMAND | SEND_PARAMETERS); + debugSerial<name< -# 1 "/Users/andrey/Documents/Arduino/lighthub/lighthub/lighthub.ino" -#include "main.h" -void setup(); -void loop(); -#line 2 "/Users/andrey/Documents/Arduino/lighthub/lighthub/lighthub.ino" -void setup(){ - - setup_main(); - - -} -void loop(){ - - loop_main(); -} \ No newline at end of file diff --git a/lighthub/main.cpp b/lighthub/main.cpp index 5826716..9846565 100644 --- a/lighthub/main.cpp +++ b/lighthub/main.cpp @@ -1746,16 +1746,34 @@ void inputSetup(void) { } } -//#ifndef MODBUS_DISABLE + void pollingLoop(void) { +// FAST POLLINT - as often AS possible every item +if (items) { + aJsonObject * item = items->child; + while (items && item) + if (item->type == aJson_Array && aJson.getArraySize(item)>1) { + Item it(item); + if (it.isValid()) { + it.Poll(POLLING_FAST); + } //isValid + item = item->next; + } //if +} + +// SLOW POLLING boolean done = false; if (lanStatus == RETAINING_COLLECTING) return; if (millis() > nextPollingCheck) { while (pollingItem && !done) { if (pollingItem->type == aJson_Array) { Item it(pollingItem); - nextPollingCheck = millis() + it.Poll(); //INTERVAL_CHECK_MODBUS; - done = true; + uint32_t ret = it.Poll(POLLING_SLOW); + if (ret) + { + nextPollingCheck = millis() + ret; //INTERVAL_CHECK_MODBUS; + done = true; + } }//if pollingItem = pollingItem->next; if (!pollingItem) { @@ -1765,7 +1783,6 @@ void pollingLoop(void) { } //while }//if } -//#endif bool isThermostatWithMinArraySize(aJsonObject *item, int minimalArraySize) { return (item->type == aJson_Array) && (aJson.getArrayItem(item, I_TYPE)->valueint == CH_THERMO) && diff --git a/lighthub/modules/in_ccs811_hdc1080.cpp b/lighthub/modules/in_ccs811_hdc1080.cpp index d7e3ccc..55bd1af 100644 --- a/lighthub/modules/in_ccs811_hdc1080.cpp +++ b/lighthub/modules/in_ccs811_hdc1080.cpp @@ -2,6 +2,7 @@ #include "Arduino.h" #include "options.h" #include "Streaming.h" +#include "item.h" #if defined(M5STACK) #include @@ -79,10 +80,11 @@ SCL_HIGH(); #endif } -int in_hdc1080::Poll() +int in_hdc1080::Poll(short cause) { float h,t; int reg; +if (cause!=POLLING_SLOW) return 0; if (!HDC1080ready) {debugSerial< INTERVAL_AC_POLLING) { prevPolling = now; @@ -253,7 +255,7 @@ delay(100); InsertData(data, 37); } } -return 1; +return INTERVAL_POLLING; }; int out_AC::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixCode, char* subItem) diff --git a/lighthub/modules/out_ac.h b/lighthub/modules/out_ac.h index 9d1d123..33a5247 100644 --- a/lighthub/modules/out_ac.h +++ b/lighthub/modules/out_ac.h @@ -25,7 +25,7 @@ public: out_AC(Item * _item):abstractOut(_item){}; int Setup() override; - int Poll() override; + int Poll(short cause) override; int Stop() override; int Status() override; int isActive() override; diff --git a/lighthub/modules/out_motor.cpp b/lighthub/modules/out_motor.cpp new file mode 100644 index 0000000..e578fec --- /dev/null +++ b/lighthub/modules/out_motor.cpp @@ -0,0 +1,246 @@ +#ifndef MOTOR_DISABLE + +#include "modules/out_motor.h" +#include "Arduino.h" +#include "options.h" +#include "Streaming.h" + +#include "item.h" + +static int driverStatus = CST_UNKNOWN; + +void out_Motor::getConfig() +{ + pinUp=item->getArg(0); + if(pinUp<=0 || pinFeedback>=PINS_COUNT) pinUp=32; + + pinDown=item->getArg(1); + if (pinDown<=0 || pinFeedback>=PINS_COUNT) pinDown=33; + + pinFeedback=item->getArg(2); + if (pinFeedback<0 || pinFeedback>=PINS_COUNT) pinFeedback=0; + + feedbackOpen=item->getArg(3); + if (feedbackOpen<=0 || feedbackOpen>1024) feedbackOpen=0; + + feedbackClosed=item->getArg(4); + if (feedbackClosed<0 || feedbackClosed>1024) feedbackClosed=1024; + + maxOnTime=item->getArg(5); + if (maxOnTime<=0) maxOnTime=10000; + } + + +int out_Motor::Setup() +{ +getConfig(); +Serial.println("Motor Init"); +digitalWrite(pinUp,LOW); +digitalWrite(pinDown,LOW); +pinMode(pinFeedback, INPUT); +item->setExt(0); +item->clearFlag(ACTION_NEEDED); +driverStatus = CST_INITIALIZED; +return 1; +} + +int out_Motor::Stop() +{ +Serial.println("Motor De-Init"); +digitalWrite(pinUp,LOW); +digitalWrite(pinDown,LOW); +item->setExt(0); +driverStatus = CST_UNKNOWN; +return 1; +} + +int out_Motor::Status() +{ +return driverStatus; +} + +int out_Motor::isActive() +{ +return item->getVal(); +} + +int out_Motor::Poll(short cause) +{ +int curPos = -1; +int targetPos = -1; +int dif; +if (!item->getFlag(ACTION_NEEDED)) return 0; + +uint32_t motorOfftime = item->getExt(); + +switch (item->getCmd()) +{ + case CMD_ON: + case CMD_XON: + targetPos = item->getVal(); + break; + + case CMD_OFF: + case CMD_HALT: + targetPos = 0; + break; +} + +if (pinFeedback && (g_APinDescription[pinFeedback].ulPinAttribute & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG) +{ +curPos=map(analogRead(pinFeedback),feedbackClosed,feedbackOpen,0,100); +if (curPos<0) curPos=0; +if (curPos>100) curPos=100; +} + +if (motorOfftime && motorOfftime=0) + dif=targetPos-curPos; +else + dif=targetPos-50; // Have No feedback + + + +if (dif<-POS_ERR) +{ + + digitalWrite(pinDown,LOW); + if (!item->getExt())item->setExt(millis()+maxOnTime); + + // + //PINS_COUNT + //PIN_ATTR_ANALOG + // uint32_t attr = g_APinDescription[pinUp].ulPinAttribute; + // if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) ; + +if (digitalPinHasPWM(pinUp)) + { + int velocity = map(-dif, 0, 10, 0, 255); + if (velocity>255) velocity=255; + analogWrite(pinUp,velocity); + } +else + { + digitalWrite(pinUp,HIGH); + } +} +else + +if (dif>POS_ERR) +{ +digitalWrite(pinUp,LOW); + +if (!item->getExt()) item->setExt(millis()+maxOnTime); +if (digitalPinHasPWM(pinDown)) +{ + int velocity = map(dif, 0, 10, 0, 255); + if (velocity>255) velocity=255; + analogWrite(pinDown,velocity); +} +else +{ + digitalWrite(pinDown,HIGH); +} + +} +else //Target zone +{ + digitalWrite(pinUp,LOW); + digitalWrite(pinDown,LOW); + item->setExt(0); + item->clearFlag(ACTION_NEEDED); + +} + + +return 0; +}; + +int out_Motor::getChanType() +{ + return CH_PWM; +} + + + +int out_Motor::Ctrl(short cmd, short n, int * Parameters, boolean send, int suffixCode, char* subItem) +{ +int chActive = item->isActive(); +bool toExecute = (chActive>0); +long st; +if (cmd>0 && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it + +item->setFlag(ACTION_NEEDED); + +switch(suffixCode) +{ +case S_NOTFOUND: + // turn on and set +toExecute = true; +debugSerial<setVal(st=Parameters[0]); //Store + if (toExecute) + { + if (chActive>0 && !st) item->setCmd(CMD_OFF); + if (chActive==0 && st) item->setCmd(CMD_ON); + item->SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED); + item->setExt(millis()+maxOnTime); //Extend motor time + } + else item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED); + + return 1; + //break; + +case S_CMD: + item->setCmd(cmd); + switch (cmd) + { + case CMD_ON: + + /* + if (chActive>0 && send) + { + SendStatus(SEND_COMMAND); + return 1; + } + */ + //retrive stored values + st = item->getVal(); + + + if (st && (stsetVal(st); + + if (st) //Stored smthng + { + if (send) item->SendStatus(SEND_COMMAND | SEND_PARAMETERS); + debugSerial<setVal(st); + if (send) item->SendStatus(SEND_COMMAND | SEND_PARAMETERS ); + } + item->setExt(millis()+maxOnTime); //Extend motor time + return 1; + + case CMD_OFF: + if (send) item->SendStatus(SEND_COMMAND); + item->setExt(millis()+maxOnTime); //Extend motor time + return 1; + +} //switch cmd + +break; +} //switch suffix +debugSerial< +#include + +#ifndef POS_ERR +#define POS_ERR 2 +#endif + +class out_Motor : public abstractOut { +public: + + out_Motor(Item * _item):abstractOut(_item){getConfig();}; + int Setup() override; + int Poll(short cause) override; + int Stop() override; + int Status() override; + int isActive() override; + int getChanType() override; + int Ctrl(short cmd, short n=0, int * Parameters=NULL, boolean send=true, int suffixCode=0, char* subItem=NULL) override; + + int8_t pinUp; + int8_t pinDown; + int8_t pinFeedback; + int16_t maxOnTime; + uint16_t feedbackOpen; + uint16_t feedbackClosed; +protected: + void getConfig(); +}; +#endif diff --git a/lighthub/modules/out_spiled.cpp b/lighthub/modules/out_spiled.cpp index 386e69d..5bd8a61 100644 --- a/lighthub/modules/out_spiled.cpp +++ b/lighthub/modules/out_spiled.cpp @@ -94,9 +94,9 @@ debugSerial<< F(" val:")<