Ein Roboter mit bürstenlosem Antrieb, differenzial und NRF24L01 Funk. Großflächig gebaut um ein großes Solarpanel aufzunehmen. https://gitlab.informatik.hs-fulda.de/fdai5253/roboter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

189 lines
8.7 KiB

  1. /*
  2. TMRh20 2014
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. version 2 as published by the Free Software Foundation.
  6. */
  7. /** Reliably transmitting large volumes of data with a low signal or in noisy environments
  8. * This example demonstrates data transfer functionality with the use of auto-retry
  9. and auto-reUse functionality enabled. This sketch demonstrates how a user can extend
  10. the auto-retry functionality to any chosen time period, preventing data loss and ensuring
  11. the consistency of data.
  12. This sketh demonstrates use of the writeBlocking() functionality, and extends the standard
  13. retry functionality of the radio. Payloads will be auto-retried until successful or the
  14. extended timeout period is reached.
  15. */
  16. #include <SPI.h>
  17. #include "nRF24L01.h"
  18. #include "RF24.h"
  19. #include "printf.h"
  20. /************* USER Configuration *****************************/
  21. RF24 radio(7,8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
  22. unsigned long timeoutPeriod = 3000; // Set a user-defined timeout period. With auto-retransmit set to (15,15) retransmission will take up to 60ms and as little as 7.5ms with it set to (1,15).
  23. // With a timeout period of 1000, the radio will retry each payload for up to 1 second before giving up on the transmission and starting over
  24. /***************************************************************/
  25. const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; // Radio pipe addresses for the 2 nodes to communicate.
  26. byte data[32]; //Data buffer
  27. volatile unsigned long counter;
  28. unsigned long rxTimer,startTime, stopTime, payloads = 0;
  29. bool TX=1,RX=0,role=0, transferInProgress = 0;
  30. void setup(void) {
  31. Serial.begin(115200);
  32. printf_begin();
  33. radio.begin(); // Setup and configure rf radio
  34. radio.setChannel(1); // Set the channel
  35. radio.setPALevel(RF24_PA_LOW); // Set PA LOW for this demonstration. We want the radio to be as lossy as possible for this example.
  36. radio.setDataRate(RF24_1MBPS); // Raise the data rate to reduce transmission distance and increase lossiness
  37. radio.setAutoAck(1); // Ensure autoACK is enabled
  38. radio.setRetries(2,15); // Optionally, increase the delay between retries. Want the number of auto-retries as high as possible (15)
  39. radio.setCRCLength(RF24_CRC_16); // Set CRC length to 16-bit to ensure quality of data
  40. radio.openWritingPipe(pipes[0]); // Open the default reading and writing pipe
  41. radio.openReadingPipe(1,pipes[1]);
  42. radio.startListening(); // Start listening
  43. radio.printDetails(); // Dump the configuration of the rf unit for debugging
  44. printf("\n\rRF24/examples/Transfer Rates/\n\r");
  45. printf("*** PRESS 'T' to begin transmitting to the other node\n\r");
  46. randomSeed(analogRead(0)); //Seed for random number generation
  47. for(int i=0; i<32; i++){
  48. data[i] = random(255); //Load the buffer with random data
  49. }
  50. radio.powerUp(); //Power up the radio
  51. }
  52. void loop(void){
  53. if(role == TX){
  54. delay(2000); // Pause for a couple seconds between transfers
  55. printf("Initiating Extended Timeout Data Transfer\n\r");
  56. unsigned long cycles = 1000; // Change this to a higher or lower number. This is the number of payloads that will be sent.
  57. unsigned long transferCMD[] = {'H','S',cycles }; // Indicate to the other radio that we are starting, and provide the number of payloads that will be sent
  58. radio.writeFast(&transferCMD,12); // Send the transfer command
  59. if(radio.txStandBy(timeoutPeriod)){ // If transfer initiation was successful, do the following
  60. startTime = millis(); // For calculating transfer rate
  61. boolean timedOut = 0; // Boolean for keeping track of failures
  62. for(int i=0; i<cycles; i++){ // Loop through a number of cycles
  63. data[0] = i; // Change the first byte of the payload for identification
  64. if(!radio.writeBlocking(&data,32,timeoutPeriod)){ // If retries are failing and the user defined timeout is exceeded
  65. timedOut = 1; // Indicate failure
  66. counter = cycles; // Set the fail count to maximum
  67. break; // Break out of the for loop
  68. }
  69. }
  70. stopTime = millis(); // Capture the time of completion or failure
  71. //This should be called to wait for completion and put the radio in standby mode after transmission, returns 0 if data still in FIFO (timed out), 1 if success
  72. if(timedOut){ radio.txStandBy(); } //Partially blocking standby, blocks until success or max retries. FIFO flushed if auto timeout reached
  73. else{ radio.txStandBy(timeoutPeriod); } //Standby, block until FIFO empty (sent) or user specified timeout reached. FIFO flushed if user timeout reached.
  74. }else{
  75. Serial.println("Communication not established"); //If unsuccessful initiating transfer, exit and retry later
  76. }
  77. float rate = cycles * 32 / (stopTime - startTime); //Display results:
  78. Serial.print("Transfer complete at "); Serial.print(rate); printf(" KB/s \n\r");
  79. Serial.print(counter);
  80. Serial.print(" of ");
  81. Serial.print(cycles); Serial.println(" Packets Failed to Send");
  82. counter = 0;
  83. }
  84. if(role == RX){
  85. if(!transferInProgress){ // If a bulk data transfer has not been started
  86. if(radio.available()){
  87. radio.read(&data,32); //Read any available payloads for analysis
  88. if(data[0] == 'H' && data[4] == 'S'){ // If a bulk data transfer command has been received
  89. payloads = data[8]; // Read the first two bytes of the unsigned long. Need to read the 3rd and 4th if sending more than 65535 payloads
  90. payloads |= data[9] << 8; // This is the number of payloads that will be sent
  91. counter = 0; // Reset the payload counter to 0
  92. transferInProgress = 1; // Indicate it has started
  93. startTime = rxTimer = millis(); // Capture the start time to measure transfer rate and calculate timeouts
  94. }
  95. }
  96. }else{
  97. if(radio.available()){ // If in bulk transfer mode, and a payload is available
  98. radio.read(&data,32); // Read the payload
  99. rxTimer = millis(); // Reset the timeout timer
  100. counter++; // Keep a count of received payloads
  101. }else
  102. if(millis() - rxTimer > timeoutPeriod){ // If no data available, check the timeout period
  103. Serial.println("Transfer Failed"); // If per-payload timeout exceeeded, end the transfer
  104. transferInProgress = 0;
  105. }else
  106. if(counter >= payloads){ // If the specified number of payloads is reached, transfer is completed
  107. startTime = millis() - startTime; // Calculate the total time spent during transfer
  108. float numBytes = counter*32; // Calculate the number of bytes transferred
  109. Serial.print("Rate: "); // Print the transfer rate and number of payloads
  110. Serial.print(numBytes/startTime);
  111. Serial.println(" KB/s");
  112. printf("Payload Count: %d \n\r", counter);
  113. transferInProgress = 0; // End the transfer as complete
  114. }
  115. }
  116. }
  117. //
  118. // Change roles
  119. //
  120. if ( Serial.available() )
  121. {
  122. char c = toupper(Serial.read());
  123. if ( c == 'T' && role == RX )
  124. {
  125. printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");
  126. radio.openWritingPipe(pipes[1]);
  127. radio.openReadingPipe(1,pipes[0]);
  128. radio.stopListening();
  129. role = TX; // Become the primary transmitter (ping out)
  130. }
  131. else if ( c == 'R' && role == TX )
  132. {
  133. radio.openWritingPipe(pipes[0]);
  134. radio.openReadingPipe(1,pipes[1]);
  135. radio.startListening();
  136. printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
  137. role = RX; // Become the primary receiver (pong back)
  138. }
  139. }
  140. }