TB6612FNG and NRF24l01 help

I’m trying to use a Arduino Nano the talk to a Arduino Mega (usingNRF24l01), and (among other things) get momentary switches to operate a 12V dc motor Via. a TB6612.

So far I have had success with other aspects of this project in communicating between the 2 Arduinos, and only am having odd results with this aspect of what is a much larger undertaking.

Simply put: I’m trying to run 1 Dc motor, where, when one of 2 buttons on the Transmitter Arduino is pressed, the Dc motor on the Receiver Rotates either Clockwise or Counterclockwise and stops when neither button is pressed.

I have successfully gotten the NRF24’s working in al other sketches and the example sketch the sparkfun library is working fine on the Mega running the dc motor from the TB6612 so I know all connections are correct and working as expected.

However, when trying to put the two together nothing works. When I took the motor portion out of the sketch, and just had it try and light and LED (pin 22) the led would stay lit and with the motor portion (sketch below) left in, the motor just spins and does not stop. So I think it might have something to do with it constantly reading the pin as HIGH.

In the sketches below I’ve only have data sent out for 1 button, figured if I could get one working right I could just copy it for the second with a negative motor value.

Can anyone help point me in the right direction?

Thank you!

Transmitter:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define sentLed 4
#define rightButton 3
#define leftButton 5

RF24 radio(7, 8 ); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
int buttonValue;
boolean buttonState = 0;


void setup() {
  pinMode(sentLed, OUTPUT);
  pinMode(rightButton, INPUT_PULLUP);
  pinMode(leftButton, INPUT_PULLUP);
  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_MIN);
}
void loop() {
  delay(5);

  radio.stopListening();
  buttonState = digitalRead(rightButton);
  radio.write(&buttonState, sizeof(buttonState));
}

Recever:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <SparkFun_TB6612.h>

#define led 22

#define AIN1 24
#define BIN1 28
#define AIN2 26
#define BIN2 30
#define PWMA 5
#define PWMB 6
#define STBY 9

RF24 radio(7, 8 ); // CE, CSN

const byte addresses[][6] = {"00001", "00002"};
int buttonValue;
const int offsetA = 1;
const int offsetB = 1;
boolean buttonState = 0;

Motor motor1 = Motor(AIN1, AIN2, PWMA, offsetA, STBY);
Motor motor2 = Motor(BIN1, BIN2, PWMB, offsetB, STBY);

void setup()
{
  pinMode(22, OUTPUT);
  radio.begin();
  radio.openWritingPipe(addresses[1]); // 00002
  radio.openReadingPipe(1, addresses[0]); // 00001
  radio.setPALevel(RF24_PA_MIN);
}
void loop()
{
  delay(5);

  radio.startListening();
  while (!radio.available());
  radio.read(&buttonState, sizeof(buttonState));
  if (buttonState == HIGH) {
    motor1.drive(100);
    delay(1000);
  }
}

Try moving the delay(1000) from the Rx program to the Tx program.

You should have no delay()s in the Rx program and you should keep the transmissions as infrequent as possible. Five per second should be quite enough to be responsive. That would be (roughly) delay(200);

...R
Simple nRF24L01+ Tutorial

When posting code please use the code button </>
codeButton.png

so your code 
looks like this

and is easy to copy to a text editor See How to use the forum

Robin2:
Try moving the delay(1000) from the Rx program to the Tx program.

Moving the Delay had no effect on the issue, tho I understand what your saying.

I've also tried changing the if to a while, but the same issue persisting. Again, changing the motor control, to an led via a digitalWrite HIGH, keeps the Led lit. and adding a Else digitalWrite LOW turns off the led (opposite of what SHOULD be happening) but has no effect when the same is applied to the motor via a motor1.brake(); function. even tho In previous sketches for the other parts of this project the Led pin is setup and defined exactly the same, and works as expected.

Then I suggest you put your program to one side and get the first example in my Tutorial working.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The examples are as simple as I could make them and they have worked for other Forum members. If you get stuck it will be easier to help with code that I am familiar with.

There is also a connection test program to check that the Arduino can talk to the nRF24 it is connected to.

A common problem with nRF24 modules is insufficient 3.3v current from the Arduino 3.3v pin. The high-power nRF24s (with the external antenna) will definitely need an external power supply. At least for testing try powering the nRF24 with a pair of AA alkaline cells (3v) with the battery GND connected to the Arduino GND.

...R

Robin2:
Then I suggest you put your program to one side and get the first example in my Tutorial working.

Wireless problems can be very difficult to debug so get the wireless part working on its own before you start adding any other features.

The wireless portion is working just fine. again, this IS the 5th feature I've added and am well confidant that its communicating just fine. As far as the other sketches and features using the NRF24, all work like a charm even when combined together.
The only thing that seams to a problem at the moment is this one button, that when sent over the NRF24 is returning a HIGH state. and I'm having problems figuring out why, in other situations, while using analogRead as buttons returns a LOW state until open on the same LED. But a digitalRead is sending a HIGH while open.

When I re-upload other sketches NOT dealing with the digitalRead button with the same connections all function as indicated with no problems.

and the 3.3v is not a issue as the NRF24 is powered correctly via the 5v adapter module to solve this issue.

Have you tried printing buttonState immediately before you send it - maybe the wireless is not sending what you think it is sending?

...R

Ok, so I figured out the “button” issue. it was perhaps a faulty button, replaced it and It’s working.

However Now I’ve gotten the button(s) transmitting correctly, I’m working on a problem with the code as it pertains to the tb6612fng and the sparkfun library.

While using one button: the motor spins in one direction fine, and stops when the button is not pressed but changing the speed as directed has no effect.

when I added the second button (sketch below), the motor spins in the same direction for both button despite the - number for the speed. ALSO button one now just pulses forward one tinny increment at a time, And also in the same direction as button 2 (again despite the difference in positive or negative numbers for the speed)

I’m following example and information on this tutorial Sparkfun but I’m either completely missing something or there is a simpler way to do this i also don’t understand.

Again, I’m using 1 motor, and while “button1” is pressed motor is supposed to rotate right at a set speed, and when “button2” is pressed, its supposed to rotate Left at a set speed, and stop when neither is pressed.

anyone Help make heads or tails out of this?

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <SparkFun_TB6612.h>

#define led 22

#define AIN1 24
#define BIN1 28
#define AIN2 26
#define BIN2 30
#define PWMA 5
#define PWMB 6
#define STBY 9

RF24 radio(7, 8); // CE, CSN

const byte addresses[][6] = {"00001", "00002"};
int buttonValue;
const int offsetA = 1;
const int offsetB = 1;
boolean buttonState1 = 0;
boolean buttonState2 = 0;

Motor motor1 = Motor(AIN1, AIN2, PWMA, offsetA, STBY);
Motor motor2 = Motor(BIN1, BIN2, PWMB, offsetB, STBY);

void setup()
{
  pinMode(22, OUTPUT);
  radio.begin();
  radio.openWritingPipe(addresses[1]); // 00002
  radio.openReadingPipe(1, addresses[0]); // 00001
  radio.setPALevel(RF24_PA_MIN);
}
void loop()
{
  delay(5);

  radio.startListening();
  buttonState1 = digitalRead(3);
  buttonState2 = digitalRead(5);
  while (!radio.available());
  radio.read(&buttonState1, sizeof(buttonState1));
  radio.read(&buttonState2, sizeof(buttonState2));
  // motor button 1 right
  if (buttonState1 == HIGH) {
    digitalWrite(led, HIGH);
    motor1.drive(100);
  }
  // motor button 2 left
  else if (buttonState2 == HIGH) {
    digitalWrite(led, HIGH);
    motor1.drive(-100);
  }
  else {
    brake(motor1, motor2);
    digitalWrite(led, LOW);
  }
}

BubbleHockey:
Again, I'm using 1 motor, and while "button1" is pressed motor is supposed to rotate right at a set speed, and when "button2" is pressed, its supposed to rotate Left at a set speed, and stop when neither is pressed.

That's not a good way to think about the problem.

Instead you should send one message when the button is pressed and another message when the button is released. Apart from anything else it greatly reduces the amount of wireless traffic that you generate.

If you need more help please post the latest version of both the Tx and the Rx programs

...R

Robin2:
Instead you should send one message when the button is pressed and another message when the button is released. Apart from anything else it greatly reduces the amount of wireless traffic that you generate.

If you need more help please post the latest version of both the Tx and the Rx programs

everything I have tried along those lines has failed or reproduced the pulsing of “// motor button 1 right”.
I have tried several attempts throwing out the Sparkfun Library and just setting up functions but also get varying versions of the same issue, sometimes both buttons.
BUT, when I remove everything having to do with the motors and just light an LED all works fine.

Here are the 2 Sketches as of the previous post (closest I’ve gotten)

Transmitter:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define sentLed 4
#define rightButton 3
#define leftButton 5

RF24 radio(7, 8); // CE, CSN
const byte addresses[][6] = {"00001", "00002"};
int buttonValue;
boolean buttonState1 = 0;
boolean buttonState2 = 0;


void setup() {
  pinMode(sentLed, OUTPUT);
  pinMode(rightButton, INPUT_PULLUP);
  pinMode(leftButton, INPUT_PULLUP);
  radio.begin();
  radio.openWritingPipe(addresses[0]); // 00001
  radio.openReadingPipe(1, addresses[1]); // 00002
  radio.setPALevel(RF24_PA_MIN);
}
void loop() {
  delay(5);

  radio.stopListening();
  buttonState1 = digitalRead(rightButton);
  buttonState2 = digitalRead(leftButton);
  radio.write(&buttonState1, sizeof(buttonState1));
  radio.write(&buttonState2, sizeof(buttonState2));
  delay(200);
}

Receiver:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <SparkFun_TB6612.h>

#define led 22

#define AIN1 24
#define BIN1 28
#define AIN2 26
#define BIN2 30
#define PWMA 5
#define PWMB 6
#define STBY 9

RF24 radio(7, 8); // CE, CSN

const byte addresses[][6] = {"00001", "00002"};
int buttonValue;
const int offsetA = 1;
const int offsetB = 1;
boolean buttonState1 = 0;
boolean buttonState2 = 0;

Motor motor1 = Motor(AIN1, AIN2, PWMA, offsetA, STBY);
Motor motor2 = Motor(BIN1, BIN2, PWMB, offsetB, STBY);

void setup()
{
  pinMode(22, OUTPUT);
  radio.begin();
  radio.openWritingPipe(addresses[1]); // 00002
  radio.openReadingPipe(1, addresses[0]); // 00001
  radio.setPALevel(RF24_PA_MIN);
}
void loop()
{
  delay(5);

  radio.startListening();
  buttonState1 = digitalRead(3);
  buttonState2 = digitalRead(5);
  while (!radio.available());
  radio.read(&buttonState1, sizeof(buttonState1));
  radio.read(&buttonState2, sizeof(buttonState2));
  // motor button 1 right
  if (buttonState1 == HIGH) {
    digitalWrite(led, HIGH);
    motor1.drive(100);
  }
  // motor button 2 left
  else if (buttonState2 == HIGH) {
    digitalWrite(led, HIGH);
    motor1.drive(-100);
  }
  else {
    brake(motor1, motor2);
    digitalWrite(led, LOW);
  }
}

You should not be sending the two values separately like this

  buttonState1 = digitalRead(rightButton);
  buttonState2 = digitalRead(leftButton);
  radio.write(&buttonState1, sizeof(buttonState1));
  radio.write(&buttonState2, sizeof(buttonState2));

Put the two values into an array and send the array as a single message

  byte buttonState[2];
  buttonState[0] = digitalRead(rightButton);
  buttonState[1] = digitalRead(leftButton);
  radio.write(&buttonState, sizeof(buttonState));

and have an equivalent array in the receiving program

Have you studied, and tried the examples in my Tutorial?

...R

Robin2:
You should not be sending the two values separately like this

Put the two values into an array and send the array as a single message
and have an equivalent array in the receiving program

Have you studied, and tried the examples in my Tutorial?

…R

THANK YOU!!! that worked!

Why did that work tho?, I see its a simpler way to send the values, but did they not do essentially the same thing?
Sorry just looking to understand, not just get it done, as I have several more things to add to this sketch Ie: sending analog button values along with it, and it may come in handy. (which I’m now changing to arrays).

I did try your tutorial (with some changes, I’m using a nano and a mega) it was very helpful when I first got started on this. Obviously I fell off the rails a bit tho.

BubbleHockey:
Why did that work tho?, I see its a simpler way to send the values, but did they not do essentially the same thing?

Sending separate values means sending separate wireless messages a few millisecs apart. There is no guarantee that the receiver will get both of them and if it doesn't then it won't know which one it did receive. Think of it like trying to make sense of a group of small kids shouting at the same time.

Put all the values into an array and make sure it does not exceed 32 bytes.

If you want to send different datatypes (for example a byte and an int) then put them into a struct and send the struct. My I2C tutorial uses structs in a way that is very similar to what you would do with an nRF24

...R

Robin2:
Sending separate values means sending separate wireless messages a few millisecs apart. There is no guarantee that the receiver will get both of them and if it doesn't then it won't know which one it did receive. Think of it like trying to make sense of a group of small kids shouting at the same time.

Put all the values into an array and make sure it does not exceed 32 bytes.

If you want to send different datatypes (for example a byte and an int) then put them into a struct and send the struct. My I2C tutorial uses structs in a way that is very similar to what you would do with an nRF24

...R

Thank you!

That actually helps a lot. I'll put a muzzle on the kids. :slight_smile:

One Follow-up question. what Im sending over from one to the other is those 2 digital inputs, 2 (so far) analog "buttons" reading values from pins A2 and A3 as switches, and 1 joystick controlling 2 other motors.

Since the analog pins have a build analog to digital converter, would they be sent in the same Array?

something like this?

byte buttonState = { A2, A3, A4, 3, 5, };
buttonState[0] = analogRead(A2); //analog button1
buttonState[1] = analogRead(A3); //analog buttons 2
buttonState[2] = analogRead(A4); //Joystick
buttonState[3] = digitalRead(3); //motor button right
buttonState[4] = digitalRead(5); //motor button left
radio.write(&buttonState, sizeof(buttonState));

If not, Can you Send I2C over the Nrf24? I thought It was for communicating between 2 wired Arduinos via a clock pin?

BubbleHockey:
something like this?

byte buttonState = { A2, A3, A4, 3, 5, };
buttonState[0] = analogRead(A2); //analog button1
buttonState[1] = analogRead(A3); //analog buttons 2
buttonState[2] = analogRead(A4); //Joystick
buttonState[3] = digitalRead(3); //motor button right
buttonState[4] = digitalRead(5); //motor button left
radio.write(&buttonState, sizeof(buttonState));

That's nearly correct. You need to define buttonState as int (rather than byte) to hold the results of analogRead()

This line makes no sense

byte buttonState[] = { A2, A3, A4, 3, 5, };

You are starting off with the pin numbers, not the values. All you need is this

int buttonState[5];

If not, Can you Send I2C over the Nrf24?

Of course not. I just provided the link so you could see how I used structs so you could bring the concept into your nRF24 program if it would be useful.

...R

Robin2:
That's nearly correct. You need to define buttonState as int (rather than byte) to hold the results of analogRead()

Of course not. I just provided the link so you could see how I used structs so you could bring the concept into your nRF24 program if it would be useful.

...R

Ah Good I thought I missed something and was doing even more things wrong! :slight_smile:

Thank you SO much!! you have been a huge help! I'm not quite out of the woods yet with this project, but this part is working and I can apply most of it going forward.

Thanks Again!