Hi gang,
New circuit here, driving three stepper motors. Various sensors (switches or LDR) will act as a limit switches to help me set a position=0 reference point for the motors. In the circuit I've built, I'm detecting if the switches are through my measuring on the downside of the switch via an Arduino pin A0-A2.
Unfortunately, if any of the switches is closed, all the sensors read 0, or pulled to ground, making it impossible to get an accurate reading on the other switches. Make sense?
Schematic attached (my first drawing with ExpressSCH...)
What should I change in the circuit so that limit switch/sensor is pulled down independantly?
Thanks,
Peter
If it matters... here's my code so far:
#include <AccelStepper.h>
// Global contstants
const int FullServingPin = A0;
const int FlapLimitPin = A1;
const int FeederLimitPin = A2;
const int FlapDir=1; // Dir valiables can be neg or positive to control direction of the motor
const int FeederDir=1;
const int NumBowls=3;
// Define a stepper and the pins it will use
AccelStepper FlapStepper (4,7,9,6,8); // specifies 4 wires, then pin#'s
AccelStepper AugerStepper (4,3,5,2,4); // specifies 4 wires, then pin#'s
AccelStepper FeederStepper (4,11,13,10,12); // specifies 4 wires, then pin#'s
// Other variables
int OkayToFeed=1; // set to 1 for now. Eventually will be =0, and then set by a schedule in the code
int FlapLimitSwitchValue=0;
int FullServingValue=0;
int FeederLimitSwitchValue=0;
int TurnAuger=1;
int TurnFlap=0;
int TurnFeeder=0;
int Bowl[NumBowls]={
0,750,1500};
int CurrentBowl=0;
int FlapOpen=0;
void setup()
{
// initialize the serial port:
Serial.begin(9600);
// initialize various pins
pinMode(FullServingPin, INPUT);
analogWrite(FullServingPin, LOW);
pinMode(FlapLimitPin, INPUT);
analogWrite(FlapLimitPin, LOW);
pinMode(FeederLimitPin, INPUT);
analogWrite(FeederLimitPin, LOW);
//Initialize flap motor, and zero the position
FlapStepper.setMaxSpeed(600.0);
FlapStepper.setAcceleration(900.0);
do{ // rotate the flap until limit switch reached, and set that as new zero position
FlapStepper.move(-400*FlapDir);
FlapStepper.run();
FlapLimitSwitchValue=analogRead(FlapLimitPin);
// String stringOut = "Flap value: ";
// stringOut = stringOut + FlapLimitSwitchValue;
// Serial.println(stringOut);
}
while (FlapLimitSwitchValue<15);
FlapStepper.setCurrentPosition(0);
delay(500); // gives enough time for the limit switch to debounce (needed for testing only)
// Initialize auger motor
AugerStepper.setMaxSpeed(600.0);
AugerStepper.setAcceleration(900.0);
//Initialize feeder motor, and zero the position
FeederStepper.setMaxSpeed(600.0);
FeederStepper.setAcceleration(900.0);
do{ // rotate the feeder until limit switch reached, and set that as new zero position
FeederStepper.move(-400*FeederDir);
FeederStepper.run();
FeederLimitSwitchValue=analogRead(FeederLimitPin);
// String stringOut = "Feeder value: ";
// stringOut = stringOut + FeederLimitSwitchValue;
// Serial.println(stringOut);
}
while (FeederLimitSwitchValue<15);
FeederStepper.setCurrentPosition(0);
delay(500); // gives enough time for the FullServing sensor to init before we enter the "loop"
}
void loop()
{
if (OkayToFeed)
{
if (TurnAuger)
{
// start turning the auger motor to dispense food into the holder.
AugerStepper.moveTo(400000);
AugerStepper.run();
FullServingValue=analogRead(FullServingPin);
String stringOut = "FullServe value: ";
stringOut = stringOut + FullServingValue;
//Serial.println(stringOut);
if(FullServingValue==0)
{
TurnAuger=0;
FlapStepper.setCurrentPosition(FlapStepper.currentPosition());
TurnFeeder=1;
}
}
if (TurnFeeder)
{
FeederStepper.moveTo(Bowl[CurrentBowl]*FeederDir);
FeederStepper.run();
if (FeederStepper.distanceToGo() == 0)
{
TurnFeeder=0;
TurnFlap=1;
}
}
if (TurnFlap)
{
String stringOut = "Flap position: ";
stringOut = stringOut + FlapStepper.distanceToGo();
//Serial.println(stringOut);
if (FlapOpen==0)
{
FlapStepper.moveTo(450*FlapDir);
FlapStepper.run();
if(FlapStepper.distanceToGo()==0)
{
FlapOpen=1;
delay(1000); // give time for all the food to fall then close flap
}
}
else
{
FlapStepper.moveTo(0);
FlapStepper.run();
if(FlapStepper.distanceToGo()==0)
{
FlapOpen=0;
TurnFlap=0;
TurnAuger=1;
CurrentBowl++;
if (CurrentBowl>=NumBowls)
{
OkayToFeed=0;
CurrentBowl=0;
}
}
}
}
}
}
Your schematic has all the A pins shorted to GND.
They should be connected to the point between the switches (or LDR) and the resistors.
BTW you've drawn a transistor not an LDR.
Rob
Schematic fixed and attached. I had it built this way on the breadboard, and just drew it wrong.
I know I drew a transistor... I couldn't find a symbol for LDR in the software, so I improvised! 
A0 is on the wrong side of the "LDR" but we'll assume it's right on the board.
Unfortunately, if any of the switches is closed, all the sensors read 0, or pulled to ground, making it impossible to get an accurate reading on the other switches.
If it's as drawn I don't see how that can happen if the code is right. Hang on
pinMode(FlapLimitPin, INPUT);
analogWrite(FlapLimitPin, LOW);
pinMode(FeederLimitPin, INPUT);
analogWrite(FeederLimitPin, LOW);
What's with writing to the input pins?
I'm not sure exactly what this will do but probably set it back to an output and create a PWM waveform on the pins.
Rob
What's with writing to the input pins?
Writing LOW to an input pin will disable the internal pull up resistor.
Writing HIGH to an input pin will enable the internal pull up resistor.
However this will be a different pin to the analogue one, if you want it to be the same pin ( which you don't ) then add 14 to the digitalWrite.
If it's as drawn I don't see how that can happen
Me nether.
internal pull up resistor.
Oh yes, I forgot about them, so I went and had a look at what exactly analogWrite() func does and see this
void analogWrite(uint8_t pin, int val)
{
pinMode(pin, OUTPUT);
if (val == 0)
{
digitalWrite(pin, LOW);
}
else if (val == 255)
{
digitalWrite(pin, HIGH);
}
...
case NOT_ON_TIMER:
default:
if (val < 128) {
digitalWrite(pin, LOW);
} else {
digitalWrite(pin, HIGH);
}
So I'm thinking that code will set the pin to an output and LOW at the end of the day.
Rob
Yes I think you are right, but it wouldn't explain why the OP is seeing all the inputs going to ground.
No, I suspect it's not quite wired as shown.
pbechard, can you reproduce this with a simple 5-line sketch, there's too much going on in that program to wade through.
Rob
Hi guys - thanks for the content so far - I learn even from reading the sidebar conversations!
I'll get back at it again this evening after work, and will verify that the schematic matches. I have a shorter script that monitors just one pin. I'll post that with some test results later.
I have a shorter script that monitors just one pin.
but if we are going to attack your problem of:-
if any of the switches is closed, all the sensors read 0
Then we need the results of you monitoring two pins.
Small update to schematic (attached). A0 was drawn on the wrong side of the LDR. It is in fact wired between the LDR and resistor.
Here's the new script, to monitor just the pins.
const int FullServingPin = A0;
const int FlapLimitPin = A1;
const int FeederLimitPin = A2;
void setup()
{
// initialize the serial port:
Serial.begin(9600);
// initialize various pins
pinMode(FullServingPin, INPUT);
analogWrite(FullServingPin, LOW);
pinMode(FlapLimitPin, INPUT);
analogWrite(FlapLimitPin, LOW);
pinMode(FeederLimitPin, INPUT);
analogWrite(FeederLimitPin, LOW);
}
void loop()
{
int FullServingValue=analogRead(FullServingPin);
int FlapLimitValue=analogRead(FlapLimitPin);
int FeederLimitValue=analogRead(FeederLimitPin);
String stringOut = "FullServingPin (A0)(LDR) value: ";
stringOut = stringOut + FullServingValue;
stringOut = stringOut + " FlapLimitPin (A1) value: ";
stringOut = stringOut + FlapLimitValue;
stringOut = stringOut + " FeederLimitPing (A2) value: ";
stringOut = stringOut + FeederLimitValue;
Serial.println(stringOut);
}
Results:
Everything open:
FullServingPin (A0)(LDR) value: 4 FlapLimitPin (A1) value: 0 FeederLimitPing (A2) value: 0
Blocking LDR only:
FullServingPin (A0)(LDR) value: 0 FlapLimitPin (A1) value: 0 FeederLimitPing (A2) value: 0
Closing A1 button only:
FullServingPin (A0)(LDR) value: 0 FlapLimitPin (A1) value: 3 FeederLimitPing (A2) value: 0
Closing A2 button only:
FullServingPin (A0)(LDR) value: 0 FlapLimitPin (A1) value: 0 FeederLimitPing (A2) value: 3
Holding A1 and A2,
FullServingPin (A0)(LDR) value: 0 FlapLimitPin (A1) value: 0 FeederLimitPing (A2) value: 0
So, what this means to me is that I can still tell when either or both of the limit switches are closed. I can live with that. However, If I ever need to add additionial switches, I'll be stuck. The results also mean that if one or both switches are closed, I can't read the status of my LDR.
I wonder if I'm approaching my problem from the right direction... ?
Thanks guys for your help.
Did you read replies 4-7 about doing an analogWrite() to the input pins?
Why are you doing that?
Rob
I did read those... trying to remember where I first saw that trick. I copied it from another sketch I wrote a couple months ago where I'm reading in and IR sensor. However, I don't remember where I got that advice originally.
If I comment out those three analogWrite lines, I get the following results with all pins open... everything floats around.
FullServingPin (A0)(LDR) value: 996 FlapLimitPin (A1) value: 26 FeederLimitPin (A2) value: 29
FullServingPin (A0)(LDR) value: 981 FlapLimitPin (A1) value: 0 FeederLimitPin (A2) value: 15
FullServingPin (A0)(LDR) value: 974 FlapLimitPin (A1) value: 36 FeederLimitPin (A2) value: 0
FullServingPin (A0)(LDR) value: 988 FlapLimitPin (A1) value: 50 FeederLimitPin (A2) value: 53
FullServingPin (A0)(LDR) value: 1001 FlapLimitPin (A1) value: 31 FeederLimitPin (A2) value: 30
FullServingPin (A0)(LDR) value: 1023 FlapLimitPin (A1) value: 48 FeederLimitPin (A2) value: 3
etc...
A1 and A2 should read 0, if the hardware matches the schematic I just can't see how you get those readings.
Have you checked the GND point for the resistors, maybe it's not really connected to GND. Often people plug wires into a power rail on a breadboard but forget to connect the rail.
A0 could be anything depending on the values of the LDR and resistor. Those readings may actually be correct. Have you tried changing the light levels?
Rob
Are the two switches shown a sw actually real switches or are they something else.
If they are real switches then you should read 0 when they are not pressed and 1023 when they are.
I get the following results with all pins open... everything floats around
That again suggests you have not wired it up as you think you have. It is not following the schematic.
Yes, they are real switches, normally open. Eventually the motors will turn and press them, but for now I'm just pressing them with my finger.
All the GNDs are definitely connected back to the GND of the wall wart.
I don't have any wires in the Arduino +5 or GND pins... all power for the discreet components is from the wall wart. Arduino is powered by USB. Do I need to tie in the Arduino +5 and/or GND to the breadboard too? Could this be a contributing factor?
Also, tried changing the swithch pins (A1, A2) in digital mode instead, removed the corresponding analogWrite(xxxx, LOW), and doing digitalReads.
const int FullServingPin = A0;
const int FlapLimitPin = A1;
const int FeederLimitPin = A2;
void setup()
{
// initialize the serial port:
Serial.begin(9600);
// initialize various pins
pinMode(FullServingPin, INPUT);
//analogWrite(FullServingPin, HIGH);
pinMode(FlapLimitPin, INPUT);
pinMode(FeederLimitPin, INPUT);
}
void loop()
{
int FullServingValue=analogRead(FullServingPin);
int FlapLimitValue=digitalRead(FlapLimitPin);
int FeederLimitValue=digitalRead(FeederLimitPin);
String stringOut = "FullServingPin (A0)(LDR) value: ";
stringOut = stringOut + FullServingValue;
stringOut = stringOut + " FlapLimitPin (A1) value: ";
stringOut = stringOut + FlapLimitValue;
stringOut = stringOut + " FeederLimitPin (A2) value: ";
stringOut = stringOut + FeederLimitValue;
Serial.println(stringOut);
}
Results:
FullServingPin (A0)(LDR) value: 1023 -- 90% of the time, floats a little, as expected by an LDR
FlapLimitPin (A1) value: 0 or 1 when button is open or closed, respectively.
FeederLimitPin (A2) value: 0 or 1 when button is open or closed, respectively.
Blocking the LDR with my finger causes A1 and A2 to float between 0 and 1
Holding both A1 and A2 down together causes them to float between 0 and 1
Classic example of when an experienced builder would glance at a breadboard and say "hey... just plug this in", but the rookie takes days to figure out on his own.
I'm at work again, so I'll wire that in tonight and report back.
I'm sure that's the problem, if so I should have twigged earlier because we're always banging on about connecting the GNDs here.
Rob