Code Monkey home page Code Monkey logo

arduino-shutters's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

arduino-shutters's Issues

multiple shutters

I want to control 4 shutters independently, so I extended the code (thx to @ludodoucet for pointing me in the right direction). But there is something strange happening and I don't know where to look.
Here's what I did: I multiplied most of the code by creating multiple shutter instances. "Shutters" is the original instance, shutters1 etc is the multiplied part. So for the moment I have 5 shutters ;-)
When I run the sketch, "shutters" stays at 0%. All other instances works fine.
When I comment out all parts involved "shutters", the problem moves to shutters1. All remaining three work just fine.
So, there is always a problem with the first instance that is not responding as it should. It seems as if whatever first instance is not responding on setLevel, or at least no more than 1%. I can't get my head around it...

#include <Shutters.h>
#include <EEPROM.h>

const byte eepromOffset = 0;
const byte eepromOffset1 = 1;
const byte eepromOffset2 = 2;
const byte eepromOffset3 = 3;
const byte eepromOffset4 = 4;

const unsigned long upCourseTime = 5000;
const unsigned long downCourseTime = 5000;
const unsigned long upCourseTime1 = 5000;
const unsigned long downCourseTime1 = 5000;
const unsigned long upCourseTime2 = 5000;
const unsigned long downCourseTime2 = 5000;
const unsigned long upCourseTime3 = 5000;
const unsigned long downCourseTime3 = 5000;
const unsigned long upCourseTime4 = 5000;
const unsigned long downCourseTime4 = 5000;

const float calibrationRatio = 0.1;
int relay1 = 35;
int relay2 = 37;
int relay3 = 39;
int relay4 = 41;

int schakelaar1 = 43;
int schakelaar2 = 45;
int schakelaar3 = 42;
int schakelaar4 = 44;

int schakelaar1State;
int schakelaar2State;
int schakelaar3State;
int schakelaar4State;

//0 default
void shuttersOperationHandler(Shutters* s, ShuttersOperation operation) {
  switch (operation) {
    case ShuttersOperation::UP:
      Serial.println("shutters going up.");
      digitalWrite(relay1, LOW);
      digitalWrite(relay2, HIGH);
      break;
    case ShuttersOperation::DOWN:
      Serial.println("shutters going down.");
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, LOW);
      break;
    case ShuttersOperation::HALT:
      Serial.println("Shutter halted.");
      digitalWrite(relay1, HIGH);
      digitalWrite(relay2, HIGH);
      break;
  }
}
void readInEeprom(char* dest, byte length) {
  for (byte i = 0; i < length; i++) {
    dest[i] = EEPROM.read(eepromOffset + i);
  }
}
void shuttersWriteStateHandler(Shutters* shutters, const char* state, byte length) {
  for (byte i = 0; i < length; i++) {
    EEPROM.write(eepromOffset + i, state[i]);
  }
}
void onShuttersLevelReached(Shutters* shutters, byte level) {
  Serial.print("shutters at ");
  Serial.print(level);
  Serial.println("%");
}
Shutters shutters;

//1
void shuttersOperationHandler1(Shutters* s, ShuttersOperation operation) {
  switch (operation) {
    case ShuttersOperation::UP:
      Serial.println("shutters1 going up.");
      break;
    case ShuttersOperation::DOWN:
      Serial.println("shutters1 going down.");
      break;
    case ShuttersOperation::HALT:
      Serial.println("shutters1 halted.");
      break;
  }
}

void readInEeprom1(char* dest, byte length) {
  for (byte i = 0; i < length; i++) {
    dest[i] = EEPROM.read(eepromOffset1 + i);
  }
}
void shuttersWriteStateHandler1(Shutters* shutters, const char* state, byte length) {
  for (byte i = 0; i < length; i++) {
    EEPROM.write(eepromOffset1 + i, state[i]);
  }
}
void onShuttersLevelReached1(Shutters* shutters, byte level) {
  Serial.print("shutters1 at ");
  Serial.print(level);
  Serial.println("%");
}
Shutters shutters1;

//2
void shuttersOperationHandler2(Shutters* s, ShuttersOperation operation) {
  switch (operation) {
    case ShuttersOperation::UP:
      Serial.println("shutters2 going up.");
      break;
    case ShuttersOperation::DOWN:
      Serial.println("shutters2 going down.");
      break;
    case ShuttersOperation::HALT:
      Serial.println("shutters2 halted.");
      break;
  }
}

void readInEeprom2(char* dest, byte length) {
  for (byte i = 0; i < length; i++) {
    dest[i] = EEPROM.read(eepromOffset2 + i);
  }
}
void shuttersWriteStateHandler2(Shutters* shutters, const char* state, byte length) {
  for (byte i = 0; i < length; i++) {
    EEPROM.write(eepromOffset2 + i, state[i]);
  }
}
void onShuttersLevelReached2(Shutters* shutters, byte level) {
  Serial.print("shutters2 at ");
  Serial.print(level);
  Serial.println("%");
}
Shutters shutters2;

//3
void shuttersOperationHandler3(Shutters* s, ShuttersOperation operation) {
  switch (operation) {
    case ShuttersOperation::UP:
      Serial.println("shutters3 going up.");
      break;
    case ShuttersOperation::DOWN:
      Serial.println("shutters3 going down.");
      break;
    case ShuttersOperation::HALT:
      Serial.println("shutters3 halted.");
      break;
  }
}

void readInEeprom3(char* dest, byte length) {
  for (byte i = 0; i < length; i++) {
    dest[i] = EEPROM.read(eepromOffset3 + i);
  }
}
void shuttersWriteStateHandler3(Shutters* shutters, const char* state, byte length) {
  for (byte i = 0; i < length; i++) {
    EEPROM.write(eepromOffset3 + i, state[i]);
  }
}
void onShuttersLevelReached3(Shutters* shutters, byte level) {
  Serial.print("shutters3 at ");
  Serial.print(level);
  Serial.println("%");
}
Shutters shutters3;

//4
void shuttersOperationHandler4(Shutters* s, ShuttersOperation operation) {
  switch (operation) {
    case ShuttersOperation::UP:
      Serial.println("shutters4 going up.");
      break;
    case ShuttersOperation::DOWN:
      Serial.println("shutters4 going down.");
      break;
    case ShuttersOperation::HALT:
      Serial.println("shutters4 halted.");
      break;
  }
}
void readInEeprom4(char* dest, byte length) {
  for (byte i = 0; i < length; i++) {
    dest[i] = EEPROM.read(eepromOffset4 + i);
  }
}
void shuttersWriteStateHandler4(Shutters* shutters, const char* state, byte length) {
  for (byte i = 0; i < length; i++) {
    EEPROM.write(eepromOffset4 + i, state[i]);
  }
}
void onShuttersLevelReached4(Shutters* shutters, byte level) {
  Serial.print("shutters4 at ");
  Serial.print(level);
  Serial.println("%");
}
Shutters shutters4;

void setup() {
  pinMode(relay1, OUTPUT);
  pinMode(relay2, OUTPUT);
  pinMode(relay3, OUTPUT);
  pinMode(relay4, OUTPUT);

  pinMode(schakelaar1, INPUT_PULLUP);
  pinMode(schakelaar2, INPUT_PULLUP);
  pinMode(schakelaar3, INPUT_PULLUP);
  pinMode(schakelaar4, INPUT_PULLUP);

  digitalWrite(relay1, HIGH);
  digitalWrite(relay2, HIGH);
  digitalWrite(relay3, HIGH);
  digitalWrite(relay4, HIGH);

  Serial.begin(9600);
  delay(100);
  Serial.println();
  Serial.println("*** start shutters ***");


  //0 original code
  char storedShuttersState[shutters.getStateLength()];
  readInEeprom(storedShuttersState, shutters.getStateLength());
  shutters
  .setOperationHandler(shuttersOperationHandler)
  .setWriteStateHandler(shuttersWriteStateHandler)
  .restoreState(storedShuttersState)
  .setCourseTime(upCourseTime, downCourseTime)
  .onLevelReached(onShuttersLevelReached)
  .begin()
  .setLevel(10);


  //shutter 1
  char storedShuttersState1[shutters1.getStateLength()];
  readInEeprom1(storedShuttersState1, shutters1.getStateLength());
  shutters1
  .setOperationHandler(shuttersOperationHandler1)
  .setWriteStateHandler(shuttersWriteStateHandler1)
  .restoreState(storedShuttersState1)
  .setCourseTime(upCourseTime1, downCourseTime1)
  .onLevelReached(onShuttersLevelReached1)
  .begin()
  .setLevel(10);

  //shutter 2
  char storedShuttersState2[shutters2.getStateLength()];
  readInEeprom2(storedShuttersState2, shutters2.getStateLength());
  shutters2
  .setOperationHandler(shuttersOperationHandler2)
  .setWriteStateHandler(shuttersWriteStateHandler2)
  .restoreState(storedShuttersState2)
  .setCourseTime(upCourseTime2, downCourseTime2)
  .onLevelReached(onShuttersLevelReached2)
  .begin()
  .setLevel(10);

  //shutter 3
  char storedShuttersState3[shutters3.getStateLength()];
  readInEeprom3(storedShuttersState3, shutters3.getStateLength());
  shutters3
  .setOperationHandler(shuttersOperationHandler3)
  .setWriteStateHandler(shuttersWriteStateHandler3)
  .restoreState(storedShuttersState3)
  .setCourseTime(upCourseTime3, downCourseTime3)
  .onLevelReached(onShuttersLevelReached3)
  .begin()
  .setLevel(10);

  //shutter 4
  char storedShuttersState4[shutters4.getStateLength()];
  readInEeprom4(storedShuttersState4, shutters4.getStateLength());
  shutters4
  .setOperationHandler(shuttersOperationHandler4)
  .setWriteStateHandler(shuttersWriteStateHandler4)
  .restoreState(storedShuttersState4)
  .setCourseTime(upCourseTime4, downCourseTime4)
  .onLevelReached(onShuttersLevelReached4)
  .begin()
  .setLevel(10);
}

void loop() {
  shutters.loop();
  shutters1.loop();
  shutters2.loop();
  shutters3.loop();
  shutters4.loop();

  if (Serial.available() > 0) {
    int level = Serial.parseInt();

    Serial.print("Goes to level ");
    Serial.print(level);
    Serial.println(" %");
    shutters.setLevel(level);
    shutters1.setLevel(level);
    shutters2.setLevel(level);
    shutters3.setLevel(level);
    shutters4.setLevel(level);
  }


  //on-OFF-on type switch
  schakelaar1State = digitalRead(schakelaar1);
  schakelaar2State = digitalRead(schakelaar2);
  schakelaar3State = digitalRead(schakelaar3);

  if (schakelaar1State == LOW) {
    shutters.setLevel(0);          //MOVE UP
  }
  else if (schakelaar2State == LOW) {
    shutters.setLevel(80);         //MOVE to 80%
  }
  else if (schakelaar3State == LOW) {
    shutters.setLevel(100);        //MOVE to 100%
  }
  else {
    shutters.stop();
  }

}  //loop ends here

EEPROMWrite

I use an arduino mega, after a power cut, the shutters go up, while they were positioned at 50.
I tried to understand how data was stored by callback without success.
If I had the address on the eeprom, I could check what happens. From 0 to 9 the value remains at 255.
Can you help me?

V3 redesign

  • Different instances of Shutters should be able to share the same callbacks
    • First parameter of the callbacks must be a pointer to the current Shutters instance
  • Course time and calibration ratio must be settable after the Shutters instantiation
  • New Shutters constructor would be:
Shutters(void (*upCallback)(Shutters* shutters), void (*downCallback)(Shutters* shutters), void (*haltCallback)(Shutters* shutters), uint8_t (*getStateCallback)(Shutters* shutters), void (*setStateCallback)(Shutters* shutters, uint8_t state));

// new methods

void .setCourseTime(uint32_t courseTime);
void .setCalibrationRatio(uint8_t calibrationLevel); // default value = 0.1
void .onLevelReached(void (*onLevelReachedCallback)(Shutters* shutters, uint8_t level));

setCourseTime must be called before the begin, otherwise begin would not do anything.
The course time would be stored in the state. We need 7 bits to store the level of the shutters, and the course time can be 32 bits. So let's put a new state that would be an uint32_t.

The schema would be this:

  • 25 first bits: the course time. This allows 33,554,432ms, which is basically about 59 minutes, so this is enough. The 0 value means unset.
  • 7 remaining bits: The known level. We'll say a clean state would be 0, so let's actually offset the state by 28. Therefore, 28 would be 0% and 128 would be 100%.

This allows the course time to be defined at runtime. If we call setCourseTime when the saved course time is 0 or a different one, the shutters would consider the state is unknown. If the value is the same as the saved one, then we consider the state is known.

Also, another change, the reset method should not "disable" the library. It should instead put itself in "pre-begin" phase.

Calibration during the runtime

How can we force one full calibration during the runtime?
As an example, I have one contact sensor and I want to perform one reset/calibration of the shutter when this sensor is triggered. Is there a good way to do it?
I tried calling shutters.reset() but nothing happens... Whats the purpose of this method?

controle volet local

Bonjour
Je suis tombé sur votre librairie et j'ai réussi a le faire fonctionner avec la fonction shutters.setLevel(niv);
Par contre, est il possible également de faire évoluer la position du volet quand on actionne un relais directement
En fait je controle aussi les volets en local depuis un bouton physique ? si entrée = 1, relais = 1 et dans ce cas je voudrais que la position du volet évolue
Si possible, quelle fonction appeler ?
Si non, possible de faire évoluer dans ce sens ?
Je précise que je suis autodidacte en code et que mon niveau est plutot bas ;)
Merci d'avance

Using the lib

Hi Marvin, thanks for sharing your codes. I'm trying to make the example work but when I give a new level the debug is always:

Going to level 50
Shutters: starting move
Shutters: going down
Shutters going down.

and then it keeps on saying going down... This is the code I am using, the sample of the example just added 2 inputs and 2 outputs to test it. (Using a nodeMCU )
Is anything i am doing wrong? Maybe using the wrong way?
Thanks.

#include <Shutters.h>
#include <EEPROM.h>
#include <Bounce2.h>

const byte eepromOffset = 0;
const unsigned long upCourseTime = 15 * 1000;
const unsigned long downCourseTime = 10 * 1000;
const float calibrationRatio = 0.1;

#define ON LOW
#define OFF HIGH

int oldTrigValue1 = -1;
int oldTrigValue2 = -1;
/*
static const uint8_t D0 = 16;
static const uint8_t D1 = 5;
static const uint8_t D2 = 4;
static const uint8_t D3 = 0;
static const uint8_t D4 = 2;
static const uint8_t D5 = 14;
static const uint8_t D6 = 12;
static const uint8_t D7 = 13;
static const uint8_t D8 = 15;
static const uint8_t D9 = 3;
static const uint8_t D10 = 1;
*/

//Pinout
const int RELAY1 = 5; //D1;
const int RELAY2 = 4; //D2;
const int PIN_TECLA1 = 14; //D5;
const int PIN_TECLA2 = 12; //D6;

Bounce debouncer = Bounce();
Bounce debouncer2 = Bounce();

void shuttersOperationHandler(Shutters* s, ShuttersOperation operation) {
switch (operation) {
case ShuttersOperation::UP:
Serial.println("Shutters going up.");
// TODO: Implement the code for the shutters to go up
digitalWrite(RELAY2, OFF);
digitalWrite(RELAY1, ON);
break;
case ShuttersOperation::DOWN:
Serial.println("Shutters going down.");
// TODO: Implement the code for the shutters to go down
digitalWrite(RELAY1, OFF);
digitalWrite(RELAY2, ON);
break;
case ShuttersOperation::HALT:
Serial.println("Shutters halting.");
// TODO: Implement the code for the shutters to halt
digitalWrite(RELAY1, OFF);
digitalWrite(RELAY2, OFF);
break;
}
}

void readInEeprom(char* dest, byte length) {
for (byte i = 0; i < length; i++) {
dest[i] = EEPROM.read(eepromOffset + i);
}
}

void shuttersWriteStateHandler(Shutters* shutters, const char* state, byte length) {
for (byte i = 0; i < length; i++) {
EEPROM.write(eepromOffset + i, state[i]);
#ifdef ESP8266
EEPROM.commit();
#endif
}
}

void onShuttersLevelReached(Shutters* shutters, byte level) {
Serial.print("Shutters at ");
Serial.print(level);
Serial.println("%");
}

Shutters shutters;

void setup() {
pinMode(RELAY1, OUTPUT);
pinMode(RELAY2, OUTPUT);
pinMode(PIN_TECLA1, INPUT); // HAY PONERLA A PULL-DOWN
pinMode(PIN_TECLA2, INPUT); //HAY QUE PONERLA A PULL-DOWN

debouncer.attach(PIN_TECLA1);
debouncer.interval(50);
debouncer2.attach(PIN_TECLA2);
debouncer2.interval(50);

Serial.begin(9600);
delay(100);
EEPROM.begin(512);
Serial.println();
Serial.println("*** Starting ***");

char storedShuttersState[shutters.getStateLength()];
//readInEeprom(&storedShuttersState, shutters.getStateLength());
shutters
.setOperationHandler(shuttersOperationHandler)
.setWriteStateHandler(shuttersWriteStateHandler)
.restoreState(storedShuttersState)
.setCourseTime(upCourseTime, downCourseTime)
.onLevelReached(onShuttersLevelReached)
.begin()
.setLevel(30); // Go to 30%
}

void loop() {
debouncer.update();
debouncer2.update();
shutters.loop();

int value1 = debouncer.read();
int value2 = debouncer2.read();

  //Teclas comunes interruptor

if (value1 != oldTrigValue1)
{
oldTrigValue1 = value1;
Serial.print("Interruptor--Light 1 : ");
Serial.println(value1);
//shutters.setLevel(100);
}

if (value2 != oldTrigValue2)
{
oldTrigValue2 = value2;
Serial.print("Interruptor--Light 2 : ");
Serial.println(value2);
//shutters.setLevel(0);
}

if (Serial.available() > 0) {
int level = Serial.parseInt();
Serial.println(shutters.getCurrentLevel());
Serial.print("Going to level ");
Serial.println(level);
shutters.setLevel(level);
}
}

Can't get exemple sketch to work

I may be doing something wrong but I really don't know what

kapture 2018-11-30 at 16 58 47

Edit: Activating the debug mode throw me this message "Stored state is invalid".

I tried to call shutters.reset(); but then this happened...

kapture 2018-12-01 at 10 27 27

Edit2: Ok now it seems to work. I just edited upCourseTime = 30 * 1000; to upCourseTime = 30000;

wrong type for _eepromPosition

For Atmega328, EEPROM is 1kbyte and in the code, _eepromPosition is unisgned char. Not enough if you put your data after 255

nullptr

Bonjour,

When I compile the example file I have this error:
I may have forgotten something?

In file included from sketch_jul05d.ino:1:0:
C:\Users\ludo\Documents\Arduino\libraries\arduino-shutters-master/Shutters.h:56:257: error: 'nullptr' was not declared in this scope
   Shutters(uint32_t courseTime, void (*upCallback)(void), void (*downCallback)(void), void (*haltCallback)(void), uint8_t (*getStateCallback)(void), void (*setStateCallback)(uint8_t), float calibrationRatio = 0.1, void (*onLevelReachedCallback)(uint8_t) = nullptr);
                                                                                                                                                                                                                                                                 ^
Erreur lors de la compilation

Merci

Exemple

Bonjour,

Je me permets de m'exprimer en Français car j'ai vu que vous étiez Parisien.

Votre code sur les volets roulants semble super mais malgré l'exemple donné, je n'arrive pas à le faire fonctionner (mon niveau en programmation est proche de 0).
Serait-il possible que vous publiiez un exemple simple avec un ou deux volets en mettant en lumière les fonctions créées dans votre code?

Cordialement.

new API

Je ne sais pas si ça vient de moi, j'ai cette erreur lorsque je compile l'exemple pour un arduino...

src/Railduino_4Volets.cpp: In function 'void setup()':
src/Railduino_4Volets.cpp:59:63: error: cannot convert 'char (*)[(<anonymous> + 1)]' to 'char*' for argument '1' to 'void readInEeprom(char*, byte)'
readInEeprom(&storedShuttersState, shutters.getStateLength());
^

courseTimeDown < courseTimeUp

Hello, I have a small question:
The closure is faster than opening within 4 seconds.
Is it possible to consider two race times in a future version?

EXAMPLE NOT WORKING

Hi Marvin ,
I'm trying to use your library and start with the example provided , but it doesn't work .
I set the new level from the serial monitor and nothing happens , level always stays @ 255 .
I'm using Arduino IDE 1.8.7
Can you please help me in this matter.
Thank you .

Issue

using interrupt allowed?

Hi Marvin,
I plan to use the library to control 4 shutters independently, using conditional statements and time of day. It's going to be a mega2560 doing some other small tasks like reading the energymeter, switching some lights around the house etc. No other domotica involved. I prefer to use a DCF77 receiver so time is always accurate. The DCF77 library uses an interrupt. I read that using delays is not preferred. Does the same go for interrupts?

_currentLevel == _targetLevel not handled properly

Firstly, thank you @marvinroger for this library.

I did some testing for my custom usage and found 2 situations when state machine wrongly changes from idle to targeting.

Initial condition: All testing is done using the latest github version and with the default example, using Arduino IDE, and an Arduino UNO type board.
The only changes I made was to add 'u' after first number for upCourseTime and downCourseTime definition and setLevel(30) changed to setLevel(0) in setup.

const unsigned long upCourseTime = 30u * 1000;
const unsigned long downCourseTime = 45u * 1000;

I found 2 bad behaviors as folows
Bad behavior 1:
During a reset, if setLevel(0) is called, when reset finishes, state machine switches from RESETTING to IDLE to TARGETING and then into a RESETTING loop because _currentLevel goes outside normal 0-100 range (to 255).
Calling for any other level fixes the loop.
Evaluating _targetLevel == _currentLevel and asigning LEVEL_NONE to _targetLevel if true, keeps the state machine in IDLE.

adding this line in loop function:
if (_targetLevel == _currentLevel) _targetLevel = LEVEL_NONE;
before:
if (_state == STATE_IDLE && _targetLevel == LEVEL_NONE) return *this; // nothing to do
solves the problem

Bad behavior 2:
If during an 100% end run calibration, setLevel(100) is called, after calibration finishes, the state machine goes into TARGETING and goes to 0% and then returns to 100%.
In setLevel function, calibration state is not evaluated and _targetLevel is changed from LEVEL_NONE to 100. State machine switches from IDLE to TARGETING because of this. At this point direction is set to UP and machine moves to 0, IDLES, but still having a target set, starts moving down to 100.
Calling a setLevel during this move fixes the behavior.
Same line as before fixes the problem, but can also be fixed before by changing:

in setLevel function this:
if (_state == STATE_IDLE && level == _currentLevel) return *this;
to:
if (_state == STATE_IDLE || _state == STATE_CALIBRATING) && level == _currentLevel) return *this;

I currently use only the first change, and both problems are gone.

Multi-shutter example

I've looked at the code and the example, but I can't figure out how a multi-shutter scenario is supposed to be implemented.

Of course I'm free to do whatever I want using callbacks, but I'd like to understand better whether the API supports handling (de)multiplexing (from)to multiple shutters.

Bug EEPROM = 100

Salut Marvin,
J'ouvre une nouvelle issue car j'ai trouver un bug dans la lib.

En effet j'ai remarqué que:
Si level = 100 et que mon volet reboot la lib lance la calibration.
Si level =< 99 et que le volet reboot la lib ne lance pas la calibration et tout fonctionne normalement,

N'y aurait-il pas un bug dans le stockage de la valeur 100 dans l'eeprom?

Marmoul

Edit: J'ai remplacer le level 100 par 99 dans mon code et sa fonctionne bien maintenant.
Le problème serait que chez moi?

Add stop/pause (delay) when shutter direction is changed due to new level request

When shutter is moving and new level is requested shutter should pause for predefined time before changing direction. This will prevent switching electrical motor direction in very short time and will help keep electrical relays in good condition.

When new level request is not changing shutter direction then shutter should not stop due to new level request - no halt() should be called.

restore state does not restore up and downCourseTime

Hi.
We started using your library to deal with our own non smart shutters.
We're doing a good job so far, but we're stuck when we want to persist course times, and let them be settable through homie properties.
We think they should be restored by a call of restoreState because they are part of a ShuttersInternal::StoredState.
Unfortunately, when looking at the content of restoreState method :

_currentLevel = _storedState.getLevel();

Only the level is restored, but not the course times.
@marvinroger : Is it a bug ?

Get the state in percent when halted

Hello,

I want to get the state in percent when the shutter is halted.

void shuttersWriteStateHandler1(Shutters* shutters, const char* state, byte length) {
  for (byte i = 0; i < length; i++) {
    EEPROM.write(eepromOffset1 + i, state[i]);
  }
  String states = String(state);
  if (debug == true) {Serial.print("shutters1 at ");
  Serial.print(states);
  Serial.println("% write");}
}

where:
shutters1 at 00007421703598089056% write when shutter is at 10%
shutters1 at 00007421703598081376% write when shutter is at 15%

with:

void onShuttersLevelReached1(Shutters* shutters, byte level) {
  if (debug == true) {Serial.print("shutters1 at ");
  Serial.print(level);
  Serial.println("%");}

the state in percent change at every step, I want to have it only when is halted, can you help me 'stp'?

Races during safety delay.

If shutters are in safety delay period invoking setLevel() and stop() before safety delay finished doesn't stop shutters. Stop is ignored.
2nd issue. In my opinion safety delay should not be taking into consideration when direction is not changed. Now safety delay is always checked even when direction in previous move was the same.
Another small improvements with safety daley is possibilty of defining SAFETY_DELAY without library source code modification.
For example 77c6865

exemple avec plusieurs shutters

Bonjour.

J'ai vraiment des difficultés pour voir comment utiliser la bibliothèques avec plusieurs volets.

N'y aurait il pas un exemple quelques part ?

Comment agir sur 1 seul des volets ?
Comment avoir les retours de position sur le volet en question ?

Le code est vraiment difficile à comprendre pour un débutant malheureusement.

Peut on toujours actuellement vous solliciter concernant cette bibliothèque ?

Calibration obligatoire??

Bonjour Marvin,

Bravo pour votre project qui est vraiment cool et correspond à mon besoin.

J'ai une question/demande car je rencontre un léger problème.
En effet j'ai des reboot aléatoire de module surement du à mon installation électrique.
Le problème est que lors du reboot les volets se calibre... Imaginez ma femme à se moment la :)
J'aimerai savoir si il était possible de se passer de la calibration quand le module est déja en place.
En effet, la position du volet est stockée dans l'epromm il me semble. On pourrais imaginer que si la valeur de l'epromm est nul ( du à nouvelle installation) calibration sinon pas de calibration...

Pensez-vous que cela sois réalisable?

Merci d'avance.

Marmoul

Manually control UP and DOWN

Hi, thanks for this awesome library, I'm starting to play with it.

Is there any way to manually control de UP and DOWN movements from a button? I would like to have both options:

  • Set a desire % level from an app.
  • Manually push a button to control the shutters. In this case I would like to track the level.

I have tried to use the shutters._up() function by making it public, but no luck at all.
Thanks

Besoin d'aide

Salut,

Je me retrouve confronté à un problème de débutant, j'ai besoin de commander plusieurs volets avec mon arduino, pour ça j'ai besoin d'ajouter une fonction, je nage...peut être plus compréhensible avec ça:

`#include <Shutters.h>

const unsigned long courseTime = 30 * 1000;
const float calibrationRatio = 0.1;

const char Volet[] = {"shutters", "shutters2"};

void shuttersUp() {
Serial.println("Shutters going up.");
// TODO: Implement the code for the shutters to go up
}

void shuttersDown() {
Serial.println("Shutter1 going down.");
// TODO: Implement the code for the shutters to go down
}

void shuttersHalt() {
Serial.println("Shutters halted.");
// TODO: Implement the code for the shutters to halt
}

uint8_t shuttersGetState() {
return 255;
}

void shuttersSetState(uint8_t state) {
Serial.print("Saving state ");
Serial.print(state);
Serial.println(".");
}

void onShuttersLevelReached(uint8_t level) {
Serial.print("Shutters at ");
Serial.print(level);
Serial.println("%");
}

Shutters shutters(courseTime, shuttersUp, shuttersDown, shuttersHalt, shuttersGetState, shuttersSetState, calibrationRatio, onShuttersLevelReached);

void setup() {
Serial.begin(9600);
shutters.begin();

Volet[1].setLevel(50); // Go to 50%
}

void loop() {
shutters.loop();
} sketch_jul10b:6: error: too many initializers for 'const char []'

const char Volet[] = {"shutters", "shutters2"};

                                          ^

C:\Users\ludo\Documents\Arduino\sketch_jul10b\sketch_jul10b.ino: In function 'void setup()':

sketch_jul10b:45: error: request for member 'setLevel' in 'Volet[1]', which is of non-class type 'const char'

Volet[1].setLevel(50); // Go to 50%

        ^

exit status 1
too many initializers for 'const char []'

`
Pouvez vous m'aider?

Detecting multiple clicks returns wrong values

Hello,

first thanks for this great library which saves me a lot of time for developing my smart home shutter control.
I try to detect and count multiple clicks of a button, but the results for multiple clicks > 2 are not correct, while detecting single and double clicks works correctly.
This is my code:

`
rollo1_taster_hoch = OneButton(
CONTROLLINO_A0, // Input pin for the button
false, // Button is active high
true // Enable internal pull-up resistor
);
rollo1_taster_hoch.attachMultiClick(handleMultiClick);

static void handleMultiClick(OneButton *oneButton) {
Serial.print("Number of clicks: ");
Serial.print(oneButton->getNumberClicks());
if(oneButton->getNumberClicks() == 5) {
Serial.println("5 klicks");
}
}

`
For 3 clicks the serial output is: "Number of clicks 55"
For 4 clicks: Number of clicks 0
For 5 clicks: Number of clicks 768
For 6 clicks: Number of clicks 771

These values are reproducible when clicking the same number of times again.

Does anyone have an idea what could cause these wrong values?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.