Also some examples where the external calling program needs to access internal variables and the library functions need to set global variables or something similar.
The examples might be rewritten so that they interact with an LED and a switch perhaps.
I have written a program making time laps photographs and stepping a stepper motor and I am trying to make libraries out of my code with out using spaghetti.
FYI, I wrote a class in the body of my main .ino program but is was very difficult to move it into a .cpp and . h file and fight variable scope. Although I succeeded it was after so much trial and error I can not claim I understand totally what I did.
Where I am now in my growth as a programmer I feel there needs to be more information helping users create classes. Perhaps it is there but I have not found it yet.
The arduino language is C/C++ and the handling of classes in arduino is no different from the general one for the language. In order to understand the topic, any good textbook can be used.
Regarding, "The arduino language is C/C++ and the handling of classes in arduino is no different from the general one for the language. In order to understand the topic, any good textbook can be used."
I am struggling to understand this very thing but I believe there are UNIQUE to the Arduino IDE constraints or methodologies to be "overcome" by the new user. These need to be better explained. Or demonstrated with a series of examples of increasing generality.
I didn't notice those...
Why limit yourself to "explanations classes in arduino" when thousands of excellent books about classes in C++ have been written in the world
the really important thing you really need to know is that the IDE will try to guess which files to include in the compilation / link for you and will also generate forward declaration for functions in the .ino files.
but for classes declaration just go with C++ (a .h and a matching .cpp file or a .hpp file)
Thanks for illustrating the development methodology. It is something like I attempted.
I would summarize it as:
Develop in the main tab ABOVE the setup() and loop() and then move.
I think it is proper that a fuller example would include putting all Class code in a .cpp file.
It is when I did that that move to .h and .cpp I began to fight variable scope with out a clear vision for the end goal.
My class was manipulating some global (which represented hardware states for example) and responding to some user input through globals and when I moved it to a .cpp file much was broken. IIRC I wrote some functions to set member variables to fix some or most of the problems but near the end I was fatigued that I literally was working trial and error clearing error messages with out understanding the big picture.
So I read read the instructions for making the Library for Arduino to which I linked helped me a lot but was not general enough. Thus my request.
this is your big mistake
One of the basic paradigm of the Object Oriented programming is that the class should not use any external data directly (for example as global variables), the one correct way doing it - to use dedicated class methods for input and output data - i.e. "getters" and "setters"
And again, this is nothing Arduino specific - it's all explained in any Object Oriented Programming textbook. I do not consider it correct to state these principles in arduino examples - this material is too extensive and can hardly be presented in a short form. Writing libraries is already beyond the needs of ordinary users, and those who want to go further need to dig into the study of C ++
There is one thing to be aware of. You should should not access hardware in a constructor; so e.g. pinMode should not be used. Reason is that the hardware is not be initialised yet. You will find that classes that access hardware always have a begin (or similar) method.
Here from my .h file is what I believe constitutes the constructor and it does not access the hardware.
If it needs some stones thrown at it please let'm fly.
/*
cameracontrol.h - Library for controling a camera focus and shutter using an open drain on Aruino.
Created by Forrest Lee Erickson
Date: 20220702
Released into the public domain.
*/
// keep from including twice
#ifndef cameracontrol_h
#define cameracontrol_h
#include "Arduino.h"
class WiredCamera {
public:
/* Wiring from Railduino
D6~ /Focus ?ring?
D7 /Shutter ?tip?
*/
// const int EXPOSURE_TIME = 30000; // 30 seconds for time laps
const int EXPOSURE_TIME = 1000; // 1 second for development.
const int nFOCUS = 6; // Pin assignment. Make low to trigger auto focus.
const int nSHUTTER = 7; // Pin assignment. Make low to trigger open shutter.
const int FOCUS_DELAY = 1000; //mSec delay from focus to shutter release.
//long OffTime; // milliseconds of off-time
const long PHOTO2SD = 3000; // milliseconds of time to load photo into SD card
//Set up the pins for this instance.
WiredCamera(int focus_Pin, int shutter_Pin);
void printCameraPins();
void setupCameraWiredInterface();
void setAutoFocus();
void focusAndPhoto();
void makePhoto();
bool updateTimeLaps();
void setExposureTimeSeconds(int seconds);
void printExposureTime();
void setLastExposure(bool isLastExposure);
private:
// int _focusPin = focus_Pin;
// int _shutterPin = shutter_Pin;
int _focusPin = nFOCUS;
int _shutterPin = nSHUTTER;
int _focusDelay = FOCUS_DELAY;
int _exposureTime = EXPOSURE_TIME;
unsigned long _previousMillis = 0; // will store last time LED was
bool _isShutterOpen = false;
bool _isLastExposure = false; //Lets start able to make expsoures.
}; //end of class decleration
#endif
This is the prototype of the constructor. You have a .cpp file as well (I guess) that has the implementation and that is where you should not access the hardware.
/*Wired Camera Control for Focus and Shutter
By Forrest Lee Erickson
Date: 20220701
License: Released into the public domain, dedicated to the public domain
Warrentee: This code is designed to kill you and render the earth uninhabitable but is not guarenteed to do so.
Developed for Canon T3 camera and tested with the same. See my Railduino project too.
*/
#include "Arduino.h"
#include "cameracontrol.h"
/*Wired Camera Control for Focus and Shutter
By Forrest Lee Erickson
Date: 20220701
License: Released into the public domain, dedicated to the public domain
Warrentee: This code is designed to kill you and render the earth uninhabitable but is not guarenteed to do so.
Developed for Canon T3 camera and tested with the same. See my Railduino project too.
*/
//Set up the pins for this instance.
WiredCamera::WiredCamera(int focus_Pin, int shutter_Pin) {
_focusPin = focus_Pin;
_shutterPin = shutter_Pin;
}//end WiredCamera
void WiredCamera::printCameraPins() {
Serial.print("Focus pin: ");
Serial.println(_focusPin);
Serial.print("Shutter pin: ");
Serial.println(_shutterPin);
}//end printCameraPins
/*
Focus and Shutter pins are high impedance at power up. Set for input just to make sure.
Write the ditital output as LOW, but since input the camera is not changed.
To activate foucus or shurter release write pinMode from input to output and then back to input.
*/
void WiredCamera::setupCameraWiredInterface() {
pinMode(_focusPin, INPUT); //Set as input for high impedance.
pinMode(_shutterPin, INPUT); // Set as input for high impedance.
digitalWrite(_focusPin, LOW); // Set for pin low to sink current when low impedance.
digitalWrite(_shutterPin, LOW);
//delay(50);
}//end setupCameraWiredInterface
void WiredCamera::setExposureTimeSeconds(int seconds) {
_exposureTime = 1000 * seconds; //milliseconds for expsoure time.
Serial.print("ExposureTime: ");
Serial.println(_exposureTime/1000);
}//end setExposureTimeSeconds
void WiredCamera::printExposureTime() {
// _exposureTime = 1000 * seconds; //milliseconds for expsoure time.
Serial.print("ExposureTime: ");
Serial.println(_exposureTime/1000);
}//end setExposureTimeSeconds
void WiredCamera::setAutoFocus() {
// Trigger auto focus before photo
pinMode(_focusPin, OUTPUT); // Make low impedance
Serial.print("Focusing! ");
delay(_focusDelay);
pinMode(_focusPin, INPUT); //Make high impedance.
Serial.println("Focus set");
}//end setAutoFocus()
void WiredCamera::focusAndPhoto() {
// Trigger auto focus before photo
pinMode(_focusPin, OUTPUT); // Make low impedance
Serial.print("Focusing! ");
delay(_focusDelay);
pinMode(_focusPin, INPUT); //Make high impedance.
Serial.println("Focus set");
//Shutter release
pinMode(_shutterPin, OUTPUT); // Make low impedance
Serial.print("Shutter release ");
//delay(_focusDelay);
delay(1);
pinMode(_shutterPin, INPUT); //Make high impedance.
}//end focusAndPhoto()
void WiredCamera::makePhoto() {
//Shutter release
pinMode(_shutterPin, OUTPUT); // Make low impedance
Serial.println("Shutter release ");
//delay(_focusDelay);
delay(500);
pinMode(_shutterPin, INPUT); //Make high impedance.
}//end makePhoto()
void WiredCamera::setLastExposure(bool isLastExposure) {
// Make local variable
_isLastExposure = isLastExposure;
}//end setLastExposure()
//Make photo of time _exposureTime. Updates _isShutterOpen returns isTimeLaps
//Need to have this setup ready to go when isTimeLaps becomes true.
bool WiredCamera::updateTimeLaps() {
unsigned long currentMillis = millis();
if ((currentMillis - _previousMillis >= PHOTO2SD) && !_isShutterOpen) {//Card written so make photo.
pinMode(_shutterPin, OUTPUT); // Make low impedance
Serial.println("Shutter open ");
_previousMillis = _previousMillis + PHOTO2SD; // Update the time
_isShutterOpen = true;
return(true); //Shutter not open so we are writing to card.
}//end time has elapsed
else if ((currentMillis - _previousMillis >= _exposureTime) && _isShutterOpen) {
pinMode(_shutterPin, INPUT); //Make high impedance to close.
Serial.println("Shutter closed ");
_previousMillis = _previousMillis + _exposureTime; // Update the time
_isShutterOpen = false;
if (_isLastExposure) {
_isLastExposure = false;
return(false);//Return is time laps
}else {
return(true); //Not yet at last exposure
}//end else if >exposure time and shutter open
}//end isTimeLaps
}//end updateTimeLaps
// };//end WiredCamera class