Hi,
I'm very new to this and have just been handed a board and a program installed to control some servos to operate model railway semaphore signals. I do have a load of programming experience but not in C++ - I think I understand the code. However, I think I have a hardware problem - as do all programmers
I am using a a switch to send 5vdc into the Arduino board which should cause a change of state and thus make the servo move. Removing that 5v signal should cause the servo to revert to it's original position. The switch is also connected to a 3-pole LED so when the 5v is present the green side lights up, when removed and 5v applied to the other cathode it shows red. This works but only after adding a diode to the input to the Arduino as there appeared to be a voltage returning back to the switch and thus the LED which glowed amber - the diode fixed this.
BUT, here's the problem - when the servo is connected and powered up it moves to it's position, when the 5v signal is removed it begins oscillating back & forth. What makes me think the spurious voltage is still there is if I connect my multi-meter to the pin on the edge connector to try & read the signal, the oscillation stops. Removing the meter probe starts the oscillation again and so ad ad nauseum.
I have been told that this can happen - the pin not staying as an INPUT - and that a possible cure is to add a pull-down 10k resistor between the pin and the 0v.
I have attached my schematic, I've marked what I believe is the correct position for the 10k resistor (in green) and I have attached my code.
Please can you confirm if my suspicions are correct and the resistor will fix it or if there is another cause entirely
First, why do you think it's a good idea to add code as txt...
Code of OP:
#include <Servo.h>
Servo servo_3;
Servo servo_4;
Servo servo_5;
Servo servo_6;
Servo servo_7;
Servo servo_8;
Servo servo_9;
Servo servo_10;
int input_11 = 11; //pin 11
int input_12 = 12; //pin12
int input_13 = 13; //pin13
int input_14 = 14; //A0
int input_15 = 15; //A1
int input_16 = 16; //A2
int input_17 = 17; //A3
int input_18 = 18; //A4
int previous_buttonState_1 = 3;
int previous_buttonState_2 = 3;
int previous_buttonState_3 = 3;
int previous_buttonState_4 = 3;
int previous_buttonState_5 = 3;
int previous_buttonState_6 = 3;
int previous_buttonState_7 = 3;
int previous_buttonState_8 = 3;
int buttonState_1 = 0;
int buttonState_2 = 0;
int buttonState_3 = 0;
int buttonState_4 = 0;
int buttonState_5 = 0;
int buttonState_6 = 0;
int buttonState_7 = 0;
int buttonState_8 = 0;
void setup() {
 // put your setup code here, to run once:
Serial.begin(9600);
pinMode(input_11,INPUT);
pinMode(input_12,INPUT);
pinMode(input_13,INPUT);
pinMode(input_14,INPUT);
pinMode(input_15,INPUT);
pinMode(input_16,INPUT);
pinMode(input_17,INPUT);
pinMode(input_18,INPUT);
}
void loop() {
Â
buttonState_1 = digitalRead(11);
buttonState_2 = digitalRead(12);
buttonState_3 = digitalRead(13);
buttonState_4 = digitalRead(14);
buttonState_5 = digitalRead(15);
buttonState_6 = digitalRead(16);
buttonState_7 = digitalRead(17);
buttonState_8 = digitalRead(18);
Serial.println("buttonState_1_read");
Serial.println(buttonState_1);
 if (buttonState_1 < previous_buttonState_1)
 {
Serial.println("buttonState_1_loop_1");
Serial.println(buttonState_1);
Serial.println("previous_buttonState_1_loop_1");
Serial.println(previous_buttonState_1);
servo_3.attach(3);
servo_3.write (25);
delay (200);
servo_3.detach();
previous_buttonState_1 = buttonState_1;
}
 if (buttonState_1 > previous_buttonState_1)
 {
Serial.println("buttonState_1_loop_2");
Serial.println(buttonState_1);
Serial.println("previous_buttonState_1_loop_2");
Serial.println(previous_buttonState_1);
servo_3.attach(3);
servo_3.write (150);
delay (200);
servo_3.detach();
previous_buttonState_1 = buttonState_1;
}
if (buttonState_2 < previous_buttonState_2)
{
servo_4.attach(4);
servo_4.write (25);
delay (200);
servo_4.detach();
previous_buttonState_2 = buttonState_2;
}
 if (buttonState_2 > previous_buttonState_2)
 {
servo_4.attach(4);
servo_4.write (150);
delay (200);
servo_4.detach();
previous_buttonState_2 = buttonState_2;
}
 if (buttonState_3 < previous_buttonState_3)
{
servo_5.attach(5);
servo_5.write (25);
delay (200);
servo_5.detach();
previous_buttonState_3 = buttonState_3;
}
 if (buttonState_3 > previous_buttonState_3)
 {
servo_5.attach(5);
servo_5.write (150);
delay (200);
servo_5.detach();
previous_buttonState_3 = buttonState_3;
}
if (buttonState_4 < previous_buttonState_4)
{
servo_6.attach(6);
servo_6.write (25);
delay (200);
servo_6.detach();
previous_buttonState_4 = buttonState_4;
}
 if (buttonState_4 > previous_buttonState_4)
 {
servo_6.attach(6);
servo_6.write (150);
delay (200);
servo_6.detach();
previous_buttonState_4 = buttonState_4;
}
if (buttonState_5 < previous_buttonState_5)
{
servo_7.attach(7);
servo_7.write (25);
delay (200);
servo_7.detach();
previous_buttonState_5 = buttonState_5;
}
 if (buttonState_5 > previous_buttonState_5)
 {
servo_7.attach(7);
servo_7.write (150);
delay (200);
servo_7.detach();
previous_buttonState_5 = buttonState_5;
}
if (buttonState_6 < previous_buttonState_6)
{
servo_8.attach(8);
servo_8.write (25);
delay (200);
servo_8.detach();
previous_buttonState_6 = buttonState_6;
}
 if (buttonState_6 > previous_buttonState_6)
 {
servo_8.attach(8);
servo_8.write (150);
delay (200);
servo_8.detach();
previous_buttonState_6 = buttonState_6;
}
if (buttonState_7 < previous_buttonState_7)
{
servo_9.attach(9);
servo_9.write (25);
delay (200);
servo_9.detach();
previous_buttonState_7 = buttonState_7;
}
 if (buttonState_7 > previous_buttonState_7)
 {
servo_9.attach(9);
servo_9.write (150);
delay (200);
servo_9.detach();
previous_buttonState_7 = buttonState_7;
}
 if (buttonState_8 < previous_buttonState_8)
{
servo_10.attach(10);
servo_10.write (25);
delay (200);
servo_10.detach();
previous_buttonState_8 = buttonState_8;
}
if (buttonState_8 > previous_buttonState_8)
{
servo_10.attach(10);
servo_10.write (150);
delay (200);
servo_10.detach();
previous_buttonState_8 = buttonState_8;
}
}
Image:
It's the common floating switch problem. If a switch isn't connected that does NOT mean it's low It's like a ball in the back of your car. If you don''t push it to the right it does not mean the ball it at the left side. It just move with every small movement.
Easiest fix, enable the internal pull up resistors. In analogy with the ball, they act like a spring to one side. If you don't push it the other way it will return. You do this with pinMode(pin, INPUT_PULLUP). BUT, as the name suggests, this will pull the input low when nothing is connected. In order to change the state you have to pull it LOW aka to GND. Just fine, your switch can do that as well.
In you're schematic you kind of have a pull DOWN resistor but the diode is preventing it to work
PS If you did not write that code yourself I would drop it. I would say that code is pretty terrible...
Thank you all for the replies, sorry about the code as I said I didn't write it. It was sent as a txt file because the IDE has an option to create it and that's how it came out.
The 10k resistor has not yet been positioned and I understand it should be direct to the pin on the before the diode.
The diode was added as when the switch was turned "off" there was sufficient signal coming back from the board to cause the LED to show amber - in other words it was getting power on the 'green' on leg. The diode fixed that.
So, rather than mess with the code for now, I'll position the 10k resistor between the diode and the pin and retest.
Curious, if the 10k resistor was there would it eliminate the need for the diode?
rynd2it:
Thank you all for the replies, sorry about the code as I said I didn't write it.
Then I would kindly suggest to put it in the bin.... Trust me, you're better off that way.
rynd2it:
It was sent as a txt file because the IDE has an option to create it and that's how it came out.
Does it? Can you tell me where?
rynd2it:
The 10k resistor has not yet been positioned and I understand it should be direct to the pin on the before the diode.
Aha! So you where lying! Don't tell us stuff that's not true if you don't understand it and want help
rynd2it:
The diode was added as when the switch was turned "off" there was sufficient signal coming back from the board to cause the LED to show amber - in other words it was getting power on the 'green' on leg. The diode fixed that.
I still very much doubt that based on what you show. But then, what you showed proofed to be not always the truth Aka, OR the pins are not set to INPUT bu INPUT_PULLUP
OR the board is more complex than that and has other stuff on it.
rynd2it:
So, rather than mess with the code for now, I'll position the 10k resistor between the diode and the pin and retest.
I don like being called a liar especially when I am not
""I have been told that this can happen - the pin not staying as an INPUT - and that a possible cure is to add a pull-down 10k resistor between the pin and the 0v.
I have attached my schematic, I've marked what I believe is the correct position for the 10k resistor (in green) and I have attached my code.""
Clearly I had NOT positioned the resistor but was asking for help in determining if it would work.
I'll accept your apology.
Believe me,the LED went amber went switched off, the diode fixed.
""Curious, if the 10k resistor was there would it eliminate the need for the diode? ""
So apart from slagging me off why didn't you answer this question?
I'm sorry, but I do read more then only this. And if someone posts a schematic (great!) that represents whats going on I don't expect I have to imagine it different But I'm sorry I missed it! But please, do cheer up and also read the emoji
According to the schematic and code that LED should NOT be on, diode or no diode, when the switch is off. Or are there antenna's long wires involved? If there is some leakage current that pull down resistor may (probably) eat it all without lighting the LED. But for now, nothing shows what could cause the leakage in the first place so that would be just a random guess.
That does remain:
just throw away the code
That does NOT generate a .txt. That will simply copy (like it says) it to the clipboard. You could have just pasted here but you decided to past it in a text editor and save it as a .txt The IDE simply does not. And yes, you could have known because that's what's the most ignored thread is about (aka How to use the forum).
OK, The wire from the switch to the Arduino board is probably about 1 metre, the switch, LED etc are on a control panel with the LED on the railway baseboard. I don't know if that constitutes a 'long wire' .
I actually use quite a few forums and nearly all ask for code samples etc to be attached rather than pasted into the thread, keeps the clutter down. My mistake, sorry.
I would throw away the code but that would mean me learning C++ and after 40 years programming (Usercode, Assembler, COBOL, PL/1, dBase, SQL, Basic, etc) I'd rather not - I'm retired! Unless of course you would like to write it for me
I'll let you know if the resistor works after tomorrow
rynd2it:
Unless of course you would like to write it for me
I kind of did Only thing is, I'm not retired so my time is a bit limited to go on with it.
I'm a model railroad idiot myself and I made something I called adServo. Aimed to control (turnout) servo's analog an digital. For the digital part I an into some trouble (of which no time is the biggest) but analog and hardware is just fine. Supports setting end positions and speed etc. By default it's designed for 4 servo's. Reason for that is a) It's so damn cheap b) servo's don't like long cables anyway
I'm still planning a redesign of the software and also implement digital (DCC) but time New job, new home, lab and train are still in boxes...
But even, there are lots of other examples/implementations of this that are better. And I could redo the code in a better way (would only be 50 lines tops) but the functionality of it will still not be great...
Correction, to mimic the code I only need 27 lines.
#include <Servo.h>
const byte InputPins[] = {11, 12, 13, A0, A1, A2, A3, A4};
const byte NrServos = sizeof(InputPins);
const byte ServoPins[NrServos] = {3, 4, 5, 6, 7, 8, 9, 10};
Servo servo;
bool previousButtonStates[NrServos];
void setup() {
 for(byte i = 0; i < NrServos; i++){
  pinMode(InputPins[i], INPUT_PULLUP);
 }
}
void loop() {
 for(byte i = 0; i < NrServos; i++){
  const bool State = digitalRead(InputPins[i]);
  if(State != previousButtonStates[i]){
   previousButtonStates[i] = State;
   servo.attach(ServoPins[i]);
   servo.write(State ? 150 : 25);
   delay(200);
   servo.detach();
  }
 }
}
Okay, I did left out the serial. And yeah, code without comment is bad. But then again, the functionality of this piece of code is as well. Only a single servo moving at the same time, fixed positions, no speed control etc.
UPDATE. Adding the 10k resistor as indicated on the revised schematic solved the problem. The servos now behave as expected and the LEDs on the panel are indicating correctly red or green according to the switch setting.
I did try & use the code that Septillion kindly provided but there was no movement at all on the servo. I suspect this is due to the use of the INPUT PULLUP (or lack of it) but I didn't have the time to investigate fully. Maybe when I have got it all working on the layout I'll come back to the programming and learn some C++ and figure out how to use the debugging tools
Good thing it works! If I make an update to adServo I'll try to remember to send you a message.
rynd2it:
BTW, the Serial stuff I believe was there for debugging purposes but I never figured out how to use it.
You don't really use it, it's indeed debug and it kind of tells you want to code is doing. But after the program is finished it's not really that useful. You can't change anything with it.
rynd2it:
I did try & use the code that Septillion kindly provided but there was no movement at all on the servo. I suspect this is due to the use of the INPUT PULLUP
Ahh, yeah. Automatism to do it that way. The code expects a button between the pin and GND. Not between the pin and Vcc. Because it saves me from having to add resistors.