Hi all,
I have been trying to send commands through Simulink (publisher) to arduino node (subscriber) but have some problems. I can make communications between my arduinos (one UNO and the other one NANO) wirelessly using two NRF24L01 modules. I can also program to subscribe a node in ROS, then I can send continuous values (PWM) to that node and see that using “rostopic echo …” command. However, I am not able to combine the two! In other words, I would like one of my arduinos (say NANO) be connected to the computer using USB, connect to it using rosserial, publish any subscribed node and get values back from my publisher block in Simulink. So far I have been able to do these! Now I want that published value which is sent to my NANO through rosserial (USB cable) be sent over to the other arduino (UNO) as well (wirelessly through NRF24L01 module). The received message in UNO should be shown in terms of a change in a voltage of pin 2 for example.
Code for the transmitter (NANO) is as follows:
#include <ros.h>
#include <std_msgs/Int8.h>
#include "Arduino.h"
#include <SPI.h>
#include <RF24.h>
ros::NodeHandle nh;
RF24 radio(7, 8);
byte addresses[][6] = {"1Node", "2Node"};
//int toggle_msg;
void messageCb( const std_msgs::Int8& toggle_msg){
digitalWrite(2, toggle_msg.data);
}
ros::Subscriber<std_msgs::Int8> sub("Arduino", messageCb);
void setup()
{
Serial.begin(9600);
pinMode(2,OUTPUT);
digitalWrite(2,0);
delayMicroseconds(10);
// nh.initNode();
// nh.subscribe(sub);
// Serial.begin(9600);
Serial.println("THIS IS THE TRANSMITTER CODE - YOU NEED THE OTHER ARDIUNO TO SEND BACK A RESPONSE");
// Initiate the radio object
radio.begin();
// Set the transmit power to lowest available to prevent power supply related issues
radio.setPALevel(RF24_PA_MIN);
// Set the speed of the transmission to the quickest available
radio.setDataRate(RF24_2MBPS);
// Use a channel unlikely to be used by Wifi, Microwave ovens etc
radio.setChannel(124);
// Open a writing and reading pipe on each radio, with opposite addresses
radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1, addresses[0]);
// Random number seeding (we're going to be sending a single random number)
randomSeed(analogRead(A0));
nh.initNode();
nh.subscribe(sub);
}
void loop()
{
// Generate a single random character to transmit
unsigned int data = toggle_msg;
// Ensure we have stopped listening (even if we're not) or we won't be able to transmit
radio.stopListening();
// Did we manage to SUCCESSFULLY transmit that (by getting an acknowledgement back from the other Arduino)?
// Even we didn't we'll continue with the sketch, you never know, the radio fairies may help us
if (!radio.write( &data, sizeof(unsigned char) )) {
Serial.println("No acknowledgement of transmission - receiving radio device connected?");
}
// Now listen for a response
radio.startListening();
// But we won't listen for long, 200 milliseconds is enough
unsigned long started_waiting_at = millis();
// Loop here until we get indication that some data is ready for us to read (or we time out)
while ( ! radio.available() ) {
// Oh dear, no response received within our timescale
if (millis() - started_waiting_at > 200 ) {
Serial.println("No response received - timeout!");
return;
}
}
// Now read the data that is waiting for us in the nRF24L01's buffer
unsigned char dataRx;
radio.read( &dataRx, sizeof(unsigned char) );
// Show user what we sent and what we got back
Serial.print("Sent: ");
Serial.print(data);
Serial.print(", received: ");
Serial.println(dataRx);
// Try again 1s later
delay(1000);
digitalWrite(2, 10);
delayMicroseconds(10);
nh.spinOnce();
delay(1000);
}
Code for the receiver (UNO) is as follows:
#include "Arduino.h"
#include <SPI.h>
#include <RF24.h>
// This is just the way the RF24 library works:
// Hardware configuration: Set up nRF24L01 radio on SPI bus (pins 10, 11, 12, 13) plus pins 7 & 8
RF24 radio(7, 8);
byte addresses[][6] = {"1Node","2Node"};
// -----------------------------------------------------------------------------
// SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP SETUP
// -----------------------------------------------------------------------------
void setup() {
Serial.begin(9600);
Serial.println("THIS IS THE RECEIVER CODE - YOU NEED THE OTHER ARDUINO TO TRANSMIT");
// Initiate the radio object
radio.begin();
// Set the transmit power to lowest available to prevent power supply related issues
radio.setPALevel(RF24_PA_MIN);
// Set the speed of the transmission to the quickest available
radio.setDataRate(RF24_2MBPS);
// Use a channel unlikely to be used by Wifi, Microwave ovens etc
radio.setChannel(124);
// Open a writing and reading pipe on each radio, with opposite addresses
radio.openWritingPipe(addresses[0]);
radio.openReadingPipe(1, addresses[1]);
// Start the radio listening for data
radio.startListening();
pinMode(2, OUTPUT);
}
// -----------------------------------------------------------------------------
// We are LISTENING on this device only (although we do transmit a response)
// -----------------------------------------------------------------------------
void loop() {
// digitalWrite(2, 1);
// This is what we receive from the other device (the transmitter)
unsigned char data;
// Is there any data for us to get?
if ( radio.available()) {
// Go and read the data and put it into that variable
while (radio.available()) {
radio.read( &data, sizeof(char));
digitalWrite(2, data);
}
// No more data to get so send it back but add 1 first just for kicks
// First, stop listening so we can talk
radio.stopListening();
data++;
radio.write( &data, sizeof(char) );
// Now, resume listening so we catch the next packets.
radio.startListening();
// Tell the user what we sent back (the random numer + 1)
Serial.print("Sent response ");
Serial.println(data);
}
// if (! radio.available()) {
// digitalWrite(2 ,1);
// }
}
Both codes inspired from HERE
I would appreciate any help!