From aab3a529f898ec40e3d62510cd535d5e2d8a5ac4 Mon Sep 17 00:00:00 2001 From: fab672000 Date: Sun, 27 Sep 2015 15:02:14 -0500 Subject: [PATCH] restored back multicast pingpair example from previous maniacbug fork --- examples/pingpair_multi_dyn/Jamfile | 206 ++++++++++++++ .../pingpair_multi_dyn/pingpair_multi_dyn.ino | 263 ++++++++++++++++++ 2 files changed, 469 insertions(+) create mode 100755 examples/pingpair_multi_dyn/Jamfile create mode 100644 examples/pingpair_multi_dyn/pingpair_multi_dyn.ino diff --git a/examples/pingpair_multi_dyn/Jamfile b/examples/pingpair_multi_dyn/Jamfile new file mode 100755 index 000000000..901f8da8c --- /dev/null +++ b/examples/pingpair_multi_dyn/Jamfile @@ -0,0 +1,206 @@ +PROJECT_NAME = $(PWD:B) ; +PROJECT_DIR = . ; +PROJECT_LIBS = SPI RF24 ; + +OUT_DIR = ojam ; +F_CPU = 16000000 ; +MCU = atmega328p ; +PORTS = /dev/tty.usbserial-A600eHIs /dev/tty.usbserial-A40081RP /dev/tty.usbserial-A9007LmI ; + +UPLOAD_RATE = 57600 ; +AVRDUDE_PROTOCOL = stk500v1 ; +COM = 33 ; + +# Host-specific overrides for locations +if $(OS) = MACOSX +{ +ARDUINO_VERSION = 22 ; +OLD_DIR = /opt/arduino-0021 ; +AVR_TOOLS_PATH = $(OLD_DIR)/hardware/tools/avr/bin ; +AVRDUDECONFIG_PATH = $(OLD_DIR)/hardware/tools/avr/etc ; +ARDUINO_DIR = /opt/Arduino ; +ARDUINO_AVR = /usr/lib/avr/include ; +} + +# Where is everything? +ARDUINO_VERSION ?= 22 ; +AVR_TOOLS_PATH ?= /usr/bin ; +ARDUINO_DIR ?= /opt/arduino-00$(ARDUINO_VERSION) ; +ARDUINO_AVR ?= $(ARDUINO_DIR)/hardware/tools/avr/avr/include/avr ; +AVRDUDECONFIG_PATH ?= $(ARDUINO_DIR)/hardware/tools ; +ARDUINO_CORE = $(ARDUINO_DIR)/hardware/arduino/cores/arduino ; +ARDUINO_LIB = $(ARDUINO_DIR)/libraries ; +SKETCH_LIB = $(HOME)/Source/Arduino/libraries ; +AVR_CC = $(AVR_TOOLS_PATH)/avr-gcc ; +AVR_CXX = $(AVR_TOOLS_PATH)/avr-g++ ; +AVR_LD = $(AVR_TOOLS_PATH)/avr-gcc ; +AVR_OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy ; +AVRDUDE = $(AVR_TOOLS_PATH)/avrdude ; + +DEFINES = F_CPU=$(F_CPU)L ARDUINO=$(ARDUINO_VERSION) VERSION_H ; +CTUNING = -ffunction-sections -fdata-sections ; +CXXTUNING = -fno-exceptions -fno-strict-aliasing ; +CFLAGS = -Os -Wall -Wextra -mmcu=$(MCU) $(CTUNING) ; +CXXFLAGS = $(CFLAGS) $(CXXTUNING) ; +LDFLAGS = -Os -lm -Wl,--gc-sections -mmcu=atmega328p ; + +# Search everywhere for headers +HDRS = $(PROJECT_DIR) $(ARDUINO_AVR) $(ARDUINO_CORE) [ GLOB $(ARDUINO_LIB) $(SKETCH_LIB) : [^.]* ] ; + +# Grab everything from the core directory +CORE_MODULES = [ GLOB $(ARDUINO_CORE) : *.c *.cpp ] ; + +# Grab everything from libraries. To avoid this "grab everything" behaviour, you +# can specify specific modules to pick up in PROJECT_MODULES +LIB_MODULES = [ GLOB $(ARDUINO_LIB)/$(PROJECT_LIBS) $(SKETCH_LIB)/$(PROJECT_LIBS) : *.cpp ] ; + +# In addition to explicitly-specified program modules, pick up anything from the current +# dir. +PROJECT_MODULES += [ GLOB $(PROJECT_DIR) : *.c *.cpp *.pde ] ; + +# Shortcut for the out files +OUT = $(OUT_DIR)/$(PROJECT_NAME) ; + +# AvrDude setup +AVRDUDE_FLAGS = -V -F -D -C $(AVRDUDECONFIG_PATH)/avrdude.conf -p $(MCU) -c $(AVRDUDE_PROTOCOL) -b $(UPLOAD_RATE) ; + +rule GitVersion +{ + Always $(<) ; + Depends all : $(<) ; +} + +actions GitVersion +{ + echo "const char program_version[] = \"\\" > $(<) + git log -1 --pretty=format:%h >> $(<) + echo "\";" >> $(<) +} + +GitVersion version.h ; + +rule AvrCc +{ + Depends $(<) : $(>) ; + Depends $(<) : $(<:D) ; + Clean clean : $(<) ; + + CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; + CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ; +} + +actions AvrCc +{ + $(AVR_CC) -c -o $(<) $(CCHDRS) $(CCDEFS) $(CFLAGS) $(>) +} + +rule AvrC++ +{ + Depends $(<) : $(>) ; + Depends $(<) : $(<:D) ; + Clean clean : $(<) ; + + CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ; + CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ; +} + +actions AvrC++ +{ + $(AVR_CXX) -c -o $(<) $(CCHDRS) $(CCDEFS) $(CXXFLAGS) $(>) +} + +rule Pde +{ + Depends $(<) : $(>) ; + Depends $(<) : $(<:D) ; + Clean clean : $(<) ; + +} + +actions Pde +{ + echo "#include " > $(<) + echo "#line 1 \"$(>)\"" >> $(<) + cat $(>) >> $(<) +} + +rule AvrPde +{ + local _CPP = $(OUT_DIR)/$(_I:B).cpp ; + Pde $(_CPP) : $(>) ; + AvrC++ $(<) : $(_CPP) ; +} + +rule AvrObject +{ + switch $(>:S) + { + case .c : AvrCc $(<) : $(>) ; + case .cpp : AvrC++ $(<) : $(>) ; + case .pde : AvrPde $(<) : $(>) ; + } +} + +rule AvrObjects +{ + for _I in $(<) + { + AvrObject $(OUT_DIR)/$(_I:B).o : $(_I) ; + } +} + +rule AvrMainFromObjects +{ + Depends $(<) : $(>) ; + Depends $(<) : $(<:D) ; + MkDir $(<:D) ; + Depends all : $(<) ; + Clean clean : $(<) ; +} + +actions AvrMainFromObjects +{ + $(AVR_LD) $(LDFLAGS) -o $(<) $(>) +} + +rule AvrMain +{ + AvrMainFromObjects $(<) : $(OUT_DIR)/$(>:B).o ; + AvrObjects $(>) ; +} + +rule AvrHex +{ + Depends $(<) : $(>) ; + Depends $(<) : $(<:D) ; + Depends hex : $(<) ; + Clean clean : $(<) ; +} + +actions AvrHex +{ + $(AVR_OBJCOPY) -O ihex -R .eeprom $(>) $(<) +} + +rule AvrUpload +{ + Depends $(1) : $(2) ; + Depends $(2) : $(3) ; + NotFile $(1) ; + Always $(1) ; + Always $(2) ; + AvrUploadAction $(2) : $(3) ; +} + +actions AvrUploadAction +{ + $(AVRDUDE) $(AVRDUDE_FLAGS) -P $(<) $(AVRDUDE_WRITE_FLASH) -U flash:w:$(>):i +} + +AvrMain $(OUT).elf : $(CORE_MODULES) $(LIB_MODULES) $(PROJECT_MODULES) ; +AvrHex $(OUT).hex : $(OUT).elf ; + +AvrUpload p6 : /dev/tty.usbserial-A600eHIs : $(OUT).hex ; +AvrUpload p4 : /dev/tty.usbserial-A40081RP : $(OUT).hex ; +AvrUpload p9 : /dev/tty.usbserial-A9007LmI : $(OUT).hex ; + diff --git a/examples/pingpair_multi_dyn/pingpair_multi_dyn.ino b/examples/pingpair_multi_dyn/pingpair_multi_dyn.ino new file mode 100644 index 000000000..03ef24c17 --- /dev/null +++ b/examples/pingpair_multi_dyn/pingpair_multi_dyn.ino @@ -0,0 +1,263 @@ +/* + Copyright (C) 2011 James Coliz, Jr. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. + */ + +/** + * Example using Dynamic Payloads + * + * This is an example of how to use payloads of a varying (dynamic) size. + */ + +#include +#include "RF24.h" + +// +// Hardware configuration +// + +// Set up nRF24L01 radio on SPI bus plus pins 8 & 9 +RF24 radio(8,9); + +// Use multicast? +// sets the multicast behavior this unit in hardware. Connect to GND to use unicast +// Leave open (default) to use multicast. +const int multicast_pin = 6 ; + +// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver +// Leave open to be the 'ping' transmitter +const int role_pin = 7; +bool multicast = true ; + +// +// Topology +// + +// Radio pipe addresses for the 2 nodes to communicate. +const uint64_t pipes[2] = { 0xEEFAFDFDEELL, 0xEEFDFAF50DFLL }; + +// +// Role management +// +// Set up role. This sketch uses the same software for all the nodes +// in this system. Doing so greatly simplifies testing. The hardware itself specifies +// which node it is. +// +// This is done through the role_pin +// + +// 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; + +// +// Payload +// + +const int min_payload_size = 1; +const int max_payload_size = 32; +const int payload_size_increments_by = 1; +int next_payload_size = min_payload_size; + +char receive_payload[max_payload_size+1]; // +1 to allow room for a terminating NULL char + +void setup(void) +{ + // + // Multicast + // + pinMode(multicast_pin, INPUT); + digitalWrite(multicast_pin,HIGH); + delay( 20 ) ; + + // read multicast role, LOW for unicast + if( digitalRead( multicast_pin ) ) + multicast = true ; + else + multicast = false ; + + + // + // Role + // + + // set up the role pin + pinMode(role_pin, INPUT); + digitalWrite(role_pin,HIGH); + delay( 20 ); // Just to get a solid reading on the role pin + + // read the address pin, establish our role + if ( digitalRead(role_pin) ) + role = role_ping_out; + else + role = role_pong_back; + + // + // Print preamble + // + + Serial.begin(115200); + + Serial.println(F("RF24/examples/pingpair_multi_dyn/")); + Serial.print(F("ROLE: ")); + Serial.println(role_friendly_name[role]); + + Serial.print(F("MULTICAST: ")); + Serial.println(multicast ? F("true (unreliable)") : F("false (reliable)")); + + // + // Setup and configure rf radio + // + + radio.begin(); + + // enable dynamic payloads + radio.enableDynamicPayloads(); + radio.setCRCLength( RF24_CRC_16 ) ; + + // optionally, increase the delay between retries & # of retries + radio.setRetries( 15, 5 ) ; + radio.setAutoAck( true ) ; + //radio.setPALevel( RF24_PA_LOW ) ; + + // + // 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.powerUp() ; + 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) + { + // The payload will always be the same, what will change is how much of it we send. + static char send_payload[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ789012"; + + // First, stop listening so we can talk. + radio.stopListening(); + + // Take the time, and send it. This will block until complete + Serial.print(F("Now sending length ")); + Serial.println(next_payload_size); + radio.write( send_payload, next_payload_size, multicast ); + + // Now, continue listening + radio.startListening(); + + // Wait here until we get a response, or timeout + unsigned long started_waiting_at = millis(); + bool timeout = false; + while ( ! radio.available() && ! timeout ) + if (millis() - started_waiting_at > 500 ) + timeout = true; + + // Describe the results + if ( timeout ) + { + Serial.println(F("Failed, response timed out.")); + } + else + { + // Grab the response, compare, and send to debugging spew + uint8_t len = radio.getDynamicPayloadSize(); + radio.read( receive_payload, len ); + + // Put a zero at the end for easy printing + receive_payload[len] = 0; + + // Spew it + Serial.print(F("Got response size=")); + Serial.print(len); + Serial.print(F(" value=")); + Serial.println(receive_payload); + } + + // Update size for next time. + next_payload_size += payload_size_increments_by; + if ( next_payload_size > max_payload_size ) + next_payload_size = min_payload_size; + + // Try again 1s later + delay(250); + } + + // + // 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 + uint8_t len; + bool done = false; + while (radio.available()) + { + // Fetch the payload, and see if this was the last one. + len = radio.getDynamicPayloadSize(); + radio.read( receive_payload, len ); + + // Put a zero at the end for easy printing + receive_payload[len] = 0; + + // Spew it + Serial.print(F("Got response size=")); + Serial.print(len); + Serial.print(F(" value=")); + Serial.println(receive_payload); + } + + // First, stop listening so we can talk + radio.stopListening(); + + // Send the final one back. + radio.write( receive_payload, len, multicast ); + Serial.println(F("Sent response.")); + + // Now, resume listening so we catch the next packets. + radio.startListening(); + } + } +} +// vim:cin:ai:sts=2 sw=2 ft=cpp \ No newline at end of file