text:
LED fading effect using a push button
Guys please help me out in verifying my program for my project -- led fading effect using a push button.
My project is simple, I want to start the LED fading effect (i.e., glowing and dimming one after another) at one click on the push button that is pushing and then leaving the push button and on my another click I want the effect to get off.
The main problem is coming in the programming part and rest all the circuit and components are fine.
THIS IS MY SKETCH :-
int ledpin = 9;
int buttonpin = 8;
boolean buttonpressed = false;   // to check whether the button was pressed //
int brightness = 0;
int fadeamount = 5;

void setup ()
{
pinMode (ledpin, OUTPUT);
pinMode (buttonpin,INPUT);
digitalWrite (ledpin,LOW);
}

void loop ()
{
if ( digitalRead (buttonpin) == HIGH)
 {
  buttonpressed = true;
 }

 else {
     if ( buttonpressed = true && digitalRead(ledpin) == LOW)
       {
           brightness = brightness + fadeamount;
           if ( brightness == 0 || brightness == 255)
            {
             fadeamount = -fadeamount;}
             analogWrite(ledpin, brightness);
             delay (30);
             buttonpressed = false;
        }
      if (buttonpressed == true && analogRead(ledpin) == brightness)
        {
          digitalWrite(ledpin,LOW);
          buttonpressed = false;
        }
   }
 }

THIS IS THE CIRCUIT DIAGRAM

Where's the resistor on your LED?

digitalWrite (buttonstate,HIGH); - What is that supposed to achieve?!

int fadeamount = 51; - That's a huge amount to fade by...

bro brightness doesn't matter i can change it any time to 5 or something low.......and about digitalWrite (buttonstate,HIGH); i used it to let the button state as high even after i leave the pushbutton so that the LED doesn't get off !!

i used it to let the button state as high even after i leave the pushbutton so that the LED doesn't get off !! well it doesn't. I don't know how you thought that might work. You're actually writing HIGH to either pin 0 or pin 1.

I think you meant to write buttonstate=HIGH; instead of digitalWrite (buttonstate,HIGH);

yep i got it wrong there...

@electromaniac That button is absolutely wrongly wired.... My suggestion, however, is to use a reverse logic: wire the button between pin 8 and ground, get rid of the resistor, then enable the internal pullup (pinMode(pushbutton,INPUT_PULLUP);). When you are reading the button, just invert the logic (digitalRead == LOW means that the button is pressed). Then I suggest you to use the Bounce2 library to debounce the button (search for it on google). And then, there are lots of problems (for instance brightness = 0 should be brightness == 0)

Your pull-down resistor on your button should be on the other side of the switch, and 1K is too low. You'll waste power. Use a 10K resistor instead. Or, as the other poster said, skip the resistor, invert your logic, and use INPUT_PULLUP mode.

I changed things a bit and got a solution
int led = 3;
int buttonpin = 8;
boolean waspressed = false;

int inertia = 10;

void setup (){
  pinMode(buttonpin,INPUT);
  pinMode(led,OUTPUT);
  analogWrite(led,0);
}

void loop(){
  if(digitalRead(buttonpin) == HIGH){
    waspressed = true;
  }else{
     if (waspressed == true){
       fadeLed(digitalRead(led), inertia);
       waspressed = false;
     }
  }
}

void fadeLed(boolean input, int inertia){
  for(int state=0;state<256;state++){
    if (input==LOW){
      analogWrite(led, state);
    }else{
      analogWrite(led, 255-state);
    }
    delay(inertia);
  }
}

I created a function called fadeLed that receives two arguments: The actual state of the led and the delay - in miliseconds - that is going to determine how long the fading is going to last.
You can see that the rest of the code is pretty much the one you got in the other question you asked. This is because we already got a good code to control the behavior of the button, so its a good practice to keep it and just change what you want to be changed: to fade instead of blink. So we just change a single line and create a function to be called by that line. Functions are a good way to keep a clean code and are a good programming practice. They make the code easy to read and maintain.
The function fadeLed() uses PWM to fade the led. In Arduino Uno, PWM is available in digital pins 3, 5, 6, 9, 10, and 11. This may change according to the model you are using. It's very important to understand PWM so you can know why analogWrite() is used in a digital pin.
If you check the documentation of analogWrite(), you are going to see that for most of the Arduino boards the default resolution is 8 bits, i.e, 0 to 255. To use all this 256 values to fade the led, a for loop is used. If you are not used to for loops, I strongly recommend you to read the documentation.
The for loop is programed to go through 256 iterations - the variable state going from 0 to 255. At each iteration, the value of state is incremented by 1. When state gets to be equal to 256, the loop ends itself. Every iteration verifies the value of input, which is just the state of the led when the button was released. This value is passed to the function only when the button is released, but the function uses it internally at every iteration. If input is LOW, it means that the led was off, so analogWrite(led, state); uses the value of state - increasing at every iteration - to fade the led, turning it on. If input is  HIGH, it means that the led was on, so analogWrite(led, 255-state); will fade the led turning it off. In this case, 255-state is just a way to set a range starting at 255 and ending at 0 while using a range that we already have - state - that starts at 0 and ends at 255.
The last line is just to set how long the fade action is going to last. To be more specific, delay(inertia) determine how long each iteration is going to last. So, when you set inertia to 10, will you see that fading will take 10(miliseconds)*255(iterations) + execution times =~ 2,6 seconds. I chose this name when I was coding and I'm not sure now if it was the better one. Maybe something like duration will have a more clear meaning. If you want to set the duration of the fade on your code - instead of the duration of each iteration - you can to something like
int fadeDuration = 3000; //duration of fade in ms

...

void fadeLed(boolean input, int inertia){
  for(int state=0;state<256;state++){
    if (input==LOW){
      analogWrite(led, state);
    }else{
      analogWrite(led, 255-state);
    }
    // delay in every iteration to achieve 3 seconds in total.
    delay(fadeDuration/256); //=(total fading duration)/(number of iterations)
  }
}

Hope this is clear. Don't forget to check the links I placed, they are all VERY important.

Can you explain me the use of inertia ? Also how are you using the fadeLed fuction ?

I tried to describe what I did. Check out

The 1k (pulldown-)resistor must be placed at the other side of the button (the pin8 side, not the 5v side).
The led needs a resistor, to limit the current.
There is no need for the buttonstate variable, as you can just check the brightness to see if the PWM value must be changed.
int ledpin = 9;
int pushbutton = 8;

int brightness = 0;
int fadeamount = 1;

void setup ()
{
  pinMode (ledpin,OUTPUT);
  pinMode (pushbutton,INPUT);
}

void loop ()
{
  if( digitalRead(pushbutton)==HIGH && brightness<255 )
  {
    // fade in led
    brightness = brightness + fadeamount;// increase brightness
    if( brightness>255 ) // check that brightness doesn't exceed 255
      brightness = 255;
    analogWrite(ledpin,brightness);
    delay (1);
  }
  else if( digitalRead(pushbutton)==LOW && brightness>0 )
  {
    // fade out led
    brightness = brightness - fadeamount;// decrease brightness
    if( brightness<0 ) // check that brightness doesn't go below 0
      brightness = 0;
    analogWrite(ledpin,brightness);
    delay (1);
  }

}

but this program will only work when i will push or leave the push button not like i wanted............i wanted the fading effect to continuously work even after leaving the push button. it should be like on first click(pressing and leaving) the fading effect should start and on another click the LED turns off again if i click the push button the fading effect should start and on my another click the LED turns off.

try this, its simple and easy to understand,
int ledPin = 9;
int btnPin = 8;
int brightness = 0;
int btnState = LOW;
bool trigger = LOW;
void setup ()
{
  pinMode (ledPin, OUTPUT);
  pinMode (btnPin, INPUT);
}

void loop ()
{
  if ( digitalRead(btnState) && !btnState)
  {
    if (trigger)
    {
      for (int i = 0; i < 256; i++)
      {
        analogWrite(ledPin, i);
        // wait for 30 milliseconds to see the dimming effect
        delay(30);
      }
    }
    else
    {
      for (int i = 255; i >= 0; i--)
      {
        analogWrite(ledPin, i);
        // wait for 30 milliseconds to see the dimming effect
        delay(30);
      }
    }
    trigger = !trigger;
  }
  btnState = digitalRead(btnState);
}

You might want to add some delay, or the fade is so fast you can see it.

There are basically two parts to your program and it's best if you deal with them completely separately:

Reading a push button to turn fading on or off
Fading if fading is turned on

Start by making an LED fade all the time. The Fade example can help you with that.
Then as a separate sketch program the button to turn an LED on or off each time you press it.
Once you have those working change the LED in the second sketch to setting a flag, and make the code from the first sketch look at that flag.

actually i had tried to make this sketch after learning to fade an LED and  toggling the the LED on and off using push button but something is still getting wrong.

Show us your LED toggling code.

@Majenko Tehee, try not to use the word "fool". But you've put some quite some effort into the question/answer which somewhat justifies it. But keep in mind that the way StackExchange works, might not be as trivial to new or foreign users (again and again indeed).

@Paul I was doing my Mr T impression. I guess these kids these days wouldn't recognise him if he jumped up in front of them and punched them in the face...

@Majenko, Ahaha, I was already thinking something, but such things can be hard to spot (depending on your frame of reference). In Germany, Mr. T wouldn't talk English (they've got those annoying voice-over things on TV) ;D and some Arduino Engineers might indeed not know him, yet. Fact of the day: "A snickers commercial (featuring Mr. T) was once banned from TV https://www.youtube.com/watch?v=Ona7QYULRVE"

I didn't get the reference. But then I never watched the A-team. You need to be careful with cultural references, sometimes they can go over people's heads due to age, country of origin, etc.

you should break down the code into two pieces, one to read the button and another to fade the led.
to fade an led, you just need to change its brightness and hold at that brightness for a short period of time. to drive the led at its brightness, use pwm.
that's all there is.
fancier ones will try to do a gamma correction but to just get started, the above is sufficient enough.


text:
Arduino Bluetooth Shield
A friend of mine bought two of these Bluetooth shields here. I have been trying to get the two Arduinos connected to each other through Bluetooth. I could not get it working myself but I found some code online here that I tried. The shields connect to each other (the lights on both turn red) but the I can't send data between them. Does anyone have any code that may works with these shields?

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Protecting your computer from stupid (arduino) mistakes
I recently ran way to much voltage through my Arduino and back into my computer via the USB connection. I'm looking for a USB hub with a fuse or some sort of protection to protect my laptop from these types of mistakes.  Any suggestions as to products that would serve this function or other precautions I might take?

If you used the barrel jack, the voltage wouldn't have reached the usb connector. So unless you connected the higher voltage to the 5V pin directly there isn't a problem.

Thanks for the advice all. In case you are wondering this is what I did http://electronics.stackexchange.com/q/223983/104362.  The board that I was attempting to probe was powered externally at 16vdc regulated to 12vdc.

Both the arduino and a USB port do have some protection against wrong connections and such. The arduino has a diode to prevent wrong polarity to reach your power supply, it also have a resetable fuse (the kinda big, often green SMD part close by your USB connection on your Arduino) that should protect your USB port pretty good from its side of the cable. Your USB port also have some good protections going on as far as i know, so basically it should be hard to break a USB port by accident.
That was the theoretical part, In real life things aren't always what they claim to be, so I use a cheap powered USB hub, that i always use as a first line of defense.

Not all Arduino have such protections: the Uno does, but a Nano is also part of the family.

The Nano is missing the polyfuse, but does have a diode to protect the USB

What happens on a UNO vs a Nano when you short +5v and GND? A completely different thing, and that is my point.
Anyway, +1 to cheap powered USB hub when unsure of schematic.

Anyone knows about nodeMCU? (Do they have some protection against wrong connections?)

There are a number of USB Isolator products available all around the world.
Here is a list of just a few:

Adafruit - USB Isolator
OLIMEX - USB Isolator
Avantech - USB Isolators
CESYS - USB Isolator
Hjelmslund Electronics - USBISO-AA

You get used to what not to do fairly quickly :)
Perhaps what you're after is a ruggeduino - http://www.rugged-circuits.com/ruggeduino/
I get the feeling that this sort of thing encourages bad habits, but then it also encourages more exploration.
You need to think carefully about what you're doing, if you put in any second source of power (e.g. USB + power plug, or USB + a signal from another device).

Please note, that I have no experience in this field, this is simply what I found after some digging.
I was concerned about connecting a Raspbery Pi Pico device to my brand new computer and did some digging in the "USB Power Delivery" specification:

7.1.7.1 Output Over Current Protection
Sources operating in SPR mode Shall implement over current
protection to prevent damage from output current that
exceeds the current handling capability of the Source. [...]

"Shall" means, that this is a mandatory requirement:

1.4.2.11 Shall/Normative
Shall and Normative are equivalent keywords indicating a mandatory
requirement.  Designers are mandated to implement all such requirements
to ensure interoperability with other compliant Devices.

At this point I am already confident enough to plug the device into my computer, so I'll stop digging into the details here.
My understanding is, that the USB controller will detect the fault, disconnect the device and then upon reset and/or reboot it would start working again.
External protection circuits should not be required, at least that is my takeaway.  Maybe for really old computers?
Edit:
It doesn't seem quite that simple after all, over-voltage protection may not be covered:

6.4.6.1.6 Over-Voltage Protection Event
The Over-Voltage Protection Event bit May be set when the
Source detects its output Voltage exceeds its limits triggering
its protection circuitry.

It seems advisable to use some sort of external device after all.  Not sure how realistic this failure case is for devices which are powered from the host, but for devices with external power this seems smart.

This answer is about overcurrent protection. The question was about overvoltage protection. Not quite the same!

@EdgarBonet Thanks for pointing this out, it seems, over-voltage protection is not always present, so this is an important correction.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
GPRS SIM900 and GPS NEO-6M don't work together
I'm trying to get GPS coordinates and send them to my API through the GPRS SIM900 and GPS NEO-6M shields.
In setup(), I first start the GPRS shield and call the function that connects to the internet. Then in loop(), I start to capture GPS coordinates and finally I send to my API, but my code doesn't work with this logic. I'd like to connect once and get GPS coordinates and send them to the API many times making a tracking.
The app stops if I run the code. connectToInternet() in setup() and getGpsPosition() in loop(). The SIM900 shield connects but the NEO6-M shield does not display the coordinates. The GPS only captures the coordinates if I do not connect to the internet.
Could someone help me? Following is my code and printout of the response to AT commands.
#include <SoftwareSerial.h>
#include <TinyGPS++.h>
#include <inetGSM.h>

static const int RXPin = 4, TXPin = 3;
InetGSM inet;
TinyGPSPlus gps;
SoftwareSerial serialGps(RXPin, TXPin);
char msg[50];
boolean started = false;
const char* dataCoord = "";

void setup() {
  // Serial connection.
  Serial.begin(19200);
  Serial.print(F("------------------------------------------------- \r\n"));
  Serial.println(F("Starting App Tracking Arduino"));
  Serial.print(F("------------------------------------------------- \r\n"));
  // Turn on GPRS
  powerUpGprs();
  // Start configuration of shield SIM900 with baudrate.
  if (gsm.begin(2400)) {
    Serial.println(F("\nstatus=READY"));
    started = true;
  } else Serial.println(F("\nstatus=IDLE"));
  if (started)
    connectToInternet();
  // Start configuration of shield GPS NEO-6M with baudrate.
  serialGps.begin(9600);
}

void loop() {
  // This sketch displays information every time a new sentence is correctly encoded.
  while (serialGps.available() > 0)
    if (gps.encode(serialGps.read())) getGpsPosition();
}

/**
  Power up
*/
void powerUpGprs() {
  pinMode(9, OUTPUT);
  delay(100);
  digitalWrite(9, HIGH);
  Serial.println(F("\nPower Up SIM900!"));
}

/**
  Connect to Internet via GSM
*/
void connectToInternet() {
  Serial.print(F("\r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  Serial.print(F(" CONNECT TO INTERNET \r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  //GPRS attach, put in order APN, username and password.
  if (inet.attachGPRS("zap.vivo.com.br", "vivo", "vivo"))
    Serial.println(F("status=ATTACHED"));
  else
    Serial.println(F("status=ERROR"));
  delay(1000);
  //Read IP address.
  gsm.SimpleWriteln("AT+CIFSR");
}

/**
  Get GPS position
*/
void getGpsPosition() {
  Serial.print(F("\r\n\r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  Serial.print(F(" GET POSITON \r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  // geolocation
  TinyGPSDate &d = gps.date;
  TinyGPSTime &t = gps.time;
  char* timestamp;
  if (!d.isValid()) {
    timestamp = "00/00/0000 00:00:00";
  } else {
    char sz[32];
    sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d",
      d.day(), d.month(), d.year(),
      t.hour(), t.minute(), t.second());
    timestamp = sz;
  }
  String position = String("");
  position.concat(String("timestamp=") + String(timestamp));
  position.concat(String("&latitude=") + String(gps.location.lat(), 6));
  position.concat(String("&longitude=") + String(gps.location.lng(), 6));
  position.concat(String("&altitude=") + String(gps.altitude.meters()));
  position.concat(String("&speed=") + String(gps.speed.kmph()));
  Serial.println(dataCoord);
  send2Api();
}

/**
  Send To API, The function inet.httpPOST(),
  this is submit method POST via http request
*/
void send2Api() {
  Serial.print(F("\r\n\r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  Serial.print(F(" SEND TO API\r\n"));
  Serial.print(F("------------------------------------------------- \r\n"));
  // Read until serial buffer is emapty.
  gsm.WhileSimpleRead();
  // TCP Client HTTP, send a POST request to the server and save the reply.
  int numdata = inet.httpPOST("api.myapp.com.br", 80, "/geolocations ", dataCoord, msg, 100);
  // Print the results.
  Serial.print(F("\nNumber of data received: "));
  Serial.println(numdata);
  Serial.print(F("\nData received: "));
  Serial.println(msg);
};

If I connect to internet the GPS does not display the coordinates.

But if I don't connect to internet the GPS displays the coordinates.

I solved.... my solution https://github.com/robsonfagundes/Arduino-GprsSIM900andGpsNEO-6M
I made example to help other developers who are facing the same problem or a similar problem with Gprs SIM900 and Gps NEO-6M working together.

Good day sir. It is possible that when send a location to mobile phone there's a link to google map so that i can find where's the vehicle.? What is the code for that?

@Cymon here https://github.com/robsonfagundes/arduino-gprs-sim-900-gps-neo-6m

and... here https://www.cooking-hacks.com/projects/arduino-realtime-gps-gprs-vehicle-tracking

You are using 2 SoftwareSerial instances and you're losing bytes when you aren't listening to the other port. Also your inetGSM library uses pins 3 for RX with the SIM900 and in your Arduino sketch, pin 3 is also the Arduino TX pin to the GPS module. Therefore, anything sent by the Arduino over pin 3 is received by both modules. Confusion.

Use the GPS module with another pair of pins, maybe, 7 for RX and 8 for TX. Connect the GPS TX to 7 and its RX to 8.
Try adding: gsm._cell.listen(); right before this line:
// Read until serial buffer is empty.
gsm.WhileSimpleRead();
Also add serialGps.listen(); right before this line:
// Print the results.
Serial.print(F("\nNumber of data received: "));

Refer to this answer for more details.

@RobsonFagundes Its in the library u're using. Have you tried it yet? Did it compile?

@RobsonFagundes what error did you get? Does everything work now? Any improvements?

@RobsonFagundes provide a link to your library. Are there any improvements?

here it is Library SIMCom SIM900

Let us continue this discussion in chat.


text:
How would one make a 3-wire GPS?
I want to collect GPS data with a cellular-enabled micro-controller to help me find my drone if it gets lost. My drone has GPS, so I tried to connect to it. Many GPS break-out boards have the following connections:

GND
5V/3.3V
TX
RX

Some of the time there are more, but these seem to be the essential ones. But, I'm studying a GPS module that uses only 3 wires. Take a look:

The red and black ones are power and ground. Must the remaining wire be TX?
I've been trying every way I can think of to tap into this GPS on my quad. I spliced into the 3 wires, but I only connected ground and what I suspect to be TX to my micro.

Also, at this point, I'm just curious.
I've studied the GPS a bit more and I can now see it has a compass and some other motion device. So it's not just a GPS board.
It also had it's own micro controller managing all of these devices.  I think the serial data on the wires I've tapped has been reformatted for the flight controller. It's gibberish in the arduino app.
At this point I'm ready give up and just put a second GPS on the thing!
But before I give up I wanted to ask if there are any other methods I can try to listen to the GPS.
Thanks!

Well, the "RX" pin on the GPS modules usually is pretty useless; it allows, maybe, to change the baud rate, but the GPS usually just spits out the data on the other line. So if you don't have any info just try to listen on it at different baud rates (start with 9600 and 115200, then try the other standard values). If you don't get anything, then maybe they are using a custom protocol (the ublox there is serial, but there is a uC between). So, have a look where you bought it if they tell you the protocol, then search for any identifier on the board and look on the internet

For anything like this you really do need a logic analyzer. That can tell you much about what the protocol is and allows you to decode the RS-232 coding (if that is what it is) or other protocol. You don't need to spend a lot of money - I bought a bunch of cheap chinese "USBee AX PRO" off eBay - couple of pounds each - and use the open source sigrok and pulseview with them. They absolutely rock.

If you only need the GPS data you could solder a wire direction to pin 20 of the metal-caned sub-board (Blox Neo 6M)

@Majenko I got zero results on ebay for "USBee AX PRO". I got a CY7C68013A board, but I had to replace the EEPROM to make it work as a Logic Analyzer.

@Gerben Maybe it was DealExtreme I got them from?  Ah yes, this is the one: http://www.dx.com/p/logic-analyzer-w-dupont-lines-and-usb-cable-for-scm-black-148945#.VvLELWGLTRY


text:
Shared Memory using SHM Library
I am trying to read sensor data from a FIFO buffer embedded in the sensor (LSM9DS1), and store that data on a Teensy 3.2 board to later be put in a file. I can only read 6 bytes at a time from the FIFO.
The sensor's FIFO is read by the Teensy when an interrupt triggers an isr function. I want to store the data on the Teensy memory. Then, after the ISR store the memory, I plan to parse the data and do a few simple calculations in the loop() function before writing it to file.
What is the best way to accomplish this? I tried using a FIFO library for Arduino here, but it doesn't work with interrupts. I encountered errors with declaring it as a volatile memory type.
Could I used shared memory using the sys/shm.h library from C++? If so, how can I import this to my arduino code?

Shared memory?? All the memory is already shared, so just declare it as volatile (so the compiler does not "optimize" access to this variable) and you are done. Instead of using an external library, just write a circular buffer with a fixed size array (one array and two indices or pointers). Remember that with microcontrollers you should follow the KISS principle

Hi frarugi. You're right, the data is shared. My idea with the shared memory was that by I could lock and release the variable as needed so that only one process, either the loop() or isr function, would be able to write/read at a time. I'm not sure if this will be a problem if I use a volatile object.

Well Alex, there is no such thing as "two processes", because that implies that there is a sort of scheduler. You won't have concurrent access, because you always know who is executing: if the ISR is working, then the ISR is executing, otherwise the loop. and you can't "pause" the ISR waiting for the loop to release the lock, because the uC won't execute the loop if it is in the isr. You just have to declare the variable as volatile, since it can be modified in the isr (and so in the loop the compiler can't save it to a register, since it can be modified in any moment)

@frarugi87 Thanks, that clarifies things for me :)

Shared memory only makes any sense in two combined situations:

You have a kernel arbitrating processes, threads and memory allocation, with process isolation
You have multiple threads or processes in your application

You certainly don't have number 1 unless you can install an operating system on the Teensy 3.1 (some RTOS may provide a SHM analogue).
As for 2 yes, it could be said you have two threads. But you don't have any form of process isolation, so what one "thread" can access the other "thread" can access.
Both the ISR and the loop() function have access to the exact same memory. Any global variables are accessible to both. You may need to inform the compiler that a variable is modified in one thread and read in another though. The simplest way of doing that is to make the variable volatile by prepending the volatile keyword to the definition.

Thanks Majenko.  I have a question about using volatile variables. What will happen to this variable if I am, say, in the middle of reading/deleting one entry, then the ISR is called. Then I will try to write new data into the volatile variable. Will this create any problems? This was one thing I was warned about when programming this.

It depends a) what the variable is, and b) what you are doing to it. You can google the phrase "Critical Sections" for ways around any problems that may arise. If your operations are atomic then there can be no problem. If they aren't they can be made atomic by making wrapping them in code to make them atomic, and there's a myriad of ways of doing that.

Thanks for the suggestion, seems to be just the right topic

@Majenko how can you make, for instance, a write to a int32_t atomic? I mean, they are at least four write instructions (and maybe shifts or counter increment). What if the ISR needs to be fired in the middle of this (and of course it needs to change the value of that int32_t )? You can't delay an ISR, so either you throw away the whole ISR (thus losing data) or you will have corrupted data. The solution can be not to work in the ISR (or at least limit the operations in the ISR only to 8 bit data)

@frarugi87 If you are writing to the same value in the ISR and outside the ISR I have to ask one simple question: why?! I can't think of a situation where you would actually want to do that. Read from it outside and write to it inside the ISR maybe, yes. The only safe way is to stop the interrupt firing for the few instructions it takes to read the value from memory into another variable. Keep that critical section as short as possible. If your ISR is firing so fast that you lose data as opposed to just delay the ISR by a few clock cycles then you are doing something wrong.

@Majenko that was a purely theoretical question, because if you have one producer and one consumer you won't have concurrency problems. For instance: you have an int (2 bytes) index in an array. You iterate over it, and in the isr you reset it. now, you are in the middle of a +1 operation (0x0122 to 0x0123). Let's suppose the compiler writes the first byte first. so it writes 0x01 to the first cell, then the ISR comes and writes 0x0000 to the variable. The loop resumes, and writes 0x23 to the second cell. Result? 0x0023. The solution is to delay the ISR, so I asked you: how can you do that?

@frarugi87 The simplest way is to make a critical section around your "outside ISR" operation. Easiest method: cli(); ... your operation ... sei();

@Majenko So disable interrupts and then enable them again... Are "pending" interrupts fired after the sei?

Yes. All you do there is disable the response to the interrupt. The interrupt still happens and is still logged. As soon as you enable interrupts again it sees that there are interrupt flags set and triggers the ISRs for them as per normal.

@Majenko Thank you :) did not know that, and I think that in the future it can come handy.. Thank you!


text:
Pin 13 fires relay when powering on... How to disable?
Pin 13 fires relay when powering on... How to disable?
I'm using pro mini 5v 16MHz and a DC 12V 2 Channel Relay Module Optocoupler. The relay Jd-VCC is powered by a 12V and it's VCC is 5V (the same as Arduino VCC). The relay is active low and I soldered pins 12 and 13 of the pro mini to IN1 and IN2 of the relay.
When I power the board up it cycles Pin 13(and the on-board LED) ON and then OFF before resuming to the code I uploaded. I believe that this can be fixed by disabling this blinking function in the startup process.
I understand that I can use other pins. Why not learn how to remove this from startup, if I prefer to use this pin for circuit layout purposes?
Any help would be much appreciated. Most of my searches ended up with people using the pin as an input... My issue is when using D13 as an active low pin it has some funky behavior at startup but then works as programmed.
Thanks!!!

Tehee, imagined your TV going on and off every time you would reboot/program your Arduino xD. But Majenko has some good solutions I see.

There are three things you can do:

Remove the bootloader entirely and program the board with a hardware programmer (USB-ASP, Another Arduino, etc).
Edit the bootloader source, recompile, and reinstall it to the board using a hardware programmer (as in option 1).
Just don't use pin 13 for the relay.

Of the three options the third one is by far the simplest.

:( no fun... I just moved my pins down to D11 and D12. I was hoping it was a simple as commenting some code out in the bootloader.

One step is as simple as commenting some code out in the bootloader. The rest of the steps involve compiling that bootloader and installing it. All can be done, but is it really worth the effort when you can just choose different pins?

There is a define in the bootloader:  LED_START_FLASHES - you could set that to zero, and recompile. But then you need extra hardware to upload it. Plus, compiling the bootloader is not something the IDE is set up to do.

@NickGammon: Way back in the day I saw a youtube video of someone programming the bootloader by putting switches/resistors on the SPI pins, and toggling it in by hand.  I've gone looking for that video again, but can't find it :(

That would take a long time. Mind you, I had to key my first assembler into my Motorolo 6800 by typing it in in hex. After that, I could use that version to assemble the next one.

Fond memories of recovering an HP2000 mainframe in 1975, using the front panel switches to enter about 50 bytes, just enough to initialize the paper tape reader which reads in the disk boot loader, which initializes the disk controller just enough to load the operating system from the disk drive.


text:
My RTC is returning a sporadic date/time
RTC seems to be sporadically returning bogus date/times. Here are the logs from my serial monitor:
2016/3/23 8:19:46
2017/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2165/165/165 15:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46
2016/3/23 8:19:46

That 2165/165/165 15:19:46 appears throughout the logs.
Here's the relevant code:
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 rtc;

void setup() {
  Serial.begin(9600);

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }
  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(__DATE__, __TIME__));
  }
}

void loop() {
  DateTime now = rtc.now();

  Serial.print(now.year(), DEC);
  Serial.print('/');
  Serial.print(now.month(), DEC);
  Serial.print('/');
  Serial.print(now.day(), DEC);
  Serial.print(" ");
  Serial.print(now.hour(), DEC);
  Serial.print(':');
  Serial.print(now.minute(), DEC);
  Serial.print(':');
  Serial.print(now.second(), DEC);
  Serial.println();
}

I have a Grove RTC module.

165 is a failure to communicate. Check your wiring for loose connections.

I think the single 2017 is also quite interesting (2017/3/23 8:19:46)

Are you using an I2C chip on the end of a 20 foot length of wire?

@Majenko Negative. The RTC module (which, to my understanding has the I2C built in) is attached to a ~10 inch piece of wire.

10" is still pretty long for I2C. Are you using the internal pullups of the Arduino or do you have real resistors attached to the wires?

I think the single 2017 is also quite interesting - a single-bit error like that tends to suggest that there is indeed something wrong with the communication, like lack of pull-up resistors, or too long a cable.

Previous reports of this RTC problem (1,2,3) attribute it to hardware issues, such as broken wires (to SCL or to battery) and overvoltage (>3.6 V supply vs 3 to 3.3 V).
If your setup uses breadboards or other temporary connections, you might try adding some redundant wires.  If your setup uses soldered connections, go over them carefully, looking for shorts and opens; or use a solder sucker / solder wick to remove old solder; then solder anew to make fresh, bright connections.
If you don't locate a hardware problem (and perhaps even if you do) you could add error-testing to your sketch.  That code would see if all relevant fields have valid, in-range values.  If any fields are invalid, it would delay a few milliseconds and then reread the RTC.

Loose wiring was the ultimate cause and making some adjustments in that area did the trick.

The RTC library does not check for communications success. In particular, here:
DateTime RTC_DS1307::now() {
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.send((byte) 0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_ADDRESS, 7);
  uint8_t ss = bcd2bin(Wire.read() & 0x7F);
  uint8_t mm = bcd2bin(Wire.read());
  uint8_t hh = bcd2bin(Wire.read());
  Wire.read();
  uint8_t d = bcd2bin(Wire.read());
  uint8_t m = bcd2bin(Wire.read());
  uint16_t y = bcd2bin(Wire.read()) + 2000;

  return DateTime (y, m, d, hh, mm, ss);
}

There should be a check for a zero returned from Wire.endTransmission(). It isn't otherwise possible to detect if the data is invalid (if we got the endTransmission OK) however generally speaking I2C will return 0xFF if the transmission has ceased.
The code in the library for bcd2bin is this:
static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); }

You can see that if passed 0xFF (255) it will return:
   255 - (6 * 15) = 165

Thus if any of the minutes, hours, day or month (which are not further affected in the code above) are 165 (or if the year is 2165) you can assume the whole date/time is bad.

Thanks for the explanation! You mentioned in a comment about there being something potentially wrong w/ communications...specifically "lack of pull-up resistors". In my set up, I don't have any resistors added. I've got wires from the RTC that go to +/- and then A4 & A5 on the Uno. Should I add resistors somewhere in that set up?

Judging by the schematic I just downloaded, that board already has them.


text:
Array + Serial Monitor Problem
I've written a Arduino sketch that converts an analogue voltage to a temperature using a lookup table - code below. I've recently changed my LUT to include more values but ever since that my Serial monitor won't print out my debugging statements etc. So I limited the number of elements in the array and it was back to normal. But when I enter more debugging statements using the serial monitor, there is garbage before my statements (still readable though when I parse through it myself) or at the start nothing is printed.
I've checked that the two baud rates are the same but I just find it peculiar that if I take some of my println() statements out it runs okay. Tested everything else with a "Hello World" example but in the simple exaples the monitor works fine.
    /*
    #####PROJECT DESCRIPTION#####
    Measures temperature with an Arduino and NTC Thermistor (10Kohms @ 25^C)                                 in a voltage divider circuit
    Since the response is non-linear, a lookup table is used since there is a non linear response
    The values in the LUT are the predicted values of the ADC at  temperature between 6^C and 40^C
    LUT has been derived from the calibration tests
    */
    //#####CONSTANTS#####
    const int constDelay = 3000; //constant delay for program
    const int constNoOfAnaloguePins = 2; //number of analogue pins that are to be read
    const int errReturn = 998; //error value that is returned ***CHECK FOR CONSITENT VALUE ACROSS FUNCTIONS***
    //#####VARIABLE DECLARATIONS#####
    float avgTempC; //float var to store average of multiple temp readings

    //#####SETUP PROCEDURE#####
    void setup()
    {
      //this is the Setup part of your project - this is for code that is run only ONCE at startup
      for (int analoguePinCounter = 0; analoguePinCounter < constNoOfAnaloguePins; analoguePinCounter++) //for loop to set up numerous analogue pins
      {
        pinMode(analoguePinCounter, INPUT);  //set pin mode of the analogue thermistor input
      }//end for
      analogReference(INTERNAL); //use the interval votlage of 1.1V for the ADC resolution
      Serial.begin(9600); //serial monitor baud rate
    }//end Setup function

    //#####LOOP PROCEDURE#####
    void loop()
    {
      //this is the main part of your project - put all continuously running code here
      for (int analoguePinCounter = 0; analoguePinCounter < constNoOfAnaloguePins; analoguePinCounter++) //for loop to take temp readings from each analogue pin
      {
        //get LPF average reading over 25 samples
        avgTempC = LPF(analoguePinCounter, 25);
        //print out the readings
        if (avgTempC < float(errReturn)) //there hasn't been any temps outside the range ***CHECK THE VALUE RETURNED FROM LPF IF ERROR***
        {
          Serial.print(analoguePinCounter);
          Serial.print(" | Average Temperature Readings = ");
          Serial.print(avgTempC, 2);
          Serial.println(" degC.");
          Serial.println("-------------------------");
        }
        else //avgTempC has returned X indicating an error
        {
          Serial.print(analoguePinCounter);
          Serial.println("**ERROR IN READING AVERAGE TEMP**");
          Serial.println("-------------------------");
          delay(10);
        }//end if
        delay(constDelay/2); //wait X/2 seconds until moving onto next sensor
      }//end for
      delay(constDelay); //wait X seconds until next loop
    }//end Loop function

    /*
    #####LOW PASS FILTER DESCRIPTION#####
    This function is a LPF for smoothing out signals or averaging
    It uses a static buffer to store the last "n" readings, and each time it is called,
    the oldest reading is discarded, the new reading is added, and the stack average
    value is returned.
    The buffer size is user-adjustable, but is constrained between 2 and 50
    An initialization function fills the entire buffer with the input value.
    This is useful when the LPF function is called for the first time.
    Note: To meet the definition of a true LPF, this function must be called         at regular intervals.
    */
    //#####LOW PASS FILTER FUNCTION#####
    float LPF(int pinAnalogue, int bufferSize)
    {
      //##PRE PROCESSOR##
      #define bufferCap 75 //maximum buffer capacity
      //##CONSTANTS##
      const int constMAXERRORS = 5; //max number of error that can occur
      const int errReturn = 998; //value return if there is an error
      //##VARIABLES##
      float tempC; //var to store instantaneous temp
      static float buffer[bufferCap]; //array to act like a 'stack' of temp values ***DOES IT NEED TO BE STATIC NOW?***
      float tempSum; //to store the sum of the temperatures
      float output; //return value of LPF which is the average of the temp readings
      int errCounter = 0; //initialise error counter to 0

      //make sure buffer size is between the range
      bufferSize = constrain(bufferSize, 2, bufferCap);

      for (int i=0; i<bufferSize; i++) //for loop to store temps in buffer array
      {
        tempC = getTempFloat(pinAnalogue); //call function to get temperature from pin
        if ((tempC > -errReturn) && (tempC < errReturn)) //no error
        {
          buffer[i] = tempC; //store temp value into array
        }
        else //error
        {
          errCounter++; //increment counter for number of erroneous readings
          i--; //decrement counter as to not skip a sample index
          if (errCounter > constMAXERRORS)
          {
            return(errReturn+1.0); //return the error value + 1
          }//end if
        }//end if
        delay(25); //allow the ADC to settle
      }//end for

      //calculate current stack average
      tempSum = 0; //initialise sum total
      for (int i=0; i<bufferSize; i++) //go through stack array
      {
        tempSum = tempSum + buffer[i]; //total up readings
      }//end for

      //average sum
      output = tempSum/bufferSize;

      return(output);
    }//end LPF function

    /*
    #####GET TEMP FLOAT DESCRIPTION#####
    This function converts a thermistor reading into a corresponding temp in ^C
    The thermistor is incorporated into a Voltage Divider Circuit:

       +Vref---[Thermistor]---+--[1.8K]---GND
                              |
                             ADC @ thermPin

    ADC Values were externally calculated from the calibration table using:           ADC = 1023*10000/(Rtherm+10000)
    The LUT is an array of integer constants containing the predicted ADC         values for all temperatures between +6^C to +40.5^C.
    The array index starts at zero, which corresponds to a temperature of         +6^C.
    A linear interpolation between the two closest entries is performed to         give a finer output resolution.
    */

    float getTempFloat (int thermPin)
    {
      //##CONSTANTS##
      /*1K8*/
      const int constLUTArraySize = 431;
      const int LUT_Therm[constLUTArraySize] = //LUT containing ADC values
      {
        223, 224, 225, 226, 227, 228, 229, 230, 231, 232,         //7^C to 7.9^C
        233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
        244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
        255, 256, 257, 258, 259, 260, 261, 263, 264, 265,
        266, 267, 268, 269, 271, 272, 273, 274, 275, 277,
        278, 279, 280, 281, 283, 284, 285, 286, 287, 289,
        290, 291, 292, 294, 295, 296, 297, 299, 300, 301,           //13^C to 13.9^C
        302, 304, 305, 306, 308, 309, 310, 312, 313, 314,
        315, 317, 318, 319, 321, 322, 323, 325, 326, 327,
        329, 330, 332, 333, 334, 336, 337, 338, 340, 341,
        343, 344, 345, 347, 348, 350, 351, 353, 354, 355,
        357, 358, 360, 361, 363, 364, 366, 367, 369, 370,
        371, 373, 374, 376, 377, 379, 380, 382, 383, 385,
        387, 388, 390, 391, 393, 394, 396, 397, 399, 400,
        402, 404, 405, 407, 408, 410, 411, 413, 415, 416,
        418, 419, 421, 423, 424, 426, 428, 429, 431, 433,
        434, 436, 438, 439, 441, 443, 444, 446, 448, 449,
        451, 453, 454, 456, 458, 460, 461, 463, 465, 466,
        468, 470, 472, 473, 475, 477, 479, 480, 482, 484,
        486, 488, 489, 491, 493, 495, 497, 498, 500, 502,
        504, 506, 507, 509, 511, 513, 515, 517, 519, 520,
        522, 524, 526, 528, 530, 532, 534, 535, 537, 539,
        541, 543, 545, 547, 549, 551, 553, 555, 557, 559,
        560, 562, 564, 566, 568, 570, 572, 574, 576, 578,
        580, 582, 584, 586, 588, 590, 592, 594, 596, 598,
        600, 602, 604, 606, 608, 611, 613, 615, 617, 619,
        621, 623, 625, 627, 629, 631, 633, 635, 638, 640,
        642, 644, 646, 648, 650, 652, 655, 657, 659, 661,
        663, 665, 667, 670, 672, 674, 676, 678, 680, 683,
        685, 687, 689, 691, 694, 696, 698, 700, 702, 705,
        707, 709, 711, 714, 716, 718, 720, 723, 725, 727,
        729, 732, 734, 736, 738, 741, 743, 745, 747, 750,
        752, 754, 757, 759, 761, 764, 766, 768, 771, 773,
        775, 778, 780, 782, 785, 787, 789, 792, 794, 796,
        799, 801, 803, 806, 808, 811, 813, 815, 818, 820,
        822, 825, 827, 830, 832, 834, 837, 839, 842, 844,
        847, 849, 851, 854, 856, 859, 861, 864, 866, 868,
        871, 873, 876, 878, 881, 883, 886, 888, 891, 893,
        896, 898, 901, 903, 906, 908, 911, 913, 916, 918,
        921, 923, 926, 928, 931, 933, 936, 938, 941, 943,
        946, 948, 951, 953, 956, 958, 961, 963, 966, 969,
        971, 974, 976, 979, 981, 984, 987, 989, 992, 994,
        997, 999, 1002, 1005, 1007, 1010, 1012, 1015, 1017, 1020, //40^C to 49.9^C
        1023                                                     //50^C
      };
      const int errReturn = 998; //error value that is returned
      //##VARIABLES##
      float _tempC; //intermediate results + final temperature return value
      int ADC_Lo; //the lower ADC matching value
      int ADC_Hi; //the higher ADC matching value
      float Temp_Lo; //the lower number matching temperature
      int mapTemp_Lo; //the lower number that will be entered into the map function
      float Temp_Hi; //the higher  number matching temperature
      int mapTemp_Hi; //the higher number that will be entered into the map function

      //prep ADC onto that particular analogue pin to sort out multiplexing etc
      analogRead(thermPin);
      delay(10);
      //get raw ADC value from VDR
      int thermValue = analogRead(thermPin);
      //Serial.println(thermValue);
      /*Serial.print("PinNo : ");
      Serial.println(thermPin);*/
      Serial.print("ADC : ");
      Serial.println(thermValue);
      //return dummy value if the sensor reading falls outside of the LUT
      if (thermValue < LUT_Therm[0]) //less than the least ADC value
        _tempC = -errReturn-1; //under range dummy value
      else if (thermValue > LUT_Therm[constLUTArraySize-1]) //more than the greatest ADC value
        _tempC = errReturn+1; //over range dummy value
      else //value falls in LUT range
      {
        for (int i=0; i<constLUTArraySize; i++) //step through LUT and look for a match
        {
          if (LUT_Therm[i] > thermValue) //LUT value is greater than the reading
          {
            //find the closest higher ADC value
            ADC_Hi = LUT_Therm[i];
            //record the closest higher temperature
            Temp_Hi = float(i/10) + 13.0; //convert to temp
            //get the closest lower temperature - taking the lower table boundary into account
            if (i != 0) //general case -> as long as it is not the first entry
            {
              ADC_Lo = LUT_Therm[i-1]; //store the previous array element as the low
              Temp_Lo = float(i/10) + 13.0 - 0.1; //convert to temp
            }
            else //special case -> counter = 0 ie first array entry
            {
              ADC_Lo = LUT_Therm[i]; //store the first array element
              Temp_Lo = i - float(i/10) + 13.0; //convert to temp
            }//end if
            //interpolate the temperature value for greater precision
            //NB the map function does not use floating-point math, so the int values of temp are multiplied by 100 and then result is subsequently divided by 100
            mapTemp_Lo = Temp_Lo*100;
            mapTemp_Hi = Temp_Hi*100;
            _tempC = float(map(thermValue,ADC_Lo,ADC_Hi,mapTemp_Lo,mapTemp_Hi))/100;
            break;  //exit for loop after the match is detected
          }//end if
        }//end for
      }//end if
      return(_tempC);
    }//end getTempFloat function

In this particular sketch no output is seen on the serial monitor. Has anyone come across this before or have any ideas how I could fix this?

Try putting the data for LUT_Therm in progmem or compressing it somehow

...because it sounds like you have run out of storage space.

Use the F() macro for all double-quoted strings you print.  Change lines like this:
Serial.println(" degC.");

...to this:
Serial.println( F(" degC.") );

This will save about 100 bytes of RAM.
And as BrettAM suggested, put that table into PROGMEM:
  const int LUT_Therm[constLUTArraySize] PROGMEM = //LUT containing ADC values
  {
    223, 224, 225, 226, 227, 228, 229, 230, 231, 232,         //7^C to 7.9^C

This requires changing how you access the array, from this:
  if (thermValue < LUT_Therm[0]) //less than the least ADC value

...to this:
  if (thermValue < (int) pgm_read_word( &LUT_Therm[0] )) //less than the least ADC value

Note the cast, the function call and the ampersand wrapped around the desired array element.  You must replace all uses of the array with this sequence.  You can also read it once into a local int and then use it normally:
      int lut_therm = (int) pgm_read_word(LUT_Therm[i]); // read it in

      if (lut_therm > thermValue) //LUT value is greater than the reading

This saves almost 1000 bytes of RAM!  The reported binary sketch size goes up by the same amount[1].
I had to pull the table out from inside getTempFloat, to the file scope.  Here's the complete sketch with those mods:
/*
#####PROJECT DESCRIPTION#####
Measures temperature with an Arduino and NTC Thermistor (10Kohms @ 25^C)                                 in a voltage divider circuit
Since the response is non-linear, a lookup table is used since there is a non linear response
The values in the LUT are the predicted values of the ADC at  temperature between 6^C and 40^C
LUT has been derived from the calibration tests
*/

//#####CONSTANTS#####
const int constDelay = 3000; //constant delay for program
const int constNoOfAnaloguePins = 2; //number of analogue pins that are to be read
const int errReturn = 998; //error value that is returned ***CHECK FOR CONSITENT VALUE ACROSS FUNCTIONS***

//#####VARIABLE DECLARATIONS#####
float avgTempC; //float var to store average of multiple temp readings

//#####SETUP PROCEDURE#####
void setup()
{
  //this is the Setup part of your project - this is for code that is run only ONCE at startup
  for (int analoguePinCounter = 0; analoguePinCounter < constNoOfAnaloguePins; analoguePinCounter++) //for loop to set up numerous analogue pins
  {
    pinMode(analoguePinCounter, INPUT);  //set pin mode of the analogue thermistor input
  }//end for
  analogReference(INTERNAL); //use the interval votlage of 1.1V for the ADC resolution
  Serial.begin(9600); //serial monitor baud rate
}//end Setup function

//#####LOOP PROCEDURE#####
void loop()
{
  //this is the main part of your project - put all continuously running code here
  for (int analoguePinCounter = 0; analoguePinCounter < constNoOfAnaloguePins; analoguePinCounter++) //for loop to take temp readings from each analogue pin
  {
    //get LPF average reading over 25 samples
    avgTempC = LPF(analoguePinCounter, 25);
    //print out the readings
    if (avgTempC < float(errReturn)) //there hasn't been any temps outside the range ***CHECK THE VALUE RETURNED FROM LPF IF ERROR***
    {
      Serial.print(analoguePinCounter);
      Serial.print( F(" | Average Temperature Readings = ") );
      Serial.print(avgTempC, 2);
      Serial.println( F(" degC.") );
      Serial.println( F("-------------------------") );
    }
    else //avgTempC has returned X indicating an error
    {
      Serial.print(analoguePinCounter);
      Serial.println( F("**ERROR IN READING AVERAGE TEMP**") );
      Serial.println( F("-------------------------") );
      delay(10);
    }//end if
    delay(constDelay/2); //wait X/2 seconds until moving onto next sensor
  }//end for
  delay(constDelay); //wait X seconds until next loop
}//end Loop function

/*
#####LOW PASS FILTER DESCRIPTION#####
This function is a LPF for smoothing out signals or averaging
It uses a static buffer to store the last "n" readings, and each time it is called,
the oldest reading is discarded, the new reading is added, and the stack average
value is returned.
The buffer size is user-adjustable, but is constrained between 2 and 50
An initialization function fills the entire buffer with the input value.
This is useful when the LPF function is called for the first time.
Note: To meet the definition of a true LPF, this function must be called         at regular intervals.
*/
//#####LOW PASS FILTER FUNCTION#####
float LPF(int pinAnalogue, int bufferSize)
{
  //##PRE PROCESSOR##
  #define bufferCap 75 //maximum buffer capacity
  //##CONSTANTS##
  const int constMAXERRORS = 5; //max number of error that can occur
  //##VARIABLES##
  float tempC; //var to store instantaneous temp
  static float buffer[bufferCap]; //array to act like a 'stack' of temp values ***DOES IT NEED TO BE STATIC NOW?***
  float tempSum; //to store the sum of the temperatures
  float output; //return value of LPF which is the average of the temp readings
  int errCounter = 0; //initialise error counter to 0

  //make sure buffer size is between the range
  bufferSize = constrain(bufferSize, 2, bufferCap);

  for (int i=0; i<bufferSize; i++) //for loop to store temps in buffer array
  {
    tempC = getTempFloat(pinAnalogue); //call function to get temperature from pin
    if ((tempC > -errReturn) && (tempC < errReturn)) //no error
    {
      buffer[i] = tempC; //store temp value into array
    }
    else //error
    {
      errCounter++; //increment counter for number of erroneous readings
      i--; //decrement counter as to not skip a sample index
      if (errCounter > constMAXERRORS)
      {
        return(errReturn+1.0); //return the error value + 1
      }//end if
    }//end if
    delay(25); //allow the ADC to settle
  }//end for

  //calculate current stack average
  tempSum = 0; //initialise sum total
  for (int i=0; i<bufferSize; i++) //go through stack array
  {
    tempSum = tempSum + buffer[i]; //total up readings
  }//end for

  //average sum
  output = tempSum/bufferSize;

  return(output);
}//end LPF function

/*
#####GET TEMP FLOAT DESCRIPTION#####
This function converts a thermistor reading into a corresponding temp in ^C
The thermistor is incorporated into a Voltage Divider Circuit:

   +Vref---[Thermistor]---+--[1.8K]---GND
                          |
                         ADC @ thermPin

ADC Values were externally calculated from the calibration table using:           ADC = 1023*10000/(Rtherm+10000)
The LUT is an array of integer constants containing the predicted ADC         values for all temperatures between +6^C to +40.5^C.
The array index starts at zero, which corresponds to a temperature of         +6^C.
A linear interpolation between the two closest entries is performed to         give a finer output resolution.
*/

//##CONSTANTS##
/*1K8*/
const int LUT_Therm[] PROGMEM = //LUT containing ADC values
{
  223, 224, 225, 226, 227, 228, 229, 230, 231, 232,         //7^C to 7.9^C
  233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
  244, 245, 246, 247, 248, 249, 250, 251, 252, 253,
  255, 256, 257, 258, 259, 260, 261, 263, 264, 265,
  266, 267, 268, 269, 271, 272, 273, 274, 275, 277,
  278, 279, 280, 281, 283, 284, 285, 286, 287, 289,
  290, 291, 292, 294, 295, 296, 297, 299, 300, 301,           //13^C to 13.9^C
  302, 304, 305, 306, 308, 309, 310, 312, 313, 314,
  315, 317, 318, 319, 321, 322, 323, 325, 326, 327,
  329, 330, 332, 333, 334, 336, 337, 338, 340, 341,
  343, 344, 345, 347, 348, 350, 351, 353, 354, 355,
  357, 358, 360, 361, 363, 364, 366, 367, 369, 370,
  371, 373, 374, 376, 377, 379, 380, 382, 383, 385,
  387, 388, 390, 391, 393, 394, 396, 397, 399, 400,
  402, 404, 405, 407, 408, 410, 411, 413, 415, 416,
  418, 419, 421, 423, 424, 426, 428, 429, 431, 433,
  434, 436, 438, 439, 441, 443, 444, 446, 448, 449,
  451, 453, 454, 456, 458, 460, 461, 463, 465, 466,
  468, 470, 472, 473, 475, 477, 479, 480, 482, 484,
  486, 488, 489, 491, 493, 495, 497, 498, 500, 502,
  504, 506, 507, 509, 511, 513, 515, 517, 519, 520,
  522, 524, 526, 528, 530, 532, 534, 535, 537, 539,
  541, 543, 545, 547, 549, 551, 553, 555, 557, 559,
  560, 562, 564, 566, 568, 570, 572, 574, 576, 578,
  580, 582, 584, 586, 588, 590, 592, 594, 596, 598,
  600, 602, 604, 606, 608, 611, 613, 615, 617, 619,
  621, 623, 625, 627, 629, 631, 633, 635, 638, 640,
  642, 644, 646, 648, 650, 652, 655, 657, 659, 661,
  663, 665, 667, 670, 672, 674, 676, 678, 680, 683,
  685, 687, 689, 691, 694, 696, 698, 700, 702, 705,
  707, 709, 711, 714, 716, 718, 720, 723, 725, 727,
  729, 732, 734, 736, 738, 741, 743, 745, 747, 750,
  752, 754, 757, 759, 761, 764, 766, 768, 771, 773,
  775, 778, 780, 782, 785, 787, 789, 792, 794, 796,
  799, 801, 803, 806, 808, 811, 813, 815, 818, 820,
  822, 825, 827, 830, 832, 834, 837, 839, 842, 844,
  847, 849, 851, 854, 856, 859, 861, 864, 866, 868,
  871, 873, 876, 878, 881, 883, 886, 888, 891, 893,
  896, 898, 901, 903, 906, 908, 911, 913, 916, 918,
  921, 923, 926, 928, 931, 933, 936, 938, 941, 943,
  946, 948, 951, 953, 956, 958, 961, 963, 966, 969,
  971, 974, 976, 979, 981, 984, 987, 989, 992, 994,
  997, 999, 1002, 1005, 1007, 1010, 1012, 1015, 1017, 1020, //40^C to 49.9^C
  1023                                                     //50^C
};
const int constLUTArraySize = sizeof(LUT_Therm)/sizeof(LUT_Therm[0]);

float getTempFloat (int thermPin)
{
  //##VARIABLES##
  float _tempC; //intermediate results + final temperature return value
  int ADC_Lo; //the lower ADC matching value
  int ADC_Hi; //the higher ADC matching value
  float Temp_Lo; //the lower number matching temperature
  int mapTemp_Lo; //the lower number that will be entered into the map function
  float Temp_Hi; //the higher  number matching temperature
  int mapTemp_Hi; //the higher number that will be entered into the map function

  //prep ADC onto that particular analogue pin to sort out multiplexing etc
  analogRead(thermPin);
  delay(10);
  //get raw ADC value from VDR
  int thermValue = analogRead(thermPin);
  //Serial.println(thermValue);
  /*Serial.print( F("PinNo : ") );
  Serial.println(thermPin);*/
  Serial.print( F("ADC : ") );
  Serial.println(thermValue);

  //return dummy value if the sensor reading falls outside of the LUT
  if (thermValue < (int) pgm_read_word( &LUT_Therm[0] )) //less than the least ADC value
    _tempC = -errReturn-1; //under range dummy value

  else if (thermValue > (int) pgm_read_word(LUT_Therm[constLUTArraySize-1])) //more than the greatest ADC value
    _tempC = errReturn+1; //over range dummy value

  else //value falls in LUT range
  {
    int prev_lut_therm = 0;
    for (int i=0; i<constLUTArraySize; i++) //step through LUT and look for a match
    {
      int lut_therm = (int) pgm_read_word(LUT_Therm[i]);
      if (lut_therm > thermValue) //LUT value is greater than the reading
      {
        //find the closest higher ADC value
        ADC_Hi = lut_therm;
        //record the closest higher temperature
        Temp_Hi = float(i/10) + 13.0; //convert to temp
        //get the closest lower temperature - taking the lower table boundary into account
        if (i != 0) //general case -> as long as it is not the first entry
        {
          ADC_Lo = prev_lut_therm; //store the previous array element as the low
          Temp_Lo = float(i/10) + 13.0 - 0.1; //convert to temp
        }
        else //special case -> counter = 0 ie first array entry
        {
          ADC_Lo = lut_therm; //store the first array element
          Temp_Lo = i - float(i/10) + 13.0; //convert to temp
        }//end if
        //interpolate the temperature value for greater precision
        //NB the map function does not use floating-point math, so the int values of temp are multiplied by 100 and then result is subsequently divided by 100
        mapTemp_Lo = Temp_Lo*100;
        mapTemp_Hi = Temp_Hi*100;
        _tempC = float(map(thermValue,ADC_Lo,ADC_Hi,mapTemp_Lo,mapTemp_Hi))/100;
        break;  //exit for loop after the match is detected
      }//end if
      prev_lut_therm = lut_therm;
    }//end for
  }//end if
  return(_tempC);
}//end getTempFloat function

Note the technique for declaring the LUT_Therm array, using the empty [] brackets (line 135).
That's followed by the const int array size (line 182) that is "calculated" from the array declaration: (Total array size) / (size of one array element).  If you ever change the lookup table, you don't have to count the elements by hand.  Let the compiler do it for you!  :)

[1] Although the IDE reports an increased binary sketch size, the total uploaded size is unchanged:

PROGMEM keyword   text    data     bss
No                5948     894     483
Yes               6810      32     483

As you can see, the 862 bytes for this table move from the data section to the text section.  The uploaded HEX files are identical at 93,737 bytes.

I have a page about putting things into PROGMEM.

“The binary sketch size goes up by the same amount”. That's wrong. Initialized arrays eat the same amount of flash whether they are PROGMEM or not.

@EdgarBonet, true, but the reported program size goes up by the same amount.  Try it!  :)  Just delete the PROGMEM keyword.  Although it wouldn't run correctly, the size reported in build log changes.  Must have something to do with which sections get added up?

...now I'm wondering which number is correct...

Your avr-size must be broken. With PROGMEM I get a program size of 6646 bytes (.text: 6604 bytes, .data: 42 bytes). If I remove PROGMEM I get 6644 bytes (.text: 5606, .data: 1038). I checked the HEX file size (the stuff that is actually transferred to the Arduino flash) and in both cases the reported program size is correct. Please fix your answer.

@EdgarBonet, my avr-size is not broken.  Perhaps the IDE does not report as you expected.  I have added a footnote with details to address your comment.  It is an artifact of how the IDE adds the sections, as I suspected.

You have likely run out of RAM.
You have 431 integers in the look-up table alone. That equates to 862 bytes of SRAM. You also have a buffer of 75 floats, which equates to 300 bytes. This is in addition to all your other variables and function calls.
The Arduino Uno only has 2KB of SRAM.
Solutions:
 1) Move your LUT to Flash (ie. program space) using the PROGMEM keyword (just before the equals sign):
const int LUT_Therm[constLUTArraySize] PROGMEM = //LUT containing ADC values

2) Use an Arduino with a greater amount of SRAM.

Arduino Mega  - 8KB SRAM
Arduino ZERO  - 32KB SRAM
Arduino Due   - 96KB SRAM
Arduino MKR 1000/1010/1400/ZERO - 32KB SRAM

I went through your program and found a few bugs you may want to fix. I
think only one of these (wastage of RAM) is really related to your
problem, but anyway, here it goes:
Fist, there are two issues with LPF(). The description states that
this is a rolling average low-pass filter. This is erroneous: a rolling
average would take a single reading, then report the average of the
last n readings. This function, in contrast, takes n readings and
reports their average. This makes a big difference: a rolling average
would need to store the last n values in static memory, while your
function does this for no good reason. You are just wasting
300 bytes of RAM.
Here is a reimplementation of LPF() that does the same thing as yours
without wasting RAM. I changed its name to be more consistent with it's
real purpose:
/*
 * Take 'count' temperature readings from 'pin' and return their average.
 * Returns NaN (not a number) if too many readings where in error.
 */
float getAvgTemp(int pin, int count)
{
  const int MAXERRORS = 5; // max number of errors that can occur
  float temp;              // current temperature reading
  float tempSum = 0;       // sum of temperatures
  int errCounter = 0;      // number of erroneous readings

  for (int i = 0; i < count; i++) {

    // Try to get a valid reading.
    do {
      temp = getTempFloat(pin);
      if (isnan(temp))
        errCounter++;
      delay(25); // allow the ADC to settle
    } while (isnan(temp) && errCounter <= MAXERRORS);

    // Too many errors: return an error.
    if (errCounter > MAXERRORS)
      return NAN;

    tempSum += temp;
  }

  return tempSum / count;
}

Here I use NaN (not a number) as an error indicator, as it is
semantically clearer than a random out-of-range value.
There are also a few errors in getTempFloat():

pgm_read_word(LUT_Therm[constLUTArraySize-1]) and
pgm_read_word(LUT_Therm[i]) will not work: you have to pass
pgm_read_word() the address where to read.
float(i/10) does not do what you want: it computes i/10 as an
integer division (i.e. discarding the fractional part), and then it
converts the result to a float. If you want a floating point division,
you should make sure that at least one of the arguments is a float.
The usual idiom is i/10.0.

Here is a version of getTempFloat() with these problems fixed, and
also somewhat simplified:
float getTempFloat(int pin)
{
  int i, lutval, prev_lutval;

  // Take an analog reading.
  analogRead(pin);  // dummy reading to settle the MUX
  delay(10);
  int adc = analogRead(pin);
  Serial.print(F("ADC: "));
  Serial.println(adc);

  // Find i such that adc lies between LUT[i-1] and LUT[i].
  for (i = 0; i < constLUTArraySize; i++) {
    prev_lutval = lutval;
    lutval = pgm_read_word(&LUT_Therm[i]);
    if (lutval >= adc) break;
  }

  // Special case: adc == LUT[0].
  if (i == 0 && adc == lutval)
    return 13.0;

  // Report an error if out of range.
  if (i == 0 || i == constLUTArraySize)
    return NAN;

  // Return interpolated temperature.
  float fraction = float(adc - prev_lutval) / (lutval - prev_lutval);
  return 13.0 + (i-1 + fraction) / 10.0;
}

Addendum
I have noticed a few more problems and inconsistencies with your
program.
Powering the thermistor from the internal reference
In setup(), you write

analogReference(INTERNAL); //use the interval votlage of 1.1V for the
  ADC resolution

and then, in a comment further down you have the schematic

+Vref---[Thermistor]---+--[1.8K]---GND

This suggests you are powering the voltage divider from the internal
voltage reference of the MCU. You should not do that, as the datasheet
states: “Note that VREF is a high impedance source, and only
a capacitive load should be connected in a system.”
Relationship between ADC reading and thermistor resistance
In the same comment as above, you wrote:

ADC = 1023*10000/(Rtherm+10000)

Actually, the factor is 1024, not 1023. Again, see the datasheet. And
the number 10000 should be 1800, i.e. the resistance you have put
between the ADC input and GND. I understand that you may have simply
changed the value and forgotten to update one of the comments. But you
should consider a misleading comment as a bug, especially if it's not
consistent with the actual code.
For this kind of measurement, you get the best precision if the pulldown
resistor has a value close to the resistance of the thermistor. The
comment at the beginning of the program says your thermistor has
10 kΩ @ 25°C. This means that, if you are mostly interested in
the range around 25°C, a 10 kΩ pulldown is better than 1.8 kΩ.
Relationship between array index and temperature
The comment before the LUT says:

The array index starts at zero, which corresponds to a temperature of
  +6^C

Then, the very first line of the LUT has the comment

//7^C to 7.9^C

And later on, the implementation of getTempFloat() assumes
index 0 means 13°C. You should sort this out and make everything
consistent.
BTW, your LUT values go all the way up to 1023. A reading of 1023 would
mean the ADC voltage is higher than 1022.5/1024×VREF. Which
in turn would imply the thermistor has a resistance lower than
14.6 Ω (assuming a 10 kΩ pulldown). I find this dubious.
Removal of the LUT
Since your program is meant to run very slowly (constDelay = 3000),
you can afford doing complex computations in it. You can get the same
precision with a way smaller LUT if you use a higher order
interpolation. For a function sampled at constant steps, the
Catmull–Rom
spline
is easy to implement and is way better than linear interpolation.
Or you can remove the LUT altogether and use an analytical expression
instead. If you derived the LUT from such an expression, why not use it
in the program? If the LUT derives from experimental data, you can try
to do an empirical fit, i.e. an arbitrary function that closely fits the
data. The most obvious (though maybe not the best) empirical function
would be a polynomial. Below is an example of such a function that
reproduces you LUT with good accuracy using a 6th degree polynomial. It
assumes the first LUT entry is for a temperature of 7°C:
float getTempFloat(int pin)
{
    const float T0 = 7;   // temperature at beginning of range
    int adc = analogRead(pin);
    float x = (adc-223.) / (1023.-223.) * 2 - 1;  // scale to [-1:1]
    if (x < -1 || x > 1) return NAN;              // out of range
    float y = 1.474 - x*(0.533 - x*(0.732 - x*0.458));
    return T0 + 26.107 + x*(19.287 - x*(3.596 - x*y));
}

Actually this may be even more accurate than your LUT-based function, as
that LUT is made of integer values whereas the calibration curve should
obviously be continuous.

Many thanks for your points some I wouldn't have considered. Yeah I've been changing the temp range so some comments don't make sense. Is the analogReference(Internal) call not use the 1.1V to get a better resolution between ADC steps and by using the Arduino's 3.3V power out as Vref and I've worked out that a 1k8ohm resistor gives me a range of 7-50degC (however as shown above I may be wrong!). I'm using this as a skin temperature logger so temps will be in the range of 30-40degC. I'm still unsure of how many measurements per minute I want but the interpolation looks nicer. Thanks


text:
How to recover from DHCP Renewal and Rebind failures?
I'm using an Ethernet shield with the built-in Ethernet library. I obtain an IP address using DHCP, and call Ethernet.maintain() periodically to ensure that the DHCP lease is renewed as required. So far I've never seen this fail, but maintain() can return error codes for renew fail and rebind fail and I assume that I should be handling them. What conditions would cause these errors to occur, and what's the best practise for recovering from them? Is it enough to call Ethernet.maintain() repeatedly until it returns cleanly, should I call Ethernet.begin() to reinitialise the Ethernet shield, or would it be best to reset both the Arduino and Ethernet shield using the watchdog timer?

You would have to set some requirements. Like, you can only lose connection for +5 minutes. Than you can try 5x once a minute (or smh). And if that won't work, you can call Ethernet.begin();. And if Ethernet.begin keeps failing, ultimately a buzzer sound/red light with diagnostic messages over your USB connection ;). This way you avoid your system being bricked when you never get a renew or new lease. The diagnostics may also prove very useful.

Possible causes:

The DHCP server might be down.
Or it might have lost its state (but I think they try really hard to preserve the list of leases).
Or some other cause which makes the server unavailable/unwilling to renew the lease.

Solutions:

If you can wait, you can retry, but otherwise I'd just say try to obtain a new lease, unless for some reason you really want to stick to the IP from the previous lease.
If you control the server and your network is kinda stable, you could assign a fixed IP to your device configure the server to associate it with the MAC address you gave to your device. In general, when the network setup is really stable, this might be preferable, since other entities on the network will probably cache the IP of your device and use it, should the DNS fail as well (ex: dnsmasquerade works both as dhcp server and dns). Similarly, your device doesn't have to worry anymore of the DHCP lease, because it's permanent.

What you described is not so much Arduino specific. Whenever you have a device in a dynamic network, you can experience the same effects.

I appreciate that the problem of DHCP errors isn't Arduino-specific, but the best way to recover from them probably is. I wondered whether repeatedly calling Ethernet.maintain() was guaranteed to renew the lease at some point (i.e. whether either the Ethernet library or DHCP server would have the intelligence to begin a new lease, possibly with a different IP address, if the old one couldn't be renewed). However, calling Ethernet.begin() to guarantee starting a new lease seems more sensible, and from the testing I've done it doesn't appear to have any negative side-effects.


text:
Power 4 leds with max7219 and LedControl.h
So this is my first arduino (or embedded for that matter) project. I am trying to power 4 leds with max7219. Max7219 seems easy to use, but for some reason after I upload the code, nothing happens. I've looked over my breadboard, and the connections seem right. My confusion arises from the fact that all the projects I have found on google use matrices for the leds. I am using 4 separate leds. Does this even matter?
Here is the code I use:
#include "LedControl.h"

LedControl ledControl = LedControl(12, 9, 10, 1);

void setup()
{
    //should be waking ledcontrol
    ledControl.shutdown(0, false);
    ledControl.setIntensity(0, 8);
}

void loop()
{
    ledControl.setLed(0, 0, 0, true);
}

Could you add a image of your breadboard wiring and possibly a schematic of how you wired it.

Try setting all the leds to on, instead of just the first one.

No it shouldn't matter that you are using separate LEDs, but you will have to connect them in a way that is acceptable to the 7219, they will have to share either a common anode or cathode (can't remember which of the top of my head).
I find its always best to check the basics (Based on personal experience)

Have you got the LEDs the correct way around?
Are you using the correct voltage for everything?
Do the LEDs work when controlled directly by the Arduino, try "Blink"?
Have you tried changing the intensity?
Have you got the required resistors in?
Try inverting the index of the LEDs, i.e. led(x=0,y=0) might be wired (x=7,y=7)?

You loop() is not pausing, so all it is going to be doing is calling that one statement repeatedly.  Now that might not be a problem or the second call may be blocking the first from completing.  So I suggest add a delay for a second or so and see if that changes anything.  Also to prove you are running you Loop() code flash the LED on the board (pin13?).
Hope that helps.


text:
What are ideal delay times between commands for RF24 lib
Am working on a WiFi based irrigation system that utilises the RF24 lib for comms.
Have got prototype of remote sensor up and running which has a standby current of 0.036mA and transmits data every hour using around a peak of 12mA.
While running the prototype I see various retry attempts which seem to vary with every transmission – despite the setup being under the same conditions all the time. I have coded a retry loop to limit this to 10 tries connecting to the master – don’t want the sensor to continuously be sending without getting a confirmation from the master
What I am trying to find is the ideal delay required between various RF24 commands to limit transmit times as much as possible to conserve power usage.
Any ideas??
(code snippets attached)
   pinMode(mostureSensorVCC, OUTPUT);
   digitalWrite (mostureSensorVCC, HIGH); //VCC to sensor
   pinMode(mostureSensor1, INPUT);      //moisture sensor on
   delay(10);
   int sensorValue1 = analogRead(mostureSensor1); // read the input on analog pin
   Serial.print("Current Value Sensor 1 is : "); // debugging
   Serial.println(sensorValue1); // print out the value you read:
   msg[0] = sensorValue1;
    digitalWrite(mostureSensor1, LOW);
    digitalWrite(mostureSensorVCC, LOW);
      while (message != sensorValue1)
        {

          Serial.print("sensorValue in while loop is "); // debugging
          Serial.println(sensorValue1);                   // debugging
          Serial.print("Message One is ");                // debugging
          Serial.println(message);                        // debugging
          radio.powerUp();
          delay(70);

          radio.stopListening();
          delay(50);
          radio.write(msg, 2);
          delay(40);
          radio.startListening();
          delay(50);

         Serial.println(d);               // debugging

          if (radio.available())
            {
             Serial.println("Radio available");     // debugging
              radio.read(msg, sizeof(msg));
              message = msg[0];
              Serial.print("Check Message received from master ");// debugging
              Serial.println(message);

            }
            if(d>=10)
            {
              Serial.println("Unable to send to master");
              break;
            }
       d++;
  }

delay(1000);
radio.powerDown();
message = 0;
msg[0] = 0;

Do you eventually get confirmation after a number of tries? What state (power saving and all) is the master in when the node is starting to transmit? And what makes you think delay (or lack therof) is the cause? Did you try to adjust transmit power and data rate instead?

Don't use delays, totally unnecessary 2. Look at the examples, PingPair etc.

Hi, Thanks for the great responses Get confirmation after different numbers of replies – ranges from 2 to 8 or 9 attempts to the master. Have seen on the master that it occasionally receives upto 3 messages which it seems to respond to.
Will include relevant code clip from master below

I have configured a specific channel outside of most used in my area, and have used recommended settings for remote sensor transmits
    //.....start radio and pipes.....

Serial.println("Start radio...");  // debugging
radio.begin();
delay(30);
radio.setPALevel(RF24_PA_MAX);
radio.setDataRate(RF24_250KBPS); //Fast enough.. Better range
radio.setChannel(108); //2.508 Ghz Above most Wifi Channels
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]);

Remove all delays except the one after startListening.
You could replace it with a "wait for radio.available to be true OR 50ms to have passed" piece of code. There is no need to wait for 50ms if the message was already received after e.g. 10ms.
Even better would be to use the ACK-package feature of the NRF. With this feature the master already prepares a package for the slave. Then when the slave sends it's message (every hour), the prepared package is included in the ACK (acknowledgement) packet.
As to optimizing it even further. It would be better to optimize the sleep code, then the send code. The sleep part will still use more power in an hour than the sending code, even if it takes 10 second to do so.
As to the lost packages. Try using a different channel. You also might want to get an NRF module with an real antenna, and maybe even an amplifier, for the master.
PS You can remove the serial.print in the deployed version.

Hi, Thanks for the response. Not sure how to configure ACK package feature – pretty new to this radio stuff. Have ( I feel) got the sleep code pretty well configured – drawing around 0.035mA while sleeping which works for me
All of the Serial.Print statements are just for debugging and I do remove them from the deployed code.

Also check out this battery calculator to see how much runtime you get.


text:
Using #define and multiple classes
I am using the FastLED library in my program and the basic usage is that the following lines go at the top of the main sketch:
#include <FastLED.h>
#define NUM_LEDS 60
#define DATA_PIN 6

You can see the documentation at https://github.com/FastLED/FastLED/wiki/Basic-usage
However, I am using the FastLED library in several different objects in my program and I would like to be able to reference NUM_LEDS in different header files for each object so that the number of LEDS can be controlled just by changing the value in the main sketch.
I am also intending that my own objects can be made into libraries for others to use, so they will then define the settings in their main sketch, that my libraries will then use.

Sure.. Create a header file containing those three lines (call it, for instance, FastLedInclude.h) and then, in each file you need the FastLed library, write #include "FastLedInclude.h" instead of #include <FastLed.h>

This won't work as someone using my library in their own fastLED sketch won't then be able to define their own size of project from the main sketch. I'll alter my question to make sure that is understood.

You will need to have NUM_LEDS defined in every file you compile; that's why you need it in a header file to be included by every cpp or ino file. Now, if you want to make a library, that file should either be in 1) the library folder, or 2) the sketch folder. The second approach is, IMHO, very bad, since it requires the user to create the file in its sketch folder and requires the library to know where the sketch is, which is against the definition of "library", i.e. a piece of code that can work by itself. My personal advice is to ask the user to modify the library file or, if you don't want

to force/allow him to modify your files, edit the code using dynamic allocation instead of compile-time static allocation. I mean, instead of defining DATA_PIN you can store a uint8_t variable in your class containing the data pin. You can do the same with NUM_LEDS, and then allocate the matrix dynamically (with mallocs or news) in the code. It can have lower performances, but it will work better

That's very helpful. I wonder if I could I ask the user to add const byte numberOfLeds = NUM_LEDS to their sketch and then use numberOfLeds in my library rather than NUM_LEDS ?

and then add a pointer to const byte numberOfLeds in my library header?

Well, your library will contain at least one class, won't it? Consequently you can store the variable in your class, then either make it public (bad) or private (better) and set it in the constructor. So the user will have to allocate your object dynamically yourclass *obj = new yourclass(60); (or, if he defined #define NUM_LEDS 60, he can write yourclass *obj = new yourclass(NUM_LEDS );) or statically yourclass obj(60); (or yourclass obj(NUM_LEDS );). In either case you will have the value stored in your object

This is very helpful, many thanks. I tried to implement the #include "FastLedInclude.h" version that you first suggested and I realised that I didn't give all of the information in the question. The FastLED setup also needs me to add struct CRGB leds[NUM_LEDS]; into pages where the code is used. If I include that in FastLedInclude.h then I get a compile error multiple definition of 'leds'

I have tried using struct CRGB leds[NUM_LEDS]; in the main sketch and extern CRGB *leds; in my cpp files and it compiles but the program does not work

Of course you can't DEFINE a variable in a header, otherwise you can happen to define it more than once. You definitely can DECLARE it, and you should declare it extern, then define it in only one cpp or ino file. The usual way is to 1) write extern struct CRGB leds[]; in the FastLedInclude.h file. 2) choose a ino or cpp file (probably the main ino file is not the most indicated, but should work) and write struct CRGB leds[NUM_LEDS];. If this does not work, post your code and I'll try to have a look at it

This works perfectly! Thank you so much for your assistance, feel free to contribute this as an 'answer'

I added the answer with some more examples..

As the OP suggested, I'm posting a summing up of the comments under his question since the answer was found.
In order to make a common define for those parameters in different source files, the easiest solution is to make a shared header. To do this, just create a new file called FastLedInclude.h and, inside of that, write
#include <FastLED.h>
#define NUM_LEDS 60
#define DATA_PIN 6

Then in every source file you will just have to #include "FastLedInclude.h" to be able to use that library.
The FastLED library also requires the programmer to create a struct. Now, placing the definition of the struct (i.e. struct CRGB leds[NUM_LEDS];) into the header file leads to compilation errors, since the compiler writes the code to allocate it once for every object file.
The correct way to share this among different object files is to declare it extern in the header, then define it just once in one of the cpp or ino files:
// into FastLedInclude.h
extern struct CRGB leds[];

// into any cpp or ino file (but just once)
struct CRGB leds[NUM_LEDS];

This can also be done in the main ino sketch file, but personally I prefer to define it into another one (it depends, however, on how you choose to divide the program).
If you want to create a library, some other problems arise. The easiest solution is to ask the user to manually modify the header file which will be in the library folder. This solution is a bit uncomfortable, but it is the safest one.
Another solution is to force the user to create a header file into the sketch folder. Then the library should know the sketch folder path to back-include it. But.. This is a very discouraged option, since it will require the library to know the sketch location, thus violating the consistency principle at the base of a library-based approach.
The third solution is to modify the approach, from a compile-time static definition to a dynamic one. In order to do this, instead of defining NUM_LEDS and DATA_PIN at compile time you save them as variables in the library class.
For instance, in your library class definition you have
class yourclass
{
    public:
        yourclass(uint8_t data_pin, uint8_t num_leds);
        ~yourclass();
    private:
        uint8_t _data_pin;
        uint8_t _num_leds;
        struct CRGB *leds = NULL;
};

And the implementation can be
yourclass::yourclass(uint8_t data_pin, uint8_t num_leds)
{
    _data_pin = data_pin;
    _num_leds = num_leds;

    // Dynamic allocation of the array
    leds = (struct CRGB *) malloc(num_leds * sizeof(struct CRGB));
}

yourclass::~yourclass()
{
    // you should free the leds array when done
    free(leds);
}

Then the user can write
yourclass *obj = new yourclass(6, 60);

// or, if he wants to define,
#define NUM_LEDS 60
#define DATA_PIN 6
...
yourclass *obj = new yourclass(DATA_PIN, NUM_LEDS);

or, in the case of a statically allocated object,
yourclass obj(6, 60);

// or, if he wants to define,
#define NUM_LEDS 60
#define DATA_PIN 6
...
yourclass obj(DATA_PIN, NUM_LEDS);