{{ Nordic_nRF24L01_DemoMaster110718a This demo uses two nRF24L01+ modules to communicate. It can also have two nRF2401A modules communicate with eachother. I can't get a nRF24L01+ to communicate with a nRF2401A. Change the value of "_CurrentConfig" (last constant) to change which type of modules this object will use. This code is mainly base on C code posted by Leon in the Propeller Forum. ---- Revision Notes ------- 110404a change to use older Nordic as aux. 4a didn't work. 7a move code from Nordic object to this top object to make file matainence easier. 7d fix problem with reading packet. 7d works. 8a change transmitString method (and others) to point to string. 8b change packet length to 32 bytes. 8b works. c make payload size a variable. c works. d try enhanced ShockBurst. 9a take out timing delays, they aren't needed. 9b use SPI_Asm. b doesn't work. c doesn't work. d works using old SPI method. e read SPI with new method. e works. f use Asm to write SPI commands as well. f works. g remove delay in PASM code of SPI object. g works. h move Nordic methods to separate object. i works. j try to make rx and tx changeable. j doesn't work. Abandon j. 10a try smaller changes. a switch rx and tx mode values. a works. b works. c works. d works. e uses two way com and works. f added minimum needed to reset rx to transmitString method. 11d works. 12d doesn't really work. 13a didn't work either. It would alternate between all "!!!!!..." and "gggg...". 13b moved parameters to DAT section of this object. b works (using same parameters as previous versions). c try changing some parameters. Enhanced ShockBurst seems to work but I'm not sure yet. I need to read retransmitted packets. 14b try to communicate with older Nordic module. b, c and d don't work. e use a case statement to start new or old Nordic modules. e doesn't work with two new modules. h works. i use 25 byte packet and other setting to use with older modules. i works. j try to use two old modules. Device 0 receives okay but device 1 isn't receiving. l works with two old modules. m with one old and one new. m doesn't work. n get ready to archive an post to forum. Make messages more helpful. 15a test a couple more adress combinations and clean up child object. 15a and 16a don't work. Did I change too many things when I cleaned up the program? b works. The problem was in a change I made to the SPI driver. c try some different address combinations. c this combination lets device 0 receive but not device 1. d try other combinations. d leave it in combination that does work. e try two old modules. e using the same address for both modules works. I didn't think it would. f try one new and one old. f doesn't work with one new module and one old module. Time to ask for help. Modify NordicPlusPlusDemo110416f to use only one nRF24L01 module and change name to Nordic_nRF24L01_Demo110505a. Change name again to Nordic_nRF24L01_DemoMaster110505a (there will also be a slave version). This change is based on a suggestion by Bill Henning. The master device send two numbers in ASCII hexidecimal. The slave device reads the two numbers adds them and sends the original two numbers with their sum back to the master device. 110629a add SpiCheck method to see if Propeller is communicating with the Nordic module. 110718a a couple of bug fixes. 19a Reduce payload size to 20. }} '' Some of this code is based on C code by Leon Heller CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 CON { 'Pins to SparkFun Nordic nRF24L01+ 'Mecanum controller board _SpiIrq = 16 _SpiMiso = 17 _SpiMosi = 18 _SpiSck = 19 _SpiCsn = 20 _SpiCe = 21 } 'Pins to Hong Kong Nordic nRF24L01+ (QuickStart board) _SpiIrq = 5 _SpiMiso = 4 _SpiMosi = 3 _SpiSck = 2 _SpiCsn = 1 _SpiCe = 0 { 'Pins to SparkFun Nordic nRF24L01+ (QuickStart board) _SpiIrq = 0 _SpiMiso = 1 _SpiMosi = 2 _SpiSck = 3 _SpiCsn = 4 _SpiCe = 5 } _RxLed = 23 ' far left LED on QuickStart board _TxLed = 16 ' far right LED on QuickStart board _DebugBaud = 57600 _LargestPayloadSize = 1 _DefaultPayloadSize = _LargestPayloadSize _AddressSizeOffset = 3 _StatusOffset = 7 _PayloadOffset = 8 _RxAddressOffset = 9 VAR byte payloadSize byte globalPayload[_LargestPayloadSize + 1] ' Add 1 so a terminating zero may be added if desired. byte bytesToAdd[2] OBJ Debug : "FullDuplexSerialPlus" Nordic : "NordicBeta110718a" 'Nordic nRF24L01 PUB Demo | localIndex 'Debug.start(31, 30, 0, _DebugBaud) waitcnt(clkfreq * 2 + cnt) {repeat while debug.rxcheck == -1 if result // 40 == 0 Debug.str(String(13, "Press any key to start.")) waitcnt(clkfreq / 10 + cnt) result++ } 'Debug.str(String("Start of Nordic Demo (Master)", 13)) dira[6]~~ dira[_TxLed]~~ outa[6]~~ 'Initialize Nordic nRF24L01 Nordic.Start(_SpiSck, _SpiMiso, _SpiMosi, _SpiCsn, _SpiCe, @configNew) payloadSize := byte[@configNew + _PayloadOffset] ' change whenever Nordic is configured. 'outa[6]~ SpiCheck outa[6]~ Nordic.Configure(@configNew) 'Debug.str(String("rx address =")) 'repeat localIndex from 0 to 4 'Debug.str(String(" $")) 'Debug.hex(byte[@rxAddress + localIndex], 2) 'Debug.str(String(13, "tx address =")) 'repeat localIndex from 0 to 4 'Debug.str(String(" $")) 'Debug.hex(byte[@txAddress + localIndex], 2) dira[_SpiIrq]~ 'Debug.str(String(13, "Transceiver configured.", 13)) repeat outa[6]~~ 'PreparePacket 'Nordic.TransmitString(@packetTemplate) Nordic.TransmitString("1") 'Debug.str(String(13, "Sent to slave: ")) 'SafeBug(@packetTemplate, payloadSize) waitcnt(2_000_000 + cnt) outa[6]~ waitcnt(40_000_000 + cnt) ' give slave device chance to receive and transmit if ina[_SpiIrq] == 0 'Wait for incoming data 'We have some data 'outa[_RxLed]~~ 'Debug.str(String(13, 13, "Status = %")) 'localIndex := Nordic.Status 'Debug.bin(localIndex, 8) Nordic.ReadPayload(@globalPayload) 'Debug.str(String(13, "Received from slave: ")) 'SafeBug(@globalPayload, payloadSize) 'Debug.tx(13) 'outa[6]~ 'waitcnt(clkfreq / 2 + cnt) ' slow the loop a littl more so we can read ' the output on the serial terminal easier. PUB PreparePacket | localIndex PUB hex(value, digits, localPtr) PUB FromAsciiHex(digits, localPtr) | localCharacter '' not ripped hence suboptimal repeat digits localCharacter := byte[localPtr++] if localCharacter => "0" and localCharacter =< "9" localCharacter -= "0" elseif localCharacter => "A" and localCharacter =< "F" localCharacter -= "A" localCharacter += $0A else localCharacter := 0 result <<= 4 result += localCharacter PUB SpiCheck | localIndex 'Debug.str(String(13, "Attempting to read rx address from module.")) Nordic.SpiReadPub(Nordic#RX_ADDR_P0, @globalPayload, 5) 'Debug.str(String(13, "rx address = $")) 'repeat localIndex from 0 to 4 'Debug.hex(globalPayload[localIndex], 2) if CompareArrays(@globalPayload, @testAddress, 5) == -1 'Debug.str(String(13, "The present rx address is the same as the test address.")) 'Debug.str(String(13, "Changing the test address from $")) 'repeat localIndex from 0 to 4 'Debug.hex(testAddress[localIndex], 2) 'Debug.str(String(", to $")) 'repeat localIndex from 0 to 4 'testAddress[localIndex] += $11 'Debug.hex(testAddress[localIndex], 2) 'Debug.str(String(13, "Attempting to write following rx address to module: $")) 'repeat localIndex from 0 to 4 'Debug.hex(testAddress[localIndex], 2) Nordic.SpiWritePub(Nordic#RX_ADDR_P0, @testAddress, 5) 'Debug.str(String(13, "Reading rx address from module: $")) Nordic.SpiReadPub(Nordic#RX_ADDR_P0, @globalPayload, 5) 'repeat localIndex from 0 to 4 'Debug.hex(globalPayload[localIndex], 2) 'if CompareArrays(@globalPayload, @testAddress, 5) == -1 'Debug.str(String(13, 13, "!!!!Success!!!!")) 'Debug.str(String(13, 13, "The rx address was successfully changed.")) 'Debug.str(String(13, "The test rx address will not necessarily be the rx address used")) 'Debug.str(String(13, "in communicating with other modules.", 13)) 'else 'Debug.str(String(13, 13, "** Failure **")) 'Debug.str(String(13, 13, "The rx address was NOT changed.")) 'Debug.str(String(13, "The Propeller was not able to communicate with the")) 'Debug.str(String(13, "Nordic module.", 13)) PRI CompareArrays(localPtr0, localPtr1, localSize) result := -1 repeat localSize if byte[localPtr0++] <> byte[localPtr1++] result := 0 PUB SafeBug(localPtr, localSize) PRI TbugTx(localCharacter) DAT '1 2 3 '01234567890123456789012345678901 packetTemplate byte "Please add $00 + $00", 0 testAddress byte $AA, $BB, $CC, $DD, $EE ''------------------ Cofig settings for new nRF24L01+ modules ---------------------------------------- '' ----------------- Keep below together and in order ------------------------------------------------ configNew byte %00111111 '%00111011 Register $00 ' use %00111111($3F)(2 bytes CRC) or %00111011($3B)(1 byte CRC) ' when communicating with older nRF2401A modules ' make sure this matches nRF2401A setting ' %00001111($0F) future with more irq options ' 7 only zero allowed, 6 Mask irq by RX_DR (1 = no irq), 5 Mask TX_DS, 4 Mask MAX_RT, ' 3 Enable CRC, 2 CRC size (1 = 2 bytes), 1 1 = power up, 0 1 = PRX 0 = PTX ' RX_DR Receive Data Ready ' TX_DS Transmit Data Sent ' MAX_RT Maximum Retries byte $00 '$03 ' Register $01 Auto Acknowledge ' use $00 when communicating with older nRF2401A modules ' %00111111 future ' 7:6 only %00, enable pipe 5 through 0 byte %00000011 ' Register $02 ' 7:6 only zero allowed, 5:0 enable rx addresses pipe 5:0 byte $03 ' Register $03 SETUP_AW setup Address Widths ' 7:2 only %000000, 1:0 %01 = 3 %11 = 5 byte $00 ' Register $04 SETUP_RETR Setup Auto Retransmission ' use $00 when communicating with older nRF2401A modules ' %00101111 = 750us delay to retx, tx 15 tries ' %01001111 = 1250us delay to retx, tx 15 tries ' 7:4 ARD delay 1111 = 4000us, 3:0 retry count 0 - 15 (1111) byte $02 ' Register $05 RF_CH RF Channel ' 7 leave 0, 6:0 frequency channel ' F = (2400 + RF_CH)MHz (both nRF24L01+ and nRF2401A modules) byte $06 ' Register $06 RF_SETUP RF Setup ' don't use 2Mbps when communicating with older nRF2401A modules ' $06 = 1Mbps and full power ' 7:6 %00 only, 5 RF_DR_LOW 1 = 250kbps use 0 for higher speeds, 4 leave %0 ' 3 1 = 2Mbps 0 = 1Mbps, 2:1 RF_POWER %11 = 0dBm (highest power), 0 don't care ' Register $07 STATUS Status Register used below. ' Register $08 OBSERVE_TX 7:4 lost packet count (read only), ' 3:0 retransmitted packets count (read only). I plan to use this ' register's infomation in the future. ' Register $09 RPD 7:1 reserved (read only), 0 Received Power Detector (read only) ' Register $0A RX_ADDR_P0 39:0 Receive address pipe 0, 5 bytes maximum LSByte written first ' used below rxAddress0 and rxAddress1 ' Register $0B RX_ADDR_P1 39:0 Receive address pipe 1 ' Register $0C RX_ADDR_P2 7:0 Receive address pipe 2 ' Register $0D RX_ADDR_P3 7:0 Receive address pipe 3 ' Register $0E RX_ADDR_P4 7:0 Receive address pipe 4 ' Register $0F RX_ADDR_P5 7:0 Receive address pipe 5 ' Register $10 TX_ADDR 39:0 Transmit address 'configNew[7] nordicStatus byte %01000000 ' $40 %01110000 '$70 ' only zero allowed, Data Ready RX, TX ACK received, MAX_RT failed, ' 3:1 Data pipe with payload %111 if empty (read only), 0 1= TX FIFO full (read only) rxPayload byte 20 '25 '32 ' Register $11 RX_PW_P0 ' This will need to be reduced to 25 (assuming 2 bytes CRC and 5 bytes address) ' to work with older nRF2401 modules. ' Newer nRF24L01+ modules can have payloads as large as 32 bytes. ' 7:6 only zero allowed, 5:0 Number of bytes in RX payload in data pipe 0 ' (1 to 32)(0 = pipe not used) ' Register $12 RX_PW_P1 7:6 only zero allowed, ' 5:0 Number of bytes in RX payload in data pipe 1 ' (1 to 32)(0 = pipe not used) ' Register $13 RX_PW_P2 7:6 only zero allowed, ' 5:0 Number of bytes in RX payload in data pipe 2 ' Register $14 RX_PW_P3 7:6 only zero allowed, ' 5:0 Number of bytes in RX payload in data pipe 3 ' Register $15 RX_PW_P4 7:6 only zero allowed, ' 5:0 Number of bytes in RX payload in data pipe 4 ' Register $16 RX_PW_P5 7:6 only zero allowed, ' 5:0 Number of bytes in RX payload in data pipe 5 ' Register $17 FIFO_STATUS 7 only zero allowed, 6 TX_REUSE (read only), ' 5 TX_FULL %1 = full (read only), 4 TX_EMPTY %1 = empty (read only), ' 3:2 only zero allowed, 1 RX_FULL %1 = full (read only), ' 0 RX_EMPTY %1 = empty (read only) ' Register $1C DYNPD Enable dynamic payload length, 7:6 only zero allowed, ' 5 DPL_P5 Enable dynamic payload length data pipe 5 (Requires EN_DPL and ENAA_5) ' 4 DPL_P4 Enable dynamic payload length data pipe 4 (Requires EN_DPL and ENAA_4) ' 3 DPL_P3 Enable dynamic payload length data pipe 3 (Requires EN_DPL and ENAA_3) ' 2 DPL_P2 Enable dynamic payload length data pipe 2 (Requires EN_DPL and ENAA_2) ' 1 DPL_P1 Enable dynamic payload length data pipe 1 (Requires EN_DPL and ENAA_1) ' 0 DPL_P0 Enable dynamic payload length data pipe 0 (Requires EN_DPL and ENAA_0) ' Register $1D FEATURE Feature Register 7:3 only zero allowed, ' 2 EN_DPL Enables Dynamic Payload Length, 1 EN_ACK_PAY Enables Payload with ACK, ' 0 EN_DYN_ACK Enables the W_TX_PAYLOAD_NOACK command rxAddress byte $E7[5] ' Register $0A Receive address data pipe 0, LSByte first txAddress byte $E7[5] ' Register $10 Transmit address data pipe 0, LSByte first '' ----------------- Keep above together and in order ------------------------------------------------