I've literally been tearing my hair out over this so any help is very much appreciated, believe me!
The basic setup I have is 2 nanos, 1 in my shed to monitor a battery bank and temperature and to control a servo. The other one in the house receives and displays the battery bank status and temperature with no problem. However, I wish to be able to use 2 buttons in the house to control that servo in the shed,(and 2 LEDs, red and green for off and on) which in turn controls the brake for a wind turbine.
At the moment, it works perfectly as the basic "monitor".
I have a separate sketch that works the 2 buttons/1 servo on the same nano, again no problem. The problems start when I try to split the sketch and implement it into my other ones. I have tried for weeks but am getting nowhere fast.
I have returned my sketches to the basic "monitor" again and will include these and the separate servo sketch also (On next post!). I have read and studied the Nrf24l01 tutorials but am still a bit lost when it comes to the compiling and sending of the data.
I'll also attach a Fritzing drawing i have made.
I am a bit of a noob (wish they had things like this when I was younger!) so please be patient!
Many thanks,
Andrew
House Nano -
//Buttons
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include <Fonts/FreeSans9pt7b.h>
#define CE_PIN 7
#define CSN_PIN 8
// OLED display TWI address
#define OLED_ADDR 0x3C
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET 0 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const byte addresses[][6] = {"00001", "00002"};
RF24 radio(CE_PIN, CSN_PIN);
int but1 = 4;
int but2 = 5;
char dataReceived[20]; // this must match dataToSend in the TX
bool newData = false;
boolean buttonState = 0;
float val2;
float temperature;
//===========
void setup()
{
// initialize and clear display
display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR);
display.clearDisplay();
pinMode(4, INPUT);
pinMode(5, INPUT);
Serial.begin(9600);
Serial.println("Receiver starting");
radio.begin();
radio.setPALevel(RF24_PA_MIN);
radio.setDataRate( RF24_2MBPS );
radio.openWritingPipe(addresses[0]); // 00002
radio.openReadingPipe(1, addresses[1]); // 00001
radio.startListening();
}
//=============
void loop(){
getData();
showData();
}
//==============
void getData()
{
if ( radio.available() )
{
radio.read( &dataReceived, sizeof(dataReceived) );
newData = true;
}
}
void showData()
{
if (newData == true)
{
Serial.print("Data received ");
Serial.println(dataReceived);
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(dataReceived, ","); // get the first part - the string
val2 = atoi(strtokIndx) / 100.00;
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
temperature = atoi(strtokIndx) / 100.00;
Serial.print("Battery Voltage ");
Serial.print(val2);
Serial.print("V ");
Serial.print(" Temperature ");
Serial.print(temperature);
Serial.println("deg C");
display.drawRect(0, 0, 128, 64, WHITE);
display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE, BLACK);
display.setCursor(70,25);
display.setTextSize(1);
display.println("Temp");
display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE, BLACK);
display.setCursor(10,25);
display.setTextSize(1);
display.println("Batts");
display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE, BLACK);
display.setCursor(70,49);
display.setTextSize(1);
display.println(temperature);
display.setFont(&FreeSans9pt7b);
display.setTextColor(WHITE, BLACK);
display.setCursor(10,49);
display.setTextSize(1);
display.println(val2);
display.display();
display.clearDisplay();
newData = false;
}
}
Shed Nano -
//Servo
#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <BMP180MI.h>
#include <Servo.h>
Servo servo;
int angle =90; // initial angle for servo
int angleStep =180;
#define CE_PIN 7
#define CSN_PIN 8
#define I2C_ADDRESS 0x77
BMP180I2C bmp180(I2C_ADDRESS);
const byte addresses[][6] = {"00001", "00002"};
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
char dataToSend[20];
char txNum = '0';
unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second
// test data *******************************
float val2;
float temperature;
boolean buttonState = 0;
int val11;
void setup() {
pinMode(5, OUTPUT);
Wire.begin();
servo.attach(4); // attaches the servo on pin 4 to the servo object
servo.write(angle);// send servo to the middle at 90 degrees
Serial.begin(9600);
Serial.println("Sender Starting");
radio.begin();
radio.setPALevel(RF24_PA_MIN);
radio.setDataRate( RF24_2MBPS );
radio.openWritingPipe(addresses[1]); // 00001
radio.openReadingPipe(1, addresses[0]); // 00002
//begin() initializes the interface, checks the sensor ID and reads the calibration parameters.
if (!bmp180.begin())
{
Serial.println("begin() failed. check your BMP180 Interface and I2C Address.");
while (1);
}
//reset sensor to default parameters.
bmp180.resetToDefaults();
//enable ultra high resolution mode for pressure measurements
bmp180.setSamplingMode(BMP180MI::MODE_UHR);
}
//====================
void loop() {
float temp ; //Float..
val11 = analogRead (1) ; //Sets analog pin 1 as input
temp = val11 / 3.930 ; //Val1 divided by 4.092
val11 = (int) temp ; //get float
val2 = ((val11 % 200) / 11.18 ); //Value divider line. I set to 200% to read from a 12 volt system with a divider value of 11.18
delay (1000 ) ; //Every 1 second(s)
currentMillis = millis();
if (currentMillis - prevMillis >= txIntervalMillis) {
makePacket(val2, temperature);
send();
prevMillis = millis();
if (!bmp180.measureTemperature())
{
Serial.println("could not start temperature measurement, is a measurement already running?");
return;
}
//wait for the measurement to finish. proceed as soon as hasValue() returned true.
do
{
delay(100);
} while (!bmp180.hasValue());
Serial.print("Battery Voltage ");
Serial.print(val2);
Serial.print("V ");
Serial.print(" Temperature ");
Serial.print(bmp180.getTemperature());
Serial.println("deg C");
}
}
//====================
void makePacket(float val2, float temp)
{
// convert data to int for easier transmission
int batteryInt = val2 * 100;
int tempInt = bmp180.getTemperature() * 100;
// make packet
sprintf(dataToSend, "%d,%d", batteryInt, tempInt);
}
void send() {
bool rslt;
rslt = radio.write( &dataToSend, sizeof(dataToSend) );
// Always use sizeof() as it gives the size as the number of bytes.
// For example if dataToSend was an int sizeof() would correctly return 2
Serial.print("Data Sent ");
Serial.print(dataToSend);
if (rslt) {
Serial.println(" Acknowledge received");
}
else {
Serial.println(" Tx failed");
}
}