I would have put this in the Exhibition/Gallery section of the forum but it does not seem to be very active. If the mods think that it should be moved then please go ahead and move it.
Despite having used the Arduino for a while I have never really investigated the OOP ability of C++ beyond using libraries provided with the IDE and others available for installation.
With that in mind I set about creating a class and putting it in a library, but what should I create ? I decided that I would create a library that allowed an output pin to toggle between HIGH and LOW with the time in each state defined by the user. I hope that it goes without saying that the code is non blocking and that it uses millis() for timing.
Having created the basic class and library I could not resist adding functionality to it and the result is the following set of functions which includes the ability to toggle the output pin a user defined number of times and to set and get the state of the output pin within the context of the object. ie setting the state stops the object toggling unlike doing it with digitalWrite()
pinToggle functions
---------------------
pinToggle();
Call this to name and create the pinToggle object.
init();
Set up pinMode(byte pin)
Parameters : pin the pin number assotiated with the object
startToggling(byte state, unsigned long lowPeriod, unsigned long highPeriod, unsigned int toggleCount = 0);
Start toggling the pin state
Parameters : state the initial state of the pin (HIGH or LOW)
lowPeriod the period in milliseconds that the pin should be LOW
highPeriod the period in milliseconds that the pin should be HIGH
toggleCount the number of times the pin should toggle before stopping. Zero (default) to disable the count and toggle continuously
restartToggling();
Restart toggling the pin state with the original parameters
update();
Update the state of the pin if the current period has ended
setOutputState(byte state);
Set the output state for the pin and stop toggling
Parameters : state the state (HIGH or LOW) into which the pin should be put
getOutputState();
Get the current state of the output
stopToggling(byte state);
Stop toggling and go into the specified state
Parameters: state the state into which the pin should be put (HIGH or LOW)
resumeToggling();
Resume toggling from where it was stopped
getTogglingState();
Get toggling state (true or false)
getToggleCount();
Get the number of toggles remaining
The more functions that I added the easier it became and the more that I could see the advantages of OOP. What fun !
Here are the library files
pinToggle.h
/*
pinToggle.h - control pin toggling
Created by Bob Burton, 25/03/2018
*/
#ifndef pinToggle_h
#define pinToggle_h
#include "Arduino.h"
class pinToggle
{
private:
byte _pinNum;
byte _startState;
byte _startStartState;
unsigned long _startLowPeriod;
unsigned long _startHighPeriod;
unsigned int _toggleCount;
unsigned int _startToggleCount;
boolean _started = false;
unsigned long _periods[2];
byte _periodIndex;
unsigned long _startTime;
unsigned long _currentTime;
boolean _toggling = false;
byte _currentState;
boolean _counting;
public:
pinToggle(); //constructor
init(byte pin); //set pinMode
startToggling(byte state, unsigned long lowPeriod, unsigned long highPeriod, unsigned int toggleCount = 0); //set initial state and periods
restartToggling(); //restart toggling with original parameters
update(); //check whether period has ended and change state if true
setOutputState(byte state); //set the output state for the pin and stop toggling
getOutputState(); //get the current state of the output
stopToggling(byte state); //stop toggling and go into the given state
resumeToggling(); //resume toggling
getTogglingState(); //get toggling state
getToggleCount(); //get the number of toggles remaining
};
#endif
pinToggle.cpp
/*
pinToggle.cpp - control pin toggling
Created by Bob Burton, 25/03/2018
*/
#include "Arduino.h"
#include "pinToggle.h"
pinToggle::pinToggle() //constructor
{
}
pinToggle::init(byte pin)
{
_pinNum = pin;
pinMode(_pinNum, OUTPUT);
}
pinToggle::startToggling(byte startState, unsigned long lowPeriod, unsigned long highPeriod, unsigned int toggleCount = 0) //set initial state, periods and count
{
_startStartState = startState;
_startLowPeriod = lowPeriod;
_startHighPeriod = highPeriod;
_startToggleCount = toggleCount;
if (toggleCount == 0)
{
_counting = false;
}
else
{
_counting = true;
}
_toggleCount = toggleCount;
_startState = startState;
_periods[0] = lowPeriod;
_periods[1] = highPeriod;
if (_startState == LOW)
{
_periodIndex = 0;
}
else
{
_periodIndex = 1;
}
_currentState = _startState;
digitalWrite(_pinNum, _currentState);
_startTime = millis();
_toggling = true;
_started = true;
}
pinToggle::restartToggling() //restart toggling with original parameters
{
if (_started)
{
startToggling(_startStartState, _startLowPeriod, _startHighPeriod, _startToggleCount);
}
}
pinToggle::update() //check whether period has ended and change state if true
{
if (!_toggling) //no need to update if not currently toggling
{
return;
}
_currentTime = millis();
if (_currentTime - _startTime >= _periods[_periodIndex])
{
_currentState = !_currentState;
digitalWrite(_pinNum, _currentState);
_periodIndex++;
_periodIndex %= 2;
_startTime = _currentTime;
if (_counting)
{
_toggleCount--;
if (_toggleCount == 0)
{
_toggling = false;
}
}
}
}
pinToggle::getToggleCount()
{
return _toggleCount;
}
pinToggle::stopToggling(byte state)
{
setOutputState(state);
}
pinToggle::setOutputState(byte state)
{
_currentState = state;
digitalWrite(_pinNum, _currentState);
_toggling = false;
}
pinToggle::getOutputState()
{
return _currentState;
}
pinToggle::resumeToggling()
{
if (_started)
{
_toggling = true;
}
}
pinToggle::getTogglingState()
{
return _toggling;
}
A small sketch to test the majority of the functions
#include <pinToggle.h>
pinToggle output1;
pinToggle output2;
pinToggle output3;
pinToggle output4;
int previousToggleCount;
int currentToggleCount;
void setup()
{
Serial.begin(115200);
output1.init(13);
output2.init(12);
output3.init(11);
output4.init(10);
output1.startToggling(HIGH, 500, 100);
output2.startToggling(HIGH, 500, 111);
output3.startToggling(HIGH, 1000, 1000, 10);
output4.setOutputState(LOW);
}
void loop()
{
output1.update();
output2.update();
output3.update();
output4.update();
previousToggleCount = currentToggleCount;
currentToggleCount = output3.getToggleCount();
if (currentToggleCount != previousToggleCount)
{
Serial.print("Toggle count : ");
Serial.println(output3.getToggleCount());
}
if (currentToggleCount == 0)
{
output3.restartToggling();
output4.setOutputState(!output4.getOutputState());
}
}
I would welcome any comments on the library both on how it is written and the functions provided so that I can improve it/fix it and possibly add to it.
Actually, that is a lie. What I really want is for everyone to say that it is perfect and cannot be improved on but I assume that is not the case !
Many thanks in advance