NRF24L01 modules not connecting - hardware or coding issue? - c++

I am trying to transmit data from an ultrasonic sensor to an LCD screen using two NRF24L01 modules connected to two separate Arduino UNOs for a distance sensor for a bike. As I am relatively new to Arduino and initially did not know how to use the NRF24L01 module, I followed a tutorial from https://www.electroniclinic.com/nrf24l01-multiple-transmitters-and-single-receiver-for-sensor-monitoring-using-arduino/
, implemented it into my code, and it is not working. I ensured on multiple occasions that the wiring for the NRF24L01 is correct for the Arduino UNOs and attempted to change radio channels, and no use. For others from the website it appeared to be working, but for me it is not. Both programs compile just fine. Is there an issue with my code or is it possible that my NRF24L01 is nonfunctional?
Here is my code:
Transmitter:
#include <RF24Network.h>
#include <RF24Network_config.h>
#include <Sync.h>
#include <RF24.h>
#include <SPI.h>
RF24 radio(5, 4); // radio module, pins 5,4 for (CE, CSN)
RF24Network network(radio);
const uint16_t this_node = 01; //address of arduino
const uint16_t node00 = 00;
//setting up pins for each device
const int buzzerPin = 10;
const int aheadTrigPin = 9;
const int aheadEchoPin = 8;
//initialize variables for ultrasonic sensor and data
unsigned long data[3];
unsigned long aheadDistance;
unsigned long aheadDuration;
void setup() {
Serial.begin(9600);
SPI.begin();
radio.begin();
network.begin(69, this_node);
radio.setDataRate(RF24_2MBPS);
pinMode(buzzerPin, OUTPUT);
pinMode(aheadTrigPin, OUTPUT);
pinMode(aheadEchoPin, INPUT);
}
void loop() {
//clears the "trig" condition for ultrasonic sensor
digitalWrite(aheadTrigPin, LOW);
delayMicroseconds(2);
//releases sound waves from ultrasonic sensor for 10 microseconds
digitalWrite(aheadTrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(aheadTrigPin, LOW);
//reads "echo" pin to return sound wave travel time in microseconds
aheadDuration = pulseIn(aheadEchoPin, HIGH);
//calculating distance of ultrasonic sensor, in inches (distance = velocity * time)
aheadDistance = (aheadDuration * 0.034 / 2) * 2.54;
Serial.println(aheadDistance);
//activates buzzer to alert rider if danger values are met
if(aheadDistance <= 100) {
tone(buzzerPin, 255);
}
else {
noTone(buzzerPin);
}
//send data to main component
network.update();
data[0] = aheadDistance;
RF24NetworkHeader header(node00);
bool ok = network.write(header, &data, sizeof(data)); // send data
Serial.println("sent to NRF24 server");
delay(200);
}
The reason I am sending an array as the data is because I am currently working on having another transmitter to send data to a single receiver.
Receiver:
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <RF24Network.h>
#include <RF24Network_config.h>
#include <Sync.h>
#include <RF24.h>
#include <SPI.h>
//sets up timer for the LCD display to constantly run
//sets up OLED screen
LiquidCrystal_I2C display(0x27,20,4);
RF24 radio (10, 9); // CE, CSN, defines new RF24 radio
RF24Network network(radio);
const uint64_t this_node = 00;
//data variables that will be collected from other arduinos
unsigned long data[3];
unsigned long aheadDistance;
unsigned long groundDistance;
unsigned long backAheadDistance;
void setup()
{
Serial.begin(9600);
display.init(); // intialize lcd
display.backlight(); //open backlight of lcd
display.clear();
//initialize starting screen
display.setCursor(0, 0);
//set up radio module (reciever)
SPI.begin();
radio.begin();
network.begin(69, this_node);
radio.setDataRate(RF24_2MBPS);
}
//method to update screen with current data values
void displayDistance() {
display.setCursor(0, 0);
display.print("Bike Sensor");
display.setCursor(0, 1);
display.print("Front: ");
display.print(aheadDistance);
display.print(" in");
display.setCursor(0, 2);
display.print("Ground: ");
display.print(groundDistance);
display.print(" in");
display.setCursor(0, 3);
display.print("Back: ");
display.print(backAheadDistance);
display.print(" in");
display.display();
}
void connectionLost() // activates when main component is unable to connect to others
{
display.clear();
display.setCursor(0, 1);
display.print("Connection");
display.setCursor(0, 2);
display.print("Lost");
display.display();
}
void loop()
{
network.update();
while(network.available()) {
RF24NetworkHeader header;
Serial.println("connection found");
network.read(header, &data, sizeof(data));
Serial.println("data recieved");
if(header.from_node == 01) {
backAheadDistance = data[0];
}
if(header.from_node == 02) {
aheadDistance = data[1];
groundDistance = data[2];
}
displayDistance();
delay(100);
}
connectionLost();
Serial.println("no connection found");
delay(200);
}
//updates OLED screen and actually displays it on the module

It’s possible that your nRF24L01 is dead. I’ve had many. Some fail. I recommend those from EByte especially ML01DP5 and ML01SP4. These are good.
Also there’s a little known hardware issue: never let the FIFO buffers remain full for over 4ms. Of course it’s hard to know. So simply flush them often as a precaution. I have fixed my code this way and now it’s robust.
Good luck!
Malcolm

Related

ESP32 Bluetooth connection status

I am running into some problems finding a solution when it comes to performing some form of Bluetooth connection check for my project that will allow me to have a connection status light.
My project consists of creating a Bluetooth speaker that has Led Strips controlled over Bluetooth serial (an app will be made to handle this) and audio stream over Bluetooth from a single ESP32.
I have found plenty of examples and had success with performing an spp callback event, however, of course this only works if I connect to the Bluetooth serial side of things through my 'Serial Bluetooth Terminal' app on my phone. If I just go into my phone Bluetooth list and connect to the audio side of things, nothing is registered, which isn't very useful for a Bluetooth speaker!
Basically I really need some help finding a way of registering that a device has connected to the Bluetooth audio so that I can have some form of indication light to tell the user that they are successfully connected to the speaker to play music.
Below is my code:
#include <btAudio.h> //<-------this is the library that I am using to handle Bluetooth audio to an external I2s DAC
#include "BluetoothSerial.h"
#include <FastLED.h>
TaskHandle_t Task1;
//POWER/BT-LIGHT-SETUP----------------------------------------
int powerPinR = 4;
int powerPinG = 16;
int powerPinB = 17;
bool BTisConnected;
//FAST-LED-STUFF----------------------------------------------
CRGB leds[NUM_STRIPS][NUM_LEDS];
CRGB leds_temp[NUM_STRIPS][NUM_LEDS/2];
//BLUETOOTH-SETUP---------------------------------------------
btAudio audio = btAudio("");
BluetoothSerial SerialBT;
//CONNECTION-CHECK--------------------------------------------
void callback(esp_spp_cb_event_t event, esp_spp_cb_param_t*param){
if(event == ESP_SPP_SRV_OPEN_EVT){
Serial.println("Client Connected");
BTisConnected = true;
}
else {
BTisConnected = false;
}
}
//------------------------------------------------------------
void setup() {
//CORE-1-INITIALISE
xTaskCreatePinnedToCore(
codeForTask1, /* Task function. */
"Task_1", /* name of task. */
1000, /* Stack size of task */
NULL, /* parameter of the task */
1, /* priority of the task */
&Task1, /* Task handle to keep track of created task */
0); /* Core */
//POWER/BLUETOOTH-CONNECTION-LIGHT-SETUP
pinMode(powerPinR, OUTPUT);
pinMode(powerPinG, OUTPUT);
pinMode(powerPinB, OUTPUT);
digitalWrite (powerPinR, HIGH);
digitalWrite (powerPinG, HIGH);
digitalWrite (powerPinB, HIGH);
//COOLDOWN-DELAY
delay(3000);
//AUDIO-INITIALISE
audio.begin();
int bck = 26;
int ws = 27;
int dout = 25;
audio.I2S(bck, dout, ws);
//LED-STRIP-SETUP-&-CLEAR-ALL
FastLED.addLeds<WS2812B,STRIP1PIN,GRB>(leds[0], NUM_LEDS);
FastLED.addLeds<WS2812B,STRIP2PIN,GRB>(leds[1], NUM_LEDS);
FastLED.clear();
FastLED.show();
//SERIAL-INITIALISE-&-CLIENT-CONNECTION-CHECK
Serial.begin(115200);
SerialBT.begin("Pilot"); //<-----BLUETOOTH NAME
SerialBT.register_callback(callback); //<-- SerialBT connection check works perfectly, but nothing for audio connection! :(
}
//CORE-0-VOID-LOOP--------------------------------------------
void codeForTask1( void * parameter )
{
for (;;) {
manageData();
delay(10);
}
}
//CORE-1-VOID-LOOP--------------------------------------------
void loop() {
BTconnectionCheck();
playScene();
}
//MANAGE-INCOMING-BLUETOOTH-SERIAL-DATA-----------------------------------------------
void manageData() {
//READ FROM SERIAL AND PARSE OUT ** READ FROM SERIAL AND PARSE OUT ** READ FROM SERIAL AND PARSE OUT **
char rawData[100] = "";
char keyword[] = "Mydata=";
if (SerialBT.available() > 0) {//new data in
size_t byteCount = SerialBT.readBytesUntil('\n', rawData, sizeof(rawData) - 1); //read in data to buffer
rawData[byteCount] = NULL;//put an end character on the data
const char delimiter[] = ",";
char parsedStrings[5][8]; //first number = how many bits of data - 2nd number = max size of eeach data
int dataCount = 0;
int dataPosition = 0;
char *token = strtok(&rawData[dataPosition], delimiter);//look for first piece of data after keyword until comma
if (token != NULL && strlen(token) < sizeof(parsedStrings[0])) {
strncpy(parsedStrings[0], token, sizeof(parsedStrings[0]));
dataCount++;
} else {
Serial.println("token to big");
strcpy(parsedStrings[0], NULL);
}
for (int i = 1; i < 5; i++) {
token = strtok(NULL, delimiter);
if (token != NULL && strlen(token) < sizeof(parsedStrings[i])) {
strncpy(parsedStrings[i], token, sizeof(parsedStrings[i]));
dataCount++;
} else {
Serial.println("token to big");
strcpy(parsedStrings[i], NULL);
}
}
if (dataCount == 5) {
scene = atoi (parsedStrings[0]);
hue = atoi(parsedStrings[1]);
saturation = atoi(parsedStrings[2]);
brightness = atoi(parsedStrings[3]);
eventInterval = atol (parsedStrings[4]);
}
}
}
//BLUETOOTH-CONNECTION-CHECK---------------------------------------------------------
void BTconnectionCheck(){
SerialBT.register_callback(callback);
if (BTisConnected == true){
bluetoothConnected();
}
else {
bluetoothSearch();
}
}
void bluetoothSearch(){
digitalWrite (powerPinR, LOW);
digitalWrite (powerPinG, LOW);
digitalWrite (powerPinB, HIGH);
}
void bluetoothConnected(){
digitalWrite (powerPinR, HIGH);
digitalWrite (powerPinG, LOW);
digitalWrite (powerPinB, HIGH);
}
I have cut lots of the code to do with the LEDs out but its still quite long, If it would help to have a more condensed version then I will chop it down further. Or if it helps to have the full code then I can also post it.
Any help would be greatly appreciated as I am well and truly stuck with this one and its a pretty important part of the project.
Thanks in advance!

Set up loop keeps looping (Adurino)

I am currently troubleshooting a code in Arduino for a temperature and humidity project. There is a line in the void setup(), Serial.println("Feather LoRa TX Test!");, which keeps popping up. My ideal code is to run that particular line once in the output and that will be it. However, the current code keeps repeating that line again, and again. May I know how do I rectify this issue (The whole code is below)? Thanks in advance!!
#include <RH_RF95.h>
#include <DHT.h>
#define DHTPIN 7 // what digital pin we're connected to
#define DHTTYPE DHT22 // DHT 11
DHT dht(DHTPIN, DHTTYPE);
#define RFM95_CS 10
#define RFM95_RST 9
#define RFM95_INT 3
// Change to 434.0 or other frequency, must match RX's freq!
#define RF95_FREQ 915.0
// Singleton instance of the radio driver
RH_RF95 rf95(RFM95_CS, RFM95_INT);
int node = 3; // to change based on node deployment
void setup()
{
pinMode(RFM95_RST, OUTPUT);
digitalWrite(RFM95_RST, HIGH);
while (!Serial);
Serial.begin(9600);
delay(100);
Serial.println("Feather LoRa TX Test!");
digitalWrite(RFM95_RST, LOW);
delay(100);
digitalWrite(RFM95_RST, HIGH);
delay(100);
while (!rf95.init()) {
Serial.println("LoRa radio init failed");
while (1);
}
Serial.println("LoRa radio init OK!");
// Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM
if (!rf95.setFrequency(RF95_FREQ)) {
Serial.println("setFrequency failed");
while (1);
}
Serial.print("Set Freq to: "); Serial.println(RF95_FREQ);
dht.begin();
rf95.setTxPower(23, false);
}
void loop()
{
float t = dht.readTemperature();
float h = dht.readHumidity();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
delay(1000);
return;
}
String d = "{\"Node\":"+ String (node) +",";
d += "\"Temp\":"+ String (t)+",";
d += "\"Hum\":"+ String (h);
d += "} "; // Add a trailing space is necessary
Serial.println("Transmitting...");
char data[d.length()];
d.toCharArray(data,d.length());
Serial.println(d);
rf95.send((uint8_t*)data, sizeof(data));
Serial.println("Waiting for packet to complete...");
delay(1000);
rf95.waitPacketSent();
Serial.println(" complete...");
delay(57000); // delay 1 minute
}
You have an infinite loop before you do any initialization. This will be detected because Arduino have a watchdog timer, and the system will reset.
And on reset setup is called again, and you again enter the infinite loop.
The loop it's about:
while (!Serial);
You must call Serial.begin(...) before that loop:
Serial.begin(9600);
while (!Serial);
Something is resetting your MCU before the code reaches the loop function. Therefore the setup function gets executed again and again. You can add more print messages in between lines so you'll know where it breaks.

Read Received via SPI data with arduino mega

There
I am working on one of the project, in that i am trying to read 16-bit data from ADS8681. Currently i get the correct waveform of SCk,MISO,MOSI and SCK on oscilloscope. But I am not able to print data on alphanumeric LCD. With readRegister(long thisRegister, long bytesToRead) also unable to print data. Can anyone suggest me how i print received data?
References which i am using:
1] https://www.arduino.cc/en/Tutorial/LibraryExamples/BarometricPressureSensor#code
Source Code :
#include <SPI.h>
#include <LiquidCrystal.h>
#define SS 53 // CS/CONVST
LiquidCrystal lcd (38,37,36,35,34,33);
void setup()
{
lcd.begin(16,4);
SPI.begin();
digitalWrite(SS,OUTPUT);
digitalWrite(SS, HIGH);
delay(10);
digitalWrite(SS,LOW);
writeRegister(0x14, 0x0001); //Write data range selection
digitalWrite(SS, HIGH);
delay(10);
digitalWrite(SS,LOW);
writeRegister(0x10, 0x4100); //Write Data_OUT_CTRL
lcd.setCursor(0,0);
lcd.print ("Data");
}
void loop()
{
digitalWrite(SS, HIGH);
delay(10);
digitalWrite(SS,LOW);
writeRegister(0x14, 0x0001); //Write data range selection
delay(100);
}
void readRegister(long thisRegister, long bytesToRead)
{
}
void writeRegister(word thisRegister, word thisValue)
{
}

Entering multiple SPI interfaces

I am having a problem with my code for arduino m0 (using microchip SAMD21). There are two SPI interfaces, first classic and second with int variable in front of the pin name, int MISO, for instance. Does someone know, how to control this classic SPI interface?
I have also attached my code.
PS: Code stucks in begin function of OZONE2CLICK sensor...
#include "Arduino.h"
#include <MQ131.h>
// include RFM69 library
#include <SPI.h>
// Local
#define PC_BAUDRATE 56700
#define MS_DELAY 0 // Number of milliseconds between data sending and LED signalization
#define LED_DELAY 100
#define Serial SerialUSB
// SD card
#define sd_cs_pin 35 // set SD's chip select pin (according to the circuit)
float PPMO2;
float PPBO2;
float MGM3O2;
float UGM3O2;
const byte pinSS = 2; //cs pin
const byte pinRDY = 12;
const byte pinSCK = 13;
const byte O2Pin = 10;
#define DcPin 8
// SD card file
File file; // SD library variable
// LEDS
#define D13_led_pin 42 // D13 LED
#define M_led_pin 36 // MLED
// Local variables
int idCounter = 1;
bool isBmeOk = true;
bool isSdOk = true;
bool isRadioOk = true;
bool isGpsConnected = true;
void OZONE2CLICKCalibrate ()
{
Serial.println("2");
//MQ131.begin(pinSS, pinRDY, O2Pin, LOW_CONCENTRATION, 10000); //(int _pinCS, int _pinRDY, int _pinPower, MQ131Model _model, int _RL)
Serial.println("99");
Serial.println("Calibration in progress...");
MQ131.calibrate();
Serial.println("Calibration done!");
Serial.print("R0 = ");
Serial.print(MQ131.getR0());
Serial.println(" Ohms");
Serial.print("Time to heat = ");
Serial.print(MQ131.getTimeToRead());
Serial.println(" s");
}
void OZONE2CLICKMeasure ()
{
Serial.println("Sampling...");
MQ131.sample();
Serial.print("Concentration O3 : ");
PPMO2 = MQ131.getO3(PPM);
Serial.print(PPMO2);
Serial.println(" ppm");
Serial.print("Concentration O3 : ");
PPBO2 = MQ131.getO3(PPB);
Serial.print(PPBO2);
Serial.println(" ppb");
Serial.print("Concentration O3 : ");
MGM3O2 = MQ131.getO3(MG_M3);
Serial.print(MGM3O2);
Serial.println(" mg/m3");
Serial.print("Concentration O3 : ");
UGM3O2 = MQ131.getO3(UG_M3);
Serial.print(UGM3O2);
Serial.println(" ug/m3");
}
void setup()
{
Serial.begin(PC_BAUDRATE);
// wait for the Arduino serial (on your PC) to connect
// please, open the Arduino serial console (right top corner)
// note that the port may change after uploading the sketch
// COMMENT OUT FOR USAGE WITHOUT A PC!
// while(!Serial);
Serial.println("openCanSat PRO");
Serial.print("Node ");
Serial.print(MYNODEID,DEC);
Serial.println(" ready");
// begin communication with the BME280 on the previously specified address
// print an error to the serial in case the sensor is not found
if (!bme.begin(BME280_ADDRESS_OPEN_CANSAT))
{
isBmeOk = false;
Serial.println("Could not find a valid BME280 sensor, check wiring!");
return;
}
// begin communication with the INA219
ina219.begin();
// check of Gps is connected
Wire.beginTransmission(0x42); // 42 is addres of GPS
int error = Wire.endTransmission();
if (error != 0)
{
isGpsConnected = false;
}
// begin communication with gps
gps.begin();
// Uncomment when you want to see debug prints from GPS library
// gps.debugPrintOn(57600);
if(!radio.initialize(FREQUENCY, MYNODEID, NETWORKID))
{
isRadioOk = false;
Serial.println("RFM69HW initialization failed!");
}
else
{
radio.setFrequency(FREQUENCYSPECIFIC);
radio.setHighPower(true); // Always use this for RFM69HW
}
pinMode(D13_led_pin, OUTPUT);
}
void loop()
{
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);
pinMode(DcPin, OUTPUT);
pinMode(O2Pin, OUTPUT);
digitalWrite(DcPin, HIGH);
digitalWrite(O2Pin, HIGH);
delay(10000);
OZONE2CLICKCalibrate();
OZONE2CLICKMeasure();
}
It looks the code opening the SPI connection is commented out:
MQ131.begin(pinSS, pinRDY, O2Pin, LOW_CONCENTRATION, 10000);
You need to configure the SPI connection to get any data from your device.
Refer to reference code from the manufacturer or library you're using to make sure your programming against it correctly.
Please format your code with predictable spacing. This is pretty hard to read.
Since you're using C++, prefer to use:
constexpr <type> NAME = <value>;
rather than macros:
#define NAME (<value>)
Since this is a bare metal compilation, using return in the setup() or loop() functions does not stop them. You probably want something more like while (true) {}. This will loop the code indefinitely, rather than proceed in a bad state.
i.e.:
void stop_forever() {
Serial.println("fatal error detected, stoping forever.");
while (true) {}
}
// then, use it later:
// ...
if (error) {
stop_forever();
}
// ...

Arduino wireless servo code

I'm trying to make a contraption where you press a button on one board and it moves the servo either to 90 degrees or 180 degrees on the other board. If it's at 90 then it moves to 180 and vice versa.
I'm not very knowledgeable when it comes to this stuff as this is my first major project so bear with me. I already have the wireless system working (thanks to hours of Googling) and a toggle system for an LED (for testing to see if the wireless is working).
I'm using one of the tiny RF transmitters, two Nanos, and a servo from Radio Shack. The problem is the servo doesn't turn but my test LED turns on and off. Here is the code for the receiver end of things:
#include <VirtualWire.h>
#include <ServoTimer2.h>
const int releu_pin = 9;
const int servoPin = 6;
const int transmit_pin = 12;
const int receive_pin = 3;//pin connected between RX module and Arduino
const int transmit_en_pin = 5;
ServoTimer2 myservo;
void setup() {
myservo.attach(servoPin);
myservo.write(45);
vw_set_tx_pin(transmit_pin);
vw_set_rx_pin(receive_pin);
vw_set_ptt_pin(transmit_en_pin);
vw_set_ptt_inverted(true);
vw_setup(2000);//speed communication bps
vw_rx_start(); // activate receiving mode
pinMode(releu_pin, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT); //Debug
}
void loop() {
uint8_t buf[VW_MAX_MESSAGE_LEN];
uint8_t buflen = VW_MAX_MESSAGE_LEN;
if (vw_get_message(buf, &buflen)) {
//verify if any data is received
if(buf[0]=='1') {
//if received 1 turn ON releu_pin
myservo.write(90);
digitalWrite(releu_pin , HIGH);
digitalWrite(LED_BUILTIN, HIGH); //Debug
delay(100);
}
if(buf[0]=='0') {
myservo.write(180);
digitalWrite(releu_pin , LOW);
digitalWrite(LED_BUILTIN, LOW); //Debug
delay(100);
}
}
}