Digital Read issue, PIN 3, INPUT_PULLUP, ROS

Hi everyone,

I have an issue I don’t understand. Maybe someone can help. I am using an Arduino to control the wheels of my robot and also to read the wheel movement using a hall sensor.

Basically I read two sensors and and write to an l298n motor controller.

Pin 4,5,6,7 go to the l298n in1,2,3,4
For pwm I use 10 and 11

for the sensors i use 3 and 13, originally i used pin 2.

Everything works so far, i use a serial connection over usb to talk to ros, so my code includes ros libraries.

The issue is that I use digital read to get the senor values (high or low) and that only works on pin2, no other FREE pin works. What am I missing? If I use Pin 2 for a Sensor it never changes state, i guess it always stays low…

The code is fine, if i swap the pins in the variables it works fine. when i physically swap sensor pins it works fine too. But only on pin 3.

I am going mad, please help :slight_smile:

Are there any limitations on the pins i am not aware off? how often can I use input_pullup? Has this something to do with the serial connection I use? Do I need to move the other components to other pins? I don’t get why pin 3 works, but 2,8,9,12 and 13 don’t… I tried a3 too, didn’t work either…

:confused:

#include <ros.h>
#include <std_msgs/Int16.h>

// motor one
int enA = 10;
int in1 = 4;
int in2 = 5;
// motor two
int enB = 11;
int in3 = 6;
int in4 = 7;

//Sensor A and B Pin Sensor Type A1120
int hallPinA = A4; 
int hallPinB = A5;

//Motor Moving Forward?
int MotorOneForwardMovement = true;
int MotorTwoForwardMovement = true;

//Am I currently counting? Against bouncing
bool isActiveA = false;
bool isActiveB = false;

//What was the last state?
bool lastSensorState1 = false;
bool lastSensorState2 = false;

//Current Sensor state
int SensorState1 = 0; 
int SensorState2 = 0; 

//How many turns must a Wheel spin around, before you can call it a wheel?
int WheelCounter1 = 0;   // counter for the number of wheel rotations
int WheelCounter2 = 0;   // counter for the number of wheel rotations

//Initialze ROS node handling
ros::NodeHandle  nh;

void rmotor_cb( const std_msgs::Int16& cmd_msg){
  
  if  (cmd_msg.data > 0){ 
    // turn on motor B forward
    //writing Pins to Set Motor direction to Motor Controller LN298N
    digitalWrite(in4, HIGH);
    digitalWrite(in3, LOW);
    //writing PWM value to Motor Controller LN298N
    analogWrite(enB, cmd_msg.data);
  }else{
    if (cmd_msg.data == 0){
      digitalWrite(in3, LOW);
      digitalWrite(in4, LOW);
    }else{
      // turn on motor B backward
      //writing Pins to Set Motor direction to Motor Controller LN298N
      digitalWrite(in3, LOW);
      digitalWrite(in4, HIGH);
      //writing PWM value to Motor Controller LN298N
      analogWrite(enB, cmd_msg.data * -1);   
    };
  };
};

void lmotor_cb( const std_msgs::Int16& cmd_msg){

  if  (cmd_msg.data > 0){ 
    // turn on motor A forward
    //writing Pins to Set Motor direction to Motor Controller LN298N
    digitalWrite(in1, HIGH);
    digitalWrite(in2, LOW);
    //writing PWM value to Motor Controller LN298N
    analogWrite(enA, cmd_msg.data);
  }else{
    if (cmd_msg.data == 0){
      digitalWrite(in1, LOW);
      digitalWrite(in2, LOW);
    }else{
      //writing Pins to Set Motor direction to Motor Controller LN298N
      // turn on motor A backward
      digitalWrite(in1, LOW);
      digitalWrite(in2, HIGH);
      //writing PWM value to Motor Controller LN298N
      analogWrite(enA, cmd_msg.data * -1);   
    };
  };
};

//Define Message
std_msgs::Int16 lwheel_msg;
//Define ROS publishers, this is a message going out over a message bus, encapsulated in serial for arduino, i will  fill it with the sensor wheel counts later
ros::Publisher pub_lwheel("lwheel", &lwheel_msg);
//Define Message
std_msgs::Int16 rwheel_msg;
//Define ROS publishers, this is a message going out over a message bus, encapsulated in serial for arduino, i will  fill it with the sensor wheel counts later
ros::Publisher pub_rwheel("rwheel", &rwheel_msg);
//Define ROS subscribers, we wait for values arriving and then call rmotor_cb
ros::Subscriber<std_msgs::Int16> sub_rmotor("rmotor", rmotor_cb);
//Define ROS subscribers, we wait for values arriving and then call lmotor_cb
ros::Subscriber<std_msgs::Int16> sub_lmotor("lmotor", lmotor_cb);


void setup(){
  // set all the motor control pins to outputs
  pinMode(enA, OUTPUT);
  pinMode(enB, OUTPUT);
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  //set sensor ports to input pullup
  pinMode(hallPinB, INPUT_PULLUP);
  pinMode(hallPinA, INPUT_PULLUP);
  //initalize ros node
  nh.initNode();
  //set wheel message to 0;
  lwheel_msg.data = 0;
  lwheel_msg.data = 0;
  //subscribe and publish
  nh.subscribe(sub_lmotor);
  nh.subscribe(sub_rmotor);
  nh.advertise(pub_lwheel);
  nh.advertise(pub_rwheel);
  
}

void loop(){
  
   // read the sensor state
  SensorState1 = digitalRead(hallPinA);
  // read the sensor state
  SensorState2 = digitalRead(hallPinB);
  
  //wheel 1 counting
  // compare the sensor State to its previous state
  if (SensorState1 != lastSensorState1) {
    // if the state has changed, and we move forward and we have an active sensor state (magnet detected) increment the counter
    if (SensorState1 == HIGH && MotorOneForwardMovement && !isActiveA) {
      isActiveA = true;
      WheelCounter1++;
    }
    // if the state has changed, and we move backward and we have an active sensor state (magnet detected) decrease the counter
   if (SensorState1 == HIGH && !MotorOneForwardMovement && !isActiveA) {
      isActiveA = true;
      WheelCounter1--;
    }  
    
   if (SensorState1 == LOW) {
      // if the state is low we are not in an active state and can reset the anti bounce.
      isActiveA = false;
    }  
  }
  // save the current state as the last state,
  //for next time through the loop
  lastSensorState1 = SensorState1;
   
  //wheel 2 counting
  // compare the sensor State to its previous state
  if (SensorState2 != lastSensorState2) {
   // if the state has changed, and we move forward and we have an active sensor state (magnet detected) increment the counter
    if (SensorState2 == HIGH && MotorTwoForwardMovement && !isActiveB) {
      isActiveB = true;
      WheelCounter2++;
    }
  // if the state has changed, and we move backward and we have an active sensor state (magnet detected) decrease the counter
   if (SensorState2 == HIGH && !MotorTwoForwardMovement && !isActiveB) {
      isActiveB = true;
      WheelCounter2--;
    }  
    
   if (SensorState2 == LOW) {
      // if the state is low we are not in an active state and can reset the anti bounce.
      isActiveB = false;
    }  
  }
  // save the current state as the last state,
  //for next time through the loop
  lastSensorState2 = SensorState2;
   
 
 
   rwheel_msg.data = WheelCounter2;
   lwheel_msg.data = WheelCounter1;
   pub_lwheel.publish( &lwheel_msg );
   pub_rwheel.publish( &rwheel_msg );
   nh.spinOnce();
   delay(25);
}

When the world appears to have gone mad, it is time to get your feet replanted on firm ground and begin establishing facts.

So - get out your multimeter (or better yet, a 'scope), pull everything off the pins in question. Does the pin go high? Is it stuck low? Is there a grounded piece of metal contacting the underside of the pin?

If

void setup() {pinMode(3,INPUT_PULLUP);}
void loop() {;}

doesn’t result in the pin going high with nothing connected to it, that suggests a hardware fault (ie, you blew the pin)…

What does nh.SpinOnce() do? is that doing anything relating to the pin?

Like - if there’s something going on in that library relating to the pin, could it be using attachInterrupt() on it? That only works on a few pins (pin 2 is one of them)

Hi DrAzzy,

thanks for helping out.

Got my multimeter out, when i set it to INPUT_PULLUP it reads around 3v when i don’t set it it is around 0.8. There is no metal, it sits in a 3d printed robot base I designed. No metal around. Currently I am using pin A4 without success, pin three works. Nh.spinonce calls back to the ros message system. Callbacks are usually queued and processed on spinonce. I use that to no overload the Arduino with requests. So it should have nothing to do with the pin. It uses the serial connection over usb though.

I commented the code and made it more readable… Sorry that I had no time for functions yet, i am close to the vacation with my wife and I would like to get the robot moving at least once :slight_smile:

This introduces some issues as going fast is usually very slow.

Still not sure whats going on…

Is that supposed to be running on 5v? Is it actually at 5v?

And you only see 3v when the pin is set input pullup with nothing connected to it?

That is not consistent with expected behavior.

3.8 volts nothing connected to the pin, but other stuff at the arduino... the arduino is running on 5 volts...

Hi Drazzy, it must be something I did wrong in the code, a4 and a5 work but only when hallpinb variable is used. So i messed something up in the code for hallpina...