Problemi modulo NRF24L01+ assieme a microSD card

Buongiorno a tutti.

Gentili signori del forum,
come si comprende dal titolo ho qualche problema nel far funzionare assieme i moduli NRF24L01+ e microSD.
Dopo aver trascorso un week end leggendo, provando, smontando, rileggendo e riprovando, mi permetto di disturbarvi alla ricerca di una possibile soluzione alla questione (grazie in anticipo).

Veniamo al dunque:
Su una millefori con un Atmega328 a 8MHz (quindi senza quarzo) ho attaccato un modulo per la scrittura su microSD ed un modulo NRF24L01+ (vedere immagini allegate) ... anche un LCD su I2C, ma non è il discriminante. Nella configurazione hardware descritta, caricando uno sketch per far funzionare solamente la microSD, la scrittura funziona a dovere. Stessa situazione positiva se viene caricato uno sketch per far funzionare il solo modulo NRF24L01+ (la configurazione hardware non è stata modificata).

Il problema nasce se carico uno sketch con il quale si voglia utilizzare entrambi i moduli. Vi allego il codice:

#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <SD.h>

#include <RF24Network.h>
#include <RF24.h>
#include <SPI.h>

LiquidCrystal_I2C lcd(0x27,20,4);
File myFile;


// nRF24L01+
// RF24 radio(CE, CS)
RF24 radio(8, 7);

// Network uses that radio
RF24Network network(radio);

// Address of our node
const uint16_t this_node = 0;

// Address of the other node
const uint16_t other_node = 1;

// Structure of our payload
struct payload_t
{
	unsigned long ms;
	unsigned long counter;
	unsigned long Postazione;
	double Valore;
};

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

	Serial.println("RF24Network/examples/helloworld_rx/");
	SPI.begin();
	radio.begin();
	network.begin(/*channel*/ 90, /*node address*/ this_node);

	// LCD
	lcd.init(); 
	lcd.backlight();
	lcd.clear();
	lcd.setCursor(0, 0);
	lcd.print("Initializing...");

	// SD, inizializzazione
	Serial.print("Initializing SD card...");
	pinMode(10, OUTPUT);

	if (!SD.begin(4)) {
		Serial.println("Initialization failed!");
		return;
	}
	Serial.println("Initialization done.");
	myFile = SD.open("test.txt", FILE_WRITE);
	// SD, fine inizializzazione
}


void loop()
{
	// LCD 
	lcd.clear();
	lcd.setCursor(0, 0);
	lcd.print("Millis: ");
	lcd. print(millis(), DEC);

	// SD, inizio scrittura
	myFile = SD.open("test.txt", FILE_WRITE);
	if (myFile) {
		myFile.print(millis());
		myFile.println("\t1234567890");
		
		lcd.setCursor(0, 2);
		lcd.print("SD OK");

		// close the file:
		myFile.close();
		Serial.println("done.");
	} else {
		// if the file didn't open, print an error:
		Serial.println("error opening file");
		lcd.setCursor(0, 2);
		lcd.print("SD Fail");

	}
	// SD, fine scrittura

	Serial.println("Punto A");
	// Pump the network regularly
	network.update();
	Serial.println("Punto B");

	// Is there anything ready for us?
	while ( network.available() )
	{
		// If so, grab it and print it out
		RF24NetworkHeader header;
		payload_t payload;
		network.read(header,&payload,sizeof(payload));
		Serial.print("Received packet #");
		Serial.print(payload.counter);
		Serial.print(" at ");
		Serial.print(payload.ms);
		Serial.print(" Postazione ");
		Serial.print(payload.Postazione);
		Serial.print(" Valore ");
		Serial.println(payload.Valore,4);
	}
	delay(2000);
}

Il processo si blocca alla riga "network.update();" ed a monitor compaiono le scritte che indicano la corretta inizializzazione dell'SDcard "Initialization done." ed in seguito la scritta "Punto A". Se nel codice vengono commentate tutte le righe relative alla scrittura su SD, il processo cicla a dovere, comunicando correttamente con un altro trasmettitore NRF24L01+ montato su un'altra scheda Arduino.

Comprendo che entrambi i moduli siano sul bus SPI e che pertanto occorre qualche accorgimento in più che non riesco a trovare.

Come si vede dal codice, il CE e CS del modulo NRF sono 8 e 7, mentre per la microSD abbiamo dedicato il pin 4 e il 10. Chiaramente i pin MOSI, MISO e SCK sono in comune.

Le librerie che utilizzo sono:
<SD.h> per la microSD
<RF24Network.h> e <RF24.h> (maniacbug · GitHub) per il modulo NRF24L01+

Sistema:
IDE 1.0.3, Windows XP

Alimentazione:
I moduli prendono corrente direttamente dall'alimentatore che eroga fino a 1A

Codici:
Ho copiato, incollato e modificato gli esempi che sono all'interno delle librerie utilizzate.

Ecco quindi esposta la questione, grazie per l'aiuto.

Buon inizio di settimana.
Tredipunta.

NRF24L01-pinout4.jpg

In un sistema SPI, è il segnale CS che indica quale dispositivo può usare la comunicazione SPI.
Ovvero ogni dispositivo deve avere un pin CS e solo uno alla volta deve attivare la linea CS (mi sembra che per attivo si intende LOW, disattivo HIGH). Gli altri pin MISO,MOSI,SCLK sono in comune.
Nella immagine SS=CS, in arancione Arduino

Puoi provare perciò a "spegnere" la linea CS del SD (pin 4) o del NFR (pin 7) usando la digitalWrite()

Caspita, ho fatto già un paio di errori, ho collegato male il segnale MOSI e MISO, facendo lo stesso tipo di collegamento previsto per la linea SCLK (ovvero collegando erroneamente in parallelo gli slave, anzichè entrare col MOSI e uscire con MISO... rientrare e uscire nuovamente).

Intanto stasera metto apposto i collegamenti e poi vedo la questione del segnale CS.

Grazie per l'aiuto.

Tredipunta.

Ciao,
Anche io ho provato nel impresa ma senza risultati usavo però:

#include <Mirf.h>
#include <nRF24L01.h>
#include <MirfHardwareSpiDriver.h>

e tentavo di "spenere" NRF24L01 con:

Mirf.ceLow();

Quali vantaggi hai nel usare la libreria RF24Network?

Ciao,
appena ho avuto in mano i moduli ho provato con la libreria Mirf.

Purtroppo ho visto che ogni tanto, per interferenza di segnali (wifi di casa, tastiera e mouse con comunicazione a 2.4GHz), il segnale ricevuto viene "sporcato" e quindi vien letto dal ricevitore un valore diverso (ho provato anche cambiando il channel).

Ho cercato pertando di attivare nella Mirf un controllo CRC (senza però riuscirvi). Ho così incluso nel segnale che invio, un controllo CRC scritto da me (un sistema banale che uso anche nei moduli radio RF433), accorgendomi quindi delle ricezioni "sbagliate" e rilevando di aver perso il dato per sempre (a meno di non interrogare nuovamente il modulo che ha effettuato l'invio ecc.. ecc... ).

Ho provato quindi la libreria RF24Network scoprendo le seguenti caratteristiche (esperienza di un week-end):

  • direi che la libreria fa da se un controllo di coerenza del segnale, probabilmente chiedendo nuovamente il dato al modulo che ha fatto l'invio (questo lo deduco io in quanto tutti i segnali giunti alla base sono corretti)

  • se la frequenza di invio è più elevata della frequenza di ricezione (metti caso che il sistema di ricezione stia facendo dell'altro), una volta che il ricevitore torna "attivo" (passando per il "network.update") giungono anche i segnali che sono stati inviati in precedenza ma che non sono stati ricevuti (in usa sorta di coda LIFO arrivano magari 3 segnali contemporaneamente, dal più recente al più vecchio)

  • leggendo la documentazione pare che il sistema Network si basi su una gerarchia tipo padre-figlio con la possibilità di creare "alberi" nei quali la comunicazione viene realizzata solo tra padre e figlio/i

Viste queste tre cose e notando soprattutto che nativamente i segnali ricevuti sono sempre corretti, ho pensato di utilizzare la RF24Network.

Un saluto,
Tredipunta.

Ottima segnalazione.
Grazie.

Approfitto visto che anche io mi sto cimentando con questi modulini wireless, avete trovato anche un qualche esempio tradotto in italiano?
Io sto provando la libreria rf24, ora son riuscito a farli funzionare con gli esempi e vorrei comprenderli meglio, ma tra inglese e scarso tempo faccio un po' fatica.
Per fare pratica vorrei creare un semplice sistema che mi inviasse la temp. esterna all'altro arduino che la mostrerà sulla seriale, vorrei lasciare quindi il minimo di comandi nello sketch e vorrei comprendere a modo ogni comando cosa fa negli sketch di esempio.
Grazie,
Marco

Purtroppo, nonostante abbia modificato i collegamenti come consigliato, non sono riuscito a far funzionare assieme entrambi i moduli.
Leggendo in rete ho compreso che la comunicazione per le schede sd, pur basandosi sul bus SPI, ne fa un uso leggermente diverso, con una modalità di utilizzo "ad hoc".
Pertanto, da come l'ho compresa io, non sembra perfettamente compatibile con altri dispositivi SPI (o almeno non con tutti).

Diverso è invece il caso della Ethernet Shield (esperienza personale) che monta un alloggiamento per la micro SD. Questa scheda di fatto utilizza il protocollo SPI sia per la "parte" ethernet che per la scrittura su sd (e funzionano bene entrambi, non saprei dire il perchè).

Ad oggi, per la mia esperienza, l'unica maniera fattibile di utilizzare la scheda SD ed il modulo NRF24L01+, è di collegarli ognuno ad un Atmega dedicato e far comunicare i due integrati via I2C oppure via seriale.

Un saluto a tutti,
Tredipunta.

una soluzione potrebbe essere:
http://www.lctech-inc.com/Hardware/Detail.aspx?id=6eef0699-1faf-406b-a5c3-75b857b63cca
non ho trovato molte informazioni a riguardo ma...

Per scanner canali occupati da wifi vi consiglio la discussione sul questo argomento di qualche giorno fa:
http://forum.arduino.cc/index.php?topic=211804.msg1566484#msg1566484

Ciao
Gio

Sembra che qui ci sia una soluzione al problema di SD e nRF4 usate insieme:

Ciao
Gio