Arduino DUE + nRF24L01
- Войдите на сайт для отправки комментариев
Пнд, 17/02/2014 - 00:27
Здравствуйте. Сделал беспроводной датчик температуры и влажности на основе DHT22, Arduino Mini PRO и nRF24L01 (передатчик). Сделал приемник на основе Arduino Mini PRO и nRF24L01 (приемник). Данные температуры и влажности передаются без ошибок, все хорошо. Подсоединил nRF24L01 к Arduino DUE и сделал его как приемник. Данные получает, но не верные! То есть Arduino Mini PRO передает данные на Arduino DUE с ошибками, а Arduino Mini PRO на Arduino Mini PRO - без ошибок. Код не менял. Может кто знает в чем дело?
Код приемника: (Arduino DUE)
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
typedef struct {
int W;
int X;
int Y;
int Z;
}
B_t;
B_t duino2;
RF24 radio(9, 10); //RF24 radio(uint8_t _cepin, uint8_t _cspin); для DUE
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
void setup()
{
Serial.begin(9600);
radio.begin();
radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1, pipes[0]);
radio.startListening();
}
void loop(void)
{
//Serial.println("Begining.");
if ( radio.available() )
{
bool done = false;
while (!done)
{
done = radio.read( &duino2, sizeof(duino2) );
Serial.print("Controller = ");
Serial.println(duino2.W);
Serial.print("T= ");
Serial.println(duino2.X);
Serial.print("H = ");
Serial.println(duino2.Y);
Serial.print("DP = ");
Serial.println(duino2.Z);
}
}
}
Код передатчика: (Arduino Mini PRO)
#include <SPI.h>
#include "RF24.h"
#include <avr/sleep.h>
#include <avr/wdt.h>
//int battVolts;
int count; //переменная для счётчика циклов
int h = 0; //влажность
int t = 0; //температура
int dp = 0; //точка росы
volatile boolean wdt_tripped = 1;
RF24 radio(9, 10);
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
#include <dht22.h>
dht22 DHT22;
//создаём структуру для передачи 4х значений
typedef struct {
int W;
int X;
int Y;
int Z;
}
B_t;
B_t duino2;
//режим сна для МК
void system_sleep() {
delay(2); // Wait for serial traffic
_SFR_BYTE(ADCSRA) &= ~_BV(ADEN); // Switch ADC off
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_mode(); // System sleeps here
sleep_disable();
_SFR_BYTE(ADCSRA) |= _BV(ADEN); // Switch ADC on
}
void wdt_interrupt_mode() {
wdt_reset();
WDTCSR |= _BV(WDIE); // Restore WDT interrupt mode
}
ISR(WDT_vect) {
wdt_tripped = 1; // set global volatile variable
}
void setup()
{
pinMode(5, OUTPUT); //Пин на который подключено питание DHT22
digitalWrite(5, HIGH);
DHT22.attach(2); //Инициализируем датчик DHT
Serial.begin(9600);
wdt_disable();
wdt_reset();
wdt_enable(WDTO_8S); //пробуждение каждые 8 сек
count = 0;
radio.begin();
radio.setRetries(15, 15); // Кол-во попыток и время между попытками
radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1, pipes[1]);
}
void loop(void)
{
//тут можно увеличить интервал времени между отправками данных по RF24 за счёт счётчика циклов
Serial.println("Wakeup duino");
wdt_interrupt_mode();
if (wdt_tripped) {
count++;
wdt_tripped = 0;
Serial.print("Run mine module #");
Serial.println(count);
if (count == 9) { // каждые 8 сек * 9 циклов = 72 секунды делаем измерения и отправляем на базу:
Serial.println("Reding sensor DHT");
int chk = DHT22.read();
h = int(floor(DHT22.humidity + 0.5)); //Влажность
t = int(floor(DHT22.temperature + 0.5)); //Температура
dp = int(floor(DHT22.dewPoint() + 0.5)); //Точка росы
//записываем в структуру данные для передачи
if (isnan(t) || isnan(h)) {
duino2.W = 1; // этот номер передатчика для идентификации в принятом пакете данных
duino2.X = 0;
duino2.Y = 0;
duino2.Z = 0;
}
else {
duino2.W = 1; // этот номер передатчика для идентификации в принятом пакете данных
duino2.X = t; // передаём температуру
duino2.Y = h; // передаем влажность
duino2.Z = dp; // передаем точку росы
}
Serial.print("Controller = ");
Serial.println(duino2.W);
Serial.print("Battery voltage= ");
Serial.println(duino2.X);
Serial.print("Temperature = ");
Serial.println(duino2.Y);
Serial.print("Humidity = ");
Serial.println(duino2.Z);
radio.powerUp(); //подаём питание на NRF24
radio.stopListening(); // отключаем режим приёма
Serial.println("Start send");
bool ok = radio.write( &duino2, sizeof(duino2) ); //отправляем данные по RF24
Serial.println("End send");
delay(20);
count = 0;
radio.powerDown(); //отключаем питание RF24 штатно
}
}
system_sleep(); //МК засыпает
}
Приведу еще пример, как неправильно показывает значения:
Controller = 1572865
T= 524324
H = 0
DP = 0
А должно быть к примеру:
Controller = 1
T= 24
H = 36
DP = 8
В том что Mini PRO имеет 8-ми битное ядро, а DUE 32-битное.
http://arduino.cc/en/Reference/Int
И ваши переданные 4 инта по 16 бит с атмеги поместились в 2 инта по 32 бита на саме.
То есть
intW;(16)иintX;(16)сидят вintW;(32), аintY;(16)иintZ;(16)вintX;(32).Попробуйте на дуе сделать так:
typedef struct { int16_t W; int16_t X; int16_t Y; int16_t Z; }если не прокатит, можно так:
done = radio.read( &duino2, sizeof(duino2) ); duino2.Y = duino2.X&0xFFFF; duino2.Z = duino2.X>>16; duino2.X = duino2.W>>16; duino2.W = duino2.W&0xFFFF; Serial.print("Controller = ");Спасибо огромное!! получилось сразу!
typedef struct { int16_t W; int16_t X; int16_t Y; int16_t Z; }Может кому интересно будет, тут http://hackaday.com/2013/09/21/sending-data-over-bluetooth-low-energy-with-a-cheap-nrf24l01-module/ , http://dmitry.gr/index.php?r=05.Projects&proj=15&proj=11.%20Bluetooth%20LE%20fakery про отправку с nrf24l01 на bluetooth и в обратном порядке
Если не секрет к каким пинам на дуе подключали nRF24?
Перепробовал уже и так и сяк в результате коменды radio.printDetails(); получаю следующее
Пробовал так:
Но тоже столкнулся с проблемой - модуль не отправляет данные, а только может прнять...
А пример кода можеш скинуть?
Код есть в примерах самой библиотеки RF24.
Использовал "Getting Started". Также где-то находил модифицированный код:
#include <SPI.h> #include "nRF24L01.h" #include "RF24.h" // // Hardware configuration // // Set up nRF24L01 radio on SPI bus plus pins 9 & 10 RF24 radio(9,10); // // Topology // // Radio pipe addresses for the 2 nodes to communicate. const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; // // Role management // // Set up role. This sketch uses the same software for all the nodes // in this system. Doing so greatly simplifies testing. // // The various roles supported by this sketch typedef enum { role_ping_out = 1, role_pong_back } role_e; // The debug-friendly names of those roles const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"}; // The role of the current running sketch role_e role = role_pong_back; void setup(void) { // // Print preamble // Serial.begin(9600); while(!Serial.available()){ Serial.println("Enter any key then ENTER to begin."); delay(1000); } Serial.println("\n\rRF24/examples/GettingStarted/\n\r"); Serial.println("ROLE: "); Serial.println(role_friendly_name[role]); Serial.println("*** PRESS 'T' then ENTER to begin transmitting to the other node. ***\n\r"); // // Setup and configure rf radio // radio.begin(); // optionally, increase the delay between retries & # of retries radio.setRetries(15,15); // optionally, reduce the payload size. seems to // improve reliability //radio.setPayloadSize(8); // // Open pipes to other nodes for communication // // This simple sketch opens two pipes for these two nodes to communicate // back and forth. // Open 'our' pipe for writing // Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading) //if ( role == role_ping_out ) { //radio.openWritingPipe(pipes[0]); radio.openReadingPipe(1,pipes[1]); } //else { //radio.openWritingPipe(pipes[1]); //radio.openReadingPipe(1,pipes[0]); } // // Start listening // radio.startListening(); // // Dump the configuration of the rf unit for debugging // radio.printDetails(); } void loop(void) { // // Ping out role. Repeatedly send the current time // if (role == role_ping_out) { // First, stop listening so we can talk. radio.stopListening(); // Take the time, and send it. This will block until complete unsigned long time = millis(); Serial.print("\n\rNow sending: "); Serial.println(time); bool ok = radio.write( &time, sizeof(unsigned long) ); if (ok) Serial.print("ok..."); else Serial.print("failed..."); // Now, continue listening radio.startListening(); // Wait here until we get a response, or timeout (250ms) unsigned long started_waiting_at = millis(); bool timeout = false; while ( ! radio.available() && ! timeout ) if (millis() - started_waiting_at > 200 ) timeout = true; // Describe the results if ( timeout ) { Serial.println("\n\rFailed, response timed out."); } else { // Grab the response, compare, and send to debugging spew unsigned long got_time; radio.read( &got_time, sizeof(unsigned long) ); // Spew it Serial.print("\n\rGot response: "); Serial.println(got_time); Serial.print("round-trip delay: "); Serial.println(millis()-got_time); } // Try again 1s later delay(1000); } // // Pong back role. Receive each packet, dump it out, and send it back // if ( role == role_pong_back ) { // if there is data ready if ( radio.available() ) { // Dump the payloads until we've gotten everything unsigned long got_time; bool done = false; while (!done) { // Fetch the payload, and see if this was the last one. done = radio.read( &got_time, sizeof(unsigned long) ); // Spew it Serial.print("Got payload: "); Serial.println(got_time); // Delay just a little bit to let the other unit // make the transition to receiver delay(20); } // First, stop listening so we can talk radio.stopListening(); // Send the final one back. radio.write( &got_time, sizeof(unsigned long) ); Serial.println("Sent response."); // Now, resume listening so we catch the next packets. radio.startListening(); } } // // Change roles // if ( Serial.available() ) { char c = toupper(Serial.read()); if ( c == 'T' && role == role_pong_back ) { Serial.println("*** CHANGING TO TRANSMIT ROLE ***"); Serial.println("Press 'R' then ENTER to switch back to Receive Role."); // Become the primary transmitter (ping out) role = role_ping_out; radio.openWritingPipe(pipes[0]); radio.openReadingPipe(1,pipes[1]); } else if ( c == 'R' && role == role_ping_out ) { Serial.println("*** CHANGING TO RECEIVE ROLE ***"); Serial.println("Press 'T' then ENTER to switch back to TRANSMIT ROLE"); // Become the primary receiver (pong back) role = role_pong_back; radio.openWritingPipe(pipes[1]); radio.openReadingPipe(1,pipes[0]); } } } // vim:cin:ai:sts=2 sw=2 ft=cppЗдравствуйте dardik. Подскажите пожалуйста, что надо изменить в вашем коде чтобы температура и заряд батарей отображались в таком виде "26,1" и "3,7".Заранее спасибо за ответ.
Здравствуйте. Подскажите неграмотному, к каким пинам Arduino DUE подключить nRF24L01. Есть UNO - передает данные, и есть DUE - должна принимать. Пробовал и как к Меге 2560 и к SPI, результата никакого. Библиотека RF24
Соединять прямо к выводам SPI расположенным в центре платы
Здравствуйте. Если возможно обновите ссылку на библиотеку DHT22. Спасибо