Nokia5110 and NRF2401 not working together

Hello fellow Ardiuniers,

I'am having trouble getting a PCD8544 and a NRF2401 working together.
The idea is to have a sender transmitting temperature values by NRF2401. The receiver will display the received values on a Nokia5110 display.
When i'am using the "PCD8544" (sketch is not included) library the values are received correctly. But whem i'am using the "ADAFruit-PCD8544" library together with the "ADAFruit-GFX" library, then there are no values being received. I want to use the ADAFruit libs so i can plot a histogram of the temperature.
Please be gentle with me, i'am absolutely not a programmer, the code has most of the part been borrowed :slight_smile:
I hope you can help me out with this one...

Here is the code for the receiver
(the transmitter follows in a seperate post)

//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
	return 1.8 * celsius + 32;
}

// fast integer version with rounding
//int Celcius2Fahrenheit(int celcius)
//{
//  return (celsius * 18 + 5)/10 + 32;
//}


//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
	return celsius + 273.15;
}

// dewPoint function NOAA
// reference: http://wahiduddin.net/calc/density_algorithms.htm 
double dewPoint(double celsius, double humidity)
{
	double RATIO = 373.15 / (273.15 + celsius);  // RATIO was originally named A0, possibly confusing in Arduino context
	double SUM = -7.90298 * (RATIO - 1);
	SUM += 5.02808 * log10(RATIO);
	SUM += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/RATIO ))) - 1) ;
	SUM += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ;
	SUM += log10(1013.246);
	double VP = pow(10, SUM - 3) * humidity;
	double T = log(VP/0.61078);   // temp var
	return (241.88 * T) / (17.558 - T);
}

// delta max = 0.6544 wrt dewPoint()
// 5x faster than dewPoint()
// reference: http://en.wikipedia.org/wiki/Dew_point
double dewPointFast(double celsius, double humidity)
{
	double a = 17.271;
	double b = 237.7;
	double temp = (a * celsius) / (b + celsius) + log(humidity/100);
	double Td = (b * temp) / (a - temp);
	return Td;
}

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


#include <OneWire.h>
//#include <DallasTemperature.h>

// Data wire is plugged into port 2 on the Arduino
#define ONE_WIRE_BUS 10

// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);


#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

// pin 7 - Serial clock out (SCLK)
// pin 6 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 7, 6);

#define Backlight_Pin 8


int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int lastmsg = 1;
String theMessage = "";
int messageLength = 0; // voor checksum of complete bericht binnen is.
int berichtLengteInt;
int teller;
int dht11_temperatureInteger;
int dht11_humidityInteger;

String berichtLengte, berichtDecoded, berichtDecodedB1, berichtDecodedB2;
String berichtID, berichtValue1, berichtValue2;
 
void setup()
{
  Serial.begin(9600);

  // Nokia 5110 display
  display.begin();

  // you can change the contrast around to adapt the display
  // for the best viewing!
  display.setContrast(50);

  pinMode(Backlight_Pin, OUTPUT);

  pinMode(0, INPUT);
  //Serial.print("Backlight ");
  //Serial.println(analogRead(0));

  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(BLACK);
  display.setCursor(0,0);
  display.println("Ready");
  display.display();
  
  // nrf2401
  radio.begin();
  radio.openReadingPipe(1,pipe);
  radio.startListening();
}

float dht11_temperature = 0;
float dht11_humidity = 0;
float ds18b20_temperature = 0;

#define TEMP_SIZE LCDWIDTH
//float temp[TEMP_SIZE] = {0.0};
float temp[TEMP_SIZE] = {0};

int temp_pos = 0; // position in circular buffer above

void loop()
{
  //Serial.println("\n");

   if (radio.available()){
      bool done = false;  
      done = radio.read(msg, 1); 
      char theChar = msg[0];
      
        berichtLengte = theMessage.substring(0,(theMessage.indexOf(" ")));  // get the first character up to the space separator and save it to bericht array
      berichtLengteInt = (berichtLengte.toInt());
      
      // bericht tekst "uitlezen", alles vanaf de spatie - "hok 8 44"
      berichtDecoded = theMessage.substring(theMessage.indexOf(" ")+1);  // get the characters from space separator up the end of the string and save it to berichtDecoded array
      // bericht tekst "uitlezen", alles vanaf de spatie gezien vanaf variable "berichtDecoded", dus eigenlijk 2e spatie van het bericht
      // "8 44"
      berichtDecodedB1 = berichtDecoded.substring(berichtDecoded.indexOf(" ")+1);   
      berichtDecodedB2 = berichtDecodedB1.substring(berichtDecodedB1.indexOf(" ")+1); // volgende spatie (humidity)
       berichtID = berichtDecoded.substring(0,(berichtDecoded.indexOf(" ")));
       // eerste getal in de string (temperatuur)
      // "8"
      berichtValue1 = berichtDecodedB1.substring(0,(berichtDecodedB1.indexOf(" ")));
      berichtValue2 = berichtDecodedB2.substring(0,(berichtDecodedB2.indexOf(" ")));
          
      /*
      Error checking part
      Wanneer de uitgelezen berichtlengte gelijk is aan de lengte van het bericht, dan is het bericht goed
      */
       if (msg[0] != 2){
          theMessage.concat(theChar);
          // gaat niet goed, checksum klopt niet!
        }
        
       else {
         if (theMessage.length() == berichtLengteInt) {
         // lcd.println(theMessage);            // gaat goed, checksum klopt!
   
  dht11_humidityInteger = (berichtValue1.toInt());  // convert the string to integer and save it to variable berichtMeting
  double dht11_humidity = dht11_humidityInteger;  // convert int to float, anders zie je de waarde niet op LCD!!!!
  
  int chk = random(10, 20);

  //dht11_humidity = random(50, 70);
  //Serial.print("Humidity (%): ");
  //Serial.println(dht11_humidity, 2);

  // dht11_temperature = random(10, 25); voor testen zonder sensor

  dht11_temperatureInteger = (berichtValue1.toInt());  // convert the string to integer and save it to variable berichtMeting
  float dht11_temperature = dht11_temperatureInteger;  // convert int to float, anders zie je de waarde niet op LCD!!!!
  //dht11_temperature = 8;

  //Serial.print("Temperature for the device 1 (index 0) is: ");
  ds18b20_temperature = random(10, 20);
  //Serial.println(ds18b20_temperature);  

  temp[temp_pos] = ds18b20_temperature;

  display.clearDisplay();
  display.setCursor(0,0);
  display.print(dht11_temperature, 0);
  //display.print(10, 0);
  display.print("C ");
  display.print(dht11_humidity, 0);
  display.print("% ");
  display.print(ds18b20_temperature, 2);
  display.print("C");

  float min = temp[0], max = temp[0];
  
  for(int i = 0; i < TEMP_SIZE; i++) {
    //    Serial.print(temp[i]);
    //    Serial.print(" ");
    if (temp[i] < min && temp[i] > 0) min = temp[i];
    if (temp[i] > max) max = temp[i];
  }
  
      // draw right to left so most recent value is on the right
      for(int x = TEMP_SIZE - 1; x >= 0; x--) {
        int pos = ( x + temp_pos + 1 ) % TEMP_SIZE;
        if ( temp[pos] > 0 ) {
          int y = ( ( temp[pos] - min ) / ( max - min ) ) * ( LCDHEIGHT - 10 );
          display.drawLine(x, LCDHEIGHT - y, x, LCDHEIGHT, BLACK);
    //      display.drawPixel(x,y + 10, BLACK);
    //      Serial.print(temp[pos],2);
    //      Serial.print(" ");
    }
  }
      //Serial.println();
    
      // refresh LCD
      display.display();
    
      // pulse display backlight
      int backlight = 0;
    
      float old_temp = temp[(temp_pos + TEMP_SIZE - 1) % TEMP_SIZE];
      if ( ds18b20_temperature < old_temp ) {
        backlight = 32;
      } else if ( ds18b20_temperature > old_temp ) {
        backlight = 255;
      }
      analogWrite(Backlight_Pin, backlight);
    
      delay(2000);
    
      // move slot in circular bugger
      if ( ++temp_pos > TEMP_SIZE ) temp_pos = 0;

    }

    }
       theMessage= ""; 
   }
}
  
// END OF FILE
//

here is the transmitter code:

// http://shanes.net/simple-nrf24l01-with-arduino-sketch-and-setup/

#include <nRF24L01.h>
#include <RF24.h>
#include <RF24_config.h>
#include <SPI.h>
int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;

String sendStationID = "hok";
String seperator = " ";
int sensorTmpReading = 8;
int sensorHumReading = 44;

 
/*  Voorbeeld hoe een integer ge'convert kan worden naar string en of char.
    float tempReading = bmp.readTemperature();
    //float tempReading = -2;

    float pressureReading = bmp.readPressure()/100;
      
    // send text over RF verb.  (Spatie voor temp waard zit in de 7, de wide value.)
    dtostrf(tempReading, 6, 2, tempC); // convert floating value to string! - Min. 6 chars wide incl. decimal point, 2 digits right of decimal
    omzetStringTemp1 = sendStationID + ScheidingsTeken + SensorTypeTemp + tempC;
    char DataPakketTemp[omzetStringTemp1.length()]; omzetStringTemp1.toCharArray(DataPakketTemp, omzetStringTemp1.length());
    
    // pressure values processing
    dtostrf(pressureReading, 8, 2, pressure);
    omzetStringPressure1 = sendStationID + ScheidingsTeken + SensorTypePressure + " " + pressure;
    char DataPakketPressure[omzetStringPressure1.length()]; omzetStringPressure1.toCharArray(DataPakketPressure, omzetStringPressure1.length());

    
    // Serial.print("te zenden variable: ");
    Serial.println(DataPakketPressure);
    Serial.println(DataPakketTemp);
    send(DataPakketTemp);
*/
void setup(void){
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);}
  void loop(void){
    // String theMessageBase = " hok 8 44 ";
  String theMessageBase = seperator + sendStationID + seperator + sensorTmpReading + seperator + sensorHumReading + seperator;

  int messageSize = theMessageBase.length();
  messageSize++; // 1 bijop tellen omdat size nr. ook in message komt
  String theMessage = messageSize + theMessageBase;
  for (int i = 0; i < messageSize; i++) {
    int charToSend[1];
    charToSend[0] = theMessage.charAt(i);
    radio.write(charToSend,1);
  }
    //send the 'terminate string' value...  
    msg[0] = 2; 
    radio.write(msg,1);
    /*delay sending for a short period of time.  radio.powerDown()/radio.powerupp
    //with a delay in between have worked well for this purpose(just using delay seems to
    //interrupt the transmission start). However, this method could still be improved
    as I still get the first character 'cut-off' sometimes. I have a 'checksum' function
    on the receiver to verify the message was successfully sent.
    */
    //radio.powerDown(); 
    //delay(2000);
    //radio.powerUp();
  
  //for (int x=0;x<255;x++){
  //msg[0] = x;
  }

You need to Redo this post using the code
button ("#") to ceate scrolling window for the code.
Use the MODIFY button to edit the post.
Put the code inside the window and Remove
the second post.

Oke, now it is more readable ;]

you should be able to create 2 separate sctoll windows in the
first post and delete the second post.
All the info should be in the first post.

;[ the message would exceed 9500 characters.....

Please be gentle with me, i'am absolutely not a programmer, the code has most of the part been borrowed

FYI,
All of your "#includes" should preceed any code.
In your receiver code, you have #includes sprinkled all through the code.
I know you are copy & pasting everything but if you are going to do that you should probably
just consolidate them all at the beginning of the code. I doubt this has anything to do with your problem but
just thought I should let you know that as a general rule , they should all be at the beginning.

Could it be a SPI thing?

Cutorix:
When i'am using the "PCD8544" (sketch is not included) library the values are received correctly. But whem i'am using the "ADAFruit-PCD8544" library together with the "ADAFruit-GFX" library, then there are no values being received. I want to use the ADAFruit libs so i can plot a histogram of the temperature.

The problem could be in the library, and nothing to do with the code, as that is where the calls to the pins on the LCD are made. If you have not come across this before, i.e. the 5110 worked with PCD8544, it could be that you just got lucky. You might check to see if your luck still holds, and the assignment is the same in the ADA library.

The area I refer to is line 28 -32 in PCD8544.h

It would pay to leave the GFX out of the game for the moment, particularly as you are unclear about it being a problem or not.

Thanks for your input, i suppose the library is OK, because when i do not use the radio
code, then the display is working fine.

I'am trying to setup SPI on my sketch, the wiring should now be SPI enabled, but the software side
is not ready yet... ;]

At this time, when de Arduino reaches the radio part;
"radio.begin();
radio.openReadingPipe(1,pipe);
radio.startListening();"

The display stops working (go's blank) When i leave the radio code out, the display works like a charm...
I tried to control SPI with code like this;

"// don't talk to LCD while we init RF24
digitalWrite(LCD_SELECT, LOW);
digitalWrite(RF24_SELECT, HIGH);"

But it doesn't seem to respond in any way to this.

I don't have a clue how to setup SPI from here, do i need to go hardware or software SPI ?
With hardware SPI, will everything go automatic ?

The wiring is as follows

Arduino nano mega328

Nokia5110
RST - 6
CE - 7
DC - 5
DIN - 11
CLK - 13

NRF2401
CE - 9
SCK - 13
MISO - 12
CSN - 10
MOSI - 11

Used libraries
<SPI.h>
<nRF24L01.h>
<RF24.h>
<RF24_config.h>
<Adafruit_GFX.h>
<Adafruit_PCD8544.h>

Are you using a decent wall-wart for power?

radio.begin(); = increase power consumption

and it might be the display that reflects that.

I'am feeding the set by a USB cable from the PC.
If it would be a power issue, the same problem would exists when i use the (simpeler/with no graphic support) PCD8544 library?

But it sure is a thing to look into, i'am gonna try with something that gives more juice :slight_smile:

Get a 9v wall-wart - immediately......

I doubt changing the library would help. Dousing the backlights would be a lot more constructive. If your 5110 has those moronic "kool" blue backlights, you might find the text is more easily read with them off anyway.

Hmm, did feed the set with a 2A supply, still the same, display backlight was never been used.

I'am out of tricks.
Any SPI experts out there ?

The volts are of more interest than the amps.

I don't claim any great expertise in SPI, in fact I was going to suggest taking the 5110 off SPI to see if that isolated the problem. I don't think there is any obligation to run the 5110 on SPI. I notice though that you have the same wiring as me. This is just a coincidence but I don't have a problem, so I don't think it is yours either.

When i remark the radio stuff from the code, the display is running as a breeze, but as soon radio.listening(); is activated everything freezes again.

I fed the display with 5v, same result, except the display was flickering a bit.
I tried to swap the display from the nano to the ATMega328 Uno, also the same freezes.

If i understand correctly from you, i don't need to do anything with SPI at this point ? (the SPI.lib has to be loaded, the PCD8544 libs depend in on it)

The stange thing is still when i use the (non-graphics) library(PCD8544) both NRF2401 AND the display are working.

Is that a 3.3V Nano ? (everything else is ...)

Cutorix:
When i remark the radio stuff from the code, the display is running as a breeze, but as soon radio.listening(); is activated everything freezes again.

I fed the display with 5v, same result, except the display was flickering a bit.
I tried to swap the display from the nano to the ATMega328 Uno, also the same freezes.

If i understand correctly from you, i don't need to do anything with SPI at this point ? (the SPI.lib has to be loaded, the PCD8544 libs depend in on it)

The strange thing is still when i use the (non-graphics) library(PCD8544) both NRF2401 AND the display are working.

I think it might be time to re-read reply #8.

There may be a problem because there are more than one library called PCD8544. The library I alluded to is the original from Philips. The wire calls are in the library, not the sketch, which means the library has to be checked against the wiring to the LCD. I'm not certain that you are using this library, but I do understand that, even if you are, you don't want to, you want to use the ADA graphics library, and that is the one that is giving you grief.

Ignore what I said about SPI, it could be wrong and is certainly irrelevant. My 5110s are on shields designed for Uno, hence use MOSI,11 and CLK,13, but run on Megas unchanged.

I recall you have already shown there is no pin clash between 5110 and NRF24 and now the two work together provided you have the non-graphics library.

So one can hardly draw any other conclusion than that Lady Ada's library, or the application thereof, is suss.

Looking at you code, I see

#include <Adafruit_GFX.h>
#include <Adafruit_PCD8544.h>

// pin 7 - Serial clock out (SCLK)
// pin 6 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 4 - LCD chip select (CS)
// pin 3 - LCD reset (RST)
Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 7, 6);

This implies that DIN is on 6 not 11, MOSI, and CLK is on 7 not 13,CLK.

I understand you have wired your 5110, the same as me, for Uno SPI bus. So, do you re-wire the 5110 to match the ADA command? If not, I believe the command should be

Adafruit_PCD8544 display = Adafruit_PCD8544(3, 4, 5, 13, 11);

The remarks in the code was not correct, it sayd something different then my problem description.
The pin setup is:

// pin 3 - Serial clock out (SCLK)
// pin 4 - Serial data out (DIN)
// pin 5 - Data/Command select (D/C)
// pin 7 - LCD chip select (CS)
// pin 6 - LCD reset (RST)

The ADA-Fruit lib i'am using says this in the readme:
It is not a rewrite/modified version.

It might be something in the code, but what?


This is a library for our Monochrome Nokia 5110 LCD Displays

Pick one up today in the adafruit shop!
------> Nokia 5110/3310 monochrome LCD + extras : ID 338 : $10.00 : Adafruit Industries, Unique & fun DIY electronics and kits

These displays use SPI to communicate, 4 or 5 pins are required to
interface

Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!

Written by Limor Fried/Ladyada for Adafruit Industries.
BSD license, check license.txt for more information
All text above must be included in any redistribution