#include <Arduino.h>
enum class State :uint8_t {
noop,
wait,
state1,
state2,
state3
};
State nextState;
State state;
uint32_t prevTime = millis();
uint32_t currentTime = millis();
uint32_t waitDelay;
void setup() {
Serial.begin(9600);
}
void nextStateAfter(State ss, uint32_t d) {
waitDelay = d;
nextState = ss;
state = State::wait;
prevTime = currentTime;
}
void loop() {
currentTime = millis();
switch (state) {
case State::noop:
//maybe wait for input? (for now just send anything to serial);
if (Serial.available() > 0) {
Serial.readString();
state = State::state1;
}
break;
case State::wait:
if (currentTime - prevTime > waitDelay) {
state = nextState;
prevTime = currentTime;
}
break;
case State::state1:
nextStateAfter(State::state2, 1000);
Serial.println("state1");
break;
case State::state2:
nextStateAfter(State::state3, 2000);
Serial.println("state2");
break;
case State::state3:
nextStateAfter(State::state1, 3000);
Serial.println("state3");
break;
}
}
typedef void (*myFunction)() ;
class RepeatEvery {
private:
unsigned long currentMillis = millis();
unsigned long prevMillis = currentMillis;
bool prevCanRun = false;
unsigned long lwait;
myFunction lf;
public:
RepeatEvery(myFunction f, unsigned long wait) {
lwait = wait;
lf = f;
}
void handle() {
bool r = true;
handle(r);
}
void handle(bool& canRun, bool reset = true) {
currentMillis = millis();
if (prevCanRun != canRun) {
prevCanRun = canRun;
if (reset == true)
prevMillis = currentMillis;
else
prevMillis = currentMillis - lwait - 1;
}
if (currentMillis - prevMillis >= lwait && prevCanRun == true ) {
prevMillis = currentMillis;
lf();
}
}
};
bool runOnce = true;
bool canRun = true;
// function which depends on external variable
// blink LED_BUILTIN sveral times
RepeatEvery fn([] {
Serial.println("Blink Blink");
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}, 1000);
// function which turns on or of function named "fn"
// disables blinking after 5s and sets LED_BUILDIN to LOW
RepeatEvery repeatAlways([] {
runOnce = false; // stop repeatAlways
canRun = false; // stop fn
digitalWrite(LED_BUILTIN, LOW);
Serial.println("disable blinking");
}, 5000);
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(LED_BUILTIN, OUTPUT);
}
void loop() {
repeatAlways.handle(runOnce);
fn.handle(canRun, true);
}
This sketch waits until button is pressed ( pin 2 connected with ground ) and if button was pressed - blinks LED 3 times.
#include <Arduino.h>
const int LED_PIN = LED_BUILTIN;
const int BUTTON_PIN = 2;
const long blingTimes = 3;
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, LOW);
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
enum {
turn_on,
turn_off,
wait,
};
byte state = wait;
unsigned long prevMillis1 = 0;
const unsigned long delay1 = 1000;
const unsigned long delay2 = 500;
long iteration = 0;
void loop() {
unsigned long currentTime = millis();
if(state == wait) {
if(digitalRead(BUTTON_PIN) == LOW) {
state = turn_on;
iteration=0;
}
}
if (state == turn_on) {
if (millis() - prevMillis1 >= delay1) {
prevMillis1 = currentTime;
digitalWrite(LED_PIN, HIGH);
state = turn_off;
}
}
if (state == turn_off) {
if (millis() - prevMillis1 >= delay2) {
prevMillis1 = currentTime;
digitalWrite(LED_PIN, LOW);
state = turn_on;
iteration++;
if (iteration > blinkTimes) {
state = wait;
}
}
}
}
The class
#include <Arduino.h>
#include <Servo.h>
class AsyncServo
{
Servo servo;
int pos;
int increment;
int incrementBy = 1;
int updateInterval = 10;
unsigned long lastUpdate;
bool done = false;
public:
AsyncServo(int interval =10, int i = 1)
{
updateInterval = interval;
increment = i;
incrementBy = i;
}
// Attach pin to servo
void Attach(int pin)
{
servo.attach(pin);
}
// Detach from servo
void Detach()
{
servo.detach();
}
// Rotate servo to "Home" ( pos = 0);
void Home()
{
if (pos >= 180)
{
done = false;
increment = -incrementBy;
}
}
// Rotate servo to "End" ( pos = 180 );
void End()
{
if (pos <= 0)
{
done = false;
increment = incrementBy;
}
}
// just set servo to some position between 0 and 180;
void setPosition(uint8_t p) {
done = true;
// pos = p; ????
servo.write(pos);
}
// check if servo done its movement
bool Done()
{
return done;
}
// check if servo is at home position: pos = 0;
bool AtHome()
{
return pos <= 0;
}
// asynchroniuosly rotate motor
void Run()
{
if (done)
return;
if ((millis() - lastUpdate) > updateInterval)
{
lastUpdate = millis();
pos += increment;
servo.write(pos);
Serial.println(pos);
if ((pos >= 180) || (pos <= 0))
{
done = true;
return;
}
}
}
};
class usage on arduino UNO / mega ( for others - check for PWM pins )
AsyncServo s1(100, 10); // slow movement
AsyncServo s2(10, 10); // fast movement
void setup()
{
// put your setup code here, to run once:
Serial.begin(9600);
s.Attach(9);
s.Attach(10);
s1.Home();
s2.Home();
}
void loop()
{
s1.Run(); // servo 1 step
s2.Run(); // servo 2 step
if (s1.Done()) // if servo motor stopped
{
if (s1.AtHome()) //check if its position is Home ( 0 )
{
s1.End(); // tell servo motor to rotate to max ( 180 )
}
else
{
s1.Home(); // tell servo motor to rate back to home ( 0 );
}
}
if (s2.Done()) // if servo motor stopped
{
if (s2.AtHome()) //check if its position is Home ( 0 )
{
s2.End(); // tell servo motor to rotate to max ( 180 )
}
else
{
s1.Home(); // tell servo motor to rate back to home ( 0 );
}
}
}
#include <EEPROM.h> // We need this library
#include <Arduino.h> // for type definitions
//We create two fucntions for writing and reading data from the EEPROM
template <class T> int EEPROM_writeAnything(int ee, const T& value)
{
const byte* p = (const byte*)(const void*)&value;
unsigned int i;
for (i = 0; i < sizeof(value); i++)
EEPROM.write(ee++, *p++);
EEPROM.commit(); // comment out on some boards / older versions.
return i;
}
template <class T> int EEPROM_readAnything(int ee, T& value)
{
byte* p = (byte*)(void*)&value;
unsigned int i;
for (i = 0; i < sizeof(value); i++)
*p++ = EEPROM.read(ee++);
return i;
}
Usage
struct {
char ssid[20];
char passwd[20];
} wifiConfig;
void setup() {
// write struct to eeprom
EEPROM_writeAnything(0, wifiConfig);
// read from eeprom to struct
EEPROM_readAnything(0, wifiConfig);
}
Happy using ;)
// led pin
const int ledPin1 = 13;
// button pin
const int buttonPin1 = 2;
// blinking delay
const int interval1 = 500;
bool ledState1;
bool canBlink1;
unsigned long previousMillis1;
void setup() {
pinMode(ledPin1, OUTPUT); // set led pin to output
pinMode(2, INPUT_PULLUP); // button pin set to INPUT with internal PULLUP(default state will be HIGH)
}
void loop() {
unsigned long currentMillis = millis();
bool buttonState1 = digitalRead(buttonPin1);
if (buttonState1 == LOW) {
while (digitalRead(buttonPin1) == LOW);
if (digitalRead(buttonPin1) == HIGH) {
canBlink1 = !canBlink1;
digitalWrite(ledPin1, LOW);
}
}
if (currentMillis - previousMillis1 >= interval1 && canBlink1) {
previousMillis1 = currentMillis;
ledState1 = !ledState1;
digitalWrite(ledPin1, ledState1);
}
}