NRF24L01 to send serial data

Hi

Ok those are the final code and they works.

Transmitter

The nano takes what's coming on his RX pin and send it.

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

String serialdata; //Holds data coming in
char msg[32]; //Char array to send data out with

RF24 transmit (9,10);                    //create RF24 object called transmit

byte address [6] = "00001";             //set address to 00001

void setup() {
  Serial.begin(9600);
  Serial.println ("Serial Port Open");
  
  transmit.begin();
  transmit.openWritingPipe(address);    //open writing pipe to address 00001
  transmit.setPALevel(RF24_PA_MAX);     //set RF power output to maximum
  transmit.setDataRate(RF24_250KBPS);   //set datarate to 250kbps
  transmit.setChannel(20);             //set frequency to channel 20
  transmit.stopListening();   
   }

void loop() {

  if (Serial.available()){
    delay (200);
    Serial.println ("I found Serial Data");// If you are having issues, these will help you find where your code doesnt work.
    serialdata=Serial.readString();//put text from serial in serialdata string¸
  }
    
    else {

      serialdata.toCharArray(msg, 32);//convert serialdat the the msg char array
      Serial.println ("I converted it to a CHAR ARRAY");
      Serial.println("Text to be Sent-");//debugging
      Serial.println("");//debugging
      Serial.print(msg);//debugging
      Serial.println("");//debugging     
   }

  transmit.write(msg, 32);    
}

This is the receiver code

it receive numbers between comma and displays it on an OLED display.

#include <Wire.h> //IIC Library
#include <Adafruit_SSD1306.h>
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);

#include <nRF24L01.h>
#include <printf.h>
#include <RF24.h>
#include <RF24_config.h>

RF24 receive (9,10);                         //create object called receive
byte address [5] = "00001";                 //creat an array with 5 elements, where each element is 1 byte;

String text = " ";//String to hold the text

void setup()
{
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  
  display.clearDisplay();
  display.setTextColor(WHITE);
  display.setCursor(25,0);  
  display.setTextSize(1);
  display.print(F("Scuba Receiver"));
  display.display();
  
  delay (1500);//set this to the interval

  Serial.begin(9600);
  Serial.print("Starting Receiver \n");
  receive.begin();
  receive.openReadingPipe(0,address);      //open reading pipe 0 at address 00001 
  receive.setPALevel(RF24_PA_MAX);         //Set RF output to maximum
  receive.setDataRate(RF24_250KBPS);       //set datarate to 250kbps
  receive.setChannel(20);                 //set frequency to channel 20 
  receive.startListening(); 

}

void loop(){

  
    if (receive.available())                //check when received data available
  {
    char buf[32];
    receive.read(&buf, sizeof(buf));
    text = (char*)buf;
    Serial.println(text);
    display.clearDisplay();
  }

    if (text.startsWith(",")) {
      int sepLocation[5];
      int index = text.indexOf(",");
      int i = 0;
      String extractedValues[4];
      while (index >= 0) {
        sepLocation[i] = index;
        i++ ;
        index = text.indexOf(",", index + 1);
      }
      for (int o = 0; o < 4; o++) {
        extractedValues[o] = text.substring((sepLocation[o] + 1), sepLocation[(o + 1)]);
      }
 
           display.setCursor(0, 0);
           display.setTextColor(WHITE, BLACK);
           display.setTextSize(1);
           display.print("PSI = " + extractedValues[0]);
           display.display();
            
           display.setCursor(0, 12);
           display.setTextColor(WHITE, BLACK);
           display.setTextSize(1);
           display.print("Oxygen = " + extractedValues[1] + "%");
           display.display();
                  
           display.setCursor(0, 25);
           display.setTextColor(WHITE, BLACK);
           display.setTextSize(1);
           display.print("Temp = " + extractedValues[2] + "C");
           display.display();             

           display.setCursor(80, 25);
           display.setTextColor(WHITE, BLACK);
           display.setTextSize(1);
           display.print("CO = " + extractedValues[3] + "");
           display.display();
    }
    delay (500);
   }

For now it's working and I will not change it except if it's only minor changes.
With time I will learn better and I will come back to it when I'm ready. Like I did
in my other project but for now I need to install this so I can use it.

I found examples of code to remotely control LED with the NRF24L01 and
I will try tomorrow to includ them in this code. I will certainly have some
bugs and if so, I will post it under a new topic.

Many many thanks for all the help.

The nano takes what's coming on his RX pin

For completeness, can you please post the UNO code which is reading the sensors and sending the Serial to the Nano for transmission?

Why do you have this two Arduino design, instead of the Uno reading the sensors and transmitting the data?

Because the UNO was already working and controling my scuba compressor. I decided not to touch it and create an addon instead with the nano. This way if something go wrong with the transmitter, at least I can continu to use my compressor.

I just tried to put the code in this post but it exceed the 9000 caracters so the forum refuse it.

I just tried to put the code in this post but it exceed the 9000 caracters so the forum refuse it.

If you use the REPLY button to bring up a new reply window, you will find a way to attach your code. This option is not available with the quick reply.

//Library

#define _DEBUG

#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <Adafruit_ADS1015.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <RunningAverage.h>
#include <Adafruit_LiquidCrystal.h>

unsigned long previousMillis1 = 0;
const long interval1 = 1000;
const long interval2 = 2000;
const long interval3 = 3000;
const long interval4 = 4000;


#define ONE_WIRE_BUS 7 // Data wire is plugged into pin 7 on the Arduino
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)

OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature. 
DallasTemperature sensors(&oneWire);



int photocellPin = 0;     // the cell and 10K pulldown are connected to a0
int photocellReading;     // the analog reading from the sensor divider

Adafruit_LiquidCrystal lcd_1(0); //LCD Display 16,4 for O2, MOD and PSI 
LiquidCrystal_I2C lcd_2(0x3F,16,2); // LCD 16,2 for Temperature and monoxyde alarme

#define RA_SIZE 20
RunningAverage RA(RA_SIZE);

Adafruit_ADS1115 ads_O2 (0x49);
Adafruit_ADS1115 ads_PSI (0x48);

// activer les RELAY et boutons

int pinButton1 = A1;  // Power compressor
int RELAY1 = 3;
int stateRELAY1 = LOW;
int stateButton1;

int pinButton2 = 9;  // Oxygen input 
int RELAY2 = 4;
int stateRELAY2 = LOW;
int stateButton2;

int pinButton3 = 10;  // Power circuit purge compressor
int RELAY3 = 5;
int stateRELAY3 = LOW;
int stateButton3;

int RELAY4 = 6;  // Buzzer output
int stateRELAY4 = LOW;

// section pour le PSI
int16_t rawADCvalue;  // The is where we store the value we receive from the ADS1115 for PSI
float scalefactor = 0.1250F; // This is the scale factor for the default +/- 4096 Volt Range we will use
float PSI = 0.0; // The result of applying the scale factor to the raw value

//Debounce and button foor O2 calibration
int previous = LOW;
long time = 0;
long debounce = 300;
const int buttonPin=2; // push button

double calibrationv;
float multiplier_O2;
float multiplier_PSI;

int programState = 0;
int buttonState;
long buttonMillis = 0;
const long intervalButton = 2000; // 2 sec button hold to calibration

/*
 Calculate MOD (Maximum Operating Depth)
*/

float max_po1 = 1.40;
float max_po2 = 1.60;
float cal_mod (float percentage, float ppo2 = 1.4) {
  //return 10 * ( (ppo2/(percentage/100)) - 1 ); // Metric meter
  return 33 * ( (ppo2/(percentage/100)) - 1 );  // in feet
}

int read_sensor(int x=0) {
  int16_t millivolts = 0;  
  if (x == 0) {
    millivolts = ads_O2.readADC_Differential_0_1();
    RA.addValue(millivolts);
  }
}


void setup() {

  #ifdef _DEBUG
  
  #endif 

  lcd_1.begin(16,4);
  lcd_1.clear();
  lcd_2.begin(16,2);
  lcd_2.init();
  lcd_2.backlight(); 
  lcd_2.clear();



  pinMode(pinButton1, INPUT); //Power compressor
  pinMode(RELAY1, OUTPUT);

  pinMode(pinButton2, INPUT); //Input Oxygen
  pinMode(RELAY2, OUTPUT);

  pinMode(pinButton3, INPUT); //Power for purge compressor
  pinMode(RELAY3, OUTPUT);

  pinMode(RELAY4, OUTPUT);

  //DEbounce button
  pinMode(buttonPin,INPUT_PULLUP); //Button for calibration



  ads_O2.begin(); // ads1115 Pour O2 initialize
  ads_PSI.begin(); // ads1115 pour PSI initialize

  ads_O2.setGain(GAIN_TWO);
  multiplier_O2 = 0.0625F;

  ads_PSI.setGain(GAIN_ONE);
  //multiplier_PSI = 0.1250F;

  RA.clear();
  for(int cx=0; cx<= RA_SIZE; cx++) {
    read_sensor(0);
  }  
  
  calibrationv = EEPROMReadInt(0);
  if (calibrationv < 100) calibrationv=calibrate(0);
  
}

void EEPROMWriteInt(int p_address, int p_value){
     byte lowByte = ((p_value >> 0) & 0xFF);
     byte highByte = ((p_value >> 8) & 0xFF);
     EEPROM.write(p_address, lowByte);
     EEPROM.write(p_address + 1, highByte);
     }

unsigned int EEPROMReadInt(int p_address){
     byte lowByte = EEPROM.read(p_address);
     byte highByte = EEPROM.read(p_address + 1);
     return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
     }

int calibrate(int x){  
  lcd_1.clear();
  lcd_1.print(F("Calibrating"));
  double result;  
  for(int cx=0; cx<= RA_SIZE; cx++) {
    read_sensor(0);
  }
  result = RA.getAverage();
  result = abs(result);
  EEPROMWriteInt(x, result); // write to eeprom
  delay(1000);

  return result;
  
}


void analysing_O2(int x, int cal, String txt) {
  double currentmv;
  double result;
  double mv = 0.0;
  
  read_sensor(x);  
  currentmv = RA.getAverage();
  currentmv = abs(currentmv);
  
  result = (currentmv / cal) * 20.9;
  if (result > 99.9) result = 99.9;
  mv = currentmv * multiplier_O2;

    unsigned long currentMillis = millis();
  buttonState = digitalRead(buttonPin); 

  if (buttonState == LOW && programState == 0) {
    buttonMillis = currentMillis;
    programState = 1;
  } 
  
  else if (programState == 1 && buttonState == HIGH) {
    programState = 0;
  }

  if(currentMillis - buttonMillis > intervalButton && programState == 1) {
    calibrationv=calibrate(0); // calibration
    programState = 1;
  }

    lcd_1.setCursor(0,0);
    if (mv < 0.02) {
    lcd_1.print(F("Sensor error!"));
  } else
  
  {
    lcd_1.print(txt);    
    lcd_1.print(result,1);
    lcd_1.print(F("% "));
    lcd_1.print(mv,1);
    lcd_1.print(F("mv"));
    
    lcd_1.setCursor(0,1);
    lcd_1.print(F("MOD 1.4 = "));
    lcd_1.print(cal_mod(result,max_po1),0);
    lcd_1.print(F("ft "));
    lcd_1.setCursor(-4,2);
    lcd_1.print(F("MOD 1.6 = "));
    lcd_1.print(cal_mod(result,max_po2),0);
    lcd_1.print(F("ft "));
  }

  if (result > 40){
    stateRELAY2 = LOW; //Stop Oxygen input
  }


 
Serial.begin(9600);
  
if (currentMillis - previousMillis1 >= interval1) {

Serial.print(",");
Serial.print(PSI,0);
Serial.print(",");
Serial.print(result,1);
Serial.print(",");
Serial.print(sensors.getTempCByIndex(0),1);
Serial.print(",");
Serial.print(photocellReading);
Serial.println(",");

previousMillis1 = currentMillis;
}
 
 return;
}


void Temperature()
{
  // Send the command to get temperatures
  sensors.requestTemperatures();
  lcd_2.setCursor(0,0);
  lcd_2.print(F("Compressor:"));  
  lcd_2.print(sensors.getTempCByIndex(0),1);
  lcd_2.print(F("C"));

 return;
}


void Pression(){

  rawADCvalue = ads_PSI.readADC_SingleEnded(0);
  PSI = (rawADCvalue * scalefactor);
    
     {
    lcd_1.setCursor(-4, 3);
    lcd_1.print(F("PSI     = "));
    lcd_1.print(PSI);  // enlever le (PSI, 0) pour (PSI) a repar� le refresh de la pression mais a ajout� un d�cimal.
   }
  
  if (PSI > 3150){
    stateRELAY1 = LOW; //Stop Compressor
    stateRELAY2 = LOW; //Stop Oxygen input
 //   stateRELAY3 = LOW; //Stop Purge timer
  }

    if (PSI > 3125){
    stateRELAY2 = LOW; //Stop Oxygen input
  }
  
 return;
}


void Button(){

{
    //bouton 1 Compressor
    stateButton1 = digitalRead(pinButton1);
    if (stateButton1 == HIGH && previous == LOW && millis() - time > debounce) { //if button is pressed and RELAY is off
      if (stateRELAY1 == HIGH) {
        stateRELAY1 = LOW;
        stateRELAY2 = LOW;         
      } else {
        stateRELAY1 = HIGH;
      
      }
      time = millis();
    }
    digitalWrite(RELAY1, stateRELAY1);
    previous == stateButton1;

    // bouton 2 Oxygen input
    stateButton2 = digitalRead(pinButton2);
    if (stateButton2 == HIGH && previous == LOW && millis() - time > debounce) { //if button is pressed and RELAY is off
      if (stateRELAY2 == HIGH) {
        stateRELAY2 = LOW;
      } else {
        stateRELAY2 = HIGH;
      }
      time = millis();
    }
    digitalWrite(RELAY2, stateRELAY2);
    previous == stateButton2;

    //bouton 3  Purge timer circuit
    stateButton3 = digitalRead(pinButton3);
    if (stateButton3 == HIGH && previous == LOW && millis() - time > debounce) { //if button is pressed and RELAY is off
      if (stateRELAY3 == HIGH) {
        stateRELAY3 = LOW;
      } else {
        stateRELAY3 = HIGH;
      }
      time = millis();
    }
    digitalWrite(RELAY3, stateRELAY3);
    previous == stateButton3;
  }
    return;
 }


void LightSensor(){

  photocellReading = analogRead(photocellPin);
  
  if (photocellReading > 500){  //adjust light sentivity

    stateRELAY4 = HIGH;
    lcd_2.setCursor(0,1);
    lcd_2.print(F("Monoxyde: Alarme"));

    stateRELAY1 = LOW; //Stop Compressor
    stateRELAY2 = LOW; //Stop Oxygen input
   // stateRELAY3 = LOW; //Stop Purge timer
  }
  
  else{
  
    stateRELAY4 = LOW;
    lcd_2.setCursor(0,1);
    lcd_2.print(F("Monoxyde:   Safe"));
  }
  {
    digitalWrite(RELAY4, stateRELAY4);
  }
  
  return;
  }

void loop(){

  Button();
  analysing_O2(0,calibrationv,"O2 ");
  Pression();
  Temperature();
  LightSensor();
}