Problem with Timer function used for speed sensors (one DC motor not working)

I have wery weird problem with timer function. First I thought that the problem is caused by the SD card module but after some mods in the code I see that SD module is ok.

In short words I am building autonomous mapping robot and I am using:

  • Arduino Mega 2560
  • Motor Shield
  • Two DC motors
  • two LM393 sensors (to get speed of wheels speening)
  • two SR04 ultrasonic sensors (to follow walls and avoid obstacles
  • micro SD card module

To measure speed I have to use timer, which I think causes the problem.

The code to my program:

And the section of the code which I think causes the problem:

void setup() {

Serial.begin(9600);

//Ustawienie timera
Timer1.initialize(1000000); // ustawienie timera na sekunde
//zwieksz counter1 gdy pin predkosciomieza jest na Hig
attachInterrupt(digitalPinToInterrupt (motor_A), ISR_count_A, RISING);
//zwieksz counter2 gdy pin predkosciomieza jest na High
attachInterrupt(digitalPinToInterrupt (motor_B), ISR_count_B, RISING);
}

void ISR_timerone(){
  Timer1.detachInterrupt(); //Stop timera
  
  Serial.print("Motor1 Speed: ");
  float rotation_A = (counter_A / diskslots) * 60.00; //obliczenie obrotow na minute (RPM) dla motor1
  Serial.print(RMPtoCmS(rotation_A));
  Serial.print(" Cm/s - ");
  counter_A = 0;

  Serial.print("Motor2 Speed: ");
  float rotation_B = (counter_B / diskslots) * 60.00; //obliczenie obrotow na minute (RPM) dla motor2
  Serial.print(RMPtoCmS(rotation_B));
  Serial.println(" Cm/s");
  counter_B = 0;

 float srednia_predkosc = (RMPtoCmS(rotation_A) + RMPtoCmS(rotation_B)) /2;

//zapisywanie informacji o prędkości na karcie SD
 myFile = SD.open("DaneMapy.txt", FILE_WRITE);
 if (myFile) {
  Serial.println("Writing to file...");
    myFile.print("Motor1: ");
    myFile.print(RMPtoCmS(rotation_A));
    myFile.print("Motor2: ");
    myFile.print(RMPtoCmS(rotation_B));
    myFile.print(" Średnia prędkość: ");
    myFile.print(srednia_predkosc);
    myFile.close();
    Serial.println("Done.");
   }

 Timer1.attachInterrupt(ISR_timerone);
}

When I run my robot with timer function involved only one motor Is working (It doesnt matter if I run it on external power or on USB power).
Second problem is that when I run my robot on external power the info is beeing written to SD card, and when I run it on external power it is not.

I think both or this problems are interrelated.
I also have to indicate that even if I comment printing to myFile section second motor is not working.
What can couse the problem? Did I implement timer function incorrectly?

I attach schematic (sorry for messy scheme but I am new).

How are you running your DC motors? Via PWM? Maybe the PWM for one motor is generated using Timer 1 so obviously that does not work after resetting the timer to count.

I am running my motors using PID controller and they are named differently. In the timer I call them morot_A and motor_B but in the running motors function I am using motor1 and motor2 names.

U can check it all in the code i attached to my post.

Ok the problem is with the use of Timer1 function. Why does it cause this problem?

I don't see a program file attached to your Original Post, I see an image file. If you want us to view an image please make it visible in your Post. See this Simple Image Guide

However don't post a picture of a program because it can't be copied to a text editor.

A clear description of the hardware you are using would also be helpful - especially the datasheet for the speed sensors.

I can't imagine why you would need to use the Timer1 function.

...R

JohnyNapalm:
I am running my motors using PID controller and they are named differently. In the timer I call them morot_A and motor_B but in the running motors function I am using motor1 and motor2 names.

Your naming has nothing to do with the actual hardware being used. The Timer 1 of your arduino is configured to generate a signal for one of the motors and you reconfigured it to count ticks instead.

But I dont have encoder motors, I use LM393 sensors instead

JohnyNapalm:
But I dont have encoder motors, I use LM393 sensors instead

Post a link to the datasheet for your sensors. I suspect there is more to it than an LM393 - which just seems to be a comparator chip.

If you are using a slotted optical switch then you need to explain how you are using it to detect the speed.

...R

Robin2:
I don't see a program file attached to your Original Post, I see an image file. If you want us to view an image please make it visible in your Post. See this Simple Image Guide

However don't post a picture of a program because it can't be copied to a text editor.

A clear description of the hardware you are using would also be helpful - especially the datasheet for the speed sensors.

I can't imagine why you would need to use the Timer1 function.

...R

The sensor I am using is https://www.waveshare.com/wiki/Photo_Interrupter_Sensor
I edited my post as you wished.

Ok I am gonna tell you what I want my robot to do.
I want to send true of fallse of working of each motors, and average speed of both of them to SD card.
For exampe:

Right Engine / Left engine / average speed
1 1 20

and I want to send this message every second.

This is like pulling teeth. How does the sensor interact with your motor?

You are looking for help with something for which you have all the info and we have none, except what you tell us. So tell us everything about it.

It is easier to make sense of a program with a clear understanding of the hardware.

...R

Sensor interacts with my motors thanks to this small wheels:


And I have posted the code like 3 times already, thru pastebin
one more try: #include <SPI.h>#include <SD.h> #include <AFMotor.h>//#include <NewPing. - Pastebin.com

should I use millis() function to send message every 1 second without interrupting the whole program?

I'm losing the will to live. How do the small wheels interact with the sensors?

...R

I've took a quick look at your code:

  1. The AFMotor library is depreceated. Is there a reason for you to use it?
  2. Don't ever use goto in your program. And by that I mean never - there is no reason to use it.
  3. What Arduino are you using?
  4. Your Timer 1 interrupt is way to long. You even write to your sd card in there ...

LightuC:
I've took a quick look at your code:

  1. The AFMotor library is depreceated. Is there a reason for you to use it?
  2. Don't ever use goto in your program. And by that I mean never - there is no reason to use it.
  3. What Arduino are you using?
  4. Your Timer 1 interrupt is way to long. You even write to your sd card in there ...
  1. So what libary for motor shield should I use?
  2. Ok I changed that
  3. Arduino Mega 2560 with L293D motorshield
  4. I know that this timer is bad and I removed it. I just dont know how to write to my sd card data, without interrupting my robots work. It can even stop for a half a second, send data and go back to driving all the time, but I dont know how to do it.

Let's forget about speed sensors, I can shut them down for now because I want to focus on data printin

Robin2:
I'm losing the will to live. How do the small wheels interact with the sensors?

...R

Sorry but I am new and not english native speaker so I might not undersand everything.

//counting pulse motor1
void ISR_count_A() {
  counter_A++;
}
//counting pulse motor2
void ISR_count_B() {
  counter_B++;
}


//rise countr1 when speed sensor pin is high
attachInterrupt(digitalPinToInterrupt (motor_A), ISR_count_A, RISING);
//rise countr2 when speed sensor pin is high
attachInterrupt(digitalPinToInterrupt (motor_B), ISR_count_B, RISING);



  
  Serial.print("Motor1 Speed: ");
  float rotation_A = (counter_A / diskslots) * 60.00; //(RPM) for motor1
  Serial.print(RMPtoCmS(rotation_A));
  Serial.print(" Cm/s - ");
  counter_A = 0;

  Serial.print("Motor2 Speed: ");
  float rotation_B = (counter_B / diskslots) * 60.00; //(RPM) for motor2
  Serial.print(RMPtoCmS(rotation_B));
  Serial.println(" Cm/s");
  counter_B = 0;

This is the only way that speed sensors have anything to do with motors. They dont set speed to them or anything. Just measuring speed. Lest forget about them now

JohnyNapalm:

  1. So what libary for motor shield should I use?
  2. Ok I changed that
  3. Arduino Mega 2560 with L293D motorshield
    [4.] I know that this timer is bad and I removed it. I just dont know how to write to my sd card data, without interrupting my robots work. It can even stop for a half a second, send data and go back to driving all the time, but I dont know how to do it.
  1. You have to do a bit of research yourself on that one.
  2. Good, because:
  3. On the Arduino Mega 2560 motor 1 uses timer 1
  4. Okay, so that is a completely different problem. The answer is: you can't. With a single core processor like the arduino, without any dma, how would that even work? The SD library is already using the SPI with interrupts and that is as asynchronous as it can get. Why do you even need to write to the sd card every second? You can buffer the data in memory, stop the robot and then write the big chunk of recorded data to sd.

LightuC:
You can buffer the data in memory, stop the robot and then write the big chunk of recorded data to sd.

Ok that sounds nice! I am gonna do a research about writing to buffer memory. Thank u very much

JohnyNapalm:
Sorry but I am new and not english native speaker so I might not undersand everything.

Let's make things very simple.

When you rotate the "small wheel" exactly one turn what happens to the sensor?

...R

Robin2:
Let's make things very simple.

When you rotate the "small wheel" exactly one turn what happens to the sensor?

...R

The ''small wheel" have an ammount of 20 holes in it as you could see on the previous picture.
The sensor have a transmiter and reciver "looking at each other" ( U shape) and their are placed between the small wheel.
So when there is a part of the small wheel with the hole in it, sensor reciver can see the light beam of transmiter, and the sensor pin goes HIGH. And and when the small wheel blocks the beam of light sensor pin goes LOW.