ardumoto + ultra sonic sensor not working together [Solved]

Hello,

this might be a simple problem, but i dont get it.

#include <Servo.h>


int dist = 0;                 // variable to store the values from sensor(initially zero)

int pwm_a = 3; //PWM control for motor outputs 1 and 2 is on digital pin 3
int pwm_b = 11; //PWM control for motor outputs 3 and 4 is on digital pin 11
int dir_a = 12; //dir control for motor outputs 1 and 2 is on digital pin 12
int dir_b = 13; //dir control for motor outputs 3 and 4 is on digital pin 13

#define TIMEOUT_OVERFLOW 1000

int TrigPin = 6;
int EchoPin = 7;
unsigned long ultrasoundDuration;
unsigned long  distance_sensor;

Servo myservo;

int pos = 0;    // variable to store the servo position


void setup()
{

  myservo.attach(servopin);
  //myservo.attach(servopin,1400,2400 );

  Serial.begin(9600);               // starts the serial monitor

  pinMode(pwm_a, OUTPUT); //Set control pins to be outputs
  pinMode(pwm_b, OUTPUT);
  pinMode(dir_a, OUTPUT);
  pinMode(dir_b, OUTPUT);

}


void loop()
{

  forward();
  
  
  getDistance_sensor();
  dist=distance_sensor;

  Serial.print("Distance is = ");
  Serial.print( dist , DEC);
  Serial.print(" cm");
  Serial.println();
  delay(100);
  
 

}


void forward() { 
  digitalWrite(dir_a,LOW);
  digitalWrite(dir_b,HIGH);

  analogWrite(pwm_a, 100); //set both motors to run at (100/255 = 39)% duty cycle (slow) 
  analogWrite(pwm_b, 100);

  return;
}



int getDistance_sensor(){

  unsigned char pin = 0;
  unsigned int time_flag = 0;

  pinMode(TrigPin, OUTPUT); //pin is output
  pinMode(EchoPin, INPUT); // pin is now input
  digitalWrite(TrigPin, HIGH);
  delayMicroseconds(2);
  digitalWrite(TrigPin, LOW);
  delayMicroseconds(10);
  digitalWrite(TrigPin, HIGH);

  // wait for a LOW pulse
  //ultrasoundDuration = pulseIn(EchoPin, HIGH);// will not work for HIGH pulse

  TCCR1A = 0x00;
  TCNT1 = 0x0000;
  TCCR1B = 0x01;
  pin = digitalRead(EchoPin);
  while(pin)
  {
    pin = digitalRead(EchoPin);
    time_flag++;
    if(time_flag > TIMEOUT_OVERFLOW)
      break;
  }
  TCCR1B = 0x00;
  ultrasoundDuration = TCNT1;
  ultrasoundDuration = ultrasoundDuration / 16;
  // get results

  distance_sensor= ultrasoundDuration*0.017;

  return distance_sensor;
}

now only the left motor and the sensor is working.

when ich comment this part of the code out:

getDistance_sensor();
  dist=distance_sensor;

  Serial.print("Distance is = ");
  Serial.print( dist , DEC);
  Serial.print(" cm");
  Serial.println();
  delay(100);

both motors are working and the robot move forward like i want. But i need that both parts are working paralell. Both motors to move forward and the sensor to measure the distance. But i dont understand why not.

I hope you can help me. Thank you.

Once upon a time, a similar problem was traced to an underpowered project:

thank you for your reply mrburnette. Unfortunately i cant find a solution in the old post neither.

I try also to connect a second battery only for the ardumoto, but i think the power is not the problem becouse i use a power supply for testing my arduino.

Its a realy strange behaviour and i dont get it why its not working like it should. Please help me.

Well, the link previously provided (easy fix) was a problem with current being provided to the motors. It was worth a try.

Note: I am not a PWM kind of person... so, no experience in the area (other than dimming LEDs). But, by answering, the thread will get "bumped" to the top of the cue... maybe one of our members familiar with PWM will also chime in...

Looking at the code in more detail and in referencing this link: http://arduino.cc/en/Tutorial/SecretsOfArduinoPWM the issue may be that you are disturbing timer1 with the function getDistance_sensor(). According to http://playground.arduino.cc/Main/TimerPWMCheatsheet

For Arduino Mega: (tested on Arduino Mega 2560) timer 0 (controls pin 13, 4) timer 1 (controls pin 12, 11) timer 2 (controls pin 10, 9) timer 3 (controls pin 5, 3, 2) timer 4 (controls pin 8, 7, 6)

and you are using both pins 11 and 12

int pwm_b = 11; //PWM control for motor outputs 3 and 4 is on digital pin 11
int dir_a = 12; //dir control for motor outputs 1 and 2 is on digital pin 12

So, my thinking is that you are "clobbering" your PWM whenever you call the getDistance_sensor() routine.

Ray

Thank you Ray for this idea.

I get what you mean, but i dont get what the function getdistance() and Timer1 have in common? Of course timer1 controlls 11 and 12 which are the pins for the PWM but why disturb the function getdistance() timer1? The pins for the sensor are Pin 6 and 7.

Do you can explain me what i have to change to solve this problem?

Thanks a lot. :)

Excerpt from inside the function getDistance_sensor()

  TCCR1A = 0x00;
  TCNT1 = 0x0000;
  TCCR1B = 0x01;

someone a idea how to solve this ???

I tryed to change the adresses from Timer1 to Timer2

like this:

/Timer1 (controls pin 12, 11) TCCR1A = 0x00; TCNT1 = 0x0000; TCCR1B = 0x01; ***/

//Timer 2 (controls pin 10, 9) TCCR2A = 0x00; TCNT2 = 0x0000; TCCR2B = 0x01

Now both motors are working but not the sensor :(

int getDistance_sensor(){

  unsigned char pin = 0;
  unsigned int time_flag = 0;

  pinMode(TrigPin, OUTPUT); //pin is output
  pinMode(EchoPin, INPUT); // pin is now input
  digitalWrite(TrigPin, HIGH);
  delayMicroseconds(2);
  digitalWrite(TrigPin, LOW);
  delayMicroseconds(10);
  digitalWrite(TrigPin, HIGH);

  // wait for a LOW pulse
  //ultrasoundDuration = pulseIn(EchoPin, HIGH); // will not work for HIGH pulse
  
/***Timer1*** (controls pin 12, 11)
  TCCR1A = 0x00;
  TCNT1 = 0x0000;
  TCCR1B = 0x01;
  ***/
  
  //Timer 2 (controls pin 10, 9)
  TCCR2A = 0x00;
  TCNT2  = 0x0000;
  TCCR2B = 0x01;
  
  pin = digitalRead(EchoPin);
  while(pin)
  {
    pin = digitalRead(EchoPin);
    time_flag++;
    if(time_flag > TIMEOUT_OVERFLOW)
      break;
  }
  
  TCCR2B = 0x00;
  ultrasoundDuration = TCNT2;
  ultrasoundDuration = ultrasoundDuration / 16;
  // get results

  distance_sensor= ultrasoundDuration*0.017;

  return distance_sensor;
}

I solve the problem.

It was a problem with the timer1 and i coudnt change the adresses to timer2. So i tryed to change the code without using the timer.

I upload the code for everyone who has the same problems…

thanks Ray for helping me :slight_smile:

Drive_test.ino (2.17 KB)

I upload the code for everyone who has the same problems...

@Matze_Ka And that is the magic of the forum... All you needed was a little insight into the solution. You did the research, you "fixed" the problem, you learned and you "gave back" to the community.

If only every person would follow your example.

Ray

PS, if you would now edit the title to show [Solved]

Thank you Ray, but sometimes i expect some more input from guys with more experience.

i expect some more input from guys with more experience.

the goal is to get you to the point where you will need no input. You cannot get there by being spoon-fed... it's a neuron thing... you need to participate in your education. I don't like it either when I need a quick question... but, I hated it so much back when I was asking that these days I don't ask too many and I am pretty much self-sufficient. I do however, give back several hours a week on the forums as thanks to those that annoyed me in the past!

Ray

Yes you are right. I will try to follow your example. I think i have a new hobby :)

Happy New Year at all.