BTS7960-M behaves weirdly after using it in if condition

Hello guys! I am pretty new in the world of arduinos. I am currently doing a project where i use 2 BTS7960 to control four motors. My problem is after i set up if conditions to be able to control the movement of the robot with a remote control, the movement of the engines completely mess up. Even though testing the motors without the if conditions seemed to be working fine and had no problems with the behaviour of the motors. This is my code since i can't upload files. Thanks for your help in advance!

#include <IRremote.h>
int jobbr_pwm = 3;
int jobbl_pwm = 5;
int balr_pwm = 9;
int ball_pwm = 10;
//int sw = 2;
//int button;
//const int x = 0;
//const int y = 1;

IRrecv IR(11);


void setup() {
  // put your setup code here, to run once:
 pinMode(3, OUTPUT);
 pinMode(5, OUTPUT);
 pinMode(9, OUTPUT);
 pinMode(10, OUTPUT);
 //pinMode(0, INPUT);
 //pinMode(1, INPUT);
 //pinMode(sw, INPUT);
 //digitalWrite(sw, HIGH);
 Serial.begin(9600);
 IR.enableIRIn();
}


void loop() {
  // put your main code here, to run repeatedly:
if(IR.decode()){
  Serial.println("i am here");
  Serial.println(IR.decodedIRData.decodedRawData, HEX);
  if (IR.decodedIRData.decodedRawData == 0x65DC8646 ){ // elore
    Serial.println("i go forward");
    analogWrite(jobbr_pwm, 50);
    analogWrite(jobbl_pwm, 0);
    analogWrite(balr_pwm, 50);
    analogWrite(ball_pwm, 0);
    Serial.println("forward");
    IR.resume();
  } else if (IR.decodedIRData.decodedRawData == 0xCC112BC2){ // hatra
    analogWrite(jobbr_pwm, 0);
    analogWrite(jobbl_pwm, 50);
    analogWrite(balr_pwm, 0);
    analogWrite(ball_pwm, 50);
    Serial.println("backwards");
    IR.resume();
  } else if (IR.decodedIRData.decodedRawData == 0x879B92C2){ // balra
    analogWrite(jobbr_pwm, 0);
    analogWrite(jobbl_pwm, 50);
    analogWrite(balr_pwm, 50);
    analogWrite(ball_pwm, 0);
    Serial.println("left");
    IR.resume();
  } else if (IR.decodedIRData.decodedRawData == 0x46868606 ){ // jobbra
    analogWrite(jobbr_pwm, 50);
    analogWrite(jobbl_pwm, 0);
    analogWrite(balr_pwm, 0);
    analogWrite(ball_pwm, 50);
    Serial.println("right");
    delay(200);
    IR.resume();
  } else if (IR.decodedIRData.decodedRawData == 0x28DE45AA ){ // all
    // If you intend to do something when this condition is met, add the corresponding code here.
    analogWrite(jobbr_pwm, 0);
    analogWrite(jobbl_pwm, 0);
    analogWrite(balr_pwm, 0);
    analogWrite(ball_pwm, 0);
    IR.resume();
    Serial.println("stop");
  } else {
    
  }
}
}

Welcome to the forum.

Can you describe this more?

One thing I notice, which may not be your, or even a, problem, is your placement of

    IR.resume();

all over the code. Do it once, in one place, every time you get anything from the remote

stop");
  } else {
// you could add code here to see if commands came through what you had no code for
    Serial.println("Hey, I don't know what to do with that, yet!");
  }

// like here, only
  IR.resume();
}

HTH

a7

Then the way You coded the "if's" contain an error.
Not knowing the IR library, here's a guess:
You call the IR decode function over and over again. Why not use an unsigned long variable receiving the result of a decode, and then, in "if" testing against this "long variable"?

To be sure the wiring, a schematics might be good. Way too often improper powering, or wiring cause trouble.

No guessing, please.

This receives

IR.decode()

and the results are decoded in the IrReceiver.decodedIRData structure. Of which IR.decodedIRData.decodedRawData is part.

I guess, after looking at the documentation and the example

HTH

a7

Yes, sure. But.... calling that function over and over again and new messages are coming... What happens then?
My guess was like: don't try to read an input buffer twice.

As the main idea, yes. But.... so many times questions are terribly poor and guesses are often posted as replies. An illness spreading out here?

There is one call per loop.

    if (IrReceiver.decode()) {

It returns true if there is something worth looking at in the IrReceiver .decodedIRData structure.

The OP's flow is the same as the example, other than the scattering of the calls to resume(), which may be OK logically, but would be clearly OK if there were but one, one each time a command was decoded and handled (or ignored).

Looking closer at the example, it seems like resume() might should be called as soon as right away decode() returns true.

a7

All of the four engines would need to go straight when i press the forward button on my remote control, but instead of them turning on, only 2 of the 4 engines turn on and those two engines are the 2 left one and whats more the left engine for example becomes right or the right one left if i change just one value when i use analogWrite. To male sure you better understand this problem. Take a look at what motors would need to be turned on when going forward. With that fommand only my left side turns on but if i change one value from 0 to 50 and the one from 50 to 0 there’s still no change in the movement of the motors or it starts going backwards imstead of forwards. Btw i believe my if conditions are fine cause i get back the correct messages in serial monitor whenever i press the direction i want to go. For example if i press forward the serial monitor says forward or when i press right it says right

Hi, @gerizon1122
Welcome to the forum.

What model Arduino are you using?

Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.
Please not a Fritzy image.

Thanks.. Tom... :grinning: :+1: :coffee: :australia:

I am afraid that i cannot provide you a right drawing of my circuit, although as i said before i had no problem with using the motors before the if statement, so i believe everything is plugged in correctly. I believe i mess something up in the programming part. Btw i use an arduino uno r3

OK I reviewed the values sent via PWM, and you did use good serial printing to demonstrate the flow of your program.

Which printing is correct according to your report.

Therefore, this is not a software problem. More accurately, I should say that at this time your focus should be on hardware, as that is currently the most likely cause of your trouble.

Ans also why we ask for pictures, schematics showing all parts, all connections and all sources of power and how power is routed to the parts that need it.

An alternative use of your time would be to build this project in the simulator. It has both an IR remote and an IR receiver you could use.

You could use LEDs on the PWM pins as proxies for the motors.

It would not take long; I believe this will rule out the possibility of a software defect.

a7

No, it did not. I used my time waiting for she who must not be kept waiting (yes - another spectacular day for the beach!) to place your code in the simulator.

I had to use different received constants, as the remote they have sends different codes. And I used LEDs where the motors go.

I used 255 instead of 50 for the PWM by defining a constant so it can be easily changed. Dimmed LEDs aren't the greatest in the simulator. But I made it adjustable:

# define kFIFTY  255  // light 'em up! was 50 all over the place

The code functions perfectly.

Then I replaced the constant

# define kFIFTY  50  // use original value

And... the code fails. Just like it fails for you.

If you write 255 to a PWM output, it just turns the pin HIGH. If you use any lower value, it uses PWM to create your desired motor speed.

The IRremote library conflicts with PWM/analogWrite() on the UNO and messes it up.

So if you want to control the speed of your motors, you will have to find a different IR library that deos not use the same resources as PWM, or use another method to generate the PWM signal to control the speed of the motor instead of analogWrite().

I can see why this was driving you mad. Trust me, we all been there once or twice. :expressionless:

As a test, just put 255 into your code where you now have 50 in the calls to the motors pins.

HTH and too bad about that.

Just in time! I have received a text, she is rolling towards me now.

a7

I have actually found a solution to this somehow, but the code and the pins are completely random. Like i was just trying out different combinations until it worked. I actually need to record a video about the robot what i have already did. Thanks for your help and your latest advice, i am going to check it. Btw should i mark this thread as solved?

OK, now I am intrigued. Post the code that works, somehow.

I don't consider this solved until it is correctly explained. "Somehow" just doesn't allow me to sleep well. In this hobby, all questions have answers. Which makwes it good and bad at once. :expressionless:

a7

There you go! I have basically changed one pin and also i think i have actually changed up left and right on the motor driver too, and then somehow came up with the right solution.

#include <IRremote.h>
int jobbr_pwm = 6;
int jobbl_pwm = 5;
int balr_pwm = 9;
int ball_pwm = 10;
//int sw = 2;
//int button;
//const int x = 0;
//const int y = 1;

IRrecv IR(11);


void setup() {
  // put your setup code here, to run once:
 pinMode(3, OUTPUT);
 pinMode(5, OUTPUT);
 pinMode(9, OUTPUT);
 pinMode(10, OUTPUT);
 //pinMode(0, INPUT);
 //pinMode(1, INPUT);
 //pinMode(sw, INPUT);
 //digitalWrite(sw, HIGH);
 Serial.begin(9600);
 IR.enableIRIn();
}


void loop() {
  // put your main code here, to run repeatedly:
if(IR.decode()){
  
  if (IR.decodedIRData.decodedRawData == 0x65DC8646 ){ // elore
    Serial.println("i go forward");
    analogWrite(jobbr_pwm, 50);
    analogWrite(jobbl_pwm, 0);
    analogWrite(balr_pwm, 0);
    analogWrite(ball_pwm, 50);
    Serial.println("forward");
    
  } else if (IR.decodedIRData.decodedRawData == 0xCC112BC2){ // hatra
    analogWrite(jobbr_pwm, 0);
    analogWrite(jobbl_pwm, 50);
    analogWrite(balr_pwm, 50);
    analogWrite(ball_pwm, 0);
    Serial.println("backwards");
  
  } else if (IR.decodedIRData.decodedRawData == 0x879B92C2){ // balra
    analogWrite(jobbr_pwm, 50);
    analogWrite(jobbl_pwm, 0);
    analogWrite(balr_pwm, 50);
    analogWrite(ball_pwm, 0);
    Serial.println("left");
    
  } else if (IR.decodedIRData.decodedRawData == 0x46868606 ){ // jobbra
    analogWrite(jobbr_pwm, 0);
    analogWrite(jobbl_pwm, 50);
    analogWrite(balr_pwm, 0);
    analogWrite(ball_pwm, 50);
    Serial.println("right");
  } else if (IR.decodedIRData.decodedRawData == 0x28DE45AA ){ // all
    // If you intend to do something when this condition is met, add the corresponding code here.
    analogWrite(jobbr_pwm, 0);
    analogWrite(jobbl_pwm, 0);
    analogWrite(balr_pwm, 0);
    analogWrite(ball_pwm, 0);
    Serial.println("stop");
  } else {
    Serial.println("veszely");
  }
  IR.resume();
}
}

You got off pin 3, and switched to pin 6 for one of the four PWM signals, and that appears to get around the resource conflict.

Why exactly that solved it will be left to someone else to 'splain. In the meantime, it seems like there might be some, um, fragility here - I would not send this to the Moon or otherwise depend on it heavily not to crop up again with but the most innocent of changes to the code.

Until what's really the problem is known.

Moving stuff around on pins shouldn't matter, unless of course you happened to pick a non-PWM capable pin in the first place (a thing I checked at some point).

Fun! THX.

a7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.