Very strange behaviour of A0 to A4 pins???

Hi,
Novice here.
But thought I could do something simple like controlling 4 servos.
Started out with the code more compacted but ended up simply defining and executing 4 identical codes and even those loops are probably unnecessarily cumbersome.

However, everything works fine on pin A1.
The exact same code does NOT work on A2,A3,A4.
Meter shows the pins going LOW when the switch is closed! High when open.
The SAME on ALL pins.

Driving me nuts.
So, 4 servos on D3,D5,D6 and D9.
4 switches on A1,A2,A3,A4
Everything common grounded.Here is the code:

//control 4 servos

//????have 4 switches high/low to change point position

//4 PWM pins for servos
//Using 4 switches on A1-A4 (SPDT) as control.
//Hopefully that means only 4 inputs (either high OR low) AND 4 PWM outputs are used

#include <Servo.h>
#include <EEPROM.h>

Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo


byte store1 = 10;             //cell address to store points position into EEPROM
byte store2 = 20;             //give each one some space
byte store3 = 30;
byte store4 = 40;

byte switch1 = A1;              //start using some analog pins here for input
byte switch2 = A2;
byte switch3 = A3;
byte switch4 = A4;

byte t1;                        //just for general use as a temp variable
byte t2;
byte t3;
byte t4;

int val1;                      //these represent actual servo position
int val2;
int val3;
int val4;

int straight = 80;          //duration of the pulse to be sent if points are straight ahead
int turn = 100;              //and if turning off

void setup()
{

  pinMode(switch1, INPUT_PULLUP);    //set input pins to PULL UP so the switch can pull them down.
  pinMode(switch2, INPUT_PULLUP);    //simply earth it for LOW
  pinMode(switch3, INPUT_PULLUP);
  pinMode(switch4, INPUT_PULLUP);

  myservoa.attach(3);

  myservob.attach(5);

  myservoc.attach(6);

  myservod.attach(9);

  //Here get the stored values  (to put everything the way it was before power-off).
  //After all, if you've got an EEPROM, why not use it?

  val1 = EEPROM.read (store1);       //get the stored values from the eeprom
  myservoa.write(val1);             //set the servo

  val2 = EEPROM.read (store2);
  myservob.write(val2);

  val3 = EEPROM.read (store3);
  myservoc.write(val3);

  val4 = EEPROM.read (store4);
  myservod.write(val4);

}

void loop()
{
  t1 = digitalRead (switch1);
  if ((t1 == LOW) && (val1 == straight))
  {
    myservoa.write(turn);
    val1 = turn;                              // if switch doesn't agree with current setting tell servo to go to new position
  }
  if ((t1 == HIGH) && (val1 == turn))
  {
    myservoa.write (straight);
    val1 = straight;                          //and update val AND EEPROM
  }
  t2 = digitalRead (switch1);
  if ((t2 == LOW) && (val2 == straight))
  {
    myservob.write(turn);
    val2 = turn;                              // if switch doesn't agree with current setting tell servo to go to new position
  }
  if ((t2 == HIGH) && (val2 == turn))
  {
    myservob.write (straight);
    val2 = straight;
  }

   t3 = digitalRead (switch3);
  if ((t3 == LOW) && (val3 == straight))
  {
    myservoc.write(turn);
    val3 = turn;                              // if switch doesn't agree with current setting tell servo to go to new position
  }
  if ((t3 == HIGH) && (val3 == turn))
  {
    myservoc.write (straight);
    val3 = straight;
  }

 t4 = digitalRead (switch4);
  if ((t4 == LOW) && (val4 == straight))
  {
    myservod.write(turn);
    val4 = turn;                              // if switch doesn't agree with current setting tell servo to go to new position
  }
  if ((t4 == HIGH) && (val4 == turn))
  {
    myservod.write (straight);
    val4 = straight;
  }
  
  EEPROM.update (store1, val1);         //store everything for power down
  EEPROM.update (store2, val2);         //update ONLY writes to EEPROM if the setting has changed.
  EEPROM.update (store3, 120);         //this prolongs EEPROM life
  EEPROM.update (store4, 120);

}

Thanks to all,

Aussiewill

You can very quickly blow your Arduino up (not literally) with that code. True that update will only write if the contents have changed but if the values do happen to change for whatever reason, in a couple of seconds your unit could be toast. It is extremely unwise to place an EEPROM write/update in an uncontrolled loop. This statement brokers no argument.

Having said that, there doesn't appear to be anything egregiously wrong with your code so it must be with the values being tested. After each digitalRead and before your if statement, print out the two values being tested (i.e. t1 and val1). Have a look at them and see what's happening. You can share that with us if you'd like.

Thank you DKWatson.

Yes, back to the good old serial.begin I suppose.

Hoping like heck to avoid that.

As for blowing the EEPROM, yes, I think I'll just set a safe value in setup and rely on that for keeping the servos under control till I execute the loop.

Thanks for that.

Aussiewill

Not the cause of your problem, but avoid any misunderstanding by anyone reading this thread. the servo outputs do not need to be on PWM enabled pins. Any digital pin will work.

As to your problem, write a small program that simply outputs a message when pins A0 to A4 are taken LOW. This will help to isolate the problem which is likely caused by a wiring fault. Are you using a breadboard and, if so, are the power strips along the edge continuous or do they have breaks in them ?

How are the servos powered ?

Thanks for the input UKHeliBob,
But I reckon I've got PWM pins available, why not take the hard work out.

Here is something even weirder than the original problem.
I took the advice re EEPROM use, worked out it's nice but not really necessary and made THE FOLLOWING changes ONLY:

Removed all mention of the EEPROM and modified the setup up code from reading the eeprom stored value to a simple constant.

 myservoa.write(val1);             //set the servo
  myservob.write(val2);
  myservoc.write(val3);
  myservod.write(val4);

THAT's IT.

Everything now works like a dream on ALL switches!!!!!!!!

Now THAT I would like an explanation for, I thought Arduinos were LOGIC devices???

So, problem solved but more mysteries.

Thanks all for their help.

Aussiewill

Just one more curious (to me) thing:

Originally my 2 settings were "main"and "turn", but I had to change "main" to "straight as the assembler didn't like it.

Came up with some obscure error (on a different line, of course) but that ended up to be the problem.
Just wondering if that term is reserved somewhere???????? Couldn't find any references.
And if it is, is there a list of all/any such words somewhere??

Aussiewill

main() is the standard main function that any C/C++ program uses; the Arduino approach hides it for you. That's where your compiler problem probably came from.

With regards to your original problem.

Your valX variables are ints, not bytes. EEPROM.read and EEPROM.update work on bytes so you will only get half of the data. Use EEPROM.get and EEPROM.put instead. EEPROM.put uses EEPROM.update under the hood.

If your valX variables only have to hold values between 0 and 255 (both included), changing them to byte will also work (with your origibal code).

I've got PWM pins available, why not take the hard work out.

It is no harder for you or the program to use PWM enabled pins or other digital pins so I don't know what you mean.

Thanks sterretje.

Yes, I should have thought of the fact that the overall program would have that name. Just never occurred to me because as you say, Arduino hides it. Brilliant!

As far as the EEPROM values are concerned, my fault. I forgot that in desperation I had changed them to integers. Originally they were simple bytes (values are only 80 or 100). I tampered with them in desperation.

Thanks again,

Aussiewill

aussiewill:
As far as the EEPROM values are concerned, my fault. I forgot that in desperation I had changed them to integers. Originally they were simple bytes (values are only 80 or 100). I tampered with them in desperation.

As far as I can see, your code should have worked in that case; you say it didn't?

Meter shows the pins going LOW when the switch is closed! High when open.
The SAME on ALL pins.

.
That's the way you have them programmed.

  pinMode(switch1, INPUT_PULLUP);    //set input pins to PULL UP so the switch can pull them down.
  pinMode(switch2, INPUT_PULLUP);    //simply earth it for LOW
  pinMode(switch3, INPUT_PULLUP);
  pinMode(switch4, INPUT_PULLUP);

Hi again,
Yes Fred, I know. I programmed them that way. Simply pointing out that HARDWARE wise everything worked identically. Link that with the fact that ALL 4 statements are absolutely identical and you might understand why I was (am) mystified that ONE always worked and the others NOT.

Aussiewill

Posting from my phone, so keeping it short and simple:

In your original code you have the four varX variables. As globals, they are initialised to zero when declared. The first time you ran the sketch you then assigned values to them from EEPROM. The values you pulled from there are for the purposes of this sketch unknown and unspecified.
Next you have a bunch of if's that compare the unspecified values to either 80 or 100. If they happen to match then you get to update varX, otherwise not.
Finally you write var1 and var2 back to EEPROM, still unspecified, and 120 to var3 and var4, which doesn't equal either 80 or 100.
Ill specified values give ill specified results.

Your second digitalRead also has the wrong pin name.

Instead of:

Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo

Try:

Servo myservoa; // create servo object to control a servo
Servo myservob;
Servo myservoc;
Servo myservod;

FredScuttle:
Instead of:

Servo myservoa, myservob, myservoc, myservod;  // create servo object to control a servo

Try:

Servo myservoa; // create servo object to control a servo

Servo myservob;
Servo myservoc;
Servo myservod;

Why? Both codes create 4 instances of the Servo class in exactly the same way.

Mind you, I prefer the second method, but there is nothing wrong with the first.

Hi
Thanks to arduarn for pointing that out. I had actually prewritten 120 into all 4 eeprom positions, by having a small loop in setup the very first time I uploaded the sketch. But valid point. As it is, I now simply center all servos on power on and don't bother with the eeprom.

Now that everything works fine, creating servo objects with comma separation works fine, I don't think the assembler cares either way.

And STILL I haven't found a really valid reason why no matter what I did, everything always worked for the first iteration of the loop bt NOT for the others. But all's well etc. I have now converted to an 8 switch point controller and have no more problems.
Think I'll just keep believing in Gremlins!

Thanks again all,

Aussiewill