mlucius291:
Hello all,
We are doing some research and need some help designing a contraption of sorts. We are in a bit of a time crunch. We are ecologist and are not the very knowledgeable with Arduino so any help you could offer is greatly appreciated.
We need a to make a stepper motor turn 180 degrees (100 steps) with a rainfall sensor when rainfall is detected (not sure on exact 0-1023 value, but will determine that later). Then, when the rain stops, the motor returns to its original position.
Thank you for looking,
Mark
You will have to either have a 'home' position switch, or a physical motion stop to create a 'starting' point for the motion. If you have a switch, you must monitor the switch during each movement, with a mechanical stop you just drive the motor against the stop for the maximum possible number of movement steps. Personally I like the switch method better. for code simplicity I will ignore home position.
Configure the Driver for 1 step per pulse.
enable -> pin D2
dir -> pin D3
pulse -> pin D4
rainSensor -> D5
abortswitch -> D6
#define ENABLEPIN 2
#define DIRPIN 3
#define PULSEPIN 4
#define ABORTPIN 6
#define RAINPIN 5
#define ACTIVEPOSITION 100 // directed distance to inuse position
#define ABORTLED LED_BUILTIN // usually 13
static int position=0; // starts out at home
static short speed=10; // 10 steps per second
static int direction=0; // 1= direction1, -1=direction2, 0=motor off
static bool aborted=false;
bool stop(){
if(digitalRead(ABORTPIN)) {
if(not aborted){ // just detected abort signal
Serial.println("ABORT DETECTED!");
}
digitalWrite(ABORTLED,HIGH);
aborted=true;
}
if(aborted) {// disable motor driver
digitalWrite(ENABLEPIN,LOW);// force motor controller OFF
}
return aborted;
}
void moveOneStep(){
unsigned long stepTime=(1000 / speed)/2; // drive pulse will be 1/2 step high,low
unsigned long timeout = millis();
if(!stop()){ // if not aborted, send pulse
digitalWrite(PULSEPIN,HIGH);
if(!aborted){ // pulse has been send, adjust position
position = position + direction;
}
while((!stop())&&((millis()-timeout)<stepTime)) ; // twiddle fingers waiting
digitalWrite(PULSEPIN,LOW);
timeout = timeout + stepTime; // other half
while((!stop())&&((millis()-timeout)<stepTime)) ; // twiddle fingers waiting
}
}
void setDirection(int dirIn){
direction = dirIn;
switch(direction){
case 0 : // no movement, release motor
digitalWrite(ENABLEPIN,LOW); // de select motor
digitalWrite(PULSEPIN,LOW); // ready for next motion
break;
case 1 : // move in direction 1
digitalWrite(PULSEPIN,LOW); // ready for next motion
digitalWrite(DIRPIN,LOW); // Select correct direction 1
if(!stop()) digitalWrite(ENABLEPIN,HIGH); // power up driver
break;
case -1 : // move in direction 2
digitalWrite(PULSEPIN,LOW); // ready for next motion
digitalWrite(DIRPIN,HIGH); // Select correct direction 1
if(!stop()) digitalWrite(ENABLEPIN,HIGH); // power up driver
break;
default : //unknow motor direction, just shutdown
aborted = true;
digitalWrite(ENABLEPIN,LOW); // shutdown motor
}
}
void goHome(){
Serial.println("Moving HOME!");
while((position!=0)&&(!stop())){
if(position>0){
setDirection(-1);
moveOneStep();
}
if(position<0){
setDirection(1);
moveOneStep();
}
}
setDirection(0); // release motor drive, power savings. remove if motor needs to hold position
}
void goOpPosition(){
Serial.println("Moving to Position");
while((position!=ACTIVEPOSITION)&&(!stop())){
if(position>ACTIVEPOSITION){
setDirection(-1);
moveOneStep();
}
if(position<ACTIVEPOSITION){
setDirection(1);
moveOneStep();
}
}
setDirection(0); // release motor drive, power savings. remove if motor needs to hold position
}
void configPins(){
pinMode(ENABLEPIN,OUTPUT);
pinMode(ABORTPIN,INPUT_PULLUP); // abort pin is held low for run mode
pinMode(ABORTLED,OUTPUT);
pinMode(DIRPIN,OUTPUT);
pinMode(PULSEPIN,OUTPUT);
pinMode(RAINPIN,INPUT_PULLUP); // rain sensor grounds pin for activation signal
setDirection(direction);
}
void setup(){
configPins();
digitalWrite(ENABLEPIN,LOW); // disable motor drive
Serial.begin(9600); // start up Serial monitor for debug messages
aborted = false;
digitalWrite(ABORTLED,LOW);
digitalWrite(DIRPIN,LOW); // direction 1
digitalWrite(PULSEPIN,LOW); // rising edge is active
Serial.println("Booted at HOME!");
}
static unsigned long timeout=0, movementTimeout=0;
static bool lastRain=false;
void loop(){
if(millis()-timeout>300000L) {
configPins(); // every 5 minutes reconfig in case static event
if(aborted) Serial.println("Abort has Been Detected, clear Abort Switch, Reboot");
}
if(!stop()){ // check rainfall switch
if((lastRain!=digitalRead(RAINPIN))&&
(millis()-movementTimeout>30000L)){ // different rain sensor position, and 30seconds since last movement
Serial.println(" Moving! ");
configPins();
lastRain=digitalRead(RAINPIN);
if(lastRain) goHome();
else goOpPosition();
movementTimeout=millis(); // start next movement timeout
}
}
}
have fun, you need to add some home position detection, I'm just counting steps from an unknown starting position.
chuck