Zkompilovat mi to šlo, ale nemám sil zkoumat co to má dělat, musel jsem do hospody a po těch pivech ....
Kód: Vybrat vše
/*
New stacker ver 1.3 20160907
Based on original by Peter Mobbs (thankyou)
Important plug in camera AFTER switch on & initialization
Modifications by David Marsden to suit ROBOT LCD shield
Delay time fixed at 5 seconds
camera pin changed to 0
enable pin changed to 1
dir pin changed to 2
drive (step) changed to 3
flash not used (always set camera to X sync)
delay in line 430 changed from 100 to 1000
Changed jog speeds - slow = 1600, fast = 800
Changed direction of fast jog, case 1 is -, case 3 is +
Speed in stack movement changed to 1600
Delay between shutter high & low changed to 1000
Distance input changed to mm
Accumulators changed to symetrical for & rev, 10 fast & 1 slow
Directions changed to suite position on bread board,
Various tidy ups
*/
#include <LiquidCrystal.h>
LiquidCrystal lcd( 8, 9, 4, 5, 6, 7 ); //Pins used by LCD
// Global variables
int adc_key_val[5] ={50, 200, 400, 600, 800 }; // These are the values returned by the adc for different button presses
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;
int jog_speed;
int rail_direction = 0;
//Pins that will be used to control the rail and the camera
// changed from original to give tidy cable run from shield to easydriver board
int camera_pin = 0;
int enable_pin = 1;
int dir_pin = 2;
int drive_pin = 3;
//int flash_pin = 16;
int number_photos =0;
int distance = 0;
int delay_time = 6000; //miliseconds.
int k = 0;
int keep[4] ={0,0,0,0}; // Only really need four members to array because not using zero member!
/*
START-UP, display setup, signs on, gives basic info etc.
*/
void setup()
{
/*
Set motor off & shutter off
*/
pinMode(enable_pin,OUTPUT);
digitalWrite(enable_pin, HIGH);
//set camera pin low (shutter off)
pinMode(camera_pin,OUTPUT);
digitalWrite(camera_pin, LOW);
/*
Sign-on
*/
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" MadBoffin Labs ");
lcd.setCursor(0,1);
lcd.print(" 5th Oct 2014 ");
delay(1500);
/*
Program name
*/
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" STEPPER RAIL ");
delay (1500);
/*
Instructions
*/
//for (char k=0;k<16;k++)
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Use buttons to ");
lcd.setCursor(0,1);
lcd.print("change values ");
delay (1500);
//
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" To end entries ");
lcd.setCursor(0,1);
lcd.print(" press <Select> ");
delay (1500);
lcd.clear();
}
/*
// Jog or Stack menu - never ending loop
*/
void loop()
{
pinMode(enable_pin,OUTPUT);
digitalWrite(enable_pin, HIGH); // motor off at return from stacker or jogger
//
lcd.print(" Stack or Jog? ");
lcd.setCursor(0,1);
lcd.print(" L=Stack, R=Jog ");
//
which_button(key);
switch (key){
//
case(3):
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Calling Stacker ");
delay(1500);
digitalWrite(enable_pin, LOW); // motor on
stacker();
break;
//
case(0):
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Calling Jogger ");
delay(1500);
digitalWrite(enable_pin, LOW); //motor on
jogger();
break;
}
}
//STACKER routine gets button presses and adds up values ascribed to them to give an accumulated answer
void stacker()
{
int stop_flag_dir_stack = -1;
int stop_flag=1;
int long accumulator = 0;
int function = 1;
rail_direction = 0;
number_photos = 0;
distance = 0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Camera away -R");
lcd.setCursor(0,1);
lcd.print("Camera toward -L");
//Get a keypress and debounce it.
do{
which_button(key);
switch (key){
//
case 3: //left button
rail_direction = -1;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Camera moving ");
lcd.setCursor(0,1);
lcd.print(" Towards ");
delay(1000);
stop_flag_dir_stack = 1;
break;
//
case 0: //right button
rail_direction = 1;
lcd.clear();
lcd.setCursor(0,0);
//
lcd.print("Camera moving ");
lcd.setCursor(0,1);
lcd.print(" Away ");
delay(1000);
stop_flag_dir_stack = 1;
break;
}
//
}while (stop_flag_dir_stack != 1);
do{
lcd.clear();
lcd.setCursor(0,0);
switch(function){
//
case 1:
lcd.print("No. of photos? ");
break;
//
case 2:
lcd.print("Distance in mm? ");
break;
//
}
which_button(key);
// Turn button presses into values
switch (key){
case 0:
accumulator = accumulator - 1;
break;
case 3:
accumulator = accumulator + 1;
break;
case 1:
accumulator = accumulator + 10;
break;
case 2:
accumulator = accumulator - 10;
break;
case 4:
stop_flag = stop_flag+1;
keep[function] = accumulator;
lcd.setCursor(0,1);
//
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("Using: ");
lcd.print(keep[function]);
delay(1000);
function = function + 1;
accumulator = 0;
break;
}
// Sets lower limit
if (accumulator <= 0){
accumulator=0;
}
if (function != 4){
lcd.setCursor(0,1);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print(accumulator);
delay(100);
}
}while (stop_flag <=2);
number_photos = keep[1];
keep[1] =0;
distance = keep[2];
distance=distance*100;
keep[2] =0;
motor_driver(rail_direction, number_photos, distance, delay_time);
}
/*
// WHICH BUTTON routine - returns debounced key
*/
int which_button (int a)
{
adc_key_in = analogRead(0);
key = get_key(adc_key_in);
if (key != oldkey){
delay(30);
adc_key_in = analogRead(0);
key = get_key(adc_key_in);
oldkey=key; // position?
return (key);
}
}
/*
// Convert ADC value from A0 to key number/button press
*/
int get_key(unsigned int input)
{
int k;
for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
{
return k;
}
}
if (k >= NUM_KEYS)k = -1; // No valid key pressed
return k;
}
/*
JOGGER routine - gets buttons and attributes values to them.
Then call jog_motor routine to move the rail.
'Up' and 'Down' buttons are fast jog away & towards
'Left' and 'Right' buttons will be slow jog away and towards.
*/
void jogger()
{
// First tell user what the buttons do
int jog_stop_flag = 0;
jog_speed =0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("L=Towards R=Away");
lcd.setCursor(0,1);
lcd.print("U=Towards D=Away");
delay(3000);
//
/*lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Use <Select> ");
lcd.setCursor(0,1);
lcd.print("to exit to menu ");
*///delay(1500);
/*
lcd.clear();
lcd.setCursor(0,0);
lcd.print("OK ready to jog!");
*/
//now get key presses
do{
which_button(key);
// Now get speed and direction for jog and call jog_motor
switch (key){
case 0://Slow
jog_speed = - 3200;
jog_motor(jog_speed);
break;
case 3://Slow
jog_speed = + 3200;
jog_motor(jog_speed);
break;
case 1://Fast
jog_speed = + 800;
jog_motor(jog_speed);
break;
case 2://Fast
jog_speed = - 800;
jog_motor(jog_speed);
break;
case 4:
// stop jog
jog_stop_flag = 1;
break;
}
}while (jog_stop_flag != 1);
}
/*
JOG MOTOR routine - jogs the motor via EasyDriver
*/
int jog_motor(int a)
{
pinMode(dir_pin,OUTPUT);
pinMode(drive_pin,OUTPUT);
pinMode(camera_pin, OUTPUT);
digitalWrite(dir_pin,LOW);
digitalWrite(drive_pin,LOW);
// Set direction and then drive motor at with jog_speed microsecond delays between pulse phases
if (jog_speed <= 0){
digitalWrite(dir_pin,HIGH);
jog_speed = jog_speed * -1;
}
digitalWrite(drive_pin,LOW);
delayMicroseconds(jog_speed);
digitalWrite(drive_pin,HIGH);
delayMicroseconds(jog_speed);
}
/*
MOTOR DRIVER routine - moves the motor via EasyDriver and activates camera to produce a photo stack
The value of [steps_per_micron] is crucial for absolute accuracy and needs to be set by moving the rail
and seeing how far it actually travels.
0.5 steps per micron gives 10mm movement per 10mm set
*/
int motor_driver(int a, int b, int c, int d)
{
float steps_per_micron = 0.5;
long int steps_between_photos;
long int distance_between_photos;
long int total_steps;
int carry_direction;
pinMode(dir_pin,OUTPUT);
pinMode(drive_pin,OUTPUT);
pinMode(camera_pin, OUTPUT);
//pinMode(flash_pin, OUTPUT);
digitalWrite(dir_pin,LOW);
digitalWrite(drive_pin,LOW);
distance_between_photos= distance/(number_photos -1);
steps_between_photos = (float)distance_between_photos / steps_per_micron; // check loss of precision!
//
//Display parameters###########################################
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Motion= ");
if (rail_direction == 1){
lcd.print("Away");
}
if (rail_direction == -1){
lcd.print("Towards");
}
lcd.clear();
lcd.setCursor(0,0);
//lcd.print("Photos= ");
lcd.print("No of photos= ");
lcd.print(number_photos);
delay (1000);
lcd.setCursor(0,1);
lcd.print("Dist = ");
lcd.print(distance/100);
lcd.print("mm");
delay (1500);
//head off in the right direction!
if (rail_direction == -1){
digitalWrite(dir_pin, LOW);
}
if (rail_direction == 1){
digitalWrite(dir_pin, HIGH);
}
//set camera_pin high - first photo is where the rail is now
//tell operator taking first photo
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Photo #: 1 ");
lcd.setCursor(0,1);
lcd.print("In stack of: ");
lcd.print(number_photos);
digitalWrite(camera_pin, HIGH);
//digitalWrite(flash_pin, HIGH);
delay(1000);
digitalWrite(camera_pin, LOW);
//digitalWrite(flash_pin, LOW);
//Take subsequent photos
for (int x_count_photos = 1; x_count_photos <= number_photos-1; x_count_photos++){
//move rail position by steps_between_photos
//motor speed is set by delays...going slowly to avoid lost steps...
for(int y_count_steps = 1; y_count_steps <= steps_between_photos; y_count_steps++){
//move camer
digitalWrite(drive_pin,LOW);
delayMicroseconds(1600);
digitalWrite(drive_pin,HIGH);
delayMicroseconds(1600);
}
//Wait a while for camera to stabilise
delay(delay_time);
//Tell user which photo is being taken
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Photo #: ");
lcd.print(x_count_photos + 1);
lcd.setCursor(0,1);
lcd.print("In stack of: ");
lcd.print(number_photos);
// take the photo and set flash_pin high with camera_pin long enough to trigger camera
digitalWrite(camera_pin, HIGH);
//digitalWrite(flash_pin, HIGH);
delay(1000);
digitalWrite(camera_pin, LOW);
//digitalWrite(flash_pin, LOW);
/*
lcd.print(x_count_photos + 1);
lcd.setCursor(0,1);
lcd.print("In stack of: ");
lcd.print(number_photos);
*/
}
// End of stack
delay(2000);// so you can see the last value for photo number
//
//Rewind the slider to the starting point by reversing rail_direction and going back total number of steps in stack
//
//Warn that rewind about to take place..
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Rewinding ");
carry_direction = rail_direction;
if (carry_direction == -1){
digitalWrite(dir_pin,HIGH);
}
if (carry_direction == 1){
digitalWrite(dir_pin,LOW);
}
//digitalWrite(dir_pin, rail_direction);
total_steps = (number_photos -1) * steps_between_photos;
for (int x_count_rewind=1; x_count_rewind <= total_steps; x_count_rewind ++){
digitalWrite(drive_pin, LOW);
delayMicroseconds(800);
digitalWrite(drive_pin, HIGH);
delayMicroseconds(800);
}
lcd.clear();
}