Advertisement
JonD1988

nrf24ReceiverRev12

Aug 24th, 2022
1,846
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Arduino 25.65 KB | None | 0 0
  1. //Rev 0 Created 7/7/2022 This is a limited version of Reference 1 focusing only on 4 pushbuttons - Receiver Code
  2. //Rev 1 Created 7/8/2022 This version of the code works with Transmitter Rev 0 to control two servo motors
  3. //Rev 2 Created 7/12/2022 This version of teh code works with Transmitter Rev 1 to control two servo motors.  In the line RF24 radio(7,8); the 7 and 8 are changed from 8 and 9 in previous versions to free up the PWM pin that was D9 to control more servo motors
  4. //Rev 3 Created 7/14/2022 This is my successfull attempt to create a 12 pushbutton receiver
  5. //Rev 4 Created 7/16/2022 This takes the receiver from being able to control 5 servos to 6 servos.  It also shifts the servo outputs to D2, D3, D4, D5, D6, D9
  6. //Rev 5 Created 7/20/2022 This a verion of the receiver which has 4 additional inputs (Potentiometer 1 or POT1, Pushbutton 13 or PB13, Pushbutton 14 or PB14, Pushbutton 15 or PB15).  Note that POT1 uses A6 and PB13-PB15 use A7 and a resistor ladder. This corresponds to transmitter code Rev 3
  7. //Rev 6 Created 8/17/2022 Each time PB13 is pressed the servo angles are saved to a text file called angles.  This version doesn't do anything with those saved angles yet (doesn't call the values back into the Arduino).
  8. //Rev 7 Created 8/18/2022 Attempt to parse saved positions back into microcontroller on startup (during the setup) - This successfully stores the SD card angles to an array with elements servo01SP[PosNt-1] thru servo06SP[PosNt-1] where the final elements of the array are at index value PosNt-1
  9. //Rev 8 Created 8/23/2022 Attempt to Use Saved Positions.  Note it deoesn't quite do that.  But it does sense PB14 being pressed and increment a counter with a pause between each press.  I'm saving this state by going to Rev 9.
  10. //Rev 9 Created 8/23/2022 This moves the save pushbutton code and step pushbutton code (PB13 and PB14 respectively) into functions savePress and stepPress.  This will make later experiments to move around the command to write to the servo motors easier
  11. //Note: Rev 8 & 9 appear to give the same functionality.  It is just that Rev 9 unclutters void loop by moving much of the code to the savePress and stepPress function definitions
  12. //Rev 10 Created 8/23/2022 This is further experiments of making the stepPress code work.  I wanted to save the state of Rev 9.  Rev 10 moved the functions out of the radio check and added a pause inside of the readValues function to control how often the readValues function is called because without this pause the servos were moving too fast at one button press of PB1 thru PB12
  13. //Rev 11 Created 8/24/2022. Continuing experiments in making stepPress function code work. The modeSelect function was implemented and the various other functions were put into an if-else statement depending on the state of modeS.  I wanted to save the state of Rev 11 so saved to Rev 12 for further modifications.
  14. //Rev 12 Created 8/24/2022. Continuing experiments in making stepPress function code work.  I think my readFile function is broken.  It isn't storing to the arrays properly like I thought.  I should check that the functions which worked in ESP32 still work here.  I will have to do more debugging.
  15. #include <SPI.h>
  16. #include <nRF24L01.h>
  17. #include <RF24.h>
  18. #include <Servo.h>
  19. #include <SD.h> //Used for microSD Card
  20.  
  21. File myFile; //Used for microSD Card
  22.  
  23. #define SIGNAL_TIMEOUT 500  // This is signal timeout in milli seconds. We will reset the data if no signal
  24.  
  25. const int J1p=2, J2p=3, J3p=4, J4p=5, J5p=6, J6p=9; //Pins the Servo Motor Signal Wires are Attached to
  26. const int sdCS=A0, nrfCS=8; //SD Card Module Chip Select Pin is A0. nrfCS is NRF24 Module Chip Select which is pin D8.
  27.  
  28. const uint64_t pipeIn = 0xF9E8F0F0E1LL;
  29. RF24 radio(7, nrfCS); //CE=Pin 7, CSN=Pin 8. Note: CSN is Chip Select Not or Chip Select that is active low
  30. unsigned long lastRecvTime = 0;
  31.  
  32. unsigned long prevMillisRead = 0; //will store last time PB1 thru PB12 were updated
  33. unsigned long prevMillisPB13 = 0; //will store last time PB13 was updated
  34. unsigned long prevMillisStep = 0; //will store last time step pushbutton was updated
  35. const long intervalPB13 = 1000; //interval at which to pause after PB13 press (milliseconds)
  36. const long intervalStep = 1000; //interval at which to pause after step pushbutton is pressed (milliseconds)
  37. const long intervalRead = 25; //interval at which to pause after PB1 thru PB12 axis pushbuttons are pressed (milliseconds) - controls speed in live play mode
  38. int pb13Cnt=0; //Stores Number of Times PB13 has been pressed
  39. int pb14Cnt=0; //Stores Number of Times PB14 has been pressed
  40.  
  41. int J1a=51, J2a=155, J3a=0, J4a=74, J5a=80, J6a=84; //Variable to Store Joint Angles i.e. Servo Motor Angles - Note: Initial values are a safe home position obtained from RxPOTRev14.ino in D:\Stuff\Projects\ESP32 Control\ServoWiFi\RxPOTRev14
  42. String dataMessage, Jnt1Beg="J1b", Jnt2Beg="J2b", Jnt3Beg="J3b", Jnt4Beg="J4b", Jnt5Beg="J5b", Jnt6Beg="J6b", Sbuffer; //dataMessage≡to store string to write to SD card. Jnt1 thru Jnt6≡bracket strings to enclose servo angles. J1 stands for Joint 1. J2 stands for Joint 2. The b suffix means beginning. Sbuffer≡a strong to hold one line of text
  43. int PosbI, PosNI, PosNd, J1bI, J2bI, J3bI, J4bI, J5bI, J6bI, PoseI; //Indexes of delimiters. PosNd≡Number of Digits in Position Number
  44. int PosNt, Jnt1t, Jnt2t, Jnt3t, Jnt4t, Jnt5t, Jnt6t; //t suffix≡indicates read from text file. PosN≡Position Number. Jnt≡Joint Number
  45. int servo01SP[50], servo02SP[50], servo03SP[50], servo04SP[50], servo05SP[50], servo06SP[50]; //Arrays used to store positions for the Saved Program Mode of the Robot
  46. int modeS=0; //Mode Selection Variable Used to Select Between Mode 0=Live Play from the Controller & Save Mode where Points Can Be Stored to SD Card and Mode=1 Playback Mode where Saved Positions Are Fed to the Servos
  47.  
  48. struct PacketData
  49. {
  50.   byte switch1Value;
  51.   byte switch2Value;
  52.   byte switch3Value;
  53.   byte switch4Value;
  54.   byte switch5Value;
  55.   byte switch6Value;
  56.   byte switch7Value;
  57.   byte switch8Value;
  58.   byte switch9Value;
  59.   byte switch10Value;
  60.   byte switch11Value;
  61.   byte switch12Value;
  62.   byte pot1Value;
  63.   byte switch13Value;
  64.   byte switch14Value;
  65.   byte switch15Value;
  66. };
  67. PacketData receiverData;
  68.  
  69. Servo servo1;     //Pin D2
  70. Servo servo2;     //Pin D3
  71. Servo servo3;     //Pin D4
  72. Servo servo4;     //Pin D5
  73. Servo servo5;     //Pin D6
  74. Servo servo6;     //Pin D9
  75.  
  76. //Assign default input received values
  77. void setInputDefaultValues()
  78. {
  79.   receiverData.switch1Value = LOW;
  80.   receiverData.switch2Value = LOW;
  81.   receiverData.switch3Value = LOW;
  82.   receiverData.switch4Value = LOW;
  83.   receiverData.switch5Value = LOW;
  84.   receiverData.switch6Value = LOW;
  85.   receiverData.switch7Value = LOW;
  86.   receiverData.switch8Value = LOW;
  87.   receiverData.switch9Value = LOW;
  88.   receiverData.switch10Value = LOW;
  89.   receiverData.switch11Value = LOW;
  90.   receiverData.switch12Value = LOW;
  91.   //Input a default value for POT1 when I decide if I want 0 or 1 digitally to be Live Play - Probably 0
  92.   receiverData.switch13Value = LOW;
  93.   receiverData.switch14Value = LOW;
  94.   receiverData.switch15Value = LOW;
  95. }
  96.  
  97. void readValues()
  98. {
  99.   unsigned long currentReadMillis = millis(); //Records time that PB1 thru PB12 are pressed - Actually controls how often the readValues function is caused
  100.   if (currentReadMillis - prevMillisRead >= intervalRead)
  101.   {
  102.   prevMillisRead = currentReadMillis; //Save the last time the readValues function was called
  103.   //Joint 1 Angle is Controlled by Pushbutton 1 and Pushbutton 2
  104.     if(receiverData.switch1Value==HIGH)
  105.     {
  106.     J1a=J1a+1; //Increments the Joint 1 Angle if Pushbutton 1 is Pressed
  107.     }
  108.     if(receiverData.switch2Value==HIGH)
  109.     {
  110.     J1a=J1a-1; //Decrements the Joint 1 Angle if Pushbutton 2 is Pressed
  111.     }
  112.  
  113.     //Joint 2 Angle is Controlled by Pushbutton 3 and Pushbutton 4
  114.     if(receiverData.switch3Value==HIGH)
  115.     {
  116.     J2a=J2a+1; //Increments the Joint 2 Angle if Pushbutton 3 is Pressed
  117.     }
  118.     if(receiverData.switch4Value==HIGH)
  119.     {
  120.     J2a=J2a-1; //Decrements the Joint 2 Angle if Pushbutton 4 is Pressed
  121.     }
  122.  
  123.     //Joint 3 Angle is Controlled by Pushbutton 5 and Pushbutton 6
  124.     if(receiverData.switch5Value==HIGH)
  125.     {
  126.     J3a=J3a+1; //Increments the Joint 3 Angle if Pushbutton 5 is Pressed
  127.     }
  128.     if(receiverData.switch6Value==HIGH)
  129.     {
  130.     J3a=J3a-1; //Decrements the Joint 3 Angle if Pushbutton 6 is Pressed
  131.     }
  132.  
  133.      //Joint 4 Angle is Controlled by Pushbutton 7 and Pushbutton 8
  134.     if(receiverData.switch7Value==HIGH)
  135.     {
  136.     J4a=J4a+1; //Increments the Joint 4 Angle if Pushbutton 7 is Pressed
  137.     }
  138.     if(receiverData.switch8Value==HIGH)
  139.     {
  140.     J4a=J4a-1; //Decrements the Joint 4 Angle if Pushbutton 8 is Pressed
  141.     }
  142.  
  143.     //Joint 5 Angle is Controlled by Pushbutton 9 and Pushbutton 10
  144.     if(receiverData.switch9Value==HIGH)
  145.     {
  146.     J5a=J5a+1; //Increments the Joint 5 Angle if Pushbutton 9 is Pressed
  147.     }
  148.     if(receiverData.switch10Value==HIGH)
  149.     {
  150.     J5a=J5a-1; //Decrements the Joint 5 Angle if Pushbutton 10 is Pressed
  151.     }
  152.  
  153.     //Joint 6 Angle is Controlled by Pushbutton 11 and Pushbutton 12
  154.     if(receiverData.switch11Value==HIGH)
  155.     {
  156.     J6a=J6a+1; //Increments the Joint 6 Angle if Pushbutton 11 is Pressed
  157.     }
  158.     if(receiverData.switch12Value==HIGH)
  159.     {
  160.     J6a=J6a-1; //Decrements the Joint 6 Angle if Pushbutton 12 is Pressed
  161.     }
  162.  
  163.     //Now let's add limits for the range of Servo Motor Angles
  164.     if(J1a>180)
  165.     {
  166.     J1a=180; //Sets the upper limit to 180  
  167.     }
  168.     if(J1a<0)
  169.     {
  170.     J1a=0; //Sets the lower limit to 0  
  171.     }
  172.  
  173.     if(J2a>180)
  174.     {
  175.     J2a=180; //Sets the upper limit to 180  
  176.     }
  177.     if(J2a<0)
  178.     {
  179.     J2a=0; //Sets the lower limit to 0  
  180.     }
  181.  
  182.     if(J3a>180)
  183.     {
  184.     J3a=180; //Sets the upper limit to 180  
  185.     }
  186.     if(J3a<0)
  187.     {
  188.     J3a=0; //Sets the lower limit to 0  
  189.     }
  190.  
  191.     if(J4a>180)
  192.     {
  193.     J4a=180; //Sets the upper limit to 180  
  194.     }
  195.     if(J4a<0)
  196.     {
  197.     J4a=0; //Sets the lower limit to 0  
  198.     }
  199.  
  200.     if(J5a>180)
  201.     {
  202.     J5a=180; //Sets the upper limit to 180  
  203.     }
  204.     if(J5a<0)
  205.     {
  206.     J5a=0; //Sets the lower limit to 0  
  207.     }
  208.  
  209.     if(J6a>180)
  210.     {
  211.     J6a=180; //Sets the upper limit to 180  
  212.     }
  213.     if(J6a<0)
  214.     {
  215.     J6a=0; //Sets the lower limit to 0  
  216.     }
  217.   } //End of If Statement Checking to see if the apuse time has elapsed after PB1 thru PB12 are pressed
  218. } //End of readValue function definition
  219.  
  220. void mapAndWriteValues(int J1a, int J2a, int J3a, int J4a, int J5a, int J6a)
  221. {
  222.   servo1.write(J1a);
  223.   servo2.write(J2a);
  224.   servo3.write(J3a);
  225.   servo4.write(J4a);
  226.   servo5.write(J5a);
  227.   servo6.write(J6a);
  228.  
  229. } //End of mapAndWriteValues function
  230.  
  231. void setup()
  232. {
  233.   Serial.begin(115200);
  234.   while (!Serial) {
  235.     ; // wait for serial port to connect. Needed for native USB port only
  236.   }
  237.   pinMode(sdCS, OUTPUT); //SD Card Module Chip Select Pin is Made an Output
  238.   //pinMode(sdCS, LOW); //SD Card Module Chip Select Pin is Started LOW So SD Card Module Is Initially Communicating
  239.  
  240.   //Initialize the SD Card
  241.   Serial.print("Initializing SD card...");
  242.  
  243.   if (!SD.begin(sdCS)) //This step takes care of setting the SD Card Module Chip Select Pin Low
  244.   {
  245.        Serial.println("initialization failed!");
  246.        while (1);
  247.   }
  248.         Serial.println("initialization done.");
  249.   //Read the contents of the SD card
  250.   readFile(); //Reads contents of SD card to the serial monitor once - Note: You will have to press reset on the receiver board after saving a new program to the SD card in order to run that changed program
  251.   pinMode(sdCS, HIGH); //SD Card Module Chip Select Pin is Set High So SD Card Module Isn't Communicating Because Radio Module Needs to Communicate
  252.   radio.begin();
  253.   radio.setDataRate(RF24_250KBPS);
  254.   radio.openReadingPipe(1,pipeIn);
  255.   radio.startListening(); //start the radio receiver
  256.  
  257.   servo1.attach(J1p);
  258.   servo2.attach(J2p);
  259.   servo3.attach(J3p);
  260.   servo4.attach(J4p);
  261.   servo5.attach(J5p);
  262.   servo6.attach(J6p);
  263.  
  264.   readValues(); //Reads the angle value initially
  265.   setInputDefaultValues();
  266.   mapAndWriteValues(J1a, J2a, J3a, J4a, J5a, J6a);
  267. } //End of void setup()
  268.  
  269. void loop()
  270. {
  271.   // Check if RF is connected and packet is available
  272.   if(radio.isChipConnected() && radio.available())
  273.   {
  274.     radio.read(&receiverData, sizeof(PacketData));
  275.     lastRecvTime = millis();
  276.    
  277.   } //End of if-statement to check if the radio signal is available
  278.   else
  279.   {
  280.     //Check Signal lost.
  281.     unsigned long now = millis();
  282.     if ( now - lastRecvTime > SIGNAL_TIMEOUT )
  283.     {
  284.       setInputDefaultValues();
  285.       //Serial.println("No Signal");
  286.     }
  287.   }
  288.  
  289.  
  290. modeSelect(); //Calls the modeSelect function to find out what mode the controller is in
  291. //Serial.println("modeS=" + String(modeS));
  292.  
  293. if (modeS==0)
  294. {
  295.   readValues(); //Reads the angles on a continual basis
  296.   //Serial.println("J1a=" + String(J1a) + ", J2a=" + String(J2a) + ", J3a=" + String(J3a) + ", J4a=" + String(J4a) + ", J5a=" + String(J5a) + ", J6a=" + String(J6a));  
  297.   mapAndWriteValues(J1a, J2a, J3a, J4a, J5a, J6a);
  298.   savePress(); //savePress function call which checks to see if save pushbutton has been pressed and takes action. At the time I write this as of Rev 9 the save pushbutton is PB13
  299. } //End of if modeS==0 i.e. end of Live Play and Save State mode
  300. else //if modeS==1
  301. {
  302.   stepPress(); //Function call for stepPress function which checks to see if step pushbutton has been pressed and takes action. At the time I write this as of Rev 9 the step pushbutton is PB14
  303.  
  304.   //Add continuous code here later
  305. } //End of if modeS==1 i.e. end of step mode and continuous mode
  306.  
  307. mapAndWriteValues(J1a, J2a, J3a, J4a, J5a, J6a);
  308. } //End of void loop()
  309.  
  310. //SD Card Module Function Definitions
  311. // Write the integer message on the SD card
  312. void logSDCard(int J1a, int J2a, int J3a, int J4a, int J5a, int J6a, int pb13Cnt) {
  313. //  dataMessage = "Posb" + String(pb13Cnt) + Jnt1Beg + String(J1a) + Jnt2Beg + String(J2a) + Jnt3Beg + String(J3a) + Jnt4Beg + String(J4a) + Jnt5Beg + String(J5a) + Jnt6Beg + String(J6a) + "Pose" + String(pb13Cnt) + "\r\n";
  314.   dataMessage = "Posb" + String(pb13Cnt) + Jnt1Beg + String(J1a) + Jnt2Beg + String(J2a) + Jnt3Beg + String(J3a) + Jnt4Beg + String(J4a) + Jnt5Beg + String(J5a) + Jnt6Beg + String(J6a) + "Pose" + String(pb13Cnt);
  315.   Serial.print("Save data: ");
  316.   Serial.println(dataMessage);
  317.   //myFile = SD.open("angles.txt", FILE_APPEND); //Note: File name should be too long or won't work
  318.   myFile = SD.open("angles.txt", FILE_WRITE);
  319.   myFile.seek(EOF);
  320.   //If the file opened okay, write to it:
  321.         if (myFile) {
  322.            Serial.print("Writing to angles.txt...");
  323.            myFile.println(dataMessage.c_str());
  324.         // close the file:
  325.         myFile.close();
  326.            Serial.println("done.");
  327.         } else{
  328.         // if the file didn't open, print an error:
  329.           Serial.println("error opening angles.txt");
  330.         }
  331. }
  332.  
  333. void readFile(){//readFile parses the contents of the angles.txt file and stores them in six arrays
  334.   Serial.println("Reading file:");
  335.   myFile = SD.open("angles.txt");
  336.   if(!myFile){
  337.     Serial.println("Failed to open file for reading");
  338.     return;
  339.   }
  340.  
  341.     while(myFile.available()){ //While the file is open
  342.       //Write one line to Sbuffer
  343.       Sbuffer = myFile.readStringUntil('\n');
  344.       //Print to serial monitor
  345.     //  Serial.println(Sbuffer);
  346.  
  347.     PosbI = Sbuffer.indexOf("Posb");
  348.     J1bI = Sbuffer.indexOf("J1b");
  349.     if (J1bI==5)
  350.     {//If the position number is a 1 digit number
  351.     PosNI = J1bI-1; //Position Number is always 1 less than the start of J1b's index
  352.     PosNd = 1; //1 Digit in Position Number
  353.     }
  354.     else if (J1bI==6)
  355.     {//If the position number is a 2 digit number
  356.     PosNI = J1bI-2; //Position Number is always 2 less than the start of J1b's index
  357.     PosNd = 2; //2 Digits in Position Number
  358.     }
  359.     J2bI = Sbuffer.indexOf("J2b");
  360.     J3bI = Sbuffer.indexOf("J3b");
  361.     J4bI = Sbuffer.indexOf("J4b");
  362.     J5bI = Sbuffer.indexOf("J5b");
  363.     J6bI = Sbuffer.indexOf("J6b");
  364.     PoseI = Sbuffer.indexOf("Pose");
  365.     Serial.println(J1bI);
  366.     Serial.print(",");
  367.     Serial.print(J2bI);
  368.     Serial.print(",");
  369.     Serial.print(J3bI);
  370.     Serial.print(",");
  371.     Serial.print(J4bI);
  372.     Serial.print(",");
  373.     Serial.print(J5bI);
  374.     Serial.print(",");
  375.     Serial.print(J6bI);
  376.     //Serial.println("Indices are Posb=" + String(PosbI) + ", PosN=" + String(PosNI) + ", J1b=" + String(J1bI) + ", J2b=" + String(J2bI) + ", J3b=" + String(J3bI) + ", J4b=" + String(J4bI) + ", J5b=" + String(J5bI) + ", J6b=" + String(J6bI) + ", Pose=" + String(PoseI) + ".");
  377.     PosNt = Sbuffer.substring(PosNI, PosNI+PosNd).toInt(); //Parses out the position number
  378.     Jnt1t = Sbuffer.substring(J1bI+3, J2bI).toInt(); //Parses out the Joint 1 Angle
  379.     Jnt2t = Sbuffer.substring(J2bI+3, J3bI).toInt(); //Parses out the Joint 2 Angle
  380.     Jnt3t = Sbuffer.substring(J3bI+3, J4bI).toInt(); //Parses out the Joint 3 Angle
  381.     Jnt4t = Sbuffer.substring(J4bI+3, J5bI).toInt(); //Parses out the Joint 4 Angle
  382.     Jnt5t = Sbuffer.substring(J5bI+3, J6bI).toInt(); //Parses out the Joint 5 Angle
  383.     Jnt6t = Sbuffer.substring(J6bI+3, PoseI).toInt(); //Parses out the Joint 6 Angle
  384.     //Serial.println(String(PosNt) + "," + String(Jnt1t) + "," + String(Jnt2t) + "," + String(Jnt3t) + "," + String(Jnt4t) + "," + String(Jnt5t) + "," + String(Jnt6t)); //This is purely a debug line
  385.  
  386.     //Store angles read from text file to arrays
  387.     servo01SP[PosNt-1] = Jnt1t; //Store current Joint 1 Angle to Element of servo01SP array. PosNT-1 is minus 1 because servo01SP array starts at index 0 but position numbers start at 1
  388.     servo02SP[PosNt-1] = Jnt2t; //Store current Joint 2 Angle to Element of servo02SP array. PosNT-1 is minus 1 because servo02SP array starts at index 0 but position numbers start at 1
  389.     servo03SP[PosNt-1] = Jnt3t; //Store current Joint 3 Angle to Element of servo03SP array. PosNT-1 is minus 1 because servo03SP array starts at index 0 but position numbers start at 1
  390.     servo04SP[PosNt-1] = Jnt4t; //Store current Joint 4 Angle to Element of servo04SP array. PosNT-1 is minus 1 because servo04SP array starts at index 0 but position numbers start at 1
  391.     servo05SP[PosNt-1] = Jnt5t; //Store current Joint 5 Angle to Element of servo05SP array. PosNT-1 is minus 1 because servo05SP array starts at index 0 but position numbers start at 1
  392.     servo06SP[PosNt-1] = Jnt6t; //Store current Joint 6 Angle to Element of servo06SP array. PosNT-1 is minus 1 because servo06SP array starts at index 0 but position numbers start at 1
  393.  
  394.     //The following section is for debugging to make sure that the array elements stored correctly - Change the number in servo06SPst and servo06SP in all 3 instances in the following lines only to each of the array elements to test one by one. Note: The following lines are commented out because they are only for debugging purposes
  395.     //String servo06SPst=String(servo06SP[PosNt-1]); //Converts Array Element to String - Do not try to do the conversion of an array element to string inside of the Serial.print function because the text file will not open
  396.     //Serial.println("Success Position" + String(PosNt) + "," + servo06SPst); //Must verify array storage one element at a time
  397.     } //End of while myFile.available() loop
  398.   myFile.close();
  399. } //End of readFile function definition
  400.  
  401. void savePress(){//savePress checks to see if the save pushbutton has been pressed and takes action to store the positions on the micro SD card
  402. if (receiverData.switch13Value == 1) //If PB13 is Pressed
  403.     {
  404.       unsigned long currentPB13Millis = millis(); //Records time that PB13 is pressed
  405.  
  406.       if (currentPB13Millis - prevMillisPB13 >= intervalPB13) { //Check to see if intervalPB13 has passed/elapsed
  407.         prevMillisPB13 = currentPB13Millis; //Save the last time you blinked the LED
  408.         pb13Cnt++; //Increment the PB13 Counter
  409.         //digitalWrite(nrfCS, HIGH); //This is active low.  So by turning the Radio Module Chip Select Pin High the communication between Radio Module and Microcontroller is Stopped
  410.         radio.stopListening(); //stop the radio receiver
  411.      
  412.         //Initialize the SD Card
  413.         Serial.print("Initializing SD card...");
  414.  
  415.         if (!SD.begin(sdCS))
  416.         {
  417.           Serial.println("initialization failed!");
  418.           while (1);
  419.         }
  420.         Serial.println("initialization done.");
  421.  
  422.         logSDCard(J1a, J2a, J3a, J4a, J5a, J6a, pb13Cnt); //Function Call to Log Angles to SD Card
  423.  
  424.         digitalWrite(sdCS, HIGH); //This is active low.  So by turning the SD Card Module Chip Select Pin High the communication between SD Card Module and Microcontroller is Stopped
  425.         radio.startListening(); //start the radio receiver
  426.         //digitalWrite(nrfCS, LOW); //This is active low.  So by turning the Radio Module Chip Select Pin LOW the communication between Radio Module and Microcontroller is Restarted
  427.  
  428.       } //End of If Statement Checking if Pushbutton Pause Interval has passed
  429.     } //End of If Statement for if PB13 is Pressed
  430. } //End of the savePress function definition
  431.  
  432. void stepPress(){//stepPress checks to see if the step pushbutton has been pressed and takes action to step through the stored positions
  433.     if (receiverData.switch14Value == 1) //If PB14 is Pressed
  434.     {
  435.           unsigned long currentStepMillis = millis(); //Records time that Step Pushbutton is pressed
  436.           if (currentStepMillis - prevMillisStep >= intervalStep)
  437.             { //Check to see if intervalStep has passed/elapsed
  438.             prevMillisStep = currentStepMillis; //Save the last time you pressed the pushbutton
  439.  
  440.             //Stepping Code
  441.                     int serv1 = servo01SP[pb14Cnt];
  442.                     int serv2 = servo02SP[pb14Cnt];
  443.                     int serv3 = servo03SP[pb14Cnt];
  444.                     int serv4 = servo04SP[pb14Cnt];
  445.                     int serv5 = servo05SP[pb14Cnt];
  446.                     int serv6 = servo06SP[pb14Cnt];
  447.                    
  448.             //radio.stopListening(); //stop the radio receiver
  449.             //digitalWrite(sdCS, HIGH); //This is active low.  So by turning the SD Card Module Chip Select Pin High the communication between SD Card Module and Microcontroller is Stopped
  450.            
  451.             servo1.write(serv1);
  452.             servo2.write(serv2);
  453.             servo3.write(serv3);
  454.             //servo4.write(serv4);
  455.             //servo5.write(serv5);
  456.             //servo6.write(serv6);
  457.  
  458.             //radio.startListening(); //start the radio receiver
  459.            
  460.             pb14Cnt++;
  461.             Serial.println("PB14 Pressed " + String(pb14Cnt) + " times." + String(serv1) + String(serv2) + String(serv3)); //A debug line just to make sure the PB14 press code works
  462.             } //End of if statement checking to see if the pause time has elasped
  463.    
  464.     } //End of If Statement for if PB14 is Pressed
  465. } //End of stepPress function definition
  466.  
  467. int modeSelect()
  468. {
  469.   int modePOT = receiverData.pot1Value; //Reads the mode selection potentiometer and stores to modePOT variable
  470.   //Serial.println("modePOT=" + String(modePOT));
  471.   if(modePOT < 127)
  472.   {
  473.     modeS=0;
  474.   }
  475.   else
  476.   {
  477.     modeS=1;
  478.   }
  479.   return modeS;
  480. }
  481.  
  482. //References
  483. //Reference 1- Adaptation of https://www.youtube.com/watch?v=gsHeNrDoK84&t=14s which is the "Hash Include Electronics" YouTube channel video "Arduino 10 Channels Wireless Transmitter Receiver | nrf24l01+| DIY" File Located at https://github.com/un0038998/10_Channel_NRF_Transmitter_Receiver
  484. //Reference 2- Used for Servo Motor Angle from Pushbutton funcionality https://www.youtube.com/watch?v=fxgcnJJlTd4&list=PLGs0VKk2DiYw-L-RibttcvK-WBZm8WLEP&index=41&t=39s - Paul McWhorter Video Arduino Tutorial 40: Controlling DC Motor Speed and Direction with Pushbuttons
  485. //Reference 3- Learning How to Use Multiple SPI Devices (micro SD card module with NRF24) http://www.learningaboutelectronics.com/Articles/Multiple-SPI-devices-to-an-arduino-microcontroller.php
  486. //Reference 4- Learning How to Use micro SD Card Module with Arduino https://dronebotworkshop.com/sd-card-arduino/ and https://randomnerdtutorials.com/guide-to-sd-card-module-with-arduino/
  487. //Reference 4- For putting a pause once Pushbutton 13 is pressed before it will read again - Blink without Delay https://create.arduino.cc/example/builtin/02.Digital%5CBlinkWithoutDelay/BlinkWithoutDelay/preview
  488. //Reference 5- For being able to Append onto a File in the micro SD card module the comment by André Carvalho https://arduino.stackexchange.com/questions/65888/arduino-sd-card-open-file-modes-append-overwrite
  489.  
  490. //Notes on Pinouts
  491. //On Arduino Nano NRF24 Breakout Board Pin SCK goes to D13. On Arduino Mega NRF24 Breakout Board Pin SCK goes to D52 which is the SCK on the Mega.
  492. //On Arduino Nano NRF24 Breakout Board Pin MO goes to D11. On Arduino Mega NRF24 Breakout Board Pin MO goes to D51 which is the MOSI on the Mega.
  493. //On Arduino Nano NRF24 Breakout Board Pin MI goes to D12. On Arduino Mega NRF24 Breakout Board Pin MI goes to D50 which is the MISO on the Mega.
  494. //On Arduino Nano NRF24 Breakout Board Pin CE goes to D7. On Arduino Mega NRF24 Breakout Board Pin CE goes to D7 which is nothing special on the Mega (this pin is not required to be PWM). Can also use D40 on the Mega
  495. //On Arduino Nano NRF24 Breakout Board Pin CSN goes to D8. On Arduino Mega NRF24 Breakout Board Pin CSN goes to D8 which needs to be a PWM pin on the Mega (it is). - Note doesn't actually need to be PWM. Can also use D41 on the Mega
  496.  
  497. //Reference 4
  498. //You only need to open the file with FILE_WRITE and use file.seek(EOF) to go to de end of the file. After that you can write whatever you want that will be appended to the end of the file.
  499. //File outputFile = SD.open(LOG_FILE, FILE_WRITE);
  500. //outputFile.seek(EOF);
  501. //outputFile.println("Appended to the EOF");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement