Hi. Completely noob question - confused. In the code below I want to count the number of void loop() iterations then terminate by setting all pins LOW. I need to make sure that all is 'dead' before switching off the power to the board.
I have adapted this sketch from a previous project in which switches were sensed. This program will run for hours in the middle of the night unattended - imaging the stars on an equatorial mount. Yet to write the code for wake - for the time being an external timer.
I don't think I understand the while and for expressions - try as I may - either the process terminates after 1 iteration or keeps going or terminates after 5 iterations where I have a constant of 3 (I have not been able to replicate this last behaviour).
// only the relevant stuff
const int iterations = 3;
int var = 0;
void loop(){
// Locks up camera mirror, waits then opens camera shutter, takes shot, then a stepper repositions the camera for next shot - this all works fine.
// Now I want to terminate camera and stepper activation by setting all pins low.
}
for (var=0; var < iterations; var++);{
// this where I get stuck - something in here to set all pins LOW and stop all processes
// based on number of iterations declared...
}
// set all pins LOW here.
}
}
while and for loops behave similarly but their syntax is different.
From the Arduino reference:
"while loops will loop continuously, and infinitely, until the expression inside the parenthesis, () becomes false. "
"The for statement is used to repeat a block of statements enclosed in curly braces. An increment counter is usually used to increment and terminate the loop. " What do you get confused about?
corrections:
const int iterations = 3;
int var = 0;
void loop(){
// Locks up camera mirror...
// Now I want to terminate ...
} /* You're closing the void loop here, remove it. did the compiler thrown an error? */
/*/// remove the semicolon after the closing parenthesis in the for declaration //////// */
for (var=0; var < iterations; var++);{
// this where I get stuck - something in here to set all pins LOW and stop all processes
// based on number of iterations declared...
}
// set all pins LOW here.
}
} /*////// not needed, remove //////*/
since you cannot exit the 'void loop()' you can use an infinite loop at the end of your code, after turning off everything. like so, while(true){ };.
The problem here is the Arduino is not running standard C - there's no main() visible in a sketch. Instead, you get one call of setup(), followed by a repeated call to loop() - so everything outside of these functions is ignored, unless you call it from inside (like a function).
If I misunderstood, and the line with var is meant to be inside loop(), then the problem is how to trigger it - do you want to use a switch, a timer, etc.? You could easily add a switch, and when it is detected, set all the pins to low and loop endlessly - the closest thing the Arduino has to exit().
My apologies. Here is the full sketch comments and all. I'm self taught and this is my second production sketch. I'm sure that it can do with polish.
Thanks for the feedback. I have tried the examples provided without success. Use of while statements exits the loop on the first iteration.
Given that this sketch is fairly simple and only needs to shutdown after a prescribed period of time, I have adapted the blink without delay script. The only criteria needed to define the number of exposures is how long the board has been running.
Number of frames could also be used. I've tried both methods without success, and for, while, switch, goto, break..
Thanks again.
#include <Stepper.h>
/*Ditherbot/Sparehand. Adapted from DoubleArmDrive sketch 2007 -
http://www.synergous.com
This sketch automates multiple long exposure imaging using a
Canon DSLR Camera and stepper driven Ditherbot/Sparehand, pressing
4 pushbutton switches on the hand controller of an equatorial mount.
I want to keep it in its original condition.
The image sequencing and dithering is independent of any equatorial
mount electronics/software and hardware, which is negatively earthed -
an antique.
Dithering - moving the camera between shots so that subsequent images
does not fall on the same sensor pixels - improves image quality.
The Ditherbot/Sparehand repositioning in RA and DEC, between exposures.
The stepper motor is bipolar - some rewriting will be needed for
3 wire reluctance motors out of CDROM drives. Unipolars
require different electronics.
A pdf of the very basic motor shield (PCB) can be downloaded from
http://www.synergous.com - see the Double Arm Drive page - its near
the bottom of the page under the Electronics sub-heading.
Change the next 5 lines as required for motor resolution, session time, exposure,
mirror delay and dither speed. It should only be necessary to change session time
thereafter.
Rule of thumb, timing not critical - e.g 8 x 7 minute exposures provides 30 seconds
between exposures per hour; that is, 32 frames in 4 hours - set for 4 hours 15 minutes
for full 4 hours of exposure.
*/
//change number of motor steps to suit motor
#define motorSteps 200
//change the session time
long sessiontime = 10000;
//change this line to set exposure time.
int exposuretime = 2000; //milliseconds
//change this line to set mirror delay
int mirrordelay = 1000;
//change this line to set dither speed
int ditherspeed = 10;
long previousMillis = 0;
int shutterPin = 8;
int mirrorPin = 11;
bool exposing = false;
//Stepper
#define motorPin1 4
#define motorPin2 5
#define motorPin3 6
#define motorPin4 7
//initialize stepper library
Stepper stepper(motorSteps, motorPin1,motorPin2,motorPin3,motorPin4);
//LED
int ledPin = 13; //on indicates dithering in progress
void setup() {
pinMode(shutterPin, OUTPUT);
pinMode(mirrorPin, OUTPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
{
digitalWrite(mirrorPin, HIGH);
delay(mirrordelay);
digitalWrite(shutterPin, HIGH);
exposing = true; //shutter open - probably superfluous
if (exposing == true) //safe guard - probably superfluous
{ //no dither
stepper.setSpeed(0); // just don't want the stepper moving
stepper.step(0); // it's stationary anyway - think about removing these lines
digitalWrite(ledPin, LOW);
delay(exposuretime);
}
digitalWrite(shutterPin, LOW);
digitalWrite(mirrorPin, LOW);
exposing = false;
if (exposing == false) //shutter closed - same superfluous?
{ //dither
digitalWrite(ledPin, HIGH);
stepper.setSpeed(5);
stepper.step(50);
}
unsigned long currentMillis = millis();
if(currentMillis - previousMillis > sessiontime)
{
digitalWrite(shutterPin, LOW);
digitalWrite(mirrorPin, LOW);
stepper.setSpeed(0);
stepper.step(0);
}
}
}
The while(1) { } here will just loop forever, until you shut down/reset your Arduino.
I have tried this several ways.
the offending line appears to be
unsigned long currentMillis = millis();
//placed here the loop terminates after 2 iterations.
unsigned long currentMillis = millis();
// pin setting prior to while is redundant
if (currentMillis - previousMillis > sessiontime)
while (1) {
}
}
}
}
}
// written this way the loop continues
if (currentMillis - previousMillis > sessiontime)
while (1) {
}
}
}
}
}
All I want to do is check the time the board has been running and terminate the process once the session time is up.
The problem here is the Arduino is not running standard C - there's no main() visible in a sketch. Instead, you get one call of setup(), followed by a repeated call to loop() - so everything outside of these functions is ignored, unless you call it from inside (like a function).
But of course we can call our own main() from setup()
void setup()
{
myMain();
}
void loop() {}
or change main.cpp - C:\Program Files (x86)\arduino-0022\hardware\arduino\cores\arduino - into something completely different ... e.g.
#include <WProgram.h>
int main(void)
{
bool stopLoop = false;
while (true)
{
init();
setup();
for ( ;stopLoop == false ; ) loop();
stopLoop = false;
postMortem();
}
return 0;
}
and you have the ability to exit loop by setting stopLoop to true ... the application will call postMortem once and if postMortem() exits it start again.
Actually, stepping away from the problem, I can see that I've made things difficult for myself. It's very simple - thanks David.
The board will not stop while the stepper is active - a session time of 30 seconds means a board time of ~34 seconds with delays. This is accounted for in the imaging run, with significant delays between exposures.
Thanks again
#include <Stepper.h>
Change the next five lines as required
*/
//change number of motor steps to suit motor
#define motorSteps 200
//change number of frames to shoot
long sessiontime = 30000;
//change this line to set exposure time.
int exposuretime = 2000; //milliseconds
//change this line to set mirror delay
int mirrordelay = 1000;
//change this line to set dither speed
int ditherspeed = 10;
long unsigned time;
int settle = 1000;
int shutterPin = 8;
int mirrorPin = 11;
bool exposing = false;
//Stepper
#define motorPin1 4
#define motorPin2 5
#define motorPin3 6
#define motorPin4 7
//initialize stepper library
Stepper stepper(motorSteps, motorPin1,motorPin2,motorPin3,motorPin4);
//LED
int ledPin = 13; //if its on dithering is in progress
void setup() {
pinMode(shutterPin, OUTPUT);
pinMode(mirrorPin, OUTPUT);
pinMode(ledPin, OUTPUT);
}
void loop() {
{
digitalWrite(mirrorPin, HIGH);
delay(mirrordelay);
digitalWrite(shutterPin, HIGH);
delay(exposuretime);
}
digitalWrite(shutterPin, LOW);
digitalWrite(mirrorPin, LOW);
exposing = false;
if (exposing == false) //shutter closed
{ //dither
digitalWrite(ledPin, HIGH);
stepper.setSpeed(5);
stepper.step(50);
delay(settle);
{
time = millis(); // time board has been running
if (time >= sessiontime) // this only works with >= for this application
while(1){
}
}
}
}
I found that it is possible for the session to end with the camera locked into an exposure. Also, I've used long unsigned time for the delays, because int doesn't handle the long times required of this program. long works too - does it really matter - there are no negative numbers to consider as far as timing is concerned.
The sketch finished up looking like this.
#include <Stepper.h>
Change the next five lines as required
*/
//change number of motor steps to suit motor
#define motorSteps 200
int steps = 50;
int rpm = 5;
//change sessiontime =
// (exposuretime+mirrordelay+motortime+printdelay)*exposures
// dithering time = 3000; time print delay = 1000;
long unsigned sessiontime = 15408000;
//change this line to set exposure time.
long unsigned exposuretime = 420000; //milliseconds
//change this line to set mirror delay
long unsigned mirrordelay = 4000;
//change this line to set dither speed
long unsigned time;
int shutterPin = 8;
int mirrorPin = 11;
bool exposing = false;
//Stepper
#define motorPin1 4
#define motorPin2 5
#define motorPin3 6
#define motorPin4 7
//initialize stepper library
Stepper stepper(motorSteps, motorPin1,motorPin2,motorPin3,motorPin4);
//LED
int ledPin = 13; //if its on dithering is in progress
void setup() {
pinMode(shutterPin, OUTPUT);
pinMode(mirrorPin, OUTPUT);
pinMode(ledPin, OUTPUT);
Serial.begin(115200);
}
void loop() {
{
digitalWrite(mirrorPin, HIGH);
delay(mirrordelay);
digitalWrite(shutterPin, HIGH);
delay(exposuretime);
}
digitalWrite(shutterPin, LOW);
digitalWrite(mirrorPin, LOW);
exposing = false;
if (exposing == false) //shutter closed
{ //dither
digitalWrite(ledPin, HIGH);
stepper.setSpeed(rpm);
stepper.step(steps);
{
Serial.print("Time: ");
time = millis();
Serial.println(time);
delay(1000);
time = millis();
if (time >= sessiontime)
{
digitalWrite(shutterPin, LOW);
digitalWrite(mirrorPin, LOW);
{
while(1){
}
}
}
}
}
}